2 commits - plugins/libkolab plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Wed Jul 11 09:17:16 CEST 2012


 plugins/libkolab/bin/Date_Recurrence_weekday.diff    |  325 ++++++++++++++++
 plugins/libkolab/bin/Date_last_weekday.diff          |   37 +
 plugins/libkolab/bin/get_horde_date.sh               |   46 +-
 plugins/libkolab/lib/Horde_Date.php                  |  210 ++++++++++
 plugins/libkolab/lib/Horde_Date_Recurrence.php       |  378 +++++++------------
 plugins/tasklist/localization/de_CH.inc              |    2 
 plugins/tasklist/localization/en_US.inc              |    2 
 plugins/tasklist/skins/larry/tasklist.css            |   12 
 plugins/tasklist/skins/larry/templates/mainview.html |   14 
 9 files changed, 756 insertions(+), 270 deletions(-)

New commits:
commit b9c8346a4d57c58194479f8911f7004b4e7c417d
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Wed Jul 11 09:17:16 2012 +0200

    Patch Horde Date classes when importing them for the use in libkolab

diff --git a/plugins/libkolab/bin/Date_Recurrence_weekday.diff b/plugins/libkolab/bin/Date_Recurrence_weekday.diff
new file mode 100644
index 0000000..e8b767d
--- /dev/null
+++ b/plugins/libkolab/bin/Date_Recurrence_weekday.diff
@@ -0,0 +1,325 @@
+--- Date/Recurrence.php.orig	2012-07-10 19:54:48.000000000 +0200
++++ Date/Recurrence.php	2012-07-10 19:55:38.000000000 +0200
+@@ -95,6 +95,20 @@
+     public $recurData = null;
+ 
+     /**
++     * BYDAY recurrence number
++     *
++     * @var integer
++     */
++    public $recurNthDay = null;
++
++    /**
++     * BYMONTH recurrence data
++     *
++     * @var array
++     */
++    public $recurMonths = array();
++
++    /**
+      * All the exceptions from recurrence for this event.
+      *
+      * @var array
+@@ -157,6 +171,44 @@
+     }
+ 
+     /**
++     *
++     * @param integer $nthDay The nth weekday of month to repeat events on
++     */
++    public function setRecurNthWeekday($nth)
++    {
++        $this->recurNthDay = (int)$nth;
++    }
++
++    /**
++     *
++     * @return integer  The nth weekday of month to repeat events.
++     */
++    public function getRecurNthWeekday()
++    {
++        return isset($this->recurNthDay) ? $this->recurNthDay : ceil($this->start->mday / 7);
++    }
++
++    /**
++     * Specifies the months for yearly (weekday) recurrence
++     *
++     * @param array $months  List of months (integers) this event recurs on.
++     */
++    function setRecurByMonth($months)
++    {
++        $this->recurMonths = (array)$months;
++    }
++
++    /**
++     * Returns a list of months this yearly event recurs on
++     *
++     * @return array List of months (integers) this event recurs on.
++     */
++    function getRecurByMonth()
++    {
++        return $this->recurMonths;
++    }
++
++    /**
+      * Returns the days this event recurs on.
+      *
+      * @return integer  A mask consisting of Horde_Date::MASK_* constants
+@@ -546,8 +598,13 @@
+             $estart = clone $this->start;
+ 
+             // What day of the week, and week of the month, do we recur on?
+-            $nth = ceil($this->start->mday / 7);
+-            $weekday = $estart->dayOfWeek();
++            if (isset($this->recurNthDay)) {
++                $nth = $this->recurNthDay;
++                $weekday = log($this->recurData, 2);
++            } else {
++                $nth = ceil($this->start->mday / 7);
++                $weekday = $estart->dayOfWeek();
++            }
+ 
+             // Adjust $estart to be the first candidate.
+             $offset = ($after->month - $estart->month) + ($after->year - $estart->year) * 12;
+@@ -660,8 +717,13 @@
+             $estart = clone $this->start;
+ 
+             // What day of the week, and week of the month, do we recur on?
+-            $nth = ceil($this->start->mday / 7);
+-            $weekday = $estart->dayOfWeek();
++            if (isset($this->recurNthDay)) {
++                $nth = $this->recurNthDay;
++                $weekday = log($this->recurData, 2);
++            } else {
++                $nth = ceil($this->start->mday / 7);
++                $weekday = $estart->dayOfWeek();
++            }
+ 
+             // Adjust $estart to be the first candidate.
+             $offset = floor(($after->year - $estart->year + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
+@@ -894,15 +956,6 @@
+         case 'W':
+             $this->setRecurType(self::RECUR_WEEKLY);
+             if (!empty($remainder)) {
+-                $maskdays = array(
+-                    'SU' => Horde_Date::MASK_SUNDAY,
+-                    'MO' => Horde_Date::MASK_MONDAY,
+-                    'TU' => Horde_Date::MASK_TUESDAY,
+-                    'WE' => Horde_Date::MASK_WEDNESDAY,
+-                    'TH' => Horde_Date::MASK_THURSDAY,
+-                    'FR' => Horde_Date::MASK_FRIDAY,
+-                    'SA' => Horde_Date::MASK_SATURDAY,
+-                );
+                 $mask = 0;
+                 while (preg_match('/^ ?[A-Z]{2} ?/', $remainder, $matches)) {
+                     $day = trim($matches[0]);
+@@ -953,7 +1006,10 @@
+                 list($year, $month, $mday) = sscanf($remainder, '%04d%02d%02d');
+                 $this->setRecurEnd(new Horde_Date(array('year' => $year,
+                                                         'month' => $month,
+-                                                        'mday' => $mday)));
++                                                        'mday' => $mday,
++                                                        'hour' => 23,
++                                                        'min' => 59,
++                                                        'sec' => 59)));
+             }
+         }
+     }
+@@ -1049,6 +1105,16 @@
+             // Always default the recurInterval to 1.
+             $this->setRecurInterval(isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1);
+ 
++            $maskdays = array(
++                'SU' => Horde_Date::MASK_SUNDAY,
++                'MO' => Horde_Date::MASK_MONDAY,
++                'TU' => Horde_Date::MASK_TUESDAY,
++                'WE' => Horde_Date::MASK_WEDNESDAY,
++                'TH' => Horde_Date::MASK_THURSDAY,
++                'FR' => Horde_Date::MASK_FRIDAY,
++                'SA' => Horde_Date::MASK_SATURDAY,
++            );
++
+             switch (Horde_String::upper($rdata['FREQ'])) {
+             case 'DAILY':
+                 $this->setRecurType(self::RECUR_DAILY);
+@@ -1057,15 +1123,6 @@
+             case 'WEEKLY':
+                 $this->setRecurType(self::RECUR_WEEKLY);
+                 if (isset($rdata['BYDAY'])) {
+-                    $maskdays = array(
+-                        'SU' => Horde_Date::MASK_SUNDAY,
+-                        'MO' => Horde_Date::MASK_MONDAY,
+-                        'TU' => Horde_Date::MASK_TUESDAY,
+-                        'WE' => Horde_Date::MASK_WEDNESDAY,
+-                        'TH' => Horde_Date::MASK_THURSDAY,
+-                        'FR' => Horde_Date::MASK_FRIDAY,
+-                        'SA' => Horde_Date::MASK_SATURDAY,
+-                    );
+                     $days = explode(',', $rdata['BYDAY']);
+                     $mask = 0;
+                     foreach ($days as $day) {
+@@ -1090,6 +1147,10 @@
+             case 'MONTHLY':
+                 if (isset($rdata['BYDAY'])) {
+                     $this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
++                    if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
++                        $this->setRecurOnDay($maskdays[$m[2]]);
++                        $this->setRecurNthWeekday($m[1]);
++                    }
+                 } else {
+                     $this->setRecurType(self::RECUR_MONTHLY_DATE);
+                 }
+@@ -1100,6 +1161,14 @@
+                     $this->setRecurType(self::RECUR_YEARLY_DAY);
+                 } elseif (isset($rdata['BYDAY'])) {
+                     $this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
++                    if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
++                        $this->setRecurOnDay($maskdays[$m[2]]);
++                        $this->setRecurNthWeekday($m[1]);
++                    }
++                    if ($rdata['BYMONTH']) {
++                        $months = explode(',', $rdata['BYMONTH']);
++                        $this->setRecurByMonth($months);
++                    }
+                 } else {
+                     $this->setRecurType(self::RECUR_YEARLY_DATE);
+                 }
+@@ -1163,13 +1232,19 @@
+             break;
+ 
+         case self::RECUR_MONTHLY_WEEKDAY:
+-            $nth_weekday = (int)($this->start->mday / 7);
+-            if (($this->start->mday % 7) > 0) {
+-                $nth_weekday++;
++            if (isset($this->recurNthDay)) {
++                $nth_weekday = $this->recurNthDay;
++                $day_of_week = log($this->recurData, 2);
++            } else {
++                $day_of_week = $this->start->dayOfWeek();
++                $nth_weekday = (int)($this->start->mday / 7);
++                if (($this->start->mday % 7) > 0) {
++                    $nth_weekday++;
++                }
+             }
+             $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
+             $rrule = 'FREQ=MONTHLY;INTERVAL=' . $this->recurInterval
+-                . ';BYDAY=' . $nth_weekday . $vcaldays[$this->start->dayOfWeek()];
++                . ';BYDAY=' . $nth_weekday . $vcaldays[$day_of_week];
+             break;
+ 
+         case self::RECUR_YEARLY_DATE:
+@@ -1182,15 +1257,22 @@
+             break;
+ 
+         case self::RECUR_YEARLY_WEEKDAY:
+-            $nth_weekday = (int)($this->start->mday / 7);
+-            if (($this->start->mday % 7) > 0) {
+-                $nth_weekday++;
+-            }
++            if (isset($this->recurNthDay)) {
++                $nth_weekday = $this->recurNthDay;
++                $day_of_week = log($this->recurData, 2);
++            } else {
++                $day_of_week = $this->start->dayOfWeek();
++                $nth_weekday = (int)($this->start->mday / 7);
++                if (($this->start->mday % 7) > 0) {
++                    $nth_weekday++;
++                }
++             }
++            $months = !empty($this->recurMonths) ? join(',', $this->recurMonths) : $this->start->month;
+             $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
+             $rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval
+                 . ';BYDAY='
+                 . $nth_weekday
+-                . $vcaldays[$this->start->dayOfWeek()]
++                . $vcaldays[$day_of_week]
+                 . ';BYMONTH=' . $this->start->month;
+             break;
+         }
+@@ -1223,6 +1305,21 @@
+ 
+         $this->setRecurInterval((int)$hash['interval']);
+ 
++        $month2number = array(
++            'january'   => 1,
++            'february'  => 2,
++            'march'     => 3,
++            'april'     => 4,
++            'may'       => 5,
++            'june'      => 6,
++            'july'      => 7,
++            'august'    => 8,
++            'september' => 9,
++            'october'   => 10,
++            'november'  => 11,
++            'december'  => 12,
++        );
++
+         $parse_day = false;
+         $set_daymask = false;
+         $update_month = false;
+@@ -1255,11 +1352,9 @@
+ 
+             case 'weekday':
+                 $this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
+-                $nth_weekday = (int)$hash['daynumber'];
+-                $hash['daynumber'] = 1;
++                $this->setRecurNthWeekday($hash['daynumber']);
+                 $parse_day = true;
+-                $update_daynumber = true;
+-                $update_weekday = true;
++                $set_daymask = true;
+                 break;
+             }
+             break;
+@@ -1297,12 +1392,13 @@
+                 }
+ 
+                 $this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
+-                $nth_weekday = (int)$hash['daynumber'];
+-                $hash['daynumber'] = 1;
++                $this->setRecurNthWeekday($hash['daynumber']);
+                 $parse_day = true;
+-                $update_month = true;
+-                $update_daynumber = true;
+-                $update_weekday = true;
++                $set_daymask = true;
++
++                if ($hash['month'] && isset($month2number[$hash['month']])) {
++                    $this->setRecurByMonth($month2number[$hash['month']]);
++                }
+                 break;
+             }
+         }
+@@ -1368,21 +1464,6 @@
+ 
+         if ($update_month || $update_daynumber || $update_weekday) {
+             if ($update_month) {
+-                $month2number = array(
+-                    'january'   => 1,
+-                    'february'  => 2,
+-                    'march'     => 3,
+-                    'april'     => 4,
+-                    'may'       => 5,
+-                    'june'      => 6,
+-                    'july'      => 7,
+-                    'august'    => 8,
+-                    'september' => 9,
+-                    'october'   => 10,
+-                    'november'  => 11,
+-                    'december'  => 12,
+-                );
+-
+                 if (isset($month2number[$hash['month']])) {
+                     $this->start->month = $month2number[$hash['month']];
+                 }
+@@ -1398,7 +1479,7 @@
+             }
+ 
+             if ($update_weekday) {
+-                $this->start->setNthWeekday($last_found_day, $nth_weekday);
++                $this->setNthWeekday($nth_weekday);
+             }
+         }
+ 
diff --git a/plugins/libkolab/bin/Date_last_weekday.diff b/plugins/libkolab/bin/Date_last_weekday.diff
new file mode 100644
index 0000000..d260360
--- /dev/null
+++ b/plugins/libkolab/bin/Date_last_weekday.diff
@@ -0,0 +1,37 @@
+--- Date.php.orig	2012-07-10 19:14:26.000000000 +0200
++++ Date.php	2012-07-10 19:16:22.000000000 +0200
+@@ -627,16 +627,25 @@
+             return;
+         }
+ 
+-        $this->_mday = 1;
+-        $first = $this->dayOfWeek();
+-        if ($weekday < $first) {
+-            $this->_mday = 8 + $weekday - $first;
+-        } else {
+-            $this->_mday = $weekday - $first + 1;
++        if ($nth < 0) {  // last $weekday of month
++            $this->_mday = $lastday = Horde_Date_Utils::daysInMonth($this->_month, $this->_year);
++            $last = $this->dayOfWeek();
++            $this->_mday += ($weekday - $last);
++            if ($this->_mday > $lastday)
++                $this->_mday -= 7;
++        }
++        else {
++            $this->_mday = 1;
++            $first = $this->dayOfWeek();
++            if ($weekday < $first) {
++                $this->_mday = 8 + $weekday - $first;
++            } else {
++                $this->_mday = $weekday - $first + 1;
++            }
++            $diff = 7 * $nth - 7;
++            $this->_mday += $diff;
++            $this->_correct(self::MASK_DAY, $diff < 0);
+         }
+-        $diff = 7 * $nth - 7;
+-        $this->_mday += $diff;
+-        $this->_correct(self::MASK_DAY, $diff < 0);
+     }
+ 
+     /**
diff --git a/plugins/libkolab/bin/get_horde_date.sh b/plugins/libkolab/bin/get_horde_date.sh
index c75b7fd..b8e663d 100755
--- a/plugins/libkolab/bin/get_horde_date.sh
+++ b/plugins/libkolab/bin/get_horde_date.sh
@@ -1,24 +1,46 @@
 #!/bin/sh
 
-# Copy Horde_Date_Recurrence classes and dependencies to stdout.
+# Copy Horde_Date_Recurrence classes and dependencies to the given target directory.
 # This will create a standalone copy of the classes requried for date recurrence computation.
 
 SRCDIR=$1
+DESTDIR=$2
+BINDIR=`dirname $0`
 
-if [ ! -d "$SRCDIR" ]; then
-  echo "Usage: get_horde_date.sh SRCDIR"
-  echo "Please enter a valid source directory of the Horde libs"
+if [ ! -d "$SRCDIR" -o ! -d "$DESTDIR" ]; then
+  echo "Usage: get_horde_date.sh SRCDIR DESTDIR"
+  echo "Please enter valid source and destination directories for the Horde libs"
   exit 1
 fi
 
+
+# concat Date.php and Date/Utils.php
+HORDE_DATE="$DESTDIR/Horde_Date.php"
+
 echo "<?php
 
 /**
  * This is a concatenated copy of the following files:
- *   Horde/Date/Utils.php, Horde/Date/Recurrence.php
+ *   Horde/Date.php, Horde/Date/Utils.php
  * Pull the latest version of these files from the PEAR channel of the Horde
  * project at http://pear.horde.org by installing the Horde_Date package.
  */
+" > $HORDE_DATE
+
+patch $SRCDIR/Date.php $BINDIR/Date_last_weekday.diff --output=$HORDE_DATE.patched
+sed 's/<?php//; s/?>//' $HORDE_DATE.patched >> $HORDE_DATE
+sed 's/<?php//; s/?>//' $SRCDIR/Date/Utils.php >> $HORDE_DATE
+
+# copy and patch Date/Recurrence.php
+HORDE_DATE_RECURRENCE="$DESTDIR/Horde_Date_Recurrence.php"
+
+echo "<?php
+
+/**
+ * This is a modified copy of Horde/Date/Recurrence.php
+ * Pull the latest version of this file from the PEAR channel of the Horde
+ * project at http://pear.horde.org by installing the Horde_Date package.
+ */
 
 if (!class_exists('Horde_Date'))
 	require_once(dirname(__FILE__) . '/Horde_Date.php');
@@ -29,10 +51,14 @@ class Horde_Date_Translation
 	function t(\$arg) { return \$arg; }
 	function ngettext(\$sing, \$plur, \$num) { return (\$num > 1 ? \$plur : \$sing); }
 }
-"
+" > $HORDE_DATE_RECURRENCE
+
+patch $SRCDIR/Date/Recurrence.php $BINDIR/Date_Recurrence_weekday.diff --output=$HORDE_DATE_RECURRENCE.patched
+sed 's/<?php//; s/?>//' $HORDE_DATE_RECURRENCE.patched >> $HORDE_DATE_RECURRENCE
+
+# remove dependency to Horde_String
+sed -i '' "s/Horde_String::/strto/" $HORDE_DATE_RECURRENCE
+
+rm $DESTDIR/Horde_Date*.patched
 
-sed 's/<?php//; s/?>//' $SRCDIR/Date/Utils.php
-echo "\n"
-sed 's/<?php//; s/?>//' $SRCDIR/Date/Recurrence.php | sed -E "s/Horde_String::/strto/"
-echo "\n"
 
diff --git a/plugins/libkolab/lib/Horde_Date.php b/plugins/libkolab/lib/Horde_Date.php
index 4ddd9d5..9197f84 100644
--- a/plugins/libkolab/lib/Horde_Date.php
+++ b/plugins/libkolab/lib/Horde_Date.php
@@ -1,4 +1,13 @@
 <?php
+
+/**
+ * This is a concatenated copy of the following files:
+ *   Horde/Date/Utils.php, Horde/Date/Recurrence.php
+ * Pull the latest version of these files from the PEAR channel of the Horde
+ * project at http://pear.horde.org by installing the Horde_Date package.
+ */
+
+
 /**
  * Horde Date wrapper/logic class, including some calculation
  * functions.
@@ -627,16 +636,25 @@ class Horde_Date
             return;
         }
 
-        $this->_mday = 1;
-        $first = $this->dayOfWeek();
-        if ($weekday < $first) {
-            $this->_mday = 8 + $weekday - $first;
-        } else {
-            $this->_mday = $weekday - $first + 1;
+        if ($nth < 0) {  // last $weekday of month
+            $this->_mday = $lastday = Horde_Date_Utils::daysInMonth($this->_month, $this->_year);
+            $last = $this->dayOfWeek();
+            $this->_mday += ($weekday - $last);
+            if ($this->_mday > $lastday)
+                $this->_mday -= 7;
+        }
+        else {
+            $this->_mday = 1;
+            $first = $this->dayOfWeek();
+            if ($weekday < $first) {
+                $this->_mday = 8 + $weekday - $first;
+            } else {
+                $this->_mday = $weekday - $first + 1;
+            }
+            $diff = 7 * $nth - 7;
+            $this->_mday += $diff;
+            $this->_correct(self::MASK_DAY, $diff < 0);
         }
-        $diff = 7 * $nth - 7;
-        $this->_mday += $diff;
-        $this->_correct(self::MASK_DAY, $diff < 0);
     }
 
     /**
@@ -1110,3 +1128,177 @@ class Horde_Date
     }
 
 }
+
+/**
+ * @category Horde
+ * @package  Date
+ */
+
+/**
+ * Horde Date wrapper/logic class, including some calculation
+ * functions.
+ *
+ * @category Horde
+ * @package  Date
+ */
+class Horde_Date_Utils
+{
+    /**
+     * Returns whether a year is a leap year.
+     *
+     * @param integer $year  The year.
+     *
+     * @return boolean  True if the year is a leap year.
+     */
+    public static function isLeapYear($year)
+    {
+        if (strlen($year) != 4 || preg_match('/\D/', $year)) {
+            return false;
+        }
+
+        return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
+    }
+
+    /**
+     * Returns the date of the year that corresponds to the first day of the
+     * given week.
+     *
+     * @param integer $week  The week of the year to find the first day of.
+     * @param integer $year  The year to calculate for.
+     *
+     * @return Horde_Date  The date of the first day of the given week.
+     */
+    public static function firstDayOfWeek($week, $year)
+    {
+        return new Horde_Date(sprintf('%04dW%02d', $year, $week));
+    }
+
+    /**
+     * Returns the number of days in the specified month.
+     *
+     * @param integer $month  The month
+     * @param integer $year   The year.
+     *
+     * @return integer  The number of days in the month.
+     */
+    public static function daysInMonth($month, $year)
+    {
+        static $cache = array();
+        if (!isset($cache[$year][$month])) {
+            $date = new DateTime(sprintf('%04d-%02d-01', $year, $month));
+            $cache[$year][$month] = $date->format('t');
+        }
+        return $cache[$year][$month];
+    }
+
+    /**
+     * Returns a relative, natural language representation of a timestamp
+     *
+     * @todo Wider range of values ... maybe future time as well?
+     * @todo Support minimum resolution parameter.
+     *
+     * @param mixed $time          The time. Any format accepted by Horde_Date.
+     * @param string $date_format  Format to display date if timestamp is
+     *                             more then 1 day old.
+     * @param string $time_format  Format to display time if timestamp is 1
+     *                             day old.
+     *
+     * @return string  The relative time (i.e. 2 minutes ago)
+     */
+    public static function relativeDateTime($time, $date_format = '%x',
+                                            $time_format = '%X')
+    {
+        $date = new Horde_Date($time);
+
+        $delta = time() - $date->timestamp();
+        if ($delta < 60) {
+            return sprintf(Horde_Date_Translation::ngettext("%d second ago", "%d seconds ago", $delta), $delta);
+        }
+
+        $delta = round($delta / 60);
+        if ($delta < 60) {
+            return sprintf(Horde_Date_Translation::ngettext("%d minute ago", "%d minutes ago", $delta), $delta);
+        }
+
+        $delta = round($delta / 60);
+        if ($delta < 24) {
+            return sprintf(Horde_Date_Translation::ngettext("%d hour ago", "%d hours ago", $delta), $delta);
+        }
+
+        if ($delta > 24 && $delta < 48) {
+            $date = new Horde_Date($time);
+            return sprintf(Horde_Date_Translation::t("yesterday at %s"), $date->strftime($time_format));
+        }
+
+        $delta = round($delta / 24);
+        if ($delta < 7) {
+            return sprintf(Horde_Date_Translation::t("%d days ago"), $delta);
+        }
+
+        if (round($delta / 7) < 5) {
+            $delta = round($delta / 7);
+            return sprintf(Horde_Date_Translation::ngettext("%d week ago", "%d weeks ago", $delta), $delta);
+        }
+
+        // Default to the user specified date format.
+        return $date->strftime($date_format);
+    }
+
+    /**
+     * Tries to convert strftime() formatters to date() formatters.
+     *
+     * Unsupported formatters will be removed.
+     *
+     * @param string $format  A strftime() formatting string.
+     *
+     * @return string  A date() formatting string.
+     */
+    public static function strftime2date($format)
+    {
+        $replace = array(
+            '/%a/'  => 'D',
+            '/%A/'  => 'l',
+            '/%d/'  => 'd',
+            '/%e/'  => 'j',
+            '/%j/'  => 'z',
+            '/%u/'  => 'N',
+            '/%w/'  => 'w',
+            '/%U/'  => '',
+            '/%V/'  => 'W',
+            '/%W/'  => '',
+            '/%b/'  => 'M',
+            '/%B/'  => 'F',
+            '/%h/'  => 'M',
+            '/%m/'  => 'm',
+            '/%C/'  => '',
+            '/%g/'  => '',
+            '/%G/'  => 'o',
+            '/%y/'  => 'y',
+            '/%Y/'  => 'Y',
+            '/%H/'  => 'H',
+            '/%I/'  => 'h',
+            '/%i/'  => 'g',
+            '/%M/'  => 'i',
+            '/%p/'  => 'A',
+            '/%P/'  => 'a',
+            '/%r/'  => 'h:i:s A',
+            '/%R/'  => 'H:i',
+            '/%S/'  => 's',
+            '/%T/'  => 'H:i:s',
+            '/%X/e' => 'Horde_Date_Utils::strftime2date(Horde_Nls::getLangInfo(T_FMT))',
+            '/%z/'  => 'O',
+            '/%Z/'  => '',
+            '/%c/'  => '',
+            '/%D/'  => 'm/d/y',
+            '/%F/'  => 'Y-m-d',
+            '/%s/'  => 'U',
+            '/%x/e' => 'Horde_Date_Utils::strftime2date(Horde_Nls::getLangInfo(D_FMT))',
+            '/%n/'  => "\n",
+            '/%t/'  => "\t",
+            '/%%/'  => '%'
+        );
+
+        return preg_replace(array_keys($replace), array_values($replace), $format);
+    }
+
+}
diff --git a/plugins/libkolab/lib/Horde_Date_Recurrence.php b/plugins/libkolab/lib/Horde_Date_Recurrence.php
index 2171a47..bbdf13d 100644
--- a/plugins/libkolab/lib/Horde_Date_Recurrence.php
+++ b/plugins/libkolab/lib/Horde_Date_Recurrence.php
@@ -1,9 +1,8 @@
 <?php
 
 /**
- * This is a concatenated copy of the following files:
- *   Horde/Date.php, Horde/Date/Utils.php, Horde/Date/Recurrence.php
- * Pull the latest version of these files from the PEAR channel of the Horde
+ * This is a modified copy of Horde/Date/Recurrence.php
+ * Pull the latest version of this file from the PEAR channel of the Horde
  * project at http://pear.horde.org by installing the Horde_Date package.
  */
 
@@ -19,182 +18,6 @@ class Horde_Date_Translation
 
 
 /**
- * @category Horde
- * @package  Date
- */
-
-/**
- * Horde Date wrapper/logic class, including some calculation
- * functions.
- *
- * @category Horde
- * @package  Date
- */
-class Horde_Date_Utils
-{
-    /**
-     * Returns whether a year is a leap year.
-     *
-     * @param integer $year  The year.
-     *
-     * @return boolean  True if the year is a leap year.
-     */
-    public static function isLeapYear($year)
-    {
-        if (strlen($year) != 4 || preg_match('/\D/', $year)) {
-            return false;
-        }
-
-        return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
-    }
-
-    /**
-     * Returns the date of the year that corresponds to the first day of the
-     * given week.
-     *
-     * @param integer $week  The week of the year to find the first day of.
-     * @param integer $year  The year to calculate for.
-     *
-     * @return Horde_Date  The date of the first day of the given week.
-     */
-    public static function firstDayOfWeek($week, $year)
-    {
-        return new Horde_Date(sprintf('%04dW%02d', $year, $week));
-    }
-
-    /**
-     * Returns the number of days in the specified month.
-     *
-     * @param integer $month  The month
-     * @param integer $year   The year.
-     *
-     * @return integer  The number of days in the month.
-     */
-    public static function daysInMonth($month, $year)
-    {
-        static $cache = array();
-        if (!isset($cache[$year][$month])) {
-            $date = new DateTime(sprintf('%04d-%02d-01', $year, $month));
-            $cache[$year][$month] = $date->format('t');
-        }
-        return $cache[$year][$month];
-    }
-
-    /**
-     * Returns a relative, natural language representation of a timestamp
-     *
-     * @todo Wider range of values ... maybe future time as well?
-     * @todo Support minimum resolution parameter.
-     *
-     * @param mixed $time          The time. Any format accepted by Horde_Date.
-     * @param string $date_format  Format to display date if timestamp is
-     *                             more then 1 day old.
-     * @param string $time_format  Format to display time if timestamp is 1
-     *                             day old.
-     *
-     * @return string  The relative time (i.e. 2 minutes ago)
-     */
-    public static function relativeDateTime($time, $date_format = '%x',
-                                            $time_format = '%X')
-    {
-        $date = new Horde_Date($time);
-
-        $delta = time() - $date->timestamp();
-        if ($delta < 60) {
-            return sprintf(Horde_Date_Translation::ngettext("%d second ago", "%d seconds ago", $delta), $delta);
-        }
-
-        $delta = round($delta / 60);
-        if ($delta < 60) {
-            return sprintf(Horde_Date_Translation::ngettext("%d minute ago", "%d minutes ago", $delta), $delta);
-        }
-
-        $delta = round($delta / 60);
-        if ($delta < 24) {
-            return sprintf(Horde_Date_Translation::ngettext("%d hour ago", "%d hours ago", $delta), $delta);
-        }
-
-        if ($delta > 24 && $delta < 48) {
-            $date = new Horde_Date($time);
-            return sprintf(Horde_Date_Translation::t("yesterday at %s"), $date->strftime($time_format));
-        }
-
-        $delta = round($delta / 24);
-        if ($delta < 7) {
-            return sprintf(Horde_Date_Translation::t("%d days ago"), $delta);
-        }
-
-        if (round($delta / 7) < 5) {
-            $delta = round($delta / 7);
-            return sprintf(Horde_Date_Translation::ngettext("%d week ago", "%d weeks ago", $delta), $delta);
-        }
-
-        // Default to the user specified date format.
-        return $date->strftime($date_format);
-    }
-
-    /**
-     * Tries to convert strftime() formatters to date() formatters.
-     *
-     * Unsupported formatters will be removed.
-     *
-     * @param string $format  A strftime() formatting string.
-     *
-     * @return string  A date() formatting string.
-     */
-    public static function strftime2date($format)
-    {
-        $replace = array(
-            '/%a/'  => 'D',
-            '/%A/'  => 'l',
-            '/%d/'  => 'd',
-            '/%e/'  => 'j',
-            '/%j/'  => 'z',
-            '/%u/'  => 'N',
-            '/%w/'  => 'w',
-            '/%U/'  => '',
-            '/%V/'  => 'W',
-            '/%W/'  => '',
-            '/%b/'  => 'M',
-            '/%B/'  => 'F',
-            '/%h/'  => 'M',
-            '/%m/'  => 'm',
-            '/%C/'  => '',
-            '/%g/'  => '',
-            '/%G/'  => 'o',
-            '/%y/'  => 'y',
-            '/%Y/'  => 'Y',
-            '/%H/'  => 'H',
-            '/%I/'  => 'h',
-            '/%i/'  => 'g',
-            '/%M/'  => 'i',
-            '/%p/'  => 'A',
-            '/%P/'  => 'a',
-            '/%r/'  => 'h:i:s A',
-            '/%R/'  => 'H:i',
-            '/%S/'  => 's',
-            '/%T/'  => 'H:i:s',
-            '/%X/e' => 'Horde_Date_Utils::strftime2date(Horde_Nls::getLangInfo(T_FMT))',
-            '/%z/'  => 'O',
-            '/%Z/'  => '',
-            '/%c/'  => '',
-            '/%D/'  => 'm/d/y',
-            '/%F/'  => 'Y-m-d',
-            '/%s/'  => 'U',
-            '/%x/e' => 'Horde_Date_Utils::strftime2date(Horde_Nls::getLangInfo(D_FMT))',
-            '/%n/'  => "\n",
-            '/%t/'  => "\t",
-            '/%%/'  => '%'
-        );
-
-        return preg_replace(array_keys($replace), array_values($replace), $format);
-    }
-
-}
-
-
-
-/**
  * This file contains the Horde_Date_Recurrence class and according constants.
  *
  * Copyright 2007-2012 Horde LLC (http://www.horde.org/)
@@ -290,6 +113,20 @@ class Horde_Date_Recurrence
     public $recurData = null;
 
     /**
+     * BYDAY recurrence number
+     *
+     * @var integer
+     */
+    public $recurNthDay = null;
+
+    /**
+     * BYMONTH recurrence data
+     *
+     * @var array
+     */
+    public $recurMonths = array();
+
+    /**
      * All the exceptions from recurrence for this event.
      *
      * @var array
@@ -352,6 +189,44 @@ class Horde_Date_Recurrence
     }
 
     /**
+     *
+     * @param integer $nthDay The nth weekday of month to repeat events on
+     */
+    public function setRecurNthWeekday($nth)
+    {
+        $this->recurNthDay = (int)$nth;
+    }
+
+    /**
+     *
+     * @return integer  The nth weekday of month to repeat events.
+     */
+    public function getRecurNthWeekday()
+    {
+        return isset($this->recurNthDay) ? $this->recurNthDay : ceil($this->start->mday / 7);
+    }
+
+    /**
+     * Specifies the months for yearly (weekday) recurrence
+     *
+     * @param array $months  List of months (integers) this event recurs on.
+     */
+    function setRecurByMonth($months)
+    {
+        $this->recurMonths = (array)$months;
+    }
+
+    /**
+     * Returns a list of months this yearly event recurs on
+     *
+     * @return array List of months (integers) this event recurs on.
+     */
+    function getRecurByMonth()
+    {
+        return $this->recurMonths;
+    }
+
+    /**
      * Returns the days this event recurs on.
      *
      * @return integer  A mask consisting of Horde_Date::MASK_* constants
@@ -741,8 +616,13 @@ class Horde_Date_Recurrence
             $estart = clone $this->start;
 
             // What day of the week, and week of the month, do we recur on?
-            $nth = ceil($this->start->mday / 7);
-            $weekday = $estart->dayOfWeek();
+            if (isset($this->recurNthDay)) {
+                $nth = $this->recurNthDay;
+                $weekday = log($this->recurData, 2);
+            } else {
+                $nth = ceil($this->start->mday / 7);
+                $weekday = $estart->dayOfWeek();
+            }
 
             // Adjust $estart to be the first candidate.
             $offset = ($after->month - $estart->month) + ($after->year - $estart->year) * 12;
@@ -855,8 +735,13 @@ class Horde_Date_Recurrence
             $estart = clone $this->start;
 
             // What day of the week, and week of the month, do we recur on?
-            $nth = ceil($this->start->mday / 7);
-            $weekday = $estart->dayOfWeek();
+            if (isset($this->recurNthDay)) {
+                $nth = $this->recurNthDay;
+                $weekday = log($this->recurData, 2);
+            } else {
+                $nth = ceil($this->start->mday / 7);
+                $weekday = $estart->dayOfWeek();
+            }
 
             // Adjust $estart to be the first candidate.
             $offset = floor(($after->year - $estart->year + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
@@ -1089,15 +974,6 @@ class Horde_Date_Recurrence
         case 'W':
             $this->setRecurType(self::RECUR_WEEKLY);
             if (!empty($remainder)) {
-                $maskdays = array(
-                    'SU' => Horde_Date::MASK_SUNDAY,
-                    'MO' => Horde_Date::MASK_MONDAY,
-                    'TU' => Horde_Date::MASK_TUESDAY,
-                    'WE' => Horde_Date::MASK_WEDNESDAY,
-                    'TH' => Horde_Date::MASK_THURSDAY,
-                    'FR' => Horde_Date::MASK_FRIDAY,
-                    'SA' => Horde_Date::MASK_SATURDAY,
-                );
                 $mask = 0;
                 while (preg_match('/^ ?[A-Z]{2} ?/', $remainder, $matches)) {
                     $day = trim($matches[0]);
@@ -1148,7 +1024,10 @@ class Horde_Date_Recurrence
                 list($year, $month, $mday) = sscanf($remainder, '%04d%02d%02d');
                 $this->setRecurEnd(new Horde_Date(array('year' => $year,
                                                         'month' => $month,
-                                                        'mday' => $mday)));
+                                                        'mday' => $mday,
+                                                        'hour' => 23,
+                                                        'min' => 59,
+                                                        'sec' => 59)));
             }
         }
     }
@@ -1244,6 +1123,16 @@ class Horde_Date_Recurrence
             // Always default the recurInterval to 1.
             $this->setRecurInterval(isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1);
 
+            $maskdays = array(
+                'SU' => Horde_Date::MASK_SUNDAY,
+                'MO' => Horde_Date::MASK_MONDAY,
+                'TU' => Horde_Date::MASK_TUESDAY,
+                'WE' => Horde_Date::MASK_WEDNESDAY,
+                'TH' => Horde_Date::MASK_THURSDAY,
+                'FR' => Horde_Date::MASK_FRIDAY,
+                'SA' => Horde_Date::MASK_SATURDAY,
+            );
+
             switch (strtoupper($rdata['FREQ'])) {
             case 'DAILY':
                 $this->setRecurType(self::RECUR_DAILY);
@@ -1252,15 +1141,6 @@ class Horde_Date_Recurrence
             case 'WEEKLY':
                 $this->setRecurType(self::RECUR_WEEKLY);
                 if (isset($rdata['BYDAY'])) {
-                    $maskdays = array(
-                        'SU' => Horde_Date::MASK_SUNDAY,
-                        'MO' => Horde_Date::MASK_MONDAY,
-                        'TU' => Horde_Date::MASK_TUESDAY,
-                        'WE' => Horde_Date::MASK_WEDNESDAY,
-                        'TH' => Horde_Date::MASK_THURSDAY,
-                        'FR' => Horde_Date::MASK_FRIDAY,
-                        'SA' => Horde_Date::MASK_SATURDAY,
-                    );
                     $days = explode(',', $rdata['BYDAY']);
                     $mask = 0;
                     foreach ($days as $day) {
@@ -1285,6 +1165,10 @@ class Horde_Date_Recurrence
             case 'MONTHLY':
                 if (isset($rdata['BYDAY'])) {
                     $this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
+                    if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
+                        $this->setRecurOnDay($maskdays[$m[2]]);
+                        $this->setRecurNthWeekday($m[1]);
+                    }
                 } else {
                     $this->setRecurType(self::RECUR_MONTHLY_DATE);
                 }
@@ -1295,6 +1179,14 @@ class Horde_Date_Recurrence
                     $this->setRecurType(self::RECUR_YEARLY_DAY);
                 } elseif (isset($rdata['BYDAY'])) {
                     $this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
+                    if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
+                        $this->setRecurOnDay($maskdays[$m[2]]);
+                        $this->setRecurNthWeekday($m[1]);
+                    }
+                    if ($rdata['BYMONTH']) {
+                        $months = explode(',', $rdata['BYMONTH']);
+                        $this->setRecurByMonth($months);
+                    }
                 } else {
                     $this->setRecurType(self::RECUR_YEARLY_DATE);
                 }
@@ -1358,13 +1250,19 @@ class Horde_Date_Recurrence
             break;
 
         case self::RECUR_MONTHLY_WEEKDAY:
-            $nth_weekday = (int)($this->start->mday / 7);
-            if (($this->start->mday % 7) > 0) {
-                $nth_weekday++;
+            if (isset($this->recurNthDay)) {
+                $nth_weekday = $this->recurNthDay;
+                $day_of_week = log($this->recurData, 2);
+            } else {
+                $day_of_week = $this->start->dayOfWeek();
+                $nth_weekday = (int)($this->start->mday / 7);
+                if (($this->start->mday % 7) > 0) {
+                    $nth_weekday++;
+                }
             }
             $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
             $rrule = 'FREQ=MONTHLY;INTERVAL=' . $this->recurInterval
-                . ';BYDAY=' . $nth_weekday . $vcaldays[$this->start->dayOfWeek()];
+                . ';BYDAY=' . $nth_weekday . $vcaldays[$day_of_week];
             break;
 
         case self::RECUR_YEARLY_DATE:
@@ -1377,15 +1275,22 @@ class Horde_Date_Recurrence
             break;
 
         case self::RECUR_YEARLY_WEEKDAY:
-            $nth_weekday = (int)($this->start->mday / 7);
-            if (($this->start->mday % 7) > 0) {
-                $nth_weekday++;
-            }
+            if (isset($this->recurNthDay)) {
+                $nth_weekday = $this->recurNthDay;
+                $day_of_week = log($this->recurData, 2);
+            } else {
+                $day_of_week = $this->start->dayOfWeek();
+                $nth_weekday = (int)($this->start->mday / 7);
+                if (($this->start->mday % 7) > 0) {
+                    $nth_weekday++;
+                }
+             }
+            $months = !empty($this->recurMonths) ? join(',', $this->recurMonths) : $this->start->month;
             $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
             $rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval
                 . ';BYDAY='
                 . $nth_weekday
-                . $vcaldays[$this->start->dayOfWeek()]
+                . $vcaldays[$day_of_week]
                 . ';BYMONTH=' . $this->start->month;
             break;
         }
@@ -1418,6 +1323,21 @@ class Horde_Date_Recurrence
 
         $this->setRecurInterval((int)$hash['interval']);
 
+        $month2number = array(
+            'january'   => 1,
+            'february'  => 2,
+            'march'     => 3,
+            'april'     => 4,
+            'may'       => 5,
+            'june'      => 6,
+            'july'      => 7,
+            'august'    => 8,
+            'september' => 9,
+            'october'   => 10,
+            'november'  => 11,
+            'december'  => 12,
+        );
+
         $parse_day = false;
         $set_daymask = false;
         $update_month = false;
@@ -1450,11 +1370,9 @@ class Horde_Date_Recurrence
 
             case 'weekday':
                 $this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
-                $nth_weekday = (int)$hash['daynumber'];
-                $hash['daynumber'] = 1;
+                $this->setRecurNthWeekday($hash['daynumber']);
                 $parse_day = true;
-                $update_daynumber = true;
-                $update_weekday = true;
+                $set_daymask = true;
                 break;
             }
             break;
@@ -1492,12 +1410,13 @@ class Horde_Date_Recurrence
                 }
 
                 $this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
-                $nth_weekday = (int)$hash['daynumber'];
-                $hash['daynumber'] = 1;
+                $this->setRecurNthWeekday($hash['daynumber']);
                 $parse_day = true;
-                $update_month = true;
-                $update_daynumber = true;
-                $update_weekday = true;
+                $set_daymask = true;
+
+                if ($hash['month'] && isset($month2number[$hash['month']])) {
+                    $this->setRecurByMonth($month2number[$hash['month']]);
+                }
                 break;
             }
         }
@@ -1563,21 +1482,6 @@ class Horde_Date_Recurrence
 
         if ($update_month || $update_daynumber || $update_weekday) {
             if ($update_month) {
-                $month2number = array(
-                    'january'   => 1,
-                    'february'  => 2,
-                    'march'     => 3,
-                    'april'     => 4,
-                    'may'       => 5,
-                    'june'      => 6,
-                    'july'      => 7,
-                    'august'    => 8,
-                    'september' => 9,
-                    'october'   => 10,
-                    'november'  => 11,
-                    'december'  => 12,
-                );
-
                 if (isset($month2number[$hash['month']])) {
                     $this->start->month = $month2number[$hash['month']];
                 }
@@ -1593,7 +1497,7 @@ class Horde_Date_Recurrence
             }
 
             if ($update_weekday) {
-                $this->start->setNthWeekday($last_found_day, $nth_weekday);
+                $this->setNthWeekday($nth_weekday);
             }
         }
 
@@ -1764,5 +1668,3 @@ class Horde_Date_Recurrence
     }
 
 }
-
-


commit c5f9fd15b43e5f3816e30160ce2eb0b2dbeeb3e4
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Wed Jul 11 09:16:01 2012 +0200

    Change tasklist main screen layout according to recent changes in Larry skin

diff --git a/plugins/tasklist/localization/de_CH.inc b/plugins/tasklist/localization/de_CH.inc
index b62f6d0..5d57e93 100644
--- a/plugins/tasklist/localization/de_CH.inc
+++ b/plugins/tasklist/localization/de_CH.inc
@@ -6,7 +6,7 @@ $labels['lists'] = 'Ressourcen';
 $labels['list'] = 'Ressource';
 $labels['tags'] = 'Tags';
 
-$labels['createnewtask'] = 'Neue Aufgabe eingeben';
+$labels['createnewtask'] = 'Neue Aufgabe eingeben (z.B. Samstag, Rasenmähen)';
 $labels['mark'] = 'Markieren';
 $labels['unmark'] = 'Markierung aufheben';
 $labels['edit'] = 'Bearbeiten';
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index b146039..b73dda9 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -6,7 +6,7 @@ $labels['lists'] = 'Resources';
 $labels['list'] = 'Resource';
 $labels['tags'] = 'Tags';
 
-$labels['createnewtask'] = 'Create new Task';
+$labels['createnewtask'] = 'Create new Task (e.g. Saturday, Mow the lawn)';
 $labels['mark'] = 'Mark';
 $labels['unmark'] = 'Unmark';
 $labels['edit'] = 'Edit';
diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index e6136f5..063632d 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -208,11 +208,14 @@ body.tasklistview #searchmenulink {
 #taskstoolbar {
 	position: absolute;
 	top: -6px;
-	right: 0;
-	width: 40%;
+	left: 0;
+	width: 100%;
 	height: 40px;
 	white-space: nowrap;
-	text-align: right;
+}
+
+#quicksearchbar {
+	top: -7px;
 }
 
 #quickaddbox {
@@ -227,7 +230,8 @@ body.tasklistview #searchmenulink {
 #quickaddinput {
 	width: 85%;
 	margin: 0;
-	padding: 5px 8px;
+	padding: 3px 8px;
+	height: 18px;
 	background: #f1f1f1;
 	background: rgba(255, 255, 255, 0.7);
 	border-color: #a3a3a3;
diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html
index 0ec9cab..927ee4b 100644
--- a/plugins/tasklist/skins/larry/templates/mainview.html
+++ b/plugins/tasklist/skins/larry/templates/mainview.html
@@ -10,12 +10,10 @@
 
 <div id="mainscreen">
 	<div id="sidebar">
-		<div id="quicksearchbar">
-			<roundcube:object name="plugin.searchform" id="quicksearchbox" />
-			<a id="searchmenulink" class="iconbutton searchoptions" > </a>
-			<roundcube:button command="reset-search" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
+		<div id="taskstoolbar" class="toolbar">
+			<roundcube:container name="toolbar" id="taskstoolbar" />
 		</div>
-		
+
 		<div id="selectorbox" class="uibox listbox">
 			<div class="scroller">
 				<h2 class="boxtitle"><roundcube:label name="tasklist.tags" /></h2>
@@ -39,8 +37,10 @@
 		<roundcube:object name="plugin.quickaddform" />
 	</div>
 
-	<div id="taskstoolbar" class="toolbar">
-		<roundcube:container name="toolbar" id="taskstoolbar" />
+	<div id="quicksearchbar">
+		<roundcube:object name="plugin.searchform" id="quicksearchbox" />
+		<a id="searchmenulink" class="iconbutton searchoptions" > </a>
+		<roundcube:button command="reset-search" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
 	</div>
 
 	<div id="tasksview" class="uibox">





More information about the commits mailing list