Allow to copy and paste events
authorMichael Spahn <kontakt@michaelspahn.de>
Tue, 10 Feb 2015 15:38:28 +0000 (16:38 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 23 Feb 2015 10:26:04 +0000 (11:26 +0100)
 + copy once
 + paste as often as you like by click right mouse
 + introducing first kind of clipboard in tine

Change-Id: Iaf9540cf2e7405858ec77e3ae251a754a76b85a2
Reviewed-on: http://gerrit.tine20.com/customers/1641
Tested-by: Jenkins CI (http://ci.tine20.com/)
Tested-by: sstamer <s.stamer@metaways.de>
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Calendar/js/EventEditDialog.js
tine20/Calendar/js/MainScreenCenterPanel.js
tine20/Tinebase/js/widgets/dialog/EditDialog.js

index 88f2300..02af3bd 100644 (file)
@@ -473,7 +473,7 @@ Tine.Calendar.EventEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
         
         // Calendar is the only app with record based grants -> user gets edit grant for all fields when copying
         this.record.set('editGrant', true);
-        
+
         Tine.log.debug('Tine.Calendar.EventEditDialog::doCopyRecord() -> record:');
         Tine.log.debug(this.record);
     },
index 7e8fd6e..ef046b6 100644 (file)
@@ -153,10 +153,17 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
             handler: this.onCutEvent.createDelegate(this),
             iconCls: 'action_cut'
         });
+
+        this.action_copy_to = new Ext.Action({
+            requiredGrant: 'deleteGrant',
+            text: this.app.i18n._('Copy Event to clipboard'),
+            handler: this.onCopyToEvent.createDelegate(this),
+            iconCls: 'action_editcopy'
+        });
         
         this.action_cancelPasting = new Ext.Action({
             requiredGrant: 'deleteGrant',
-            text: this.app.i18n._('Stop cut & paste'),
+            text: this.app.i18n._('Stop cut / copy & paste'),
             handler: this.onCutCancelEvent.createDelegate(this),
             iconCls: 'action_cut_break'
         });
@@ -522,7 +529,7 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
      */
     onContextMenu: function (e) {
         e.stopEvent();
-        
+
         var view = this.getCalendarPanel(this.activeView).getView();
         var event = view.getTargetEvent(e);
         var datetime = view.getTargetDateTime(e);
@@ -534,6 +541,7 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         }
         
         var addAction, responseAction, copyAction;
+
         if (datetime || event) {
             var dtStart = datetime || event.get('dtstart').clone();
             if (dtStart.format('H:i') === '00:00') {
@@ -551,7 +559,6 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
                 responseAction = this.getResponseAction(event);
                 copyAction = this.getCopyAction(event);
             }
-        
         } else {
             addAction = this.action_addInNewWindow;
         }
@@ -561,15 +568,16 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         } else {
             view.getSelectionModel().clearSelections();
         }
-        
+
         var menuitems = this.recordActions.concat(addAction, responseAction || [], copyAction || []);
         
         if (event) {
-            menuitems = menuitems.concat(['-', this.action_cut, '-']);
+            this.action_copy_to.setDisabled(event.isRecurInstance() || event.isRecurException() || event.isRecurBase());
+            menuitems = menuitems.concat(['-', this.action_cut, this.action_copy_to, '-']);
         } else if (Tine.Tinebase.data.Clipboard.has('Calendar', 'Event')) {
             menuitems = menuitems.concat(['-', this.getPasteAction(datetime, Tine.Tinebase.data.Clipboard.pull('Calendar', 'Event', true)), this.action_cancelPasting, '-']);
         }
-        
+
         var ctxMenu = new Ext.menu.Menu({
             plugins: [{
                 ptype: 'ux.itemregistry',
@@ -633,14 +641,14 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
      */
     getCopyAction: function(event) {
         var copyAction = {
-            text: String.format(_('Copy {0}'), this.i18nRecordName),
+            text: String.format(this.app.i18n._('Copy {0}'), this.i18nRecordName),
             handler: this.onEditInNewWindow.createDelegate(this, ["copy", event]),
             iconCls: 'action_editcopy',
             // TODO allow to copy recurring events / exceptions
             disabled: event.isRecurInstance() || event.isRecurException() || event.isRecurBase()
         };
         
-        return copyAction;
+        return copyAction
     },
     
     checkPastEvent: function(event, checkBusyConflicts, actionType) {
@@ -1064,6 +1072,24 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         }
         Tine.Tinebase.data.Clipboard.push(event);
     },
+
+    /**
+     * Is called on copy to clipboard
+     *
+     * @param action
+     * @param event
+     */
+    onCopyToEvent: function(action, event) {
+        var panel = this.getCalendarPanel(this.activeView);
+        var selection = panel.getSelectionModel().getSelectedEvents();
+        if (Ext.isArray(selection) && selection.length === 1) {
+            event = selection[0];
+        }
+
+        event.isCopy = true;
+
+        Tine.Tinebase.data.Clipboard.push(event);
+    },
     
     /**
      * is called on cancelling cut & paste
@@ -1074,7 +1100,7 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         
         for (var index = 0; index < ids.length; index++) {
             var record = store.getAt(store.findExact('id', ids[index]));
-            if (record.ui) {
+            if (record && record.ui) {
                 record.ui.clearDirty();
             }
         }
@@ -1089,7 +1115,8 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
      */
     onPasteEvent: function(datetime) {
         var record = Tine.Tinebase.data.Clipboard.pull('Calendar', 'Event');
-        
+        var isCopy = record.isCopy;
+
         if (! record) {
             return;
         }
@@ -1097,18 +1124,40 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         var dtend   = record.get('dtend');
         var dtstart = record.get('dtstart');
         var eventLength = dtend - dtstart;
-        
-        // remove before update
-        var store = this.getStore();
-        var oldRecord = store.getAt(store.findExact('id', record.getId()));
-        if (oldRecord && oldRecord.hasOwnProperty('ui')) {
-            oldRecord.ui.remove();
+
+        if (isCopy != true) {
+            // remove before update
+            var store = this.getStore();
+            var oldRecord = store.getAt(store.findExact('id', record.getId()));
+            if (oldRecord && oldRecord.hasOwnProperty('ui')) {
+                oldRecord.ui.remove();
+            }
+        } else {
+            record = Tine.Calendar.EventEditDialog.superclass.doCopyRecordToReturn.call(this, record);
+
+            record.set('editGrant', true);
+            record.set('id', '');
+
+            // remove attender ids
+            Ext.each(record.data.attendee, function(attender) {
+                delete attender.id;
+            }, this);
         }
-        
+
         record.set('dtstart', datetime);
         record.set('dtend', new Date(datetime.getTime() + eventLength));
-        
-        this.onUpdateEvent(record);
+
+        if (isCopy == true) {
+            record.isCopy = true;
+            Tine.Tinebase.data.Clipboard.push(record);
+            if (record.ui) {
+                record.ui.clearDirty();
+            }
+
+            this.onAddEvent(record);
+        } else {
+            this.onUpdateEvent(record);
+        }
     },
     
     /**
@@ -1149,7 +1198,7 @@ Tine.Calendar.MainScreenCenterPanel = Ext.extend(Ext.Panel, {
         }
         
         Tine.log.debug('Tine.Calendar.MainScreenCenterPanel::onEditInNewWindow() - Opening event edit dialog with action: ' + action);
-        
+
         Tine.Calendar.EventEditDialog.openWindow({
             plugins: plugins ? Ext.encode(plugins) : null,
             record: Ext.encode(event.data),
index 4a6ad07..30c2ca7 100644 (file)
@@ -560,23 +560,32 @@ Tine.widgets.dialog.EditDialog = Ext.extend(Ext.FormPanel, {
     },
 
     /**
-     * copy record
+     * copy this.record record
      */
     doCopyRecord: function() {
+        this.record = this.doCopyRecordToReturn(this.record);
+    },
+
+    /**
+     * Copy record and returns "new record with same settings"
+     *
+     * @param record
+     */
+    doCopyRecordToReturn: function(record) {
         var omitFields = this.recordClass.getMeta('copyOmitFields') || [];
         // always omit id + notes + attachments
         omitFields = omitFields.concat(['id', 'notes', 'attachments', 'relations']);
-        
+
         var fieldsToCopy = this.recordClass.getFieldNames().diff(omitFields),
-            recordData = Ext.copyTo({}, this.record.data, fieldsToCopy);
+            recordData = Ext.copyTo({}, record.data, fieldsToCopy);
 
         var resetProperties = {
             alarms:    ['id', 'record_id', 'sent_time', 'sent_message'],
             relations: ['id', 'own_id', 'created_by', 'creation_time', 'last_modified_by', 'last_modified_time']
         };
-        
+
         var setProperties = {alarms: {sent_status: 'pending'}};
-        
+
         Ext.iterate(resetProperties, function(property, properties) {
             if (recordData.hasOwnProperty(property)) {
                 var r = recordData[property];
@@ -589,7 +598,7 @@ Tine.widgets.dialog.EditDialog = Ext.extend(Ext.FormPanel, {
                 }
             }
         });
-        
+
         Ext.iterate(setProperties, function(property, properties) {
             if (recordData.hasOwnProperty(property)) {
                 var r = recordData[property];
@@ -602,9 +611,10 @@ Tine.widgets.dialog.EditDialog = Ext.extend(Ext.FormPanel, {
                 }
             }
         });
-        
-        this.record = new this.recordClass(recordData, 0);
+
+        return new this.recordClass(recordData, 0);
     },
+
     
     /**
      * executed after record got updated from proxy