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 += ''+
title+"
";
@@ -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;
}