2 commits - plugins/libkolab plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Mon May 19 18:23:10 CEST 2014


 plugins/libkolab/lib/kolab_format_task.php                     |    4 -
 plugins/tasklist/drivers/database/SQL/mysql.initial.sql        |    3 -
 plugins/tasklist/drivers/database/SQL/mysql/2014051900.sql     |    3 +
 plugins/tasklist/drivers/database/SQL/postgres.initial.sql     |    3 -
 plugins/tasklist/drivers/database/tasklist_database_driver.php |   21 +++++-----
 plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php       |    7 +--
 plugins/tasklist/drivers/tasklist_driver.php                   |   13 +++++-
 plugins/tasklist/localization/en_US.inc                        |    5 ++
 plugins/tasklist/skins/larry/tasklist.css                      |   16 +++++--
 plugins/tasklist/skins/larry/templates/mainview.html           |    4 +
 plugins/tasklist/skins/larry/templates/taskedit.html           |    4 +
 plugins/tasklist/tasklist.js                                   |   20 +++++++--
 plugins/tasklist/tasklist.php                                  |   11 ++---
 plugins/tasklist/tasklist_ui.php                               |   17 +++++++-
 14 files changed, 99 insertions(+), 32 deletions(-)

New commits:
commit 3a2d5eed5aa92318f468a100e3e43b01873d080a
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Mon May 19 18:20:23 2014 +0200

    Use status attribute to set a task as 'complete' (#3026)

diff --git a/plugins/libkolab/lib/kolab_format_task.php b/plugins/libkolab/lib/kolab_format_task.php
index 465ba90..b3c6a42 100644
--- a/plugins/libkolab/lib/kolab_format_task.php
+++ b/plugins/libkolab/lib/kolab_format_task.php
@@ -44,7 +44,7 @@ class kolab_format_task extends kolab_format_xcal
         $this->obj->setPercentComplete(intval($object['complete']));
 
         $status = kolabformat::StatusUndefined;
-        if ($object['complete'] == 100)
+        if ($object['complete'] == 100 && !array_key_exists('status', $object))
             $status = kolabformat::StatusCompleted;
         else if ($object['status'] && array_key_exists($object['status'], $this->status_map))
             $status = $this->status_map[$object['status']];
@@ -113,7 +113,7 @@ class kolab_format_task extends kolab_format_xcal
     {
         $tags = array();
 
-        if ($this->data['status'] == 'COMPLETED' || $this->data['complete'] == 100)
+        if ($this->data['status'] == 'COMPLETED' || ($this->data['complete'] == 100 && empty($this->data['status'])))
             $tags[] = 'x-complete';
 
         if ($this->data['priority'] == 1)
diff --git a/plugins/tasklist/drivers/database/SQL/mysql.initial.sql b/plugins/tasklist/drivers/database/SQL/mysql.initial.sql
index 2746ca4..aae636d 100644
--- a/plugins/tasklist/drivers/database/SQL/mysql.initial.sql
+++ b/plugins/tasklist/drivers/database/SQL/mysql.initial.sql
@@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS `tasks` (
   `starttime` varchar(5) DEFAULT NULL,
   `flagged` tinyint(4) NOT NULL DEFAULT '0',
   `complete` float NOT NULL DEFAULT '0',
+  `status` enum('','NEEDS-ACTION','IN-PROCESS','COMPLETED','CANCELLED') NOT NULL DEFAULT '',
   `alarms` varchar(255) DEFAULT NULL,
   `recurrence` varchar(255) DEFAULT NULL,
   `organizer` varchar(255) DEFAULT NULL,
@@ -48,4 +49,4 @@ CREATE TABLE IF NOT EXISTS `tasks` (
     REFERENCES `tasklists`(`tasklist_id`) ON DELETE CASCADE ON UPDATE CASCADE
 ) /*!40000 ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci */;
 
-REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2013011000');
+REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2014051900');
diff --git a/plugins/tasklist/drivers/database/SQL/mysql/2014051900.sql b/plugins/tasklist/drivers/database/SQL/mysql/2014051900.sql
new file mode 100644
index 0000000..e5f9a62
--- /dev/null
+++ b/plugins/tasklist/drivers/database/SQL/mysql/2014051900.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `tasks` ADD `status` ENUM('','NEEDS-ACTION','IN-PROCESS','COMPLETED','CANCELLED') NOT NULL DEFAULT '' AFTER `complete`;
+
+UPDATE `tasks` SET status='COMPLETED' WHERE complete=1.0 AND status='';
diff --git a/plugins/tasklist/drivers/database/SQL/postgres.initial.sql b/plugins/tasklist/drivers/database/SQL/postgres.initial.sql
index 4a44512..e5665c2 100644
--- a/plugins/tasklist/drivers/database/SQL/postgres.initial.sql
+++ b/plugins/tasklist/drivers/database/SQL/postgres.initial.sql
@@ -49,6 +49,7 @@ CREATE TABLE tasks (
     starttime varchar(5) DEFAULT NULL,
     flagged smallint NOT NULL DEFAULT 0,
     complete float NOT NULL DEFAULT 0,
+    status varchar(16) NOT NULL DEFAULT '',
     alarms varchar(255) DEFAULT NULL,
     recurrence varchar(255) DEFAULT NULL,
     organizer varchar(255) DEFAULT NULL,
@@ -60,4 +61,4 @@ CREATE TABLE tasks (
 CREATE INDEX tasks_tasklisting_idx ON tasks (tasklist_id, del, date);
 CREATE INDEX tasks_uid_idx ON tasks (uid);
 
-INSERT INTO system (name, value) VALUES ('tasklist-database-version', '2013011000');
+INSERT INTO system (name, value) VALUES ('tasklist-database-version', '2014051900');
diff --git a/plugins/tasklist/drivers/database/tasklist_database_driver.php b/plugins/tasklist/drivers/database/tasklist_database_driver.php
index d9bf414..6c1e0ea 100644
--- a/plugins/tasklist/drivers/database/tasklist_database_driver.php
+++ b/plugins/tasklist/drivers/database/tasklist_database_driver.php
@@ -24,6 +24,8 @@
 
 class tasklist_database_driver extends tasklist_driver
 {
+    const IS_COMPLETE_SQL = "(status='COMPLETED' OR (complete=1 AND status=''))";
+
     public $undelete = true; // yes, we can
     public $sortable = false;
     public $alarm_types = array('DISPLAY');
@@ -224,7 +226,7 @@ class tasklist_database_driver extends tasklist_driver
         $result = $this->rc->db->query(sprintf(
             "SELECT task_id, flagged, date FROM " . $this->db_tasks . "
              WHERE tasklist_id IN (%s)
-             AND del=0 AND complete<1",
+             AND del=0 AND NOT " . self::IS_COMPLETE_SQL,
             join(',', $list_ids)
         ));
 
@@ -286,9 +288,9 @@ class tasklist_database_driver extends tasklist_driver
             $sql_add = ' AND date IS NULL';
 
         if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE)
-            $sql_add .= ' AND complete=1';
+            $sql_add .= ' AND ' . self::IS_COMPLETE_SQL;
         else if (empty($filter['since']))  // don't show complete tasks by default
-            $sql_add .= ' AND complete<1';
+            $sql_add .= ' AND NOT ' . self::IS_COMPLETE_SQL;
 
         if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED)
             $sql_add .= ' AND flagged=1';
@@ -435,7 +437,7 @@ class tasklist_database_driver extends tasklist_driver
             $result = $this->rc->db->query(sprintf(
                 "SELECT * FROM " . $this->db_tasks . "
                  WHERE tasklist_id IN (%s)
-                 AND notify <= %s AND complete < 1",
+                 AND notify <= %s AND NOT " . self::IS_COMPLETE_SQL,
                 join(',', $list_ids),
                 $this->rc->db->fromunixtime($time)
             ));
@@ -529,7 +531,7 @@ class tasklist_database_driver extends tasklist_driver
             $prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']);
         }
 
-        foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence') as $col) {
+        foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) {
             if (empty($prop[$col]))
                 $prop[$col] = null;
         }
@@ -537,8 +539,8 @@ class tasklist_database_driver extends tasklist_driver
         $notify_at = $this->_get_notification($prop);
         $result = $this->rc->db->query(sprintf(
             "INSERT INTO " . $this->db_tasks . "
-             (tasklist_id, uid, parent_id, created, changed, title, date, time, startdate, starttime, description, tags, flagged, complete, alarms, recurrence, notify)
-             VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+             (tasklist_id, uid, parent_id, created, changed, title, date, time, startdate, starttime, description, tags, flagged, complete, status, alarms, recurrence, notify)
+             VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
              $this->rc->db->now(),
              $this->rc->db->now()
             ),
@@ -554,6 +556,7 @@ class tasklist_database_driver extends tasklist_driver
             join(',', (array)$prop['tags']),
             $prop['flagged'] ? 1 : 0,
             intval($prop['complete']),
+            $prop['status'],
             $prop['alarms'],
             $prop['recurrence'],
             $notify_at
@@ -586,7 +589,7 @@ class tasklist_database_driver extends tasklist_driver
             if (isset($prop[$col]))
                 $sql_set[] = $this->rc->db->quote_identifier($col) . '=' . $this->rc->db->quote($prop[$col]);
         }
-        foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence') as $col) {
+        foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) {
             if (isset($prop[$col]))
                 $sql_set[] = $this->rc->db->quote_identifier($col) . '=' . (empty($prop[$col]) ? 'NULL' : $this->rc->db->quote($prop[$col]));
         }
@@ -694,7 +697,7 @@ class tasklist_database_driver extends tasklist_driver
      */
     private function _get_notification($task)
     {
-        if ($task['valarms'] && $task['complete'] < 1) {
+        if ($task['valarms'] && !$this->is_complete($task)) {
             $alarm = libcalendaring::get_next_alarm($task, 'task');
 
         if ($alarm['time'] && in_array($alarm['action'], $this->alarm_types))
diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index ad36777..3118523 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -307,7 +307,7 @@ class tasklist_kolab_driver extends tasklist_driver
             foreach ($folder->select(array(array('tags','!~','x-complete'))) as $record) {
                 $rec = $this->_to_rcube_task($record);
 
-                if ($rec['complete'] >= 1.0)  // don't count complete tasks
+                if ($this->is_complete($rec))  // don't count complete tasks
                     continue;
 
                 $counts['all']++;
@@ -603,7 +603,8 @@ class tasklist_kolab_driver extends tasklist_driver
             'description' => $record['description'],
             'tags' => array_filter((array)$record['categories']),
             'flagged' => $record['priority'] == 1,
-            'complete' => $record['status'] == 'COMPLETED' ? 1 : floatval($record['complete'] / 100),
+            'complete' => floatval($record['complete'] / 100),
+            'status' => $record['status'],
             'parent_id' => $record['parent_id'],
             'recurrence' => $record['recurrence'],
         );
@@ -672,7 +673,7 @@ class tasklist_kolab_driver extends tasklist_driver
         }
 
         $object['complete'] = $task['complete'] * 100;
-        if ($task['complete'] == 1.0)
+        if ($task['complete'] == 1.0 && empty($task['complete']))
             $object['status'] = 'COMPLETED';
 
         if ($task['flagged'])
diff --git a/plugins/tasklist/drivers/tasklist_driver.php b/plugins/tasklist/drivers/tasklist_driver.php
index 6c31fa7..76480f5 100644
--- a/plugins/tasklist/drivers/tasklist_driver.php
+++ b/plugins/tasklist/drivers/tasklist_driver.php
@@ -41,7 +41,7 @@
   *    'categories' => 'Task category',
   *       'flagged' => 'Boolean value whether this record is flagged',
   *      'complete' => 'Float value representing the completeness state (range 0..1)',
-  *   'sensitivity' => 0|1|2,   // Event sensitivity (0=public, 1=private, 2=confidential)
+  *      'status'   => 'Task status string according to (NEEDS-ACTION, IN-PROCESS, COMPLETED, CANCELLED) RFC 2445',
   *       'valarms' => array(           // List of reminders (new format), each represented as a hash array:
   *                array(
   *                   'trigger' => '-PT90M',     // ISO 8601 period string prefixed with '+' or '-', or DateTime object
@@ -271,6 +271,17 @@ abstract class tasklist_driver
     public function get_attachment_body($id, $task) { }
 
     /**
+     * Helper method to determine whether the given task is considered "complete"
+     *
+     * @param array  $task  Hash array with event properties:
+     * @return boolean True if complete, False otherwiese
+     */
+    public function is_complete($task)
+    {
+        return ($task['complete'] >= 1.0 && empty($task['status'])) || $task['status'] === 'COMPLETED';
+    }
+
+    /**
      * List availabale categories
      * The default implementation reads them from config/user prefs
      */
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index 18456fa..714e79c 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -19,6 +19,11 @@ $labels['datetime'] = 'Due';
 $labels['start'] = 'Start';
 $labels['alarms'] = 'Reminder';
 $labels['repeat'] = 'Repeat';
+$labels['status'] = 'Status';
+$labels['status-needs-action'] = 'Needs action';
+$labels['status-in-process'] = 'In process';
+$labels['status-completed'] = 'Completed';
+$labels['status-cancelled'] = 'Cancelled';
 
 $labels['all'] = 'All';
 $labels['flagged'] = 'Flagged';
diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html
index fe3f88b..1761683 100644
--- a/plugins/tasklist/skins/larry/templates/mainview.html
+++ b/plugins/tasklist/skins/larry/templates/mainview.html
@@ -141,6 +141,10 @@
 		<label><roundcube:label name="tasklist.complete" /></label>
 		<span class="task-text"></span>
 	</div>
+	<div id="task-status" class="form-section">
+		<label><roundcube:label name="tasklist.status" /></label>
+		<span class="task-text"></span>
+	</div>
 	<div id="task-attachments" class="form-section">
 		<label><roundcube:label name="attachments" /></label>
 		<div class="task-text"></div>
diff --git a/plugins/tasklist/skins/larry/templates/taskedit.html b/plugins/tasklist/skins/larry/templates/taskedit.html
index 31ee79c..97f604d 100644
--- a/plugins/tasklist/skins/larry/templates/taskedit.html
+++ b/plugins/tasklist/skins/larry/templates/taskedit.html
@@ -46,6 +46,10 @@
 				<input type="text" name="title" id="taskedit-completeness" size="3"  tabindex="25" /> %
 				<div id="taskedit-completeness-slider"></div>
 			</div>
+			<div class="form-section">
+				<label for="taskedit-status"><roundcube:label name="tasklist.status" /></label>
+				<roundcube:object name="plugin.status_select" id="taskedit-status" tabindex="26" />
+			</div>
 			<div class="form-section" id="tasklist-select">
 				<label for="taskedit-tasklist"><roundcube:label name="tasklist.list" /></label>
 				<roundcube:object name="plugin.tasklist_select" id="taskedit-tasklist" tabindex="26" />
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index fcf4306..4bc82b0 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -264,7 +264,7 @@ function rcube_tasklist_ui(settings)
                     if (rcmail.busy)
                         return false;
 
-                    rec.complete = e.target.checked ? 1 : 0;
+                    rec.status = e.target.checked ? 'COMPLETED' : (rec.complete == 1 ? 'NEEDS-ACTION' : '');
                     li.toggleClass('complete');
                     save_task(rec, 'edit');
                     return true;
@@ -815,7 +815,7 @@ function rcube_tasklist_ui(settings)
 
         var div = $('<div>').addClass('taskhead').html(
             '<div class="progressbar"><div class="progressvalue" style="width:' + (rec.complete * 100) + '%"></div></div>' +
-            '<input type="checkbox" name="completed[]" value="1" class="complete" ' + (rec.complete == 1.0 ? 'checked="checked" ' : '') + '/>' + 
+            '<input type="checkbox" name="completed[]" value="1" class="complete" ' + (is_complete(rec) ? 'checked="checked" ' : '') + '/>' + 
             '<span class="flagged"></span>' +
             '<span class="title">' + text2html(Q(rec.title)) + '</span>' +
             '<span class="tags">' + tags_html + '</span>' +
@@ -835,7 +835,7 @@ function rcube_tasklist_ui(settings)
                 revertDuration: 300
             });
 
-        if (rec.complete == 1.0)
+        if (is_complete(rec))
             div.addClass('complete');
         if (rec.flagged)
             div.addClass('flagged');
@@ -951,13 +951,21 @@ function rcube_tasklist_ui(settings)
      */
     function task_cmp(a, b)
     {
-        var d = Math.floor(a.complete) - Math.floor(b.complete);
+        var d = is_complete(a) - is_complete(b);
         if (!d) d = (b._hasdate-0) - (a._hasdate-0);
         if (!d) d = (a.datetime||99999999999) - (b.datetime||99999999999);
         return d;
     }
 
     /**
+     * Determine whether the given task should be displayed as "complete"
+     */
+    function is_complete(rec)
+    {
+        return ((rec.complete == 1.0 && !rec.status) || rec.status === 'COMPLETED') ? 1 : 0;
+    }
+
+    /**
      *
      */
     function get_all_childs(id)
@@ -1144,6 +1152,7 @@ function rcube_tasklist_ui(settings)
         $('#task-starttime').html(Q(rec.starttime || ''));
         $('#task-alarm')[(rec.alarms_text ? 'show' : 'hide')]().children('.task-text').html(Q(rec.alarms_text));
         $('#task-completeness .task-text').html(((rec.complete || 0) * 100) + '%');
+        $('#task-status')[(rec.status ? 'show' : 'hide')]().children('.task-text').html(rcmail.gettext('status-'+String(rec.status).toLowerCase(),'tasklist'));
         $('#task-list .task-text').html(Q(me.tasklists[rec.list] ? me.tasklists[rec.list].name : ''));
 
         var itags = get_inherited_tags(rec);
@@ -1257,6 +1266,7 @@ function rcube_tasklist_ui(settings)
         var recstarttime = $('#taskedit-starttime').val(rec.starttime || '');
         var complete = $('#taskedit-completeness').val((rec.complete || 0) * 100);
         completeness_slider.slider('value', complete.val());
+        var taskstatus = $('#taskedit-status').val(rec.status || '');
         var tasklist = $('#taskedit-tasklist').val(rec.list || me.selected_list).prop('disabled', rec.parent_id ? true : false);
 
         // tag-edit line
@@ -1308,7 +1318,7 @@ function rcube_tasklist_ui(settings)
         var buttons = {};
         buttons[rcmail.gettext('save', 'tasklist')] = function() {
             // copy form field contents into task object to save
-            $.each({ title:title, description:description, date:recdate, time:rectime, startdate:recstartdate, starttime:recstarttime, list:tasklist }, function(key,input){
+            $.each({ title:title, description:description, date:recdate, time:rectime, startdate:recstartdate, starttime:recstarttime, status:taskstatus, list:tasklist }, function(key,input){
                 me.selected_task[key] = input.val();
             });
             me.selected_task.tags = [];
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index 65376d7..d8ba4d0 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -214,7 +214,7 @@ class tasklist extends rcube_plugin
                         $child = array('id' => $cid, 'list' => $rec['list'], '_fromlist' => $rec['_fromlist']);
                         if ($this->driver->move_task($child)) {
                             $r = $this->driver->get_task($child);
-                            if ((bool)($filter & self::FILTER_MASK_COMPLETE) == ($r['complete'] == 1.0)) {
+                            if ((bool)($filter & self::FILTER_MASK_COMPLETE) == $this->driver->is_complete($r)) {
                                 $refresh[] = $r;
                             }
                         }
@@ -237,7 +237,7 @@ class tasklist extends rcube_plugin
                           $child['id'] = $cid;
                           if ($this->driver->move_task($child)) {
                               $r = $this->driver->get_task($child);
-                              if ((bool)($filter & self::FILTER_MASK_COMPLETE) == ($r['complete'] == 1.0)) {
+                              if ((bool)($filter & self::FILTER_MASK_COMPLETE) == $this->driver->is_complete($r)) {
                                   $refresh[] = $r;
                               }
                           }
@@ -524,7 +524,7 @@ class tasklist extends rcube_plugin
     private function handle_recurrence(&$rec, $old)
     {
         $clone = null;
-        if ($rec['complete'] == 1.0 && $old && $old['complete'] < 1.0 && is_array($rec['recurrence'])) {
+        if ($this->driver->is_complete($rec) && $old && $this->driver->is_complete($old) && is_array($rec['recurrence'])) {
             $engine = libcalendaring::get_recurrence();
             $rrule = $rec['recurrence'];
             $updates = array();
@@ -569,6 +569,7 @@ class tasklist extends rcube_plugin
                 // update the task but unset completed flag
                 $rec = array_merge($rec, $updates);
                 $rec['complete'] = $old['complete'];
+                $rec['satus'] = $old['satus'];
             }
         }
 
@@ -718,7 +719,7 @@ class tasklist extends rcube_plugin
                 $tags = array_merge($tags, (array)$rec['tags']);
 
             // apply filter; don't trust the driver on this :-)
-            if ((!$f && $rec['complete'] < 1.0) || ($rec['mask'] & $f))
+            if ((!$f && !$this->driver->is_complete($rec)) || ($rec['mask'] & $f))
                 $data[] = $rec;
         }
 
@@ -845,7 +846,7 @@ class tasklist extends rcube_plugin
 
         if ($rec['flagged'])
             $mask |= self::FILTER_MASK_FLAGGED;
-        if ($rec['complete'] == 1.0)
+        if ($this->driver->is_complete($rec))
             $mask |= self::FILTER_MASK_COMPLETE;
 
         if (empty($rec['date']))
diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php
index 6988a61..f6d4b3a 100644
--- a/plugins/tasklist/tasklist_ui.php
+++ b/plugins/tasklist/tasklist_ui.php
@@ -67,7 +67,7 @@ class tasklist_ui
     {
         $this->plugin->register_handler('plugin.tasklists', array($this, 'tasklists'));
         $this->plugin->register_handler('plugin.tasklist_select', array($this, 'tasklist_select'));
-        $this->plugin->register_handler('plugin.category_select', array($this, 'category_select'));
+        $this->plugin->register_handler('plugin.status_select', array($this, 'status_select'));
         $this->plugin->register_handler('plugin.searchform', array($this->rc->output, 'search_form'));
         $this->plugin->register_handler('plugin.quickaddform', array($this, 'quickadd_form'));
         $this->plugin->register_handler('plugin.tasks', array($this, 'tasks_resultview'));
@@ -129,6 +129,21 @@ class tasklist_ui
         return html::tag('ul', $attrib, $li, html::$common_attrib);
     }
 
+    /**
+     * Render HTML form for task status selector
+     */
+    function status_select($attrib = array())
+    {
+        $attrib['name'] = 'status';
+        $select = new html_select($attrib);
+        $select->add('---', '');
+        $select->add($this->plugin->gettext('status-needs-action'), 'NEEDS-ACTION');
+        $select->add($this->plugin->gettext('status-in-process'),   'IN-PROCESS');
+        $select->add($this->plugin->gettext('status-completed'),    'COMPLETED');
+        $select->add($this->plugin->gettext('status-cancelled'),    'CANCELLED');
+
+        return $select->show(null);
+    }
 
     /**
      * Render a HTML select box for list selection


commit d87c46acacdbeb708a5d84145f936ad560c70428
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Mon May 19 18:05:15 2014 +0200

    Fix some styles after Larry skin update

diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index c940dff..f8d9d0f 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -75,7 +75,7 @@ body.attachmentwin #topnav .topright {
 }
 
 #taskselector {
-	margin: -4px 40px 0 0;
+	margin: -1px 40px 0 0;
 	padding: 0;
 }
 
@@ -90,14 +90,20 @@ body.attachmentwin #topnav .topright {
 #taskselector li a {
 	display: inline-block;
 	color: #004458;
-	min-width: 4em;
-	padding: 0.2em 0.6em 0.3em 0.6em;
+	min-width: 3.5em;
+	padding: 0.2em 0.6em 0.2em 0.6em;
 	text-align: center;
 	text-decoration: none;
 	border: 1px solid #eee;
 	border-color: transparent;
 }
 
+.webkit .tagcloud li,
+.webkit #taskselector li a {
+	padding-bottom: 0.25em;
+}
+
+
 #taskselector li:first-child {
 	border-top: 0;
 	border-radius: 4px 4px 0 0;
@@ -131,7 +137,7 @@ body.attachmentwin #topnav .topright {
 	-webkit-box-shadow: inset 0 1px 1px 0 #003645;
 	-moz-box-shadow: inset 0 1px 1px 0 #003645;
 	border-color: #003645;
-	border-radius: 9px;
+	border-radius: 10px;
 	text-shadow: none;
 	outline: none;
 }
@@ -397,6 +403,8 @@ body.attachmentwin #topnav .topright {
 	background: linear-gradient(top, #eee 0%, #dfdfdf 100%);
 	border-bottom: 1px solid #ccc;
 	position: relative;
+	line-height: 13px;
+	height: 20px;
 }
 
 #tasksview .buttonbar .buttonbar-right {




More information about the commits mailing list