Calendar app runs by et2

This commit is contained in:
Hadi Nategh 2013-10-31 14:51:19 +00:00
parent cce5514771
commit 7783ec44e0
12 changed files with 574 additions and 481 deletions

View File

@ -219,8 +219,6 @@ class calendar_uiforms extends calendar_ui
{
$msg = lang('Alarm deleted');
unset($content['alarm'][$id]);
$js = "opener.location.search += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
}
else
{
@ -427,8 +425,7 @@ class calendar_uiforms extends calendar_ui
}
if (!$content['no_popup'])
{
$js = "opener.location.search += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
//we are handling refreshing for status changes on client side
}
if ($status == 'R' && $event['alarm'])
{
@ -557,19 +554,6 @@ class calendar_uiforms extends calendar_ui
case 'infolog':
if ($event['id'] && !$this->bo->check_perms(EGW_ACL_EDIT,$event))
{
switch ($button)
{
case 'sendrequest':
case 'mail': // just mail without edit-rights is ok
$js = $this->custom_mail($event,false,($button=='sendrequest'));
break 2;
case 'print': // just print without edit-rights is ok
$js = $this->custom_print($event,false);
break 2;
case 'infolog': // create infolog without edit-rights is ok
$this->create_infolog($event['id']);
break 2;
}
$msg = lang('Permission denied');
$button = '';
break;
@ -874,23 +858,6 @@ class calendar_uiforms extends calendar_ui
{
egw_link::link('calendar',$event['id'],$content['link_to']['to_id']);
}
$js = "opener.location.search += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
if ($button == 'print')
{
$js = $this->custom_print($event,!$content['id'])."\n".$js; // first open the new window and then update the view
}
if ($button == 'mail' || $button == 'sendrequest')
{
$js = $this->custom_mail($event,!$content['id'],($button=='sendrequest'))."\n".$js; // first open the new window and then update the view
}
if ($button == 'infolog')
{
$this->create_infolog($event['id']);
}
}
else
{
@ -901,8 +868,7 @@ class calendar_uiforms extends calendar_ui
case 'cancel':
if($content['cancel_needs_refresh'])
{
$js = "opener.location.search += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
egw_framework::refresh_opener($msg, 'calendar');
}
break;
@ -921,14 +887,13 @@ class calendar_uiforms extends calendar_ui
{
$msg = lang('Event deleted');
}
$js = "opener.location += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
}
break;
case 'freetime':
// the "click" has to be in onload, to make sure the button is already created
$GLOBALS['egw']->js->set_onload("document.getElementsByName('exec[freetime]')[0].click();");
$event['button_was'] = $button;
break;
case 'add_alarm':
@ -961,8 +926,7 @@ class calendar_uiforms extends calendar_ui
$event['alarm'][$alarm_id] = $alarm;
$msg = lang('Alarm added');
$js = "opener.location.search += (opener.location.search?'&msg=':'?msg=')+'".
addslashes($msg)."';";
egw_framework::refresh_opener($msg,'calendar', $event['id'], 'update');
}
else
{
@ -994,12 +958,12 @@ class calendar_uiforms extends calendar_ui
'msg' => $msg,
));
}
$js .= 'window.close();';
echo "<html><body onload=\"$js\"></body></html>\n";
egw_framework::window_close();
common::egw_exit();
}
unset($event['no_notifications']);
return $this->edit($event,$preserv,$msg,$js,$event['id'] ? $event['id'] : $content['link_to']['to_id']);
return $this->edit($event,$preserv,$msg,$event['id'] ? $event['id'] : $content['link_to']['to_id']);
}
/**
@ -1039,7 +1003,7 @@ class calendar_uiforms extends calendar_ui
* @param boolean $added
* @return string javascript window.open command
*/
function custom_mail($event,$added,$asrequest=false)
function ajax_custom_mail($event,$added,$asrequest=false)
{
$to = array();
@ -1089,7 +1053,7 @@ class calendar_uiforms extends calendar_ui
fclose($f);
}
$vars = array(
'menuaction' => 'felamimail.uicompose.compose',
'menuaction' => 'mail.mail_compose.compose',
'mimeType' => 'plain', // force type to plain as thunderbird seems to try to be smart while parsing html messages with ics attachments
'preset[to]' => $to,
'preset[subject]' => $subject,
@ -1100,39 +1064,8 @@ class calendar_uiforms extends calendar_ui
'preset[size]' => filesize($ics_file),
);
if ($asrequest) $vars['preset[msg]'] = lang('You attempt to mail a meetingrequest to the recipients above. Depending on the client this mail is opened with, the recipient may or may not see the mailbody below, but only see the meeting request attached.');
return "window.open('".egw::link('/index.php',$vars)."','_blank','width=700,height=700,scrollbars=yes,status=no');";
}
/**
* return javascript to open compose window to print the event
*
* @param array $event
* @param boolean $added
* @return string javascript window.open command
*/
function custom_print($event,$added)
{
$vars = array(
'menuaction' => 'calendar.calendar_uiforms.edit',
'cal_id' => $event['id'],
'print' => true,
);
return "window.open('".egw::link('/index.php',$vars)."','_blank','width=700,height=700,scrollbars=yes,status=no');";
}
/**
* Open new infolog window to convert event to an infolog
*
* @param array|int $event event or id
*/
function create_infolog($event,$added)
{
$vars = array(
'menuaction' => 'infolog.infolog_ui.edit',
'action' => 'calendar',
'action_id' => is_array($event) ? $event['id'] : $event,
);
egw::redirect_link('/index.php', $vars);
$response = egw_json_response::get();
$response->call('app.calendar.custom_mail', $vars);
}
/**
@ -1176,10 +1109,9 @@ class calendar_uiforms extends calendar_ui
* no_popup boolean use a popup or not
* edit_single int timestamp of single event edited, unset/null otherwise
* @param string $msg='' msg to display
* @param string $js='window.focus();' javascript to include in the page
* @param mixed $link_to_id='' $content from or for the link-widget
*/
function edit($event=null,$preserv=null,$msg='',$js = 'window.focus();',$link_to_id='')
function edit($event=null,$preserv=null,$msg='',$link_to_id='')
{
$sel_options = array(
'recur_type' => &$this->bo->recur_types,
@ -1251,7 +1183,7 @@ class calendar_uiforms extends calendar_ui
{
if (!$preserv['no_popup'])
{
$js = "alert('".lang('Permission denied')."'); window.close();";
egw_framework::window_close(lang('Permission denied'));
}
else
{
@ -1328,7 +1260,7 @@ class calendar_uiforms extends calendar_ui
}
}
}
$etpl = new etemplate();
$etpl = new etemplate_new();
if (!$etpl->read($preserv['template']))
{
$etpl->read($preserv['template'] = 'calendar.edit');
@ -1357,40 +1289,13 @@ class calendar_uiforms extends calendar_ui
}
elseif(egw_vfs::lock($lock_path,$preserv['lock_token'],$locktime,$lock_owner,$scope='shared',$type='write',false,false))
{
// install ajax handler to unlock the entry again, if the window get's closed by the user (X of window or our [Close] button)
$GLOBALS['egw']->js->set_onunload("if (do_onunload) xajax_doXMLHTTPsync('calendar.calendar_uiforms.ajax_unlock',$event[id],'$preserv[lock_token]');");
$GLOBALS['egw']->js->set_onload("replace_eTemplate_onsubmit();");
// overwrite submit method of eTemplate form AND onSubmit event, to switch off onUnload handler for regular form submits
// selectboxes use onchange(this.form.submit()) which does not fire onSubmit event --> need to overwrite submit() method
// regular submit buttons dont call submit(), but trigger onSubmit event --> need to overwrite onSubmit event
$GLOBALS['egw_info']['flags']['java_script'] .= '
<script>
var do_onunload = true;
function replace_eTemplate_onsubmit()
{
document.eTemplate.old_submit = document.eTemplate.submit;
document.eTemplate.submit = function()
{
do_onunload = false;
this.old_submit();
}
document.eTemplate.old_onsubmit = document.eTemplate.onsubmit;
document.eTemplate.onsubmit = function()
{
do_onunload = false;
this.old_onsubmit();
}
}
</script>
';
//We handle AJAX_REQUEST in client-side for unlocking the locked entry, in case of closing the entry by X button or close button
}
else
{
$msg .= ' '.lang("Can't aquire lock!"); // eg. an exclusive lock via CalDAV ...
$view = true;
}
//echo "<p>lock_path=$lock_path, lock_owner=$lock_owner, lock_token=$preserv[lock_token], msg=$msg</p>\n";
}
$content = array_merge($event,array(
'link_to' => array(
@ -1573,22 +1478,13 @@ function replace_eTemplate_onsubmit()
}
else
{
//Add the check_recur_type function to onload, which disables recur_data function
//if recur_type is not repeat weekly.
$onload = "check_recur_type('recur_type',2);";
// We hide the enddate if one of our predefined durations fits
// the call to set_style_by_class has to be in onload, to make sure the function and the element is already created
$onload .= " \$j('table.end_hide').css('display','".($content['duration'] && isset($sel_options['duration'][$content['duration']]) ? 'none' : 'block')."');";
$GLOBALS['egw']->js->set_onload($onload);
$readonlys['recur_exception'] = true;
if ($event['recur_type'] != MCAL_RECUR_NONE)
{
$readonlys['recur_exception'] = !count($content['recur_exception']); // otherwise we get a delete button
$onclick =& $etpl->get_cell_attribute('button[delete]','onclick');
$onclick = str_replace('Delete this event','Delete this series of recuring events',$onclick);
//$onclick =& $etpl->get_cell_attribute('button[delete]','onclick');
//$onclick = str_replace('Delete this event','Delete this series of recuring events',$onclick);
}
elseif ($event['reference'] != 0)
{
@ -1663,16 +1559,10 @@ function replace_eTemplate_onsubmit()
: ($view ? ($content['edit_single'] ? lang('View exception') : ($content['recur_type'] ? lang('View series') : lang('View')))
: ($content['edit_single'] ? lang('Create exception') : ($content['recur_type'] ? lang('Edit series') : lang('Edit')))));
//Function for disabling the recur_data multiselect box
$js .=
"\nfunction check_recur_type(_id, _ind)\n{\nif(document.getElementById('exec['+_id+']')) {
egw_set_checkbox_multiselect_enabled('recur_data',".
"document.getElementById('exec['+_id+']').selectedIndex == _ind);\n\n}\n}\n";
$GLOBALS['egw_info']['flags']['java_script'] .= "<script>\n$js\n</script>\n";
$content['cancel_needs_refresh'] = (bool)$_GET['cancel_needs_refresh'];
if (!empty($preserv['lock_token'])) $content['lock_token'] = $preserv['lock_token'];
// non_interactive==true from $_GET calls immediate save action without displaying the edit form
if(isset($_GET['non_interactive']) && (bool)$_GET['non_interactive'] === true)
{
@ -1701,9 +1591,6 @@ function replace_eTemplate_onsubmit()
{
egw_vfs::unlock($lock_path,$token,false);
}
$response = new xajaxResponse();
$response->addScript('window.close();');
return $response->getXML();
}
/**
@ -1879,12 +1766,12 @@ function replace_eTemplate_onsubmit()
$event['ics_method'] = $readonlys['ics_method'] = strtolower($ical_method);
$event['ics_method_label'] = strtolower($ical_method) == 'request' ?
lang('Meeting request') : lang('Reply to meeting request');
$tpl = new etemplate('calendar.meeting');
$tpl = new etemplate_new('calendar.meeting');
$tpl->exec('calendar.calendar_uiforms.meeting', $event, $sel_options, $readonlys, $event, 2);
}
/**
* displays a sheduling conflict
* displays a scheduling conflict
*
* @param array $event
* @param array $conflicts array with conflicting events, the events are not garantied to be readable by the user!
@ -1892,7 +1779,7 @@ function replace_eTemplate_onsubmit()
*/
function conflicts($event,$conflicts,$preserv)
{
$etpl = CreateObject('etemplate.etemplate','calendar.conflicts');
$etpl = CreateObject('etemplate.etemplate_new','calendar.conflicts');
foreach($conflicts as $k => $conflict)
{
@ -1943,7 +1830,7 @@ function replace_eTemplate_onsubmit()
*/
function ajax_freetimesearch(array $edit_content)
{
$response = new xajaxResponse();
$response = egw_json_response::get();
//$response->addAlert(__METHOD__.'('.array2string($edit_content).')');
if ($edit_content['duration'])
@ -1994,14 +1881,12 @@ function replace_eTemplate_onsubmit()
egw_cache::setSession('calendar','freetimesearch_args_'.(int)$edit_content['id'],$content);
//menuaction=calendar.calendar_uiforms.freetimesearch&values2url('start,end,duration,participants,recur_type,whole_day'),ft_search,700,500
$link = egw::link('/index.php',array(
'menuaction' => 'calendar.calendar_uiforms.freetimesearch',
'cal_id' => $edit_content['id'],
));
$link = 'calendar.calendar_uiforms.freetimesearch&cal_id='. $edit_content['id'];
$response->addScriptCall('egw_openWindowCentered2',$link,'ft_search',700,500);
$response->call('app.calendar.freetime_search_popup',$link);
//$response->addScriptCall('egw_openWindowCentered2',$link,'ft_search',700,500);
return $response->getXML();
}
/**
@ -2019,8 +1904,7 @@ function replace_eTemplate_onsubmit()
*/
function freetimesearch($content = null)
{
$etpl = new etemplate('calendar.freetimesearch');
$etpl = new etemplate_new('calendar.freetimesearch');
$sel_options['search_window'] = array(
7*DAY_s => lang('one week'),
14*DAY_s => lang('two weeks'),
@ -2033,6 +1917,12 @@ function replace_eTemplate_onsubmit()
// get content from session (and delete it immediatly)
$content = egw_cache::getSession('calendar','freetimesearch_args_'.(int)$_GET['cal_id']);
egw_cache::unsetSession('calendar','freetimesearch_args_'.(int)$_GET['cal_id']);
//Since the start_time and end_time from calendar_user_preferences are numbers, not timestamp, in order to show them on date-timeonly
//widget we need to convert them from numbers to timestamps, only for the first time when we have template without content
$sTime = $content['start_time'];
$eTime = $content['end_time'];
$content['start_time'] = strtotime(((strlen($content['start_time'])<2)?("0".$content['start_time']):$content['start_time']).":00");
$content['end_time'] = strtotime(((strlen($content['end_time'])<2)?("0".$content['end_time']):$content['end_time']).":00");
// pick a searchwindow fitting the duration (search for a 10 day slot in a one week window never succeeds)
foreach($sel_options['search_window'] as $window => $label)
@ -2047,83 +1937,30 @@ function replace_eTemplate_onsubmit()
else
{
if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
if (is_array($content['freetime']['select']))
$weekds = 0;
foreach ($content['weekdays'] as $keys =>$wdays)
{
list($selected) = each($content['freetime']['select']);
//echo "$selected = ".date('D d.m.Y H:i',$content['freetime'][$selected]['start']);
$start = (int) $content['freetime'][$selected]['start'];
$end = $start + $content['duration'];
/**
* ToDo: make this an eTemplate function to transmit content back to the opener
*/
$fields_to_set = array(
'exec[start][str]' => date($this->common_prefs['dateformat'],$start),
'exec[start][i]' => (int) date('i',$start),
'exec[end][str]' => date($this->common_prefs['dateformat'],$end),
'exec[end][i]' => (int) date('i',$end),
'exec[duration]' => $content['duration'],
);
if ($this->common_prefs['timeformat'] == 12)
{
$fields_to_set += array(
'exec[start][H]' => date('h',$start),
'exec[start][a]' => date('a',$start),
'exec[end][H]' => date('h',$end),
'exec[end][a]' => date('a',$end),
);
}
else
{
$fields_to_set += array(
'exec[start][H]' => (int) date('H',$start),
'exec[end][H]' => (int) date('H',$end),
);
}
echo "<html>
<script>
var fields = Array('".implode("','",array_keys($fields_to_set))."');
var values = Array('".implode("','",$fields_to_set)."');
for (i=0; i < fields.length; ++i) {
elements = opener.document.getElementsByName(fields[i]);
if (elements) {
if (elements.length == 1)
elements[0].value = values[i];
else
for (n=0; n < elements.length; ++n) {
if (elements[n].value == values[i]) elements[n].checked = true;
}
}
}
window.close();
</script>
</html>\n";
exit;
$weekds = $weekds + $wdays;
}
//split_freetime_daywise function expects to get start_time and end_time values as string numbers, only "hour", therefore, since the date-timeonly widget returns
//always timestamp, we need to convert them to only "hour" string numbers.
$sTime = date('H', $content['start_time']);
$eTime = date('H', $content['end_time']);
}
if ($content['recur_type'])
{
$content['msg'] .= lang('Only the initial date of that recuring event is checked!');
}
$content['freetime'] = $this->freetime($content['participants'],$content['start'],$content['start']+$content['search_window'],$content['duration'],$content['cal_id']);
$content['freetime'] = $this->split_freetime_daywise($content['freetime'],$content['duration'],$content['weekdays'],$content['start_time'],$content['end_time'],$sel_options);
$content['freetime'] = $this->split_freetime_daywise($content['freetime'],$content['duration'],(is_array($content['weekdays'])?$weekds:$content['weekdays']),$sTime,$eTime,$sel_options);
//echo "<pre>".print_r($content,true)."</pre>\n";
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('freetime search');
// let the window popup, if its already there
$GLOBALS['egw_info']['flags']['java_script'] .= "<script>\nwindow.focus();\n</script>\n";
if (!is_object($GLOBALS['egw']->js))
{
$GLOBALS['egw']->js = CreateObject('phpgwapi.javascript');
}
$sel_options['duration'] = $this->durations;
if ($content['duration'] && isset($sel_options['duration'][$content['duration']])) $content['end'] = '';
// We hide the enddate if one of our predefined durations fits
// the call to set_style_by_class has to be in onload, to make sure the function and the element is already created
$GLOBALS['egw']->js->set_onload("\$j('table.end_hide').css('visibility','".($content['duration'] && isset($sel_options['duration'][$content['duration']]) ? 'hidden' : 'visible')."');");
$etpl->exec('calendar.calendar_uiforms.freetimesearch',$content,$sel_options,'',array(
$etpl->exec('calendar.calendar_uiforms.freetimesearch',$content,$sel_options,NULL,array(
'participants' => $content['participants'],
'cal_id' => $content['cal_id'],
'recur_type' => $content['recur_type'],
@ -2275,7 +2112,7 @@ function replace_eTemplate_onsubmit()
$end_date = $e-$daybegin > DAY_s ? lang(date('l',$e)).' '.date($this->common_prefs['dateformat'],$e).' ' : '';
$times[$s] = date($time_format,$s).' - '.$end_date.date($time_format,$e);
}
$sel_options[$n.'[start]'] = $times;
$sel_options[$n.'start'] = $times;
}
}
return $freetime_daywise;
@ -2343,7 +2180,7 @@ function replace_eTemplate_onsubmit()
$content['msg'] = $msg;
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('iCal Export');
$etpl = new etemplate('calendar.export');
$etpl = new etemplate_new('calendar.export');
$etpl->exec('calendar.calendar_uiforms.export',$content);
}
@ -2383,7 +2220,7 @@ function replace_eTemplate_onsubmit()
'msg' => $msg,
);
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('iCal Import');
$etpl = new etemplate('calendar.import');
$etpl = new etemplate_new('calendar.import');
$etpl->exec('calendar.calendar_uiforms.import',$content);
}
@ -2449,7 +2286,7 @@ function replace_eTemplate_onsubmit()
$content['rows'][] = array('cat_id' => '');
$GLOBALS['egw_info']['flags']['app_header'] = lang('Calendar').' - '.lang('Category ACL');
$tmp = new etemplate('calendar.cat_acl');
$tmp = new etemplate_new('calendar.cat_acl');
$tmp->exec('calendar.calendar_uiforms.cat_acl',$content,null,$readonlys,$preserv);
}

View File

@ -95,7 +95,7 @@ class calendar_uilist extends calendar_ui
if ($_GET['msg']) $msg .= $_GET['msg'];
if ($this->group_warning) $msg .= $this->group_warning;
$etpl = new etemplate('calendar.list');
$etpl = new etemplate_new('calendar.list');
// Handle merge from sidebox
if($_GET['merge'])
@ -157,7 +157,7 @@ class calendar_uilist extends calendar_ui
'order' => 'cal_start',// IO name of the column to sort after (optional for the sortheaders)
'sort' => 'ASC',// IO direction of the sort: 'ASC' or 'DESC'
'default_cols' => '!week,weekday,cal_title,cal_description,recure,cal_location,cal_owner,cat_id,pm_id,legacy_actions',
'filter_onchange' => "set_style_by_class('table','custom_hide','visibility',this.value == 'custom' ? 'visible' : 'hidden'); if (this.value != 'custom') this.form.submit();",
'filter_onchange' => "app.calendar.filter_change",
'header_left' => 'calendar.list.dates',
'row_id' => 'row_id', // set in get rows "$event[id]:$event[recur_date]"
'actions' => $this->get_actions(),
@ -188,7 +188,7 @@ class calendar_uilist extends calendar_ui
$html = $etpl->exec('calendar.calendar_uilist.listview',$content,$sel_options,$readonlys,array(),$home ? -1 : 0);
// Not sure why this has to be echoed instead of appended, but that's what works.
echo calendar_uiviews::edit_series();
//echo calendar_uiviews::edit_series();
return $html;
}
@ -290,7 +290,6 @@ class calendar_uilist extends calendar_ui
$label = lang('Before %1',$this->bo->long_date($this->date));
break;
case 'custom':
$GLOBALS['egw']->js->set_onload("set_style_by_class('table','custom_hide','visibility','visible');");
$this->first = $search_params['start'] = $params['startdate'];
$this->last = $search_params['end'] = strtotime('+1 day', $params['enddate'])-1;
$label = $this->bo->long_date($this->first,$this->last);
@ -456,10 +455,8 @@ class calendar_uilist extends calendar_ui
unset($app);
unset($app_id);
}
// set js_calendar_integration object, for app.js cal_open() function
$GLOBALS['egw_info']['flags']['java_script'] = '<script type="text/javascript">
var js_integration_data='.json_encode($js_integration_data).';
</script>';
// set js_calendar_integration object, to use it in app.js cal_open() function
$params['js_integration_data'] = json_encode($js_integration_data);
$wv=0;
$dv=0;
@ -801,7 +798,7 @@ class calendar_uilist extends calendar_ui
'url' => 'menuaction=calendar.calendar_uiforms.edit&cal_id=$id',
'popup' => egw_link::get_registry('calendar', 'view_popup'),
'group' => $group=1,
'onExecute' => 'javaScript:cal_open',
'onExecute' => 'javaScript:app.calendar.cal_open',
'disableClass' => 'rowNoView',
),
'copy' => array(
@ -843,7 +840,7 @@ class calendar_uilist extends calendar_ui
'url' => 'menuaction=filemanager.filemanager_ui.index&path=/apps/$app/$id',
'group' => $group,
'allowOnMultiple' => false,
'onExecute' => 'javaScript:cal_fix_app_id',
'onExecute' => 'javaScript:app.calendar.cal_fix_app_id',
'disableClass' => 'rowNoView',
);
}
@ -867,7 +864,7 @@ class calendar_uilist extends calendar_ui
'group' => $group,
'allowOnMultiple' => false,
'hideOnDisabled' => true, // show only one timesheet action in context menu
'onExecute' => 'javaScript:cal_fix_app_id',
'onExecute' => 'javaScript:app.calendar.cal_fix_app_id',
'popup' => egw_link::get_registry('timesheet', 'add_popup'),
);
$actions['timesheet-add'] = array( // automatic add for multiple events
@ -893,9 +890,7 @@ class calendar_uilist extends calendar_ui
++$group;
$actions['delete'] = array(
'caption' => 'Delete',
'confirm' => 'Delete this event',
'confirm_multiple' => 'Delete these entries',
'onExecute' => 'javaScript:cal_delete',
'onExecute' => 'javaScript:app.calendar.cal_delete',
'group' => $group,
'disableClass' => 'rowNoDelete',
);
@ -904,11 +899,10 @@ class calendar_uilist extends calendar_ui
{
$actions['undelete'] = array(
'caption' => 'Un-delete',
'onExecute' => 'javaScript:cal_delete',
'onExecute' => 'javaScript:app.calendar.cal_delete',
'icon' => 'revert',
'hint' => 'Recover this event',
'group' => $group,
'enabled' => 'javaScript:nm_enableClass',
'enableClass' => 'rowDeleted',
'hideOnDisabled' => true,
);

View File

@ -360,7 +360,6 @@ class calendar_uiviews extends calendar_ui
$content =& $this->plannerWidget($events,$this->first,$this->last,$this->sortby != 'category' ? $this->sortby : (int) $this->cat_id);
$content .= $this->edit_series();
if (!$home)
{
@ -395,7 +394,6 @@ class calendar_uiviews extends calendar_ui
{
if ($this->debug > 0) $this->bo->debug_message('uiviews::year date=%2',True,$this->date);
$content = $this->edit_series();
$this->_month_align_year($this->first,$this->last);
@ -675,7 +673,6 @@ class calendar_uiviews extends calendar_ui
'end' => $this->last,
)+$this->search_params);
$content = $this->edit_series();
// we add DAY_s/2 to $this->first (using 12h), to deal with daylight saving changes
for ($week_start = $this->first; $week_start < $this->last; $week_start = strtotime("+1 week",$week_start))
{
@ -885,7 +882,6 @@ class calendar_uiviews extends calendar_ui
count($users) * $this->cal_prefs['interval'],400 / count($users),'','',$uid);
}
}
$content .= $this->edit_series();
if (!$home)
{
@ -970,7 +966,6 @@ class calendar_uiviews extends calendar_ui
$cols[0] =& $this->timeGridWidget($this->tagWholeDayOnTop($dayEvents),$this->cal_prefs['interval'],450,'','',$owner);
$cols[0] .= $this->edit_series();
// only show todo's for a single user
if (count($users) == 1 && ($todos = $this->get_todos($todo_label)) !== false)
@ -1004,7 +999,6 @@ class calendar_uiviews extends calendar_ui
else
{
$content = $this->timeGridWidget($this->bo->search($this->search_params),$this->cal_prefs['interval'],300);
$content .= $this->edit_series();
// make wz_dragdrop elements work
if(is_object($this->dragdrop)) { $this->dragdrop->setJSCode(); }
@ -1013,75 +1007,6 @@ class calendar_uiviews extends calendar_ui
}
}
/**
* Return HTML and Javascript to query user about editing an event series or create an exception
*
* Layout is defined in eTemplate 'calendar.edit_series'
*
* @param string $link=null url without cal_id and date GET parameters, default calendar.calendar_uiforms.edit
* @param string $target='_blank' target
* @return string
*/
function edit_series($link=null,$target='_blank')
{
if (is_null($link)) $link = egw::link('/index.php',array('menuaction'=>'calendar.calendar_uiforms.edit'));
$tpl = new etemplate('calendar.edit_series');
return $tpl->show(array()).'<script type="text/javascript">
var calendar_edit_id;
var calendar_edit_date;
function edit_series(event,id,date)
{
// Coming from list, there is no event
if(arguments.length == 2)
{
date = id;
id = event;
event = null;
}
calendar_edit_id = id;
calendar_edit_date = date;
var popup = jQuery("#edit_series").show();
var row = null;
if(event)
{
// If there is a mouse event, open the popup there
popup.css({
position: "absolute",
top: event.pageY,
left: (event.pageX + popup.width() > $j(window).width() ? $j(window).width() - popup.width() : event.pageX)
});
} else if (row = jQuery("#"+id+"\\\:"+date)) {
// Open at row
popup.css({
position: "absolute",
top: row.position().top + row.height() -popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
} else {
// Open popup in the middle
popup.css({
position: "absolute",
top: $j(window).height()/2-popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
}
}
function open_edit(series)
{
document.getElementById("edit_series").style.display = "none";
var extra = "&cal_id="+calendar_edit_id+"&date="+calendar_edit_date;
if (!series) extra += "&exception=1";
'.$this->popup($link."'+extra+'").';
}
</script>';
}
/**
* Query the open ToDo's via a hook from InfoLog or any other 'calendar_include_todos' provider
*
@ -1875,7 +1800,7 @@ function open_edit(series)
{
if ($event['recur_type'] != MCAL_RECUR_NONE)
{
$popup = ' onclick="edit_series(event,'.$event['id'].','.$this->bo->date2string($event['start']).');"';
$popup = ' onclick="app.calendar.edit_series(event,'.$event['id'].','.$this->bo->date2string($event['start']).');"';
}
else
{

View File

@ -1,147 +1,499 @@
/**
* Calendar - static javaScript functions
* EGroupware - Calendar - Javascript UI
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@stylite.de>
* @package calendar
* @author Hadi Nategh <hn-AT-stylite.de>
* @copyright (c) 2008-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
/**
* Fix calendar specific id: "cal_id:recurrence" or "appId:", replacing $app and $id in url
*
* Cut away the recurrence date from id, and use app from calendar integration
*
* @param _action
* @param _senders
* UI for calendar
*
* @augments AppJS
*/
function cal_fix_app_id(_action, _senders)
app.calendar = AppJS.extend(
{
var app = 'calendar';
var id = _senders[0].id;
var matches = id.match(/^([0-9]+):([0-9]+)$/);
if (matches)
/**
* application name
*/
appname: 'calendar',
/**
* et2 widget container
*/
et2: null,
/**
* edit_series vars
*/
calendar_edit_id: null,
calendar_edit_date: null,
/**
* Constructor
*
* @memberOf app.calendar
*/
init: function()
{
id = matches[1];
}
else if (matches = id.match(/^([a-z_-]+)([0-9]+)/i))
// call parent
this._super.apply(this, arguments);
},
/**
* Destructor
*/
destroy: function()
{
app = matches[1];
id = matches[2];
}
var backup_url = _action.data.url;
delete this.et2;
// call parent
this._super.apply(this, arguments);
},
/**
* This function is called when the etemplate2 object is loaded
* and ready. If you must store a reference to the et2 object,
* make sure to clean it up in destroy().
*
* @param et2 etemplate2 Newly ready object
*/
et2_ready: function(et2)
{
// call parent
this._super.apply(this, arguments);
var content = this.et2.getArrayMgr('content');
if (typeof et2.templates['calendar.list'] != 'undefined')
{
this.filter_change();
}
if (typeof et2.templates['calendar.edit'] != 'undefined' && typeof content.data['conflicts'] == 'undefined')
{
$j(document.getElementById('calendar-edit_calendar-delete_series')).hide();
//Check if it's fallback from conflict window or it's from edit window
if (content.data['button_was'] != 'freetime')
{
this.set_enddate_visibility();
this.check_recur_type();
}
else
{
this.freetime_search();
}
//send Syncronus ajax request to the server to unlock the on close entry
//set onbeforeunload with json request to send request when the window gets close by X button
window.onbeforeunload = function () {
this.egw.json('calendar.calendar_uiforms.ajax_unlock'
, [content.data['id'],content.data['lock_token']],null,true,null,null).sendRequest(true);
};
}
//this.replace_eTemplate_onsubmit();
if (typeof et2.templates['calendar.freetimesearch'] != 'undefined')
{
this.set_enddate_visibility();
}
},
/**
* open the freetime search popup
*
*/
freetime_search_popup: function(_link)
{
this.egw.open_link(_link,'ft_search','700x500') ;
},
/**
* send an ajax request to server to set the freetimesearch window content
*
*/
freetime_search: function()
{
var content = this.et2.getArrayMgr('content').data;
content['start'] = this.et2.getWidgetById('start').get_value();
content['end'] = this.et2.getWidgetById('end').get_value();
content['duration'] = this.et2.getWidgetById('duration').get_value();
var request = this.egw.json('calendar.calendar_uiforms.ajax_freetimesearch', [content],null,null,null,null);
request.sendRequest();
},
/**
* Function for disabling the recur_data multiselect box
*
*/
check_recur_type: function()
{
var recurType = this.et2.getWidgetById('recur_type');
var recurData = this.et2.getWidgetById('recur_data');
if(recurType && recurData)
{
recurData.set_disabled(recurType.get_value() != 2);
}
},
/**
* Show/Hide end date, for both edit and freetimesearch popups,
* based on if "use end date" selected or not.
*
*/
set_enddate_visibility: function()
{
var duration = this.et2.getWidgetById('duration');
var end = this.et2.getWidgetById('end');
if (typeof duration != 'undefined' && typeof end != 'undefined')
{
end.set_disabled(duration.get_value()!=='');
}
},
/**
* handles actions selectbox in calendar edit popup
*
* @param {widget object} widget, widget "actions selectBox" in edit popup window
*/
actions_change: function(egw,widget)
{
var event = this.et2.getArrayMgr('content').data;
if (widget)
{
var id = this.et2.getArrayMgr('content').data['id'];
switch (widget.get_value())
{
case 'print':
this.egw.open_link('calendar.calendar_uiforms.edit&cal_id='+id+'&print=1','_blank','700x700');
this.et2._inst.submit();
break;
case 'mail':
this.egw.json('calendar.calendar_uiforms.ajax_custom_mail', [event, !event['id'], false],null,null,null,null).sendRequest();
this.et2._inst.submit();
break;
case 'sendrequest':
this.egw.json('calendar.calendar_uiforms.ajax_custom_mail', [event, !event['id'], true],null,null,null,null).sendRequest();
this.et2._inst.submit();
break;
case 'infolog':
this.egw.open_link('infolog.infolog_ui.edit&action=calendar&action_id='+($j.isPlainObject(event)?event['id']:event),'_self','700x600','infolog');
this.et2._inst.submit();
break;
default:
this.et2._inst.submit();
}
}
},
/**
* open mail compose popup window
*
* @param {Array} vars,
* @todo need to provide right mail compose from server to custom_mail function
*/
custom_mail: function (vars)
{
this.egw.open_link('mail.mail_compose.compose&','_blank','700x700');
},
/**
* control delete_series popup visibility
*
* @param {Array} exceptions, an array contains number of exception entries
*
*/
delete_btn: function(exceptions)
{
var content = this.et2.getArrayMgr('content').data;
if (exceptions)
{
$j(document.getElementById('calendar-edit_calendar-delete_series')).show();
}
else if (content['recur_type'] !== 0)
{
return confirm('Delete this series of recuring events');
}
else
{
return confirm('Delete this event');
}
},
/**
* print_participants_status(egw,widget)
* Handle to apply changes from status in print popup
*
* @param {widget object} widget, widget "status" in print popup window
*
*/
print_participants_status: function(egw,widget)
{
if (widget && window.opener)
{
//Parent popup window
var editPopWindow = window.opener;
if (editPopWindow)
{
//Update paretn popup window
editPopWindow.etemplate2.getByApplication('calendar')[0].widgetContainer.getWidgetById(widget.id).set_value(widget.get_value());
}
this.et2._inst.submit();
editPopWindow.opener.egw_refresh('status changed','calendar');
}
else if (widget)
{
window.egw_refresh(this.egw.lang('The original popup edit window is closed! You need to close the print window and reopen the entry again.'),'calendar');
}
},
/**
* Handles to select freetime, and replace the selected one on Start,
* and End date&time in edit calendar entry popup.
*
* @param {widget object} _widget, widget "select button" in freetime search popup window
*
*/
freetime_select: function(_egw,_widget)
{
if (_widget)
{
var content = this.et2._inst.widgetContainer.getArrayMgr('content').data;
// Make the Id from selected button by checking the index
var selectedId = _widget.id.match(/^select\[([0-9])\]$/i)[1];
var sTime = this.et2.getWidgetById(selectedId+'start');
var eTime = this.et2.getWidgetById(selectedId+'[end]');
//Catches the start time from freetime content
var str = sTime.get_value();
var end = parseInt(str) + parseInt(content['duration']);
//check the parent window is still open before to try to access it
if (window.opener)
{
var editWindowObj = window.opener.etemplate2.getByApplication('calendar')[0];
if (typeof editWindowObj != "undefined")
{
var startTime = editWindowObj.widgetContainer.getWidgetById('start');
var endTime = editWindowObj.widgetContainer.getWidgetById('end');
if (startTime && endTime)
{
startTime.set_value(str);
endTime.set_value(end);
}
}
}
else
{
alert(this.egw.lang('The original calendar edit popup is closed!'));
}
}
window.close();
},
/**
* show/hide the filter of nm list in calendar listview
*
*/
filter_change: function()
{
var filter = this.et2.getWidgetById('filter');
var dates = this.et2.getWidgetById('calendar.list.dates');
if (filter && dates)
{
dates.set_disabled(filter.value !== "custom");
}
},
/**
* this function try to fix ids which are from integrated apps
*
*/
cal_fix_app_id: function(_action, _senders)
{
var app = 'calendar';
var id = _senders[0].id;
var matches = id.match(/^([0-9]+):([0-9]+)$/);
if (matches)
{
id = matches[1];
}
else if (matches = id.match(/^([a-z_-]+)([0-9]+)/i))
{
app = matches[1];
id = matches[2];
}
var backup_url = _action.data.url;
_action.data.url = _action.data.url.replace(/(\$|%24)id/,id);
_action.data.url = _action.data.url.replace(/(\$|%24)app/,app);
nm_action(_action, _senders);
_action.data.url = backup_url; // restore url
}
nm_action(_action, _senders);
//egw.open_link( _action.data.url,'timesheet','edit');
_action.data.url = backup_url; // restore url
},
/**
* Open calendar entry, taking into accout the calendar integration of other apps
*
* calendar_uilist::get_rows sets var js_calendar_integration object
*
* @param _action
* @param _senders
*/
function cal_open(_action, _senders)
{
var id = _senders[0].id;
var matches = id.match(/^(?:calendar::)?([0-9]+):([0-9]+)$/);
var backup = _action.data;
if (matches)
/**
* Open calendar entry, taking into accout the calendar integration of other apps
*
* calendar_uilist::get_rows sets var js_calendar_integration object
*
* @param _action
* @param _senders
*
*/
cal_open: function(_action, _senders)
{
edit_series(matches[1],matches[2]);
return;
}
else if (matches = id.match(/^([a-z_-]+)([0-9]+)/i))
{
var app = matches[1];
_action.data.url = window.egw_webserverUrl+'/index.php?';
var get_params = js_integration_data[app].edit;
get_params[js_integration_data[app].edit_id] = matches[2];
for(var name in get_params)
_action.data.url += name+"="+encodeURIComponent(get_params[name])+"&";
if (js_integration_data[app].edit_popup &&
(matches = js_integration_data[app].edit_popup.match(/^(.*)x(.*)$/)))
{
_action.data.width = matches[1];
_action.data.height = matches[2];
}
else
{
_action.data.nm_action = 'location';
}
}
console.log(_action);
nm_action(_action, _senders, null, {ids: []});
_action.data = backup; // restore url, width, height, nm_action
}
/**
* Delete calendar entry, asking if you want to delete series or exception
*
*
* @param _action
* @param _senders
*/
function cal_delete(_action, _senders)
{
var backup = _action.data;
var matches = false;
// Loop so we ask if any of the selected entries is part of a series
for(var i = 0; i < _senders.length; i++)
{
var id = _senders[i].id;
if(!matches)
{
matches = id.match(/^(?:calendar::)?([0-9]+):([0-9]+)$/);
}
}
if (matches)
{
var id = matches[1];
var date = matches[2];
var popup = jQuery(document.getElementById(_action.getManager().etemplate_var_prefix + '[' + _action.id + '_popup]'));
var row = null;
// Cancel normal confirm
delete _action.data.confirm;
delete _action.data.confirm_multiple;
// nm action - show popup
nm_open_popup(_action,_senders);
if(!popup)
var js_integration_data = this.et2.getArrayMgr('content').data.nm.js_integration_data;
var id = _senders[0].id;
var matches = id.match(/^(?:calendar::)?([0-9]+):([0-9]+)$/);
var backup = _action.data;
if (matches)
{
this.edit_series(matches[1],matches[2]);
return;
}
if (row = jQuery("#"+id+"\\:"+date)) {
// Open at row
popup.css({
position: "absolute",
top: row.position().top + row.height() -popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
} else {
// Open popup in the middle
popup.css({
position: "absolute",
top: $j(window).height()/2-popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
else if (matches = id.match(/^([a-z_-]+)([0-9]+)/i))
{
var app = matches[1];
_action.data.url = window.egw_webserverUrl+'/index.php?';
var get_params = js_integration_data[app].edit;
get_params[js_integration_data[app].edit_id] = matches[2];
for(var name in get_params)
_action.data.url += name+"="+encodeURIComponent(get_params[name])+"&";
if (js_integration_data[app].edit_popup &&
(matches = js_integration_data[app].edit_popup.match(/^(.*)x(.*)$/)))
{
_action.data.width = matches[1];
_action.data.height = matches[2];
}
else
{
_action.data.nm_action = 'location';
}
}
return;
}
console.log(_action);
nm_action(_action, _senders, null, {ids: []});
_action.data = backup; // restore url, width, height, nm_action
}
egw.open(id.replace(/^calendar::/g,''),'calendar','edit');
_action.data = backup; // restore url, width, height, nm_action
},
/**
* Delete calendar entry, asking if you want to delete series or exception
*
*
* @param _action
* @param _senders
*/
cal_delete: function(_action, _senders)
{
var backup = _action.data;
var matches = false;
// Loop so we ask if any of the selected entries is part of a series
for(var i = 0; i < _senders.length; i++)
{
var id = _senders[i].id;
if(!matches)
{
matches = id.match(/^(?:calendar::)?([0-9]+):([0-9]+)$/);
}
}
if (matches)
{
var id = matches[1];
var date = matches[2];
var popup = jQuery(document.getElementById(_action.getManager().etemplate_var_prefix + '[' + _action.id + '_popup]'));
var row = null;
// Cancel normal confirm
delete _action.data.confirm;
delete _action.data.confirm_multiple;
// nm action - show popup
nm_open_popup(_action,_senders);
if(!popup)
{
return;
}
if (row = jQuery("#"+id+"\\:"+date)) {
// Open at row
popup.css({
position: "absolute",
top: row.position().top + row.height() -popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
} else {
// Open popup in the middle
popup.css({
position: "absolute",
top: $j(window).height()/2-popup.height()/2,
left: $j(window).width()/2-popup.width()/2
});
}
return;
}
console.log(_action);
nm_action(_action, _senders, null, {ids: []});
_action.data = backup; // restore url, width, height, nm_action
},
/**
* Create edit exception dialog for recurrence entries
*
* @param {timestamp} date
* @param {string} id, cal_id
* @param {type} name description
*/
edit_series: function(event,id,date)
{
// Coming from list, there is no event
if(arguments.length == 2)
{
date = id;
id = event;
event = null;
}
calendar_edit_id = id;
calendar_edit_date = date;
var that = this;
var buttons = [
{text: this.egw.lang("Edit exception"), id: "exception", class: "ui-priority-primary", "default": true},
{text: this.egw.lang("Edit series"), id:"series"},
{text: this.egw.lang("Cancel"), id:"cancel"},
];
var callbackExceptionDialog = function (button_id)
{
switch(button_id)
{
case 'exception':
that.open_edit(false);
break;
case 'series':
that.open_edit(true);
break;
case 'cancel':
default:
break;
}
}
var confirmExcDialog = et2_dialog.show_dialog(callbackExceptionDialog, this.egw.lang("Do you want to edit this event as an exception or the whole series?"),this.egw.lang("This event is part of a series"), {},buttons, et2_dialog.WARNING_MESSAGE);
},
/**
* open calendar entry with the proper url either as series modifiction or exception modification
*
*/
open_edit: function(series)
{
this.egw.open(calendar_edit_id,'calendar','edit','&date='+calendar_edit_date
+(!series?'&exception=1':''));
},
});

View File

@ -10,7 +10,7 @@
/**
* Sidebox navigation for calendar
*
*
* @todo add code from jscalendar->flat(), or better replace it altogether ...
*/
(function()
@ -35,13 +35,13 @@
egw_appWindow('calendar').location=url+'&owner='+(no_reset?'':'0,')+owner;
}
}
/**
* Initialisation after DOM *and* jQuery is loaded
*/
egw_LAB.wait(function() {
$j(function(){
var calendar_window = egw_appWindow('calendar');
var calendar_window = egw_appWindow('calendar');
// change handlers setting a certain url, eg. view
$j('#calendar_view').change(function(){
calendar_window.location = egw_webserverUrl+'/index.php?'+this.value;
@ -60,14 +60,14 @@
if ($j.isArray(val)) val = val.join(',');
calendar_window.location = current_view_url+
(current_view_url.search.length ? '&' : '?')+this.name+'='+val;
if (this.name == 'merge') this.value='';
if (this.name == 'merge') this.value='';
});
// click handler to switch selectbox to multiple
$j('#calendar_cat_id_multiple').click(function(){
var selectBox = document.getElementById(this.id.replace('_multiple', ''));
if (selectBox && !selectBox.multiple)
if (selectBox && !selectBox.multiple)
{
selectBox.size=4;
selectBox.size=4;
selectBox.multiple=true;
}
});

File diff suppressed because one or more lines are too long

View File

@ -508,22 +508,15 @@ e.g. the div with class calTimeGrid is generated by the timeGridWidget method of
* edit series or exception popup used in eventWidget and
* delete series and exceptions popup used in edit event
*/
#delete_series,#edit_series {
#calendar-edit_calendar-delete_series{
position: fixed;
top: 200px;
left: 500px;
top: 100px;
left: 200px;
z-index: 20000;
display: none;
border-collapse:collapse;
border-spacing:0px
}
#delete_series {
top: 100px;
left: 200px;
}
#delete_series input,#edit_series input {
margin: 8px;
}
#dialog-content {
display:block;
height:100px;

View File

@ -20,14 +20,14 @@
<description for="duration" value="Duration" width="0"/>
<hbox options="0,0">
<menulist>
<menupopup statustext="Duration of the meeting" id="duration" no_lang="1" onchange="set_style_by_class('table','end_hide','display',this.value == '' ? 'block' : 'none'); if (this.value == '') document.getElementById(form::name('end[str]')).value = document.getElementById(form::name('start[str]')).value;" options="Use end date,,,,,,,false"/>
<menupopup statustext="Duration of the meeting" id="duration" no_lang="1" onchange="app.calendar.set_enddate_visibility" options="Use end date,,,,,,,false"/>
</menulist>
<date-time id="end" class="end_hide"/>
<date-time id="end"/>
</hbox>
</row>
<row>
<description/>
<buttononly statustext="Find free timeslots where the selected participants are availible for the given timespan" label="Freetime search" id="freetime" onclick="ajax_submit(this.form,'calendar.calendar_uiforms.ajax_freetimesearch'); return false;"/>
<buttononly statustext="Find free timeslots where the selected participants are availible for the given timespan" label="Freetime search" id="freetime" onclick="app.calendar.freetime_search"/>
</row>
<row class="row">
<description for="location" value="Location" width="0"/>
@ -139,14 +139,11 @@
<description/>
<description/>
<description/>
<description/>
<description/>
<description/>
</row>
<row class="row" height="12">
<description for="recur_type" value="Repeat type"/>
<menulist>
<menupopup id="recur_type" onchange="check_recur_type('recur_type', 2);"/>
<menupopup id="recur_type" onchange="app.calendar.check_recur_type"/>
</menulist>
<description for="recur_interval" value="Interval"/>
<menulist>
@ -166,7 +163,7 @@
<listbox type="select-dow" statustext="Days of the week for a weekly repeated event" id="recur_data" rows="6" options="1"/>
<vbox options="0,0">
<description value="Exceptions"/>
<button statustext="Create an exception for the given date" label="@exception_label" id="button[exception]" no_lang="1"/>
<button statustext="Create an exception for the given date" label="@exception_label" id="button[exception]" no_lang="1" />
</vbox>
<grid id="recur_exception">
<columns>
@ -294,16 +291,16 @@
</grid>
</template>
<template id="calendar.delete_series" template="" lang="" group="0" version="1.7.003">
<vbox id="#delete_series">
<hbox id="#dialog-header" class="promptheader">
<vbox>
<hbox class="promptheader">
<description value="This event is part of a series"/>
</hbox>
<vbox id="dialog-content" class="prompt">
<vbox class="prompt">
<description value="Do you want to keep the series exceptions in your calendar?"/>
<hbox align="center">
<button statustext="All exceptions are converted into single events." label="Keep exceptions" id="button[delete_keep_exceptions]"/>
<button statustext="The exceptions are deleted together with the series." label="Delete exceptions" id="button[delete_exceptions]"/>
<buttononly label="Cancel" onclick="document.getElementById('delete_series').style.display = 'none';"/>
<buttononly label="Cancel" onclick="jQuery(document.getElementById('calendar-edit_calendar-delete_series')).hide();"/>
</hbox>
</vbox>
</vbox>
@ -315,9 +312,6 @@
<column width="300"/>
<column/>
<column/>
<column/>
<column/>
<column/>
</columns>
<rows>
<row disabled="!@msg">
@ -325,9 +319,6 @@
<description/>
<description/>
<description/>
<description/>
<description/>
<description/>
</row>
<row class="th" height="28">
<description value="Title"/>
@ -376,14 +367,14 @@
<button statustext="apply the changes" label="Apply" id="button[apply]"/>
<button statustext="Close the window" label="Cancel" id="button[cancel]" onclick="window.close();"/>
<menulist>
<menupopup statustext="Execute a further action for this entry" id="action" onchange="this.form.submit(); this.value='';" options="Actions..."/>
<menupopup statustext="Execute a further action for this entry" id="action" onchange="app.calendar.actions_change" options="Actions..."/>
</menulist>
<checkbox label="Do not notify of these changes" id="no_notifications" span="2"/>
</hbox>
<button align="right" statustext="Delete this event" label="Delete" id="button[delete]" onclick="if ($cont[query_delete_exceptions]) { getElementById('delete_series').style.display='block'; return false; } else return confirm('Delete this event');"/>
<button align="right" statustext="Delete this event" label="Delete" id="button[delete]" onclick="return app.calendar.delete_btn($cont[query_delete_exceptions]);"/>
</row>
<row disabled="!@recur_type">
<template id="calendar.delete_series" span="all"/>
<row >
<template id="calendar.delete_series" span="all" />
</row>
</rows>
</grid>

View File

@ -9,8 +9,8 @@
<vbox class="prompt" id="dialog-content">
<description value="Do you want to edit this event as an exception or the whole series?"/>
<hbox align="center">
<buttononly label="Edit exception" onclick="open_edit(false);"/>
<buttononly label="Edit series" onclick="open_edit(true);"/>
<buttononly label="Edit exception" onclick="app.calendar.open_edit(false);"/>
<buttononly label="Edit series" onclick="app.calendar.open_edit(true);"/>
<buttononly label="Cancel" onclick="document.getElementById('edit_series').style.display = 'none';"/>
</hbox>
</vbox>

View File

@ -19,9 +19,9 @@
<row class="row">
<date options=",16" id="${row}[start]" readonly="true"/>
<menulist>
<menupopup no_lang="1" id="${row}[start]" statustext="select a time"/>
<menupopup no_lang="1" id="{$row}start" statustext="select a time"/>
</menulist>
<button label="Select" id="select[$row]" statustext="use the selected time and close the popup"/>
<button label="Select" id="select[$row]" statustext="use the selected time and close the popup" onclick="app.calendar.freetime_select" />
<date-time id="${row}[end]" readonly="true"/>
</row>
</rows>
@ -46,17 +46,17 @@
<description value="Duration"/>
<hbox>
<menulist>
<menupopup no_lang="1" id="duration" statustext="Duration of the meeting" onchange="set_style_by_class('table','end_hide','visibility',this.value == '' ? 'visible' : 'hidden');" options="Use end date"/>
<menupopup no_lang="1" id="duration" statustext="Duration of the meeting" onchange="app.calendar.set_enddate_visibility" options="Use end date"/>
</menulist>
<date-time id="end" statustext="Enddate / -time of the meeting, eg. for more then one day" class="end_hide"/>
<date-time id="end" statustext="Enddate / -time of the meeting, eg. for more then one day"/>
</hbox>
</row>
<row>
<description value="Timeframe"/>
<hbox>
<date-houronly id="start_time" statustext="Timeframe to search"/>
<date-timeonly id="start_time" statustext="Timeframe to search"/>
<description value="til"/>
<date-houronly id="end_time" statustext="Timeframe to search"/>
<date-timeonly id="end_time" statustext="Timeframe to search"/>
<description value="Weekdays"/>
<listbox type="select-dow" rows="3" id="weekdays" statustext="Weekdays to use in search"/>
</hbox>

View File

@ -126,7 +126,7 @@
<description align="center" id="msg" no_lang="1" class="redItalic"/>
</row>
<row>
<nextmatch id="nm" options="calendar.list.rows" span="all"/>
<nextmatch id="nm" template="calendar.list.rows" span="all"/>
</row>
<row class="noPrint" disabled="!@nm[selectcols]=/legacy_actions/">
<description/>

View File

@ -27,7 +27,7 @@
<int id="${row}[quantity]" options="1,,3" readonly="true"/>
<checkbox id="${row}[status_recurrence]" align="center" readonly="true"/>
<menulist>
<menupopup id="${row}[status]" no_lang="1" onchange="1"/>
<menupopup id="${row}[status]" no_lang="1" onchange="app.calendar.print_participants_status"/>
</menulist>
</row>
</rows>