Implement individual alarms for tasks.
authorJan Schneider <jan@horde.org>
Tue, 8 Jun 2010 14:17:23 +0000 (16:17 +0200)
committerJan Schneider <jan@horde.org>
Tue, 8 Jun 2010 14:17:23 +0000 (16:17 +0200)
kronolith/index.php
kronolith/js/kronolith.js
kronolith/lib/Ajax/Application.php
kronolith/templates/index/edit.inc
kronolith/templates/index/task.inc
nag/lib/Task.php

index 4213a2f..e8a9417 100644 (file)
@@ -36,45 +36,64 @@ $_SESSION['horde_notification']['override'] = array(
     'Kronolith_Notification_Listener_AjaxStatus'
 );
 
-$alarm_methods = $alarm_params = '';
+$eventAlarmMethods = $eventAlarmParams = $taskAlarmMethods = $taskAlarmParams = '';
 foreach ($injector->getInstance('Horde_Alarm')->handlers() as $method => $handler) {
-    $alarm_methods .= ' <input type="checkbox" name="event_alarms[]" id="kronolithEventAlarm' . $method . '" value="' . $method . '" /> <label for="kronolithEventAlarm' . $method . '">' . $handler->getDescription() . '</label>';
+    $eventAlarmMethods .= ' <input type="checkbox" name="event_alarms[]" id="kronolithEventAlarm' . $method . '" value="' . $method . '" /> <label for="kronolithEventAlarm' . $method . '">' . $handler->getDescription() . '</label>';
+    $taskAlarmMethods .= ' <input type="checkbox" name="task[alarm_methods][]" id="kronolithTaskAlarm' . $method . '" value="' . $method . '" /> <label for="kronolithTaskAlarm' . $method . '">' . $handler->getDescription() . '</label>';
     $params = $handler->getParameters();
     if (!count($params)) {
         continue;
     }
-    $alarm_params .= ' <div id="kronolithEventAlarm' . $method . 'Params" style="display:none">';
+    $eventAlarmParams .= ' <div id="kronolithEventAlarm' . $method . 'Params" style="display:none">';
+    $taskAlarmParams .= ' <div id="kronolithTaskAlarm' . $method . 'Params" style="display:none">';
     foreach ($params as $name => $param) {
-        $alarm_params .= ' <label for="kronolithEventAlarmParam' . $name
+        $eventAlarmParams .= ' <label for="kronolithEventAlarmParam' . $name
             . '">' . $param['desc'] . '</label> ';
-        $name_att = 'name="event_alarms_' . $name . '"';
-        $att = 'id="kronolithEventAlarmParam' . $name . '" ' . $name_att;
+        $eventNameAtt = 'name="event_alarms_' . $name . '"';
+        $eventAtt = 'id="kronolithEventAlarmParam' . $name . '" ' . $eventNameAtt;
+        $taskAlarmParams .= ' <label for="kronolithTaskAlarmParam' . $name
+            . '">' . $param['desc'] . '</label> ';
+        $taskNameAtt = 'name="task[methods][' . $method . '][' . $name . ']"';
+        $taskAtt = 'id="kronolithTaskAlarmParam' . $name . '" ' . $taskNameAtt;
         switch ($param['type']) {
         case 'text':
-            $alarm_params .= '<input type="text" ' . $att . ' />';
+            $eventAlarmParams .= '<input type="text" ' . $eventAtt . ' />';
+            $taskAlarmParams .= '<input type="text" ' . $taskAtt . ' />';
             break;
         case 'boolean':
-            $alarm_params .= '<input type="checkbox" ' . $att . ' />';
+            $eventAlarmParams .= '<input type="checkbox" ' . $eventAtt . ' />';
+            $taskAlarmParams .= '<input type="checkbox" ' . $taskAtt . ' />';
             break;
         case 'sound':
-            $alarm_params .= '<ul class="sound-list"><li><input type="radio" ' . $att
+            $eventAlarmParams .= '<ul class="sound-list"><li><input type="radio" ' . $eventAtt
+                . ' value="" checked="checked" /> ' . _("No Sound") . '</li>';
+            $taskAlarmParams .= '<ul class="sound-list"><li><input type="radio" ' . $taskAtt
                 . ' value="" checked="checked" /> ' . _("No Sound") . '</li>';
             foreach (Horde_Themes::soundList() as $key => $val) {
                 $sound = htmlspecialchars($key);
-                $alarm_params .= '<li><input type="radio" id="kronolithEventAlarmParam'
-                    . $name . str_replace('.wav', '', $sound) . '" ' . $name_att
-                    . ' value="' .  $sound
-                    . '" /> <embed autostart="false" src="'
-                    . htmlspecialchars($val->uri)
-                    . '" /> ' . $sound . '</li>';
+                $value = sprintf('<li><input type="radio" id="%s%s" %s value="%s" /> <embed autostart="false" src="%s" /> %s</li>',
+                                 '%s',
+                                 $name . str_replace('.wav', '', $sound),
+                                 '%s',
+                                 $sound,
+                                 htmlspecialchars($val->uri),
+                                 $sound);
+                $eventAlarmParams .= sprintf($value,
+                                             'kronolithEventAlarmParam',
+                                             $eventNameAtt);
+                $taskAlarmParams .= sprintf($value,
+                                             'kronolithTaskAlarmParam',
+                                             $taskNameAtt);
             }
-            $alarm_params .= '</ul>';
+            $eventAlarmParams .= '</ul>';
+            $taskAlarmParams .= '</ul>';
             break;
         }
-        $alarm_params .= '<br />';
+        $eventAlarmParams .= '<br />';
+        $taskAlarmParams .= '<br />';
     }
-    $alarm_params = substr($alarm_params, 0, - 6);
-    $alarm_params .= '</div>';
+    $eventAlarmParams = substr($eventAlarmParams, 0, - 6) . '</div>';
+    $taskAlarmParams = substr($taskAlarmParams, 0, - 6) . '</div>';
 }
 
 Kronolith::header();
index ce557a2..ea2c8b2 100644 (file)
@@ -2370,6 +2370,7 @@ KronolithCore = {
         $('kronolithTaskDelete').show();
         $('kronolithTaskForm').down('.kronolithFormActions .kronolithSeparator').show();
         this.updateTasklistDropDown();
+        this.disableAlarmMethods('Task');
         if (id) {
             RedBox.loading();
             this.doAction('getTask', { list: tasklist, id: id }, this.editTaskCallback.bind(this));
@@ -2429,8 +2430,37 @@ KronolithCore = {
                     throw $break;
                 }
             });
+            if (task.m) {
+                $('kronolithTaskAlarmDefaultOff').checked = true;
+                $H(task.m).each(function(method) {
+                    if (!$('kronolithTaskAlarm' + method.key)) {
+                        return;
+                    }
+                    $('kronolithTaskAlarm' + method.key).setValue(1);
+                    if ($('kronolithTaskAlarm' + method.key + 'Params')) {
+                        $('kronolithTaskAlarm' + method.key + 'Params').show();
+                    }
+                    $H(method.value).each(function(param) {
+                        var input = $('kronolithTaskAlarmParam' + param.key);
+                        if (!input) {
+                            return;
+                        }
+                        if (input.type == 'radio') {
+                            input.up('form').select('input[type=radio]').each(function(radio) {
+                                if (radio.name == input.name &&
+                                    radio.value == param.value) {
+                                    radio.setValue(1);
+                                    throw $break;
+                                }
+                            });
+                        } else {
+                            input.setValue(param.value);
+                        }
+                    });
+                });
+            }
         } else {
-            $('kronolithEventAlarmOff').setValue(true);
+            $('kronolithTaskAlarmOff').setValue(true);
         }
 
         if (!task.pe) {
@@ -2494,10 +2524,10 @@ KronolithCore = {
     removeTask: function(task, list)
     {
         this.deleteTasksCache(task, list);
-        $('kronolithViewTasksBody').select('tr').find(function(el) {
+        $('kronolithViewTasksBody').select('tr').findAll(function(el) {
             return el.retrieve('tasklist') == list &&
                 el.retrieve('taskid') == task;
-        }).remove();
+        }).invoke('remove');
     },
 
     /**
@@ -3699,7 +3729,11 @@ KronolithCore = {
                 break;
 
             case 'kronolithEventAlarmDefaultOn':
-                this.disableAlarmMethods();
+                this.disableAlarmMethods('Event');
+                break;
+
+            case 'kronolithTaskAlarmDefaultOn':
+                this.disableAlarmMethods('Task');
                 break;
 
             case 'kronolithEventAlarmPrefs':
@@ -4288,8 +4322,14 @@ KronolithCore = {
                 window.history.back();
                 e.stop();
                 break;
-            } else if (elt.tagName == 'INPUT' && elt.name == 'event_alarms[]') {
-                $('kronolithEventAlarmDefaultOff').setValue(1);
+            } else if (elt.tagName == 'INPUT' &&
+                       (elt.name == 'event_alarms[]' ||
+                        elt.name == 'task[alarm_methods][]')) {
+                if (elt.name == 'event_alarms[]') {
+                    $('kronolithEventAlarmDefaultOff').setValue(1);
+                } else {
+                    $('kronolithTaskAlarmDefaultOff').setValue(1);
+                }
                 if ($(elt.id + 'Params')) {
                     if (elt.getValue()) {
                         $(elt.id + 'Params').show();
@@ -4526,7 +4566,7 @@ KronolithCore = {
         this.updateCalendarDropDown('kronolithEventTarget');
         this.toggleAllDay(false);
         this.openTab($('kronolithEventForm').down('.tabset a.kronolithTabLink'));
-        this.disableAlarmMethods();
+        this.disableAlarmMethods('Event');
         $('kronolithEventForm').reset();
         kronolithEAttendeesAc.reset();
         kronolithETagAc.reset();
@@ -4993,9 +5033,9 @@ KronolithCore = {
     /**
      * Disables all custom alarm methods in the event form.
      */
-    disableAlarmMethods: function() {
-        $('kronolithEventTabReminder').select('input').each(function(input) {
-            if (input.name == 'event_alarms[]') {
+    disableAlarmMethods: function(type) {
+        $('kronolith' + type + 'TabReminder').select('input').each(function(input) {
+            if (input.name == (type == 'Event' ? 'event_alarms[]' : 'task[alarm_methods][]')) {
                 input.setValue(0);
                 if ($(input.id + 'Params')) {
                     $(input.id + 'Params').hide();
index 13f8190..6e621fa 100644 (file)
@@ -410,9 +410,25 @@ class Kronolith_Ajax_Application extends Horde_Ajax_Application_Base
                 $value = $unit = 1;
             }
             $task['alarm'] = $value * $unit;
+            if (isset($task['alarm_methods']) && isset($task['methods'])) {
+                foreach (array_keys($task['methods']) as $method) {
+                    if (!in_array($method, $task['alarm_methods'])) {
+                        unset($task['methods'][$method]);
+                    }
+                }
+                foreach ($task['alarm_methods'] as $method) {
+                    if (!isset($task['methods'][$method])) {
+                        $task['methods'][$method] = array();
+                    }
+                }
+            } else {
+                $task['methods'] = array();
+            }
         } else {
             $task['alarm'] = 0;
+            $task['methods'] = array();
         }
+        unset($task['alarm_methods']);
 
         $result = new stdClass;
         try {
index 25028a5..b2ad6c0 100644 (file)
   '<input type="radio" name="alarm_change_method" id="kronolithEventAlarmDefaultOn" value="0" checked="checked" />
   <label for="kronolithEventAlarmDefaultOn">', '</label>',
   '<input type="radio" name="alarm_change_method" id="kronolithEventAlarmDefaultOff" value="1" style="display:none" />') ?>
-  <?php echo $alarm_methods . $alarm_params ?>
+  <?php echo $eventAlarmMethods . $eventAlarmParams ?>
 </div>
 
 <div id="kronolithEventTabRecur" class="kronolithTabsOption" style="display:none">
index 3a6310e..e3eaf23 100644 (file)
@@ -56,7 +56,7 @@
 
 <div id="kronolithTaskTabReminder" class="kronolithTabsOption" style="display:none">
   <div class="kronolithDialogInfo"><?php printf(_("You can change the default settings in the %sNotification options%s"), '<a id="kronolithTaskAlarmPrefs" href="#">', '</a>') ?></div>
-  <?php printf(_("%s don't set %s or %s set %s before due date"),
+  <?php printf(_("%s don't set %s or %s set %s before due date %s"),
   '<label><input type="radio" name="task[alarm][on]" id="kronolithTaskAlarmOff" value="0" checked="checked" />', '</label>',
   '<label><input type="radio" name="task[alarm][on]" id="kronolithTaskAlarmOn" value="1" />', '</label>
   <input type="text" name="task[alarm][value]" id="kronolithTaskAlarmValue" size="3" value="15" class="kronolithEventValue" />
     <option value="60">' . _("hours") . '</option>
     <option value="1440">' . _("days") . '</option>
     <option value="10080">' . _("weeks") . '</option>
-  </select>') ?>
+  </select>
+  <label for="kronolithTaskAlarmValue">',
+  '</label>') ?>
+  <br />
+  <?php printf(_("Alert me %s as default %s or %s using:"),
+  '<input type="radio" name="alarm_change_method" id="kronolithTaskAlarmDefaultOn" value="0" checked="checked" />
+  <label for="kronolithTaskAlarmDefaultOn">', '</label>',
+  '<input type="radio" name="alarm_change_method" id="kronolithTaskAlarmDefaultOff" value="1" style="display:none" />') ?>
+  <?php echo $taskAlarmMethods . $taskAlarmParams ?>
 </div>
 
 <div id="kronolithTaskTabUrl" class="kronolithTabsOption" style="display:none">
index 1ca6900..66402be 100644 (file)
@@ -701,7 +701,7 @@ class Nag_Task {
                 $json->cd = $date->toJson();
             }
             */
-            $json->a = $this->alarm;
+            $json->a = (int)$this->alarm;
             $json->m = $this->methods;
             //$json->pv = (boolean)$this->private;