--- /dev/null
+2004-06-30 Marcus Müller <znek@mulle-kybernetik.com>
+
+ * 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 <helge.hess@opengroupware.org>
+
+ * Scheduler/UIxAppointmentEditor.m: made the hack more hackish to work
+ on MacOSX
+
+2004-06-28 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * Scheduler/GNUmakefile.preamble: links against libSOGoLogic now.
+
+ * Scheduler/UIxAppointmentView.m, Scheduler/UIxAppointmentView.wox:
+ test of iCal object.
+
+2004-06-23 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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 <helge.hess@skyrix.com>
+
+ * Common/GNUmakefile.preamble: fixed linking for OGo gstep-make
+
+2004-06-21 Helge Hess <helge.hess@opengroupware.org>
+
+ * Scheduler/OGoCalWeekOverview.m: fixed syntax errors
+
+2004-06-18 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * Implemented proper calendar in week overview. Highlighting isn't
+ enabled, yet.
+
+2004-06-18 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * Common/UIxTabView.m: removed class from <a> 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 <helge.hess@opengroupware.org>
+
+ * Scheduler/OGoCalMonthOverview.wox: added missing rsrc namespace
+
+2004-06-14 Helge Hess <helge.hess@skyrix.com>
+
+ * Common/common.h: fixed a gcc 3.4 warning
+
+2004-06-14 Helge Hess <helge.hess@opengroupware.org>
+
+ * added aggregate project for UI-X
+
+2004-06-14 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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 <helge.hess@opengroupware.org>
+
+ * Scheduler/NOTES: added class hierarchy
+
+ * */common.h, GNUmakefile.preamble.: fixed for OSX compile
+
+2004-06-08 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * Common/images: added a bunch of images from OGo
+
+2004-06-07 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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 <helge.hess@opengroupware.org>
+
+ * 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 <znek@mulle-kybernetik.com>
+
+ * 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
--- /dev/null
+/*
+ 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 <Foundation/NSObject.h>
+
+@interface CommonUIProduct : NSObject
+{
+}
+
+@end
+
+#include "common.h"
+
+@implementation CommonUIProduct
+@end /* CommonUIProduct */
--- /dev/null
+# $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
--- /dev/null
+# $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
--- /dev/null
+# $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
--- /dev/null
+// $Id$
+
+#include <NGObjWeb/SoComponent.h>
+
+@interface UIxAppFrame : SoComponent
+@end
+
+#include "common.h"
+
+@implementation UIxAppFrame
+@end /* UIxAppFrame */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+>
+ <head>
+ <title><var:string value="title"/></title>
+
+ <meta name="description" content="ZideStore Web Interface" />
+ <meta name="author" content="SKYRIX Software AG" />
+ <meta name="robots" content="stop" />
+
+ <link href="mailto:hh@skyrix.com" rev="made" />
+ </head>
+
+ <frameset rows="48,*" frameborder="0" framespacing="0" border="0">
+
+ <frame src="appheader"
+ name="head"
+ leftmargin="0" topmargin="0" marginheight="0" marginwidth="0"
+ scrolling="no" noresize="yes" />
+
+ <frameset cols="150,*">
+
+ <frame src="appnavigation"
+ name="navi"
+ leftmargin="0" topmargin="0" marginheight="0" marginwidth="0"
+ scrolling="yes" />
+
+ <frame src="view"
+ name="content"
+ leftmargin="0" topmargin="0" marginheight="0" marginwidth="0"
+ scrolling="yes" />
+
+ </frameset>
+
+ </frameset>
+
+ <noframes>
+ This pages requires frame tags, which your browser does not support,
+ sorry ;->
+ </noframes>
+</html>
--- /dev/null
+// $Id$
+
+#include <NGObjWeb/SoComponent.h>
+
+@interface UIxAppHeader : SoComponent
+@end
+
+#include "common.h"
+
+@implementation UIxAppHeader
+@end /* UIxAppHeader */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+>
+ <head>
+ <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css" />
+
+ <script language="javascript">
+ function viewInNavi(url) {
+ parent.navi.location=url;
+ return true
+ }
+ </script>
+ </head>
+
+ <body>
+ <div id="header">
+ <img filename="OGoLogo.gif" class="headerlogo" alt="Logo" />
+ <div id="headerhistory">
+ <span id="navtitle">ZideStore UI - Experimental</span>
+ </div>
+ </div>
+
+ <div style="text-align: right; font-size: 8pt;">
+ <a href="#" onClick="viewInNavi('appnavigation')">reload</a> -
+ resistance is obsolete <entity name="trade"/> ;-)
+ </div>
+ </body>
+</html>
--- /dev/null
+/*
+ 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 <NGObjWeb/NGObjWeb.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <Foundation/Foundation.h>
+
+
+@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
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<font xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ class="defaultfont"
+>
+<b>You are here:</b><var:entity const:name="nbsp" /><var:foreach list="navPathElements" item="element"><var:if condition="element" value="lastElement" const:negate="YES"><a var:href="element.url"><var:string value="element.name" /></a><var:entity const:name="nbsp" />/<var:entity const:name="nbsp" /></var:if><var:if condition="element" value="lastElement"><var:string value="element.name" /></var:if></var:foreach>
+</font>
\ No newline at end of file
--- /dev/null
+// $Id$
+
+#include <NGObjWeb/SoComponent.h>
+
+@interface UIxAppNavigation : SoComponent
+@end
+
+#include "common.h"
+
+@implementation UIxAppNavigation
+@end /* UIxAppNavigation */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+>
+ <head>
+ <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css" />
+
+ <style>
+ a:link, a:visited, a:active, a:hover {
+ text-decoration: none;
+ font-family: Arial, Helvetica, Helv, Sans-Serif;
+ font-size: 9pt;
+ color: #0000FF;
+ }
+ a.reloadlink {
+ color: black;
+ }
+
+ ul {
+ margin: 0; /*removes indent IE and Opera*/
+ padding: 0; /*removes indent Mozilla and NN7*/
+ /* list-style-type: none; */ /*turns off display of bullet*/
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 14pt;
+ }
+
+ ul li {
+ /* padding-left: 4px; */
+ /* list-style: url(http://vesper.in.skyrix.com/SKYRiXgreen/WebServerResources/EN.lproj/nav_folder_open.gif); */
+ list-style: url(http://move:9000/OpenGroupware.woa/WebServerResources/English.lproj/icon_folder.gif);
+ }
+
+ ul li a {
+ display: block;
+ border: 1px solid #FFFFFF;
+ padding: 2px 2px 2px 24px;
+ width: 80%;
+ background-color: #EEEEEE;
+ }
+
+ ul li a:link, ul li a:visited {
+ text-decoration: none;
+ }
+ ul li a:hover {
+ border: 1px solid #333333;
+ background-color: #CCCCCC;
+ }
+ </style>
+
+ <script language="javascript"><![CDATA[
+ function viewInContent(url) {
+ parent.content.location=url;
+ return true;
+ }
+ ]]></script>
+ </head>
+
+ <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
+ <br />
+ <ul>
+ <li><a href="#">OGo</a></li>
+ <li><a href="#" onclick="viewInContent('view')" >View</a></li>
+ <li><a href="#" onclick="viewInContent('weekoverview')" >Week</a></li>
+ <li><a href="#" onclick="viewInContent('monthoverview')">Month</a></li>
+ <li><a href="#">OGo</a></li>
+ </ul>
+ <br />
+
+ <div style="border-top: 1px solid #000000;">
+ <a href="appnavigation" class="reloadlink"
+ var:_o="context.contextID"><i>(reload)</i></a>
+ </div>
+
+ <br />
+
+ <div style="border-top: 1px solid #000000; font-size: 8pt">
+ <var:string value="context.contextID" />
+ </div>
+ <a href="http://www.projectseven.com/tutorials/css_menus/list_01/"
+ target="extlink">CSS Menues</a>
+ </body>
+</html>
--- /dev/null
+/*
+ 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 <NGObjWeb/SoComponent.h>
+
+@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_ */
--- /dev/null
+/*
+ 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 <Foundation/Foundation.h>
+#include <NGObjWeb/NGObjWeb.h>
+#include <NGExtensions/NGExtensions.h>
+
+
+@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
--- /dev/null
+/*
+ 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 <NGObjWeb/WOxElemBuilder.h>
+
+/*
+ This builder builds various elements from the UI-X product.
+
+ All tags are mapped into the <uix:> namespace (XMLNS_OD_BIND).
+
+ <var:tabview .../> maps to UIxTabView
+ <var:tab .../> maps to UIxTabItem
+*/
+
+@interface UIxElemBuilder : WOxTagClassElemBuilder
+{
+}
+
+@end
+
+#include <SaxObjC/XMLNamespaces.h>
+#include "common.h"
+
+#define XMLNS_UIX @"OGo:uix"
+
+
+@implementation UIxElemBuilder
+
+- (Class)classForElement:(id<DOMElement>)_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 */
--- /dev/null
+// $Id$
+
+#include <NGObjWeb/SoComponent.h>
+#include <NGObjWeb/SoHTTPAuthenticator.h>
+#include <NGObjWeb/SoUser.h>
+
+
+@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 */
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:var="http://www.skyrix.com/od/binding" xmlns:const="http://www.skyrix.com/od/constant" xmlns:rsrc="OGo:url">
+ <head>
+ <title>
+ <var:string value="title"/>
+ </title>
+ <meta name="description" content="ZideStore Web Interface"/>
+ <meta name="author" content="SKYRIX Software AG"/>
+ <meta name="robots" content="stop"/>
+ <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css"/>
+ <link type="text/css" rel="stylesheet" rsrc:href="calendar.css"/>
+ <link href="mailto:hh@skyrix.com" rev="made"/>
+ </head>
+ <body>
+<!--
+ <div id="header">
+ <img filename="OGoLogo.gif" class="headerlogo" alt="Logo" />
+ <div id="headerhistory">
+ <span id="navtitle">ZideStore UI - Experimental</span>
+ </div>
+ </div>
+ <br />
+-->
+ <table cellpadding="5" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td colspan="2">
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td valign="bottom">
+ <var:component className="UIxAppNavView" />
+ </td>
+ <td align="right">
+ <a href="http://www.opengroupware.org:80/" target="OGo">
+ <img rsrc:src="menu_logo_top.gif" align="center" border="0" ALT="" Valign="middle"/>
+ </a>
+ </td>
+ </tr>
+ </table>
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td class="linecolor">
+ <img rsrc:src="line_left.gif"/>
+ </td>
+ <td class="linecolor" width="100%">
+ <img rsrc:src="line_stretch.gif"/>
+ </td>
+ <td class="linecolor">
+ <img rsrc:src="line_right.gif"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+<!-- $Id: SkyDock.html,v 1.13 2004/02/13 14:08:27 helge Exp $ -->
+ <td valign="top">
+ <table border="0" cellspacing="0" cellpadding="0" class="leftmenu">
+ <tr>
+ <td>
+ <img rsrc:src="box_topleft.gif"/>
+ </td>
+ <td valign="top" rsrc:background="box_top.gif">
+ <img rsrc:src="box_top.gif"/>
+ </td>
+ <td>
+ <img rsrc:src="box_topright.gif"/>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td rsrc:background="box_left.gif">
+ <img rsrc:src="box_left.gif"/>
+ </td>
+ <td width="100%">
+ <table width="100%" border="0" cellspacing="2" cellpadding="" class="leftmenu">
+ <tr>
+ <td>
+ <font class="skydockfont">
+ <a href="/ZideStore/" class="skydockfont">SOGo (<var:string value="login" />)</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td class="linecolor">
+ <img rsrc:src="line_left.gif"/>
+ </td>
+ <td class="linecolor" width="100%">
+ <img rsrc:src="line_stretch.gif"/>
+ </td>
+ <td class="linecolor">
+ <img rsrc:src="line_right.gif"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td height="3"/>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">News</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Projects</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Contacts</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Companies</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skyDockFont">Calendar</a>
+ </font>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <font class="skydockfont">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Tasks</a>
+ </font>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td rsrc:background="box_right.gif">
+ <img rsrc:src="box_right.gif"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <img rsrc:src="box_botleft.gif"/>
+ </td>
+ <td rsrc:background="box_bottom.gif">
+ <img rsrc:src="box_bottom.gif"/>
+ </td>
+ <td>
+ <img rsrc:src="box_botright.gif"/>
+ </td>
+ </tr>
+ </table>
+<!-- $Id: SkyDockedProjects.html,v 1.10 2004/05/07 16:05:03 helge Exp $ -->
+ </td>
+ </tr>
+ </table>
+ <br/>
+<!-- $Id: SkyFavorites.html,v 1.5 2003/10/29 18:06:00 helge Exp $ -->
+<!-- the misc box -->
+ <span>
+ <table cellspacing="0" class="leftmenu" border="0" cellpadding="0">
+ <tr>
+ <td>
+ <img rsrc:src="box_topleft.gif"/>
+ </td>
+ <td rsrc:background="box_top.gif">
+ <img rsrc:src="box_top.gif"/>
+ </td>
+ <td>
+ <img rsrc:src="box_topright.gif"/>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td rsrc:background="box_left.gif">
+ <img rsrc:src="box_left.gif"/>
+ </td>
+ <td width="100%">
+ <table width="100%" cellspacing="2" class="leftmenu" border="0" cellpadding="">
+ <tr>
+ <td>
+ <font class="skydockfont">Misc</font>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table width="100%" cellspacing="0" border="0" cellpadding="0">
+ <tr>
+ <td class="linecolor">
+ <img rsrc:src="line_left.gif"/>
+ </td>
+ <td width="100%" class="linecolor">
+ <img rsrc:src="line_stretch.gif"/>
+ </td>
+ <td class="linecolor">
+ <img rsrc:src="line_right.gif"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td height="3"/>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/mail" class="skydockfont">New Email</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/mail" class="skydockfont">Inbox</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Preferences</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/downloadBookmark" target="private_desktop" class="skydockfont">Home</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/downloadBookmark" target="public_desktop" class="skydockfont">Desktop</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <a href="/OpenGroupware/x/dock" class="skydockfont">Logout</a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td rsrc:background="box_right.gif">
+ <img rsrc:src="box_right.gif"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <img rsrc:src="box_botleft.gif"/>
+ </td>
+ <td rsrc:background="box_bottom.gif">
+ <img rsrc:src="box_bottom.gif"/>
+ </td>
+ <td>
+ <img rsrc:src="box_botright.gif"/>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </td>
+ <td valign="top" width="100%">
+ <var:component-content/>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td class="linecolor">
+ <img rsrc:src="line_left.gif"/>
+ </td>
+ <td class="linecolor" width="100%">
+ <img rsrc:src="line_stretch.gif"/>
+ </td>
+ <td class="linecolor">
+ <img rsrc:src="line_right.gif"/>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3"/>
+ </tr>
+ </table>
+ <table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td valign="top" align="left">
+ <font class="defaultfont"><var:entity const:name="copy"/>
+ 2000-2004 <a href="http://www.skyrix.com:80/knoppix/skyrix/" target="SKYRIX">SKYRIX Software AG</a>.
+ We welcome your
+ <a href="http://www.opengroupware.org/en/feedback.html" target="feedback">feedback</a>.
+ </font>
+ </td>
+ <td valign="top" align="right">
+ <font class="defaultfont">
+ No sessions required! ;-)
+ </font>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </body>
+</html>
--- /dev/null
+/*
+ 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:@"<div id=\""];
+ [_response appendContentString:k];
+ [_response appendContentString:@"TabLayer\" style=\"display: none;\">\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:@"</div>"];
+
+ jsout = [NSString alloc];
+ jsout = [jsout initWithFormat:
+ @"<script language=\"JavaScript\">\n<!--\n"
+ @"%@Tab[\"Div\"] = %@TabLayer;\n",
+ k, k];
+
+ [_response appendContentString:jsout];
+ [jsout release];
+
+#if DEBUG_JS
+ jsout = [NSString alloc];
+ jsout = [jsout initWithFormat:
+ @"if (%@Tab[\"Div\"].style==null) {"
+ @"alert('missing style in div for tab %@');}",
+ k, k];
+
+ [_response appendContentString:jsout];
+ [jsout release];
+#endif
+
+ if (isActive) {
+ [_response appendContentString:@"showTab("];
+ [_response appendContentString:k];
+ [_response appendContentString:@"Tab);\n"];
+ }
+ [_response appendContentString:@"//-->\n</script>"];
+ }
+}
+
+/* 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 */
--- /dev/null
+/*
+ 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 <NGObjWeb/WODynamicElement.h>
+
+/*
+ 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__ */
--- /dev/null
+/*
+ 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 <NGObjWeb/NGObjWeb.h>
+#import <NGExtensions/NGExtensions.h>
+#import <EOControl/EOControl.h>
+#include <WEExtensions/WEClientCapabilities.h>
+
+#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:@"<td align='center' valign='middle'"];
+
+ if (styleName) {
+ [_response appendContentString:@" class='"];
+ [_response appendContentHTMLAttributeValue:styleName];
+ [_response appendContentCharacter:'\''];
+ }
+
+ // click on td background
+ if ([ccaps isInternetExplorer] && [ccaps isJavaScriptBrowser]) {
+ [_response appendContentString:@" onclick=\"window.location.href='"];
+ [_response appendContentHTMLAttributeValue:headUri];
+ [_response appendContentString:@"'\""];
+ }
+
+ [_response appendContentCharacter:'>'];
+
+ [_response appendContentString:@"<a href=\""];
+
+ if (_doScript && (_info->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:@"<nobr>"];
+ [_response appendContentHTMLString:label];
+ [_response appendContentString:@"</nobr>"];
+
+ [_response appendContentString:@"</a>"];
+
+ [_response appendContentString:@"</td>"];
+
+#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:
+ @"<script language=\"JavaScript\">\n"
+ @"<!--\n"
+ @"var %@Tab = new Array();\n"
+ @"%@Tab[\"link\"] = %@TabLink;\n"
+ @"%@Tab[\"href1\"] = \"%@\";\n"
+ @"%@Tab[\"href2\"] = \"%@\";\n"
+ @"%@Tab[\"Img\"] = window.document.%@TabImg;\n"
+ @"%@Tab[\"Ar\"] = new Array();\n"
+ @"%@Tab[\"Ar\"][0] = new Image();\n"
+ @"%@Tab[\"Ar\"][0].src = \"%@\";\n"
+ @"%@Tab[\"Ar\"][1] = new Image();\n"
+ @"%@Tab[\"Ar\"][1].src = \"%@\";\n"
+ @"//-->\n</script>",
+ 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_(@"<script language=\"JavaScript\">\n<!--\nvar ");
+ _appendStr_(k); _appendStr_(@"Tab = new Array();\n");
+
+ _appendStr_(k); _appendStr_(@"Tab[\"link\"] = ");
+ _appendStr_(k); _appendStr_(@"TabLink;\n"); // linkName
+
+ _appendStr_(k); _appendStr_(@"Tab[\"href1\"] = \"");
+ _appendStr_(scriptHref); _appendStr_(@"\";\n"); // scriptHref
+
+ _appendStr_(k); _appendStr_(@"Tab[\"href2\"] = \"");
+ _appendStr_(_info->uri); _appendStr_(@"\";\n"); // actionHref
+
+ _appendStr_(k); _appendStr_(@"Tab[\"Img\"] = window.document.");
+ _appendStr_(k); _appendStr_(@"TabImg;\n");
+ _appendStr_(k); _appendStr_(@"Tab[\"Ar\"] = new Array();\n");
+ _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][0] = new Image();\n");
+ _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][0].src = \"");
+ _appendStr_(u); _appendStr_(@"\";\n"); // unselected img
+ _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][1] = new Image();\n");
+ _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][1].src = \"");
+ _appendStr_(s); _appendStr_(@"\";\n"); // selected img
+ _appendStr_(@"//-->\n</script>");
+#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:
+ @"<script language=\"JavaScript\">\n<!--\n\n"
+ @"function showTab(obj) {\n"
+#if DEBUG_JS
+ @" if (obj==null) { alert('missing tab obj ..'); return; }\n"
+ @" if (obj['Div']==null) {"
+ @" alert('missing div key in ' + obj); return; }\n"
+ @" if (obj['Div'].style==null) {"
+ @" alert('missing style key in div ' + obj['Div']);return; }\n"
+#endif
+ @" obj['Div'].style.display = \"\";\n"
+ @" obj['Img'].src = obj[\"Ar\"][1].src;\n"
+ @" obj['link'].href = obj[\"href2\"];\n"
+ @"}\n"
+ @"function hideTab(obj) {\n"
+#if DEBUG_JS
+ @" if (obj==null) { alert('missing tab obj ..'); return; }\n"
+ @" if (obj['Div']==null) {"
+ @" alert('missing div key in ' + obj); return; }\n"
+ @" if (obj['Div'].style==null) {"
+ @" alert('missing style key in div ' + obj['Div']);return; }\n"
+#endif
+ @" obj['Div'].style.display = \"none\";\n"
+ @" obj['Img'].src = obj[\"Ar\"][0].src;\n"
+ @" obj['link'].href = obj[\"href1\"];\n"
+ @"}\n"
+ @"function swapCorners(obj1,obj2) {\n"
+ @" if (obj1==null) { alert('missing corner 1'); return; }\n"
+ @" if (obj2==null) { alert('missing corner 2'); return; }\n"
+ @" obj1.style.display = \"none\";\n"
+ @" obj2.style.display = \"\";\n"
+ @"}\n"
+ @"//-->\n</script>"];
+}
+
+- (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:@"<tr><td colspan='2'>"];
+
+ styleName = [self->headerStyle stringValueInComponent:[_ctx component]];
+ if(styleName) {
+ [_response appendContentString:
+ @"<table border='0' cellpadding='0' cellspacing='0' class='"];
+ [_response appendContentHTMLAttributeValue:styleName];
+ [_response appendContentString:@"'><tr>"];
+ }
+ else {
+ [_response appendContentString:
+ @"<table border='0' cellpadding='0' cellspacing='0'><tr>"];
+ }
+
+ 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:@"<td></td>"];
+ [_response appendContentString:@"</tr></table>"];
+ [_response appendContentString:@"</td></tr>"];
+}
+
+- (void)_appendHeaderFootRowToResponse:(WOResponse *)_response
+ inContext:(WOContext *)_ctx
+ bgcolor:(NSString *)bgcolor
+ doScript:(BOOL)doScript
+ isLeftActive:(BOOL)isLeftActive
+{
+ NSString *styleName;
+ [_response appendContentString:@" <tr"];
+
+ styleName = [self->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:@" <td align=\"left\" width=\"10\">"];
+
+ if (doScript) {
+ [_response appendContentString:@"<div id=\"tabCorner"];
+ [_response appendContentString:[self _tabViewCountInContext:_ctx]];
+ [_response appendContentString:@"\" "];
+ [_response appendContentString:@"style=\"display: "];
+ [_response appendContentString:(isLeftActive) ? @"" : @"none"];
+ [_response appendContentString:@";\">"];
+ [_response appendContentString:@" "];
+ [_response appendContentString:@"</div>"];
+ }
+ else if (isLeftActive)
+ [_response appendContentString:@" "];
+
+ if (doScript) {
+ [_response appendContentString:@"<div id=\"tabCornerLeft"];
+ [_response appendContentString:[self _tabViewCountInContext:_ctx]];
+ [_response appendContentString:@"\" "];
+ [_response appendContentString:@"style=\"display: "];
+ [_response appendContentString:(!isLeftActive) ? @"visible" : @"none"];
+ [_response appendContentString:@";\">"];
+ }
+
+ if (!isLeftActive || doScript) {
+ NSString *uri;
+
+ uri = [self->leftCornerIcon stringValueInComponent:[_ctx component]];
+ if ((uri = WEUriOfResource(uri, _ctx))) {
+ [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
+ [_response appendContentString:uri];
+ [_response appendContentString:@"\">"];
+ }
+ else
+ [_response appendContentString:@" "];
+ }
+ if (doScript)
+ [_response appendContentString:@"</div>"];
+
+ [_response appendContentString:@"</td>\n"];
+
+ /* right corner */
+ [_response appendContentString:@" <td align=\"right\">"];
+ {
+ NSString *uri;
+
+ uri = [self->rightCornerIcon stringValueInComponent:[_ctx component]];
+ if ((uri = WEUriOfResource(uri, _ctx))) {
+ [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
+ [_response appendContentString:uri];
+ [_response appendContentString:@"\" />"];
+ }
+ else
+ [_response appendContentString:@" "];
+ }
+ [_response appendContentString:@"</td>\n"];
+
+ [_response appendContentString:@" </tr>\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:@"<tr"];
+ if(styleName) {
+ [_response appendContentString:@" class='"];
+ [_response appendContentHTMLAttributeValue:styleName];
+ [_response appendContentCharacter:'\''];
+ }
+ [_response appendContentString:@"><td colspan='2'"];
+ if (bgcolor) {
+ [_response appendContentString:@" bgcolor=\""];
+ [_response appendContentHTMLAttributeValue:bgcolor];
+ [_response appendContentCharacter:'\"'];
+ }
+ [_response appendContentCharacter:'>'];
+
+ if (indentContent) {
+ /* start padding table */
+ [_response appendContentString:
+ @"<table border='0' width='100%'"
+ @" cellpadding='10' cellspacing='0'>"];
+ [_response appendContentString:@"<tr><td>"];
+ }
+
+ [_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:@"</td></tr></table>"];
+
+ [_response appendContentString:@"</td></tr>"];
+}
+
+- (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:
+ @"<table border='0' width='100%'"
+ @" cellpadding='0' cellspacing='0'>"];
+
+ /* 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:@"</table>"];
+ [_ctx removeObjectForKey:UIxTabView_ACTIVEKEY];
+ [_ctx removeObjectForKey:UIxTabView_KEYS];
+ [self restoreNestedState:nestedState inContext:_ctx];
+}
+
+@end /* UIxTabView */
--- /dev/null
+/*
+ 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 <NGObjWeb/NGObjWeb.h>
+
+
+@interface UIxWinClose : WOComponent
+{
+
+}
+
+@end
+
+
+@implementation UIxWinClose
+
+@end
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<a xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ href="javascript:history.back()"><img border="0" alt="X" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/closewindow.gif"/></a>
--- /dev/null
+# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
+
+SUBMINOR_VERSION:=1
+
+# 1.1.0 requires NGObjWeb 4.2.202
--- /dev/null
+{
+ "__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"; },
+ );
+ };
+}
--- /dev/null
+.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;
+}
--- /dev/null
+/*
+ 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 <Foundation/Foundation.h>
+
+#if LIB_FOUNDATION_LIBRARY
+# include <Foundation/exceptions/GeneralExceptions.h>
+#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
+# include <NGExtensions/NGObjectMacros.h>
+# include <NGExtensions/NSString+Ext.h>
+#endif
+
+#include <NGExtensions/NGExtensions.h>
+#include <NGObjWeb/NGObjWeb.h>
+#include <NGObjWeb/SoObjects.h>
+
+@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:@"<font"];
+ if (_color) {
+ [_resp appendContentString:@" color=\""];
+ [_resp appendContentHTMLAttributeValue:_color];
+ [_resp appendContentCharacter:'"'];
+ }
+ if (_face) {
+ [_resp appendContentString:@" face=\""];
+ [_resp appendContentHTMLAttributeValue:_face];
+ [_resp appendContentCharacter:'"'];
+ }
+ if (_size) {
+ [_resp appendContentString:@" size=\""];
+ [_resp appendContentHTMLAttributeValue:_size];
+ [_resp appendContentCharacter:'"'];
+ }
+ [_resp appendContentCharacter:'>'];
+}
+
+static inline void WEAppendTD(WOResponse *_resp,
+ NSString *_align,
+ NSString *_valign,
+ NSString *_bgColor)
+{
+ [_resp appendContentString:@"<td"];
+ if (_bgColor) {
+ [_resp appendContentString:@" bgcolor=\""];
+ [_resp appendContentHTMLAttributeValue:_bgColor];
+ [_resp appendContentCharacter:'"'];
+ }
+ if (_align) {
+ [_resp appendContentString:@" align=\""];
+ [_resp appendContentHTMLAttributeValue:_align];
+ [_resp appendContentCharacter:'"'];
+ }
+ if (_valign) {
+ [_resp appendContentString:@" valign=\""];
+ [_resp appendContentHTMLAttributeValue:_valign];
+ [_resp appendContentCharacter:'"'];
+ }
+ [_resp appendContentCharacter:'>'];
+}
+
+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
--- /dev/null
+{
+ 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";
+ };
+ };
+ };
+ };
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+# $Id$
+
+include $(GNUSTEP_MAKEFILES)/common.make
+
+SUBPROJECTS = \
+ Common \
+ Scheduler \
+
+include $(GNUSTEP_MAKEFILES)/aggregate.make
--- /dev/null
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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
+\f
+ 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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+Copyright (C) 2004 SKYRIX Software AG
+
+
+Contact: info@skyrix.com
--- /dev/null
+# $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
--- /dev/null
+# $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
--- /dev/null
+# $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
--- /dev/null
+// $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
--- /dev/null
+/*
+ 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 <Foundation/NSObject.h>
+
+@interface SchedulerUIProduct : NSObject
+{
+}
+
+@end
+
+#include "common.h"
+
+@implementation SchedulerUIProduct
+@end /* SchedulerUIProduct */
--- /dev/null
+/*
+ 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 <Common/UIxComponent.h>
+#include <SOGoLogic/SOGoAppointment.h>
+#include <NGiCal/NGiCal.h>
+
+
+/* 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
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ className="UIxPageFrame"
+ title="name"
+>
+
+ <form href="save">
+ <table cellspacing="0" cellpadding="5" width="100%">
+ <tr>
+ <td>
+ <table cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td width="5"/>
+ <td class="window_label">Appointment Editor</td>
+ <td width="36" align="right" valign="center">
+ <var:component className="UIxWinClose" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <table border="0" cellpadding="2" width="100%" cellspacing="0" bgcolor="#e8e8e0">
+ <tr>
+ <td align="left" colspan="2">
+ <span class="aptview_title">Appointment on <var:string value="formattedAptStartTime" /></span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">Start time:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <input type="text" name="startDate" var:value="appointment.startDate" const:dateformat="%Y-%m-%d %H:%M" const:size="40" />
+ </span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">End time:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <input type="text" name="endDate" var:value="appointment.endDate" const:dateformat="%Y-%m-%d %H:%M" const:size="40" />
+ </span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">Title:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <input type="text" name="summary" var:value="appointment.summary" const:size="40" />
+ </span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">Location:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <input type="text" name="location" var:value="appointment.location" const:size="40"/>
+ </span>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <table border="0" cellpadding="2" width="100%" cellspacing="0" bgcolor="#e8e8e0">
+ <tr>
+ <td align="left" colspan="2">
+ <span class="aptview_title">Search participants</span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">Participants:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <textarea name="participants" var:value="participants" cols="40" rows="5" />
+ </span>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <input type="submit" value="Save" />
+ <input type="hidden" name="ical" var:value="iCalString" />
+ </td>
+ </tr>
+ </table>
+ </form>
+ <!-- -->
+ <hr />
+ clientObject: <var:string value="clientObject" />
+</var:component>
--- /dev/null
+/*
+ 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 __UIxAppointmentFormatter_H__
+#define __UIxAppointmentFormatter_H__
+
+#import <Foundation/NSFormatter.h>
+
+/*
+ Formatter to format appointment-dicts to readable strings:
+
+ %[(dateFormat)]S
+ - startDate formatted with the dateFormat string
+ - if no dateFormat is defined, the default formats are used
+ - !!! dont forget the ()brakes !!!
+ %[(dateFormat)]E
+ - endDate formatted with the dateFormat string
+ - if no dateFormat is defined, the default formats are used
+ - !!! dont forget the ()brakes !!!
+
+ %[length]T - title with the specified length
+ - if title has more chars than length overLengthString is appended
+ - if no length is defined, no limit is set
+
+ %[max]P - participants
+ - if more than max participants at appointment
+ moreParticipantsString is appended
+ - if no max defined no limit is set
+
+ %[length]L - location
+ - if location has more chars than length overLengthString is
+ appended
+ - if no length is defined, no limit is set
+
+ Example:
+ format: @"%S - %E, \n%T";
+
+ */
+
+@class NSCalendarDate;
+
+@interface UIxAppointmentFormatter : NSFormatter
+{
+@protected
+ NSString *formatString; // default: @"%S - %E, \n%T"
+
+ NSString *dateFormat; // default: @"%H:%M"
+ NSString *otherDayDateFormat; // default: @"%H:%M(%m-%d)"
+ NSString *otherYearDateFormat; // default: @"%H:%M(%Y-%m-%d)"
+
+ NSString *toLongString; // default: @".."
+ NSString *moreParticipantsString; // default: @"..."
+ NSString *participantsSeparator; // default: @", "
+
+ NSCalendarDate *relationDate; // if nil, dateFormat used as format
+ // to know whether its the same day, the same year or another year
+
+ BOOL showFullNames; // try to show full names of participants
+}
+
+//init
+- (id)initWithFormat:(NSString *)_format;
++ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format;
++ (UIxAppointmentFormatter *)formatter;
+
+//accessors
+- (void)setFormat:(NSString *)_format;
+- (NSString *)format;
+
+- (void)setDateFormat:(NSString *)_format;
+- (NSString *)dateFormat;
+
+- (void)setOtherDayDateFormat:(NSString *)_format;
+- (NSString *)otherDayDateFormat;
+
+- (void)setOtherYearDateFormat:(NSString *)_format;
+- (NSString *)otherYearDateFormat;
+
+- (void)setToLongString:(NSString *)_toLong;
+- (NSString *)toLongString;
+
+- (void)setMoreParticipantsString:(NSString *)_more;
+- (NSString *)moreParticipantsString;
+
+- (void)setParticipantsSeparator:(NSString *)_sep;
+- (NSString *)participantsSeparator;
+
+- (void)setRelationDate:(NSCalendarDate *)_relation;
+- (NSCalendarDate *)relationDate;
+
+- (void)setShowFullNames:(BOOL)_flag;
+- (BOOL)showFullNames;
+
+// easy switches
+
+// this resets the date format
+- (void)switchToAMPMTimes:(BOOL)_showAMPM;
+
+@end
+
+#endif
--- /dev/null
+/*
+ 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 "UIxAppointmentFormatter.h"
+#import <Foundation/Foundation.h>
+#import <NGExtensions/NGExtensions.h>
+#import <EOControl/EOControl.h>
+
+@implementation UIxAppointmentFormatter
+
+- (id)init {
+ if ((self = [super init])) {
+ [self setFormat:@"%S - %E, \n%T"];
+ [self setDateFormat:@"%H:%M"];
+ [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
+ [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
+ [self setToLongString:@".."];
+ [self setMoreParticipantsString:@"..."];
+ [self setParticipantsSeparator:@", "];
+ [self setRelationDate:nil];
+ self->showFullNames = NO;
+ }
+ return self;
+}
+
+- (id)initWithFormat:(NSString *)_format {
+ if ((self = [self init])) {
+ [self setFormat:_format];
+ }
+ return self;
+}
+
++ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format {
+ return AUTORELEASE([(UIxAppointmentFormatter *)[UIxAppointmentFormatter alloc]
+ initWithFormat:_format]);
+}
+
++ (UIxAppointmentFormatter *)formatter {
+ return AUTORELEASE([[UIxAppointmentFormatter alloc] init]);
+}
+
+#if !LIB_FOUNDATION_BOEHM_GC
+- (void)dealloc {
+ RELEASE(self->formatString);
+ RELEASE(self->dateFormat);
+ RELEASE(self->otherDayDateFormat);
+ RELEASE(self->otherYearDateFormat);
+ RELEASE(self->toLongString);
+ RELEASE(self->moreParticipantsString);
+ RELEASE(self->participantsSeparator);
+ RELEASE(self->relationDate);
+
+ [super dealloc];
+}
+#endif
+
+// accessors
+
+- (void)setFormat:(NSString *)_format {
+ ASSIGN(self->formatString,_format);
+}
+- (NSString *)format {
+ return self->formatString;
+}
+
+- (void)setDateFormat:(NSString *)_format {
+ ASSIGN(self->dateFormat,_format);
+}
+- (NSString *)dateFormat {
+ return self->dateFormat;
+}
+
+- (void)setOtherDayDateFormat:(NSString *)_format {
+ ASSIGN(self->otherDayDateFormat,_format);
+}
+- (NSString *)otherDayDateFormat {
+ return self->otherDayDateFormat;
+}
+
+- (void)setOtherYearDateFormat:(NSString *)_format {
+ ASSIGN(self->otherYearDateFormat,_format);
+}
+- (NSString *)otherYearDateFormat {
+ return self->otherYearDateFormat;
+}
+
+- (void)setToLongString:(NSString *)_toLong {
+ ASSIGN(self->toLongString,_toLong);
+}
+- (NSString *)toLongString {
+ return self->toLongString;
+}
+
+- (void)setMoreParticipantsString:(NSString *)_more {
+ ASSIGN(self->moreParticipantsString,_more);
+}
+- (NSString *)moreParticipantsString {
+ return self->moreParticipantsString;
+}
+
+- (void)setParticipantsSeparator:(NSString *)_sep {
+ ASSIGN(self->participantsSeparator,_sep);
+}
+- (NSString *)participantsSeparator {
+ return self->participantsSeparator;
+}
+
+- (void)setRelationDate:(NSCalendarDate *)_relation {
+ ASSIGN(self->relationDate,_relation);
+}
+- (NSCalendarDate *)relationDate {
+ return self->relationDate;
+}
+
+- (void)setShowFullNames:(BOOL)_flag {
+ self->showFullNames = _flag;
+}
+- (BOOL)showFullNames {
+ return self->showFullNames;
+}
+
+// easy switching
+- (void)switchToAMPMTimes:(BOOL)_showAMPM {
+ if (_showAMPM) {
+ [self setDateFormat:@"%I:%M %p"];
+ [self setOtherDayDateFormat:@"%I:%M %p(%m-%d)"];
+ [self setOtherYearDateFormat:@"%I:%M %p(%Y-%m-%d)"];
+ }
+ else {
+ [self setDateFormat:@"%H:%M"];
+ [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
+ [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
+ }
+}
+
+// formatting helpers
+
+- (NSString *)formatDate:(NSCalendarDate *)_date
+ withFormat:(NSString *)_format
+{
+ NSString *f;
+ NSCalendarDate *rel;
+
+ rel = self->relationDate;
+
+ if (_format == nil) {
+ if (rel == nil) {
+ f = self->dateFormat;
+ }
+ else if ([_date isDateOnSameDay:rel]) {
+ f = self->dateFormat;
+ }
+ else if ([_date yearOfCommonEra] == [rel yearOfCommonEra]) {
+ f = self->otherDayDateFormat;
+ }
+ else {
+ f = self->otherYearDateFormat;
+ }
+ }
+ else {
+ f = _format;
+ }
+ return [_date descriptionWithCalendarFormat:f];
+}
+
+- (NSString *)formatStartDateFromApt:(id)_apt
+ withFormat:(NSString *)_format
+{
+ return [self formatDate:[_apt valueForKey:@"startDate"]
+ withFormat:_format];
+}
+
+- (NSString *)formatEndDateFromApt:(id)_apt
+ withFormat:(NSString *)_format
+{
+ return [self formatDate:[_apt valueForKey:@"endDate"]
+ withFormat:_format];
+}
+
+- (NSString *)stringForParticipant:(id)_part {
+ id label = nil;
+
+ if ([[_part valueForKey:@"isTeam"] boolValue]) {
+ if ((label = [_part valueForKey:@"info"]) == nil)
+ label = [_part valueForKey:@"description"];
+ }
+ else if (self->showFullNames) {
+ label = [_part valueForKey:@"firstname"];
+ label = ([label length])
+ ? [label stringByAppendingFormat:@" %@", [_part valueForKey:@"name"]]
+ : [_part valueForKey:@"name"];
+ }
+ else if ([[_part valueForKey:@"isAccount"] boolValue]) {
+ label = [_part valueForKey:@"login"];
+ }
+ else {
+ if ((label = [_part valueForKey:@"name"]) == nil) {
+ if ((label = [_part valueForKey:@"info"]) == nil)
+ label = [_part valueForKey:@"description"];
+ }
+ }
+
+ if (![label isNotNull])
+ label = @"*";
+
+ return label;
+}
+
+- (NSString *)participantsForApt:(id)_apt
+ withMaxCount:(NSString *)_cnt {
+ NSArray *p;
+ int max;
+ int cnt;
+ NSMutableString *pString;
+
+ pString = [NSMutableString stringWithCapacity:255];
+
+ if (_cnt == nil) {
+ max = -1; // no limit
+ }
+ else {
+ max = [_cnt intValue];
+ }
+
+ p = [_apt valueForKey:@"participants"];
+
+ p = [p sortedArrayUsingKeyOrderArray:
+ [NSArray arrayWithObjects:
+ [EOSortOrdering sortOrderingWithKey:@"isAccount"
+ selector:EOCompareAscending],
+ [EOSortOrdering sortOrderingWithKey:@"login"
+ selector:EOCompareAscending],
+ nil]];
+
+ max = ((max > [p count]) || (max == -1))
+ ? [p count]
+ : max;
+
+ for (cnt = 0; cnt < max; cnt++) {
+
+ if (cnt != 0)
+ [pString appendString:self->participantsSeparator];
+
+ [pString appendString:
+ [self stringForParticipant:[p objectAtIndex:cnt]]];
+ }
+
+ if (max < [p count]) {
+ [pString appendString:self->moreParticipantsString];
+ }
+
+ return pString;
+}
+
+- (NSString *)titleForApt:(id)_apt withMaxLength:(NSString *)_length {
+ NSString *t = nil;
+ int l;
+
+ l = (_length == nil)
+ ? -1
+ : [_length intValue];
+
+ t = [_apt valueForKey:@"title"];
+ if (!t) return @"*";
+
+ if (l > 1) {
+ if ([t length] > l) {
+ t = [t substringToIndex:(l - 2)];
+ t = [t stringByAppendingString:self->toLongString];
+ }
+ }
+
+ if (l == 0)
+ t = @"*";
+
+ return t;
+}
+
+- (NSString *)locationForApt:(id)_apt withMaxLength:(NSString *)_length {
+ NSString *t = nil;
+ int l;
+
+ l = (_length == nil)
+ ? -1
+ : [_length intValue];
+
+ t = [_apt valueForKey:@"location"];
+ if (![t isNotNull] ||
+ [t length] == 0 ||
+ [t isEqualToString:@" "])
+ return @"";
+
+ if (l > 1) {
+ if ([t length] > l) {
+ t = [t substringToIndex:(l - 2)];
+ t = [t stringByAppendingString:self->toLongString];
+ }
+ }
+
+ if (l == 0)
+ t = @"";
+
+ return t;
+}
+
+- (NSString *)resourcesForApt:(id)_apt withMaxLength:(NSString *)_length {
+ NSString *t = nil;
+ int l;
+
+ l = (_length == nil)
+ ? -1
+ : [_length intValue];
+
+ t = [_apt valueForKey:@"resourceNames"];
+ if (![t isNotNull] ||
+ [t length] == 0 ||
+ [t isEqualToString:@" "])
+ return @"";
+
+ if (l > 1) {
+ if ([t length] > l) {
+ t = [t substringToIndex:(l - 2)];
+ t = [t stringByAppendingString:self->toLongString];
+ }
+ }
+
+ if (l == 0)
+ t = @"";
+
+ return t;
+}
+
+// NSFormatter stuff
+
+- (NSString *)stringForObjectValue:(id)_obj {
+ NSMutableString *newString;
+ int cnt;
+ int length;
+ BOOL replaceMode = NO;
+ NSString *helper = nil;
+ NSCharacterSet *digits;
+
+ newString = [NSMutableString stringWithCapacity:255];
+ length = [self->formatString length];
+ digits = [NSCharacterSet decimalDigitCharacterSet];
+
+ // NSLog(@"Formatting with format: %@", self->formatString);
+
+ for (cnt = 0; cnt < length; cnt++) {
+ unichar c;
+ c = [self->formatString characterAtIndex:cnt];
+ // NSLog(@"Character is: %c mode is: %@", c,
+ // [NSNumber numberWithBool:replaceMode]);
+ if (replaceMode) {
+ if (c == 'S') {
+ [newString appendString:
+ [self formatStartDateFromApt:_obj withFormat:helper]];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == 'E') {
+ [newString appendString:
+ [self formatEndDateFromApt:_obj withFormat:helper]];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == 'P') {
+ [newString appendString:
+ [self participantsForApt:_obj withMaxCount:helper]];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == 'T') {
+ [newString appendString:
+ [self titleForApt:_obj withMaxLength:helper]];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == 'L') {
+ NSString *l;
+
+ l = [self locationForApt:_obj withMaxLength:helper];
+
+ if ([l length] > 0)
+ [newString appendString:l];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == 'R') {
+ NSString *r;
+
+ r = [self resourcesForApt:_obj withMaxLength:helper];
+
+ if ([r length] > 0)
+ [newString appendString:r];
+ helper = nil;
+ replaceMode = NO;
+ }
+ else if (c == '(') {
+ int end;
+ NSRange r = NSMakeRange(cnt,length-cnt);
+
+ r = [self->formatString rangeOfString:@")"
+ options:0 range:r];
+
+ end = r.location - 1;
+ r = NSMakeRange(cnt+1, end-cnt-1);
+
+ helper = [self->formatString substringWithRange:r];
+ cnt = end + 1;
+ }
+ else if ([digits characterIsMember:c]) {
+ helper = (helper == nil)
+ ? [NSString stringWithFormat:@"%c",c]
+ : [NSString stringWithFormat:@"%@%c", helper, c];
+ }
+ else {
+ NSLog(@"UNKNOWN FORMAT CHARACTER '%c'!!",c);
+ replaceMode = NO;
+ helper = nil;
+ }
+ } else {
+ if (c == '%') {
+ replaceMode = YES;
+ }
+ else {
+ [newString appendFormat:@"%c", c];
+ }
+ }
+ }
+
+ return newString;
+}
+
+@end
--- /dev/null
+// $Id$
+
+#ifndef __ZideStoreUI_UIxAppointmentView_H__
+#define __ZideStoreUI_UIxAppointmentView_H__
+
+#include <Common/UIxComponent.h>
+
+@interface UIxAppointmentView : UIxComponent
+{
+ NSString *tabSelection;
+ id appointment;
+ id attendee;
+}
+
+- (id)appointment;
+
+- (NSString *)attributesTabLink;
+- (NSString *)participantsTabLink;
+
+- (NSString *)completeHrefForMethod:(NSString *)_method
+ withParameter:(NSString *)_param
+ forKey:(NSString *)_key;
+
+@end
+
+#endif /* __ZideStoreUI_UIxAppointmentView_H__ */
--- /dev/null
+// $Id$
+
+#include "UIxAppointmentView.h"
+#include "common.h"
+#include <Backend/SxAptManager.h>
+#include <SOGoLogic/SOGoAppointment.h>
+
+
+@interface NSObject(UsedPrivates)
+- (SxAptManager *)aptManagerInContext:(id)_ctx;
+@end
+
+@implementation UIxAppointmentView
+
+- (void)dealloc {
+ [self->appointment release];
+ [self->attendee release];
+ [super dealloc];
+}
+
+
+/* accessors */
+
+
+- (NSString *)tabSelection {
+ NSString *selection;
+
+ selection = [self queryParameterForKey:@"tab"];
+ if(! selection)
+ selection = @"attributes";
+ return selection;
+}
+
+- (void)setAttendee:(id)_attendee {
+ ASSIGN(self->attendee, _attendee);
+}
+- (id)attendee {
+ return self->attendee;
+}
+
+
+/* backend */
+
+
+- (SxAptManager *)aptManager {
+ return [[self clientObject] aptManagerInContext:[self context]];
+}
+
+- (SOGoAppointment *)appointment {
+ if(self->appointment == nil) {
+ NSString *iCalString;
+
+ iCalString = [[self clientObject] valueForKey:@"iCalString"];
+ self->appointment = [[SOGoAppointment alloc] initWithICalString:iCalString];
+ }
+ return self->appointment;
+}
+
+- (NSString *)formattedAptStartTime {
+ NSCalendarDate *date;
+
+ date = [[self appointment] startDate];
+ /* TODO: convert this into display timeZone! */
+ return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"];
+}
+
+- (NSString *)formattedAptEndTime {
+ NSCalendarDate *date;
+
+ date = [[self appointment] endDate];
+ /* TODO: convert this into display timeZone! */
+ return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"];
+}
+
+
+/* hrefs */
+
+
+- (NSString *)attributesTabLink {
+ return [self completeHrefForMethod:[self ownMethodName]
+ withParameter:@"attributes"
+ forKey:@"tab"];
+}
+
+- (NSString *)participantsTabLink {
+ return [self completeHrefForMethod:[self ownMethodName]
+ withParameter:@"participants"
+ forKey:@"tab"];
+}
+
+- (NSString *)debugTabLink {
+ return [self completeHrefForMethod:[self ownMethodName]
+ withParameter:@"debug"
+ forKey:@"tab"];
+}
+
+- (NSString *)completeHrefForMethod:(NSString *)_method
+ withParameter:(NSString *)_param
+ forKey:(NSString *)_key
+{
+ NSString *href;
+
+ [self setQueryParameter:_param forKey:_key];
+ href = [self completeHrefForMethod:[self ownMethodName]];
+ [self setQueryParameter:nil forKey:_key];
+ return href;
+}
+
+@end /* UIxAppointmentView */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ className="UIxPageFrame"
+ title="name"
+>
+
+ <table cellspacing="0" cellpadding="5" width="100%">
+ <tr>
+ <td>
+ <table cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td width="5"/>
+ <td class="window_label">Appointment Viewer</td>
+ <td width="36" align="right" valign="center">
+ <var:component className="UIxWinClose" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <table border="0" cellpadding="2" width="100%" cellspacing="0">
+ <tr bgcolor="#e8e8e0">
+ <td align="left">
+ <span class="aptview_title"><var:string value="formattedAptStartTime" /></span>
+ </td>
+ <td align="right" >
+ <table border='0' cellpadding='0' cellspacing='1'>
+ <tr>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto"
+ href="printview"
+ var:queryDictionary="queryParameters"
+ target="SOGoPrintView"
+ >printview</a>
+ </td>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto"
+ href="edit"
+ var:queryDictionary="queryParameters"
+ >edit</a>
+ </td>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto"
+ href="delete"
+ var:queryDictionary="queryParameters"
+ >delete</a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="100%">
+ <table width="100%" border="0" cellpadding="4" cellspacing="0">
+ <!-- general appointment info -->
+ <tr valign="top">
+ <td align="right" width="15%" bgcolor="#E8E8E0">
+ <span class="aptview_text">Title:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <var:string value="appointment.summary" />
+ </span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%" bgcolor="#E8E8E0">
+ <span class="aptview_text">Location:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <var:string value="appointment.location" />
+ </span>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="100%">
+ <uix:tabview var:selection="tabSelection"
+ const:tabStyle="tab"
+ const:selectedTabStyle="tab_selected"
+ const:bodyStyle="tabview_body"
+ >
+ <uix:tab const:key="attributes"
+ const:label="attributes"
+ var:href="attributesTabLink">
+ <table width="100%" border="0" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <td align="right" width="15%" bgcolor="#E8E8E0">
+ <span class="aptview_text">Start time:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <var:string value="formattedAptStartTime" />
+ </span>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right" width="15%" bgcolor="#E8E8E0">
+ <span class="aptview_text">End time:</span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <var:string value="formattedAptEndTime" />
+ </span>
+ </td>
+ </tr>
+ </table>
+ </uix:tab>
+ <uix:tab const:key="participants"
+ const:label="participants"
+ var:href="participantsTabLink">
+ <table width="100%" border="0" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <td align="left" bgcolor="#E8E8E0">
+ <span class="aptview_title">Email</span>
+ </td>
+ </tr>
+ <var:foreach list="appointment.attendees" item="attendee">
+ <tr valign="top">
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <var:string value="attendee.email" />
+ </span>
+ </td>
+ </tr>
+ </var:foreach>
+ </table>
+ </uix:tab>
+ <uix:tab const:key="debug"
+ const:label="DEBUG"
+ var:href="debugTabLink">
+ OGo ZideStore Server - <var:string value="name"/>
+ <br />
+ Client: <var:string value="clientObject"/>
+ <br />
+ Group: <var:string value="clientObject.group"/><br />
+ Deletable: <var:string value="clientObject.isDeletionAllowed"/><br />
+ Generation: <var:string value="clientObject.zlGenerationCount"/><br />
+ MsgClass: <var:string value="clientObject.outlookMessageClass"/><br />
+
+ <hr />
+ As iCal:<br />
+ <pre><var:string value="clientObject.iCalString"/></pre>
+
+ <hr />
+ As Mail:<br />
+ <pre><var:string value="clientObject.iCalMailString"/></pre>
+
+ </uix:tab>
+ </uix:tabview>
+ </td>
+ </tr>
+ </table>
+</var:component>
--- /dev/null
+/*
+ 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$
+
+#include <NGObjWeb/SoComponent.h>
+
+@class NSArray, NSCalendarDate;
+
+@interface UIxAptTableView : SoComponent
+{
+ NSArray *appointments;
+ id appointment;
+}
+
+/* accessors */
+
+- (NSArray *)appointments;
+- (id)appointment;
+
+@end
+
+#include "common.h"
+
+@implementation UIxAptTableView
+
+- (void)dealloc {
+ [self->appointment release];
+ [self->appointments release];
+ [super dealloc];
+}
+
+/* accessors */
+
+- (void)setAppointments:(NSArray *)_apts {
+ ASSIGN(self->appointments, _apts);
+}
+- (NSArray *)appointments {
+ return self->appointments;
+}
+
+- (void)setAppointment:(id)_apt {
+ ASSIGN(self->appointment, _apt);
+}
+- (id)appointment {
+ return self->appointment;
+}
+
+- (NSString *)appointmentViewURL {
+ id pkey;
+
+ if ((pkey = [[self appointment] valueForKey:@"dateId"]) == nil)
+ return nil;
+
+ return [NSString stringWithFormat:@"%@/view", pkey];
+}
+
+@end /* UIxAptTableView */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<table
+ style="font-size: 11px;"
+ border="0" cellspacing="0" cellpadding="2"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+>
+ <tr>
+ <th>ID</th>
+ <th>Title</th>
+ <th>Time</th>
+ <th>Version</th>
+ <th>Location</th>
+ </tr>
+ <var:foreach list="appointments" item="appointment">
+ <tr>
+ <td><var:string value="appointment.dateId"/></td>
+ <td>
+ <a var:href="appointmentViewURL"
+ ><var:string value="appointment.title"/></a>
+ </td>
+ <td>
+ <var:string value="appointment.startDate"
+ const:dateformat="%Y-%m-%d %H:%M" />
+ -
+ <var:string value="appointment.endDate"
+ const:dateformat="%Y-%m-%d %H:%M" />
+ </td>
+ <td><var:string value="appointment.objectVersion"/></td>
+ <td><var:string value="appointment.location"/></td>
+ </tr>
+ </var:foreach>
+</table>
--- /dev/null
+/*
+ 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 <NGObjWeb/NGObjWeb.h>
+
+/*
+ Associations:
+
+ methodName -> maps to href
+ prevQueryParameters -> queryDictionary
+ currentQueryParameters -> queryDictionary
+ nextQueryParameters -> queryDictionary
+ label -> user presentable name to display for "this"
+ */
+
+@interface UIxCalBackForthNavView : WOComponent
+{
+}
+
+@end
+
+
+@implementation UIxCalBackForthNavView
+
+- (BOOL)synchronizesVariablesWithBindings {
+ return NO;
+}
+
+@end
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<table xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ border="0"
+ >
+ <tr>
+ <td align="right" valign="middle">
+ <a var:href="^methodName" var:queryDictionary="^prevQueryParameters"><img rsrc:src="previous_week.gif" alt="previous" border="0"/></a>
+ </td>
+ <td align="right" valign="middle" class="button_auto_env">
+ <a var:href="^methodName" var:queryDictionary="^currentQueryParameters" class="button_auto"><var:string value="^label" escapeHTML="NO" /></a>
+ </td>
+ <td align="right" valign="middle">
+ <a var:href="^methodName" var:queryDictionary="^nextQueryParameters"><img rsrc:src="next_week.gif" alt="next" border="0"/></a>
+ </td>
+ </tr>
+</table>
\ No newline at end of file
--- /dev/null
+/*
+ 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 <NGObjWeb/NGObjWeb.h>
+
+
+@interface UIxCalDateLabel : WOComponent
+{
+ NSString *selection;
+ NSCalendarDate *startDate;
+ NSCalendarDate *endDate;
+}
+
+- (NSString *)dayLabel;
+- (NSString *)weekLabel;
+- (NSString *)monthLabel;
+- (NSString *)yearLabel;
+
+@end
+
+
+@implementation UIxCalDateLabel
+
+- (void)dealloc {
+ [self->selection release];
+ [self->startDate release];
+ [self->endDate release];
+ [super dealloc];
+}
+
+- (void)setSelection:(NSString *)_selection {
+ ASSIGN(self->selection, _selection);
+}
+
+- (NSString *)selection {
+ return self->selection;
+}
+
+- (void)setStartDate:(NSCalendarDate *)_date {
+ ASSIGN(self->startDate, _date);
+}
+
+- (NSCalendarDate *)startDate {
+ return self->startDate;
+}
+
+- (void)setEndDate:(NSCalendarDate *)_date {
+ ASSIGN(self->endDate, _date);
+}
+
+- (NSCalendarDate *)endDate {
+ return self->endDate;
+}
+
+- (NSString *)label {
+ NSString *key = [self selection];
+ if([key isEqualToString:@"day"])
+ return [self dayLabel];
+ else if([key isEqualToString:@"week"])
+ return [self weekLabel];
+ else if([key isEqualToString:@"month"])
+ return [self monthLabel];
+ return [self yearLabel];
+}
+
+- (NSString *)dayLabel {
+ return [self->startDate descriptionWithCalendarFormat:@"%Y-%m-%d"];
+}
+
+- (NSString *)weekLabel {
+ NSString *label;
+
+ label = [self->startDate descriptionWithCalendarFormat:@"%B %Y"];
+ if([self->startDate monthOfYear] != [self->endDate monthOfYear]) {
+ NSString *ext;
+
+ ext = [self->endDate descriptionWithCalendarFormat:@"%B %Y"];
+ label = [NSString stringWithFormat:@"<nobr>%@ / %@</nobr>",
+ label,
+ ext];
+ }
+ return label;
+}
+
+- (NSString *)monthLabel {
+ return [self->startDate descriptionWithCalendarFormat:@"%B %Y"];
+}
+
+- (NSString *)yearLabel {
+ return [self->startDate descriptionWithCalendarFormat:@"%Y"];
+}
+
+@end
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<span xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ const:class="window_label"
+><var:string value="label" const:escapeHTML="NO" /></span>
\ No newline at end of file
--- /dev/null
+// $Id$
+
+#include "UIxCalMonthView.h"
+#include <NGExtensions/NGExtensions.h>
+
+
+@interface UIxCalMonthOverview : UIxCalMonthView
+{
+ int dayIndex;
+ int dayOfWeek;
+ int weekOfYear;
+ NSCalendarDate *currentWeekStart;
+}
+
+@end
+
+#include "common.h"
+
+@implementation UIxCalMonthOverview
+
+- (void)dealloc {
+ [self->currentWeekStart release];
+ [super dealloc];
+}
+
+- (void)setDayIndex:(int)_idx {
+ self->dayIndex = _idx;
+}
+
+- (int)dayIndex {
+ return self->dayIndex;
+}
+
+- (void)setDayOfWeek:(int)_day {
+ self->dayOfWeek = _day;
+}
+
+- (int)dayOfWeek {
+ return self->dayOfWeek;
+}
+
+- (void)setCurrentWeekStartDate:(NSCalendarDate *)_date {
+ ASSIGN(self->currentWeekStart, _date);
+}
+
+- (NSCalendarDate *)currentWeekStartDate {
+ return self->currentWeekStart;
+}
+
+- (void)setWeekOfYear:(int)_week {
+ NSCalendarDate *date;
+
+ self->weekOfYear = _week;
+ if(_week == 52 || _week == 53)
+ date = [[self startDate] mondayOfWeek];
+ else
+ date = [self startDate];
+ date = [date mondayOfWeek:_week];
+ [self setCurrentWeekStartDate:date];
+}
+
+- (int)weekOfYear {
+ return self->weekOfYear;
+}
+
+- (int)year {
+ return [[self startDate] yearOfCommonEra];
+}
+
+- (int)month {
+ return [[self startDate] monthOfYear];
+}
+
+- (NSString *)localizedNameOfDayOfWeek {
+ // TODO: move this to some locale method
+ static char *dayNames[] = {
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ };
+ return [[[NSString alloc] initWithCString:
+ dayNames[self->dayOfWeek]] autorelease];
+}
+
+- (NSDictionary *)currentWeekQueryParameters {
+ return [self queryParametersBySettingSelectedDate:self->currentWeekStart];
+}
+
+
+/* style sheet */
+
+
+- (NSString *)weekStyle {
+ if([self->currentWeekStart isDateInSameWeek:[NSCalendarDate date]])
+ return @"monthoverview_week_hilite";
+ return @"monthoverview_week";
+}
+
+- (NSString *)contentStyle {
+ if([self->currentDay isToday])
+ return @"monthoverview_content_hilite";
+ else if([self->currentDay monthOfYear] != [[self startDate] monthOfYear])
+ return @"monthoverview_content_dimmed";
+ return @"monthoverview_content";
+}
+
+
+/* appointments */
+
+
+- (NSArray *)appointments {
+ return [self fetchCoreInfos];
+}
+
+@end /* UIxCalMonthOverview */
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<var:component className="UIxPageFrame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+>
+
+ <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
+ <tr>
+ <td class="wintitle">
+ <table cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td width="5"/>
+ <td class="wintitle"><var:component className="UIxCalDateLabel" startDate="startDate" endDate="endDate" const:selection="month" /></td>
+ <td width="36" align="right" valign="center">
+ <var:component className="UIxWinClose" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td id="skywinbodycell" class="wincontent">
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr bgcolor="#e8e8e0">
+ <td align="left" valign="middle" width="80%">TODO: controls</td><!-- 99% -->
+ <td align="right">
+ <var:component className="UIxCalBackForthNavView"
+ methodName="ownMethodName"
+ prevQueryParameters="prevMonthQueryParameters"
+ currentQueryParameters="todayQueryParameters"
+ nextQueryParameters="nextMonthQueryParameters"
+ const:label="this month"
+ />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td id="skywinbodycell" class="wincontent">
+ <table border="0" width="100%" cellpadding="0" cellspacing="0">
+ <tr>
+ <td colspan="2">
+ <var:component className="UIxCalSelectTab"
+ const:selection="month"
+ currentDate="selectedDate"
+ >
+ <table border="0" cellpadding="4" width="100%" cellspacing="2">
+ <tr>
+ <td align="right" bgcolor="#e8e8e0">
+ <table border='0' cellpadding='0' cellspacing='1'>
+ <tr>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto" href="monthprintview" var:queryDictionary="queryParameters" target="SOGoPrintView">printview</a>
+ </td>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto" href="proposal" var:queryDictionary="queryParameters">proposal</a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <var:month-overview
+ list="appointments"
+ item="appointment"
+ currentDay="currentDay"
+ index="dayIndex"
+ year="year"
+ month="month"
+ const:startDateKey = "startDate"
+ const:endDateKey = "endDate"
+
+ const:class="monthoverview"
+ contentStyle="contentStyle"
+ const:width="100%"
+ >
+ <var:month-info>
+ <var:if condition="hasHolidayInfo">
+ <var:string value="holidayInfo" const:class="monthoverview_holidayinfo" />
+ </var:if>
+ <var:foreach list="allDayApts" item="appointment">
+ <a var:href="appointmentViewURL"><var:string value="shortTextForApt" /></a>
+ </var:foreach>
+ </var:month-info>
+ <var:month-label const:orientation="top"
+ dayOfWeek="dayOfWeek"
+ const:class="monthoverview_title"
+ >
+ <var:string value="localizedNameOfDayOfWeek" />
+ </var:month-label>
+ <var:month-label const:orientation="left"
+ weekOfYear="weekOfYear"
+ class="weekStyle"
+ >
+ <a href="weekoverview"
+ var:queryDictionary="currentWeekQueryParameters"
+ ><var:string value="weekOfYear" /></a>
+ </var:month-label>
+
+ <var:month-title class="contentStyle">
+ <span class="monthoverview_day">
+ <a href="dayoverview"
+ var:queryDictionary="currentDayQueryParameters"
+ ><var:string value="currentDay.dayOfMonth" /></a>
+ </span>
+ <br />
+ <span class="monthoverview_day_new">
+ <a href="new"
+ var:queryDictionary="currentDayQueryParameters"
+ >[new]</a>
+ </span>
+ </var:month-title>
+
+ <var:month>
+ <a var:href="appointmentViewURL"
+ class="monthoverview_content_link"
+ var:title="shortTextForApt"
+ var:queryDictionary="currentDayQueryParameters"
+ ><var:string value="shortTitleForApt" /></a>
+ </var:month>
+ </var:month-overview>
+ </var:component>
+ </td>
+ </tr>
+ <tr bgcolor="#F5F5E9">
+ <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+ <td align="right"><img border="0" alt="" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/corner_right.gif"/></td>
+ </tr>
+ <tr>
+ <td colspan="2" bgcolor="#F5F5E9">
+ <table border="0" width="100%" cellpadding="10" cellspacing="0">
+ <tr/>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+<!--
+ <hr />
+ OGo ZideStore Server - <var:string value="name"/>
+ <br />
+ Client: <var:string value="clientObject"/>
+ <br />
+ Appointments: #<var:string value="appointments.count"/>
+ from <var:string value="startDate" />
+ to <var:string value="endDate" />
+ <br />
+
+
+ <hr />
+
+ Appointments:
+ <var:component className="UIxAptTableView" appointments="appointments"/>
+ -->
+ <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
+</var:component>
--- /dev/null
+// $Id$
+
+#ifndef __ZideStoreUI_UIxCalMonthView_H__
+#define __ZideStoreUI_UIxCalMonthView_H__
+
+#include "UIxCalView.h"
+
+/*
+ UIxCalMonthView
+
+ Abstract superclass for views which display months.
+*/
+
+@interface UIxCalMonthView : UIxCalView
+{
+}
+
+- (NSDictionary *)prevMonthQueryParameters;
+- (NSDictionary *)nextMonthQueryParameters;
+
+@end
+
+#endif /* __ZideStoreUI_UIxCalMonthView_H__ */
--- /dev/null
+// $Id$
+
+#include "UIxCalMonthView.h"
+#include "common.h"
+
+@implementation UIxCalMonthView
+
+- (NSCalendarDate *)startDate {
+ return [[super startDate] firstDayOfMonth];
+}
+
+- (NSCalendarDate *)endDate {
+ NSCalendarDate *startDate = [self startDate];
+ return [startDate dateByAddingYears:0
+ months:0
+ days:[startDate numberOfDaysInMonth]
+ hours:0
+ minutes:0
+ seconds:0];
+}
+
+/* URLs */
+
+
+- (NSDictionary *)prevMonthQueryParameters {
+ NSCalendarDate *date;
+
+ date = [[self startDate] dateByAddingYears:0
+ months:-1
+ days:0
+ hours:0
+ minutes:0
+ seconds:0];
+ return [self queryParametersBySettingSelectedDate:date];
+}
+
+- (NSDictionary *)nextMonthQueryParameters {
+ NSCalendarDate *date;
+
+ date = [[self startDate] dateByAddingYears:0
+ months:1
+ days:0
+ hours:0
+ minutes:0
+ seconds:0];
+ return [self queryParametersBySettingSelectedDate:date];
+}
+
+@end /* UIxCalMonthView */
--- /dev/null
+/*
+ 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/UIxComponent.h>
+#include <NGObjWeb/NGObjWeb.h>
+#include <NGExtensions/NGExtensions.h>
+
+
+@interface UIxCalSelectTab : UIxComponent
+{
+ NSString *selection;
+ NSCalendarDate *currentDate;
+}
+
+@end
+
+
+@implementation UIxCalSelectTab
+
+- (void)dealloc {
+ [self->selection release];
+ [self->currentDate release];
+ [super dealloc];
+}
+
+- (void)setSelection:(NSString *)_selection {
+ ASSIGN(self->selection, _selection);
+}
+
+- (NSString *)selection {
+ return self->selection;
+}
+
+- (void)setCurrentDate:(NSCalendarDate *)_date {
+ ASSIGN(self->currentDate, _date);
+}
+
+- (NSCalendarDate *)currentDate {
+ return self->currentDate;
+}
+
+
+/* labels */
+
+
+- (NSString *)dayLabel {
+ return [self->currentDate descriptionWithCalendarFormat:@"%d"];
+}
+
+- (NSString *)weekLabel {
+ return [NSString stringWithFormat:@"Week %d", [self->currentDate weekOfYear]];
+}
+
+- (NSString *)monthLabel {
+ return [self->currentDate descriptionWithCalendarFormat:@"%B"];
+}
+
+- (NSString *)yearLabel {
+ return [self->currentDate descriptionWithCalendarFormat:@"%Y"];
+}
+
+
+/* hrefs */
+
+
+- (NSString *)daytabLink {
+ return [self completeHrefForMethod:@"dayoverview"];
+}
+
+- (NSString *)weektabLink {
+ return [self completeHrefForMethod:@"weekoverview"];
+}
+
+- (NSString *)monthtabLink {
+ return [self completeHrefForMethod:@"monthoverview"];
+}
+
+- (NSString *)yeartabLink {
+ return [self completeHrefForMethod:@"yearoverview"];
+}
+
+
+@end
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+
+<uix:tabview xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ xmlns:uix="OGo:uix"
+ var:selection="selection"
+ const:tabStyle="tab"
+ const:selectedTabStyle="tab_selected"
+ const:bodyStyle="tabview_body"
+>
+ <uix:tab const:key="day" var:label="dayLabel" var:href="daytabLink">
+ <var:component-content />
+ </uix:tab>
+ <uix:tab const:key="week" var:label="weekLabel" var:href="weektabLink">
+ <var:component-content />
+ </uix:tab>
+ <uix:tab const:key="month" var:label="monthLabel" var:href="monthtabLink">
+ <var:component-content />
+ </uix:tab>
+ <uix:tab const:key="year" var:label="yearLabel" var:href="yeartabLink">
+ <var:component-content />
+ </uix:tab>
+</uix:tabview>
--- /dev/null
+// $Id$
+
+#ifndef __ZideStoreUI_UIxCalView_H__
+#define __ZideStoreUI_UIxCalView_H__
+
+#include <Common/UIxComponent.h>
+
+@class NSArray, NSCalendarDate;
+@class SxAptManager, SxAptSetIdentifier;
+
+@interface UIxCalView : UIxComponent
+{
+ NSArray *appointments;
+ id appointment;
+ NSCalendarDate *currentDay;
+}
+
+/* accessors */
+
+- (NSArray *)appointments;
+- (id)appointment;
+
+- (NSDictionary *)aptTypeDict;
+- (NSString *)aptTypeLabel;
+- (NSString *)aptTypeIcon;
+- (NSString *)shortTextForApt;
+- (NSString *)shortTitleForApt;
+
+/* related to current day */
+- (void)setCurrentDay:(NSCalendarDate *)_day;
+- (NSCalendarDate *)currentDay;
+- (NSString *)currentDayName;
+- (NSArray *)allDayApts;
+- (BOOL)hasDayInfo;
+- (BOOL)hasHoldidayInfo;
+
+
+- (BOOL)showFullNames;
+- (BOOL)showAMPMDates;
+- (NSCalendarDate *)referenceDateForFormatter;
+
+/* URLs */
+
+- (NSString *)appointmentViewURL;
+
+/* backend */
+
+- (SxAptManager *)aptManager;
+- (SxAptSetIdentifier *)aptSetID;
+
+/* fetching */
+
+- (NSCalendarDate *)startDate;
+- (NSCalendarDate *)endDate;
+- (NSArray *)fetchGIDs;
+- (NSArray *)fetchCoreInfos;
+
+/* date selection */
+- (NSDictionary *)todayQueryParameters;
+- (NSDictionary *)currentDayQueryParameters;
+- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date;
+- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
+ inDictionary:(NSMutableDictionary *)_qp;
+
+@end
+
+#endif /* __ZideStoreUI_UIxCalView_H__ */
--- /dev/null
+// $Id$
+
+#include "UIxCalView.h"
+#include "common.h"
+#include <Backend/SxAptManager.h>
+#include "UIxAppointmentFormatter.h"
+
+@interface NSObject(UsedPrivates)
+- (SxAptManager *)aptManagerInContext:(id)_ctx;
+@end
+
+@implementation UIxCalView
+
+- (void)dealloc {
+ [self->appointment release];
+ [self->appointments release];
+ [self->currentDay release];
+ [super dealloc];
+}
+
+/* accessors */
+
+
+- (void)setAppointments:(NSArray *)_apts {
+ ASSIGN(self->appointments, _apts);
+}
+- (NSArray *)appointments {
+ return self->appointments;
+}
+
+- (void)setAppointment:(id)_apt {
+ ASSIGN(self->appointment, _apt);
+}
+- (id)appointment {
+ return self->appointment;
+}
+
+- (NSDictionary *)aptTypeDict {
+ return nil;
+}
+
+- (NSString *)aptTypeLabel {
+ return @"aptLabel";
+}
+
+- (NSString *)aptTypeIcon {
+ return @"";
+}
+
+- (NSString *)shortTextForApt {
+ UIxAppointmentFormatter *f;
+
+ f = [UIxAppointmentFormatter formatterWithFormat:
+ @"%S - %E;\n%T;\n%L;\n%5P;\n%50R"];
+ [f setRelationDate:[self referenceDateForFormatter]];
+ [f setShowFullNames:[self showFullNames]];
+ if([self showAMPMDates])
+ [f switchToAMPMTimes:YES];
+
+ return [NSString stringWithFormat:@"%@:\n%@",
+ [self aptTypeLabel],
+ [f stringForObjectValue:self->appointment]];
+}
+
+- (NSString *)shortTitleForApt {
+ NSString *title;
+
+ title = [self->appointment valueForKey:@"title"];
+ if([title length] > 12) {
+ title = [NSString stringWithFormat:@"%@...",
+ [title substringToIndex:11]];
+ }
+ return title;
+}
+
+- (NSCalendarDate *)referenceDateForFormatter {
+ return [self selectedDate];
+}
+
+/* current day related */
+
+- (void)setCurrentDay:(NSCalendarDate *)_day {
+ ASSIGN(self->currentDay, _day);
+}
+- (NSCalendarDate *)currentDay {
+ return self->currentDay;
+}
+
+- (NSString *)currentDayName {
+ // TODO: this is slow, use locale dictionary to speed this up
+ return [self->currentDay descriptionWithCalendarFormat:@"%A"];
+}
+
+- (BOOL)hasDayInfo {
+ return [self hasHoldidayInfo] || ([[self allDayApts] count] != 0);
+}
+
+- (BOOL)hasHoldidayInfo {
+ return NO;
+}
+
+- (NSArray *)allDayApts {
+ return [NSArray array];
+}
+
+
+/* defaults */
+
+
+- (BOOL)showFullNames {
+ return YES;
+}
+
+- (BOOL)showAMPMDates {
+ return NO;
+}
+
+
+/* URLs */
+
+- (NSString *)appointmentViewURL {
+ id pkey;
+
+ if ((pkey = [[self appointment] valueForKey:@"dateId"]) == nil)
+ return nil;
+
+ return [NSString stringWithFormat:@"%@/view", pkey];
+}
+
+
+/* backend */
+
+- (SxAptManager *)aptManager {
+ return [[self clientObject] aptManagerInContext:[self context]];
+}
+- (SxAptSetIdentifier *)aptSetID {
+ return [[self clientObject] aptSetID];
+}
+
+/* resource URLs (TODO?) */
+
+- (NSString *)resourcePath {
+ return @"/ZideStore.woa/WebServerResources/";
+}
+
+- (NSString *)favIconPath {
+ return [[self resourcePath] stringByAppendingPathComponent:@"favicon.ico"];
+}
+- (NSString *)cssPath {
+ NSString *path;
+
+ // TODO: there should be reusable functionality for that!
+ path = @"ControlPanel/Products/ZideStoreUI/Resources/zidestoreui.css";
+ return [[self context] urlWithRequestHandlerKey:@"so"
+ path:path
+ queryString:nil];
+}
+
+- (NSString *)calCSSPath {
+ NSString *path;
+
+ // TODO: there should be reusable functionality for that!
+ path = @"ControlPanel/Products/ZideStoreUI/Resources/calendar.css";
+ return [[self context] urlWithRequestHandlerKey:@"so"
+ path:path
+ queryString:nil];
+}
+
+/* fetching */
+
+- (NSCalendarDate *)startDate {
+ return [self selectedDate];
+}
+- (NSCalendarDate *)endDate {
+ return [[self startDate] tomorrow];
+}
+
+- (NSArray *)fetchGIDs {
+ return [[self aptManager] gidsOfAppointmentSet:[self aptSetID]
+ from:[self startDate] to:[self endDate]];
+}
+
+- (NSArray *)fetchCoreInfos {
+ NSArray *gids;
+
+ if (self->appointments)
+ return self->appointments;
+
+ [self logWithFormat:@"fetching (%@ => %@) ...",
+ [self startDate], [self endDate]];
+ gids = [self fetchGIDs];
+ [self logWithFormat:@" %i GIDs ...", [gids count]];
+
+ self->appointments =
+ [[[self aptManager] coreInfoOfAppointmentsWithGIDs:gids
+ inSet:[self aptSetID]] retain];
+
+ [self logWithFormat:@"fetched %i records.", [self->appointments count]];
+ return self->appointments;
+}
+
+
+/* date selection & conversion */
+
+
+- (NSDictionary *)todayQueryParameters {
+ NSCalendarDate *date;
+
+ date = [NSCalendarDate date]; /* today */
+ return [self queryParametersBySettingSelectedDate:date];
+}
+
+- (NSDictionary *)currentDayQueryParameters {
+ return [self queryParametersBySettingSelectedDate:self->currentDay];
+}
+
+- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date {
+ NSMutableDictionary *qp;
+
+ qp = [[self queryParameters] mutableCopy];
+ [self setSelectedDateQueryParameter:_date inDictionary:qp];
+ return [qp autorelease];
+}
+
+- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
+ inDictionary:(NSMutableDictionary *)_qp;
+{
+ if(_newDate != nil)
+ [_qp setObject:[self dateStringForDate:_newDate]
+ forKey:@"day"];
+ else
+ [_qp removeObjectForKey:@"day"];
+}
+
+@end /* UIxCalView */
--- /dev/null
+/*
+ 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 "UIxCalWeekView.h"
+
+@interface UIxCalWeekOverview : UIxCalWeekView
+{
+ int dayIndex;
+}
+
+@end
+
+#include "common.h"
+#include <Backend/SxAptManager.h>
+
+
+@implementation UIxCalWeekOverview
+
+- (NSArray *)appointments {
+ return [self fetchCoreInfos];
+}
+
+- (void)setDayIndex:(char)_idx {
+ NSCalendarDate *d;
+
+ if ((self->dayIndex == _idx) && (self->currentDay != nil))
+ return;
+
+ self->dayIndex = _idx;
+
+ if (_idx > 0) {
+ d = [[self startDate]
+ dateByAddingYears:0 months:0 days:_idx
+ hours:0 minutes:0 seconds:0];
+ }
+ else
+ d = [self startDate];
+
+ [self setCurrentDay:d];
+}
+
+- (int)dayIndex {
+ return self->dayIndex;
+}
+
+/* style sheet */
+
+- (NSString *)titleStyle {
+ if([self->currentDay isToday])
+ return @"weekoverview_title_hilite";
+ return @"weekoverview_title";
+}
+
+- (NSString *)contentStyle {
+ if([self->currentDay isToday])
+ return @"weekoverview_content_hilite";
+ return @"weekoverview_content";
+}
+
+@end /* UIxCalWeekOverview */
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ xmlns:uix="OGo:uix"
+ className="UIxPageFrame"
+ title="name">
+
+ <!-- $Id: SkyNews.html,v 1.3 2003/12/22 16:53:55 helge Exp $ -->
+ <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
+ <tr>
+ <td class="wintitle">
+ <table cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td width="5"/>
+ <td class="wintitle"><var:component className="UIxCalDateLabel" startDate="startDate" endDate="endDate" const:selection="week" /></td>
+ <td width="36" align="right" valign="center">
+ <var:component className="UIxWinClose" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td id="skywinbodycell" class="wincontent">
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr bgcolor="#e8e8e0">
+ <td align="left" valign="middle" width="80%">TODO: controls</td><!-- 99% -->
+ <td align="right">
+ <var:component className="UIxCalBackForthNavView"
+ methodName="ownMethodName"
+ prevQueryParameters="prevWeekQueryParameters"
+ currentQueryParameters="todayQueryParameters"
+ nextQueryParameters="nextWeekQueryParameters"
+ const:label="this week"
+ />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td id="skywinbodycell" class="wincontent">
+ <table border="0" width="100%" cellpadding="0" cellspacing="0">
+ <tr>
+ <td colspan="2">
+ <var:component className="UIxCalSelectTab" const:selection="week" currentDate="selectedDate">
+
+ <table border="0" cellpadding="4" width="100%" cellspacing="2">
+ <tr>
+ <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
+ <table border='0' cellpadding='0' cellspacing='0'>
+ <tr>
+ <td><img rsrc:src="icon_apt_overview_inactive.gif" title="Overview" alt="Overview" border="0" valign="top" /></td>
+ <td><a href="weekchartview"><img rsrc:src="icon_apt_chart.gif" title="Chart" alt="Chart" border="0" valign="top" /></a></td>
+ <td><a href="weeklistview"><img rsrc:src="icon_apt_list.gif" title="List" alt="List" border="0" valign="top" /></a></td>
+ <td>
+ <a href="weekcolumnview"><img rsrc:src="icon_apt_column_view.gif" title="Columns" alt="Columns" border="0" valign="top" /></a>
+ </td>
+ </tr>
+ </table>
+ </td>
+
+ <td align="right" bgcolor="#e8e8e0">
+ <table border='0' cellpadding='0' cellspacing='1'>
+ <tr>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto" href="weekprintview" var:queryDictionary="queryParameters" target="SOGoPrintView">printview</a>
+ </td>
+ <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
+ <a class="button_auto" href="proposal" var:queryDictionary="queryParameters">proposal</a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <var:week-overview list="appointments"
+ item="appointment"
+ weekStart="startDate"
+ dayIndex="dayIndex"
+ const:startDateKey="startDate"
+ const:endDateKey="endDate"
+ const:titleStyle="weekoverview_title"
+ contentStyle="contentStyle"
+ >
+ <var:week-title>
+ <table cellpadding="0"
+ width="100%"
+ border="0"
+ cellspacing="0"
+ var:class="titleStyle"
+ >
+ <tr>
+ <td align="left" valign="top">
+ <a href="dayoverview"
+ var:queryDictionary="currentDayQueryParameters"
+ class="weekoverview_title_daylink"
+ ><var:string value="currentDay.dayOfMonth" /></a>
+ </td>
+ <td align="center" valign="top" width="97%">
+ <var:string value="currentDayName" /><br />
+ [<a href="new"
+ var:queryDictionary="currentDayQueryParameters"
+ class="weekoverview_title_newlink"
+ >new</a>]
+ </td>
+ </tr>
+ </table>
+ </var:week-title>
+ <var:if condition="hasDayInfo">
+ <var:week-info>
+ <var:if condition="hasHolidayInfo">
+ <var:string value="holidayInfo" const:class="weekoverview_holidayinfo" />
+ </var:if>
+ <var:foreach list="allDayApts" item="appointment">
+ <a var:href="appointmentViewURL"
+ var:queryDictionary="currentDayQueryParameters"
+ ><var:string value="shortTextForApt" /></a>
+ </var:foreach>
+ </var:week-info>
+ </var:if>
+ <var:week>
+ <a var:href="appointmentViewURL"><var:string value="appointment.title"/></a>
+ </var:week>
+ </var:week-overview>
+ </var:component>
+ </td>
+ </tr>
+ <tr bgcolor="#F5F5E9">
+ <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+ <td align="right"><img border="0" alt="" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/corner_right.gif"/></td>
+ </tr>
+ <tr>
+ <td colspan="2" bgcolor="#F5F5E9">
+ <table border="0" width="100%" cellpadding="10" cellspacing="0">
+ <tr/>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <!--
+ <hr />
+ <var:string value="thisWeekQueryParameters" />
+ -->
+ <!--
+ <hr/>
+
+ Appointments:
+ <var:component className="UIxAptTableView" appointments="appointments"/>
+ -->
+ <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
+
+</var:component>
--- /dev/null
+// $Id$
+
+#ifndef __ZideStoreUI_UIxCalWeekView_H__
+#define __ZideStoreUI_UIxCalWeekView_H__
+
+#include "UIxCalView.h"
+
+@interface UIxCalWeekView : UIxCalView
+{
+}
+
+/* Query Parameters */
+
+- (NSDictionary *)prevWeekQueryParameters;
+- (NSDictionary *)nextWeekQueryParameters;
+
+@end
+
+#endif /* __ZideStoreUI_UIxCalWeekView_H__ */
--- /dev/null
+// $Id$
+
+#include "UIxCalWeekView.h"
+#include "common.h"
+
+@implementation UIxCalWeekView
+
+- (NSCalendarDate *)startDate {
+ return [[super startDate] mondayOfWeek];
+}
+
+- (NSCalendarDate *)endDate {
+ return [[self startDate] dateByAddingYears:0 months:0 days:7
+ hours:0 minutes:0 seconds:0];
+}
+
+/* URLs */
+
+- (NSDictionary *)prevWeekQueryParameters {
+ NSCalendarDate *date;
+
+ date = [[self startDate] dateByAddingYears:0 months:0 days:-7
+ hours:0 minutes:0 seconds:0];
+ return [self queryParametersBySettingSelectedDate:date];
+}
+
+- (NSDictionary *)nextWeekQueryParameters {
+ NSCalendarDate *date;
+
+ date = [[self startDate] dateByAddingYears:0 months:0 days:7
+ hours:0 minutes:0 seconds:0];
+ return [self queryParametersBySettingSelectedDate:date];
+}
+
+@end /* UIxCalWeekView */
--- /dev/null
+# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
+
+SUBMINOR_VERSION:=1
+
+# 1.1.0 requires NGObjWeb 4.2.202
--- /dev/null
+{
+ "__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 = SchedulerUIProduct; } );
+
+ classes = (
+ );
+
+ WOComponents = (
+ );
+ };
+}
--- /dev/null
+/*
+ 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: common.h,v 1.1 2003/11/24 01:24:40 helge Exp $
+
+#import <Foundation/Foundation.h>
+
+#if LIB_FOUNDATION_LIBRARY
+# include <Foundation/exceptions/GeneralExceptions.h>
+#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
+# include <NGExtensions/NGObjectMacros.h>
+# include <NGExtensions/NSString+Ext.h>
+#endif
+
+#include <NGExtensions/NGExtensions.h>
+#include <NGObjWeb/NGObjWeb.h>
+#include <NGObjWeb/SoObjects.h>
--- /dev/null
+{
+ requires = ( MAIN, CommonUI );
+
+ publicResources = (
+ previous_week.gif,
+ next_week.gif,
+ icon_apt_chart.gif,
+ icon_apt_overview.gif,
+ icon_apt_chart_inactive.gif,
+ icon_apt_overview_inactive.gif,
+ icon_apt_column_view.gif,
+ icon_apt_list.gif,
+ icon_apt_list_inactive.gif
+ );
+
+ factories = {
+ };
+
+ categories = {
+ SxAppointmentFolder = {
+ methods = {
+ "weekoverview" = {
+ protectedBy = "View";
+ pageName = "UIxCalWeekOverview";
+ };
+ "weekchartview" = {
+ protectedBy = "View";
+ pageName = "UIxCalWeekOverview";
+ };
+ "weeklistview" = {
+ protectedBy = "View";
+ pageName = "UIxCalWeekOverview";
+ };
+ "weekcolumnview" = {
+ protectedBy = "View";
+ pageName = "UIxCalWeekOverview";
+ };
+ "weekprintview" = {
+ protectedBy = "View";
+ pageName = "UIxCalWeekOverview";
+ };
+ "monthoverview" = {
+ protectedBy = "View";
+ pageName = "UIxCalMonthOverview";
+ };
+ "new" = {
+ protectedBy = "View";
+ pageName = "UIxAppointmentEditor";
+ };
+ };
+ };
+
+ SxAppointment = {
+ methods = {
+ "view" = {
+ protectedBy = "View";
+ pageName = "UIxAppointmentView";
+ };
+ "edit" = {
+ protectedBy = "View";
+ pageName = "UIxAppointmentEditor";
+ };
+ "save" = {
+ protectedBy = "View";
+ pageName = "UIxAppointmentEditor";
+ actionName = "save";
+ };
+ };
+ };
+ };
+}