From 29648e712fc5af0d1bcd2a0b7103aa85ec2adf61 Mon Sep 17 00:00:00 2001 From: znek Date: Wed, 30 Jun 2004 09:13:47 +0000 Subject: [PATCH] created branch of ZideStore/UI-X for SOGo git-svn-id: http://svn.opengroupware.org/SOGo/trunk@101 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/UI/ChangeLog | 208 +++++ SOGo/UI/Common/CommonUIProduct.m | 34 + SOGo/UI/Common/GNUmakefile | 82 ++ SOGo/UI/Common/GNUmakefile.postamble | 17 + SOGo/UI/Common/GNUmakefile.preamble | 16 + SOGo/UI/Common/UIxAppFrame.m | 11 + SOGo/UI/Common/UIxAppFrame.wox | 44 + SOGo/UI/Common/UIxAppHeader.m | 11 + SOGo/UI/Common/UIxAppHeader.wox | 32 + SOGo/UI/Common/UIxAppNavView.m | 104 +++ SOGo/UI/Common/UIxAppNavView.wox | 10 + SOGo/UI/Common/UIxAppNavigation.m | 11 + SOGo/UI/Common/UIxAppNavigation.wox | 85 ++ SOGo/UI/Common/UIxComponent.h | 55 ++ SOGo/UI/Common/UIxComponent.m | 168 ++++ SOGo/UI/Common/UIxElemBuilder.m | 86 ++ SOGo/UI/Common/UIxPageFrame.m | 44 + SOGo/UI/Common/UIxPageFrame.wox | 308 +++++++ SOGo/UI/Common/UIxTabItem.m | 475 ++++++++++ SOGo/UI/Common/UIxTabView.h | 134 +++ SOGo/UI/Common/UIxTabView.m | 819 ++++++++++++++++++ SOGo/UI/Common/UIxWinClose.m | 37 + SOGo/UI/Common/UIxWinClose.wox | 6 + SOGo/UI/Common/Version | 5 + SOGo/UI/Common/bundle-info.plist | 40 + SOGo/UI/Common/calendar.css | 189 ++++ SOGo/UI/Common/common.h | 155 ++++ SOGo/UI/Common/images/OGoLogo.gif | Bin 0 -> 2047 bytes SOGo/UI/Common/images/box_botleft.gif | Bin 0 -> 100 bytes SOGo/UI/Common/images/box_botright.gif | Bin 0 -> 102 bytes SOGo/UI/Common/images/box_bottom.gif | Bin 0 -> 43 bytes SOGo/UI/Common/images/box_left.gif | Bin 0 -> 47 bytes SOGo/UI/Common/images/box_right.gif | Bin 0 -> 47 bytes SOGo/UI/Common/images/box_top.gif | Bin 0 -> 43 bytes SOGo/UI/Common/images/box_topleft.gif | Bin 0 -> 102 bytes SOGo/UI/Common/images/box_topright.gif | Bin 0 -> 101 bytes SOGo/UI/Common/images/closewindow.gif | Bin 0 -> 96 bytes SOGo/UI/Common/images/corner_right.gif | Bin 0 -> 49 bytes SOGo/UI/Common/images/line_left.gif | Bin 0 -> 264 bytes SOGo/UI/Common/images/line_right.gif | Bin 0 -> 262 bytes SOGo/UI/Common/images/line_stretch.gif | Bin 0 -> 234 bytes SOGo/UI/Common/images/menu_logo_top.gif | Bin 0 -> 2047 bytes SOGo/UI/Common/images/tab_.gif | Bin 0 -> 127 bytes SOGo/UI/Common/images/tab_selected.gif | Bin 0 -> 127 bytes SOGo/UI/Common/product.plist | 47 + SOGo/UI/Common/zidestoreui.css | 199 +++++ SOGo/UI/GNUmakefile | 9 + SOGo/UI/Scheduler/COPYING | 482 +++++++++++ SOGo/UI/Scheduler/COPYRIGHT | 4 + SOGo/UI/Scheduler/GNUmakefile | 66 ++ SOGo/UI/Scheduler/GNUmakefile.postamble | 17 + SOGo/UI/Scheduler/GNUmakefile.preamble | 17 + SOGo/UI/Scheduler/NOTES | 52 ++ SOGo/UI/Scheduler/SchedulerUIProduct.m | 34 + SOGo/UI/Scheduler/UIxAppointmentEditor.m | 277 ++++++ SOGo/UI/Scheduler/UIxAppointmentEditor.wox | 111 +++ SOGo/UI/Scheduler/UIxAppointmentFormatter.h | 120 +++ SOGo/UI/Scheduler/UIxAppointmentFormatter.m | 454 ++++++++++ SOGo/UI/Scheduler/UIxAppointmentView.h | 26 + SOGo/UI/Scheduler/UIxAppointmentView.m | 109 +++ SOGo/UI/Scheduler/UIxAppointmentView.wox | 166 ++++ SOGo/UI/Scheduler/UIxAptTableView.m | 75 ++ SOGo/UI/Scheduler/UIxAptTableView.wox | 34 + SOGo/UI/Scheduler/UIxCalBackForthNavView.m | 49 ++ SOGo/UI/Scheduler/UIxCalBackForthNavView.wox | 20 + SOGo/UI/Scheduler/UIxCalDateLabel.m | 113 +++ SOGo/UI/Scheduler/UIxCalDateLabel.wox | 8 + SOGo/UI/Scheduler/UIxCalMonthOverview.m | 119 +++ SOGo/UI/Scheduler/UIxCalMonthOverview.wox | 165 ++++ SOGo/UI/Scheduler/UIxCalMonthView.h | 23 + SOGo/UI/Scheduler/UIxCalMonthView.m | 49 ++ SOGo/UI/Scheduler/UIxCalSelectTab.m | 103 +++ SOGo/UI/Scheduler/UIxCalSelectTab.wox | 25 + SOGo/UI/Scheduler/UIxCalView.h | 67 ++ SOGo/UI/Scheduler/UIxCalView.m | 235 +++++ SOGo/UI/Scheduler/UIxCalWeekOverview.m | 79 ++ SOGo/UI/Scheduler/UIxCalWeekOverview.wox | 161 ++++ SOGo/UI/Scheduler/UIxCalWeekView.h | 19 + SOGo/UI/Scheduler/UIxCalWeekView.m | 35 + SOGo/UI/Scheduler/Version | 5 + SOGo/UI/Scheduler/bundle-info.plist | 20 + SOGo/UI/Scheduler/common.h | 34 + SOGo/UI/Scheduler/images/icon_apt_chart.gif | Bin 0 -> 360 bytes .../images/icon_apt_chart_inactive.gif | Bin 0 -> 181 bytes .../Scheduler/images/icon_apt_column_view.gif | Bin 0 -> 250 bytes SOGo/UI/Scheduler/images/icon_apt_list.gif | Bin 0 -> 360 bytes .../images/icon_apt_list_inactive.gif | Bin 0 -> 181 bytes .../UI/Scheduler/images/icon_apt_overview.gif | Bin 0 -> 343 bytes .../images/icon_apt_overview_inactive.gif | Bin 0 -> 165 bytes SOGo/UI/Scheduler/images/next_week.gif | Bin 0 -> 121 bytes SOGo/UI/Scheduler/images/previous_week.gif | Bin 0 -> 121 bytes SOGo/UI/Scheduler/product.plist | 71 ++ 92 files changed, 6885 insertions(+) create mode 100644 SOGo/UI/ChangeLog create mode 100644 SOGo/UI/Common/CommonUIProduct.m create mode 100644 SOGo/UI/Common/GNUmakefile create mode 100644 SOGo/UI/Common/GNUmakefile.postamble create mode 100644 SOGo/UI/Common/GNUmakefile.preamble create mode 100644 SOGo/UI/Common/UIxAppFrame.m create mode 100644 SOGo/UI/Common/UIxAppFrame.wox create mode 100644 SOGo/UI/Common/UIxAppHeader.m create mode 100644 SOGo/UI/Common/UIxAppHeader.wox create mode 100644 SOGo/UI/Common/UIxAppNavView.m create mode 100644 SOGo/UI/Common/UIxAppNavView.wox create mode 100644 SOGo/UI/Common/UIxAppNavigation.m create mode 100644 SOGo/UI/Common/UIxAppNavigation.wox create mode 100644 SOGo/UI/Common/UIxComponent.h create mode 100644 SOGo/UI/Common/UIxComponent.m create mode 100644 SOGo/UI/Common/UIxElemBuilder.m create mode 100644 SOGo/UI/Common/UIxPageFrame.m create mode 100644 SOGo/UI/Common/UIxPageFrame.wox create mode 100644 SOGo/UI/Common/UIxTabItem.m create mode 100644 SOGo/UI/Common/UIxTabView.h create mode 100644 SOGo/UI/Common/UIxTabView.m create mode 100644 SOGo/UI/Common/UIxWinClose.m create mode 100644 SOGo/UI/Common/UIxWinClose.wox create mode 100644 SOGo/UI/Common/Version create mode 100644 SOGo/UI/Common/bundle-info.plist create mode 100644 SOGo/UI/Common/calendar.css create mode 100644 SOGo/UI/Common/common.h create mode 100755 SOGo/UI/Common/images/OGoLogo.gif create mode 100644 SOGo/UI/Common/images/box_botleft.gif create mode 100644 SOGo/UI/Common/images/box_botright.gif create mode 100644 SOGo/UI/Common/images/box_bottom.gif create mode 100644 SOGo/UI/Common/images/box_left.gif create mode 100644 SOGo/UI/Common/images/box_right.gif create mode 100644 SOGo/UI/Common/images/box_top.gif create mode 100644 SOGo/UI/Common/images/box_topleft.gif create mode 100644 SOGo/UI/Common/images/box_topright.gif create mode 100644 SOGo/UI/Common/images/closewindow.gif create mode 100644 SOGo/UI/Common/images/corner_right.gif create mode 100644 SOGo/UI/Common/images/line_left.gif create mode 100644 SOGo/UI/Common/images/line_right.gif create mode 100644 SOGo/UI/Common/images/line_stretch.gif create mode 100644 SOGo/UI/Common/images/menu_logo_top.gif create mode 100644 SOGo/UI/Common/images/tab_.gif create mode 100644 SOGo/UI/Common/images/tab_selected.gif create mode 100644 SOGo/UI/Common/product.plist create mode 100644 SOGo/UI/Common/zidestoreui.css create mode 100644 SOGo/UI/GNUmakefile create mode 100644 SOGo/UI/Scheduler/COPYING create mode 100644 SOGo/UI/Scheduler/COPYRIGHT create mode 100644 SOGo/UI/Scheduler/GNUmakefile create mode 100644 SOGo/UI/Scheduler/GNUmakefile.postamble create mode 100644 SOGo/UI/Scheduler/GNUmakefile.preamble create mode 100644 SOGo/UI/Scheduler/NOTES create mode 100644 SOGo/UI/Scheduler/SchedulerUIProduct.m create mode 100644 SOGo/UI/Scheduler/UIxAppointmentEditor.m create mode 100644 SOGo/UI/Scheduler/UIxAppointmentEditor.wox create mode 100644 SOGo/UI/Scheduler/UIxAppointmentFormatter.h create mode 100644 SOGo/UI/Scheduler/UIxAppointmentFormatter.m create mode 100644 SOGo/UI/Scheduler/UIxAppointmentView.h create mode 100644 SOGo/UI/Scheduler/UIxAppointmentView.m create mode 100644 SOGo/UI/Scheduler/UIxAppointmentView.wox create mode 100644 SOGo/UI/Scheduler/UIxAptTableView.m create mode 100644 SOGo/UI/Scheduler/UIxAptTableView.wox create mode 100644 SOGo/UI/Scheduler/UIxCalBackForthNavView.m create mode 100644 SOGo/UI/Scheduler/UIxCalBackForthNavView.wox create mode 100644 SOGo/UI/Scheduler/UIxCalDateLabel.m create mode 100644 SOGo/UI/Scheduler/UIxCalDateLabel.wox create mode 100644 SOGo/UI/Scheduler/UIxCalMonthOverview.m create mode 100644 SOGo/UI/Scheduler/UIxCalMonthOverview.wox create mode 100644 SOGo/UI/Scheduler/UIxCalMonthView.h create mode 100644 SOGo/UI/Scheduler/UIxCalMonthView.m create mode 100644 SOGo/UI/Scheduler/UIxCalSelectTab.m create mode 100644 SOGo/UI/Scheduler/UIxCalSelectTab.wox create mode 100644 SOGo/UI/Scheduler/UIxCalView.h create mode 100644 SOGo/UI/Scheduler/UIxCalView.m create mode 100644 SOGo/UI/Scheduler/UIxCalWeekOverview.m create mode 100644 SOGo/UI/Scheduler/UIxCalWeekOverview.wox create mode 100644 SOGo/UI/Scheduler/UIxCalWeekView.h create mode 100644 SOGo/UI/Scheduler/UIxCalWeekView.m create mode 100644 SOGo/UI/Scheduler/Version create mode 100644 SOGo/UI/Scheduler/bundle-info.plist create mode 100644 SOGo/UI/Scheduler/common.h create mode 100644 SOGo/UI/Scheduler/images/icon_apt_chart.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_chart_inactive.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_column_view.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_list.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_list_inactive.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_overview.gif create mode 100644 SOGo/UI/Scheduler/images/icon_apt_overview_inactive.gif create mode 100644 SOGo/UI/Scheduler/images/next_week.gif create mode 100644 SOGo/UI/Scheduler/images/previous_week.gif create mode 100644 SOGo/UI/Scheduler/product.plist diff --git a/SOGo/UI/ChangeLog b/SOGo/UI/ChangeLog new file mode 100644 index 00000000..f8c8667d --- /dev/null +++ b/SOGo/UI/ChangeLog @@ -0,0 +1,208 @@ +2004-06-30 Marcus Müller + + * Scheduler/UIxAppointmentEditor.m: improved -saveAction. Does + everything in a complete manner now - except for saving which isn't + done at all. + +2004-06-30 Helge Hess + + * Scheduler/UIxAppointmentEditor.m: made the hack more hackish to work + on MacOSX + +2004-06-28 Marcus Mueller + + * Common/UIxComponent.[hm]: moved -ownMethodName here. + + * Scheduler/UIxCalView.[hm]: removed -ownMethodName, moved to + UIxComponent (reuse). + + * Scheduler/UIxAppointmentView.[hm]: first "draft" of view component. + The look of OGo is resembled closely, but most features are still + missing. + +2004-06-28 Marcus Mueller + + * Scheduler/GNUmakefile.preamble: links against libSOGoLogic now. + + * Scheduler/UIxAppointmentView.m, Scheduler/UIxAppointmentView.wox: + test of iCal object. + +2004-06-23 Marcus Mueller + + * UIxCalMonthOverview.[m,wox]: completed month view. Turned out to + be much more difficult to improve with style sheets than expected. + Requires version 4.2.45 of WEExtensions. + +2004-06-22 Marcus Mueller + + * Refactoring: Renamed everything from OGo to UIx in order to avoid + nameclashes (happens on OSX related to NGBundleManager) + + * Refactoring 2: Moved methods from UIxWeekOverview to UIxCalView. + + * Highlighting in UIxWeekOverview works now. + +2004-06-22 Helge Hess + + * Common/GNUmakefile.preamble: fixed linking for OGo gstep-make + +2004-06-21 Helge Hess + + * Scheduler/OGoCalWeekOverview.m: fixed syntax errors + +2004-06-18 Marcus Mueller + + * Implemented proper calendar in week overview. Highlighting isn't + enabled, yet. + +2004-06-18 Marcus Mueller + + * Common/OGoComponent.[hm]: new component which serves as a base + component for calendar components now. Knows how to deal with + queryParameters and offers url construction method(s). + + * All existing components have been rewritten to use queryParameters + instead of hardcoded strings where this is feasible. This provides + future extensibility and flexibility. + + * Handling of dates has been fixed to center around the use of a + 'day' parameter. startDate/endDate are coupled to this, but + don't override it as it's the duty of the individual view to set + its (feasible) ranges accordingly. The new behaviour is noticable + in the calendar selection tabview instantly, as it now replicates + what OGo does. + +2004-06-16 Marcus Mueller + + * Common/OGoAppNavView.m: construct URL correctly. + + * Common/OGoPageFrame.m: display login correctly. + + * Common/calendar.css: cosmetic changes. + + * Scheduler/OGoCalSelectTab.m: always display mondayOfWeek. + + * Scheduler/OGoCalBackForthNavView.m: created. + +2004-06-16 Marcus Mueller + + * Common/zidestoreui.css: new style for button_auto. + + * Scheduler/OGoCalView.[hm]: API for completing hrefs with necessary + query parts. + + * Scheduler/OGoCalWeekView.m: bugfix for startDate. + + * Scheduler/product.plist: added still missing views -> point to + weekoverview for the time being. + +2004-06-15 Marcus Mueller + + * Common/UIxTabView.m: removed class from tag, removed rendering + of headerFooter (what's that good for anyways?) + + * Several resources which resolved to wrong products added statically + in templates. + + * Cosmetic changes in templates. + +2004-06-14 Helge Hess + + * Scheduler/OGoCalMonthOverview.wox: added missing rsrc namespace + +2004-06-14 Helge Hess + + * Common/common.h: fixed a gcc 3.4 warning + +2004-06-14 Helge Hess + + * added aggregate project for UI-X + +2004-06-14 Marcus Mueller + + * Common/calendar.css: new date_label (unused) + + * Scheduler/OGoCalSelectTab.m: finished all labels + + * Scheduler/OGoCalDateLabel.m, Scheduler/OGoCalDateLabel.wox: new + component for rendering the correct date label based on startDate, + endDate and selection + + * Scheduler/OGoCalMonthView.m: prev/next month corrected + + * Scheduler/OGoCalMonthOverview.wox: uses date label and tabs now + + * Scheduler/OGoCalWeekOverview.wox: completed layout + + * Scheduler/GNUmakefile: new component added + +2004-06-14 Marcus Mueller + + * Common/UIxTabView.[hm]: more stylesheet support via headerStyle + and bodyStyle bindings. + + * Common/zidestoreui.css: styles for tabs, resembling OGo look. + + * Scheduler/OGoCalSelectTab.m: implemented dateLabel (for testing). + + * Scheduler/OGoCalSelectTab.wox: corrected selection binding namespace. + +2004-06-08 Helge Hess + + * Scheduler/NOTES: added class hierarchy + + * */common.h, GNUmakefile.preamble.: fixed for OSX compile + +2004-06-08 Marcus Mueller + + * Common/images: added a bunch of images from OGo + +2004-06-07 Marcus Mueller + + * Custom/GNUmakefile: changed ZIDESTORE to include installed version + (ZideStore12). Removed post install hooks. + + * Custom/GNUmakefile.postamble: new file, post install hooks and + xmllint for .wox. + +2004-06-07 Marcus Mueller + + * Scheduler/GNUmakefile: changed ZIDESTORE to include installed version + (ZideStore12). Removed post install hooks. + + * Scheduler/GNUmakefile.postamble: post install hooks updated for + GNUSTEP_BUILD_DIR. + +2004-06-03 Helge Hess + + * Scheduler/OGoCalWeekOverview.m: moved navigation URL generation to + superclass (now generic because we use the 'ownMethodName'). Could + even be moved to OGoCalView? + + * Scheduler/OGoCalMonthView.m: added next/prev month URL generation + methods, calculate startdate from form value + + * Scheduler/OGoCalView.m: added -ownMethodName method to return the + last path component of the request URL (the SOPE method), eg + 'weekoverview' for OGoCalWeekView, added + -dateNavigationURLWithNewStartDate: method to calculate 'startDate' + URLs (should be improved to include existing query parameters!) + + * Scheduler/OGoCalWeekOverview.m: minor tweaks ;-) + +2004-06-03 Marcus Mueller + + * Scheduler/OGoCalWeekView.m: construct startDate from formValue, + otherwise use current week's monday as startDate. + + * Scheduler/OGoCalWeekOverview.wox: switch back/forth + + * Scheduler/OGoCalWeekOverview.m: provide URLs for switching back/forth + weekoverview. + + * Scheduler/OGoCalView.[hm]: methods for converting dates into strings + and vice versa. + + * Scheduler/OGoAppointmentView.m, Scheduler/OGoCalView.m: fixed include + + * ChangeLog: created diff --git a/SOGo/UI/Common/CommonUIProduct.m b/SOGo/UI/Common/CommonUIProduct.m new file mode 100644 index 00000000..b5a4da4a --- /dev/null +++ b/SOGo/UI/Common/CommonUIProduct.m @@ -0,0 +1,34 @@ +/* + Copyright (C) 2000-2003 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id: CommonUIProduct.m,v 1.1 2003/11/24 01:24:40 helge Exp $ + +#import + +@interface CommonUIProduct : NSObject +{ +} + +@end + +#include "common.h" + +@implementation CommonUIProduct +@end /* CommonUIProduct */ diff --git a/SOGo/UI/Common/GNUmakefile b/SOGo/UI/Common/GNUmakefile new file mode 100644 index 00000000..0fda272f --- /dev/null +++ b/SOGo/UI/Common/GNUmakefile @@ -0,0 +1,82 @@ +# $Id: GNUmakefile,v 1.2 2003/12/09 17:38:42 helge Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +ZIDESTORE=$(GNUSTEP_USER_ROOT)/Headers/ZideStore12 + + +BUNDLE_NAME = CommonUI +BUNDLE_EXTENSION = .zsp +BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/ZideStore12 + +LIBRARY_NAME = libZideStoreCommonUI + + +libZideStoreCommonUI_HEADER_FILES_DIR = . +libZideStoreCommonUI_HEADER_FILES_INSTALL_DIR = $(ZIDESTORE)/Common + +libZideStoreCommonUI_HEADER_FILES += \ + UIxComponent.h \ + +libZideStoreCommonUI_OBJC_FILES += \ + UIxComponent.m \ + + +CommonUI_PRINCIPAL_CLASS = CommonUIProduct + +CommonUI_OBJC_FILES += \ + CommonUIProduct.m \ + UIxPageFrame.m \ + UIxAppFrame.m \ + UIxAppHeader.m \ + UIxAppNavigation.m \ + UIxWinClose.m \ + UIxAppNavView.m \ + \ + UIxElemBuilder.m \ + UIxTabView.m \ + UIxTabItem.m \ + + +CommonUI_RESOURCE_FILES += \ + Version \ + product.plist \ + UIxPageFrame.wox \ + UIxAppFrame.wox \ + UIxAppHeader.wox \ + UIxAppNavigation.wox \ + UIxWinClose.wox \ + UIxAppNavView.wox \ + \ + zidestoreui.css \ + calendar.css \ + \ + images/OGoLogo.gif \ + images/menu_logo_top.gif \ + images/line_left.gif \ + images/line_stretch.gif \ + images/line_right.gif \ + images/box_topleft.gif \ + images/box_top.gif \ + images/box_topright.gif \ + images/box_left.gif \ + images/box_right.gif \ + images/box_botleft.gif \ + images/box_bottom.gif\ + images/box_botright.gif\ + images/tab_selected.gif\ + images/tab_.gif\ + images/corner_right.gif\ + images/closewindow.gif + +ADDITIONAL_INCLUDE_DIRS += \ + -I. \ + -I$(ZIDESTORE)/Frontend -I$(ZIDESTORE)/Backend -I$(ZIDESTORE) + + +# make + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/library.make +include $(GNUSTEP_MAKEFILES)/bundle.make +-include GNUmakefile.postamble diff --git a/SOGo/UI/Common/GNUmakefile.postamble b/SOGo/UI/Common/GNUmakefile.postamble new file mode 100644 index 00000000..3986bcce --- /dev/null +++ b/SOGo/UI/Common/GNUmakefile.postamble @@ -0,0 +1,17 @@ +# $Id: GNUmakefile.postamble,v 1.1 2004/05/12 14:45:56 helge Exp $ + +validate-wox: + xmllint --noout *.wox + +before-all :: validate-wox + + +ifneq ($(GNUSTEP_BUILD_DIR),) +after-all :: + @(cp bundle-info.plist \ + $(GNUSTEP_BUILD_DIR)/$(BUNDLE_NAME)$(BUNDLE_EXTENSION)) +else +after-all :: + @(cd $(BUNDLE_NAME)$(BUNDLE_EXTENSION);\ + cp ../bundle-info.plist .) +endif diff --git a/SOGo/UI/Common/GNUmakefile.preamble b/SOGo/UI/Common/GNUmakefile.preamble new file mode 100644 index 00000000..e76e480c --- /dev/null +++ b/SOGo/UI/Common/GNUmakefile.preamble @@ -0,0 +1,16 @@ +# $Id$ + +ifneq ($(GNUSTEP_BUILD_DIR),) + RELBUILD_DIR_libZideStoreCommonUI = $(GNUSTEP_OBJ_DIR) +else + RELBUILD_DIR_libZideStoreCommonUI = $(GNUSTEP_OBJ_DIR) +endif + +libZideStoreCommonUI_LIBRARIES_DEPEND_UPON += -lNGObjWeb + +CommonUI_LIB_DIRS += -L$(RELBUILD_DIR_libZideStoreCommonUI) + +CommonUI_BUNDLE_LIBS += \ + -lNGObjWeb -lNGScripting \ + -lNGMime -lNGStreams -lNGExtensions -lEOControl \ + -lXmlRpc -lDOM -lSaxObjC -lZideStoreCommonUI diff --git a/SOGo/UI/Common/UIxAppFrame.m b/SOGo/UI/Common/UIxAppFrame.m new file mode 100644 index 00000000..8d9553fb --- /dev/null +++ b/SOGo/UI/Common/UIxAppFrame.m @@ -0,0 +1,11 @@ +// $Id$ + +#include + +@interface UIxAppFrame : SoComponent +@end + +#include "common.h" + +@implementation UIxAppFrame +@end /* UIxAppFrame */ diff --git a/SOGo/UI/Common/UIxAppFrame.wox b/SOGo/UI/Common/UIxAppFrame.wox new file mode 100644 index 00000000..0437cf39 --- /dev/null +++ b/SOGo/UI/Common/UIxAppFrame.wox @@ -0,0 +1,44 @@ + + + + + <var:string value="title"/> + + + + + + + + + + + + + + + + + + + + + + + + This pages requires frame tags, which your browser does not support, + sorry ;-> + + diff --git a/SOGo/UI/Common/UIxAppHeader.m b/SOGo/UI/Common/UIxAppHeader.m new file mode 100644 index 00000000..5a4db92f --- /dev/null +++ b/SOGo/UI/Common/UIxAppHeader.m @@ -0,0 +1,11 @@ +// $Id$ + +#include + +@interface UIxAppHeader : SoComponent +@end + +#include "common.h" + +@implementation UIxAppHeader +@end /* UIxAppHeader */ diff --git a/SOGo/UI/Common/UIxAppHeader.wox b/SOGo/UI/Common/UIxAppHeader.wox new file mode 100644 index 00000000..4f8c0d27 --- /dev/null +++ b/SOGo/UI/Common/UIxAppHeader.wox @@ -0,0 +1,32 @@ + + + + + + + + + + + + +
+ reload - + resistance is obsolete ;-) +
+ + diff --git a/SOGo/UI/Common/UIxAppNavView.m b/SOGo/UI/Common/UIxAppNavView.m new file mode 100644 index 00000000..8bf1ff12 --- /dev/null +++ b/SOGo/UI/Common/UIxAppNavView.m @@ -0,0 +1,104 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + + +#import +#import +#import +#import + + +@interface UIxAppNavView : WOComponent +{ + id element; + id lastElement; +} + +@end + + +@implementation UIxAppNavView + +- (void)dealloc { + [self->element release]; + [self->lastElement release]; + [super dealloc]; +} + +- (void)setElement:(id)_element { + ASSIGN(self->element, _element); +} + +- (id)element { + return self->element; +} + +- (void)setLastElement:(id)_element { + ASSIGN(self->lastElement, _element); +} + +- (id)lastElement { + return self->lastElement; +} + +- (NSArray *)navPathElements { + NSArray *traversalObjects; + NSMutableArray *navPathComponents; + NSMutableString *navURL; + unsigned int i, count; + + traversalObjects = [[self context] objectTraversalStack]; + count = ([traversalObjects count] - 1); /* remove SoPageInvocation */ + navPathComponents = [[NSMutableArray alloc] initWithCapacity:count]; + navURL = [[NSMutableString alloc] initWithString:@"/"]; + + for(i = 0; i < count; i++) { + NSString *name, *url; + id obj; + + obj = [traversalObjects objectAtIndex:i]; + + name = [obj davDisplayName]; + if(!name) + name = NSStringFromClass([obj class]); + + [navURL appendString:name]; + [navURL appendString:@"/"]; + + if(! [name hasPrefix:@"ZideStore"]) { + NSMutableDictionary *c; + + c = [[NSMutableDictionary alloc] initWithCapacity:2]; + [c setObject:name forKey:@"name"]; + url = [navURL copy]; + [c setObject:url forKey:@"url"]; + [url release]; + [navPathComponents addObject:c]; + [c release]; + } + } + + [self setLastElement:[navPathComponents lastObject]]; + return [navPathComponents autorelease]; +} + +@end diff --git a/SOGo/UI/Common/UIxAppNavView.wox b/SOGo/UI/Common/UIxAppNavView.wox new file mode 100644 index 00000000..6e924d43 --- /dev/null +++ b/SOGo/UI/Common/UIxAppNavView.wox @@ -0,0 +1,10 @@ + + + +You are here:/ + \ No newline at end of file diff --git a/SOGo/UI/Common/UIxAppNavigation.m b/SOGo/UI/Common/UIxAppNavigation.m new file mode 100644 index 00000000..529127de --- /dev/null +++ b/SOGo/UI/Common/UIxAppNavigation.m @@ -0,0 +1,11 @@ +// $Id$ + +#include + +@interface UIxAppNavigation : SoComponent +@end + +#include "common.h" + +@implementation UIxAppNavigation +@end /* UIxAppNavigation */ diff --git a/SOGo/UI/Common/UIxAppNavigation.wox b/SOGo/UI/Common/UIxAppNavigation.wox new file mode 100644 index 00000000..27eadaf5 --- /dev/null +++ b/SOGo/UI/Common/UIxAppNavigation.wox @@ -0,0 +1,85 @@ + + + + + + + + + + + + +
+ +
+ +
+ (reload) +
+ +
+ +
+ +
+ CSS Menues + + diff --git a/SOGo/UI/Common/UIxComponent.h b/SOGo/UI/Common/UIxComponent.h new file mode 100644 index 00000000..d9a0c6ff --- /dev/null +++ b/SOGo/UI/Common/UIxComponent.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + + +#ifndef __UIxComponent_H_ +#define __UIxComponent_H_ + +#include + +@class NSCalendarDate; + + +@interface UIxComponent : SoComponent +{ + NSMutableDictionary *queryParameters; +} + +- (NSString *)queryParameterForKey:(NSString *)_key; +- (NSDictionary *)queryParameters; + +/* use this to set 'sticky' query parameters */ +- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key; + +/* appends queryParameters to _method if any are set */ +- (NSString *)completeHrefForMethod:(NSString *)_method; + +- (NSString *)ownMethodName; + +/* date selection */ +- (NSCalendarDate *)selectedDate; +- (NSString *)dateStringForDate:(NSCalendarDate *)_date; +- (NSCalendarDate *)dateForDateString:(NSString *)_dateString; + +@end + +#endif /* __UIxComponent_H_ */ diff --git a/SOGo/UI/Common/UIxComponent.m b/SOGo/UI/Common/UIxComponent.m new file mode 100644 index 00000000..280bcd71 --- /dev/null +++ b/SOGo/UI/Common/UIxComponent.m @@ -0,0 +1,168 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + + +#include "UIxComponent.h" +#include +#include +#include + + +@interface UIxComponent (PrivateAPI) +- (void)_parseQueryString:(NSString *)_s; +@end + + +@implementation UIxComponent + +- (id)init { + if ((self = [super init])) { + self->queryParameters = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)dealloc { + [self->queryParameters release]; + [super dealloc]; +} + + +- (void)awake { + WORequest *req; + NSString *uri; + NSRange r; + + [super awake]; + + req = [[self context] request]; + uri = [req uri]; + r = [uri rangeOfString:@"?"]; + if(r.length > 0) { + NSString *qs; + + qs = [uri substringFromIndex:(r.location + r.length)]; + [self->queryParameters removeAllObjects]; + [self _parseQueryString:qs]; + } +} + +- (void)_parseQueryString:(NSString *)_s { + NSEnumerator *e; + NSString *part; + + e = [[_s componentsSeparatedByString:@"&"] objectEnumerator]; + while ((part = [e nextObject])) { + NSRange r; + NSString *key, *value; + + r = [part rangeOfString:@"="]; + if (r.length == 0) { + /* missing value of query parameter */ + key = [part stringByUnescapingURL]; + value = @"1"; + } + else { + key = [[part substringToIndex:r.location] stringByUnescapingURL]; + value = [[part substringFromIndex:(r.location + r.length)] + stringByUnescapingURL]; + } + [self->queryParameters setObject:value forKey:key]; + } +} + +- (NSString *)queryParameterForKey:(NSString *)_key { + return [self->queryParameters objectForKey:_key]; +} + +- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key { + if(_key == nil) + return; + + if(_param != nil) + [self->queryParameters setObject:_param forKey:_key]; + else + [self->queryParameters removeObjectForKey:_key]; +} + +- (NSDictionary *)queryParameters { + return self->queryParameters; +} + +- (NSString *)completeHrefForMethod:(NSString *)_method { + NSDictionary *qp; + NSString *qs; + + qp = [self queryParameters]; + if([qp count] == 0) + return _method; + + qs = [[self context] queryStringFromDictionary:qp]; + return [_method stringByAppendingFormat:@"?%@", qs]; +} + +- (NSString *)ownMethodName { + NSString *uri; + NSRange r; + + uri = [[[self context] request] uri]; + + /* first: cut off query parameters */ + + r = [uri rangeOfString:@"?" options:NSBackwardsSearch]; + if (r.length > 0) + uri = [uri substringToIndex:r.location]; + + /* next: strip trailing slash */ + + if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)]; + r = [uri rangeOfString:@"/" options:NSBackwardsSearch]; + + /* then: cut of last path component */ + + if (r.length == 0) // no slash? are we at root? + return @"/"; + + return [uri substringFromIndex:(r.location + 1)]; +} + +/* date */ + +- (NSCalendarDate *)selectedDate { + NSString *s; + + s = [self queryParameterForKey:@"day"]; + if(s) { + return [self dateForDateString:s]; + } + return [NSCalendarDate date]; +} + +- (NSString *)dateStringForDate:(NSCalendarDate *)_date { + return [_date descriptionWithCalendarFormat:@"%Y%m%d"]; +} + +- (NSCalendarDate *)dateForDateString:(NSString *)_dateString { + return [NSCalendarDate dateWithString:_dateString calendarFormat:@"%Y%m%d"]; +} + +@end diff --git a/SOGo/UI/Common/UIxElemBuilder.m b/SOGo/UI/Common/UIxElemBuilder.m new file mode 100644 index 00000000..00579088 --- /dev/null +++ b/SOGo/UI/Common/UIxElemBuilder.m @@ -0,0 +1,86 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + +#include + +/* + This builder builds various elements from the UI-X product. + + All tags are mapped into the namespace (XMLNS_OD_BIND). + + maps to UIxTabView + maps to UIxTabItem +*/ + +@interface UIxElemBuilder : WOxTagClassElemBuilder +{ +} + +@end + +#include +#include "common.h" + +#define XMLNS_UIX @"OGo:uix" + + +@implementation UIxElemBuilder + +- (Class)classForElement:(id)_element { + NSString *tagName; + unsigned tl; + unichar c1; + + if (![[_element namespaceURI] isEqualToString:XMLNS_UIX]) + return Nil; + + tagName = [_element tagName]; + if ((tl = [tagName length]) < 2) + return Nil; + + c1 = [tagName characterAtIndex:0]; + + switch (c1) { + case 't': { /* starting with 't' */ + unichar c2; + + c2 = [tagName characterAtIndex:1]; + + if (tl == 3 && c2 == 'a') { + if ([tagName characterAtIndex:2] == 'b') + return NSClassFromString(@"UIxTabItem"); + } + + if (tl > 5) { + if (c2 == 'a') { + if ([tagName isEqualToString:@"tabview"]) + return NSClassFromString(@"UIxTabView"); + } + } + break; + } + } + + return Nil; +} + +@end /* UIxElemBuilder */ diff --git a/SOGo/UI/Common/UIxPageFrame.m b/SOGo/UI/Common/UIxPageFrame.m new file mode 100644 index 00000000..ba39e5f4 --- /dev/null +++ b/SOGo/UI/Common/UIxPageFrame.m @@ -0,0 +1,44 @@ +// $Id$ + +#include +#include +#include + + +@interface UIxPageFrame : SoComponent +{ + NSString *title; +} + +@end + +#include "common.h" + +@implementation UIxPageFrame + +- (void)dealloc { + [self->title release]; + [super dealloc]; +} + +/* accessors */ + +- (void)setTitle:(NSString *)_value { + ASSIGN(self->title, _value); +} + +- (NSString *)title { + return self->title; +} + +- (NSString *)login { + WOContext *ctx; + SoUser *user; + + ctx = [self context]; + user = [[[self clientObject] authenticatorInContext:ctx] + userInContext:ctx]; + return [user login]; +} + +@end /* UIxPageFrame */ diff --git a/SOGo/UI/Common/UIxPageFrame.wox b/SOGo/UI/Common/UIxPageFrame.wox new file mode 100644 index 00000000..efc1f4d9 --- /dev/null +++ b/SOGo/UI/Common/UIxPageFrame.wox @@ -0,0 +1,308 @@ + + + + + <var:string value="title"/> + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + SOGo () + +
+ + + + + + +
+ + + + + +
+
+
+ + News + +
+ + Projects + +
+ + Contacts + +
+ + Companies + +
+ + Calendar + +
+ + Tasks + +
+
+ +
+ + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Misc +
+ + + + + + +
+ + + + + +
+
+
+ New Email +
+ Inbox +
+ Preferences +
+ Home +
+ Desktop +
+ Logout +
+
+ +
+ + + + + +
+
+
+ +
+ + + + + + + + +
+ + + + + +
+
+ + + + + +
+ + 2000-2004 SKYRIX Software AG. + We welcome your + feedback. + + + + No sessions required! ;-) + +
+
+ + diff --git a/SOGo/UI/Common/UIxTabItem.m b/SOGo/UI/Common/UIxTabItem.m new file mode 100644 index 00000000..21046f9d --- /dev/null +++ b/SOGo/UI/Common/UIxTabItem.m @@ -0,0 +1,475 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + +#include "UIxTabView.h" +#include "common.h" + +#if DEBUG +# define DEBUG_JS 1 +#endif + +/* context keys */ +extern NSString *UIxTabView_HEAD; +extern NSString *UIxTabView_BODY; +extern NSString *UIxTabView_KEYS; +extern NSString *UIxTabView_SCRIPT; +extern NSString *UIxTabView_ACTIVEKEY; +extern NSString *UIxTabView_COLLECT; + +@implementation UIxTabItem + +static Class StrClass = Nil; + ++ (int)version { + return [super version] + 0; +} ++ (void)initialize { + StrClass = [NSString class]; +} + +static NSString *retStrForInt(int i) { + switch(i) { + case 0: return @"0"; + case 1: return @"1"; + case 2: return @"2"; + case 3: return @"3"; + case 4: return @"4"; + case 5: return @"5"; + case 6: return @"6"; + case 7: return @"7"; + case 8: return @"8"; + case 9: return @"9"; + case 10: return @"10"; + // TODO: find useful count! + default: + return [[StrClass alloc] initWithFormat:@"%i", i]; + } +} + +- (id)initWithName:(NSString *)_name + associations:(NSDictionary *)_config + template:(WOElement *)_subs +{ + if ((self = [super initWithName:_name associations:_config template:_subs])) { + self->key = WOExtGetProperty(_config, @"key"); + self->label = WOExtGetProperty(_config, @"label"); + + self->isScript = WOExtGetProperty(_config, @"isScript"); + self->href = WOExtGetProperty(_config, @"href"); + + self->icon = WOExtGetProperty(_config, @"icon"); + self->action = WOExtGetProperty(_config, @"action"); + + self->tabStyle = WOExtGetProperty(_config, @"tabStyle"); + self->selectedTabStyle = WOExtGetProperty(_config, @"selectedTabStyle"); + + self->tabIcon = WOExtGetProperty(_config, @"tabIcon"); + self->leftTabIcon = WOExtGetProperty(_config, @"leftTabIcon"); + self->selectedTabIcon = WOExtGetProperty(_config, @"selectedTabIcon"); + + self->asBackground = WOExtGetProperty(_config, @"asBackground"); + self->width = WOExtGetProperty(_config, @"width"); + self->height = WOExtGetProperty(_config, @"height"); + self->activeBgColor = WOExtGetProperty(_config, @"activeBgColor"); + self->inactiveBgColor = WOExtGetProperty(_config, @"inactiveBgColor"); + + self->template = [_subs retain]; + } + return self; +} + +- (void)dealloc { + [self->key release]; + [self->label release]; + + [self->href release]; + + [self->action release]; + + [self->isScript release]; + [self->template release]; + + [self->tabStyle release]; + [self->selectedTabStyle release]; + + [self->icon release]; + [self->leftTabIcon release]; + [self->selectedTabIcon release]; + [self->tabIcon release]; + + [self->asBackground release]; + [self->width release]; + [self->height release]; + + [self->activeBgColor release]; + [self->inactiveBgColor release]; + + [super dealloc]; +} + +/* responder */ + +- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { + NSString *activeTabKey; + NSString *myTabKey; + BOOL doCheck; + + if ([_ctx objectForKey:UIxTabView_HEAD]) { + /* head clicks */ + [[_ctx component] debugWithFormat: + @"UIxTabItem: head takes (no) values, eid='%@'", + [_ctx elementID]]; + return; + } + + if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY]) == nil) { + [[_ctx component] debugWithFormat:@"UIxTabItem: invalid state"]; + [self->template takeValuesFromRequest:_rq inContext:_ctx]; + return; + } + + myTabKey = [self->key stringValueInComponent:[_ctx component]]; + doCheck = [self->isScript boolValueInComponent:[_ctx component]]; + + if ([activeTabKey isEqualToString:myTabKey] || doCheck) { +#if ADD_OWN_ELEMENTIDS + [_ctx appendElementIDComponent:activeTabKey]; +#endif + +#if DEBUG_TAKEVALUES + [[_ctx component] debugWithFormat: + @"UIxTabItem: body takes values, eid='%@'", + [_ctx elementID]]; +#endif + + [self->template takeValuesFromRequest:_rq inContext:_ctx]; +#if ADD_OWN_ELEMENTIDS + [_ctx deleteLastElementIDComponent]; +#endif + } +#if DEBUG_TAKEVALUES + else { + [[_ctx component] debugWithFormat: + @"UIxTabItem: body takes no values, eid='%@'", + [_ctx elementID]]; + } +#endif +} + +- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx { + id result; + WOAssociation *tmp; + NSString *activeTabKey; + + if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) { + /* click on tab icon */ + NSString *tabkey; + + tabkey = [_ctx currentElementID]; + [_ctx consumeElementID]; + [_ctx appendElementIDComponent:tabkey]; + + if ([tmp isValueSettable]) + [tmp setValue:tabkey inComponent:[_ctx component]]; + +#if 0 + result = [self->action valueInComponent:[_ctx component]]; +#endif + + [_ctx deleteLastElementIDComponent]; + } + else if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY])) { + /* clicked somewhere in the (active) body */ + result = [self->template invokeActionForRequest:_req inContext:_ctx]; + } + else { + [[_ctx component] logWithFormat:@"UIxTabItem: invalid invoke state"]; + result = [self->template invokeActionForRequest:_req inContext:_ctx]; + } + + return result; +} + +/* info collection */ + +- (void)_collectInContext:(WOContext *)_ctx key:(NSString *)k { + BOOL isLeft = NO; + NSMutableArray *keys; + UIxTabItemInfo *info; + WOComponent *cmp; + + cmp = [_ctx component]; + keys = [_ctx objectForKey:UIxTabView_KEYS]; + if (keys == nil) { + keys = [[[NSMutableArray alloc] init] autorelease]; + [_ctx setObject:keys forKey:UIxTabView_KEYS]; + isLeft = YES; + } + + if (k == nil) { + /* auto-assign a key */ + k = retStrForInt([keys count]); + } + else + k = [k retain]; + [_ctx appendElementIDComponent:k]; + + info = [[UIxTabItemInfo alloc] init]; + info->key = [k copy]; + info->label = [[self->label stringValueInComponent:cmp] copy]; + info->icon = [[self->icon stringValueInComponent:cmp] copy]; +#if 0 + info->uri = [[_ctx componentActionURL] copy]; +#else + info->uri = [[self->href stringValueInComponent:cmp] copy]; +#endif + info->isScript = [self->isScript boolValueInComponent:cmp]; + info->tabIcon = [[self->tabIcon stringValueInComponent:cmp] copy]; + info->leftIcon = [[self->leftTabIcon stringValueInComponent:cmp] copy]; + info->selIcon = [[self->selectedTabIcon stringValueInComponent:cmp] + copy]; + info->tabStyle = [[self->tabStyle stringValueInComponent:cmp] copy]; + info->selectedTabStyle = [[self->selectedTabStyle stringValueInComponent:cmp] + copy]; + + if (self->asBackground == nil) + info->asBackground = 0; + else { + info->asBackground + = ([self->asBackground boolValueInComponent:cmp]) ? 1 : -1; + } + info->width = [[self->width stringValueInComponent:cmp] copy]; + info->height = [[self->height stringValueInComponent:cmp] copy]; + info->activeBg = [[self->activeBgColor stringValueInComponent:cmp] + copy]; + info->inactiveBg = [[self->inactiveBgColor stringValueInComponent:cmp] + copy]; + + if (info->leftIcon == nil) info->leftIcon = [info->tabIcon copy]; + + [keys addObject:info]; + [info release]; + [k release]; + + [_ctx deleteLastElementIDComponent]; +} + +/* header generation */ + +- (void)_appendHeadToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + activeKey:(NSString *)activeKey + key:(NSString *)k +{ + /* head is currently generated in UIxTabView */ +#if 0 + // note: some associations can be inherited by UIxTabView ! + BOOL doImages; + WOComponent *comp; + BOOL doBgIcon; + NSString *label; + NSString *w, *h; + + doImages = ![[[_ctx request] clientCapabilities] isTextModeBrowser]; + comp = [_ctx component]; + + doBgIcon = self->asBackground && doImages + ? [self->asBackground boolValueInComponent:comp] ? YES : NO + : NO; + + if ((label = [self->label stringValueInComponent:comp]) == nil) + label = k; + + if (doImages) { + /* lookup image */ + NSString *imgName = nil; + // ... + + imgUri = WEUriOfResource(imgName, _ctx); + if ([imgUri length] < 1) + doImages = NO; + } + + // .... _isActive +#endif +} + +/* body generation */ + +- (void)_appendBodyToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + activeKey:(NSString *)tmp + key:(NSString *)k +{ + BOOL doScript; + BOOL isScript_; + BOOL isActive; + + doScript = [[_ctx objectForKey:UIxTabView_SCRIPT] boolValue]; + isScript_ = [self->isScript boolValueInComponent:[_ctx component]]; + isActive = [tmp isEqualToString:k]; + + if (doScript && (isActive || isScript_)) { + [_response appendContentString:@"
\n"]; + } + + if (isActive || (doScript && isScript_)) { + /* content is active or used as layer*/ +#if ADD_OWN_ELEMENTIDS + [_ctx appendElementIDComponent:k]; +#endif +#if DEBUG && 0 + NSLog(@"TAB: %@", k); +#endif + + [self->template appendToResponse:_response inContext:_ctx]; + +#if ADD_OWN_ELEMENTIDS + [_ctx deleteLastElementIDComponent]; +#endif + } + + if (doScript && (isActive || isScript_)) { + NSString *jsout; + [_response appendContentString:@"
"]; + + jsout = [NSString alloc]; + jsout = [jsout initWithFormat: + @""]; + } +} + +/* master generation method */ + +- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + NSString *k; + BOOL doForm; + id tmp; + + doForm = [_ctx isInForm]; + k = [self->key stringValueInComponent:[_ctx component]]; + + if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) { + if ([tmp isEqual:UIxTabView_COLLECT]) { + [self _collectInContext:_ctx key:k]; + } + else { + [self _appendHeadToResponse:_response inContext:_ctx + activeKey:tmp key:k]; + } + } + else if ((tmp = [_ctx objectForKey:UIxTabView_BODY])) { + [self _appendBodyToResponse:_response inContext:_ctx + activeKey:tmp key:k]; + } + else { + NSLog(@"WARNING(%s): invalid UIxTabItem state !!!", __PRETTY_FUNCTION__); + [_response appendContentString:@"[invalid state]"]; + } +} + +@end /* UIxTabItem */ + +@implementation UIxTabItemInfo + +- (void)dealloc { + [self->uri release]; + [self->icon release]; + [self->label release]; + [self->key release]; + [self->tabStyle release]; + [self->selectedTabStyle release]; + [self->tabIcon release]; + [self->selIcon release]; + [self->leftIcon release]; + [self->width release]; + [self->height release]; + [self->activeBg release]; + [self->inactiveBg release]; + + [super dealloc]; +} + +/* accessors */ + +- (NSString *)key { + return self->key; +} +- (NSString *)label { + return self->label; +} +- (NSString *)icon { + return self->icon; +} +- (NSString *)uri { + return self->uri; +} +- (BOOL)isScript { + return self->isScript; +} + +- (int)asBackground { + return self->asBackground; +} + +- (NSString *)width { + return self->width; +} + +- (NSString *)height { + return self->height; +} + +- (NSString *)activeBg { + return self->activeBg; +} + +- (NSString *)inactiveBg { + return self->inactiveBg; +} + +@end /* UIxTabItemInfo */ diff --git a/SOGo/UI/Common/UIxTabView.h b/SOGo/UI/Common/UIxTabView.h new file mode 100644 index 00000000..8224b442 --- /dev/null +++ b/SOGo/UI/Common/UIxTabView.h @@ -0,0 +1,134 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + +#ifndef __UIxTabView_H__ +#define __UIxTabView_H__ + +/* + This is a library private header ! +*/ + +#include + +/* + Does not support tab-head-creation from nested components !!! + + hh: Why not ??? -> Because selection is manipulated in sub-elements + + UIxTabView creates element-IDs like + + .h.*.$key. for the tab-items (head-mode) + .b.$key... for the tab-content (content-mode) (new, hh) + + !!! UIxTabView JavaScript can't handle duplicate tab-keys !!! +*/ + +@interface UIxTabView : WODynamicElement +{ + WOAssociation *selection; + + /* config: */ + WOAssociation *headerStyle; + WOAssociation *bodyStyle; + WOAssociation *tabStyle; + WOAssociation *selectedTabStyle; + + /* old config: */ + WOAssociation *bgColor; + WOAssociation *nonSelectedBgColor; + WOAssociation *leftCornerIcon; + WOAssociation *rightCornerIcon; + + WOAssociation *tabIcon; + WOAssociation *leftTabIcon; + WOAssociation *selectedTabIcon; + + WOAssociation *asBackground; + WOAssociation *width; + WOAssociation *height; + WOAssociation *activeBgColor; + WOAssociation *inactiveBgColor; + + WOAssociation *fontColor; + WOAssociation *fontSize; + WOAssociation *fontFace; + + id template; +} + +@end + +@interface UIxTabItem : WODynamicElement +{ + WOAssociation *key; + WOAssociation *label; + + WOAssociation *href; + WOAssociation *isScript; + + WOAssociation *action; + WOAssociation *icon; + + /* config: */ + WOAssociation *tabStyle; + WOAssociation *selectedTabStyle; + + /* old config */ + WOAssociation *tabIcon; + WOAssociation *leftTabIcon; + WOAssociation *selectedTabIcon; + + WOAssociation *asBackground; + WOAssociation *width; + WOAssociation *height; + WOAssociation *activeBgColor; + WOAssociation *inactiveBgColor; + + id template; +} + +@end + +@interface UIxTabItemInfo : NSObject +{ +@public + NSString *label; + NSString *icon; + NSString *key; + NSString *uri; + NSString *tabIcon; + NSString *leftIcon; + NSString *selIcon; + NSString *tabStyle; + NSString *selectedTabStyle; + + int asBackground; // 0 -> not set, 1 -> YES, else -> NO + NSString *width; + NSString *height; + NSString *activeBg; + NSString *inactiveBg; + + BOOL isScript; +} +@end + +#endif /* __UIxTabView_H__ */ diff --git a/SOGo/UI/Common/UIxTabView.m b/SOGo/UI/Common/UIxTabView.m new file mode 100644 index 00000000..ac635c3e --- /dev/null +++ b/SOGo/UI/Common/UIxTabView.m @@ -0,0 +1,819 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + +#include "UIxTabView.h" +#include "common.h" +#import +#import +#import +#include + +#if DEBUG +// # define DEBUG_TAKEVALUES 1 +# define DEBUG_JS 1 +#endif + +/* context keys */ +NSString *UIxTabView_HEAD = @"UIxTabView_head"; +NSString *UIxTabView_BODY = @"UIxTabView_body"; +NSString *UIxTabView_KEYS = @"UIxTabView_keys"; +NSString *UIxTabView_SCRIPT = @"UIxTabView_script"; +NSString *UIxTabView_ACTIVEKEY = @"UIxTabView_activekey"; +NSString *UIxTabView_COLLECT = @"~tv~"; + +@implementation UIxTabView + +static NSNumber *YesNumber; + ++ (void)initialize { + if (YesNumber == nil) + YesNumber = [[NSNumber numberWithBool:YES] retain]; +} + ++ (int)version { + return [super version] + 0; +} + +- (id)initWithName:(NSString *)_name + associations:(NSDictionary *)_config + template:(WOElement *)_subs +{ + if ((self = [super initWithName:_name associations:_config template:_subs])) { + self->selection = WOExtGetProperty(_config, @"selection"); + + self->headerStyle = WOExtGetProperty(_config, @"headerStyle"); + self->bodyStyle = WOExtGetProperty(_config, @"bodyStyle"); + self->tabStyle = WOExtGetProperty(_config, @"tabStyle"); + self->selectedTabStyle = WOExtGetProperty(_config, @"selectedTabStyle"); + + self->bgColor = WOExtGetProperty(_config, @"bgColor"); + self->nonSelectedBgColor = WOExtGetProperty(_config, @"nonSelectedBgColor"); + self->leftCornerIcon = WOExtGetProperty(_config, @"leftCornerIcon"); + self->rightCornerIcon = WOExtGetProperty(_config, @"rightCornerIcon"); + + self->tabIcon = WOExtGetProperty(_config, @"tabIcon"); + self->leftTabIcon = WOExtGetProperty(_config, @"leftTabIcon"); + self->selectedTabIcon = WOExtGetProperty(_config, @"selectedTabIcon"); + + self->asBackground = WOExtGetProperty(_config, @"asBackground"); + self->width = WOExtGetProperty(_config, @"width"); + self->height = WOExtGetProperty(_config, @"height"); + self->activeBgColor = WOExtGetProperty(_config, @"activeBgColor"); + self->inactiveBgColor = WOExtGetProperty(_config, @"inactiveBgColor"); + + self->fontColor = WOExtGetProperty(_config, @"fontColor"); + self->fontSize = WOExtGetProperty(_config, @"fontSize"); + self->fontFace = WOExtGetProperty(_config, @"fontFace"); + + self->template = RETAIN(_subs); + } + return self; +} + +- (void)dealloc { + [self->selection release]; + + [self->headerStyle release]; + [self->bodyStyle release]; + [self->tabStyle release]; + [self->selectedTabStyle release]; + + RELEASE(self->bgColor); + RELEASE(self->nonSelectedBgColor); + RELEASE(self->leftCornerIcon); + RELEASE(self->rightCornerIcon); + + RELEASE(self->leftTabIcon); + RELEASE(self->selectedTabIcon); + RELEASE(self->tabIcon); + + RELEASE(self->width); + RELEASE(self->height); + + RELEASE(self->activeBgColor); + RELEASE(self->inactiveBgColor); + + RELEASE(self->fontColor); + RELEASE(self->fontSize); + RELEASE(self->fontFace); + + RELEASE(self->template); + [super dealloc]; +} + +/* nesting */ + +- (id)saveNestedStateInContext:(WOContext *)_ctx { + return nil; +} +- (void)restoreNestedState:(id)_state inContext:(WOContext *)_ctx { + if (_state == nil) return; +} + +- (NSArray *)collectKeysInContext:(WOContext *)_ctx { + /* collect mode, collects all keys */ + [_ctx setObject:UIxTabView_COLLECT forKey:UIxTabView_HEAD]; + + [self->template appendToResponse:nil inContext:_ctx]; + + [_ctx removeObjectForKey:UIxTabView_HEAD]; + return [_ctx objectForKey:UIxTabView_KEYS]; +} + +/* responder */ + +- (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx { + id nestedState; + NSString *activeTabKey; + + activeTabKey = [self->selection stringValueInComponent:[_ctx component]]; + NSLog(@"%s activeTabKey:%@", __PRETTY_FUNCTION__, activeTabKey); + nestedState = [self saveNestedStateInContext:_ctx]; + [_ctx appendElementIDComponent:@"b"]; + [_ctx appendElementIDComponent:activeTabKey]; + + [_ctx setObject:activeTabKey forKey:UIxTabView_BODY]; + +#if DEBUG_TAKEVALUES + [[_ctx component] debugWithFormat:@"UIxTabView: body takes values, eid='%@'", + [_ctx elementID]]; +#endif + + [self->template takeValuesFromRequest:_req inContext:_ctx]; + + [_ctx removeObjectForKey:UIxTabView_BODY]; + [_ctx deleteLastElementIDComponent]; // activeKey + [_ctx deleteLastElementIDComponent]; /* 'b' */ + [self restoreNestedState:nestedState inContext:_ctx]; +} + +- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx { + NSString *key; + id result; + id nestedState; + + if ((key = [_ctx currentElementID]) == nil) + return nil; + + result = nil; + nestedState = [self saveNestedStateInContext:_ctx]; + + if ([key isEqualToString:@"h"]) { + /* header action */ + //NSString *urlKey; + + [_ctx consumeElementID]; + [_ctx appendElementIDComponent:@"h"]; +#if 0 + if ((urlKey = [_ctx currentElementID]) == nil) { + [[_ctx application] + debugWithFormat:@"missing active head tab key !"]; + } + else { + //NSLog(@"clicked: %@", urlKey); + [_ctx consumeElementID]; + [_ctx appendElementIDComponent:urlKey]; + } +#endif + + [_ctx setObject:self->selection forKey:UIxTabView_HEAD]; + result = [self->template invokeActionForRequest:_req inContext:_ctx]; + [_ctx removeObjectForKey:UIxTabView_HEAD]; + +#if 0 + if (urlKey) + [_ctx deleteLastElementIDComponent]; // active key +#endif + [_ctx deleteLastElementIDComponent]; // 'h' + } + else if ([key isEqualToString:@"b"]) { + /* body action */ + NSString *activeTabKey, *urlKey; + + [_ctx consumeElementID]; + [_ctx appendElementIDComponent:@"b"]; + + if ((urlKey = [_ctx currentElementID]) == nil) { + [[_ctx application] + debugWithFormat:@"missing active body tab key !"]; + } + else { + //NSLog(@"clicked: %@", urlKey); + [_ctx consumeElementID]; + [_ctx appendElementIDComponent:urlKey]; + } + + activeTabKey = [self->selection stringValueInComponent:[_ctx component]]; + [_ctx setObject:activeTabKey forKey:UIxTabView_BODY]; + + result = [self->template invokeActionForRequest:_req inContext:_ctx]; + + [_ctx removeObjectForKey:UIxTabView_BODY]; + + if (urlKey) + [_ctx deleteLastElementIDComponent]; // active key + [_ctx deleteLastElementIDComponent]; // 'b' + } + else { + [[_ctx application] + debugWithFormat:@"unknown tab container key '%@'", key]; + } + + [self restoreNestedState:nestedState inContext:_ctx]; + return result; +} + +- (NSString *)_tabViewCountInContext:(WOContext *)_ctx { + int count; + count = [[_ctx valueForKey:@"UIxTabViewScriptDone"] intValue]; + return [NSString stringWithFormat:@"%d",count]; +} + +- (NSString *)scriptHref:(UIxTabItemInfo *)_info + inContext:(WOContext *)_ctx + isLeft:(BOOL)_isLeft + keys:(NSArray *)_keys +{ + NSMutableString *result = [NSMutableString string]; + UIxTabItemInfo *tmp; + NSString *activeKey; + int i, cnt; + NSString *elID; + NSString *tstring; + + activeKey = [self->selection stringValueInComponent:[_ctx component]]; + [result appendString:@"JavaScript:showTab("]; + [result appendString:_info->key]; + [result appendString:@"Tab);"]; + + [result appendString:@"swapCorners("]; + tstring = (!_isLeft) + ? @"tabCorner%@,tabCornerLeft%@);" + : @"tabCornerLeft%@,tabCorner%@);"; + elID = [self _tabViewCountInContext:_ctx]; + [result appendString:[NSString stringWithFormat:tstring,elID,elID]]; + + for (i=0, cnt = [_keys count]; i < cnt; i++) { + tmp = [_keys objectAtIndex:i]; + + if ((tmp->isScript || [tmp->key isEqualToString:activeKey]) + && ![tmp->key isEqualToString:_info->key]) { + [result appendString:@"hideTab("]; + [result appendString:tmp->key]; + [result appendString:@"Tab);"]; + } + } + return result; +} + +- (void)appendLink:(UIxTabItemInfo *)_info + toResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + isActive:(BOOL)_isActive isLeft:(BOOL)_isLeft + doScript:(BOOL)_doScript keys:(NSArray *)_keys +{ + NSString *headUri = nil; + NSString *label = nil; + NSString *scriptHref = nil; + NSString *styleName = nil; + + WEClientCapabilities *ccaps; + WOComponent *comp; + + ccaps = [[_ctx request] clientCapabilities]; + + comp = [_ctx component]; + headUri = _info->uri; + + if ((label = _info->label) == nil) + label = _info->key; + + if (_isActive) { + styleName = (_info->selectedTabStyle) + ? _info->selectedTabStyle + : [self->selectedTabStyle stringValueInComponent:comp]; + } + else { + styleName = (_info->tabStyle) + ? _info->tabStyle + : [self->tabStyle stringValueInComponent:comp]; + } + + [_response appendContentString:@"']; + + [_response appendContentString:@"isScript || _isActive)) { + scriptHref = + [self scriptHref:_info inContext:_ctx isLeft:_isLeft keys:_keys]; + [_response appendContentHTMLAttributeValue:scriptHref]; + } + else { + [_response appendContentHTMLAttributeValue:headUri]; + } + + [_response appendContentString:@"\" "]; + [_response appendContentString: + [NSString stringWithFormat:@"name='%@TabLink'", _info->key]]; + [_response appendContentString:@">"]; + + if ([label length] < 1) + label = _info->key; + [_response appendContentString:@""]; + [_response appendContentHTMLString:label]; + [_response appendContentString:@""]; + + [_response appendContentString:@""]; + + [_response appendContentString:@""]; + +#if 0 + if (_doScript && (_info->isScript || _isActive)) { + NSString *k; // key + NSString *s; // selected tab icon + NSString *u; // unselected tab icon + //NSString *out; + + k = _info->key; + s = _info->selIcon; // selectedTabIcon + u = (_isLeft) ? _info->leftIcon : _info->tabIcon; + + s = WEUriOfResource(s, _ctx); + u = WEUriOfResource(u, _ctx); + + s = ([s length] < 1) ? imgUri : s; + u = ([u length] < 1) ? imgUri : u; + +#if 0 + out = [NSString alloc]; + out = [out initWithFormat: + @"", + k, k, k, k, scriptHref, k, headUri, + k, k, k, k, + k, u, k, k, s + ]; + + [_response appendContentString:out]; + RELEASE(out); +#else +# define _appendStr_(_str_) [_response appendContentString:_str_] + _appendStr_(@""); +#undef _appendStr_ +#endif + } +#endif +} + +- (void)appendSubmitButton:(UIxTabItemInfo *)_info + toResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + isActive:(BOOL)_isActive isLeft:(BOOL)_left + doScript:(BOOL)_doScript keys:(NSArray *)_keys +{ + [self appendLink:_info + toResponse:_response + inContext:_ctx + isActive:_isActive isLeft:_left + doScript:_doScript keys:_keys]; +} + +- (void)_appendTabViewJSScriptToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx +{ + [_response appendContentString: + @""]; +} + +- (void)_appendHeaderRowToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + keys:(NSArray *)keys activeKey:(NSString *)activeKey + doScript:(BOOL)doScript +{ + unsigned i, count; + BOOL doForm; + NSString *styleName; + + doForm = NO; /* generate form controls ? */ + + [_response appendContentString:@""]; + + styleName = [self->headerStyle stringValueInComponent:[_ctx component]]; + if(styleName) { + [_response appendContentString: + @""]; + } + else { + [_response appendContentString: + @"
"]; + } + + for (i = 0, count = [keys count]; i < count; i++) { + UIxTabItemInfo *info; + NSString *key; + BOOL isActive; + + info = [keys objectAtIndex:i]; + key = info->key; + isActive = [key isEqualToString:activeKey]; + + [_ctx appendElementIDComponent:key]; + + if (doForm) { + /* tab is inside of a FORM, so produce submit buttons */ + [self appendSubmitButton:info + toResponse:_response + inContext:_ctx + isActive:isActive + isLeft:(i == 0) ? YES : NO + doScript:doScript + keys:keys]; + } + else { + /* tab is not in a FORM, generate hyperlinks for tab */ + [self appendLink:info + toResponse:_response + inContext:_ctx + isActive:isActive + isLeft:(i == 0) ? YES : NO + doScript:doScript + keys:keys]; + } + + [_ctx deleteLastElementIDComponent]; + } + // [_response appendContentString:@""]; + [_response appendContentString:@"
"]; + [_response appendContentString:@""]; +} + +- (void)_appendHeaderFootRowToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + bgcolor:(NSString *)bgcolor + doScript:(BOOL)doScript + isLeftActive:(BOOL)isLeftActive +{ + NSString *styleName; + [_response appendContentString:@" bodyStyle stringValueInComponent:[_ctx component]]; + if(styleName) { + [_response appendContentString:@" class='"]; + [_response appendContentHTMLAttributeValue:styleName]; + [_response appendContentCharacter:'\'']; + } + if (bgcolor) { + [_response appendContentString:@" bgcolor=\""]; + [_response appendContentHTMLAttributeValue:bgcolor]; + [_response appendContentString:@"\""]; + } + [_response appendContentString:@">\n"]; + + /* left corner */ + [_response appendContentString:@" "]; + + if (doScript) { + [_response appendContentString:@"
"]; + [_response appendContentString:@" "]; + [_response appendContentString:@"
"]; + } + else if (isLeftActive) + [_response appendContentString:@" "]; + + if (doScript) { + [_response appendContentString:@"
"]; + } + + if (!isLeftActive || doScript) { + NSString *uri; + + uri = [self->leftCornerIcon stringValueInComponent:[_ctx component]]; + if ((uri = WEUriOfResource(uri, _ctx))) { + [_response appendContentString:@"\"\""]; + } + else + [_response appendContentString:@" "]; + } + if (doScript) + [_response appendContentString:@"
"]; + + [_response appendContentString:@"\n"]; + + /* right corner */ + [_response appendContentString:@" "]; + { + NSString *uri; + + uri = [self->rightCornerIcon stringValueInComponent:[_ctx component]]; + if ((uri = WEUriOfResource(uri, _ctx))) { + [_response appendContentString:@"\"\""]; + } + else + [_response appendContentString:@" "]; + } + [_response appendContentString:@"\n"]; + + [_response appendContentString:@" \n"]; +} + +- (void)_appendBodyRowToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx + bgcolor:(NSString *)bgcolor + activeKey:(NSString *)activeKey +{ + WEClientCapabilities *ccaps; + BOOL indentContent; + NSString *styleName; + + styleName = [self->bodyStyle stringValueInComponent:[_ctx component]]; + ccaps = [[_ctx request] clientCapabilities]; + + /* put additional padding table into content ??? */ + indentContent = [ccaps isFastTableBrowser] && ![ccaps isTextModeBrowser]; + + [_response appendContentString:@"']; + + if (indentContent) { + /* start padding table */ + [_response appendContentString: + @""]; + [_response appendContentString:@"
"]; + } + + [_ctx appendElementIDComponent:@"b"]; + [_ctx appendElementIDComponent:activeKey]; + + /* generate currently active body */ + { + [_ctx setObject:activeKey forKey:UIxTabView_BODY]; + [self->template appendToResponse:_response inContext:_ctx]; + [_ctx removeObjectForKey:UIxTabView_BODY]; + } + + [_ctx deleteLastElementIDComponent]; // activeKey + [_ctx deleteLastElementIDComponent]; // 'b' + + if (indentContent) + /* close padding table */ + [_response appendContentString:@"
"]; + + [_response appendContentString:@""]; +} + +- (BOOL)isLeftActiveInKeys:(NSArray *)keys activeKey:(NSString *)activeKey{ + unsigned i, count; + BOOL isLeftActive; + + isLeftActive = NO; + + for (i = 0, count = [keys count]; i < count; i++) { + UIxTabItemInfo *info; + + info = [keys objectAtIndex:i]; + + if ((i == 0) && [info->key isEqualToString:activeKey]) + isLeftActive = YES; + } + + return isLeftActive; +} + +- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + WOComponent *cmp; + NSString *bgcolor; + BOOL isLeftActive; + BOOL doScript; + id nestedState; + NSString *activeKey; + NSArray *keys; + int tabViewCount; /* used for image id's and writing script once */ + + doScript = NO; /* perform tab-clicks on browser (use javascript) */ + tabViewCount = [[_ctx valueForKey:@"UIxTabViewScriptDone"] intValue]; + cmp = [_ctx component]; + + /* check for browser */ + { + WEClientCapabilities *ccaps; + //BOOL isJavaScriptBrowser; + + ccaps = [[_ctx request] clientCapabilities]; + doScript = [ccaps isInternetExplorer] && [ccaps isJavaScriptBrowser]; + doScript = (doScript && + [[[cmp session] + valueForKey:@"isJavaScriptEnabled"] boolValue]); + } + + /* disable javascript */ + doScript = NO; + + /* save state */ + + nestedState = [self saveNestedStateInContext:_ctx]; + + /* configure */ + + activeKey = [self->selection stringValueInComponent:cmp]; + + bgcolor = [self->bgColor stringValueInComponent:cmp]; + bgcolor = [bgcolor stringValue]; + + [_ctx appendElementIDComponent:@"h"]; + + /* collect & process keys (= available tabs) */ + + keys = [self collectKeysInContext:_ctx]; + + if (![[keys valueForKey:@"key"] containsObject:activeKey]) + /* selection is not available in keys */ + activeKey = nil; + + if ((activeKey == nil) && ([keys count] > 0)) { + /* no or invalid selection, use first key */ + activeKey = [[keys objectAtIndex:0] key]; + if ([self->selection isValueSettable]) + [self->selection setValue:activeKey inComponent:[_ctx component]]; + } + + if (doScript) { + doScript = [[keys valueForKey:@"isScript"] containsObject:YesNumber]; + [_ctx setObject:[NSNumber numberWithBool:doScript] + forKey:UIxTabView_SCRIPT]; + } + + /* start appending */ + + if ((doScript) && (tabViewCount == 0)) + [self _appendTabViewJSScriptToResponse:_response inContext:_ctx]; + + /* count up for unique tabCorner/tabCornerLeft images */ + [_ctx takeValue:[NSNumber numberWithInt:(tabViewCount + 1)] + forKey:@"UIxTabViewScriptDone"]; + + [_response appendContentString: + @""]; + + /* find out whether left is active */ + + isLeftActive = [self isLeftActiveInKeys:keys activeKey:activeKey]; + + /* generate header row */ + + [self _appendHeaderRowToResponse:_response inContext:_ctx + keys:keys activeKey:activeKey + doScript:doScript]; + + [_ctx deleteLastElementIDComponent]; // 'h' for head + [_ctx removeObjectForKey:UIxTabView_HEAD]; + +#if 0 + /* header foot row */ + + [self _appendHeaderFootRowToResponse:_response inContext:_ctx + bgcolor:bgcolor + doScript:doScript + isLeftActive:isLeftActive]; +#endif + + /* body row */ + + [self _appendBodyRowToResponse:_response inContext:_ctx + bgcolor:bgcolor + activeKey:activeKey]; + + /* close table */ + + [_response appendContentString:@"
"]; + [_ctx removeObjectForKey:UIxTabView_ACTIVEKEY]; + [_ctx removeObjectForKey:UIxTabView_KEYS]; + [self restoreNestedState:nestedState inContext:_ctx]; +} + +@end /* UIxTabView */ diff --git a/SOGo/UI/Common/UIxWinClose.m b/SOGo/UI/Common/UIxWinClose.m new file mode 100644 index 00000000..e8320e69 --- /dev/null +++ b/SOGo/UI/Common/UIxWinClose.m @@ -0,0 +1,37 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + + +#include + + +@interface UIxWinClose : WOComponent +{ + +} + +@end + + +@implementation UIxWinClose + +@end diff --git a/SOGo/UI/Common/UIxWinClose.wox b/SOGo/UI/Common/UIxWinClose.wox new file mode 100644 index 00000000..35769e42 --- /dev/null +++ b/SOGo/UI/Common/UIxWinClose.wox @@ -0,0 +1,6 @@ + +X diff --git a/SOGo/UI/Common/Version b/SOGo/UI/Common/Version new file mode 100644 index 00000000..d64ce5ad --- /dev/null +++ b/SOGo/UI/Common/Version @@ -0,0 +1,5 @@ +# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $ + +SUBMINOR_VERSION:=1 + +# 1.1.0 requires NGObjWeb 4.2.202 diff --git a/SOGo/UI/Common/bundle-info.plist b/SOGo/UI/Common/bundle-info.plist new file mode 100644 index 00000000..c7081c18 --- /dev/null +++ b/SOGo/UI/Common/bundle-info.plist @@ -0,0 +1,40 @@ +{ + "__cvs__" = "$Id: bundle-info.plist,v 1.1 2003/11/24 01:24:40 helge Exp $"; + + requires = { + bundleManagerVersion = 1; + classes = ( + { name = NSObject; } + ); + }; + + provides = { + ZideStoreProducts = ( { name = CommonUIProduct; } ); + + classes = ( + { name = CommonUIProduct; }, + { name = UIxComponent; }, + { name = UIxPageFrame; }, + { name = UIxWinClose; }, + { name = UIxAppNavView; }, + { name = "UIxElemBuilder"; }, + { name = "UIxTabView"; }, + { name = "UIxTabItem"; }, + ); + + WOComponents = ( + { name = UIxPageFrame; }, + { name = UIxWinClose; }, + { name = UIxAppNavView; }, + ); + + WOxElemBuilder = ( + { name = "UIxElemBuilder"; }, + ); + + WODynamicElements = ( + { name = "UIxTabView"; }, + { name = "UIxTabItem"; }, + ); + }; +} diff --git a/SOGo/UI/Common/calendar.css b/SOGo/UI/Common/calendar.css new file mode 100644 index 00000000..34553bb4 --- /dev/null +++ b/SOGo/UI/Common/calendar.css @@ -0,0 +1,189 @@ +.aptview_title { + font-size: 10pt; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + color: #000000; + font-weight: bold; +} + +.aptview_text { + font-size: 10pt; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + color: #000000; +} + +.weekoverview_title { + font-size: 10pt; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + letter-spacing: 0pt; + color: #000000; + background-color: #d2d2cc; +} + +.weekoverview_title a { + color: #0033cc; + text-decoration: none; +} + +.weekoverview_title_hilite { + font-size: 10pt; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + letter-spacing: 0pt; + color: #000000; + background-color: #d2d2cc; + font-weight: bold; +} + +.weekoverview_title_hilite a { + color: #0033cc; + text-decoration: none; +} + +.weekoverview_title_daylink { + font-size: 12pt; + color: #0033cc; + font-weight: bold; +} + +.weekoverview_title_newlink { + font-size: 8pt; +} + +.weekoverview_holidayinfo { + font-size: 8pt; + font-weight: bold; +} + +.weekoverview_content { + color: #FFFFFF; + background-color: #e8e8e0; +} + +.weekoverview_content a { + color: #0000FF; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + letter-spacing: 0pt; + text-decoration: none; +} + +.weekoverview_content_hilite { + background-color: #fffff0; +} + +.weekoverview_content_hilite a { + color: #0000FF; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + letter-spacing: 0pt; + text-decoration: none; +} + +.monthoverview { + color: #000000; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 10pt; + letter-spacing: 0pt; + padding: 2px; +} + +.monthoverview a { + color: #0033cc; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 7pt; + font-style: normal; + font-weight: normal; + letter-spacing: 0pt; + text-decoration: none; +} + +.monthoverview a:hover { + text-decoration: underline; +} + +.monthoverview_title { + background-color: #d2d2cc; + text-align: center; +} + +.monthoverview_week { + background-color: #d2d2cc; + width: 16pt; + text-align: center; + vertical-align: middle; +} + +.monthoverview_week a { + color: #000000; + font-size: 10pt; +} + +.monthoverview_week_hilite { + background-color: #fffff0; + width: 16pt; + text-align: center; + vertical-align: middle; +} + +.monthoverview_week_hilite a { + color: #000000; + font-size: 10pt; +} + +.monthoverview_content { + background-color: #e8e8e0; + font-size: 9pt; + height: 60; +} + +.monthoverview_content a { + font-style: italic; + font-weight: bold; +} + +.monthoverview_content td { + text-align: let; + vertical-align: top; +} + + +.monthoverview_content_hilite { + background-color: #fffff0; + font-size: 9pt; + height: 60; +} + +.monthoverview_content_hilite a { + font-style: italic; + font-weight: bold; +} + +.monthoverview_content_dimmed { + background-color: #d2d2cc; + font-size: 9pt; + height: 60; +} + +.monthoverview_content_dimmed a { + font-style: normal; + font-weight: normal; +} + +.monthoverview_day a { + color: #000000; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 12pt; +} + +.monthoverview_day_new a { + font-style: normal; + font-weight: normal; +} + +.monthoverview_day_new a:hover { + font-style: normal; + font-weight: normal; + color: #ff0000; +} + +.monthoverview_content_link { + font-style: normal; + font-weight: normal; +} diff --git a/SOGo/UI/Common/common.h b/SOGo/UI/Common/common.h new file mode 100644 index 00000000..ea759a93 --- /dev/null +++ b/SOGo/UI/Common/common.h @@ -0,0 +1,155 @@ +/* + Copyright (C) 2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id: common.h,v 1.1 2003/11/24 01:24:40 helge Exp $ + +#import + +#if LIB_FOUNDATION_LIBRARY +# include +#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY +# include +# include +#endif + +#include +#include +#include + +@interface WOContext(WOExtensionsPrivate) +- (void)addActiveFormElement:(WOElement *)_element; +@end + +static inline id WOExtGetProperty(NSDictionary *_set, NSString *_name) { + id propValue = [_set objectForKey:_name]; + + if (propValue) { + propValue = [propValue retain]; + [(NSMutableDictionary *)_set removeObjectForKey:_name]; + } + return propValue; +} + +static inline NSString *WEUriOfResource(NSString *_name, WOContext *_ctx) { + NSArray *languages; + WOResourceManager *resourceManager; + NSString *uri; + + if (_name == nil) + return nil; + + languages = [_ctx hasSession] + ? [[_ctx session] languages] + : [[_ctx request] browserLanguages]; + + resourceManager = [[_ctx application] resourceManager]; + + uri = [resourceManager urlForResourceNamed:_name + inFramework:nil + languages:languages + request:[_ctx request]]; + if ([uri rangeOfString:@"/missingresource?"].length > 0) + uri = nil; + + return uri; +} + +static inline void WEAppendFont(WOResponse *_resp, + NSString *_color, + NSString *_face, + NSString *_size) +{ + [_resp appendContentString:@"']; +} + +static inline void WEAppendTD(WOResponse *_resp, + NSString *_align, + NSString *_valign, + NSString *_bgColor) +{ + [_resp appendContentString:@"']; +} + +static inline WOElement *WECreateElement(NSString *_className, + NSString *_name, + NSDictionary *_config, + WOElement *_template) +{ + Class c; + WOElement *result = nil; + NSMutableDictionary *config = nil; + + if ((c = NSClassFromString(_className)) == Nil) { + NSLog(@"%s: missing '%@' class", __PRETTY_FUNCTION__, _className); + return nil; + } + config = [NSMutableDictionary dictionaryWithCapacity:4]; + { + NSEnumerator *keyEnum; + id key; + + keyEnum = [_config keyEnumerator]; + + while ((key = [keyEnum nextObject])) { + WOAssociation *a; + + a = [WOAssociation associationWithValue:[_config objectForKey:key]]; + [config setObject:a forKey:key]; + } + } + result = [[c alloc] initWithName:_name + associations:config + template:_template]; + return [result autorelease]; +} + +#define OWGetProperty WOExtGetProperty diff --git a/SOGo/UI/Common/images/OGoLogo.gif b/SOGo/UI/Common/images/OGoLogo.gif new file mode 100755 index 0000000000000000000000000000000000000000..ea1b5f5551ab4b07432a323d084cc8174cb61549 GIT binary patch literal 2047 zcmcJM`&ZI=0){^zauLukh)PNmWEmz?plI4y3wVjJ3szQ|84{I}oi28_owz0lId~0= zP6#xav1a8|Q{j>$NfxHl*u^|#*0IYHVOvgn&aSTeN9=pvU*B_{^SsNJXQ!qWUkBfT zdjL#LO*!s)mCY{QbkBM`PsaRyzvGresa5LKy7(0)G+PJQN-t6UaGL( z)aDUy6Wcqzt|w#U%=&ntDV`c%aG*mfcX)muV{JB7$d%$!F?W|uD(|p&4*EY&2uf`Q zN9^KV`#!Z>ra6b@dJP@r?M2 z8dpVwL#m#p@*}H)i`ABX?n2AOR&C;GY^)k#!loICFlA6%Y*W)IoN<;Br-V7NsaA|4-3ECq zXa(A;LRkx}D5W*dN>Tn{5m*KJ7B5733*|iK^*zE2DxQwp6ve zhfitv+MtzZgiVGp&zFb@bwS0Bq1JX(ahBz@MdaNimVHX$vOj5C6-3#vnUyCE6eD_3Zo;9@p2QLx zz0&}jvwl&@Ka&8(G#6%Qi)OD)r;*NAZd`}U$U@+qD@$M>U#t9)R+Yz+QsX8AnIsSY z3J$d>E?|b`h7z-C(cRQ%#Pq`4)$m0jwW?Y`mLbw1=3e8mzln%1OPd}VF!+B-_8EeW zXr>!)a<}L11ey^+qJ{GWR;@Y6>?QIkA{RXhH+y6F*8?c-fyWJLAz|wfaqb<^I??-x zETSSVEc>Iu11yd#&dg-=mgkf|Uz{IOt@VUj3PD}G1;Fq>J)3RlMp}IRA8)We zI+dO2z638^&0zZSea#V!+2OZ7=fo`pV4xD;vgaWpc{0_f3rYMkBx5>B*D#Db@hAM3 z9y0{bQ>vPisz~XnPy6(s|3Ur|Tc(tP;OTM0j&Ie!Bf=Ep{Z4oWKj5O$_<=|HFyUN2 zhWv9^&Q(H{D=Ibb5^)O*d&l_osi^Y%iDwclSq6e2A!krcyS4rKo($q$#u-tfJOhX$ z!@~Fe=|CfUBr+YcvBV-jevI1=OGWN)Z?gZmY$+e%=W^Sfi*xdJtn7z)tH7SxgBlCdN{ol z%@dh|L1>8#x3pb5d{bLvdB!=sC(6Vzjh-wrZQ=EsF~F-_yn>XVFCA9lo{aWAA#-;3 zwOpVU9Sxfp4`u$ElfO^gesM3Cn*QL+^S+z0XzsnOsFcH5QDlyc@U9CL%UGX~XqL(_ zqK5<+{{^7t>$f7zpmft2niP`b@y_5{rqc+?WJ4?-Mnkkvs|{)d)Dt}<+qr3VaTCJ% zkbtD~>W2%^sDA^l-t8O^zRFG%_z5>Ee6&cB99H;wpPz7E5(9g5V^<_m4!{rp1)>R% A`2YX_ literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/box_botleft.gif b/SOGo/UI/Common/images/box_botleft.gif new file mode 100644 index 0000000000000000000000000000000000000000..edaa19035f05f7297deaacc8c649121b3ac61d6b GIT binary patch literal 100 zcmZ?wbhEHb(_Vg+_`Gis-;VpPMbC@Gcz+ZG}O(_4Xgw~ o=zy3Yy$mdp0xh1*R;AOXG<&$ZYdEKCB)X|^hH(_Vg+_`Gis-;VpPMbC@Gcz+ZG}O(_4Xgw~ q=zy3Yy$meU1}7vLrn29ia7wq+ftSlsw98P|Gs%k~s3Vw#!5RQ3XdaFL literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/box_bottom.gif b/SOGo/UI/Common/images/box_bottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..c63a9cf945095116016b61fa61625058a83474d5 GIT binary patch literal 43 scmZ?wbhEHb(_Vg+_`Gis-;VpPMbC@Gcz+ZG}O(_4Xgw~ q=zy3Yy$meU1}7A_m?keNSr&LyMBtPHm#2nUr-tI(?wyV-4AuZFzaMJ= literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/box_topright.gif b/SOGo/UI/Common/images/box_topright.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b3ca17b84e44500138bba6c5044721aa2c5723d GIT binary patch literal 101 zcmZ?wbhEHb(_Vg+_`Gis-;VpPMbC@Gcz+ZG}O(_4Xgw~ p=zy3Yy$mc;0t=LywyLWZDzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/line_left.gif b/SOGo/UI/Common/images/line_left.gif new file mode 100644 index 0000000000000000000000000000000000000000..19415f34782520e996dfae64708d20ff3c147f23 GIT binary patch literal 264 zcmZ?wbhEHb)L>v_xXJ(m|NsC0_wWDTzyF@U{_^bAXJNaE5>As+ zyG@mGn=0=)UCDcfn%^wF(0Pt2%iJH-x*@J+OM3H;{H{HflMYr)JkYc7 z+Z^ zfx(hN2P6ve69b#-fd+>3oi{UDBvsjFd&I31<6h*o(2wtu$B~E@p^pCc%@;F_+7uY9 E0a6QnAs+ zyG@mGn=0=)UCDcfn%^wF(0Pt2%iJH-x*@J+OM3H;{H{HflMYr)JkYc7 z+Z^ zfx(hN2P6ve69b#FgU_=KFDvX8v?LwO=As+ zyG@mGn=0=)UCDcfn%^wF(0Pt2%iJH-x*@J+OM3H;{H{HflMYr)JkYc7 z+Z^ Yfx(hN2P6ve69XIjfo{i+gFs$NfxHl*u^|#*0IYHVOvgn&aSTeN9=pvU*B_{^SsNJXQ!qWUkBfT zdjL#LO*!s)mCY{QbkBM`PsaRyzvGresa5LKy7(0)G+PJQN-t6UaGL( z)aDUy6Wcqzt|w#U%=&ntDV`c%aG*mfcX)muV{JB7$d%$!F?W|uD(|p&4*EY&2uf`Q zN9^KV`#!Z>ra6b@dJP@r?M2 z8dpVwL#m#p@*}H)i`ABX?n2AOR&C;GY^)k#!loICFlA6%Y*W)IoN<;Br-V7NsaA|4-3ECq zXa(A;LRkx}D5W*dN>Tn{5m*KJ7B5733*|iK^*zE2DxQwp6ve zhfitv+MtzZgiVGp&zFb@bwS0Bq1JX(ahBz@MdaNimVHX$vOj5C6-3#vnUyCE6eD_3Zo;9@p2QLx zz0&}jvwl&@Ka&8(G#6%Qi)OD)r;*NAZd`}U$U@+qD@$M>U#t9)R+Yz+QsX8AnIsSY z3J$d>E?|b`h7z-C(cRQ%#Pq`4)$m0jwW?Y`mLbw1=3e8mzln%1OPd}VF!+B-_8EeW zXr>!)a<}L11ey^+qJ{GWR;@Y6>?QIkA{RXhH+y6F*8?c-fyWJLAz|wfaqb<^I??-x zETSSVEc>Iu11yd#&dg-=mgkf|Uz{IOt@VUj3PD}G1;Fq>J)3RlMp}IRA8)We zI+dO2z638^&0zZSea#V!+2OZ7=fo`pV4xD;vgaWpc{0_f3rYMkBx5>B*D#Db@hAM3 z9y0{bQ>vPisz~XnPy6(s|3Ur|Tc(tP;OTM0j&Ie!Bf=Ep{Z4oWKj5O$_<=|HFyUN2 zhWv9^&Q(H{D=Ibb5^)O*d&l_osi^Y%iDwclSq6e2A!krcyS4rKo($q$#u-tfJOhX$ z!@~Fe=|CfUBr+YcvBV-jevI1=OGWN)Z?gZmY$+e%=W^Sfi*xdJtn7z)tH7SxgBlCdN{ol z%@dh|L1>8#x3pb5d{bLvdB!=sC(6Vzjh-wrZQ=EsF~F-_yn>XVFCA9lo{aWAA#-;3 zwOpVU9Sxfp4`u$ElfO^gesM3Cn*QL+^S+z0XzsnOsFcH5QDlyc@U9CL%UGX~XqL(_ zqK5<+{{^7t>$f7zpmft2niP`b@y_5{rqc+?WJ4?-Mnkkvs|{)d)Dt}<+qr3VaTCJ% zkbtD~>W2%^sDA^l-t8O^zRFG%_z5>Ee6&cB99H;wpPz7E5(9g5V^<_m4!{rp1)>R% A`2YX_ literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/tab_.gif b/SOGo/UI/Common/images/tab_.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad720a0c634d7e8c6ffc3490b425e8d261312f82 GIT binary patch literal 127 zcmZ?wbhEHbOl1&bn8*ME|NsAIGwFWu;(-o`2NGvsikQ;B^7LDNW$wfq-J9?2`OV)p z+oAJW=Q7R6mG8J`=lERzmh=2q=lg%_Uoy7aDSnJFR+_G-`dL%kak-7=*I$K6+r@On dU;hm{oTRbyjLqVSuS_?-WjplP)r*nA8UXE_I41xA literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/images/tab_selected.gif b/SOGo/UI/Common/images/tab_selected.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cbdea66a508c7d581fa1f4775de5bbb2e253b97 GIT binary patch literal 127 zcmZ?wbhEHbOl1&bn8*ME|NsAIGwJ^N^`#Do2NGvsikQ;B^7LDNW$wfq-J9?2`OV)p z+oAJW=Q7R6mG8J`=lERzmh=2q=lg%_Uoy7aDSnJFR+_G-`dL%kak-7=*I$K6+r@On dU;hm{oTRbyjLqVSuS_?-WjplP)r*nA8UXv)I7$Ej literal 0 HcmV?d00001 diff --git a/SOGo/UI/Common/product.plist b/SOGo/UI/Common/product.plist new file mode 100644 index 00000000..1636c420 --- /dev/null +++ b/SOGo/UI/Common/product.plist @@ -0,0 +1,47 @@ +{ + requires = ( MAIN ); + + publicResources = ( + calendar.css, + zidestoreui.css, + menu_logo_top.gif, + line_left.gif, + line_stretch.gif, + line_right.gif, + box_topleft.gif, + box_top.gif, + box_topright.gif, + box_left.gif, + box_right.gif, + box_botleft.gif, + box_bottom.gif, + box_botright.gif, + tab_selected.gif, + tab_.gif, + corner_right.gif, + closewindow.gif, + OGoLogo.gif + ); + + factories = { + }; + + categories = { + SxFolder = { + methods = { + "app" = { + protectedBy = "View"; + pageName = "UIxAppFrame"; + }; + "appheader" = { + protectedBy = "View"; + pageName = "UIxAppHeader"; + }; + "appnavigation" = { + protectedBy = "View"; + pageName = "UIxAppNavigation"; + }; + }; + }; + }; +} diff --git a/SOGo/UI/Common/zidestoreui.css b/SOGo/UI/Common/zidestoreui.css new file mode 100644 index 00000000..5d1e878c --- /dev/null +++ b/SOGo/UI/Common/zidestoreui.css @@ -0,0 +1,199 @@ +/* ZideStore UI Stylesheet */ + +/* common stuff */ + +body { + color: #000000; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 10pt; + background-color: #FFFFFF; + margin: 0px; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; +} + +a:link { + color: #0033CC; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + text-decoration: none; +} +a:visited { + color: #660066; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + text-decoration: none; +} +a:hover { + color: #FF0000; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + text-decoration: underline; +} + +.linecolor { + background-color: #06348B; +} + +font.defaultfont { + text-decoration: none; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 8pt; + color: #000000; +} + +.window_label { + color: #06348b; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 12pt; + font-weight: bold; +} + + +/* tabs */ + +.tab { + color: #000000; + background-color: #e8e8e0; + font-size: 10pt; + text-decoration: none; + width: 100px; + height: 22px; + border-top: 1px solid #06348b; + border-right: 1px solid #06348b; +} + +.tab a { + color: #000000; + border: none; + text-decoration: none; +} + +.tab_selected { + color: #000000; + background-color: #f5f5e9; + font-size: 10pt; + text-decoration: none; + font-weight: bold; + width: 100px; + height: 22px; + border-top: 1px solid #06348b; + border-right: 1px solid #06348b; +} + +.tab_selected a { + color: #000000; + border: none; + text-decoration: none; +} + +.tabview_body { + background-color: #f5f5e9; +} + + +/* buttons */ + +.button_auto_env { + height: 16px; + text-align: center; + vertical-align: middle; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; + overflow: hidden; +} + +.button_auto_env a { + text-decoration: none; + color: #000000; +} + +.button_auto_env a:hover { + text-decoration: underline; + color: #ff0000; +} + +.button_auto { + height: 20px; + border-style: outset; + border-color: #DDDDDD; + border-width: 2px; + color: #000000; + background-color: #e8e8e0; + font-size: 8pt; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + letter-spacing: 0pt; + text-decoration: none; + text-color: #000000; + text-align: center; + vertical-align: middle; + padding-left: 5px; + padding-right: 5px; + padding-top: 1px; + padding-bottom: 1px; + overflow: hidden; +} + + +/* header */ + +div#header { + margin-left: 5px; + margin-right: 5px; + padding: 0; + border-bottom: 1px solid #000000; +} +div#header img.headerlogo { + float: right; + width: 182px; + height: 30px; +} + +div#header div#headerhistory { + font-size: 11px; + color: #000000; + margin: 0px; + padding-top: 18px; + height: 12px; +} +div#header a, div#header span { + margin: 0px; +} +div#header span#navtitle { + font-weight: bold; +} +div#header a:hover { + text-decoration: none; +} + +/* the dock */ + +a.skydockfont { + text-decoration: none; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 8pt; + color: #06348B; +} +font.skydockfont { + text-decoration: none; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 8pt; + color: #06348B; +} +font.skydockfont_inactiveMail { + text-decoration: none; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 8pt; + color: #CCCCCC; + font-weight: bold; +} +font.skydockfont_newMail { + text-decoration: none; + font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + font-size: 8pt; + color: #06348B; + font-weight: bold; +} +table.skytextdocktable { + padding: 0px; + table-layout: auto; +} diff --git a/SOGo/UI/GNUmakefile b/SOGo/UI/GNUmakefile new file mode 100644 index 00000000..68855649 --- /dev/null +++ b/SOGo/UI/GNUmakefile @@ -0,0 +1,9 @@ +# $Id$ + +include $(GNUSTEP_MAKEFILES)/common.make + +SUBPROJECTS = \ + Common \ + Scheduler \ + +include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/SOGo/UI/Scheduler/COPYING b/SOGo/UI/Scheduler/COPYING new file mode 100644 index 00000000..161a3d1d --- /dev/null +++ b/SOGo/UI/Scheduler/COPYING @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/SOGo/UI/Scheduler/COPYRIGHT b/SOGo/UI/Scheduler/COPYRIGHT new file mode 100644 index 00000000..1053b2aa --- /dev/null +++ b/SOGo/UI/Scheduler/COPYRIGHT @@ -0,0 +1,4 @@ +Copyright (C) 2004 SKYRIX Software AG + + +Contact: info@skyrix.com diff --git a/SOGo/UI/Scheduler/GNUmakefile b/SOGo/UI/Scheduler/GNUmakefile new file mode 100644 index 00000000..40c6391c --- /dev/null +++ b/SOGo/UI/Scheduler/GNUmakefile @@ -0,0 +1,66 @@ +# $Id: GNUmakefile,v 1.4 2004/06/04 16:15:23 znek Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +BUNDLE_NAME = SchedulerUI +BUNDLE_EXTENSION = .zsp +BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/ZideStore12 + +SchedulerUI_PRINCIPAL_CLASS = SchedulerUIProduct + +SchedulerUI_OBJC_FILES = \ + SchedulerUIProduct.m \ + UIxAppointmentFormatter.m \ + UIxCalView.m \ + UIxCalWeekView.m \ + UIxCalMonthView.m \ + UIxAptTableView.m \ + \ + UIxCalWeekOverview.m \ + UIxCalMonthOverview.m \ + UIxAppointmentView.m \ + UIxAppointmentEditor.m \ + UIxCalSelectTab.m \ + UIxCalDateLabel.m \ + UIxCalBackForthNavView.m \ + +SchedulerUI_RESOURCE_FILES += \ + Version \ + product.plist \ + \ + UIxAptTableView.wox \ + UIxCalWeekOverview.wox \ + UIxCalMonthOverview.wox \ + UIxAppointmentView.wox \ + UIxAppointmentEditor.wox \ + UIxCalSelectTab.wox \ + UIxCalDateLabel.wox \ + UIxCalBackForthNavView.wox \ + images/next_week.gif \ + images/previous_week.gif \ + images/icon_apt_chart.gif \ + images/icon_apt_overview.gif \ + images/icon_apt_chart_inactive.gif \ + images/icon_apt_overview_inactive.gif \ + images/icon_apt_column_view.gif \ + images/icon_apt_list.gif \ + images/icon_apt_list_inactive.gif \ + + +ifeq ($(FOUNDATION_LIB),apple) +ZIDESTORE=$(GNUSTEP_USER_ROOT)/Library/Headers/ZideStore12 +else +ZIDESTORE=$(GNUSTEP_USER_ROOT)/Headers/ZideStore12 +endif + +ADDITIONAL_INCLUDE_DIRS += \ + -I. \ + -I.. \ + -I$(ZIDESTORE)/Frontend -I$(ZIDESTORE)/Backend \ + -I$(ZIDESTORE) -I$(ZIDESTORE)/Common + +# make + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/bundle.make +-include GNUmakefile.postamble diff --git a/SOGo/UI/Scheduler/GNUmakefile.postamble b/SOGo/UI/Scheduler/GNUmakefile.postamble new file mode 100644 index 00000000..3986bcce --- /dev/null +++ b/SOGo/UI/Scheduler/GNUmakefile.postamble @@ -0,0 +1,17 @@ +# $Id: GNUmakefile.postamble,v 1.1 2004/05/12 14:45:56 helge Exp $ + +validate-wox: + xmllint --noout *.wox + +before-all :: validate-wox + + +ifneq ($(GNUSTEP_BUILD_DIR),) +after-all :: + @(cp bundle-info.plist \ + $(GNUSTEP_BUILD_DIR)/$(BUNDLE_NAME)$(BUNDLE_EXTENSION)) +else +after-all :: + @(cd $(BUNDLE_NAME)$(BUNDLE_EXTENSION);\ + cp ../bundle-info.plist .) +endif diff --git a/SOGo/UI/Scheduler/GNUmakefile.preamble b/SOGo/UI/Scheduler/GNUmakefile.preamble new file mode 100644 index 00000000..23c9438a --- /dev/null +++ b/SOGo/UI/Scheduler/GNUmakefile.preamble @@ -0,0 +1,17 @@ +# $Id$ + +ifneq ($(GNUSTEP_BUILD_DIR),) + RELBUILD_DIR_libZideStoreCommonUI = \ + $(GNUSTEP_BUILD_DIR)/../Common/$(GNUSTEP_OBJ_DIR_NAME) +else + RELBUILD_DIR_libZideStoreCommonUI = ../Common +endif + +SchedulerUI_LIB_DIRS += -L$(RELBUILD_DIR_libZideStoreCommonUI) + +SchedulerUI_BUNDLE_LIBS += \ + -lNGObjWeb -lNGScripting -lNGJavaScript -ljs \ + -lNGMime -lNGStreams -lNGExtensions -lEOControl \ + -lXmlRpc -lDOM -lSaxObjC \ + -lSOGoLogic -lZideStoreCommonUI \ + -lNGiCal diff --git a/SOGo/UI/Scheduler/NOTES b/SOGo/UI/Scheduler/NOTES new file mode 100644 index 00000000..35c83b1b --- /dev/null +++ b/SOGo/UI/Scheduler/NOTES @@ -0,0 +1,52 @@ +// $Id: NOTES,v 1.1 2003/11/24 01:24:40 helge Exp $ + +Scheduler +========= + +SOPE based interface for scheduler. + +Class Hierarchy +=============== + + [WOComponent] + [SoComponent] + UIxAppointmentView + UIxCalView + UIxCalMonthView + UIxCalMonthOverview + UIxCalWeekView + UIxCalWeekOverview + UIxAptTableView + SchedulerUIProduct + +TBD: + UIxCalDayView + UIxCalDayOverview + UIxCalDayChart + UIxCalDayHChart + [UIxCalWeekView] + UIxCalWeekColumnView + UIxCalWeekChart + UIxCalWeekHChart + OGoYearOverview - should use aggressive caching in the long run + + - editor page (which comes up in a new window) + - delete page + - print views + +Notes +===== + +editor pages need to use JavaScript to trigger reloads in the parent window +=> find out how to do that + +URLs +==== + +/zidestore/ControlPanel/ => SoControlPanel +/zidestore/ControlPanel/Products => SoProductRegistry +/zidestore/ControlPanel/Products/ZideStoreUI => SoProduct +/zidestore/ControlPanel/Products/ZideStoreUI/Resources/ +=> SoProductResourceManager +/zidestore/ControlPanel/Products/ZideStoreUI/Resources/calendar.css +=> resource diff --git a/SOGo/UI/Scheduler/SchedulerUIProduct.m b/SOGo/UI/Scheduler/SchedulerUIProduct.m new file mode 100644 index 00000000..7666ef0a --- /dev/null +++ b/SOGo/UI/Scheduler/SchedulerUIProduct.m @@ -0,0 +1,34 @@ +/* + Copyright (C) 2000-2003 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id: SchedulerUIProduct.m,v 1.1 2003/11/24 01:24:40 helge Exp $ + +#import + +@interface SchedulerUIProduct : NSObject +{ +} + +@end + +#include "common.h" + +@implementation SchedulerUIProduct +@end /* SchedulerUIProduct */ diff --git a/SOGo/UI/Scheduler/UIxAppointmentEditor.m b/SOGo/UI/Scheduler/UIxAppointmentEditor.m new file mode 100644 index 00000000..5d1ef100 --- /dev/null +++ b/SOGo/UI/Scheduler/UIxAppointmentEditor.m @@ -0,0 +1,277 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ +// $Id$ + + +#include "common.h" +#include +#include +#include + + +/* TODO: CLEAN THIS MESS UP */ + + +@interface NSObject (AppointmentHack) +- (BOOL)isAppointment; +@end + +@implementation NSObject (AppointmentHack) +- (BOOL)isAppointment { + return [self isKindOfClass:NSClassFromString(@"SxAppointment")]; +} +@end + +@interface iCalPerson (Convenience) +- (NSString *)rfc822Email; +@end + +@implementation iCalPerson (Convenience) +- (NSString *)rfc822Email { + NSString *_email = [self email]; + NSRange colon = [_email rangeOfString:@":"]; + if(colon.location != NSNotFound) { + return [_email substringFromIndex:colon.location + 1]; + } + return _email; +} +@end + +@interface UIxAppointmentEditor : UIxComponent +{ + id appointment; + id participants; +} + +- (SOGoAppointment *)appointment; +- (NSString *)iCalStringTemplate; +- (NSString *)iCalString; +- (BOOL)isNewAppointment; + +@end + +@implementation UIxAppointmentEditor + +- (void)dealloc { + [self->appointment release]; + [self->participants release]; + [super dealloc]; +} + + +/* accessors */ + + +- (NSString *)formattedAptStartTime { + NSCalendarDate *date; + + date = [[self appointment] startDate]; + /* TODO: convert this into display timeZone! */ + return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"]; +} + +- (BOOL)isNewAppointment { + return ! [[self clientObject] isAppointment]; +} + +- (NSString *)iCalString { + if([self isNewAppointment]) { + return [self iCalStringTemplate]; + } + else { + return [[self clientObject] valueForKey:@"iCalString"]; + } +} + +- (NSString *)iCalStringTemplate { + static NSString *iCalStringTemplate = \ + @"BEGIN:VCALENDAR\nMETHOD:REQUEST\nPRODID:OpenGroupware.org ZideStore 1.2\n" \ + @"VERSION:2.0\nBEGIN:VEVENT\nCLASS:PRIVATE\nSTATUS:CONFIRMED\n" \ + @"DTSTART:%@\nDTEND:%@\n" \ + @"TRANSP:OPAQUE\n" \ + @"END:VEVENT\nEND:VCALENDAR"; + NSCalendarDate *startDate, *endDate; + NSString *template; + + startDate = [self selectedDate]; + endDate = [startDate dateByAddingYears:0 months:0 days:0 + hours:1 minutes:0 seconds:0]; + + template = [NSString stringWithFormat:iCalStringTemplate, + [startDate icalString], + [endDate icalString]]; + + return template; +} + + +/* backend */ + + +- (SOGoAppointment *)appointment { + if(self->appointment == nil) { + self->appointment = [[SOGoAppointment alloc] + initWithICalString:[self iCalString]]; + } + return self->appointment; +} + +- (id)participants { + if(self->participants == nil) { + NSArray *attendees; + NSMutableArray *emailAddresses; + unsigned i, count; + + attendees = [self->appointment attendees]; + count = [attendees count]; + emailAddresses = [[NSMutableArray alloc] initWithCapacity:count]; + for(i = 0; i < count; i++) { + NSString *email; + + email = [[attendees objectAtIndex:i] rfc822Email]; + if(email) + [emailAddresses addObject:email]; + } + self->participants = [[emailAddresses componentsJoinedByString:@"\n"] + retain]; + [emailAddresses release]; + } + return self->participants; +} + + +/* helper */ + +- (NSString *)uriAsFormat { + NSString *uri, *qp; + NSRange r; + + uri = [[[self context] request] uri]; + + /* first: identify query parameters */ + r = [uri rangeOfString:@"?" options:NSBackwardsSearch]; + if (r.length > 0) { + uri = [uri substringToIndex:r.location]; + qp = [uri substringFromIndex:r.location]; + } + else { + qp = nil; + } + + /* next: strip trailing slash */ + if([uri hasSuffix:@"/"]) + uri = [uri substringToIndex:([uri length] - 1)]; + r = [uri rangeOfString:@"/" options:NSBackwardsSearch]; + + /* then: cut of last path component */ + if(r.location == NSNotFound) { // no slash? are we at root? + uri = @"/"; + } + else { + uri = [uri substringToIndex:(r.location + 1)]; + } + /* next: append format token */ + uri = [uri stringByAppendingString:@"%@"]; + if(qp != nil) + uri = [uri stringByAppendingString:qp]; + return uri; +} + + +/* save */ + + +- (id)saveAction { + SOGoAppointment *apt; + NSString *iCalString, *summary, *location, *nextMethod, *uri, *uriFormat; + NSCalendarDate *sd, *ed; + NSArray *ps; + unsigned i, count; + WOResponse *r; + WORequest *req; + + req = [[self context] request]; + + /* get iCalString from hidden input */ + iCalString = [req formValueForKey:@"ical"]; + apt = [[SOGoAppointment alloc] initWithICalString:iCalString]; + + /* merge in form values */ + sd = [NSCalendarDate dateWithString:[req formValueForKey:@"startDate"] + calendarFormat:@"%Y-%m-%d %H:%M"]; + [apt setStartDate:sd]; + ed = [NSCalendarDate dateWithString:[req formValueForKey:@"endDate"] + calendarFormat:@"%Y-%m-%d %H:%M"]; + [apt setEndDate:ed]; + summary = [req formValueForKey:@"summary"]; + [apt setSummary:title]; + location = [req formValueForKey:@"location"]; + [apt setLocation:location]; + + [apt removeAllAttendees]; /* clean up */ + ps = [[req formValueForKey:@"participants"] + componentsSeparatedByString:@"\n"]; + count = [ps count]; + for(i = 0; i < count; i++) { + NSString *email; + + email = [ps objectAtIndex:i]; + if([email length] > 0) { + iCalPerson *p; + NSRange cnr; + + p = [[iCalPerson alloc] init]; + [p setEmail:[NSString stringWithFormat:@"mailto:%@", email]]; + /* construct a fake CN */ + cnr = [email rangeOfString:@"@"]; + if(cnr.location != NSNotFound) { + [p setCn:[email substringToIndex:cnr.location]]; + } + [apt addToAttendees:p]; + [p release]; + } + } + + /* receive current representation for save operation */ + iCalString = [apt iCalString]; + [apt release]; + + + /* determine what's to do and where to go next */ + if([self isNewAppointment]) { + nextMethod = @"duhduh"; + } + else { + nextMethod = @"view"; + } + + NSLog(@"%s new iCalString:\n%@", __PRETTY_FUNCTION__, iCalString); + + uriFormat = [self uriAsFormat]; + uri = [NSString stringWithFormat:uriFormat, nextMethod]; + + r = [WOResponse responseWithRequest:req]; + [r setStatus:302 /* moved */]; + [r setHeader:uri forKey:@"location"]; + return r; +} + +@end diff --git a/SOGo/UI/Scheduler/UIxAppointmentEditor.wox b/SOGo/UI/Scheduler/UIxAppointmentEditor.wox new file mode 100644 index 00000000..ce2381aa --- /dev/null +++ b/SOGo/UI/Scheduler/UIxAppointmentEditor.wox @@ -0,0 +1,111 @@ + + + +
+ + + + + + + + + + +
+ + + + + +
+ Appointment Editor + +
+
+ + + + + + + + + + + + + + + + + + + + +
+ Appointment on +
+ Start time: + + + + +
+ End time: + + + + +
+ Title: + + + + +
+ Location: + + + + +
+
+ + + + + + +
+ Search participants +
+ Participants: + + +