2
Calendar Toplevel Window
4
# Copyright (C) 2004 Henning Jacobs <henning@srcco.de>
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
11
# $Id: CalendarWindow.py 82 2004-07-11 13:01:44Z henning $
26
from JournalListWidget import JournalListWidget
27
from JournalEditWidget import JournalEditWidget
29
def __init__(self, model, tkroot=None):
35
# Handle to DateStart Mapping:
36
self._journaldates = {}
41
self.registerAtBroadcaster()
44
def registerAtBroadcaster(self):
45
"Register our Callback Handlers"
46
broadcaster.Register(self.onJournalsOpen,
47
source='Journals', title='Opened')
48
broadcaster.Register(self.onJournalsClose,
49
source='Journals', title='Closed')
50
broadcaster.Register(self.onJournalNew,
51
source='Journal', title='Added')
52
broadcaster.Register(self.onJournalDel,
53
source='Journal', title='Deleted')
54
broadcaster.Register(self.onJournalSave,
55
source='Journal', title='Saved')
56
# Broadcasted by JournalWindow:
57
broadcaster.Register(self.onJournalOpen,
58
source='Journal', title='Opened')
60
def createWidgets(self):
61
"create the top level window"
62
top = self.top = Toplevel(self.tkroot, class_='CalendarWindow')
63
top.protocol('WM_DELETE_WINDOW', self.close)
65
top.iconname('PyCoCuMa')
67
os.chdir(os.path.dirname(sys.argv[0]))
68
if sys.platform == "win32":
69
top.iconbitmap("pycocuma.ico")
71
top.iconbitmap("@pycocuma.xbm")
72
top.iconmask("@pycocuma_mask.xbm")
74
debug.echo("Could not set TopLevel window icon")
78
from CalendarWidget import CalendarWidget
80
self.monthdisp = CalendarWidget(top,
81
selectcommand=self._daySelect,
82
dblclickcommand=self._dayDblClick)
85
def centerWindow(self, relx=0.5, rely=0.3):
86
"Center the Main Window on Screen"
89
widget.update_idletasks() # Actualize geometry information
90
if master.winfo_ismapped():
91
m_width = master.winfo_width()
92
m_height = master.winfo_height()
93
m_x = master.winfo_rootx()
94
m_y = master.winfo_rooty()
96
m_width = master.winfo_screenwidth()
97
m_height = master.winfo_screenheight()
99
w_width = widget.winfo_reqwidth()
100
w_height = widget.winfo_reqheight()
101
x = m_x + (m_width - w_width) * relx
102
y = m_y + (m_height - w_height) * rely
103
if x+w_width > master.winfo_screenwidth():
104
x = master.winfo_screenwidth() - w_width
107
if y+w_height > master.winfo_screenheight():
108
y = master.winfo_screenheight() - w_height
111
widget.geometry("+%d+%d" % (x, y))
112
widget.deiconify() # Become visible at the desired location
114
def _daySelect(self, date, createnew=0):
115
# This variable prevents a looping callback:
116
self._indayselectcallback = 1
117
datadict = {'date':date}
118
if createnew: datadict['createnew'] = createnew
119
broadcaster.Broadcast('Calendar', 'Date Selected', data=datadict)
120
self._indayselectcallback = 0
122
def _dayDblClick(self, date):
123
self.top.event_generate('<<view-journal>>')
124
if self.monthdisp.getmarks().has_key(date):
125
self._daySelect(date, createnew=0)
127
# Create New Journal Entry for a free day
128
self._daySelect(date, createnew=1)
131
def onJournalsOpen(self):
132
"Callback, triggered on Broadcast"
133
handles = self.model.ListJournalHandles()
134
# take only the first 10 chars from dtstart, remainder could be time:
135
dates = map(lambda x: x[:10],
136
self.model.QueryJournalAttributes(handles, 'DateStart'))
137
self._journaldates = dict(zip(handles, dates))
138
self.monthdisp.setmarks(dict(zip(dates,[None]*len(dates))))
140
def onJournalsClose(self):
141
"Callback, triggered on Broadcast"
142
self.monthdisp.setmarks({})
144
_indayselectcallback = 0
145
def onJournalOpen(self):
146
"Callback, triggered on Broadcast by JournalWindow"
147
if not self._indayselectcallback:
148
# dtstart may include time, we take only the first 10 characters:
149
year, month, day = tuple(map(int,
150
broadcaster.CurrentData()['dtstart'][:10].split('-')))
151
self.monthdisp.setmonth(year, month)
152
self.monthdisp.setday(day)
154
def onJournalNew(self):
155
"Callback, registered at Broadcaster"
156
handle = broadcaster.CurrentData()['handle']
157
date = broadcaster.CurrentData()['dtstart'][:10]
158
self._journaldates[handle] = date
159
self.monthdisp.getmarks()[date] = 1
160
self.monthdisp.update()
162
def onJournalDel(self):
163
"Callback, registered at Broadcaster"
164
handle = broadcaster.CurrentData()['handle']
165
date = self._journaldates[handle]
166
del self._journaldates[handle]
167
del self.monthdisp.getmarks()[date]
168
self.monthdisp.update()
170
def onJournalSave(self):
171
"Callback, registered at Broadcaster"
172
handle = broadcaster.CurrentData()['handle']
173
# Maybe the entry's date changed:
174
# we take only the first 10 chars, because dtstart may include time:
175
date = self.model.QueryJournalAttributes([handle], 'DateStart')[0][:10]
176
# this mapping is for onDel only:
177
olddate = self._journaldates[handle]
179
self._journaldates[handle] = date
180
del self.monthdisp.getmarks()[olddate]
181
self.monthdisp.getmarks()[date] = 1
182
self.monthdisp.update()
184
def close(self, event=None):
188
"Returns Tk's TopLevel Widget"
192
"Withdraw: Forward to TopLevel Method"
196
"DeIconify: Forward to TopLevel Method"