Add calendar view
review395003
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
Copyright (C) 2012-2013 Antoine Smolders.
|
||||
Copyright (C) 2010-2013 Nicolas Évrard.
|
||||
Copyright (C) 2007-2013 Cédric Krier.
|
||||
Copyright (C) 2007-2013 Bertrand Chenal.
|
||||
|
||||
@@ -165,6 +165,7 @@ dist = setup(name=PACKAGE,
|
||||
'timezone': ['pytz'],
|
||||
'simplejson': ['simplejson'],
|
||||
'cdecimal': ['cdecimal'],
|
||||
'calendar': ['GooCalendar'],
|
||||
},
|
||||
**args
|
||||
)
|
||||
|
||||
@@ -367,7 +367,7 @@ class Record(SignalEvent):
|
||||
self._check_load()
|
||||
res = True
|
||||
for field_name, field in self.group.fields.iteritems():
|
||||
if fields and field_name not in fields:
|
||||
if fields is not None and field_name not in fields:
|
||||
continue
|
||||
if field.get_state_attrs(self).get('readonly', False):
|
||||
continue
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
"Screen"
|
||||
import copy
|
||||
import gobject
|
||||
import datetime
|
||||
import calendar
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
@@ -185,6 +187,12 @@ class Screen(SignalEvent):
|
||||
else:
|
||||
domain = self.domain
|
||||
|
||||
if self.current_view.view_type == 'calendar':
|
||||
if domain:
|
||||
domain = ['AND', domain, self.current_view.current_domain()]
|
||||
else:
|
||||
domain = self.current_view.current_domain()
|
||||
|
||||
tab_domain = self.screen_container.get_tab_domain()
|
||||
if tab_domain:
|
||||
domain = ['AND', domain, tab_domain]
|
||||
@@ -428,12 +436,15 @@ class Screen(SignalEvent):
|
||||
return False
|
||||
|
||||
def new(self, default=True):
|
||||
previous_view = self.current_view
|
||||
if self.current_view.view_type == 'calendar':
|
||||
selected_date = self.current_view.get_selected_date()
|
||||
if (self.current_view
|
||||
and ((self.current_view.view_type == 'tree'
|
||||
and not (hasattr(self.current_view.widget_tree,
|
||||
'editable')
|
||||
and self.current_view.widget_tree.editable))
|
||||
or self.current_view.view_type == 'graph')):
|
||||
or self.current_view.view_type in ('graph', 'calendar'))):
|
||||
self.switch_view('form')
|
||||
if self.current_view.view_type != 'form':
|
||||
return None
|
||||
@@ -443,6 +454,8 @@ class Screen(SignalEvent):
|
||||
group = self.group
|
||||
record = group.new(default)
|
||||
group.add(record, self.new_model_position())
|
||||
if previous_view.view_type == 'calendar':
|
||||
previous_view.set_default_date(record, selected_date)
|
||||
self.current_record = record
|
||||
self.display()
|
||||
self.set_cursor(new=True)
|
||||
@@ -674,10 +687,6 @@ class Screen(SignalEvent):
|
||||
else:
|
||||
self.current_record = None
|
||||
if self.views:
|
||||
#XXX To remove when calendar will be implemented
|
||||
if self.current_view.view_type == 'calendar' and \
|
||||
len(self.views) > 1:
|
||||
self.switch_view()
|
||||
self.search_active(self.current_view.view_type
|
||||
in ('tree', 'graph', 'calendar'))
|
||||
for view in self.views:
|
||||
@@ -731,6 +740,27 @@ class Screen(SignalEvent):
|
||||
record = next
|
||||
break
|
||||
self.current_record = record
|
||||
elif view.view_type == 'calendar':
|
||||
record = self.current_record
|
||||
goocalendar = view.children['goocalendar']
|
||||
date = goocalendar.selected_date
|
||||
year = date.year
|
||||
month = date.month
|
||||
start = datetime.datetime(year, month, 1)
|
||||
nb_days = calendar.monthrange(year, month)[1]
|
||||
delta = datetime.timedelta(days=nb_days)
|
||||
end = start + delta
|
||||
events = goocalendar.event_store.get_events(start, end)
|
||||
events.sort()
|
||||
if not record:
|
||||
self.current_record = len(events) and events[0].record
|
||||
else:
|
||||
for idx, event in enumerate(events):
|
||||
if event.record == record:
|
||||
next_id = idx + 1
|
||||
if next_id < len(events):
|
||||
self.current_record = events[next_id].record
|
||||
break
|
||||
else:
|
||||
self.current_record = self.group[0] if len(self.group) else None
|
||||
self.set_cursor(reset_view=False)
|
||||
@@ -765,6 +795,27 @@ class Screen(SignalEvent):
|
||||
if parent:
|
||||
record = parent
|
||||
self.current_record = record
|
||||
elif view.view_type == 'calendar':
|
||||
record = self.current_record
|
||||
goocalendar = view.children['goocalendar']
|
||||
date = goocalendar.selected_date
|
||||
year = date.year
|
||||
month = date.month
|
||||
start = datetime.datetime(year, month, 1)
|
||||
nb_days = calendar.monthrange(year, month)[1]
|
||||
delta = datetime.timedelta(days=nb_days)
|
||||
end = start + delta
|
||||
events = goocalendar.event_store.get_events(start, end)
|
||||
events.sort()
|
||||
if not record:
|
||||
self.current_record = len(events) and events[0].record
|
||||
else:
|
||||
for idx, event in enumerate(events):
|
||||
if event.record == record:
|
||||
prev_id = idx - 1
|
||||
if prev_id >= 0:
|
||||
self.current_record = events[prev_id].record
|
||||
break
|
||||
else:
|
||||
self.current_record = self.group[-1] if len(self.group) else None
|
||||
self.set_cursor(reset_view=False)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from functools import wraps
|
||||
|
||||
from interface import ParserView
|
||||
|
||||
|
||||
def goocalendar_required(func):
|
||||
"Decorator for goocalendar required"
|
||||
@wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if 'goocalendar' not in self.children:
|
||||
return
|
||||
return func(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
class ViewCalendar(ParserView):
|
||||
|
||||
def __init__(self, screen, widget, children=None, buttons=None,
|
||||
notebooks=None, cursor_widget=None, children_field=None):
|
||||
super(ViewCalendar, self).__init__(screen, widget, children, buttons,
|
||||
notebooks, cursor_widget, children_field)
|
||||
self.view_type = 'calendar'
|
||||
|
||||
def __getitem__(self, name):
|
||||
return None
|
||||
|
||||
@goocalendar_required
|
||||
def destroy(self):
|
||||
self.widget.destroy()
|
||||
self.children['goocalendar'].destroy()
|
||||
|
||||
@goocalendar_required
|
||||
def get_selected_date(self):
|
||||
return self.children['goocalendar'].selected_date
|
||||
|
||||
@goocalendar_required
|
||||
def set_default_date(self, record, selected_date):
|
||||
self.children['goocalendar'].set_default_date(record, selected_date)
|
||||
|
||||
def current_domain(self):
|
||||
if 'goocalendar' in self.children:
|
||||
return self.children['goocalendar'].current_domain()
|
||||
else:
|
||||
# No need to load any record as nothing will be shown
|
||||
return [('id', '=', -1)]
|
||||
|
||||
def cancel(self):
|
||||
pass
|
||||
|
||||
def set_value(self):
|
||||
pass
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
|
||||
@goocalendar_required
|
||||
def display(self):
|
||||
self.children['goocalendar'].display(self.screen.group)
|
||||
gtkcal = self.children['toolbar'].gtkcal
|
||||
if gtkcal and not gtkcal.is_drawable():
|
||||
import goocanvas
|
||||
# disable gtk.Calendar if it is not drawable anymore
|
||||
self.children['toolbar'].gtkcal_item.set_property('visibility',
|
||||
goocanvas.ITEM_INVISIBLE)
|
||||
self.children['toolbar'].current_page.set_active(False)
|
||||
|
||||
def set_cursor(self, new=False, reset_view=True):
|
||||
pass
|
||||
|
||||
def get_fields(self):
|
||||
return []
|
||||
@@ -0,0 +1,3 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from parser import *
|
||||
@@ -0,0 +1,120 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import calendar
|
||||
import datetime
|
||||
import goocalendar
|
||||
import tryton.common as common
|
||||
from dates_period import DatesPeriod
|
||||
|
||||
|
||||
class Calendar_(goocalendar.Calendar):
|
||||
'Calendar'
|
||||
|
||||
def __init__(self, attrs, model, root_node, fields, screen,
|
||||
event_store=None):
|
||||
super(Calendar_, self).__init__(event_store)
|
||||
self.attrs = attrs
|
||||
self.model = model
|
||||
self.root_node = root_node
|
||||
self.fields = fields
|
||||
self.screen = screen
|
||||
self.event_store = event_store
|
||||
self.current_domain_period = self.get_displayed_period()
|
||||
|
||||
def destroy(self):
|
||||
super(Calendar_, self).destroy()
|
||||
|
||||
def set_default_date(self, record, selected_date):
|
||||
attrs = common.node_attributes(self.root_node)
|
||||
dtstart = attrs.get('dtstart')
|
||||
record[dtstart].set(record, datetime.datetime.combine(selected_date,
|
||||
datetime.time(0)))
|
||||
|
||||
def get_displayed_period(self):
|
||||
cal = calendar.Calendar(self.firstweekday)
|
||||
if self.view == 'week':
|
||||
week = goocalendar.util.my_weekdatescalendar(cal,
|
||||
self.selected_date)
|
||||
first_date = week[0]
|
||||
last_date = week[6]
|
||||
last_date += datetime.timedelta(1)
|
||||
elif self.view == 'month':
|
||||
weeks = goocalendar.util.my_monthdatescalendar(cal,
|
||||
self.selected_date)
|
||||
first_date = weeks[0][0]
|
||||
last_date = weeks[5][6]
|
||||
last_date += datetime.timedelta(1)
|
||||
displayed_period = DatesPeriod(first_date, last_date)
|
||||
return displayed_period
|
||||
|
||||
def update_domain(self):
|
||||
displayed_period = self.get_displayed_period()
|
||||
if not displayed_period.is_in(self.current_domain_period):
|
||||
self.current_domain_period = displayed_period
|
||||
return True
|
||||
return False
|
||||
|
||||
def current_domain(self):
|
||||
first_datetime, last_datetime = \
|
||||
self.current_domain_period.get_dates(True)
|
||||
attrs = common.node_attributes(self.root_node)
|
||||
dtstart = attrs.get('dtstart')
|
||||
dtend = attrs.get('dtend') or dtstart
|
||||
domain = ['OR',
|
||||
['AND', (dtstart, '>=', first_datetime),
|
||||
(dtstart, '<', last_datetime)],
|
||||
['AND', (dtend, '>=', first_datetime),
|
||||
(dtend, '<', last_datetime)],
|
||||
['AND', (dtstart, '<', first_datetime),
|
||||
(dtend, '>', last_datetime)]]
|
||||
return domain
|
||||
|
||||
def display(self, group):
|
||||
attrs = common.node_attributes(self.root_node)
|
||||
dtstart = attrs.get('dtstart')
|
||||
dtend = attrs.get('dtend') or dtstart
|
||||
if self.screen.current_record:
|
||||
record = self.screen.current_record
|
||||
date = record[dtstart].get(record)
|
||||
if date: # select the day of the current record
|
||||
self.select(date)
|
||||
|
||||
if self._event_store:
|
||||
self._event_store.clear()
|
||||
else:
|
||||
event_store = goocalendar.EventStore()
|
||||
self.event_store = event_store
|
||||
|
||||
fields = []
|
||||
for node in self.root_node.childNodes:
|
||||
if not node.nodeType == node.ELEMENT_NODE:
|
||||
continue
|
||||
if node.localName == 'field':
|
||||
attrs = common.node_attributes(node)
|
||||
fields.append(attrs.get('name'))
|
||||
|
||||
for record in group:
|
||||
if not record[dtstart].get(record):
|
||||
continue
|
||||
|
||||
start = record[dtstart].get(record)
|
||||
end = record[dtend].get(record)
|
||||
midnight = datetime.time(0)
|
||||
all_day = False
|
||||
if not isinstance(start, datetime.datetime):
|
||||
start = datetime.datetime.combine(start, midnight)
|
||||
if end and not isinstance(end, datetime.datetime):
|
||||
end = datetime.datetime.combine(end, midnight)
|
||||
all_day = True
|
||||
elif not end:
|
||||
all_day = True
|
||||
|
||||
# TODO define color code
|
||||
label = '\n'.join(record[name].get_client(record)
|
||||
for name in fields).rstrip()
|
||||
event = goocalendar.Event(label, start, end,
|
||||
bg_color='lightblue', all_day=all_day)
|
||||
event.record = record
|
||||
self._event_store.add(event)
|
||||
|
||||
self.grab_focus(self.get_root_item())
|
||||
@@ -0,0 +1,31 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
|
||||
|
||||
class DatesPeriod():
|
||||
"""
|
||||
This class represents a period of time between two dates or two datetimes.
|
||||
"""
|
||||
|
||||
def __init__(self, start, end):
|
||||
assert type(start) == type(end)
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
def is_in(self, period):
|
||||
return self.start >= period.start \
|
||||
and self.end <= period.end
|
||||
|
||||
def get_dates(self, format_datetime=False):
|
||||
if not format_datetime:
|
||||
return self.start, self.end
|
||||
|
||||
midnight = datetime.time(0)
|
||||
start = datetime.datetime.combine(self.start, midnight)
|
||||
end = datetime.datetime.combine(self.end, midnight)
|
||||
return start, end
|
||||
|
||||
def __str__(self):
|
||||
string = self.start.__str__() + ' => ' + self.end.__str__()
|
||||
return string
|
||||
@@ -0,0 +1,85 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
import gettext
|
||||
import gtk
|
||||
from tryton.gui.window.view_form.view.interface import ParserInterface
|
||||
import tryton.common as common
|
||||
try:
|
||||
from calendar_ import Calendar_
|
||||
from toolbar import Toolbar
|
||||
except ImportError:
|
||||
Calendar_ = None
|
||||
Toolbar = None
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class ParserCalendar(ParserInterface):
|
||||
|
||||
def on_page_changed(self, goocalendar, day, toolbar):
|
||||
toolbar.update_displayed_date()
|
||||
if goocalendar.update_domain():
|
||||
self.screen.search_filter()
|
||||
|
||||
def on_view_changed(self, goocalendar, view, toolbar):
|
||||
toolbar.update_displayed_date()
|
||||
if goocalendar.update_domain():
|
||||
self.screen.search_filter()
|
||||
|
||||
def on_event_pressed(self, goocalendar, event):
|
||||
self.screen.current_record = event.record
|
||||
|
||||
def on_event_activated(self, goocalendar, event):
|
||||
self.screen.switch_view('form')
|
||||
|
||||
def on_event_released(self, goocalendar, event, attrs):
|
||||
dtstart = attrs.get('dtstart')
|
||||
dtend = attrs.get('dtend') or dtstart
|
||||
record = event.record
|
||||
group = record.group
|
||||
previous_start = record[dtstart].get(record)
|
||||
new_start = event.start
|
||||
new_end = event.end
|
||||
if not isinstance(previous_start, datetime.datetime):
|
||||
new_start = event.start.date()
|
||||
new_end = event.end.date() if event.end else None
|
||||
if previous_start <= new_start:
|
||||
if new_end:
|
||||
group.fields[dtend].set_client(record, new_end)
|
||||
group.fields[dtstart].set_client(record, new_start)
|
||||
else:
|
||||
group.fields[dtstart].set_client(record, new_start)
|
||||
if new_end:
|
||||
group.fields[dtend].set_client(record, new_end)
|
||||
goocalendar.select(new_start)
|
||||
record.save()
|
||||
|
||||
def on_day_pressed(self, goocalendar, day):
|
||||
self.screen.current_record = None
|
||||
|
||||
def on_day_activated(self, goocalendar, day):
|
||||
self.screen.new()
|
||||
|
||||
def parse(self, model, root_node, fields):
|
||||
attrs = common.node_attributes(root_node)
|
||||
self.title = attrs.get('string', 'Unknown')
|
||||
vbox = gtk.VBox()
|
||||
if not Calendar_:
|
||||
return vbox, {}, [], '', [], None
|
||||
goocalendar = Calendar_(attrs=attrs, model=model, root_node=root_node,
|
||||
fields=fields, screen=self.screen)
|
||||
toolbar = Toolbar(goocalendar)
|
||||
goocalendar.connect('view-changed', self.on_view_changed, toolbar)
|
||||
goocalendar.connect('page-changed', self.on_page_changed, toolbar)
|
||||
goocalendar.connect('event-pressed', self.on_event_pressed)
|
||||
goocalendar.connect('event-activated', self.on_event_activated)
|
||||
goocalendar.connect('event-released', self.on_event_released, attrs)
|
||||
goocalendar.connect('day-pressed', self.on_day_pressed)
|
||||
goocalendar.connect('day-activated', self.on_day_activated)
|
||||
scrolledWindow = gtk.ScrolledWindow()
|
||||
scrolledWindow.add_with_viewport(goocalendar)
|
||||
vbox.pack_start(toolbar, False, False)
|
||||
vbox.pack_start(scrolledWindow, True, True)
|
||||
return vbox, {'root': scrolledWindow, 'toolbar': toolbar,
|
||||
'goocalendar': goocalendar}, [], '', [], None
|
||||
@@ -0,0 +1,176 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
import calendar
|
||||
import gettext
|
||||
import gtk
|
||||
import goocanvas
|
||||
from tryton.gui import Main
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Toolbar(gtk.Toolbar):
|
||||
|
||||
def __init__(self, goocalendar):
|
||||
super(Toolbar, self).__init__()
|
||||
self.goocalendar = goocalendar
|
||||
self.accel_group = Main.get_main().accel_group
|
||||
|
||||
today_label = gtk.Label(_('Today'))
|
||||
today_button = gtk.ToolButton(today_label)
|
||||
today_button.set_homogeneous(False)
|
||||
today_button.connect("clicked", self.on_today_button_clicked)
|
||||
today_button.add_accelerator("clicked", self.accel_group,
|
||||
gtk.keysyms.t, gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
|
||||
self.insert(today_button, -1)
|
||||
|
||||
arrow_left = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_NONE)
|
||||
go_back = gtk.ToolButton(arrow_left, "go left")
|
||||
go_back.set_expand(False)
|
||||
go_back.set_homogeneous(False)
|
||||
go_back.connect("clicked", self.on_go_back_clicked)
|
||||
self.insert(go_back, -1)
|
||||
|
||||
self.current_page_label = gtk.Label("")
|
||||
self.current_page = gtk.ToggleToolButton()
|
||||
self.current_page.set_icon_widget(self.current_page_label)
|
||||
self.current_page.connect("clicked", self.on_current_page_clicked)
|
||||
self.insert(self.current_page, -1)
|
||||
|
||||
gtkcal = gtk.Calendar()
|
||||
gtkcal.connect('day-selected', self.on_gtkcal_day_selected)
|
||||
gtkcal.set_display_options(
|
||||
gtk.CALENDAR_SHOW_HEADING |
|
||||
gtk.CALENDAR_SHOW_WEEK_NUMBERS |
|
||||
gtk.CALENDAR_SHOW_DAY_NAMES)
|
||||
gtkcal.set_no_show_all(True)
|
||||
gtkcal_item = goocanvas.Widget(widget=gtkcal)
|
||||
gtkcal_item.set_property('visibility', goocanvas.ITEM_INVISIBLE)
|
||||
goocalendar.get_root_item().add_child(gtkcal_item)
|
||||
self.gtkcal = gtkcal
|
||||
self.gtkcal_item = gtkcal_item
|
||||
self.goocalendar.connect('day-selected',
|
||||
self.on_goocalendar_day_selected)
|
||||
|
||||
arrow_right = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_NONE)
|
||||
go_forward = gtk.ToolButton(arrow_right, "go right")
|
||||
go_forward.set_expand(False)
|
||||
go_forward.set_homogeneous(False)
|
||||
go_forward.connect("clicked", self.on_go_forward_clicked)
|
||||
self.insert(go_forward, -1)
|
||||
|
||||
arrow_left = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_NONE)
|
||||
previous_year = gtk.ToolButton(arrow_left, "next year")
|
||||
previous_year.set_expand(False)
|
||||
previous_year.set_homogeneous(False)
|
||||
previous_year.connect("clicked", self.on_previous_year_clicked)
|
||||
self.insert(previous_year, -1)
|
||||
|
||||
self.current_year_label = gtk.Label("")
|
||||
current_year = gtk.ToolItem()
|
||||
current_year.add(self.current_year_label)
|
||||
self.insert(current_year, -1)
|
||||
|
||||
arrow_right = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_NONE)
|
||||
next_year = gtk.ToolButton(arrow_right, "next year")
|
||||
next_year.set_expand(False)
|
||||
next_year.set_homogeneous(False)
|
||||
next_year.connect("clicked", self.on_next_year_clicked)
|
||||
self.insert(next_year, -1)
|
||||
|
||||
blank_widget = gtk.ToolItem()
|
||||
blank_widget.set_expand(True)
|
||||
self.insert(blank_widget, -1)
|
||||
|
||||
week_button = gtk.RadioToolButton()
|
||||
week_button.set_label(_('Week View'))
|
||||
week_button.connect("clicked", self.on_week_button_clicked)
|
||||
week_button.add_accelerator("clicked", self.accel_group, gtk.keysyms.w,
|
||||
gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
|
||||
self.insert(week_button, -1)
|
||||
|
||||
month_view_label = gtk.Label(_('Month View'))
|
||||
month_button = gtk.RadioToolButton(week_button)
|
||||
month_button.set_icon_widget(month_view_label)
|
||||
month_button.set_label(_('month_view'))
|
||||
month_button.connect("clicked", self.on_month_button_clicked)
|
||||
month_button.add_accelerator("clicked", self.accel_group,
|
||||
gtk.keysyms.m, gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
|
||||
month_button.set_active(True)
|
||||
self.insert(month_button, -1)
|
||||
self.update_displayed_date()
|
||||
self.set_style(gtk.TOOLBAR_ICONS)
|
||||
|
||||
def update_displayed_date(self):
|
||||
date = self.goocalendar.selected_date
|
||||
year = date.timetuple()[0]
|
||||
month = date.timetuple()[1]
|
||||
day = date.timetuple()[2]
|
||||
self.current_year_label.set_text(str(year))
|
||||
|
||||
if self.goocalendar.view == "month":
|
||||
new_label = calendar.month_name[month]
|
||||
self.current_page_label.set_text(new_label)
|
||||
elif self.goocalendar.view == "week":
|
||||
week_number = datetime.date(year, month, day).isocalendar()[1]
|
||||
new_label = _('Week') + ' ' + str(week_number)
|
||||
new_label += ' (' + calendar.month_name[month] + ')'
|
||||
self.current_page_label.set_text(new_label)
|
||||
|
||||
def on_today_button_clicked(self, widget):
|
||||
self.goocalendar.select(datetime.date.today())
|
||||
|
||||
def on_go_back_clicked(self, widget):
|
||||
self.goocalendar.previous_page()
|
||||
|
||||
def on_current_page_clicked(self, widget):
|
||||
gtkcal_item = self.gtkcal_item
|
||||
if gtkcal_item.get_property('visibility') == goocanvas.ITEM_VISIBLE:
|
||||
gtkcal_item.set_property('visibility', goocanvas.ITEM_INVISIBLE)
|
||||
else:
|
||||
gtkcal_item.set_property('visibility', goocanvas.ITEM_VISIBLE)
|
||||
|
||||
def on_gtkcal_day_selected(self, gtkcal):
|
||||
year, month, day = gtkcal.get_date()
|
||||
month += 1 # months go from 1 to 12 instead of from 0 to 11
|
||||
self.goocalendar.select(datetime.date(year, month, day))
|
||||
|
||||
def on_goocalendar_day_selected(self, goocalendar, day):
|
||||
# months go from 0 to 11 in gtk.Calendar instead of 1 to 12
|
||||
new_date = self.goocalendar.selected_date
|
||||
self.gtkcal.select_month(new_date.month - 1, new_date.year)
|
||||
self.gtkcal.handler_block_by_func(self.on_gtkcal_day_selected)
|
||||
self.gtkcal.select_day(new_date.day)
|
||||
self.gtkcal.handler_unblock_by_func(self.on_gtkcal_day_selected)
|
||||
|
||||
def on_go_forward_clicked(self, widget):
|
||||
self.goocalendar.next_page()
|
||||
|
||||
def on_previous_year_clicked(self, widget):
|
||||
date = datetime.datetime.combine(self.goocalendar.selected_date,
|
||||
datetime.time(0))
|
||||
year, month, day = date.timetuple()[:3]
|
||||
year -= 1
|
||||
cal = calendar.Calendar(self.goocalendar.firstweekday)
|
||||
next_month_days = [d for d in cal.itermonthdays(year, month)]
|
||||
if day not in next_month_days:
|
||||
day = max(next_month_days)
|
||||
self.goocalendar.select(datetime.datetime(year, month, day))
|
||||
|
||||
def on_next_year_clicked(self, widget):
|
||||
date = datetime.datetime.combine(self.goocalendar.selected_date,
|
||||
datetime.time(0))
|
||||
year, month, day = date.timetuple()[:3]
|
||||
year += 1
|
||||
cal = calendar.Calendar(self.goocalendar.firstweekday)
|
||||
next_month_days = [d for d in cal.itermonthdays(year, month)]
|
||||
if day not in next_month_days:
|
||||
day = max(next_month_days)
|
||||
self.goocalendar.select(datetime.datetime(year, month, day))
|
||||
|
||||
def on_week_button_clicked(self, widget):
|
||||
self.goocalendar.set_view("week")
|
||||
|
||||
def on_month_button_clicked(self, widget):
|
||||
self.goocalendar.set_view("month")
|
||||
@@ -4,32 +4,31 @@ from interface import ParserInterface
|
||||
import form_gtk
|
||||
import list_gtk
|
||||
import graph_gtk
|
||||
#import calendar_gtk
|
||||
import calendar_gtk
|
||||
from form import ViewForm
|
||||
from list import ViewList
|
||||
from graph import ViewGraph
|
||||
#from calendar import ViewCalendar
|
||||
from calendar_ import ViewCalendar
|
||||
from tryton.exceptions import TrytonError
|
||||
|
||||
PARSERS = {
|
||||
'form': form_gtk.ParserForm,
|
||||
'tree': list_gtk.ParserTree,
|
||||
'graph': graph_gtk.ParserGraph,
|
||||
#'calendar': calendar_gtk.parser_calendar,
|
||||
}
|
||||
'calendar': calendar_gtk.ParserCalendar,
|
||||
}
|
||||
|
||||
PARSERS2 = {
|
||||
'form': ViewForm,
|
||||
'tree': ViewList,
|
||||
'graph': ViewGraph,
|
||||
#'calendar': ViewCalendar,
|
||||
}
|
||||
'calendar': ViewCalendar,
|
||||
}
|
||||
|
||||
|
||||
class WidgetParse(ParserInterface):
|
||||
|
||||
def parse(self, screen, root_node, fields, children_field=None):
|
||||
widget = None
|
||||
for node in root_node.childNodes:
|
||||
if not node.nodeType == node.ELEMENT_NODE:
|
||||
continue
|
||||
@@ -43,8 +42,6 @@ class WidgetParse(ParserInterface):
|
||||
res = PARSERS2[node.localName](screen, wid, child,
|
||||
state_widgets, notebooks, cursor_widget, children_field)
|
||||
res.title = widget.title
|
||||
widget = res
|
||||
break
|
||||
return res
|
||||
else:
|
||||
raise TrytonError('Unknow view mode: %s' % node.localName)
|
||||
return widget
|
||||
|
||||
Reference in New Issue
Block a user