12646: Display and print filed mails
authorMichael Spahn <m.spahn@metaways.de>
Mon, 13 Mar 2017 14:06:45 +0000 (15:06 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Tue, 21 Mar 2017 13:03:04 +0000 (14:03 +0100)
* adds email view to MailFiler Node edit dialog
* download attachments from edit dialog
* adds print action to grid panel

https://forge.tine20.org/view.php?id=12646

Change-Id: Ifa152c53460baebdf5778c5e0065d82f22375fb3
Reviewed-on: http://gerrit.tine20.com/customers/4333
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Filemanager/Frontend/JsonTests.php
tine20/Felamimail/js/MessageDisplayDialog.js
tine20/Filemanager/Controller/Node.php
tine20/MailFiler/MailFiler.jsb2
tine20/MailFiler/css/MailFiler.css
tine20/MailFiler/js/MailDetailsPanel.js [new file with mode: 0644]
tine20/MailFiler/js/NodeEditDialog.js
tine20/MailFiler/js/NodeGridPanel.js
tine20/Tinebase/Model/Tree/Node.php

index 0118c47..d7255f9 100644 (file)
@@ -900,7 +900,20 @@ class Filemanager_Frontend_JsonTests extends TestCase
         $this->assertTrue(is_array($result[0]['name']), 'array with container data expected: ' . print_r($result[0], TRUE));
         $this->_objects['containerids'][] = $result[0]['name']['id'];
     }
-    
+
+    /**
+     * Test if notes are correctly decorated with path field
+     */
+    public function testGetNode()
+    {
+        $node = $this->testCreateContainerNodeInPersonalFolder();
+
+        $result = Filemanager_Controller_Node::getInstance()->get($node['id']);
+
+        $this->assertTrue($result->path != "");
+        $this->assertEquals('/personal/' . Tinebase_Core::getUser()->accountLoginName . '/testcontainer', $result->path);
+    }
+
     /**
      * testDeleteContainerNode
      */
index 9d012ea..04ce712 100644 (file)
@@ -6,7 +6,7 @@
  * @copyright   Copyright (c) 2009-2013 Metaways Infosystems GmbH (http://www.metaways.de)
  */
  
-Ext.ns('Tine.Felamimail')
+Ext.ns('Tine.Felamimail');
 
 
 Tine.Felamimail.MessageDisplayDialog = Ext.extend(Tine.Felamimail.GridDetailsPanel ,{
index 87a4007..de07205 100644 (file)
@@ -180,6 +180,10 @@ class Filemanager_Controller_Node extends Tinebase_Controller_Record_Abstract
         if ($record) {
             $record->notes = Tinebase_Notes::getInstance()->getNotesOfRecord('Tinebase_Model_Tree_Node', $record->getId());
         }
+
+        $nodePath = Tinebase_Model_Tree_Node_Path::createFromStatPath($this->_backend->getPathOfNode($record, true));
+        $record->path = Tinebase_Model_Tree_Node_Path::removeAppIdFromPath($nodePath->flatpath, $this->_applicationName);
+
         return $record;
     }
     
@@ -758,7 +762,9 @@ class Filemanager_Controller_Node extends Tinebase_Controller_Record_Abstract
 
     /**
      * resolve node container and path
-     * 
+     *
+     * if a single record is given, use the resulting record set, because the referenced record is no longer updated!
+     *
      * (1) add path to records 
      * (2) replace name with container record, if node name is a container id 
      *     / path is toplevel (shared/personal with useraccount
@@ -816,6 +822,8 @@ class Filemanager_Controller_Node extends Tinebase_Controller_Record_Abstract
                 }
             }
         }
+
+        return $records;
     }
     
     /**
index 95450fe..757c902 100644 (file)
           "path": "js/"
         },
         {
+          "text": "MailDetailsPanel.js",
+          "path": "js/"
+        },
+        {
           "text": "NodeTreePanel.js",
           "path": "js/"
         },
index 116393a..9ab3bab 100644 (file)
 
 .x-btn-large .action_publish {
     background-image: url("../../images/oxygen/32x32/apps/package-network.png");
+}
+
+/* mail preview @todo make it more general and move to tinebase for use in felamimail */
+.preview-panel-mail {
+    padding: 5px;
+}
+
+.preview-panel-mail-body {
+    margin-top: 5px;
+}
+
+.mail-message-body-html,
+.preview-panel-mail-body {
+    font-size: 13px;
+    background-color: #fff;
+    padding: 5px;
+}
+
+.preview-panel-mail-body ul {
+    list-style: circle outside;
+    margin-left: 20px;
+}
+.preview-panel-mail-body ol {
+    list-style: decimal outside;
+    margin-left: 20px;
+}
+
+.preview-panel-mail-body strong {
+    font-weight: bold;
+    font-style: inherit;
+}
+
+.preview-panel-mail-body em {
+    font-style: italic;
+    font-weight: inherit;
+}
+
+.preview-panel-mail-body .x-form-textarea {
+    margin-top: 5px;
+    font: normal 13px courier;
+    border: 0;
+}
+
+.mail-edit-text-plain .x-form-textarea {
+    font-size: 13px;
+    padding-top: 5px;
+    padding-left: 5px;
 }
\ No newline at end of file
diff --git a/tine20/MailFiler/js/MailDetailsPanel.js b/tine20/MailFiler/js/MailDetailsPanel.js
new file mode 100644 (file)
index 0000000..6c6df37
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Tine 2.0
+ *
+ * @package     MailFiler
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+Ext.ns('Tine.MailFiler');
+
+/**
+ * @namespace   Tine.MailFiler
+ * @class       Tine.MailFiler.MailDetailsPanel
+ * @extends     Ext.Panel
+ *
+ * @todo: Improve this and use in Felamimail (this one is more configurable()
+ */
+Tine.MailFiler.MailDetailsPanel = Ext.extend(Ext.Panel, {
+    record: null,
+    app: null,
+    appName: null,
+    nodeRecord: null,
+
+    initComponent: function () {
+        this.app = Tine.Tinebase.appMgr.get(this.appName);
+        Tine.MailFiler.MailDetailsPanel.superclass.initComponent.call(this);
+    },
+
+    /**
+     * add on click event after render
+     * @private
+     */
+    afterRender: function () {
+        Tine.MailFiler.MailDetailsPanel.superclass.afterRender.apply(this, arguments);
+        this.body.on('click', this.onClick, this);
+    },
+
+    /**
+     * init single message template (this.tpl)
+     */
+    initTemplate: function () {
+        var me = this;
+
+        this.tpl = new Ext.XTemplate(
+            '<div class="preview-panel-mail">',
+            '<div class="preview-panel-mail-headers">',
+            '<b>' + this.app.i18n._('Subject') + ':</b> {[this.encode(values.subject)]}<br/>',
+            '<b>' + this.app.i18n._('From') + ':</b>',
+            ' {[this.showFrom(values.from_email, values.from_name, "' + this.app.i18n._('Add') + '", "'
+            + this.app.i18n._('Add contact to addressbook') + '")]}<br/>',
+            '<b>' + this.app.i18n._('Date') + ':</b> {[this.showDate(values.sent, values)]}',
+            '{[this.showRecipients(values.headers)]}',
+            '{[this.showHeaders("' + this.app.i18n._('Show or hide header information') + '")]}',
+            '</div>',
+            '<div class="preview-panel-mail-attachments">{[this.showAttachments(values.attachments, values)]}</div>',
+            '<div class="preview-panel-mail-body">{values.body}</div>',
+            '</div>', {
+                app: me.app,
+                panel: me,
+                encode: function (value) {
+                    if (value) {
+                        var encoded = Ext.util.Format.htmlEncode(value);
+                        encoded = Ext.util.Format.nl2br(encoded);
+                        // it should be enough to replace only 2 or more spaces
+                        encoded = encoded.replace(/ /g, '&nbsp;');
+
+                        return encoded;
+                    } else {
+                        return '';
+                    }
+                },
+
+                showDate: function (sent, recordData) {
+                    var date = sent ? Date.parseDate(sent, Date.patterns.ISO8601Long) : Date.parseDate(recordData.received, Date.patterns.ISO8601Long);
+                    return date.format('l') + ', ' + Tine.Tinebase.common.dateTimeRenderer(date);
+                },
+
+                showFrom: function (email, name, addText, qtip) {
+                    if (name === null || name === undefined) {
+                        return '';
+                    }
+
+                    var result = this.encode(name + ' <' + email + '>');
+
+                    // add link with 'add to contacts'
+                    var id = Ext.id() + ':' + email;
+
+                    var nameSplit = name.match(/^"*([^,^ ]+)(,*) *(.+)/i);
+                    var firstname = (nameSplit && nameSplit[1]) ? nameSplit[1] : '';
+                    var lastname = (nameSplit && nameSplit[3]) ? nameSplit[3] : '';
+                    if (nameSplit && nameSplit[2] == ',') {
+                        firstname = lastname;
+                        lastname = nameSplit[1];
+                    }
+
+                    id += Ext.util.Format.htmlEncode(':' + Ext.util.Format.trim(firstname) + ':' + Ext.util.Format.trim(lastname));
+                    result = '<a id="' + id + '" class="tinebase-email-link">' + result + '</a>'
+                    result += ' <span ext:qtip="' + Tine.Tinebase.common.doubleEncode(qtip) + '" id="' + id + '" class="tinebase-addtocontacts-link">[+]</span>';
+                    return result;
+                },
+
+                showHeaders: function (qtip) {
+                    var result = ' <span ext:qtip="' + Tine.Tinebase.common.doubleEncode(qtip) + '" id="' + Ext.id() + ':show" class="tinebase-showheaders-link">[...]</span>';
+                    return result;
+                },
+
+                showRecipients: function (value) {
+                    if (value) {
+                        var result = '';
+                        for (header in value) {
+                            if (value.hasOwnProperty(header) && (header == 'to' || header == 'cc' || header == 'bcc')) {
+                                result += '<br/><b>' + this.app.i18n._hidden(Ext.util.Format.capitalize(header)) + ':</b> '
+                                    + Ext.util.Format.htmlEncode(value[header]);
+                            }
+                        }
+                        return result;
+                    } else {
+                        return '';
+                    }
+                },
+
+                showAttachments: function (attachments) {
+                    var result = (attachments.length > 0) ? '<b>' + this.app.i18n._('Attachments') + ':</b> ' : '';
+
+                    for (var i = 0, id; i < attachments.length; i++) {
+                        result += '<span id="' + Ext.id() + ':' + i + '" class="tinebase-download-link">'
+                            + '<i>' + attachments[i].filename + '</i>'
+                            + ' (' + Ext.util.Format.fileSize(attachments[i].size) + ')</span> ';
+                    }
+
+                    return result;
+                }
+            });
+        this.tpl.apply(this.record);
+    },
+
+    /**
+     * on click for attachment download / compose dlg / edit contact dlg
+     *
+     * @private
+     */
+    onClick: function (e) {
+        var selectors = [
+            'span[class=tinebase-download-link]',
+            'a[class=tinebase-email-link]',
+            'span[class=tinebase-addtocontacts-link]',
+            'span[class=tinebase-showheaders-link]'
+        ];
+
+        // find the correct target
+        for (var i = 0, target = null, selector = ''; i < selectors.length; i++) {
+            target = e.getTarget(selectors[i]);
+            if (target) {
+                selector = selectors[i];
+                break;
+            }
+        }
+
+        switch (selector) {
+            case 'span[class=tinebase-download-link]':
+                var idx = target.id.split(':')[1],
+                    attachment = this.record.attachments[idx];
+
+                // remove part id if set (that is the case in message/rfc822 attachments)
+                var messageId = (this.record.id.match(/_/)) ? this.record.id.split('_')[0] : this.record.id;
+
+                if (attachment['content-type'] === 'message/rfc822') {
+                    // display message
+                    var window = Tine.Felamimail.MessageDisplayDialog.openWindow({
+                        message: new Tine.Felamimail.Model.Message({
+                            id: messageId + '_' + attachment.partId
+                        })
+                    });
+
+                } else {
+                    new Ext.ux.file.Download({
+                        params: {
+                            requestType: 'HTTP',
+                            method: 'MailFiler.downloadAttachment',
+                            path: this.nodeRecord.data.path,
+                            nodeId: this.record.node_id,
+                            partId: attachment.partId
+                        }
+                    }).start();
+                }
+
+                break;
+
+            case 'a[class=tinebase-email-link]':
+                // open compose dlg
+                var email = target.id.split(':')[1];
+                var defaults = Tine.Felamimail.Model.Message.getDefaultData();
+                defaults.to = [email];
+                defaults.body = Tine.Felamimail.getSignature();
+
+                var message = new Tine.Felamimail.Model.Message(defaults, 0);
+                Tine.Felamimail.MessageEditDialog.openWindow({
+                    message: message
+                });
+                break;
+
+            case 'span[class=tinebase-addtocontacts-link]':
+                // open edit contact dlg
+
+                // check if addressbook app is available
+                if (!Tine.Addressbook || !Tine.Tinebase.common.hasRight('run', 'Addressbook')) {
+                    return;
+                }
+
+                var id = Ext.util.Format.htmlDecode(target.id);
+                var parts = id.split(':');
+
+                Tine.Addressbook.ContactEditDialog.openWindow({
+                    listeners: {
+                        scope: this,
+                        'load': function (editdlg) {
+                            editdlg.record.set('email', parts[1]);
+                            editdlg.record.set('n_given', parts[2]);
+                            editdlg.record.set('n_family', parts[3]);
+                        }
+                    }
+                });
+
+                break;
+
+            case 'span[class=tinebase-showheaders-link]':
+                // show headers
+
+                var parts = target.id.split(':');
+                var targetId = parts[0];
+                var action = parts[1];
+
+                var html = '';
+                if (action == 'show') {
+                    var messageHeaders = this.record.headers;
+
+                    for (header in messageHeaders) {
+                        if (messageHeaders.hasOwnProperty(header) && (header != 'to' || header != 'cc' || header != 'bcc')) {
+                            html += '<br/><b>' + header + ':</b> '
+                                + Ext.util.Format.htmlEncode(messageHeaders[header]);
+                        }
+                    }
+
+                    target.id = targetId + ':' + 'hide';
+
+                } else {
+                    html = ' <span ext:qtip="' + Ext.util.Format.htmlEncode(this.app.i18n._('Show or hide header information')) + '" id="'
+                        + Ext.id() + ':show" class="tinebase-showheaders-link">[...]</span>'
+                }
+
+                target.innerHTML = html;
+
+                break;
+        }
+    },
+
+    /**
+     * fills this fields with the corresponding message data
+     *
+     * @param {Tine.Tinebase.data.Record} record
+     */
+    loadRecord: function (record) {
+        this.record = record.data.hasOwnProperty('message') ? record.data.message : record;
+        this.nodeRecord = record;
+        this.initTemplate();
+        this.update(this.record);
+    }
+});
index 9734bed..d58349c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Tine 2.0
- * 
+ *
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Alexander Stintzing <a.stintzing@metaways.de>
  * @copyright   Copyright (c) 2012-2014 Metaways Infosystems GmbH (http://www.metaways.de)
@@ -11,19 +11,19 @@ Ext.ns('Tine.MailFiler');
  * @namespace   Tine.MailFiler
  * @class       Tine.MailFiler.NodeEditDialog
  * @extends     Tine.widgets.dialog.EditDialog
- * 
+ *
  * <p>Node Compose Dialog</p>
  * <p></p>
- * 
+ *
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Alexander Stintzing <a.stintzing@metaways.de>
- * 
+ *
  * @param       {Object} config
  * @constructor
  * Create a new Tine.MailFiler.NodeEditDialog
  */
 Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
-    
+
     /**
      * @private
      */
@@ -35,11 +35,12 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
     evalGrants: true,
     showContainerSelector: false,
     displayNotes: true,
-    
+    mailDetailsPanel: null,
+
     /**
      * @type Tine.MailFiler.DownloadLinkGridPanel
      */
-    initComponent: function() {
+    initComponent: function () {
         this.app = Tine.Tinebase.appMgr.get('MailFiler');
         this.downloadAction = new Ext.Action({
             requiredGrant: 'readGrant',
@@ -51,9 +52,9 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
             disabled: false,
             scope: this
         });
-        
+
         this.tbarItems = [this.downloadAction];
-        
+
         Tine.MailFiler.NodeEditDialog.superclass.initComponent.call(this);
     },
     /**
@@ -66,21 +67,23 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
             return this.record.data.type == 'folder' ? this.app.i18n._('Folder') : this.app.i18n._('File');
         }
     },
-    
+
     /**
      * executed when record is loaded
      * @private
      */
-    onRecordLoad: function() {
+    onRecordLoad: function () {
         Tine.MailFiler.NodeEditDialog.superclass.onRecordLoad.apply(this, arguments);
-        
+
         this.window.setTitle(this.getFittingTypeTranslation(true));
+
+        this.mailDetailsPanel.loadRecord(this.record);
     },
-    
+
     /**
      * download file
      */
-    onDownload: function() {
+    onDownload: function () {
         var downloader = new Ext.ux.file.Download({
             params: {
                 method: 'MailFiler.downloadFile',
@@ -90,62 +93,70 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
             }
         }).start();
     },
-    
+
     /**
      * returns dialog
      * @return {Object}
      * @private
      */
-    getFormItems: function() {
+    getFormItems: function () {
         var formFieldDefaults = {
-            xtype:'textfield',
+            xtype: 'textfield',
             anchor: '100%',
             labelSeparator: '',
             columnWidth: .5,
             readOnly: true,
             disabled: true
         };
-        
+
+        this.mailDetailsPanel = new Tine.MailFiler.MailDetailsPanel({
+            appName: this.appName
+        });
+
         return {
             xtype: 'tabpanel',
             border: false,
-            plain:true,
+            plain: true,
             plugins: [{
-                ptype : 'ux.tabpanelkeyplugin'
+                ptype: 'ux.tabpanelkeyplugin'
             }],
             activeTab: 0,
             border: false,
-            items:[{
+            items: [{
                 title: this.getFittingTypeTranslation(false),
-                autoScroll: true,
                 border: false,
                 frame: true,
                 layout: 'border',
                 items: [{
                     region: 'center',
-                    layout: 'hfit',
+                    layout: 'vbox',
+                    layoutConfig: {
+                        align : 'stretch',
+                        pack  : 'start'
+                    },
                     border: false,
                     items: [{
                         xtype: 'fieldset',
                         layout: 'hfit',
-                        autoHeight: true,
+                        height: 155,
+                        // flex: 1,
                         title: this.getFittingTypeTranslation(false),
                         items: [{
                             xtype: 'columnform',
                             labelAlign: 'top',
                             formDefaults: formFieldDefaults,
                             items: [[{
-                                    fieldLabel: this.app.i18n._('Name'),
-                                    name: 'name',
-                                    allowBlank: false,
-                                    readOnly: false,
-                                    columnWidth: .75,
-                                    disabled: false
-                                }, {
-                                    fieldLabel: this.app.i18n._('Type'),
-                                    name: 'contenttype',
-                                    columnWidth: .25
-                                }],[
+                                fieldLabel: this.app.i18n._('Name'),
+                                name: 'name',
+                                allowBlank: false,
+                                readOnly: false,
+                                columnWidth: .75,
+                                disabled: false
+                            }, {
+                                fieldLabel: this.app.i18n._('Type'),
+                                name: 'contenttype',
+                                columnWidth: .25
+                            }], [
                                 Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                     userOnly: true,
                                     useAccountRecord: true,
@@ -157,7 +168,7 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
                                     name: 'creation_time',
                                     xtype: 'datefield'
                                 }
-                                ],[
+                            ], [
                                 Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                     userOnly: true,
                                     useAccountRecord: true,
@@ -169,11 +180,16 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
                                     name: 'last_modified_time',
                                     xtype: 'datefield'
                                 }
-                                ]]
+                            ]]
                         }]
-                    }
-                    
-                    ]
+                    }, {
+                        layout: 'hfit',
+                        autoScroll: true,
+                        flex: 1,
+                        items: [
+                            this.mailDetailsPanel
+                        ]
+                    }]
                 }, {
                     // activities and tags
                     layout: 'accordion',
@@ -213,21 +229,17 @@ Tine.MailFiler.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
                         })
                     ]
                 }]
-            }, 
-            new Tine.widgets.activities.ActivitiesTabPanel({
-                app: this.appName,
-                record_id: this.record.id,
-                record_model: this.appName + '_Model_' + this.recordClass.getMeta('modelName')
-                }),
+            },
+                new Tine.widgets.activities.ActivitiesTabPanel()
             ]
         };
     }
-    
+
 });
 
 /**
  * MailFiler Edit Popup
- * 
+ *
  * @param   {Object} config
  * @return  {Ext.ux.Window}
  */
@@ -240,6 +252,6 @@ Tine.MailFiler.NodeEditDialog.openWindow = function (config) {
         contentPanelConstructor: 'Tine.MailFiler.NodeEditDialog',
         contentPanelConstructorConfig: config
     });
-    
+
     return window;
 };
index 08701e0..22fd074 100644 (file)
@@ -460,6 +460,16 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             scope: this
         });
 
+        this.action_printmessage = new Ext.Action({
+            requiredGrant: 'readGrant',
+            text: this.app.i18n._('Print Message'),
+            handler: this.onPrint.createDelegate(this, []),
+            disabled: true,
+            iconCls:'action_print',
+            actionUpdater: this.updateMessageAction,
+            scope:this
+        });
+
         this.contextMenu = Tine.MailFiler.GridContextMenu.getMenu({
             nodeName: Tine.MailFiler.Model.Node.getRecordName(),
             actions: ['delete',  'download', 'edit'],
@@ -490,7 +500,8 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             this.action_goUpFolder,
             this.action_download,
             this.action_deleteRecord,
-            this.action_editFile
+            this.action_editFile,
+            this.action_printmessage
        ]);
     },
 
@@ -534,28 +545,66 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             actionUpdater: this.updateMessageAction,
             disabled: true
         });
+    },
+
+    /**
+     * Ripped off felamimail
+     *
+     * @param detailsPanel
+     */
+    onPrint: function(detailsPanel) {
+        var id = Ext.id(),
+            doc = document,
+            frame = doc.createElement('iframe');
+
+        Ext.fly(frame).set({
+            id: id,
+            name: id,
+            style: {
+                position: 'absolute',
+                width: '210mm',
+                height: '297mm',
+                top: '-10000px',
+                left: '-10000px'
+            }
+        });
+
+        doc.body.appendChild(frame);
+
+        Ext.fly(frame).set({
+            src : Ext.SSL_SECURE_URL
+        });
+
+        var doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document,
+            content = this.getDetailsPanelContentForPrinting(detailsPanel || this.detailsPanel);
+
+        doc.open();
+        doc.write(content);
+        doc.close();
 
-        //this.action_printPreview = new Ext.Action({
-        //    requiredGrant: 'readGrant',
-        //    text: this.app.i18n._('Print Preview'),
-        //    handler: this.onPrintPreview.createDelegate(this, []),
-        //    disabled:true,
-        //    iconCls:'action_printPreview',
-        //    scope:this
-        //});
-        //this.action_print = new Ext.Action({
-        //    requiredGrant: 'readGrant',
-        //    text: this.app.i18n._('Print Message'),
-        //    handler: this.onPrint.createDelegate(this, []),
-        //    disabled:true,
-        //    iconCls:'action_print',
-        //    scope:this,
-        //    menu:{
-        //        items:[
-        //            this.action_printPreview
-        //        ]
-        //    }
-        //});
+        frame.contentWindow.focus();
+        frame.contentWindow.print();
+    },
+
+    /**
+     * get detail panel content
+     *
+     * @param {Tine.Felamimail.GridDetailsPanel} details panel
+     * @return {String}
+     */
+    getDetailsPanelContentForPrinting: function(detailsPanel) {
+        // TODO somehow we have two <div class="preview-panel-felamimail"> -> we need to fix that and get the first element found
+        var detailsPanels = detailsPanel.getEl().query('.preview-panel-felamimail');
+
+        var detailsPanelContent = (detailsPanels.length > 1) ? detailsPanels[1].innerHTML : detailsPanels[0].innerHTML;
+
+        var buffer = '<html><head>';
+        buffer += '<title>' + this.app.i18n._('Print Preview') + '</title>';
+        buffer += '</head><body>';
+        buffer += detailsPanelContent;
+        buffer += '</body></html>';
+
+        return buffer;
     },
 
     onMessageReplyTo: function(toAll) {
@@ -655,7 +704,7 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
                     xtype: 'buttongroup',
                     layout: 'toolbar',
                     buttonAlign: 'left',
-                    columns: 8,
+                    columns: 9,
                     defaults: {minWidth: 60},
                     items: [
                         Ext.apply(new Ext.Button(this.action_write), {
@@ -678,6 +727,11 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
                             rowspan: 2,
                             iconAlign: 'top'
                         }),
+                        Ext.apply(new Ext.Button(this.action_printmessage), {
+                            scale: 'medium',
+                            rowspan: 2,
+                            iconAlign: 'top'
+                        }),
                         Ext.apply(new Ext.Button(this.action_editFile), {
                             scale: 'medium',
                             rowspan: 2,
@@ -722,20 +776,20 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
      * opens the edit dialog
      */
     onEditFile: function() {
-        var sel = this.getGrid().getSelectionModel().getSelections();
+        var selectionModel = this.getGrid().getSelectionModel();
 
-        if(sel.length == 1) {
-            var record = new Tine.MailFiler.Model.Node(sel[0].data);
+        if (selectionModel.getCount() === 1) {
+            var record = selectionModel.getSelected();
             var window = Tine.MailFiler.NodeEditDialog.openWindow({record: record});
+
+            window.on('saveAndClose', function() {
+                this.getGrid().store.reload();
+            }, this);
         }
-        
-        window.on('saveAndClose', function() {
-            this.getGrid().store.reload();
-        }, this);
     },
     
     /**
-     * create folder in current position
+     * create folder in current positionc
      * 
      * @param {Ext.Component} button
      * @param {Ext.EventObject} event
@@ -1007,7 +1061,7 @@ Tine.MailFiler.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
                     if(nodes[i].id == target.id) {
                         return false;
                     }
-                }
+                        }
                 
                 var targetNode = treePanel.getNodeById(target.id);
                 if(targetNode && targetNode.isAncestor(nodes[0])) {
index d0b8910..77d98ea 100644 (file)
@@ -107,8 +107,10 @@ class Tinebase_Model_Tree_Node extends Tinebase_Record_Abstract
         'revision'       => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'hash'           => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'size'           => array(Zend_Filter_Input::ALLOW_EMPTY => true),
-    // not persistent
+
+        // not persistent
         'container_name' => array(Zend_Filter_Input::ALLOW_EMPTY => true),
+
         // this is needed should be sent by / delivered to client (not persistent in db atm)
         'path'           => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'account_grants' => array(Zend_Filter_Input::ALLOW_EMPTY => true),
@@ -138,6 +140,6 @@ class Tinebase_Model_Tree_Node extends Tinebase_Record_Abstract
     public function __construct($_data = NULL, $_bypassFilters = FALSE, $_convertDates = TRUE)
     {
         $this->_filters['size'] = new Zend_Filter_Empty(0);
-        return parent::__construct($_data, $_bypassFilters, $_convertDates);
+        parent::__construct($_data, $_bypassFilters, $_convertDates);
     }
 }