plugins/calendar plugins/kolab_notes

Thomas Brüderli bruederli at kolabsys.com
Sat Apr 12 21:44:02 CEST 2014


 plugins/calendar/calendar.php              |    1 
 plugins/kolab_notes/kolab_notes.php        |   62 ++++++++++++-
 plugins/kolab_notes/kolab_notes_ui.php     |   56 ++++++++----
 plugins/kolab_notes/localization/en_US.inc |    2 
 plugins/kolab_notes/notes.js               |  134 ++++++++++++++++++++++++++---
 plugins/kolab_notes/skins/larry/notes.css  |   37 +++++++-
 6 files changed, 257 insertions(+), 35 deletions(-)

New commits:
commit 49f9771ed437488aab2b21f9a7482d8587af57bd
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Sat Apr 12 21:43:44 2014 +0200

    Add function to create a note from mail view with a link to the selected message (link not saved yet)

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 2857ee3..2666d3c 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -2168,7 +2168,6 @@ class calendar extends rcube_plugin
       foreach ($p['messages'] as $i => $header) {
         $part = new StdClass;
         $part->mimetype = $header->ctype;
-        $part->filename = '';
         if ($this->is_vcalendar($part)) {
           $header->list_flags['attachmentClass'] = 'ical';
         }
diff --git a/plugins/kolab_notes/kolab_notes.php b/plugins/kolab_notes/kolab_notes.php
index cdf61bd..3be3ab9 100644
--- a/plugins/kolab_notes/kolab_notes.php
+++ b/plugins/kolab_notes/kolab_notes.php
@@ -64,7 +64,7 @@ class kolab_notes extends rcube_plugin
         }
 
         // load localizations
-        $this->add_texts('localization/', $args['task'] == 'notes' && !$args['action']);
+        $this->add_texts('localization/', $args['task'] == 'notes' && (!$args['action'] || $args['action'] == 'dialog-ui'));
         $this->rc->load_language($_SESSION['language'], array('notes.notes' => $this->gettext('navtitle')));  // add label for task title
 
         if ($args['task'] == 'notes') {
@@ -74,12 +74,31 @@ class kolab_notes extends rcube_plugin
             $this->register_action('get',   array($this, 'note_record'));
             $this->register_action('action', array($this, 'note_action'));
             $this->register_action('list',  array($this, 'list_action'));
+            $this->register_action('dialog-ui', array($this, 'dialog_view'));
         }
         else if ($args['task'] == 'mail') {
             $this->add_hook('message_compose', array($this, 'mail_message_compose'));
+            $this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html'));
+
+            // add 'Append note' item to message menu
+            if ($this->api->output->type == 'html' && $_REQUEST['_rel'] != 'note') {
+                $this->api->add_content(html::tag('li', null, 
+                    $this->api->output->button(array(
+                      'command'  => 'append-kolab-note',
+                      'label'    => 'kolab_notes.appendnote',
+                      'type'     => 'link',
+                      'classact' => 'icon appendnote active',
+                      'class'    => 'icon appendnote',
+                      'innerclass' => 'icon note',
+                    ))),
+                    'messagemenu');
+
+                $this->api->output->add_label('kolab_notes.appendnote', 'save', 'cancel');
+                $this->include_script('notes_mail.js');
+            }
         }
 
-        if (!$this->rc->output->ajax_call && (!$this->rc->output->env['framed'] || $args['action'] == 'folder-acl')) {
+        if (!$this->rc->output->ajax_call && (!$this->rc->output->env['framed'] || in_array($args['action'], array('folder-acl','dialog-ui')))) {
             require_once($this->home . '/kolab_notes_ui.php');
             $this->ui = new kolab_notes_ui($this);
             $this->ui->init();
@@ -208,6 +227,32 @@ class kolab_notes extends rcube_plugin
     }
 
     /**
+     * Deliver a rediced UI for inline (dialog)
+     */
+    public function dialog_view()
+    {
+        // resolve message reference
+        if ($msgref = rcube_utils::get_input_value('_msg', RCUBE_INPUT_GPC, true)) {
+            $storage = $this->rc->get_storage();
+            $storage->set_options(array('all_headers' => true));
+            list($uid, $folder) = explode('-', $msgref, 2);
+            if ($message = $storage->get_message_headers($msgref)) {
+                $this->rc->output->set_env('kolab_notes_template', array(
+                    'title' => $message->get('subject'),
+                    'links' => array(array(
+                        'uri' => $this->get_message_uri($message, $folder),
+                        'message_id' => $message->get('message-id'),
+                        'subject' => $message->get('subject'),
+                    )),
+                ));
+            }
+        }
+
+        $this->ui->init_templates();
+        $this->rc->output->send('kolab_notes.dialogview');
+    }
+
+    /**
      * Handler to retrieve note records for the given list and/or search query
      */
     public function notes_fetch()
@@ -635,6 +680,14 @@ class kolab_notes extends rcube_plugin
     }
 
     /**
+     * Handler for 'messagebody_html' hooks
+     */
+    public function mail_messagebody_html($args)
+    {
+      
+    }
+
+    /**
      * Determine whether the given note is HTML formatted
      */
     private function is_html($note)
@@ -682,6 +735,11 @@ class kolab_notes extends rcube_plugin
         return $message->getMessage();
     }
 
+    private function get_message_uri($headers, $folder)
+    {
+      return sprintf('imap://%s/%s#%s', $headers->folder ?: $folder, $headers->uid, urlencode($headers->messageID));
+    }
+
     /**
      * Process the given note data (submitted by the client) before saving it
      */
diff --git a/plugins/kolab_notes/kolab_notes_ui.php b/plugins/kolab_notes/kolab_notes_ui.php
index ce8bb97..bbb3ca7 100644
--- a/plugins/kolab_notes/kolab_notes_ui.php
+++ b/plugins/kolab_notes/kolab_notes_ui.php
@@ -50,6 +50,7 @@ class kolab_notes_ui
         $this->plugin->register_handler('plugin.editform', array($this, 'editform'));
         $this->plugin->register_handler('plugin.notetitle', array($this, 'notetitle'));
         $this->plugin->register_handler('plugin.detailview', array($this, 'detailview'));
+        $this->plugin->register_handler('plugin.attachments_list', array($this, 'attachments_list'));
 
         $this->rc->output->include_script('list.js');
         $this->rc->output->include_script('treelist.js');
@@ -64,8 +65,11 @@ class kolab_notes_ui
             'print_template' => $this->rc->url('print'),
         );
 
-        if (!empty($_REQUEST['_list'])) {
-            $settings['selected_list'] = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC);
+        if ($list = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC)) {
+            $settings['selected_list'] = $list;
+        }
+        if ($uid = rcube_utils::get_input_value('_id', RCUBE_INPUT_GPC)) {
+            $settings['selected_uid'] = $uid;
         }
 
         // TinyMCE uses two-letter lang codes, with exception of Chinese
@@ -92,6 +96,10 @@ class kolab_notes_ui
     {
         $attrib += array('id' => 'rcmkolabnotebooks');
 
+        if ($attrib['type'] == 'select') {
+            $select = new html_select($attrib);
+        }
+
         $jsenv = array();
         $items = '';
         foreach ($this->plugin->get_lists() as $prop) {
@@ -102,26 +110,33 @@ class kolab_notes_ui
             if (!$prop['virtual'])
                 $jsenv[$id] = $prop;
 
-            $html_id = rcube_utils::html_identifier($id);
-            $title = $prop['name'] != $prop['listname'] ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '';
-
-            if ($prop['virtual'])
-                $class .= ' virtual';
-            else if (!$prop['editable'])
-                $class .= ' readonly';
-            if ($prop['class_name'])
-                $class .= ' '.$prop['class_name'];
-
-            $items .= html::tag('li', array('id' => 'rcmliknb' . $html_id, 'class' => trim($class)),
-                html::span(array('class' => 'listname', 'title' => $title), $prop['listname']) .
-                html::span(array('class' => 'count'), '')
-            );
+            if ($attrib['type'] == 'select') {
+                if ($prop['editable']) {
+                    $select->add($prop['name'], $prop['id']);
+                }
+            }
+            else {
+                $html_id = rcube_utils::html_identifier($id);
+                $title = $prop['name'] != $prop['listname'] ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '';
+
+                if ($prop['virtual'])
+                    $class .= ' virtual';
+                else if (!$prop['editable'])
+                    $class .= ' readonly';
+                if ($prop['class_name'])
+                    $class .= ' '.$prop['class_name'];
+
+                $items .= html::tag('li', array('id' => 'rcmliknb' . $html_id, 'class' => trim($class)),
+                    html::span(array('class' => 'listname', 'title' => $title), $prop['listname']) .
+                    html::span(array('class' => 'count'), '')
+                );
+            }
         }
 
         $this->rc->output->set_env('kolab_notebooks', $jsenv);
         $this->rc->output->add_gui_object('notebooks', $attrib['id']);
 
-        return html::tag('ul', $attrib, $items, html::$common_attrib);
+        return $attrib['type'] == 'select' ? $select->show() : html::tag('ul', $attrib, $items, html::$common_attrib);
     }
 
     public function listing($attrib)
@@ -175,6 +190,13 @@ class kolab_notes_ui
         return html::div($attrib, $html);
     }
 
+    public function attachments_list($attrib)
+    {
+        $attrib += array('id' => 'rcmkolabnotesattachmentslist');
+        $this->rc->output->add_gui_object('notesattachmentslist', $attrib['id']);
+        return html::tag('ul', $attrib, '', html::$common_attrib);
+    }
+
     /**
      * Render edit for notes lists (folders)
      */
diff --git a/plugins/kolab_notes/localization/en_US.inc b/plugins/kolab_notes/localization/en_US.inc
index 66545c0..ccb737d 100644
--- a/plugins/kolab_notes/localization/en_US.inc
+++ b/plugins/kolab_notes/localization/en_US.inc
@@ -24,6 +24,8 @@ $labels['tabsharing'] = 'Sharing';
 $labels['discard'] = 'Discard';
 $labels['abort'] = 'Abort';
 $labels['unsavedchanges'] = 'Unsaved Changes!';
+$labels['appendnote'] = 'Add a note';
+$labels['savein'] = 'Save in';
 
 $labels['savingdata'] = 'Saving data...';
 $labels['recordnotfound'] = 'Record not found';
diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js
index ef8262c..c05be5a 100644
--- a/plugins/kolab_notes/notes.js
+++ b/plugins/kolab_notes/notes.js
@@ -222,7 +222,64 @@ function rcube_kolab_notes_ui(settings)
             return false;
         });
 
-        // initialize tinyMCE editor
+        init_editor();
+
+        if (settings.selected_list) {
+            notebookslist.select(settings.selected_list)
+        }
+    }
+    this.init = init;
+
+    /**
+     *
+     */
+    function init_dialog()
+    {
+        rcmail.register_command('save', save_note, true);
+        rcmail.addEventListener('plugin.update_note', function(data){
+            data.id = rcmail.html_identifier_encode(data.uid);
+            notesdata[data.id] = data;
+            render_note(data);
+        });
+        rcmail.addEventListener('plugin.unlock_saving', function(){
+            if (saving_lock) {
+                rcmail.set_busy(false, null, saving_lock);
+            }
+            if (rcmail.gui_objects.noteseditform) {
+                rcmail.lock_form(rcmail.gui_objects.noteseditform, false);
+            }
+        });
+
+        var id;
+        for (id in me.notebooks) {
+            if (me.notebooks[id].editable) {
+                me.selected_list = id;
+                break;
+            }
+        }
+
+        init_editor();
+        setTimeout(function(){
+            me.selected_note = $.extend({
+                list: me.selected_list,
+                uid: null,
+                title: rcmail.gettext('newnote','kolab_notes'),
+                description: '',
+                categories: [],
+                created: rcmail.gettext('now', 'kolab_notes'),
+                changed: rcmail.gettext('now', 'kolab_notes')
+            }, rcmail.env.kolab_notes_template || {});
+            render_note(me.selected_note);
+
+        }, 100);
+    }
+    this.init_dialog = init_dialog;
+
+    /**
+     * initialize tinyMCE editor
+     */
+    function init_editor()
+    {
         var editor_conf = {
             mode: 'textareas',
             elements: 'notecontent',
@@ -260,11 +317,21 @@ function rcube_kolab_notes_ui(settings)
 
         tinyMCE.init(editor_conf);
 
-        if (settings.selected_list) {
-            notebookslist.select(settings.selected_list)
-        }
+        // register click handler for message links
+        $(rcmail.gui_objects.notesattachmentslist).on('click', 'li a.messagelink', function(){
+            var uri = $(this).attr('rel');
+            if (uri && uri.match(/imap:\/\/.+/)) {
+                var path = uri.split('#')[0].substr(7).split('/'),
+                    uid = path.pop(),
+                    folder = path.join('/');
+                if (folder && uid) {
+                    rcmail.open_window(rcmail.url('mail/show', { _mbox: folder, _uid: uid, _rel: 'note' }));
+                }
+            }
+
+            return false;
+        });
     }
-    this.init = init;
 
     /**
      * Quote HTML entities
@@ -288,7 +355,8 @@ function rcube_kolab_notes_ui(settings)
     function edit_note(uid, action)
     {
         if (!uid) {
-            noteslist.clear_selection();
+            if (noteslist)
+                noteslist.clear_selection();
             me.selected_note = {
                 list: me.selected_list,
                 uid: null,
@@ -554,6 +622,7 @@ function rcube_kolab_notes_ui(settings)
         noteslist.clear(true);
         notesdata = {};
         tagsfilter = [];
+        update_state();
     }
 
     function filter_notes()
@@ -625,9 +694,9 @@ function rcube_kolab_notes_ui(settings)
         if (data.data.length == 1) {
             noteslist.select(data.data[0].id);
         }
-        else if (settings.selected_id) {
-            noteslist.select(settings.selected_id);
-            delete settings.selected_id;
+        else if (settings.selected_uid) {
+            noteslist.select(rcmail.html_identifier_encode(settings.selected_uid));
+            delete settings.selected_uid;
         }
         else if (me.selected_note && notesdata[me.selected_note.id]) {
             noteslist.select(me.selected_note.id);
@@ -648,7 +717,8 @@ function rcube_kolab_notes_ui(settings)
 
         var list = me.notebooks[data.list] || me.notebooks[me.selected_list];
             content = $('#notecontent').val(data.description),
-            readonly = data.readonly || !list.editable;
+            readonly = data.readonly || !list.editable,
+            attachmentslist = $(rcmail.gui_objects.notesattachmentslist).html('');
         $('.notetitle', rcmail.gui_objects.noteviewtitle).val(data.title).prop('disabled', readonly);
         $('.dates .notecreated', rcmail.gui_objects.noteviewtitle).html(Q(data.created || ''));
         $('.dates .notechanged', rcmail.gui_objects.noteviewtitle).html(Q(data.changed || ''));
@@ -679,7 +749,21 @@ function rcube_kolab_notes_ui(settings)
             checkNewEntriesCaseSensitive: false,
             autocompleteOptions: { source: tags, minLength: 0, noCheck: true },
             texts: { removeLinkTitle: rcmail.gettext('removetag', 'kolab_notes') }
-        })
+        });
+
+        if (data.links) {
+            $.each(data.links, function(i, link){
+                $('<li>').addClass('link')
+                    .addClass('message eml')
+                    .append($('<a>')
+                        .attr('href', '#show')
+                        .attr('rel', link.uri)
+                        .addClass('messagelink')
+                        .html(Q(link.subject || link.message_id || link.uri))
+                    )
+                    .appendTo(attachmentslist);
+            });
+        }
 
         if (!readonly) {
             $('.tagedit-list', rcmail.gui_objects.noteviewtitle)
@@ -922,6 +1006,10 @@ function rcube_kolab_notes_ui(settings)
 
         var savedata = get_save_data();
 
+        // copy links as they're yet immutable
+        if (me.selected_note.links)
+            savedata.links = me.selected_note.links;
+
         // do some input validation
         if (savedata.title == '') {
             alert(rcmail.gettext('entertitle', 'kolab_notes'));
@@ -1101,6 +1189,23 @@ function rcube_kolab_notes_ui(settings)
         }
     }
 
+    /**
+     * update browser location to remember current view
+     */
+    function update_state()
+    {
+        var query = { _list: me.selected_list }
+
+        if (settings.selected_uid) {
+            query._id = settings.selected_uid;
+        }
+
+        if (window.history.replaceState) {
+            window.history.replaceState({}, document.title, rcmail.url('', query));
+        }
+    }
+
+
     /*  Helper functions for drag & drop functionality of tags  */
     
     function tag_draggable_helper()
@@ -1200,7 +1305,10 @@ jQuery.fn.sortElements = (function(){
 /* notes plugin UI initialization */
 var kolabnotes;
 window.rcmail && rcmail.addEventListener('init', function(evt) {
-  kolabnotes = new rcube_kolab_notes_ui(rcmail.env.kolab_notes_settings);
-  kolabnotes.init();
+    kolabnotes = new rcube_kolab_notes_ui(rcmail.env.kolab_notes_settings);
+    if (rcmail.env.action == 'dialog-ui')
+        kolabnotes.init_dialog();
+    else
+        kolabnotes.init();
 });
 
diff --git a/plugins/kolab_notes/skins/larry/notes.css b/plugins/kolab_notes/skins/larry/notes.css
index 97a7421..96d283b 100644
--- a/plugins/kolab_notes/skins/larry/notes.css
+++ b/plugins/kolab_notes/skins/larry/notes.css
@@ -114,6 +114,10 @@
 	bottom: 0px;
 }
 
+.notesdialog #notedetailsbox {
+	left: 0;
+}
+
 .notesview #notedetailsbox .formbuttons {
 	position: absolute;
 	bottom: 0;
@@ -133,6 +137,10 @@
 	width: 100%;
 }
 
+.notesdialog #noteform {
+	bottom: 30px;
+}
+
 .notesview #notedetails {
 	padding: 8px;
 	-webkit-box-sizing: border-box;
@@ -207,14 +215,16 @@
 }
 
 .notesview #notedetailstitle .dates,
-.notesview #notedetailstitle .tagline {
+.notesview #notedetailstitle .tagline,
+.notesdialog .notebookselect label {
 	color: #999;
 	font-weight: normal;
 	font-size: 0.9em;
 	margin-top: 6px;
 }
 
-.notesview #notedetailstitle .dates {
+.notesview #notedetailstitle .dates,
+.notesview #notedetailstitle .notebookselect {
 	margin-top: 4px;
 	margin-bottom: 4px;
 }
@@ -252,6 +262,16 @@
 	color: #777;
 }
 
+.notesview #notereferences {
+	position: absolute;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	height: 27px;
+	background: #fff;
+	padding-left: 10px;
+}
+
 .notesview #notebooks li {
 	margin: 0;
 	height: 20px;
@@ -336,4 +356,17 @@
 
 .notesview .uidialog .propform #noteslist-name {
 	width: 20em;
+}
+
+.notesdialog #notesdialogheader {
+	height: auto;
+}
+
+#kolabnotesinlinegui {
+	border: 0;
+	padding: 0;
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	    -ms-box-sizing: border-box;
+	        box-sizing: border-box;
 }
\ No newline at end of file




More information about the commits mailing list