Commits

Christian Fischer committed 797d335

Version 0.1 des Kalenders

Comments (0)

Files changed (28)

calendar.kdevelop

+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>Christian Fischer</author>
+    <email>baldur@Erinyes</email>
+    <version>0.1</version>
+    <projectmanagement>KDevScriptProject</projectmanagement>
+    <primarylanguage>PHP</primarylanguage>
+    <keywords>
+      <keyword>PHP</keyword>
+    </keywords>
+    <ignoreparts/>
+    <versioncontrol>kdevsubversion</versioncontrol>
+    <projectname>calendar</projectname>
+  </general>
+  <kdevscriptproject>
+    <general>
+      <activedir/>
+      <includepatterns>*.php,*.phps,*.php3,*.inc</includepatterns>
+    </general>
+    <run>
+      <directoryradio>executable</directoryradio>
+    </run>
+  </kdevscriptproject>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>c++_bugs_gcc</toc>
+      <toc>clanlib</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>libc</toc>
+      <toc>libstdc++</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>stl</toc>
+      <toc>sw</toc>
+      <toc>wxwidgets_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+  </kdevdoctreeview>
+  <kdevphpsupport>
+    <codeHelp>
+      <codeCompletion>true</codeCompletion>
+      <codeHinting>true</codeHinting>
+      <realtimeParsing>true</realtimeParsing>
+    </codeHelp>
+  </kdevphpsupport>
+  <kdevfilecreate>
+    <useglobaltypes>
+      <type ext="php" />
+    </useglobaltypes>
+  </kdevfilecreate>
+  <kdevfileview>
+    <groups>
+      <group pattern="*.php;*.phps;*.php3" name="PHP files" />
+      <group pattern="*.inc" name="Include files" />
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+    </tree>
+  </kdevfileview>
+  <substmap>
+    <APPNAME>calendar</APPNAME>
+    <APPNAMELC>calendar</APPNAMELC>
+    <APPNAMESC>Calendar</APPNAMESC>
+    <APPNAMEUC>CALENDAR</APPNAMEUC>
+    <AUTHOR>Christian Fischer</AUTHOR>
+    <EMAIL>baldur@Erinyes</EMAIL>
+    <LICENSE>LGPL</LICENSE>
+    <LICENSEFILE>COPYING.LIB</LICENSEFILE>
+    <VERSION>0.1</VERSION>
+    <YEAR>2007</YEAR>
+    <dest>/data/src/wbb2/src/wbb3/modules/calendar</dest>
+  </substmap>
+</kdevelop>

calendar/config/groupoptions.xml

+<?xml version="1.0"?>
+<!DOCTYPE data SYSTEM "http://www.woltlab.com/DTDs/options.dtd">
+<data>	
+	<import>
+		<categories>
+			<category name="user.calendar">
+				<parent>user</parent>
+			</category>
+			<category name="mod.calendar">
+				<parent>mod</parent>
+			</category>
+		</categories>
+		
+		<options>
+			<option name="user.calendar.canEnter">
+				<categoryname>user.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>1</showorder>
+				<enableoptions>user.calendar.canViewEvents,user.calendar.canCreateEvents</enableoptions>
+			</option>
+			<option name="user.calendar.canViewEvents">
+				<categoryname>user.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>2</showorder>
+				<enableoptions>user.calendar.canSignupEvents</enableoptions>
+			</option>
+			<option name="user.calendar.canCreateEvents">
+				<categoryname>user.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>3</showorder>
+			</option>
+			<option name="user.calendar.canSignupEvents">
+				<categoryname>user.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>4</showorder>
+			</option>
+			<option name="mod.calendar.canEditEvents">
+				<categoryname>mod.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>1</showorder>
+			</option>
+			<option name="mod.calendar.canChangeSignupState">
+				<categoryname>mod.calendar</categoryname>
+				<optiontype>boolean</optiontype>
+				<defaultvalue>0</defaultvalue>
+				<showorder>2</showorder>
+			</option>
+		</options>
+	</import>
+</data>

calendar/config/headermenu.xml

+<?xml version="1.0"?>
+<!DOCTYPE import SYSTEM "DTD/import.dtd">
+<data>	
+	<import>
+		<headermenuitem name="net.northshirebund.wbb.calendar.title">
+			<icon>icon/calendarM.png</icon>
+			<link>index.php?page=Calendar</link>
+			<showorder>3</showorder>
+			<permissions>user.calendar.canEnter</permissions> 
+		</headermenuitem>
+	</import>
+</data>

calendar/config/install.sql

+-- 
+-- Tabellenstruktur für Tabelle `wcf1_calendar_event`
+-- 
+
+CREATE TABLE `wcf1_calendar_event` (
+  `eventID` int(10) unsigned NOT NULL auto_increment,
+  `eventType` varchar(32) NOT NULL,
+  `userID` int(10) unsigned NOT NULL,
+  `eventPostTime` int(10) unsigned NOT NULL,
+  `eventTime` int(10) unsigned NOT NULL,
+  `duration` varchar(255) NOT NULL,
+  `subject` varchar(255) NOT NULL,
+  `message` mediumtext NOT NULL,
+  `signupEnabled` tinyint(1) unsigned NOT NULL default '0',
+  `signupCount` mediumint(5) unsigned NOT NULL default '0',
+  `signupMax` mediumint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`eventID`)
+);
+
+-- --------------------------------------------------------
+
+-- 
+-- Tabellenstruktur für Tabelle `wcf1_calendar_event_signup`
+-- 
+
+CREATE TABLE `wcf1_calendar_event_signup` (
+  `eventID` int(10) NOT NULL,
+  `userID` int(10) NOT NULL,
+  `signupTime` int(10) NOT NULL,
+  `signupUpdateTime` int(10) NOT NULL,
+  `signupMessage` text NOT NULL,
+  `signupState` char(1) NOT NULL,
+  `signupStateModerated` char(1) NOT NULL,
+  PRIMARY KEY  (`eventID`,`userID`)
+);

calendar/config/pagelocation.xml

+<?xml version="1.0"?>
+<!DOCTYPE data SYSTEM "http://www.woltlab.com/DTDs/pageLocations.dtd">
+<data>	
+	<import>
+		<pagelocation name="wcf.usersOnline.location.calendar">
+			<pattern><![CDATA[index\.php\?page=Calendar]]></pattern>
+		</pagelocation>
+		<pagelocation name="wcf.usersOnline.location.event.view">
+			<pattern><![CDATA[index\.php\?page=CalendarViewEvent&.*eventID=(\d+)]]></pattern>
+			<classpath>lib/data/page/location/CalendarEventLocation.class.php</classpath>
+		</pagelocation>
+		<pagelocation name="wcf.usersOnline.location.event.edit">
+			<pattern><![CDATA[index\.php\?form=CalendarEditEvent&.*eventID=(\d+)]]></pattern>
+			<classpath>lib/data/page/location/CalendarEventLocation.class.php</classpath>
+		</pagelocation>
+		<pagelocation name="wcf.usersOnline.location.event.add">
+			<pattern><![CDATA[index\.php\?form=CalendarAddEvent]]></pattern>
+		</pagelocation>
+	</import>
+</data>

calendar/dist/net.northshirebund.wbb.calendar-0.1.tar

Binary file added.

calendar/dist/net.northshirebund.wbb.calendar-0.1.tar.gz

Binary file added.

calendar/dist/net.northshirebund.wbb.calendar-0.1.zip

Binary file added.

calendar/files/acp/calendar_install.php

+<?php
+
+// registered users: can view the calendar, add events and signup to them
+$sql = "UPDATE     wcf".WCF_N."_group_option_value
+    SET    optionValue = 1
+    WHERE    groupID IN (3)
+        AND optionID IN (
+            SELECT    optionID
+            FROM    wcf".WCF_N."_group_option
+            WHERE    optionName IN ('user.calendar.canEnter', 'user.calendar.canViewEvents', 'user.calendar.canCreateEvents', 'user.calendar.canSignupEvents')
+        )
+        AND optionValue = '0'";
+WCF::getDB()->sendQuery($sql);
+
+
+// guests: can only view the calendar and events, but cannot add events or signup to them
+$sql = "UPDATE     wcf".WCF_N."_group_option_value
+    SET    optionValue = 1
+    WHERE    groupID IN (2)
+        AND optionID IN (
+            SELECT    optionID
+            FROM    wcf".WCF_N."_group_option
+            WHERE    optionName IN ('user.calendar.canEnter', 'user.calendar.canViewEvents')
+        )
+        AND optionValue = '0'";
+WCF::getDB()->sendQuery($sql);
+
+
+// administrators & super moderators: can edit events and change the signup state of users
+$sql = "UPDATE     wcf".WCF_N."_group_option_value
+    SET    optionValue = 1
+    WHERE    groupID IN (4, 6)
+        AND optionID IN (
+            SELECT    optionID
+            FROM    wcf".WCF_N."_group_option
+            WHERE    optionName IN ('mod.calendar.canEditEvents', 'mod.calendar.canChangeSignupState')
+        )
+        AND optionValue = '0'";
+WCF::getDB()->sendQuery($sql);
+
+?>

calendar/files/icon/calendarL.png

Added
New image

calendar/files/icon/calendarS.png

Added
New image

calendar/files/lib/action/CalendarEventSignupAction.class.php

+<?php
+require_once(WCF_DIR.'lib/action/AbstractAction.class.php');
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+
+/**
+ * Add or edit a signup to an event.
+ *
+ * @package	
+ * @author	Christian Fischer
+ */
+class CalendarEventSignupAction extends AbstractAction {
+	public $event = null;
+	
+	
+	/**
+	 * @see Action::readParameters()
+	 */
+	public function readParameters() {
+		parent::readParameters();
+		
+		if(isset($_REQUEST['eventID'])) {
+			$this->event = AbstractEvent::getEventById(intval($_REQUEST['eventID']));
+		}
+	}
+	
+	/**
+	 * @see Action::execute()
+	 */
+	public function execute() {
+		parent::execute();
+		
+		// validate
+		$this->validate();
+		
+		// execute
+		$this->event->handleSignup();
+		
+		// done
+		$this->executed();
+		
+		// forward to the event's page
+		header('Location: '.FileUtil::addTrailingSlash(dirname(WCF::getSession()->requestURI)).'index.php?page=CalendarViewEvent&eventID=' . $this->event->eventID . SID_ARG_2ND_NOT_ENCODED);
+		exit;
+	}
+	
+	/**
+	 * Validates the active user.
+	 * Throws an IllegalLinkException if the active user can not logout.
+	 */
+	protected function validate() {
+		return;
+	}
+}
+?>

calendar/files/lib/data/calendar/events/AbstractEvent.class.php

+<?php
+
+abstract class AbstractEvent extends DatabaseObject {
+	
+	public $id		= 0;
+	public $hour	= 0;
+	public $minute	= 0;
+	public $day		= 0;
+	public $month	= 0;
+	public $year	= 0;
+	
+	/**
+	 * Creates a empty instance of the AbstractEvent class.
+	 */
+	public function __construct() {
+		return;
+	}
+	
+	/**
+	 * Create an instance of an empty event by its classname
+	 * @param	string		$class
+	 */
+	public static function createNew($class = 'EventNote') {
+		require_once(WCF_DIR.'lib/data/calendar/events/'.$class.'.class.php');
+		$event = new $class();
+		$event->init();
+		return $event;
+	}
+	
+	/**
+	 * Fetch an event from the database by using it's ID.
+	 * @param	string		$class
+	 */
+	public static function getEventById($id) {
+		$result = WCF::getDB()->sendQuery('
+				SELECT		*, e.eventID AS eventID, u.userID AS userID
+				FROM		wcf'.WCF_N.'_calendar_event e
+				JOIN		wcf'.WCF_N.'_user u USING(userID)
+				LEFT JOIN	wcf'.WCF_N.'_calendar_event_signup su ON(e.eventID = su.eventID AND su.userID = '.WCF::getUser()->userID.')
+				WHERE		e.eventID='.$id
+		);
+		
+		while($row = WCF::getDB()->fetchArray($result)) {
+			$class = $row['eventType'];
+			
+			require_once(WCF_DIR.'lib/data/calendar/events/'.$class.'.class.php');
+			$event = new $class();
+			$event->handleData($row);
+			return $event;
+		}
+		
+		// no event with the given ID found - throw an IllegalLinkException
+		require_once(WCF_DIR.'lib/system/exception/IllegalLinkException.class.php');
+		throw new IllegalLinkException();
+	}
+	
+	
+	/**
+	 * Returns a list of all available event classes
+	 */
+	public function getEventClasses() {
+		return array(
+			'net.northshirebund.wbb.calendar.class.EventNote'	=> 'EventNote',
+			'net.northshirebund.wbb.calendar.class.SignupEvent'	=> 'SignupEvent',
+		);
+	}
+	
+	
+	/**
+	 * Initialize the instance of a new event
+	 */
+	protected function init() {
+		$this->handleData(array(
+			'eventTime'		=> TIME_NOW,
+			'eventType'		=> get_class($this),
+			'signupMax'		=> 0,
+			'signupCount'	=> 0,
+		));
+		
+		return;
+	}
+
+	/**
+	 * Stores the data of a database row.
+	 * 
+	 * @param	array		$data
+	 */
+	protected function handleData($data) {
+		parent::handleData($data);
+		
+		if(isset($data['eventID'])) {
+			$this->id = $data['eventID'];
+		}
+		else {
+			$this->id = 0;
+		}
+		
+		list(
+			$this->day,
+			$this->month,
+			$this->year,
+			$this->hour,
+			$this->minute
+		)
+		= preg_split('/,/', date('d,n,Y,H,i', $data['eventTime']));
+		
+		return;
+	}
+	
+	
+	/**
+	 * Reads the parameters from the current form.
+	 */
+	public function readFormParameters($form) {
+		$this->data['subject']	= $form->subject;
+		$this->data['message']	= $form->text;
+		
+		if(isset($_REQUEST['eventDay']))	$this->day		= intval($_REQUEST['eventDay']);
+		if(isset($_REQUEST['eventMonth']))	$this->month	= intval($_REQUEST['eventMonth']);
+		if(isset($_REQUEST['eventYear']))	$this->year		= intval($_REQUEST['eventYear']);
+		if(isset($_REQUEST['eventHour']))	$this->hour		= intval($_REQUEST['eventHour']);
+		if(isset($_REQUEST['eventMinute']))	$this->minute	= intval($_REQUEST['eventMinute']);
+		
+		$this->data['eventTime'] = mktime($this->hour, $this->minute, 0, $this->month, $this->day, $this->year);
+		
+		if(isset($_REQUEST['duration']))	$this->data['duration']	= StringUtil::trim($_REQUEST['duration']);
+		
+		return;
+	}
+	
+	
+	/**
+	 * Validates the current event and throw an UserInputException if there are any errors.
+	 */
+	public function validate() {
+		if(empty($this->data['subject'])) throw new UserInputException('subject', 'empty');
+		if(empty($this->data['message'])) throw new UserInputException('text', 'empty');
+		
+		if(!checkdate($this->month, $this->day, $this->year)) throw new UserInputException('date', 'invalid');
+		if($this->hour<0 or $this->hour>23 or $this->minute<0 or $this->minute>59) throw new UserInputException('time', 'invalid');
+		if($this->data['eventTime'] < TIME_NOW) throw new UserInputException('time', 'outdated');
+		
+		return;
+	}
+	
+	
+	/**
+	 * Assigns the event's variables to the template engine.
+	 */
+	public function assignVariables() {
+		WCF::getTPL()->assign(array(
+				'event'	=> $this,
+				'tabs'	=> $this->getTabs(),
+		));
+		
+		return;
+	}
+	
+	
+	/**
+	 * returns true, if this event is able to handle signups
+	 */
+	public function canHandleSignups() {
+		return false;
+	}
+	
+	
+	/**
+	 * Handles a signup action
+	 */
+	public function handleSignup() {
+		return;
+	}
+	
+	
+	/**
+	 * Returns a list of all tabs available for this event.
+	 */
+	public function getTabs() {
+		return array(
+		//	array('key' => 'signuplist',	'caption' => WCF::getLanguage()->get('wcf.user.profile.information'), 'icon' => RELATIVE_WCF_DIR.'icon/userProfileInformationM.png'),
+		//	array('key' => 'description',	'caption' => 'Beschreibung', 'icon' => RELATIVE_WCF_DIR.'icon/userProfileInformationM.png'),
+		);
+	}
+	
+	
+	/**
+	 * Get the content of a tab
+	 */
+	public function getTabContent($key) {
+		switch($key) {
+			default:			return 'sorry, not implemented yet!';	break;
+		}
+		
+		return '';
+	}
+	
+	
+	/**
+	 * Inserts the current event into the database.
+	 */
+	public function insert() {
+		// Check permission
+		WCF::getUser()->checkPermission('user.calendar.canCreateEvents');
+		
+		WCF::getDB()->sendQuery("
+				INSERT INTO wcf".WCF_N."_calendar_event(eventID, eventType, userID, eventPostTime, eventTime, duration, subject, message, signupMax)
+				VALUES(NULL, '".escapeString($this->data['eventType'])."', '".WCF::getUser()->userID."','".TIME_NOW."', '".$this->data['eventTime']."', '".escapeString($this->data['duration'])."', '".escapeString($this->data['subject'])."', '".escapeString($this->data['message'])."', '".$this->data['signupMax']."');"
+		);
+		
+		$this->id = WCF::getDB()->getInsertID();
+		
+		return;
+	}
+	
+	
+	public function update() {
+		// Check Permission
+		if (WCF::getUser()->userID != $this->userID) {
+			WCF::getUser()->checkPermission('user.calendar.canEditEvents');
+		}
+		
+		WCF::getDB()->sendQuery("
+				UPDATE
+					wcf".WCF_N."_calendar_event
+				SET
+					eventTime	= '".$this->data['eventTime']."',
+					duration	= '".escapeString($this->data['duration'])."',
+					subject		= '".escapeString($this->data['subject'])."',
+					message		= '".escapeString($this->data['message'])."',
+					signupMax	= '".$this->data['signupMax']."'
+				WHERE
+					eventID = ".$this->id
+		);
+		
+		return;
+	}
+}
+
+?>

calendar/files/lib/data/calendar/events/EventNote.class.php

+<?php
+
+
+class EventNote extends AbstractEvent {
+}
+
+
+?>

calendar/files/lib/data/calendar/events/SignupEvent.class.php

+<?php
+
+
+class SignupEvent extends AbstractEvent {
+	public function canHandleSignups() {
+		return true;
+	}
+	
+	
+	public function readFormParameters($form) {
+		parent::readFormParameters($form);
+		
+		if(isset($_REQUEST['signupMax'])) $this->data['signupMax'] = intval($_REQUEST['signupMax']);
+		
+		return;
+	}
+	
+	
+	public function validate() {
+		parent::validate();
+		
+		if($this->data['signupMax'] <= 0) throw new UserInputException('signupMax', 'invalid');
+		
+		return;
+	}
+	
+	
+	/**
+	 * Returns a list of all tabs available for this event.
+	 */
+	public function getTabs() {
+		return array(
+			array(
+					'key'		=> 'signuplist',
+					'caption'	=> WCF::getLanguage()->get('net.northshirebund.wbb.calendar.event.signup.signupList.title').' ('.$this->data['signupCount'].')',
+					'icon'		=> RELATIVE_WCF_DIR.'icon/calendarM.png'
+			),
+		);
+	}
+	
+	
+	/**
+	 * Get the content of a tab
+	 */
+	public function getTabContent($key) {
+		switch($key) {
+			case 'signuplist': {
+				WCF::getTPL()->assign('signupList', $this->getSignupList());
+				WCF::getTPL()->assign('signupListHeader', array('user', 'signupUpdateTime', 'signupMessage'));
+				
+				break;
+			}
+			
+			default: {
+				return parent::getTabContent($key);
+			}
+		}
+		
+		return '';
+	}
+	
+	
+	public function getSignupListSQL() {
+		return '
+				SELECT		*
+				FROM		wcf'.WCF_N.'_calendar_event_signup
+				JOIN		wcf'.WCF_N.'_user USING(userID)
+				WHERE		eventID = '.$this->id.'
+				ORDER BY	signupUpdateTime ASC';
+	}
+	
+	
+	public function getSignupList() {
+		require_once(WCF_DIR.'lib/data/message/bbcode/MessageParser.class.php');
+		require_once(WCF_DIR.'lib/data/message/bbcode/URLParser.class.php');
+		
+		$parser = MessageParser::getInstance();
+		$parser->setOutputType('text/html');
+		
+		$result  = WCF::getDB()->sendQuery($this->getSignupListSQL());
+		$signups = array();
+		$index   = 0;
+		
+		while($row = WCF::getDB()->fetchArray($result)) {
+			if($row['signupState'] == 'c') {
+				$row['index'] = '<img src="'.RELATIVE_WCF_DIR.'icon/deleteS.png" alt=""/>';
+			}
+			else {
+				$row['index'] = ++$index;
+			}
+		//	$row['user']	= '<a href="index.php?page=User&amp;userID='.$row['userID'].SID_ARG_2ND.'">'.StringUtil::encodeHTML($row['username']).'</a>';
+			
+			if($row['signupMessage']) {
+				$message = $row['signupMessage'];
+				
+				// parse URLs
+				$message = URLParser::parse($message);
+				
+				// parse smilies & BBCode
+				$message = $parser->parse($message, /*smilies*/true, /*html*/false, /*bbcode*/true, /*highlighting*/false);
+				
+				$row['signupMessage'] = $message;
+			}
+			
+			$signups []= $row;
+		}
+		
+		return $signups;
+	}
+	
+	
+	public function handleSignup() {
+		// Check Permission
+		WCF::getUser()->checkPermission('user.calendar.canSignupEvents');
+		
+		if(isset($_REQUEST['text'])) 		$this->data['signupMessage']	= StringUtil::trim($_REQUEST['text']);
+		if(isset($_REQUEST['signupState']))	$this->data['NEW_signupState']	= StringUtil::trim($_REQUEST['signupState']);
+		
+		if(!$this->data['signupTime']) {
+			$this->data['signupTime'] = TIME_NOW;
+			$this->data['signupUpdateTime'] = TIME_NOW;
+			
+			$this->insertSignup();
+		}
+		else {
+			$this->updateSignup();
+		}
+		
+		return;
+	}
+	
+	
+	public function insertSignup() {
+		WCF::getDB()->sendQuery('
+				INSERT INTO wcf'.WCF_N.'_calendar_event_signup(eventID, userID, signupTime, signupUpdateTime, signupMessage, signupState)
+				VALUES('.$this->id.', '.WCF::getUser()->userID.', '.TIME_NOW.', '.TIME_NOW.', \''.escapeString($this->data['signupMessage']).'\',\''.$this->data['signupState'].'\')'
+		);
+		
+		$this->updateSignupCount();
+		
+		return;
+	}
+	
+	
+	public function updateSignup() {
+		if($this->data['NEW_signupState'] != $this->data['signupState']) $this->data['signupUpdateTime'] = TIME_NOW;
+		$this->data['signupState'] = $this->data['NEW_signupState'];
+		
+		WCF::getDB()->sendQuery("
+				UPDATE
+					wcf".WCF_N."_calendar_event_signup
+				SET
+					signupUpdateTime	= '".$this->data['signupUpdateTime']."',
+					signupMessage		= '".escapeString($this->data['signupMessage'])."',
+					signupState			= '".$this->data['signupState']."'
+				WHERE
+					eventID = ".$this->id." AND userID = ".WCF::getUser()->userID
+		);
+		
+		$this->updateSignupCount();
+		
+		return;
+	}
+	
+	
+	public function updateSignupCount() {
+		$result = WCF::getDB()->getFirstRow('SELECT count(*) AS count FROM wcf'.WCF_N.'_calendar_event_signup WHERE signupState <> \'c\' AND eventID='.$this->id);
+		WCF::getDB()->sendUnbufferedQuery('UPDATE wcf'.WCF_N.'_calendar_event SET signupCount=\''.$result['count'].'\' WHERE eventID='.$this->id);
+		
+		return;
+	}
+}
+
+
+?>

calendar/files/lib/data/page/location/CalendarEventLocation.class.php

+<?php
+require_once(WCF_DIR.'lib/data/page/location/Location.class.php');
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+
+/**
+ * CalendarLocation is an implementation of Location for the calendarevent page.
+ * 
+ * @author	Christian Fischer
+ * @package	
+ */
+class CalendarEventLocation implements Location {
+//	public $cachedThreadIDs = array();
+	
+	/**
+	 * @see Location::cache()
+	 */
+	public function cache($location, $requestURI, $requestMethod, $match) {
+	//	$this->cachedThreadIDs[] = $match[1];
+	}
+	
+	/**
+	 * @see Location::get()
+	 */
+	public function get($location, $requestURI, $requestMethod, $match) {
+		
+		$eventID = intval($match[1]);
+		$event = AbstractEvent::getEventById($eventID);
+		
+		return WCF::getLanguage()->get($location['locationName'], array('$event' => '<a href="index.php?page=CalendarViewEvetn&amp;eventID='.$eventID.SID_ARG_2ND.'">'.StringUtil::encodeHTML($event->subject).'</a>'));
+	}
+}
+?>

calendar/files/lib/form/CalendarAddEventForm.class.php

+<?php
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+require_once(WCF_DIR.'lib/form/MessageForm.class.php');
+require_once(WCF_DIR.'lib/page/util/InlineCalendar.class.php');
+require_once(WCF_DIR.'lib/page/util/menu/HeaderMenu.class.php');
+
+/**
+ * Form for creating new private messages.
+ *
+ * @package	com.woltlab.wcf.form
+ * @author	Marcel Werk
+ */
+class CalendarAddEventForm extends MessageForm {
+	public $templateName = 'calendarAddEvent';
+	
+	// request parameters
+	public $event = null;
+	
+	
+	/**
+	 * @see Page::readParameters()
+	 */
+	public function readParameters() {
+		parent::readParameters();
+		
+		if(isset($_REQUEST['class'])) {
+			$this->event = AbstractEvent::createNew(trim($_REQUEST['class']));
+		}
+		else {
+			$this->event = AbstractEvent::createNew();
+		}
+		
+		return;
+	}
+	
+	/**
+	 * @see Form::readFormParameters()
+	 */
+	public function readFormParameters() {
+		parent::readFormParameters();
+		$this->event->readFormParameters($this);
+		return;
+	}
+	
+	/**
+	 * @see Form::submit()
+	 */
+	public function submit() {
+		// call submit event
+		EventHandler::fireAction($this, 'submit');
+		
+		$this->readFormParameters();
+		
+		try {
+			$this->validate();
+			
+		/*
+			// preview
+			if ($this->preview) {
+				require_once(WCF_DIR.'lib/data/message/bbcode/AttachmentBBCode.class.php');
+				AttachmentBBCode::setAttachments($this->attachmentsEditor->getSortedAttachments());
+				WCF::getTPL()->assign('preview', PMEditor::createPreview($this->subject, $this->text, $this->enableSmilies, $this->enableHtml, $this->enableBBCodes));
+			}
+		*/
+			
+			// no errors? SAVE!
+			$this->save();
+		}
+		catch (UserInputException $e) {
+			$this->errorField = $e->getField();
+			$this->errorType = $e->getType();
+		}
+	}
+	
+	/**
+	 * @see Form::validate()
+	 */
+	public function validate() {
+		// validate subject and text
+		parent::validate();
+		$this->event->validate();
+		return;
+	}
+	
+	/**
+	 * @see Form::save()
+	 */
+	public function save() {
+		parent::save();
+		$this->event->insert();
+		
+		// forward to calendar
+		header('Location: '.FileUtil::addTrailingSlash(dirname(WCF::getSession()->requestURI)).'index.php?page=Calendar' . SID_ARG_2ND_NOT_ENCODED);
+		exit;
+	}
+	
+	/**
+	 * @see Page::readData()
+	 */
+	public function readData() {
+		parent::readData();
+		return;
+	}
+	
+	/**
+	 * @see Page::assignVariables()
+	 */
+	public function assignVariables() {
+		parent::assignVariables();
+		
+		InlineCalendar::assignVariables();
+		$this->event->assignVariables();
+		
+		/*
+		WCF::getTPL()->assign(array(
+			'pmID' => $this->pmID,
+			'forwarding' => $this->forwarding,
+			'reply' => $this->reply,
+			'recipients' => $this->recipients,
+			'blindCopies' => $this->blindCopies,
+			'replyToAll' => $this->replyToAll
+		));
+		*/
+	}
+	
+	/**
+	 * @see Page::show()
+	 */
+	public function show() {
+		// set active header menu item
+		HeaderMenu::setActiveMenuItem('net.northshirebund.wbb.calendar.title');
+		
+		// check permissions
+		WCF::getUser()->checkPermission('user.calendar.canEnter');
+		WCF::getUser()->checkPermission('user.calendar.canCreateEvents');
+		
+		parent::show();
+		
+		return;
+	}
+}
+?>

calendar/files/lib/form/CalendarEditEventForm.class.php

+<?php
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+require_once(WCF_DIR.'lib/form/MessageForm.class.php');
+require_once(WCF_DIR.'lib/page/util/InlineCalendar.class.php');
+require_once(WCF_DIR.'lib/page/util/menu/HeaderMenu.class.php');
+
+/**
+ * Form for creating new private messages.
+ *
+ * @package	com.woltlab.wcf.form
+ * @author	Marcel Werk
+ */
+class CalendarEditEventForm extends MessageForm {
+	public $templateName = 'calendarEditEvent';
+	
+	// request parameters
+	public $event = null;
+	
+	
+	/**
+	 * @see Page::readParameters()
+	 */
+	public function readParameters() {
+		parent::readParameters();
+		
+		if(isset($_REQUEST['eventID'])) {
+			$this->event = AbstractEvent::getEventById(intval($_REQUEST['eventID']));
+		}
+		
+		return;
+	}
+	
+	/**
+	 * @see Form::readFormParameters()
+	 */
+	public function readFormParameters() {
+		parent::readFormParameters();
+		$this->event->readFormParameters($this);
+		return;
+	}
+	
+	/**
+	 * @see Form::submit()
+	 */
+	public function submit() {
+		// call submit event
+		EventHandler::fireAction($this, 'submit');
+		
+		$this->readFormParameters();
+		
+		try {
+			$this->validate();
+			
+		/*
+			// preview
+			if ($this->preview) {
+				require_once(WCF_DIR.'lib/data/message/bbcode/AttachmentBBCode.class.php');
+				AttachmentBBCode::setAttachments($this->attachmentsEditor->getSortedAttachments());
+				WCF::getTPL()->assign('preview', PMEditor::createPreview($this->subject, $this->text, $this->enableSmilies, $this->enableHtml, $this->enableBBCodes));
+			}
+		*/
+			
+			// no errors? SAVE!
+			$this->save();
+		}
+		catch (UserInputException $e) {
+			$this->errorField = $e->getField();
+			$this->errorType = $e->getType();
+		}
+	}
+	
+	/**
+	 * @see Form::validate()
+	 */
+	public function validate() {
+		// validate subject and text
+		parent::validate();
+		$this->event->validate();
+		return;
+	}
+	
+	/**
+	 * @see Form::save()
+	 */
+	public function save() {
+		parent::save();
+		$this->event->update();
+		
+		// forward to event
+		header('Location: '.FileUtil::addTrailingSlash(dirname(WCF::getSession()->requestURI)).'index.php?page=CalendarViewEvent&eventID=' . $this->event->eventID . SID_ARG_2ND_NOT_ENCODED);
+		exit;
+	}
+	
+	/**
+	 * @see Page::readData()
+	 */
+	public function readData() {
+		parent::readData();
+		return;
+	}
+	
+	/**
+	 * @see Page::assignVariables()
+	 */
+	public function assignVariables() {
+		parent::assignVariables();
+		
+		InlineCalendar::assignVariables();
+		$this->event->assignVariables();
+		
+		return;
+	}
+	
+	/**
+	 * @see Page::show()
+	 */
+	public function show() {
+		// set active header menu item
+		HeaderMenu::setActiveMenuItem('net.northshirebund.wbb.calendar.title');
+		
+		// check permissions
+		WCF::getUser()->checkPermission('user.calendar.canEnter');
+		
+		if (WCF::getUser()->userID != $this->event->userID) {
+			WCF::getUser()->checkPermission('user.calendar.canEditEvents');
+		}
+		
+		parent::show();
+		
+	}
+}
+?>

calendar/files/lib/page/CalendarPage.class.php

+<?php
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+require_once(WCF_DIR.'lib/page/AbstractPage.class.php');
+require_once(WCF_DIR.'lib/page/util/menu/HeaderMenu.class.php');
+
+define('TIME_1_DAY', 24 * 60 * 60);
+
+
+/**
+ * This class provides default implementations for the Page interface.
+ * This includes the call of the default event listeners for a page: construct, readParameters, assignVariables and show.
+ * 
+ * @author	Christian Fischer
+ * @package	
+ */
+class CalendarPage extends AbstractPage {
+	/**
+	 * Name of the template for the called page.
+	 */
+	public $templateName = 'calendar';
+	public $todayDay	= 0;
+	public $todayMonth	= 0;
+	public $todayYear	= 0;
+	public $view;	// month / week
+	public $year;
+	public $month;
+	public $data;
+	public $weekdays	= array();
+	
+	/**
+	 * @see Page::readParameters()
+	 */
+	public function readParameters() {
+		parent::readParameters();
+		
+		$this->todayDay		= intval(date('d', TIME_NOW));
+		$this->todayMonth	= intval(date('m', TIME_NOW));
+		$this->todayYear	= intval(date('Y', TIME_NOW));
+		$this->year			= $this->todayYear;
+		$this->month		= $this->todayMonth;
+		
+		if(isset($_REQUEST['view'])) {
+			$this->view = trim($_REQUEST['view']);
+		}
+		
+		switch($this->view) {
+			case 'month':
+			default: {
+				$this->view = 'month';
+				if(isset($_REQUEST['month'])) $this->month = intval($_REQUEST['month']);
+				if(isset($_REQUEST['year']))  $this->year  = intval($_REQUEST['year']);
+				break;
+			}
+		}
+		
+		return;
+	}
+	
+	
+	public function getBirthdays($month='__', $day='__') {
+		$fieldname = 'userOption'.User::getUserOptionID('birthday');
+		
+		$sql = 	'SELECT		
+							user_options.userID,user_data.username,
+							user_options.'.$fieldname.' AS birthday
+				FROM		wcf'.WCF_N.'_user_option_value user_options
+				LEFT JOIN	wcf'.WCF_N.'_user user_data USING (userID)
+				WHERE		'.$fieldname." LIKE '____-$month-$day'"
+		;
+		
+		$result = WCF::getDB()->sendQuery($sql);
+		$birthdays = array();
+		$bday_icon = RELATIVE_WCF_DIR.'icon/userS.png';
+		$year_now  = date('Y', TIME_NOW);
+		
+		while($row = WCF::getDB()->fetchArray($result)) {
+			$bday = array();
+			list($bday['year'], $bday['month'], $bday['day']) = preg_split('/-/', $row['birthday']);
+			
+			$bday['icon']	= $bday_icon;
+			$bday['link']	= 'index.php?page=User&userID='.$row['userID'];
+			$bday['title']	= $row['username'];;
+			
+			if ($bday['year'] > 0) {
+				$bday['title'] .= ' ('.($year_now - $bday['year']).')';
+			}
+			
+			$birthdays []= $bday;
+		}
+		
+		return $birthdays;
+	}
+	
+	public function getEvents($from, $to) {
+		$sql = 'SELECT
+							*
+				FROM		wcf'.WCF_N.'_calendar_event e
+				LEFT JOIN	wcf'.WCF_N.'_user u USING(userID)
+				WHERE		eventTime > '.$from.'
+				AND			eventTime < '.$to
+		;
+		
+		$result = WCF::getDB()->sendQuery($sql);
+		$events = array();
+		
+		while($row = WCF::getDB()->fetchArray($result)) {
+			$event = array();
+			list($event['year'], $event['month'], $event['day']) = preg_split('/,/', date('Y,n,d', $row['eventTime']));
+			
+			$event['icon']  = RELATIVE_WCF_DIR.'icon/calendarM.png';
+			$event['title'] = $row['subject'].' ('.date('H:i', $row['eventTime']).')';
+			$event['link']  = 'index.php?page=CalendarViewEvent&eventID='.$row['eventID'];
+			
+			$events []= $event;
+		}
+		
+		return $events;
+	}
+	
+	
+	/**
+	 * @see Page::assignVariables()
+	 */
+	public function assignVariables() {
+		parent::assignVariables();
+		$firstday = '1';
+		
+		// previous and next month and year
+		$prevYear  = $this->year;
+		$nextYear  = $this->year;
+		$prevMonth = $this->month - 1;
+		$nextMonth = $this->month + 1;
+		
+		if ($prevMonth < 1) {
+			$prevMonth = 12;
+			$prevYear--;
+		}
+		
+		if ($nextMonth > 12) {
+			$nextMonth = 1;
+			$nextYear++;
+		}
+		
+		// compute weekdays
+		for($i=0; $i<7; $i++) {
+			$this->weekdays[] = date('l', mktime(0, 0, 0, 7, 1 + $i + $firstday, 2007));
+		}
+		
+		switch($this->view) {
+			case 'month': {
+				$time = mktime (
+								0,	// hour
+								0,	// min
+								0,	// seconds
+								$this->month,
+								1,	// day
+								$this->year
+				);
+				
+				$events = array_merge(
+							$this->getBirthdays(($this->month < 10) ? ('0'.$this->month) : $this->month),
+							$this->getEvents($time, mktime(0, 0, 0, $nextMonth, 1, $nextYear))
+				);
+				
+				// step backwards to the first day in the table
+				while(date('w', $time) != $firstday) $time -= TIME_1_DAY;
+				
+				$this->data = array();
+				$day;
+				
+				do {
+					$week = array();
+					
+					for($i=0; $i<7; $i++) {
+						//echo '<td>'.date('d', $time).'</td>';
+						$day = array(
+							'day'		=> date('d', $time),
+							'month'		=> date('m', $time),
+							'today'		=> (($time <= TIME_NOW) and ($time + TIME_1_DAY > TIME_NOW)),
+							'events'	=> array(),
+						);
+						
+						// add events of the current day
+						foreach($events as $event) {
+							if($event['day'] == $day['day'] and $event['month'] == $day['month']) {
+								$day['events'] []= $event;
+							}
+						}
+						
+						$week[] = $day;
+						$time += TIME_1_DAY;
+					}
+					
+					if(($week[0]['month'] == $this->month) or ($week[6]['month'] == $this->month)) {
+						$this->data[] = $week;
+					}
+				}
+				while($day['month'] == $this->month);
+				
+				break;
+			}
+		}
+		
+		WCF::getTPL()->assign(array(
+			'view'			=> $this->view,
+			'weekdays'		=> $this->weekdays,
+			'calendarData'	=> $this->data,
+			'currentYear'	=> $this->year,
+			'currentMonth'	=> $this->month,
+			'previousMonth'	=> $prevMonth,
+			'previousYear'	=> $prevYear,
+			'nextMonth'		=> $nextMonth,
+			'nextYear'		=> $nextYear,
+			
+			'eventClasses'	=> AbstractEvent::getEventClasses(),
+			
+			'currentMonthLabel'		=> date('F', mktime(0, 0, 0, $this->month, 1, $this->year)),
+			'previousMonthLabel'	=> date('F', mktime(0, 0, 0, $prevMonth, 1, $prevYear)),
+			'nextMonthLabel'		=> date('F', mktime(0, 0, 0, $nextMonth, 1, $nextYear)),
+		));
+		
+		return;
+	}
+	
+	
+	/**
+	 * @see Page::show()
+	 */
+	public function show() {
+		// set active header menu item
+		HeaderMenu::setActiveMenuItem('net.northshirebund.wbb.calendar.title');
+		
+		// check permission
+		WCF::getUser()->checkPermission('user.calendar.canEnter');
+		
+		parent::show();
+		
+		return;
+	}
+}
+?>

calendar/files/lib/page/CalendarViewEventPage.class.php

+<?php
+require_once(WCF_DIR.'lib/data/calendar/events/AbstractEvent.class.php');
+require_once(WCF_DIR.'lib/page/AbstractPage.class.php');
+require_once(WCF_DIR.'lib/page/util/menu/HeaderMenu.class.php');
+
+//HeaderMenu::setActiveMenuItem('net.northshirebund.wbb.shoutbox.page.title');
+
+
+/**
+ * This class provides default implementations for the Page interface.
+ * This includes the call of the default event listeners for a page: construct, readParameters, assignVariables and show.
+ * 
+ * @author	Christian Fischer
+ * @package	
+ */
+class CalendarViewEventPage extends AbstractPage {
+	/**
+	 * Name of the template for the called page.
+	 */
+	public $templateName = 'calendarViewEvent';
+	public $activeTab;
+	
+	public $event;
+	
+	/**
+	 * @see Page::readParameters()
+	 */
+	public function readParameters() {
+		parent::readParameters();
+		
+		if(isset($_REQUEST['eventID'])) {
+			$this->event = AbstractEvent::getEventById(intval($_REQUEST['eventID']));
+		}
+		
+		if(isset($_REQUEST['tab'])) {
+			$this->activeTab = StringUtil::trim($_REQUEST['tab']);
+		}
+		
+		return;
+	}
+	
+	
+	/**
+	 * @see Page::assignVariables()
+	 */
+	public function assignVariables() {
+	
+		parent::assignVariables();
+		$this->event->assignVariables();
+		
+		if(!$this->activeTab) {
+			$tabs = $this->event->getTabs();
+			
+			if(count($tabs) > 0) {
+				$this->activeTab = $tabs[0]['key'];
+			}
+		}
+		
+		WCF::getTPL()->assign('activeTab', $this->activeTab);
+		
+		if($this->activeTab) {
+			WCF::getTPL()->assign('tabContent', $this->event->getTabContent($this->activeTab));
+		}
+		
+		return;
+	}
+	
+	
+	/**
+	 * @see Page::show()
+	 */
+	public function show() {
+		// set active header menu item
+		HeaderMenu::setActiveMenuItem('net.northshirebund.wbb.calendar.title');
+		
+		// check permissions
+		WCF::getUser()->checkPermission('user.calendar.canEnter');
+		WCF::getUser()->checkPermission('user.calendar.canViewEvents');
+		
+		parent::show();
+		
+		return;
+	}
+}
+?>

calendar/lang/calendar.lang.xml

+<?xml version="1.0" encoding="UTF-8"?><?mso-application progid="Excel.Sheet"?>
+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet"><OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"><Colors><Color><Index>3</Index><RGB>#000000</RGB></Color><Color><Index>4</Index><RGB>#c0c0c0</RGB></Color><Color><Index>5</Index><RGB>#ff0000</RGB></Color></Colors></OfficeDocumentSettings><ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"><WindowHeight>9000</WindowHeight><WindowWidth>13860</WindowWidth><WindowTopX>240</WindowTopX><WindowTopY>75</WindowTopY><ProtectStructure>False</ProtectStructure><ProtectWindows>False</ProtectWindows></ExcelWorkbook><Styles><Style ss:ID="Default" ss:Name="Default"/><Style ss:ID="Result" ss:Name="Result"><Font ss:Bold="1" ss:Italic="1" ss:Size="10" ss:Underline="Single"/></Style><Style ss:ID="Result2" ss:Name="Result2"><Font ss:Bold="1" ss:Italic="1" ss:Size="10" ss:Underline="Single"/><NumberFormat ss:Format="General"/></Style><Style ss:ID="Heading" ss:Name="Heading"><Alignment ss:Horizontal="Center"/><Font ss:Bold="1" ss:Italic="1" ss:Size="16"/></Style><Style ss:ID="Heading1" ss:Name="Heading1"><Alignment ss:Horizontal="Center" ss:Rotate="90"/><Font ss:Bold="1" ss:Italic="1" ss:Size="16"/></Style><Style ss:ID="Normal" ss:Name="Normal"><Alignment ss:Vertical="Bottom"/><Font ss:Color="#000000" ss:FontName="Calibri" ss:Size="11"/></Style><Style ss:ID="co1"/><Style ss:ID="co2"/><Style ss:ID="co3"/><Style ss:ID="co4"/><Style ss:ID="ta1"/><Style ss:ID="ce1"><Alignment ss:WrapText="1"/><Font ss:FontName="Times New Roman11" ss:Size="10"/></Style><Style ss:ID="ce2"><Alignment ss:WrapText="1"/><Font ss:FontName="DejaVu Sans11" ss:Size="10"/></Style><Style ss:ID="ce3"><Alignment ss:WrapText="1"/></Style><Style ss:ID="ce4"><Alignment ss:WrapText="1"/><Font ss:FontName="DejaVu Sans1" ss:Size="10"/></Style></Styles><ss:Worksheet ss:Name="Tabelle1"><Table ss:StyleID="ta1"><Column ss:StyleID="Default" ss:Width="188.7024"/><Column ss:StyleID="ce1" ss:Width="409.4362"/><Column ss:StyleID="Default" ss:Span="3" ss:Width="229.011"/><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell ss:Index="2" ss:StyleID="Default"/><Cell><Data ss:Type="String">De</Data></Cell><Cell><Data ss:Type="String">De-informal</Data></Cell><Cell><Data ss:Type="String">En</Data></Cell><Cell><Data ss:Type="String">It</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.title</Data></Cell><Cell><Data ss:Type="String">Kalender</Data></Cell><Cell><Data ss:Type="String">Kalender</Data></Cell><Cell><Data ss:Type="String">Kalender</Data></Cell><Cell><Data ss:Type="String">Kalender</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month1</Data></Cell><Cell><Data ss:Type="String">Januar</Data></Cell><Cell><Data ss:Type="String">Januar</Data></Cell><Cell><Data ss:Type="String">Januar</Data></Cell><Cell><Data ss:Type="String">Januar</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month2</Data></Cell><Cell><Data ss:Type="String">Februar</Data></Cell><Cell><Data ss:Type="String">Februar</Data></Cell><Cell><Data ss:Type="String">Februar</Data></Cell><Cell><Data ss:Type="String">Februar</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month3</Data></Cell><Cell><Data ss:Type="String">März</Data></Cell><Cell><Data ss:Type="String">März</Data></Cell><Cell><Data ss:Type="String">März</Data></Cell><Cell><Data ss:Type="String">März</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month4</Data></Cell><Cell><Data ss:Type="String">April</Data></Cell><Cell><Data ss:Type="String">April</Data></Cell><Cell><Data ss:Type="String">April</Data></Cell><Cell><Data ss:Type="String">April</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month5</Data></Cell><Cell><Data ss:Type="String">Mai</Data></Cell><Cell><Data ss:Type="String">Mai</Data></Cell><Cell><Data ss:Type="String">Mai</Data></Cell><Cell><Data ss:Type="String">Mai</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month6</Data></Cell><Cell><Data ss:Type="String">Juni</Data></Cell><Cell><Data ss:Type="String">Juni</Data></Cell><Cell><Data ss:Type="String">Juni</Data></Cell><Cell><Data ss:Type="String">Juni</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month7</Data></Cell><Cell><Data ss:Type="String">Juli</Data></Cell><Cell><Data ss:Type="String">Juli</Data></Cell><Cell><Data ss:Type="String">Juli</Data></Cell><Cell><Data ss:Type="String">Juli</Data></Cell></Row><Row ss:Index="10" ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month8</Data></Cell><Cell><Data ss:Type="String">August</Data></Cell><Cell><Data ss:Type="String">August</Data></Cell><Cell><Data ss:Type="String">August</Data></Cell><Cell><Data ss:Type="String">August</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month9</Data></Cell><Cell><Data ss:Type="String">September</Data></Cell><Cell><Data ss:Type="String">September</Data></Cell><Cell><Data ss:Type="String">September</Data></Cell><Cell><Data ss:Type="String">September</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month10</Data></Cell><Cell><Data ss:Type="String">Oktober</Data></Cell><Cell><Data ss:Type="String">Oktober</Data></Cell><Cell><Data ss:Type="String">Oktober</Data></Cell><Cell><Data ss:Type="String">Oktober</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month11</Data></Cell><Cell><Data ss:Type="String">November</Data></Cell><Cell><Data ss:Type="String">November</Data></Cell><Cell><Data ss:Type="String">November</Data></Cell><Cell><Data ss:Type="String">November</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.month12</Data></Cell><Cell><Data ss:Type="String">Dezember</Data></Cell><Cell><Data ss:Type="String">Dezember</Data></Cell><Cell><Data ss:Type="String">Dezember</Data></Cell><Cell><Data ss:Type="String">Dezember</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday0</Data></Cell><Cell><Data ss:Type="String">Sonntag</Data></Cell><Cell><Data ss:Type="String">Sonntag</Data></Cell><Cell><Data ss:Type="String">Sonntag</Data></Cell><Cell><Data ss:Type="String">Sonntag</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday1</Data></Cell><Cell><Data ss:Type="String">Montag</Data></Cell><Cell><Data ss:Type="String">Montag</Data></Cell><Cell><Data ss:Type="String">Montag</Data></Cell><Cell><Data ss:Type="String">Montag</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday2</Data></Cell><Cell><Data ss:Type="String">Dienstag</Data></Cell><Cell><Data ss:Type="String">Dienstag</Data></Cell><Cell><Data ss:Type="String">Dienstag</Data></Cell><Cell><Data ss:Type="String">Dienstag</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday3</Data></Cell><Cell><Data ss:Type="String">Mittwoch</Data></Cell><Cell><Data ss:Type="String">Mittwoch</Data></Cell><Cell><Data ss:Type="String">Mittwoch</Data></Cell><Cell><Data ss:Type="String">Mittwoch</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday4</Data></Cell><Cell><Data ss:Type="String">Donnerstag</Data></Cell><Cell><Data ss:Type="String">Donnerstag</Data></Cell><Cell><Data ss:Type="String">Donnerstag</Data></Cell><Cell><Data ss:Type="String">Donnerstag</Data></Cell></Row><Row ss:Index="20" ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday5</Data></Cell><Cell><Data ss:Type="String">Freitag</Data></Cell><Cell><Data ss:Type="String">Freitag</Data></Cell><Cell><Data ss:Type="String">Freitag</Data></Cell><Cell><Data ss:Type="String">Freitag</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.weekday6</Data></Cell><Cell><Data ss:Type="String">Samstag</Data></Cell><Cell><Data ss:Type="String">Samstag</Data></Cell><Cell><Data ss:Type="String">Samstag</Data></Cell><Cell><Data ss:Type="String">Samstag</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.new</Data></Cell><Cell><Data ss:Type="String">Neuer Termin</Data></Cell><Cell><Data ss:Type="String">Neuer Termin</Data></Cell><Cell><Data ss:Type="String">Neuer Termin</Data></Cell><Cell><Data ss:Type="String">Neuer Termin</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.edit</Data></Cell><Cell><Data ss:Type="String">Bearbeiten</Data></Cell><Cell><Data ss:Type="String">Bearbeiten</Data></Cell><Cell><Data ss:Type="String">Bearbeiten</Data></Cell><Cell><Data ss:Type="String">Bearbeiten</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.information</Data></Cell><Cell><Data ss:Type="String">Termindaten</Data></Cell><Cell><Data ss:Type="String">Termindaten</Data></Cell><Cell><Data ss:Type="String">Termindaten</Data></Cell><Cell><Data ss:Type="String">Termindaten</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.subject</Data></Cell><Cell><Data ss:Type="String">Betreff</Data></Cell><Cell><Data ss:Type="String">Betreff</Data></Cell><Cell><Data ss:Type="String">Betreff</Data></Cell><Cell><Data ss:Type="String">Betreff</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.time</Data></Cell><Cell><Data ss:Type="String">Beginn</Data></Cell><Cell><Data ss:Type="String">Beginn</Data></Cell><Cell><Data ss:Type="String">Beginn</Data></Cell><Cell><Data ss:Type="String">Beginn</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.duration</Data></Cell><Cell><Data ss:Type="String">Dauer</Data></Cell><Cell><Data ss:Type="String">Dauer</Data></Cell><Cell><Data ss:Type="String">Dauer</Data></Cell><Cell><Data ss:Type="String">Dauer</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.maxSignups</Data></Cell><Cell><Data ss:Type="String">Maximale Anmeldungen</Data></Cell><Cell><Data ss:Type="String">Maximale Anmeldungen</Data></Cell><Cell><Data ss:Type="String">Maximale Anmeldungen</Data></Cell><Cell><Data ss:Type="String">Maximale Anmeldungen</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.event.text</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell></Row><Row ss:Index="30" ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.class.EventNote</Data></Cell><Cell><Data ss:Type="String">Kalendernotiz</Data></Cell><Cell><Data ss:Type="String">Kalendernotiz</Data></Cell><Cell><Data ss:Type="String">Kalendernotiz</Data></Cell><Cell><Data ss:Type="String">Kalendernotiz</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.class.SignupEvent</Data></Cell><Cell><Data ss:Type="String">Termin mit Anmeldung</Data></Cell><Cell><Data ss:Type="String">Termin mit Anmeldung</Data></Cell><Cell><Data ss:Type="String">Termin mit Anmeldung</Data></Cell><Cell><Data ss:Type="String">Termin mit Anmeldung</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.error.invalidDate</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie ein gültiges Datum ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie ein gültiges Datum ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie ein gültiges Datum ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie ein gültiges Datum ein.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.error.invalidTime</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine gültige Zeit ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine gültige Zeit ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine gültige Zeit ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine gültige Zeit ein.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.error.outdatedTime</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie einen Zeitpunkt in der Zukunft an.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie einen Zeitpunkt in der Zukunft an.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie einen Zeitpunkt in der Zukunft an.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie einen Zeitpunkt in der Zukunft an.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar.error.invalidMaxSignups</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine Zahl größer als 0 ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine Zahl größer als 0 ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine Zahl größer als 0 ein.</Data></Cell><Cell><Data ss:Type="String">Bitte geben Sie eine Zahl größer als 0 ein.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.title</Data></Cell><Cell><Data ss:Type="String">Anmelden</Data></Cell><Cell><Data ss:Type="String">Anmelden</Data></Cell><Cell><Data ss:Type="String">Anmelden</Data></Cell><Cell><Data ss:Type="String">Anmelden</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.message</Data></Cell><Cell><Data ss:Type="String">Nachricht&lt;br/&gt;(optional)</Data></Cell><Cell><Data ss:Type="String">Nachricht&lt;br/&gt;(optional)</Data></Cell><Cell><Data ss:Type="String">Nachricht&lt;br/&gt;(optional)</Data></Cell><Cell><Data ss:Type="String">Nachricht&lt;br/&gt;(optional)</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.asReserves</Data></Cell><Cell><Data ss:Type="String">Als Ersatz anmelden</Data></Cell><Cell><Data ss:Type="String">Als Ersatz anmelden</Data></Cell><Cell><Data ss:Type="String">Als Ersatz anmelden</Data></Cell><Cell><Data ss:Type="String">Als Ersatz anmelden</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.cancel</Data></Cell><Cell><Data ss:Type="String">Anmeldung zurückziehen</Data></Cell><Cell><Data ss:Type="String">Anmeldung zurückziehen</Data></Cell><Cell><Data ss:Type="String">Anmeldung zurückziehen</Data></Cell><Cell><Data ss:Type="String">Anmeldung zurückziehen</Data></Cell></Row><Row ss:Index="40" ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.signupList.title</Data></Cell><Cell><Data ss:Type="String">Anmeldeliste</Data></Cell><Cell><Data ss:Type="String">Anmeldeliste</Data></Cell><Cell><Data ss:Type="String">Anmeldeliste</Data></Cell><Cell><Data ss:Type="String">Anmeldeliste</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.signupList.column.user</Data></Cell><Cell><Data ss:Type="String">Name</Data></Cell><Cell><Data ss:Type="String">Name</Data></Cell><Cell><Data ss:Type="String">Name</Data></Cell><Cell><Data ss:Type="String">Name</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.signupList.column.signupUpdateTime</Data></Cell><Cell><Data ss:Type="String">Anmeldezeit</Data></Cell><Cell><Data ss:Type="String">Anmeldezeit</Data></Cell><Cell><Data ss:Type="String">Anmeldezeit</Data></Cell><Cell><Data ss:Type="String">Anmeldezeit</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.signupList.column.signupMessage</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell><Cell><Data ss:Type="String">Nachricht</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state</Data></Cell><Cell><Data ss:Type="String">Anmeldestatus</Data></Cell><Cell><Data ss:Type="String">Anmeldestatus</Data></Cell><Cell><Data ss:Type="String">Anmeldestatus</Data></Cell><Cell><Data ss:Type="String">Anmeldestatus</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state.accepted</Data></Cell><Cell><Data ss:Type="String">Bestätigt</Data></Cell><Cell><Data ss:Type="String">Bestätigt</Data></Cell><Cell><Data ss:Type="String">Bestätigt</Data></Cell><Cell><Data ss:Type="String">Bestätigt</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state.available</Data></Cell><Cell><Data ss:Type="String">Angemeldet</Data></Cell><Cell><Data ss:Type="String">Angemeldet</Data></Cell><Cell><Data ss:Type="String">Angemeldet</Data></Cell><Cell><Data ss:Type="String">Angemeldet</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state.waiting</Data></Cell><Cell><Data ss:Type="String">Warteliste</Data></Cell><Cell><Data ss:Type="String">Warteliste</Data></Cell><Cell><Data ss:Type="String">Warteliste</Data></Cell><Cell><Data ss:Type="String">Warteliste</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state.reserves</Data></Cell><Cell><Data ss:Type="String">Ersatzbank</Data></Cell><Cell><Data ss:Type="String">Ersatzbank</Data></Cell><Cell><Data ss:Type="String">Ersatzbank</Data></Cell><Cell><Data ss:Type="String">Ersatzbank</Data></Cell></Row><Row ss:Index="49" ss:AutoFitHeight="0" ss:Height="12.1039"><Cell><Data ss:Type="String">net.northshirebund.wbb.calendar</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">net.northshirebund.wbb.calendar.event.signup.state.cancelled</Data></Cell><Cell><Data ss:Type="String">Abgemeldet</Data></Cell><Cell><Data ss:Type="String">Abgemeldet</Data></Cell><Cell><Data ss:Type="String">Abgemeldet</Data></Cell><Cell><Data ss:Type="String">Abgemeldet</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">wcf.acp.group.option.category.user.calendar</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kalender</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.category.user.calendar.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="Default"><Data ss:Type="String">wcf.acp.group.option.category.mod.calendar</Data></Cell><Cell ss:StyleID="ce4"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce4"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce4"><Data ss:Type="String">Kalender</Data></Cell><Cell ss:StyleID="ce4"><Data ss:Type="String">Kalender</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="13.4079"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.category.mod.calendar.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String"> </Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canEnter</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann den Kalender benutzen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann den Kalender benutzen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann den Kalender benutzen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann den Kalender benutzen</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canEnter.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann die Kalenderseite betreten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann die Kalenderseite betreten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann die Kalenderseite betreten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann die Kalenderseite betreten.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canViewEvents</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine betrachten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine betrachten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine betrachten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine betrachten</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canViewEvents.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann Termine betrachten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann Termine betrachten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann Termine betrachten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann Termine betrachten.</Data></Cell></Row><Row ss:Index="59" ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canCreateEvents</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine anlegen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine anlegen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine anlegen</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine anlegen</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canCreateEvents.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann eigene Termine anlegen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann eigene Termine anlegen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann eigene Termine anlegen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann eigene Termine anlegen.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canSignupEvents</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann sich für Termine anmelden</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann sich für Termine anmelden</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann sich für Termine anmelden</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann sich für Termine anmelden</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.user.calendar.canSignupEvents.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann sich für Termine anmelden.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann sich für Termine anmelden.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann sich für Termine anmelden.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann sich für Termine anmelden.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.mod.calendar.canEditEvents</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine bearbeiten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine bearbeiten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine bearbeiten</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Termine bearbeiten</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.mod.calendar.canEditEvents.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann fremde Termine bearbeiten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann fremde Termine bearbeiten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann fremde Termine bearbeiten.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann fremde Termine bearbeiten.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.mod.calendar.canChangeSignupState</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Anmeldestatus ändern</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Anmeldestatus ändern</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Anmeldestatus ändern</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Kann Anmeldestatus ändern</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.acp.group</Data></Cell><Cell ss:StyleID="ce2"><Data ss:Type="String">wcf.acp.group.option.mod.calendar.canChangeSignupState.description</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann den Status von Anmeldungen auf „Akzeptiert“, „Ersatz“ oder „Abgelehnt“ setzen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann den Status von Anmeldungen auf „Akzeptiert“, „Ersatz“ oder „Abgelehnt“ setzen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann den Status von Anmeldungen auf „Akzeptiert“, „Ersatz“ oder „Abgelehnt“ setzen.</Data></Cell><Cell ss:StyleID="ce3"><Data ss:Type="String">Der Benutzer kann den Status von Anmeldungen auf „Akzeptiert“, „Ersatz“ oder „Abgelehnt“ setzen.</Data></Cell></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.usersOnline</Data></Cell><Cell><Data ss:Type="String">wcf.usersOnline.location.calendar</Data></Cell><Cell><Data ss:Type="String">&lt;a href=“index.php?page=Calendar{SID_ARG_2ND}“&gt;Kalender&lt;/a&gt;</Data></Cell><Cell><Data ss:Type="String">&lt;a href=“index.php?page=Calendar{SID_ARG_2ND}“&gt;Kalender&lt;/a&gt;</Data></Cell><Cell><Data ss:Type="String">&lt;a href=“index.php?page=Calendar{SID_ARG_2ND}“&gt;Kalender&lt;/a&gt;</Data></Cell><Cell><Data ss:Type="String">&lt;a href=“index.php?page=Calendar{SID_ARG_2ND}“&gt;Kalender&lt;/a&gt;</Data></Cell></Row><Row ss:Index="69" ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.usersOnline</Data></Cell><Cell><Data ss:Type="String">wcf.usersOnline.location.event.add</Data></Cell><Cell><Data ss:Type="String">Neuen Termin erstellen.</Data></Cell><Cell ss:Index="5"><Data ss:Type="String">Neuen Termin erstellen.</Data></Cell><Cell ss:Index="6"/></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.usersOnline</Data></Cell><Cell><Data ss:Type="String">wcf.usersOnline.location.event.edit</Data></Cell><Cell><Data ss:Type="String">Termin: {$event} bearbeiten.</Data></Cell><Cell ss:Index="5"><Data ss:Type="String">Termin: {$event} bearbeiten.</Data></Cell><Cell ss:Index="6"/></Row><Row ss:AutoFitHeight="0" ss:Height="12.6425"><Cell><Data ss:Type="String">wcf.usersOnline</Data></Cell><Cell><Data ss:Type="String">wcf.usersOnline.location.event.view</Data></Cell><Cell><Data ss:Type="String">Termin: {$event}.</Data></Cell><Cell ss:Index="5"><Data ss:Type="String">Termin: {$event}.</Data></Cell><Cell ss:Index="6"/></Row><Row ss:AutoFitHeight="0" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Index="74" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Index="65494" ss:AutoFitHeight="0" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Index="65510" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Index="65531" ss:AutoFitHeight="0" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Index="65535" ss:Height="12.1039"><Cell ss:Index="6"/></Row><Row ss:Height="12.1039"><Cell ss:Index="6"/></Row></Table><x:WorksheetOptions/></ss:Worksheet></Workbook>

calendar/package.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<package name="net.northshirebund.wbb.calendar">
+    <packageInformation>
+        <packageName>Kalender</packageName>
+        <packageDescription>Ein Kalender fuer das WCF</packageDescription>
+        <version>0.1</version>
+        <plugin>com.woltlab.wcf</plugin>
+        <standalone>0</standalone>
+        <isUnique>1</isUnique>
+    </packageInformation>
+    
+    <authorInformation>
+        <author>Christian Fischer</author>
+        <authorURL>www.northshirebund.net</authorURL>
+    </authorInformation>
+    
+    <requiredPackages>
+        <requiredPackage minversion="1.0.0 RC7">com.woltlab.wcf</requiredPackage>
+        <requiredPackage minversion="1.0.0 RC7">com.woltlab.wcf.data.message.bbcode</requiredPackage>
+        <requiredPackage minversion="1.0.0 RC7">com.woltlab.wcf.form.message.wysiwyg</requiredPackage>
+    </requiredPackages>
+    
+    <optionalPackages>
+    </optionalPackages>
+    
+    <addfiles>
+		<file name="config/groupoptions.xml"					/>
+		<file name="config/headermenu.xml"						/>
+		<file name="config/pagelocation.xml"					/>
+		<file type="tar" tag="files"		src="files/"		/>
+		<file type="tar" tag="templates"	src="templates/"	/>
+    </addfiles>
+    
+	<instructions type="install">
+		<addfiles>
+			<file name="config/install.sql" tag="sql" />
+		</addfiles>
+		<script>acp/calendar_install.php</script>
+	</instructions>
+   
+</package>

calendar/templates/calendar.tpl

+{include file="documentHeader"}
+<head>
+	<title>{lang}net.northshirebund.wbb.calendar.title{/lang} - {PAGE_TITLE}</title>
+	{include file="headInclude"}
+</head>
+<body>
+{include file="header" sandbox=false}
+
+<div id="main">
+	
+	<ul class="breadCrumbs">
+		<li><a href="index.php?page=Index{@SID_ARG_2ND}"><img src="icon/indexS.png" alt="" /> <span>{PAGE_TITLE}</span></a> &raquo;</li>
+	</ul>
+	
+	<div class="mainHeadline">
+		<img src="{@RELATIVE_WCF_DIR}icon/calendarL.png" alt="" />
+		<div class="headlineContainer">
+			<h2> {lang}net.northshirebund.wbb.calendar.title{/lang}</h2>
+		</div>
+	</div>
+	
+	{if $userMessages|isset}{@$userMessages}{/if}
+	
+	{if $view == 'month'}
+		{include file="calendarViewMonth"}
+	{else}
+		Unknown: {$view}
+	{/if}
+	
+</div>
+{include file="footer" sandbox=false}
+
+</body>
+</html>

calendar/templates/calendarAddEvent.tpl

+{include file="documentHeader"}
+<head>
+	<title>{lang}net.northshirebund.wbb.calendar.event.new{/lang} - {lang}net.northshirebund.wbb.calendar.title{/lang} - {PAGE_TITLE}</title>
+	{include file='headInclude' sandbox=false}
+	{include file="wysiwyg"}
+	<script src="{@RELATIVE_WCF_DIR}js/Calendar.class.js" type="text/javascript"></script>
+	<script type="text/javascript">
+		//<![CDATA[
+		function showSearchForm(formID, show) {
+			if (show) {
+				document.getElementById(formID).style.display = 'block';
+			}
+			else {
+				document.getElementById(formID).style.display = 'none';
+			}
+		}
+		
+		var calendar = new Calendar('{$monthList}', '{$weekdayList}', {@$startOfWeek});
+		//]]>
+	</script>
+</head>
+<body>
+{include file='header' sandbox=false}
+
+<div id="main">
+	
+	<ul class="breadCrumbs">
+		<li><a href="index.php?page=Index{@SID_ARG_2ND}"><img src="icon/indexS.png" alt="" /> <span>{PAGE_TITLE}</span></a> &raquo;</li>
+		<li><a href="index.php?page=Calendar{@SID_ARG_2ND}"><img src="{@RELATIVE_WCF_DIR}icon/calendarM.png" alt="" /> <span>{lang}net.northshirebund.wbb.calendar.title{/lang}</span></a> &raquo;</li>
+		{if $event|isset}<li><a href="index.php?page=Calendar&amp;month={$event->month}{@SID_ARG_2ND}"><img src="{@RELATIVE_WCF_DIR}icon/calendarM.png" alt="" /> <span>{lang}net.northshirebund.wbb.calendar.month{$event->month}{/lang}</span></a> &raquo;</li>{/if}
+	</ul>
+	
+	<div class="mainHeadline">
+		<img src="{@RELATIVE_WCF_DIR}icon/calendarL.png" alt="" />
+		<div class="headlineContainer">
+			<h2> {lang}net.northshirebund.wbb.calendar.event.new{/lang}</h2>
+		</div>
+	</div>
+	
+	{if $userMessages|isset}{@$userMessages}{/if}
+	
+	{if $errorField}
+		<p class="error">{lang}wcf.global.form.error{/lang}</p>
+	{/if}
+	
+	{if $preview|isset}
+		<div class="border">
+			<div class="containerHead">
+				<h3>{lang}wcf.pm.preview{/lang}</h3>
+			</div>
+			
+			<div class="message content">
+				<div class="messageInner container-1">
+					{if $subject}
+						<h4>{$subject}</h4>
+					{/if}
+					<div class="messageBody">
+						{@$preview}
+					</div>
+				</div>
+			</div>
+		</div>
+	{/if}
+	
+	<form enctype="multipart/form-data" method="post" action="index.php?form=CalendarAddEvent">
+		<div class="border content">
+			<div class="container-1">
+				<fieldset>
+					<legend>{lang}net.northshirebund.wbb.calendar.event.information{/lang}</legend>
+					
+					<div class="formElement{if $errorField == 'subject'} formError{/if}">
+						<div class="formFieldLabel">
+							<label for="subject">{lang}net.northshirebund.wbb.calendar.event.subject{/lang}</label>
+						</div>
+						<div class="formField">
+							<input type="text" class="inputText" name="subject" id="subject" value="{$event->subject}" />
+							{if $errorField == 'subject'}
+								<p class="innerError">
+									{if $errorType == 'empty'}{lang}wcf.global.error.empty{/lang}{/if}
+								</p>
+							{/if}
+						</div>
+					</div>
+				
+					<div class="formGroup">
+						<div class="formGroupLabel">
+							<label for="fromDay">{lang}net.northshirebund.wbb.calendar.event.time{/lang}</label>
+						</div>
+						
+						<div class="formGroupField{if $errorField == 'date' || $errorField == 'time'} formError{/if}">
+							<fieldset id="eventTime">
+								<legend></legend>
+								
+								<div class="floatedElement">
+									<div class="floatedElement">
+										<label for="eventDay">{lang}wcf.global.date.day{/lang}</label>
+										{htmlOptions options=$dayOptions selected=$event->day id=eventDay name=eventDay}
+									</div>
+									
+									<div class="floatedElement">
+										<label for="eventMonth">{lang}wcf.global.date.month{/lang}</label>
+										{htmlOptions options=$monthOptions selected=$event->month id=eventMonth name=eventMonth}
+									</div>
+									
+									<div class="floatedElement">
+										<label for="eventYear">{lang}wcf.global.date.year{/lang}</label>
+										<input id="eventYear" class="inputText fourDigitInput" type="text" name="eventYear" value="{$event->year}" maxlength="4" />
+									</div>
+									
+									<div class="floatedElement">
+										<a id="eventButton"><img src="{@RELATIVE_WCF_DIR}icon/calendarOptionsM.png" alt="" /></a>
+										<div id="eventCalendar" class="inlineCalendar"></div>
+									</div>
+									
+									<div class="floatedElement">
+										<label for="eventHour">{lang}wcf.global.date.hour{/lang}</label>
+										<input id="eventHour" class="inputText fourDigitInput" type="text" name="eventHour" value="{$event->hour}" maxlength="2" />
+									</div>
+									
+									<div class="floatedElement">
+										<label for="eventMinute">{lang}wcf.global.date.minutes{/lang}</label>
+										<input id="eventMinute" class="inputText fourDigitInput" type="text" name="eventMinute" value="{$event->minute}" maxlength="2" />
+									</div>
+								</div>
+								
+								<script type="text/javascript">
+									//<![CDATA[
+									calendar.init('event');
+									//]]>
+								</script>
+							</fieldset>
+						{if $errorField == 'date'}
+							<p class="innerError">
+								{if $errorType == 'invalid'}{lang}net.northshirebund.wbb.calendar.error.invalidDate{/lang}{/if}
+							</p>
+						{/if}
+						{if $errorField == 'time'}
+							<p class="innerError">
+								{if $errorType == 'invalid'}{lang}net.northshirebund.wbb.calendar.error.invalidTime{/lang}{/if}
+								{if $errorType == 'outdated'}{lang}net.northshirebund.wbb.calendar.error.outdatedTime{/lang}{/if}
+							</p>
+						{/if}
+						</div>
+					</div>
+					
+					<div class="formElement{if $errorField == 'duration'} formError{/if}">
+						<div class="formFieldLabel">
+							<label for="duration">{lang}net.northshirebund.wbb.calendar.event.duration{/lang}</label>
+						</div>
+						<div class="formField">
+							<input type="text" class="inputText" name="duration" id="duration" value="{$event->duration}" />
+							{if $errorField == 'duration'}
+								<p class="innerError">
+									{if $errorType == 'illegal'}{lang}wcf.user.option.error.validationFailed{/lang}{/if}
+								</p>
+							{/if}
+						</div>
+					</div>
+				
+					{if $event->canHandleSignups()}
+					<div class="formElement{if $errorField == 'signupMax'} formError{/if}">
+						<div class="formFieldLabel">
+							<label for="subject">{lang}net.northshirebund.wbb.calendar.event.maxSignups{/lang}</label>
+						</div>
+						<div class="formField">
+							<input type="text" class="inputText" name="signupMax" id="signupMax" value="{$event->signupMax}" />
+							{if $errorField == 'signupMax'}
+								<p class="innerError">
+									{if $errorType == 'invalid'}{lang}net.northshirebund.wbb.calendar.error.invalidMaxSignups{/lang}{/if}
+								</p>
+							{/if}
+						</div>
+					</div>
+					{/if}
+				</fieldset>
+					
+				<fieldset>
+					<legend>{lang}net.northshirebund.wbb.calendar.event.text{/lang}</legend>
+					
+					<div class="formElement{if $errorField == 'text'} formError{/if}" id="editor">
+						<div class="formFieldLabel">
+							<label for="text">{lang}net.northshirebund.wbb.calendar.event.text{/lang}</label>
+						</div>
+						<div class="formField">
+							<textarea name="text" id="text" rows="20" cols="40">{$event->message}</textarea>
+							{if $errorField == 'text'}
+								<p class="innerError">
+									{if $errorType == 'empty'}{lang}wcf.global.error.empty{/lang}{/if}
+									{if $errorType == 'tooLong'}{lang}wcf.message.error.tooLong{/lang}{/if}
+									{if $errorType == 'censoredWordsFound'}{lang}wcf.message.error.censoredWordsFound{/lang}{/if}
+								</p>
+							{/if}
+						</div>
+					</div>
+					{*
+					{include file="messageFormTabs"}
+					*}
+				</fieldset>
+				{*
+				{if $additionalFields|isset}{@$additionalFields}{/if}
+				*}
+			</div>
+		</div>
+		
+		<div class="formSubmit">
+			<input type="hidden" name="class" value="{$event->eventType}" />
+			<input type="submit" name="send" accesskey="s" value="{lang}wcf.global.button.submit{/lang}" />
+			<input type="submit" name="preview" accesskey="p" value="{lang}wcf.global.button.preview{/lang}" />
+			<input type="reset" name="reset" accesskey="r" value="{lang}wcf.global.button.reset{/lang}" />
+		</div>
+		
+		{@SID_INPUT_TAG}
+	</form>
+	
+</div>
+
+{include file='footer' sandbox=false}
+</body>
+</html>

calendar/templates/calendarEditEvent.tpl

+{include file="documentHeader"}
+<head>
+	<title>{lang}net.northshirebund.wbb.calendar.event.new{/lang} - {lang}net.northshirebund.wbb.calendar.title{/lang} - {PAGE_TITLE}</title>
+	{include file='headInclude' sandbox=false}
+	{include file="wysiwyg"}
+	<script src="{@RELATIVE_WCF_DIR}js/Calendar.class.js" type="text/javascript"></script>
+	<script type="text/javascript">
+		//<![CDATA[
+		function showSearchForm(formID, show) {
+			if (show) {
+				document.getElementById(formID).style.display = 'block';
+			}
+			else {
+				document.getElementById(formID).style.display = 'none';
+			}
+		}
+		
+		var calendar = new Calendar('{$monthList}', '{$weekdayList}', {@$startOfWeek});
+		//]]>
+	</script>
+</head>
+<body>
+{include file='header' sandbox=false}
+
+<div id="main">
+	
+	<ul class="breadCrumbs">
+		<li><a href="index.php?page=Index{@SID_ARG_2ND}"><img src="icon/indexS.png" alt="" /> <span>{PAGE_TITLE}</span></a> &raquo;</li>
+		<li><a href="index.php?page=Calendar{@SID_ARG_2ND}"><img src="{@RELATIVE_WCF_DIR}icon/calendarM.png" alt="" /> <span>{lang}net.northshirebund.wbb.calendar.title{/lang}</span></a> &raquo;</li>
+		{if $event|isset}<li><a href="index.php?page=Calendar&amp;month={$event->month}{@SID_ARG_2ND}"><img src="{@RELATIVE_WCF_DIR}icon/calendarM.png" alt="" /> <span>{lang}net.northshirebund.wbb.calendar.month{$event->month}{/lang}</span></a> &raquo;</li>{/if}
+	</ul>
+	
+	<div class="mainHeadline">
+		<img src="{@RELATIVE_WCF_DIR}icon/calendarL.png" alt="" />
+		<div class="headlineContainer">
+			<h2> {lang}net.northshirebund.wbb.calendar.event.new{/lang}</h2>
+		</div>
+	</div>
+	
+	{if $userMessages|isset}{@$userMessages}{/if}
+	
+	{if $errorField}
+		<p class="error">{lang}wcf.global.form.error{/lang}</p>
+	{/if}
+	
+	{if $preview|isset}
+		<div class="border">
+			<div class="containerHead">
+				<h3>{lang}wcf.pm.preview{/lang}</h3>
+			</div>
+			
+			<div class="message content">
+				<div class="messageInner container-1">
+					{if $subject}
+						<h4>{$subject}</h4>
+					{/if}
+					<div class="messageBody">
+						{@$preview}
+					</div>
+				</div>
+			</div>
+		</div>