diff --git a/calendar/inc/class.calendar_uiforms.inc.php b/calendar/inc/class.calendar_uiforms.inc.php index 686d53ec04..0424d3dcd0 100644 --- a/calendar/inc/class.calendar_uiforms.inc.php +++ b/calendar/inc/class.calendar_uiforms.inc.php @@ -215,6 +215,13 @@ class calendar_uiforms extends calendar_ui notifications::errors(true); $messages = null; $msg_permission_denied_added = false; + + // We'd like to just refresh the data as that's the fastest, but some changes + // affect more than just one event widget, so require a full refresh. + // $update_type is one of the update types + // (add, edit, update, delete) + $update_type = 'update'; + list($button) = @each($content['button']); if (!$button && $content['action']) $button = $content['action']; // action selectbox unset($content['button']); unset($content['action']); @@ -247,6 +254,7 @@ class calendar_uiforms extends calendar_ui unset($content['recur_exception'][$key]); $content['recur_exception'] = array_values($content['recur_exception']); } + $update_type = 'edit'; } // delete an alarm if ($content['alarm']['delete_alarm']) @@ -691,6 +699,7 @@ class calendar_uiforms extends calendar_ui unset($recur_event['start']); unset($recur_event['end']); // no update necessary unset($recur_event['alarm']); // unsetting alarms too, as they cant be updated without start! $this->bo->update($recur_event,true); // no conflict check here +foreach($recur_event as $_k => $_v) error_log($_k . ': ' . array2string($_v)); unset($recur_event); unset($event['edit_single']); // if we further edit it, it's just a single event unset($preserv['edit_single']); @@ -701,6 +710,7 @@ class calendar_uiforms extends calendar_ui $event['reference'] = $event['recurrence'] = 0; $event['uid'] = $content['uid']; } + $update_type = 'edit'; } else // we edited a non-reccuring event or the whole series { @@ -708,6 +718,8 @@ class calendar_uiforms extends calendar_ui { if ($event['recur_type'] != MCAL_RECUR_NONE) { + $update_type = 'edit'; + // we edit a existing series event if ($event['start'] != $old_event['start'] || $event['whole_day'] != $old_event['whole_day']) @@ -851,6 +863,7 @@ class calendar_uiforms extends calendar_ui // series moved by splitting in two --> move alarms and exceptions if ($old_event && $old_event['id'] != $event['id']) { + $update_type = 'edit'; foreach ((array)$old_alarms as $alarm) { // check if alarms still needed in old event, if not delete it @@ -919,7 +932,7 @@ class calendar_uiforms extends calendar_ui } $response = egw_json_response::get(); - if($response) + if($response && $update_type == 'update') { // Directly update stored data. If event is still visible, it will // be notified & update itself. @@ -935,7 +948,7 @@ class calendar_uiforms extends calendar_ui } $msg = $message . ($msg ? ', ' . $msg : ''); - egw_framework::refresh_opener($msg, 'calendar', $event['id']); + egw_framework::refresh_opener($msg, 'calendar', $event['id'], $event['recur_type'] ? 'edit' : $update_type); // writing links for new entry, existing ones are handled by the widget itself if (!$content['id'] && is_array($content['link_to']['to_id'])) { @@ -2640,12 +2653,42 @@ class calendar_uiforms extends calendar_ui $d->setUser(); } $event = $this->bo->read($eventId, $d, true); - $preserv['actual_date'] = $d; // remember the date clicked - // For DnD, always create an exception + // For DnD, create an exception if they gave the date $this->_create_exception($event,$preserv); unset($event['id']); $date = $d->format('ts'); + + $conflicts = $this->bo->update($event,false,true,false,true,$messages); + if (!is_array($conflicts) && $conflicts) + { + // now we need to add the original start as recur-execption to the series + $recur_event = $this->bo->read($event['reference']); + $recur_event['recur_exception'][] = $this->bo->date2ts($targetDateTime); + // check if we need to move the alarms, because they are next on that exception + foreach($recur_event['alarm'] as $id => $alarm) + { + if ($alarm['time'] == $content['edit_single'] - $alarm['offset']) + { + $rrule = calendar_rrule::event2rrule($recur_event, true); + foreach ($rrule as $time) + { + if ($content['edit_single'] < $time->format('ts')) + { + $alarm['time'] = $time->format('ts') - $alarm['offset']; + $this->bo->save_alarm($event['reference'], $alarm); + break; + } + } + } + } + unset($recur_event['start']); unset($recur_event['end']); // no update necessary + unset($recur_event['alarm']); // unsetting alarms too, as they cant be updated without start! + $this->bo->update($recur_event,true); // no conflict check here + unset($recur_event); + unset($event['edit_single']); // if we further edit it, it's just a single event + unset($preserv['edit_single']); + } } // Drag a whole day to a time @@ -2699,14 +2742,16 @@ class calendar_uiforms extends calendar_ui $response = egw_json_response::get(); if(!is_array($conflicts) && $conflicts) { - // Directly update stored data. If event is still visible, it will - // be notified & update itself. - $this->to_client($event); - $response->call('egw.dataStoreUID','calendar::'.$event['id'].($date?':'.$date:''),$event); - - if(!$sameday ) + if(!$event['recur_type'] && !$old_event['recur_type']) { - $response->call('egw.refresh', '','calendar',$event['id'],'update'); + // Directly update stored data. If event is still visible, it will + // be notified & update itself. + $this->to_client($event); + $response->call('egw.dataStoreUID','calendar::'.$event['id'].($date?':'.$date:''),$event); + } + else + { + $response->call('egw.refresh', '','calendar',$event['id'],'edit'); } } else if ($conflicts) diff --git a/calendar/js/app.js b/calendar/js/app.js index 5e41c0eaf5..0378ff0ec4 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -259,7 +259,7 @@ app.classes.calendar = AppJS.extend( { event = egw.dataGetUIDdata('calendar::'+_id); } - if(event && event.data && event.data.date) + if(_type != 'edit' && event && event.data && event.data.date) { var new_cache_id = app.classes.calendar._daywise_cache_id(event.data.date,this.state.owner) var daywise = egw.dataGetUIDdata(new_cache_id); diff --git a/calendar/js/et2_widget_event.js b/calendar/js/et2_widget_event.js index 4ba7001627..e9f7c99322 100644 --- a/calendar/js/et2_widget_event.js +++ b/calendar/js/et2_widget_event.js @@ -162,7 +162,9 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], egw.dataStoreUID(old_cache_id,old_daywise); egw.dataStoreUID(new_cache_id,new_daywise); - this._parent.removeChild(this); + // This should now cease to exist, as new events have been created + this.free(); + return; } // Copy to avoid changes, which may cause nm problems diff --git a/calendar/js/et2_widget_timegrid.js b/calendar/js/et2_widget_timegrid.js index 026e50c203..15d657de2f 100644 --- a/calendar/js/et2_widget_timegrid.js +++ b/calendar/js/et2_widget_timegrid.js @@ -414,7 +414,8 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz { // Need to refresh the event with original info to clean up var app_id = event_widget.options.value.app_id ? event_widget.options.value.app_id : event_widget.options.value.id + (event_widget.options.value.recur_type ? ':'+event_widget.options.value.recur_date : ''); - egw().dataStoreUID(app_id,event_dataGetUIDdata(app_id)); + egw().dataStoreUID('calendar::'+app_id,egw.dataGetUIDdata('calendar::'+app_id).data); + loading.remove(); return; } //Get infologID if in case if it's an integrated infolog event