diff --git a/calendar/inc/class.calendar_uiviews.inc.php b/calendar/inc/class.calendar_uiviews.inc.php index c163af1892..6551a07096 100644 --- a/calendar/inc/class.calendar_uiviews.inc.php +++ b/calendar/inc/class.calendar_uiviews.inc.php @@ -524,11 +524,11 @@ class calendar_uiviews extends calendar_ui // Loop through, using egw_time to handle DST $week = 0; - $week_start = new egw_time($this->first); + $week_start = new EGroupware\Api\DateTime($this->first); $week_start->setTime(0,0,0); $week_end = new egw_time($week_start); $week_end->add(new DateInterval('P6DT23H59M59S')); - $last = new egw_time($this->last); + $last = new EGroupware\Api\DateTime($this->last); for ($week_start; $week_start < $last; $week_start->add('1 week'), $week_end->add('1 week')) { $search_params = $this->search_params; @@ -1717,7 +1717,30 @@ class calendar_uiviews extends calendar_ui } return ''; } - + + /** + * Calculates a brighter color for a given color + * + * @param $rgb string color as #rrggbb value + * @param $decr int value to add to each component, default 64 + * @return string the brighter color + */ + static function brighter($rgb,$decr=64) + { + if (!preg_match('/^#?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/',$rgb,$components)) + { + return '#ffffff'; + } + $brighter = '#'; + for ($i = 1; $i <=3; ++$i) + { + $val = hexdec($components[$i]) + $decr; + if ($val > 255) $val = 255; + $brighter .= sprintf('%02x',$val); + } + //echo "brighter($rgb=".print_r($components,True).")=$brighter

\n"; + return $brighter; + } /** * Calculates the brightness of a hexadecimal rgb color (median of the r, g and b components) diff --git a/calendar/js/app.js b/calendar/js/app.js index f5faed8897..53b77fe56e 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -810,7 +810,7 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend( } ); */ - if(framework.applications.calendar && framework.applications.calendar.tab) + if(typeof framework !== 'undefined' && framework.applications.calendar && framework.applications.calendar.tab) { jQuery(framework.applications.calendar.tab.contentDiv).swipe('destroy') .swipe({ @@ -1620,7 +1620,7 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend( update_state: function update_state(_set) { // Make sure we're running in top window - if(window !== window.top) + if(window !== window.top && window.top.app.calendar) { return window.top.app.calendar.update_state(_set); } @@ -1643,7 +1643,7 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend( { // This activates calendar app if you call setState from a different app // such as home. If we change state while not active, sizing is wrong. - if(framework && framework.applications.calendar && framework.applications.calendar.hasSideboxMenuContent) + if(typeof framework !== 'undefined' && framework.applications.calendar && framework.applications.calendar.hasSideboxMenuContent) { framework.setActiveApp(framework.applications.calendar); } @@ -2599,7 +2599,10 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend( csv_export: false }); // Show ajax loader - framework.applications.calendar.sidemenuEntry.showAjaxLoader() + if(typeof framework !== 'undefined') + { + framework.applications.calendar.sidemenuEntry.showAjaxLoader(); + } // Already in progress? var query_string = JSON.stringify(query); @@ -2693,7 +2696,10 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend( } // Hide AJAX loader - framework.applications.calendar.sidemenuEntry.hideAjaxLoader(); + if(framework) + { + framework.applications.calendar.sidemenuEntry.hideAjaxLoader(); + } }, this,null ); }, diff --git a/calendar/js/et2_widget_event.js b/calendar/js/et2_widget_event.js index f0d72d19c1..e7864100b8 100644 --- a/calendar/js/et2_widget_event.js +++ b/calendar/js/et2_widget_event.js @@ -233,18 +233,21 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten } // Copy actions set in parent - var action_parent = this; - while(action_parent != null && !action_parent.options.actions && - !action_parent.instanceOf(et2_container) - ) + if(!this.options.readonly && !this._parent.options.readonly) { - action_parent = action_parent.getParent(); - } - try { - this._link_actions(action_parent.options.actions||{}); - } catch (e) { - // something went wrong, but keep quiet about it - debugger; + var action_parent = this; + while(action_parent != null && !action_parent.options.actions && + !action_parent.instanceOf(et2_container) + ) + { + action_parent = action_parent.getParent(); + } + try { + this._link_actions(action_parent.options.actions||{}); + } catch (e) { + // something went wrong, but keep quiet about it + debugger; + } } // Make sure category stuff is there @@ -267,11 +270,14 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten .append(this.title) .append(this.body); } + if(!this._parent.options.readonly && !this.options.readonly) + { + this.div + // Let timegrid always get the drag + .droppable('option','greedy',false); + } // DOM nodes this.div - // Let timegrid always get the drag - .droppable('option','greedy',false) - // Set full day flag .attr('data-full_day', event.whole_day) diff --git a/calendar/js/et2_widget_planner.js b/calendar/js/et2_widget_planner.js index abf378d0f3..fdc05fa0c9 100644 --- a/calendar/js/et2_widget_planner.js +++ b/calendar/js/et2_widget_planner.js @@ -473,7 +473,7 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e for(var i = 0; i < 12; i++) { // Not using UTC because we corrected for timezone offset - labels.push({id: d.getFullYear() +'-'+d.getMonth(), label:app.calendar.egw.lang(date('F',d))+' '+d.getFullYear()}); + labels.push({id: d.getFullYear() +'-'+d.getMonth(), label:this.egw().lang(date('F',d))+' '+d.getFullYear()}); d.setMonth(d.getMonth()+1); } return labels; @@ -829,6 +829,8 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e // Draw the rows for(var key in labels) { + if (!labels.hasOwnProperty(key)) continue; + // Skip sub-categories (events are merged into top level) if(this.options.group_by == 'category' && (!app.calendar.state.cat_id || app.calendar.state.cat_id == '') && @@ -873,7 +875,8 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e label: label, start_date: start, end_date: end, - value: events + value: events, + readonly: this.options.readonly },this); @@ -900,8 +903,8 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e var end = new Date(this.options.end_date); end = new Date(end.valueOf() + end.getTimezoneOffset() * 60 * 1000); - var title = app.calendar.egw.lang(date('F',start))+' '+date('Y',start)+' - '+ - app.calendar.egw.lang(date('F',end))+' '+date('Y',end); + var title = this.egw().lang(date('F',start))+' '+date('Y',start)+' - '+ + this.egw().lang(date('F',end))+' '+date('Y',end); content += '"; @@ -946,7 +949,7 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e { days_in_month = days - i; } - var title = app.calendar.egw.lang(date('F',new Date(t.valueOf() + t.getTimezoneOffset() * 60 * 1000))); + var title = this.egw().lang(date('F',new Date(t.valueOf() + t.getTimezoneOffset() * 60 * 1000))); if (days_in_month > 10) { title += ' '+t.getUTCFullYear(); @@ -1000,7 +1003,7 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e week_width = 100 / days * Math.min(days, days_in_week); - var title = app.calendar.egw.lang('Week')+' '+app.calendar.date.week_number(usertime); + var title = this.egw().lang('Week')+' '+app.calendar.date.week_number(usertime); if(start.getTimezoneOffset() > 0) { @@ -1053,15 +1056,15 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e if (days <= 3) { - title = app.calendar.egw.lang(date('l',t))+', '+date('j',t)+'. '+app.calendar.egw.lang(date('F',t)); + title = this.egw().lang(date('l',t))+', '+date('j',t)+'. '+this.egw().lang(date('F',t)); } else if (days <= 7) { - title = app.calendar.egw.lang(date('l',t))+' '+date('j',t); + title = this.egw().lang(date('l',t))+' '+date('j',t); } else { - title = app.calendar.egw.lang(date('D',t)).substr(0,2)+'
'+date('j',t); + title = this.egw().lang(date('D',t)).substr(0,2)+'
'+date('j',t); } state = new Date(t.valueOf() - start.getTimezoneOffset() * 60 * 1000).toJSON(); @@ -1740,7 +1743,7 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e var result = true; // Is this click in the event stuff, or in the header? - if(this.gridHeader.has(_ev.target).length === 0 && !$j(_ev.target).hasClass('calendar_plannerRowHeader')) + if(!this.options.readonly && this.gridHeader.has(_ev.target).length === 0 && !$j(_ev.target).hasClass('calendar_plannerRowHeader')) { // Event came from inside, maybe a calendar event var event = this._get_event_info(_ev.originalEvent.target); @@ -1795,7 +1798,7 @@ var et2_calendar_planner = (function(){ "use strict"; return et2_calendar_view.e } app.calendar.update_state(_ev.data); } - else + else if (!this.options.readonly) { // Default handler to open a new event at the selected time // TODO: Determine date / time more accurately from position diff --git a/calendar/sitemgr/class.module_calendar_planner.inc.php b/calendar/sitemgr/class.module_calendar_planner.inc.php index 08a75c2cf9..7e3d6eb764 100644 --- a/calendar/sitemgr/class.module_calendar_planner.inc.php +++ b/calendar/sitemgr/class.module_calendar_planner.inc.php @@ -16,15 +16,19 @@ class module_calendar_planner extends Module { /** - * Default callendar CSS file + * Default calendar CSS file */ const CALENDAR_CSS = '/calendar/templates/default/app.css'; + const ETEMPLATE_CSS = '/etemplate/templates/default/etemplate2.css'; + /** * Constructor */ function __construct() { + parent::__construct(); + $this->arguments = array( 'sortby' => array( 'type' => 'select', @@ -32,8 +36,7 @@ class module_calendar_planner extends Module 'options' => array( 0 => lang('Planner by category'), 'user' => lang('Planner by user'), - 'month' => lang('Yearly Planner'), - 'yearly' => lang('Yearly Planner').' ('.lang('initially year aligned').')', + 'month' => lang('Yearly Planner') ), ), 'cat_id' => array( @@ -186,10 +189,9 @@ class module_calendar_planner extends Module */ function get_content(&$arguments,$properties) { - translation::add_app('calendar'); + $GLOBALS['egw_info']['flags']['currentapp'] = 'calendar'; - //_debug_array($arguments); - $arguments['view'] = 'planner'; + //error_log(array2string($arguments)); if (empty($arguments['date'])) { $arguments['date'] = date('Ymd'); @@ -200,7 +202,7 @@ class module_calendar_planner extends Module $arguments['date'] = substr($arguments['date'],0,4).'0101'; } if (isset($_GET['date'])) $arguments['date'] = $_GET['date']; - if (empty($arguments['cat_id'])) $arguments['cat_id'] = 0; + if (empty($arguments['cat_id'])) $arguments['cat_id'] = ''; if(isset($arguments['resources']) && in_array('r0', $arguments['resources'])) { foreach($arguments['resources'] as $index => $value) @@ -221,28 +223,94 @@ class module_calendar_planner extends Module $html = ''."\n"; + $html .= '@import url('.$GLOBALS['egw_info']['server']['webserver_url'].self::ETEMPLATE_CSS.");\n"; + $html .= '@import url('.$GLOBALS['egw_info']['server']['webserver_url'].categories::css(categories::GLOBAL_APPNAME).");\n"; + $html .= '@import url('.$GLOBALS['egw_info']['server']['webserver_url'].categories::css('calendar').");\n"; + $html .= '.popupMainDiv #calendar-planner { position: static;} + #calendar-planner .calendar_plannerWidget, #calendar-planner div.calendar_plannerRows { + height: auto !important; +} + '."\n"; + $html .= html::image('sitemgr', 'left', lang('Previous'), 'onclick=\'app.calendar.toolbar_action({id:"previous"});\'') + . html::image('sitemgr', 'right', lang('Next'), 'style="float: right;" onclick=\'app.calendar.toolbar_action({id:"next"});\''); if (is_array($params['owner'])) { - $params['owner'] = implode(',', $params['owner']); + // Buffer, and add anything that gets cleared to the content + ob_start(function($buffer) use(&$html) { + $html .= $buffer; + return ''; + }); + egw_framework::$header_done = true; + $ui = new calendar_uiviews(); + $ui->sortby = $arguments['sortby']; + $ui->owner = $params['owner']; + + if (!$ui->planner_view || $ui->planner_view == 'month') // planner monthview + { + if ($ui->day < 15) // show one complete month + { + $ui->_week_align_month($ui->first,$ui->last); + } + else // show 2 half month + { + $ui->_week_align_month($ui->first,$ui->last,15); + } + } + elseif ($ui->planner_view == 'week' || $ui->planner_view == 'weekN') // weeekview + { + $ui->first = $ui->datetime->get_weekday_start($ui->year,$ui->month,$ui->day); + $ui->last = $ui->bo->date2array($this->first); + $ui->last['day'] += ($ui->planner_view == 'week' ? 7 : 7 * $ui->cal_prefs['multiple_weeks'])-1; + $ui->last['hour'] = 23; $ui->last['minute'] = $ui->last['sec'] = 59; + unset($ui->last['raw']); + $ui->last = $ui->bo->date2ts($ui->last); + } + else // dayview + { + $ui->first = $ui->bo->date2ts($ui->date); + $ui->last = $ui->bo->date2array($ui->first); + $ui->last['day'] += 0; + $ui->last['hour'] = 23; $ui->last['minute'] = $ui->last['sec'] = 59; + unset($ui->last['raw']); + $ui->last = $ui->bo->date2ts($ui->last); + } - $uiviews = new calendar_uiviews($params); - $uiviews->allowEdit = false; // switches off all edit popups + $search_params = $ui->search_params; + $search_params['daywise'] = false; + $search_params['start'] = $ui->first; + $search_params['end'] = $ui->last; + $search_params['owner'] = $ui->owner; + $search_params['enum_groups'] = $ui->sortby == 'user'; + $content['planner'] = $ui->bo->search($search_params); + foreach($content['planner'] as &$event) + { + $ui->to_client($event); + } - // Initialize Tooltips - static $wz_tooltips; - if (!$wz_tooltips++) $html .= ''."\n"; + $tmpl = new etemplate_new('calendar.planner'); - // replacing egw-urls with sitemgr ones, allows to use navigation links - $html .= str_replace($GLOBALS['egw_info']['server']['webserver_url'].'/index.php?', - $this->link().'&', - $uiviews->planner(true)); + $tmpl->setElementAttribute('planner','start_date', egw_time::to($ui->first, egw_time::ET2)); + $tmpl->setElementAttribute('planner','end_date', egw_time::to($ui->last, egw_time::ET2)); + $tmpl->setElementAttribute('planner','owner', $search_params['users']); + $tmpl->setElementAttribute('planner','group_by', $ui->sortby); + $tmpl->exec(__METHOD__, $content,array(), array('__ALL__' => true),array(),2); + $html .= ob_get_contents(); + $html .= ''; } else { $html .= '
'.lang('No owner selected').'
'; } + + while(@ob_end_clean()); return $html; }