summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Wrobel <wrobel@pardus.de>2009-10-07 21:01:46 (GMT)
committerGunnar Wrobel <wrobel@pardus.de>2009-10-07 21:01:46 (GMT)
commit575e24afdabfb882140b3f4cfc834dbe45b754c7 (patch)
tree96e70b7a213557a85013d7b0c2799e0ab87bd67c
parent14ebc367f1615e5b7cfefa5b1d08c3800592fbb2 (diff)
downloadserver-575e24afdabfb882140b3f4cfc834dbe45b754c7.tar.gz
Added functionality for anonymous
java script based export of calendar data.
-rw-r--r--kolab-webclient/ChangeLog5
-rw-r--r--kolab-webclient/Makefile2
-rw-r--r--kolab-webclient/kolab-webclient.spec6
-rw-r--r--patches/horde-webmail/1.2.0/horde-webmail-1.2.0_kolab_openpkg.patch453
-rw-r--r--patches/horde-webmail/1.2.0/tg/series1
-rw-r--r--patches/horde-webmail/1.2.0/tg/t_kronolith_HK_GW_ExportEventList.diff453
6 files changed, 916 insertions, 4 deletions
diff --git a/kolab-webclient/ChangeLog b/kolab-webclient/ChangeLog
index ab9751e..39a663a 100644
--- a/kolab-webclient/ChangeLog
+++ b/kolab-webclient/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-07 Gunnar Wrobel <p@rdus.de>
+
+ * kolab-webclient.spec: Added functionality for anonymous
+ java script based export of calendar data.
+
2009-05-28 Gunnar Wrobel <p@rdus.de>
* kolab-webclient.spec: Added functionality for anonymous
diff --git a/kolab-webclient/Makefile b/kolab-webclient/Makefile
index 4e49e2a..16e0c52 100644
--- a/kolab-webclient/Makefile
+++ b/kolab-webclient/Makefile
@@ -26,7 +26,7 @@ PACKAGE = $(shell grep "%define[ ]*V_package" *.spec | sed -e "s/.*V_package \([
VERSION = $(shell grep "%define[ ]*V_version" *.spec | sed -e "s/.*V_version\s*\([0-9._a-z]*\).*/\1/")
SOURCE_VERSION = $(shell grep "%define[ ]*V_source_version" *.spec | sed -e "s/.*V_source_version\s*\([0-9._a-z-]*\).*/\1/")
PASSWD_VERSION = $(shell grep "%define[ ]*V_passwd_version" *.spec | sed -e "s/.*V_passwd_version\s*\([0-9._a-z]*\).*/\1/")
-RELEASE = ${YEAR}${MONTH}${DAY}suc03
+RELEASE = ${YEAR}${MONTH}${DAY}suc01
PATCHES = ../patches/horde-webmail/$(VERSION)/horde-webmail-$(VERSION)_kolab_openpkg.patch
TEMPLATES = $(shell find . -name "*.template")
diff --git a/kolab-webclient/kolab-webclient.spec b/kolab-webclient/kolab-webclient.spec
index 3721ecd..05aef59 100644
--- a/kolab-webclient/kolab-webclient.spec
+++ b/kolab-webclient/kolab-webclient.spec
@@ -2,13 +2,13 @@
%define V_horde_name horde-webmail
%define V_package kolab-webclient
%define V_year 2009
-%define V_month 06
-%define V_day 26
+%define V_month 10
+%define V_day 07
%define V_version 1.2.0
%define V_source_version 1.2
%define V_passwd_version 3.0.1
%define V_date %{V_year}-%{V_month}-%{V_day}
-%define V_release %{V_year}%{V_month}%{V_day}suc03
+%define V_release %{V_year}%{V_month}%{V_day}suc01
# Package Information
Name: %{V_package}
diff --git a/patches/horde-webmail/1.2.0/horde-webmail-1.2.0_kolab_openpkg.patch b/patches/horde-webmail/1.2.0/horde-webmail-1.2.0_kolab_openpkg.patch
index 0062a39..14bd784 100644
--- a/patches/horde-webmail/1.2.0/horde-webmail-1.2.0_kolab_openpkg.patch
+++ b/patches/horde-webmail/1.2.0/horde-webmail-1.2.0_kolab_openpkg.patch
@@ -27122,6 +27122,459 @@ Author: Gunnar Wrobel <p@rdus.de>
Date: Thu May 28 12:42:44 2009 +0200
First version of the anonymous ics download patch.
+From: Gunnar Wrobel <p@rdus.de>
+Subject: [PATCH] t/kronolith/HK/GW/ExportEventList
+
+Export a list of events.
+
+STATUS: OPEN
+
+Signed-off-by: Gunnar Wrobel <p@rdus.de>
+
+---
+ horde-webmail/kronolith/imple_kolab.php | 92 +++++++++
+ horde-webmail/kronolith/lib/Block/eventlist.php | 243 +++++++++++++++++++++++
+ horde-webmail/kronolith/themes/embed.css | 51 +++++-
+ horde-webmail/lib/Horde/Kolab/Storage/List.php | 2 +-
+ 4 files changed, 386 insertions(+), 2 deletions(-)
+
+diff --git a/horde-webmail/kronolith/imple_kolab.php b/horde-webmail/kronolith/imple_kolab.php
+new file mode 100644
+index 0000000..f18d2ad
+--- /dev/null
++++ b/horde-webmail/kronolith/imple_kolab.php
+@@ -0,0 +1,92 @@
++<?php
++/**
++ * $Horde: kronolith/imple.php,v 1.1.2.3 2008/04/25 03:50:58 chuck Exp $
++ *
++ * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
++ *
++ * See the enclosed file COPYING for license information (GPL). If you
++ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
++ *
++ * @author Michael Slusarz <slusarz@horde.org>
++ */
++if (!defined('HORDE_BASE')) {
++ define('HORDE_BASE', dirname(__FILE__) . '/..');
++}
++
++/* Load the Horde Framework core, and set up inclusion paths. */
++require_once HORDE_BASE . '/lib/core.php';
++
++@define('AUTH_HANDLER', true);
++/* Registry. */
++$session_control = 'none';
++$registry = &Registry::singleton(HORDE_SESSION_NONE);
++
++$auth = &Auth::singleton($conf['auth']['driver']);
++
++if (isset($conf['ics']['default_user'])
++ && isset($conf['ics']['default_pass'])) {
++ $user = $conf['ics']['default_user'];
++ $pass = $conf['ics']['default_pass'];
++ $auth->authenticate($user,
++ array('password' =>
++ $pass));
++}
++
++@define('KRONOLITH_BASE', dirname(__FILE__));
++require_once KRONOLITH_BASE . '/lib/base.php';
++require_once KRONOLITH_BASE . '/lib/Imple.php';
++
++
++$path = Util::getFormData('imple');
++if (!$path) {
++ exit;
++}
++if ($path[0] == '/') {
++ $path = substr($path, 1);
++}
++$path = explode('/', $path);
++$impleName = array_shift($path);
++
++$imple = Imple::factory($impleName);
++if (!$imple) {
++ exit;
++}
++
++$args = array();
++foreach ($path as $pair) {
++ if (strpos($pair, '=') === false) {
++ $args[$pair] = true;
++ } else {
++ list($name, $val) = explode('=', $pair);
++ $args[$name] = $val;
++ }
++}
++
++$result = $imple->handle($args);
++
++if (!empty($_SERVER['Content-Type'])) {
++ $ct = $_SERVER['Content-Type'];
++} else {
++ $ct = is_string($result) ? 'plain' : 'json';
++}
++
++switch ($ct) {
++case 'json':
++ header('Content-Type: text/x-json');
++ require_once KRONOLITH_BASE . '/lib/JSON.php';
++ echo Kronolith_Serialize_JSON::encode(String::convertCharset($result, NLS::getCharset(), 'utf-8'));
++ break;
++
++case 'plain':
++ header('Content-Type: text/plain');
++ echo $result;
++ break;
++
++case 'html':
++ header('Content-Type: text/html');
++ echo $result;
++ break;
++
++default:
++ echo $result;
++}
+diff --git a/horde-webmail/kronolith/lib/Block/eventlist.php b/horde-webmail/kronolith/lib/Block/eventlist.php
+new file mode 100644
+index 0000000..420a984
+--- /dev/null
++++ b/horde-webmail/kronolith/lib/Block/eventlist.php
+@@ -0,0 +1,243 @@
++<?php
++
++$block_name = _("Calendar List View");
++
++/**
++ * Horde_Block_Kronolith_eventlist:: Implementation of the Horde_Block API to
++ * display a list of events.
++ *
++ * $Horde: kronolith/lib/Block/summary.php,v 1.41.2.14 2008/08/21 00:31:03 mrubinsk Exp $
++ *
++ * @package Horde_Block
++ */
++class Horde_Block_Kronolith_eventlist extends Horde_Block {
++
++ var $_app = 'kronolith';
++
++ function _params()
++ {
++ @define('KRONOLITH_BASE', dirname(__FILE__) . '/../..');
++ require_once KRONOLITH_BASE . '/lib/base.php';
++
++ $params = array('days' => array('name' => _("Days"),
++ 'type' => 'int',
++ 'default' => 42),
++ 'maxevents' => array('name' => _("Maximum number of events to display (0 = no limit)"),
++ 'type' => 'int',
++ 'default' => 0));
++
++ return $params;
++ }
++
++ /**
++ * The title to go in this block.
++ *
++ * @return string The title text.
++ */
++ function _title()
++ {
++ global $registry;
++ return '';
++ }
++
++ /**
++ * The content to go in this block.
++ *
++ * @return string The content
++ */
++ function _content()
++ {
++ global $kronolith_driver, $registry, $prefs;
++ require_once dirname(__FILE__) . '/../base.php';
++ require_once KRONOLITH_BASE . '/lib/Day.php';
++ require_once 'Horde/Prefs/CategoryManager.php';
++ require_once 'Horde/Text/Filter.php';
++
++ if (!empty($this->_params['days'])) {
++ $span = $this->_params['days'];
++ } else {
++ $span = 42;
++ }
++
++ $now = $_SERVER['REQUEST_TIME'];
++ $today = date('j');
++
++ $startDate = new Horde_Date(array('year' => date('Y'), 'month' => date('n'), 'mday' => date('j')));
++ $endDate = new Horde_Date(array('year' => date('Y'), 'month' => date('n'), 'mday' => date('j') + $span));
++ $endDate->correct();
++
++ if (isset($this->_params['calendar']) &&
++ $this->_params['calendar'] != '__all') {
++
++ $calendar = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']);
++ if (!is_a($calendar, 'PEAR_Error') && !$calendar->hasPermission(Auth::getAuth(), PERMS_SHOW)) {
++ return _("Permission Denied");
++ }
++
++ $all_events = Kronolith::listEvents($startDate,
++ $endDate,
++ array($this->_params['calendar']));
++ } else {
++ $calendars = Kronolith::listCalendars(false, PERMS_SHOW);
++ $all_events = Kronolith::listEvents($startDate,
++ $endDate,
++ array_keys($calendars));
++ }
++ if (is_a($all_events, 'PEAR_Error')) {
++ return '<em>' . $all_events->getMessage() . '</em>';
++ }
++
++ $iMax = $today + $span;
++
++ $html = '';
++ $firstday = true;
++ $olddayname = '';
++ $totalevents = 0;
++
++ $displayed = array();
++
++ for ($i = $today; $i < $iMax; ++$i) {
++ $day = new Kronolith_Day(date('n'), $i);
++
++ if ($day->isToday()) {
++ $dayname = _("Today");
++ } elseif ($day->isTomorrow()) {
++ $dayname = _("Tomorrow");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear()) {
++ $dayname = _("This week");
++ } elseif ($day->month == $startDate->month) {
++ if ($day->weekOfYear() == $startDate->weekOfYear() + 1) {
++ $dayname = _("Next week");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 2) {
++ $dayname = _("Two weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 3) {
++ $dayname = _("Three weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 4) {
++ $dayname = _("Four weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 5) {
++ $dayname = _("Five weeks from now");
++ }
++ } elseif ($day->month - 1 == $startDate->month
++ || ($day->month == 1 && $startDate->month == 12)) {
++ $dayname = _("Next month");
++ } elseif ($day->year == $startDate->year) {
++ $dayname = $day->format('F');
++ } elseif ($day->year - 1 == $startDate->year) {
++ $dayname = _("Next year");
++ } else {
++ $dayname = _("After the next year");
++ }
++
++ if (empty($all_events[$day->getStamp()])) {
++ continue;
++ }
++
++ $events = &$all_events[$day->getStamp()];
++
++ $today12am = mktime(0, 0, 0,
++ $day->month,
++ $day->mday,
++ $day->year);
++ $tomorrow12am = mktime(0, 0, 0,
++ $day->month,
++ $day->mday + 1,
++ $day->year);
++ foreach ($events as $event) {
++
++ if (!empty($this->_params['maxevents']) &&
++ $totalevents >= $this->_params['maxevents']) {
++ break 2;
++ }
++
++ if ($event->end->timestamp() < $now) {
++ continue;
++ }
++ if ($dayname != $olddayname) {
++ if (!$firstday) {
++ $html .= '<tr><td colspan="3">&nbsp;</td></tr>';
++ }
++ $html .= '<tr align="center"><td colspan="3" class="section">';
++ $html .= $dayname . '</td></tr>';
++ $olddayname = $dayname;
++ $firstday = false;
++ }
++
++ if (in_array($event->getId(), $displayed)) {
++ continue;
++ }
++
++ $category = $event->getCategory();
++ if (!empty($category)) {
++ $ctd = '<td class="category_bar category' . md5($category) . '" width="1%" />';
++ } else {
++ $ctd = '<td />';
++ }
++
++ if ($event->isAllDay()) {
++ $format = 'D, d M Y';
++ } else {
++ $format = 'G:i T D, d M Y';
++ }
++
++ if ($event->start->timestamp() < $now) {
++ $time = _('until') . date($format, $event->end->timestamp());
++ } else {
++ $time = date($format, $event->start->timestamp()) . _(' to ') .
++ date($format, $event->end->timestamp());
++ }
++
++ $html .= '<tr>' . $ctd . '<td class="event" style="vertical-align:top;"><div class="time">';
++
++ if ($event->start->timestamp() < $now &&
++ $event->end->timestamp() > $now) {
++ $html .= '<strong>';
++ }
++
++ $html .= $time;
++
++ if ($event->start->timestamp() < $now &&
++ $event->end->timestamp() > $now) {
++ $html .= '</strong>';
++ }
++
++ $html .= '</div><div class="location" style="vertical-align:top">';
++ $html .= $event->getLocation();
++ $html .= '</div></td><td style="vertical-align:top;" class="event"><div class="eventtitle">';
++ $html .= $event->getTitle();
++ $html .= '</div>';
++
++ $html .= '<div class="description">';
++ $desc = Text_Filter::filter($event->getDescription(), 'text2html', array('parselevel' => TEXT_HTML_MICRO, 'class' => 'text'));
++ $html .= strtr($desc, array("\n" => " ", "\r" => " "));
++ $html .= '</div>';
++
++ $html .= '</td></tr>';
++
++ $html .= '<tr>' . $ctd . '<td class="linedRow"/><td class="linedRow annotation">';
++
++ if (!empty($category)) {
++ $html .= '<div style="text-align:right;float:left;">';
++ $html .= _("Category") . ': ' . $category;
++ $html .= '</div>';
++ }
++
++ $html .= '<div style="text-align:right">';
++ $html .= _("Calendar") . ': ' . urldecode($event->getCalendar());
++ $html .= '</div>';
++
++ $html .= '</td></tr>';
++
++ $totalevents++;
++
++ $displayed[] = $event->getId();
++ }
++ }
++
++ if (empty($html)) {
++ return '<em>' . _("No events to display") . '</em>';
++ }
++
++ return '<link href="' . Horde::applicationUrl('themes/categoryCSS.php') . '" rel="stylesheet" type="text/css" /><table cellspacing="0" width="100%">' . $html . '</table>';
++ }
++
++}
+diff --git a/horde-webmail/kronolith/themes/embed.css b/horde-webmail/kronolith/themes/embed.css
+index 6ce8835..b084aa2 100644
+--- a/horde-webmail/kronolith/themes/embed.css
++++ b/horde-webmail/kronolith/themes/embed.css
+@@ -103,4 +103,53 @@ div.horde_nicetitle pre {
+ text-align: left;
+ font-size: 75%;
+ font-family: "Lucida Console",Courier,"Courier New";
+-}
+\ No newline at end of file
++}
++
++.kronolith_embedded category_bar {
++}
++
++.kronolith_embedded .eventtitle {
++ font-weight: bold;
++ padding: 5px;
++}
++
++.kronolith_embedded .leftbar {
++ border-right: 1px solid #DDDDDD;
++ padding: 4px;
++}
++
++.kronolith_embedded .location {
++ font-size: 85%;
++ padding-top: 10px;
++ margin-left: 5px;
++}
++
++.kronolith_embedded .annotation {
++ font-size: 75%;
++ padding-top: 10px;
++ padding-left: 5px;
++}
++
++.kronolith_embedded .description {
++ font-size: 85%;
++ padding-top: 10px;
++ padding-left: 5px;
++}
++
++.kronolith_embedded .time {
++ font-size: 85%;
++ margin-top: 5px;
++ padding: 5px;
++ margin-left: 5px;
++ background: #ddddff;
++ -moz-border-radius: 5px;
++ -webkit-border-radius: 5px;
++}
++
++.kronolith_embedded .section {
++ font-weight: bold;
++ background: #eeeeee;
++ border-bottom: 1px solid #999999;
++ color: #000000;
++ padding: 1px;
++}
+diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
+index a9bff36..a31ef82 100644
+--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
++++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
+@@ -136,7 +136,7 @@ class Kolab_List {
+ */
+ function &listFolders()
+ {
+- if (!isset($this->_list)) {
++ if (!isset($this->_list) || is_a($this->_list, 'PEAR_Error')) {
+ $session = &Horde_Kolab_Session::singleton();
+ $imap = &$session->getImap();
+ if (is_a($imap, 'PEAR_Error')) {
+--
+tg: (2f74c4c..) t/kronolith/HK/GW/ExportEventList (depends on: t/dimp/H/BL/CloseContextMenu)
+--
+TOPGIT patch commit log
+=======================
+
+commit 992834cabdcc4a7aabbf566c7a5a27df639bef98
+Author: Gunnar Wrobel <p@rdus.de>
+Date: Wed Oct 7 22:22:07 2009 +0200
+
+ Comment.
+
+commit 787cac7fd3a7dd282ad66596c30fc0eaf67bbe20
+Author: Gunnar Wrobel <p@rdus.de>
+Date: Wed Oct 7 22:19:43 2009 +0200
+
+ Export a list of events.
diff -c a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
diff --git a/patches/horde-webmail/1.2.0/tg/series b/patches/horde-webmail/1.2.0/tg/series
index 0530e06..852b4f7 100644
--- a/patches/horde-webmail/1.2.0/tg/series
+++ b/patches/horde-webmail/1.2.0/tg/series
@@ -71,3 +71,4 @@ t_Kolab__Format_HK_GW_HandleEmptyXmlParserReturn.diff -p1
t_pear_HK_GW_AddNetLDAP2.diff -p1
t_Kolab__Server_HK_GW_MappableAttributes.diff -p1
t_kronolith_HK_GW_AnonymousiCalDownload.diff -p1
+t_kronolith_HK_GW_ExportEventList.diff -p1
diff --git a/patches/horde-webmail/1.2.0/tg/t_kronolith_HK_GW_ExportEventList.diff b/patches/horde-webmail/1.2.0/tg/t_kronolith_HK_GW_ExportEventList.diff
new file mode 100644
index 0000000..28bf727
--- /dev/null
+++ b/patches/horde-webmail/1.2.0/tg/t_kronolith_HK_GW_ExportEventList.diff
@@ -0,0 +1,453 @@
+From: Gunnar Wrobel <p@rdus.de>
+Subject: [PATCH] t/kronolith/HK/GW/ExportEventList
+
+Export a list of events.
+
+STATUS: OPEN
+
+Signed-off-by: Gunnar Wrobel <p@rdus.de>
+
+---
+ horde-webmail/kronolith/imple_kolab.php | 92 +++++++++
+ horde-webmail/kronolith/lib/Block/eventlist.php | 243 +++++++++++++++++++++++
+ horde-webmail/kronolith/themes/embed.css | 51 +++++-
+ horde-webmail/lib/Horde/Kolab/Storage/List.php | 2 +-
+ 4 files changed, 386 insertions(+), 2 deletions(-)
+
+diff --git a/horde-webmail/kronolith/imple_kolab.php b/horde-webmail/kronolith/imple_kolab.php
+new file mode 100644
+index 0000000..f18d2ad
+--- /dev/null
++++ b/horde-webmail/kronolith/imple_kolab.php
+@@ -0,0 +1,92 @@
++<?php
++/**
++ * $Horde: kronolith/imple.php,v 1.1.2.3 2008/04/25 03:50:58 chuck Exp $
++ *
++ * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
++ *
++ * See the enclosed file COPYING for license information (GPL). If you
++ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
++ *
++ * @author Michael Slusarz <slusarz@horde.org>
++ */
++if (!defined('HORDE_BASE')) {
++ define('HORDE_BASE', dirname(__FILE__) . '/..');
++}
++
++/* Load the Horde Framework core, and set up inclusion paths. */
++require_once HORDE_BASE . '/lib/core.php';
++
++@define('AUTH_HANDLER', true);
++/* Registry. */
++$session_control = 'none';
++$registry = &Registry::singleton(HORDE_SESSION_NONE);
++
++$auth = &Auth::singleton($conf['auth']['driver']);
++
++if (isset($conf['ics']['default_user'])
++ && isset($conf['ics']['default_pass'])) {
++ $user = $conf['ics']['default_user'];
++ $pass = $conf['ics']['default_pass'];
++ $auth->authenticate($user,
++ array('password' =>
++ $pass));
++}
++
++@define('KRONOLITH_BASE', dirname(__FILE__));
++require_once KRONOLITH_BASE . '/lib/base.php';
++require_once KRONOLITH_BASE . '/lib/Imple.php';
++
++
++$path = Util::getFormData('imple');
++if (!$path) {
++ exit;
++}
++if ($path[0] == '/') {
++ $path = substr($path, 1);
++}
++$path = explode('/', $path);
++$impleName = array_shift($path);
++
++$imple = Imple::factory($impleName);
++if (!$imple) {
++ exit;
++}
++
++$args = array();
++foreach ($path as $pair) {
++ if (strpos($pair, '=') === false) {
++ $args[$pair] = true;
++ } else {
++ list($name, $val) = explode('=', $pair);
++ $args[$name] = $val;
++ }
++}
++
++$result = $imple->handle($args);
++
++if (!empty($_SERVER['Content-Type'])) {
++ $ct = $_SERVER['Content-Type'];
++} else {
++ $ct = is_string($result) ? 'plain' : 'json';
++}
++
++switch ($ct) {
++case 'json':
++ header('Content-Type: text/x-json');
++ require_once KRONOLITH_BASE . '/lib/JSON.php';
++ echo Kronolith_Serialize_JSON::encode(String::convertCharset($result, NLS::getCharset(), 'utf-8'));
++ break;
++
++case 'plain':
++ header('Content-Type: text/plain');
++ echo $result;
++ break;
++
++case 'html':
++ header('Content-Type: text/html');
++ echo $result;
++ break;
++
++default:
++ echo $result;
++}
+diff --git a/horde-webmail/kronolith/lib/Block/eventlist.php b/horde-webmail/kronolith/lib/Block/eventlist.php
+new file mode 100644
+index 0000000..420a984
+--- /dev/null
++++ b/horde-webmail/kronolith/lib/Block/eventlist.php
+@@ -0,0 +1,243 @@
++<?php
++
++$block_name = _("Calendar List View");
++
++/**
++ * Horde_Block_Kronolith_eventlist:: Implementation of the Horde_Block API to
++ * display a list of events.
++ *
++ * $Horde: kronolith/lib/Block/summary.php,v 1.41.2.14 2008/08/21 00:31:03 mrubinsk Exp $
++ *
++ * @package Horde_Block
++ */
++class Horde_Block_Kronolith_eventlist extends Horde_Block {
++
++ var $_app = 'kronolith';
++
++ function _params()
++ {
++ @define('KRONOLITH_BASE', dirname(__FILE__) . '/../..');
++ require_once KRONOLITH_BASE . '/lib/base.php';
++
++ $params = array('days' => array('name' => _("Days"),
++ 'type' => 'int',
++ 'default' => 42),
++ 'maxevents' => array('name' => _("Maximum number of events to display (0 = no limit)"),
++ 'type' => 'int',
++ 'default' => 0));
++
++ return $params;
++ }
++
++ /**
++ * The title to go in this block.
++ *
++ * @return string The title text.
++ */
++ function _title()
++ {
++ global $registry;
++ return '';
++ }
++
++ /**
++ * The content to go in this block.
++ *
++ * @return string The content
++ */
++ function _content()
++ {
++ global $kronolith_driver, $registry, $prefs;
++ require_once dirname(__FILE__) . '/../base.php';
++ require_once KRONOLITH_BASE . '/lib/Day.php';
++ require_once 'Horde/Prefs/CategoryManager.php';
++ require_once 'Horde/Text/Filter.php';
++
++ if (!empty($this->_params['days'])) {
++ $span = $this->_params['days'];
++ } else {
++ $span = 42;
++ }
++
++ $now = $_SERVER['REQUEST_TIME'];
++ $today = date('j');
++
++ $startDate = new Horde_Date(array('year' => date('Y'), 'month' => date('n'), 'mday' => date('j')));
++ $endDate = new Horde_Date(array('year' => date('Y'), 'month' => date('n'), 'mday' => date('j') + $span));
++ $endDate->correct();
++
++ if (isset($this->_params['calendar']) &&
++ $this->_params['calendar'] != '__all') {
++
++ $calendar = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']);
++ if (!is_a($calendar, 'PEAR_Error') && !$calendar->hasPermission(Auth::getAuth(), PERMS_SHOW)) {
++ return _("Permission Denied");
++ }
++
++ $all_events = Kronolith::listEvents($startDate,
++ $endDate,
++ array($this->_params['calendar']));
++ } else {
++ $calendars = Kronolith::listCalendars(false, PERMS_SHOW);
++ $all_events = Kronolith::listEvents($startDate,
++ $endDate,
++ array_keys($calendars));
++ }
++ if (is_a($all_events, 'PEAR_Error')) {
++ return '<em>' . $all_events->getMessage() . '</em>';
++ }
++
++ $iMax = $today + $span;
++
++ $html = '';
++ $firstday = true;
++ $olddayname = '';
++ $totalevents = 0;
++
++ $displayed = array();
++
++ for ($i = $today; $i < $iMax; ++$i) {
++ $day = new Kronolith_Day(date('n'), $i);
++
++ if ($day->isToday()) {
++ $dayname = _("Today");
++ } elseif ($day->isTomorrow()) {
++ $dayname = _("Tomorrow");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear()) {
++ $dayname = _("This week");
++ } elseif ($day->month == $startDate->month) {
++ if ($day->weekOfYear() == $startDate->weekOfYear() + 1) {
++ $dayname = _("Next week");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 2) {
++ $dayname = _("Two weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 3) {
++ $dayname = _("Three weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 4) {
++ $dayname = _("Four weeks from now");
++ } elseif ($day->weekOfYear() == $startDate->weekOfYear() + 5) {
++ $dayname = _("Five weeks from now");
++ }
++ } elseif ($day->month - 1 == $startDate->month
++ || ($day->month == 1 && $startDate->month == 12)) {
++ $dayname = _("Next month");
++ } elseif ($day->year == $startDate->year) {
++ $dayname = $day->format('F');
++ } elseif ($day->year - 1 == $startDate->year) {
++ $dayname = _("Next year");
++ } else {
++ $dayname = _("After the next year");
++ }
++
++ if (empty($all_events[$day->getStamp()])) {
++ continue;
++ }
++
++ $events = &$all_events[$day->getStamp()];
++
++ $today12am = mktime(0, 0, 0,
++ $day->month,
++ $day->mday,
++ $day->year);
++ $tomorrow12am = mktime(0, 0, 0,
++ $day->month,
++ $day->mday + 1,
++ $day->year);
++ foreach ($events as $event) {
++
++ if (!empty($this->_params['maxevents']) &&
++ $totalevents >= $this->_params['maxevents']) {
++ break 2;
++ }
++
++ if ($event->end->timestamp() < $now) {
++ continue;
++ }
++ if ($dayname != $olddayname) {
++ if (!$firstday) {
++ $html .= '<tr><td colspan="3">&nbsp;</td></tr>';
++ }
++ $html .= '<tr align="center"><td colspan="3" class="section">';
++ $html .= $dayname . '</td></tr>';
++ $olddayname = $dayname;
++ $firstday = false;
++ }
++
++ if (in_array($event->getId(), $displayed)) {
++ continue;
++ }
++
++ $category = $event->getCategory();
++ if (!empty($category)) {
++ $ctd = '<td class="category_bar category' . md5($category) . '" width="1%" />';
++ } else {
++ $ctd = '<td />';
++ }
++
++ if ($event->isAllDay()) {
++ $format = 'D, d M Y';
++ } else {
++ $format = 'G:i T D, d M Y';
++ }
++
++ if ($event->start->timestamp() < $now) {
++ $time = _('until') . date($format, $event->end->timestamp());
++ } else {
++ $time = date($format, $event->start->timestamp()) . _(' to ') .
++ date($format, $event->end->timestamp());
++ }
++
++ $html .= '<tr>' . $ctd . '<td class="event" style="vertical-align:top;"><div class="time">';
++
++ if ($event->start->timestamp() < $now &&
++ $event->end->timestamp() > $now) {
++ $html .= '<strong>';
++ }
++
++ $html .= $time;
++
++ if ($event->start->timestamp() < $now &&
++ $event->end->timestamp() > $now) {
++ $html .= '</strong>';
++ }
++
++ $html .= '</div><div class="location" style="vertical-align:top">';
++ $html .= $event->getLocation();
++ $html .= '</div></td><td style="vertical-align:top;" class="event"><div class="eventtitle">';
++ $html .= $event->getTitle();
++ $html .= '</div>';
++
++ $html .= '<div class="description">';
++ $desc = Text_Filter::filter($event->getDescription(), 'text2html', array('parselevel' => TEXT_HTML_MICRO, 'class' => 'text'));
++ $html .= strtr($desc, array("\n" => " ", "\r" => " "));
++ $html .= '</div>';
++
++ $html .= '</td></tr>';
++
++ $html .= '<tr>' . $ctd . '<td class="linedRow"/><td class="linedRow annotation">';
++
++ if (!empty($category)) {
++ $html .= '<div style="text-align:right;float:left;">';
++ $html .= _("Category") . ': ' . $category;
++ $html .= '</div>';
++ }
++
++ $html .= '<div style="text-align:right">';
++ $html .= _("Calendar") . ': ' . urldecode($event->getCalendar());
++ $html .= '</div>';
++
++ $html .= '</td></tr>';
++
++ $totalevents++;
++
++ $displayed[] = $event->getId();
++ }
++ }
++
++ if (empty($html)) {
++ return '<em>' . _("No events to display") . '</em>';
++ }
++
++ return '<link href="' . Horde::applicationUrl('themes/categoryCSS.php') . '" rel="stylesheet" type="text/css" /><table cellspacing="0" width="100%">' . $html . '</table>';
++ }
++
++}
+diff --git a/horde-webmail/kronolith/themes/embed.css b/horde-webmail/kronolith/themes/embed.css
+index 6ce8835..b084aa2 100644
+--- a/horde-webmail/kronolith/themes/embed.css
++++ b/horde-webmail/kronolith/themes/embed.css
+@@ -103,4 +103,53 @@ div.horde_nicetitle pre {
+ text-align: left;
+ font-size: 75%;
+ font-family: "Lucida Console",Courier,"Courier New";
+-}
+\ No newline at end of file
++}
++
++.kronolith_embedded category_bar {
++}
++
++.kronolith_embedded .eventtitle {
++ font-weight: bold;
++ padding: 5px;
++}
++
++.kronolith_embedded .leftbar {
++ border-right: 1px solid #DDDDDD;
++ padding: 4px;
++}
++
++.kronolith_embedded .location {
++ font-size: 85%;
++ padding-top: 10px;
++ margin-left: 5px;
++}
++
++.kronolith_embedded .annotation {
++ font-size: 75%;
++ padding-top: 10px;
++ padding-left: 5px;
++}
++
++.kronolith_embedded .description {
++ font-size: 85%;
++ padding-top: 10px;
++ padding-left: 5px;
++}
++
++.kronolith_embedded .time {
++ font-size: 85%;
++ margin-top: 5px;
++ padding: 5px;
++ margin-left: 5px;
++ background: #ddddff;
++ -moz-border-radius: 5px;
++ -webkit-border-radius: 5px;
++}
++
++.kronolith_embedded .section {
++ font-weight: bold;
++ background: #eeeeee;
++ border-bottom: 1px solid #999999;
++ color: #000000;
++ padding: 1px;
++}
+diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
+index a9bff36..a31ef82 100644
+--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
++++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
+@@ -136,7 +136,7 @@ class Kolab_List {
+ */
+ function &listFolders()
+ {
+- if (!isset($this->_list)) {
++ if (!isset($this->_list) || is_a($this->_list, 'PEAR_Error')) {
+ $session = &Horde_Kolab_Session::singleton();
+ $imap = &$session->getImap();
+ if (is_a($imap, 'PEAR_Error')) {
+--
+tg: (2f74c4c..) t/kronolith/HK/GW/ExportEventList (depends on: t/dimp/H/BL/CloseContextMenu)
+--
+TOPGIT patch commit log
+=======================
+
+commit 992834cabdcc4a7aabbf566c7a5a27df639bef98
+Author: Gunnar Wrobel <p@rdus.de>
+Date: Wed Oct 7 22:22:07 2009 +0200
+
+ Comment.
+
+commit 787cac7fd3a7dd282ad66596c30fc0eaf67bbe20
+Author: Gunnar Wrobel <p@rdus.de>
+Date: Wed Oct 7 22:19:43 2009 +0200
+
+ Export a list of events.