1from Cocoa import *
2from ToDoDocument import *
3
4NOTIFY_TAG     = 0
5RESCHEDULE_TAG = 1
6NOTES_TAG      = 2
7
8NotifyLengthNone    = 0
9NotifyLengthQuarter = 1
10NotifyLengthHour    = 2
11NotifyLengthDay     = 3
12NotifyLengthOther   = 4
13
14_sharedInfoWindowController = None
15
16class InfoWindowController (NSWindowController):
17    dummyView = objc.IBOutlet()
18    infoDate = objc.IBOutlet()
19    infoItem = objc.IBOutlet()
20    infoNotes = objc.IBOutlet()
21    infoNotifyAMPM = objc.IBOutlet()
22    infoNotifyHour = objc.IBOutlet()
23    infoNotifyMinute = objc.IBOutlet()
24    infoNotifyOtherHours = objc.IBOutlet()
25    infoNotifySwitchMatrix = objc.IBOutlet()
26    infoPopUp = objc.IBOutlet()
27    infoSchedComplete = objc.IBOutlet()
28    infoSchedDate = objc.IBOutlet()
29    infoSchedMatrix = objc.IBOutlet()
30    infoWindowViews = objc.IBOutlet()
31    notesView = objc.IBOutlet()
32    notifyView = objc.IBOutlet()
33    reschedView = objc.IBOutlet()
34
35
36    __slots__ = ('_inspectingDocument', )
37
38    @objc.IBAction
39    def switchClicked_(self, sender):
40        dueSecs = 0
41        idx = 0
42        theItem = self._inspectingDocument.selectedItem()
43        if theItem is None:
44            return
45
46        if sender is self.infoNotifyAMPM:
47            if self.infoNotifyHour.intValue():
48                pmFlag = (self.infoNotifyAMPM.selectedRow() == 1)
49                dueSecs = ConvertTimeToSeconds(
50                    self.infoNotifyHour.intValue(),
51                    self.infoNotifyMinute.intValue(),
52                    pmFlag)
53                theItem.setSecsUntilDue_(dueSecs)
54        elif sender is self.infoNotifySwitchMatrix:
55            idx = self.infoNotifySwitchMatrix.selectedRow()
56
57            if not theItem:
58                pass
59            elif idx == NotifyLengthNone:
60                theItem.setSecsUntilNotify_(0)
61            elif idx == NotifyLengthQuarter:
62                theItem.setSecsUntilNotify_(SECS_IN_HOUR/4)
63            elif idx == NotifyLengthHour:
64                theItem.setSecsUntilNotify_(SECS_IN_HOUR)
65            elif idx == NotifyLengthDay:
66                theItem.setSecsUntilNotify_(SECS_IN_DAY)
67            elif idx == NotifyLengthOther:
68                theItem.setSecsUntilNotify_(
69                    infoNotifyOtherHours.intValue() *
70                    SECS_IN_HOUR)
71            else:
72                NSLog("Error in selectedRow")
73        elif sender is self.infoSchedComplete:
74            if theItem:
75                theItem.setStatus_(COMPLETE)
76        elif sender is self.infoSchedMatrix:
77            # left as an exercise in the objective-C code
78            pass
79
80        self.updateInfoWindow()
81        self._inspectingDocument.selectedItemModified()
82
83    def textDidChange_(self, notification):
84        if notification.object() is self.infoNotes:
85            self._inspectingDocument.selectedItem().setNotes_(self.infoNotes.string())
86            self._inspectingDocument.selectItemModified()
87
88    def textDidEndEditing_(self, notification):
89        if notification.object() is self.infoNotes:
90            self._inspectingDocument.selectedItem().setNotes_(infoNotes.string())
91            self._inspectingDocument.selectedItemModified()
92
93
94
95    def controlTextDidEndEditing_(self, notification):
96        #print "controlTextDidEndEditing:", notification.description()
97        dueSecs = 0
98        theItem = self._inspectingDocument.selectedItem()
99        if theItem is None:
100            return
101
102        if (notification.object() is self.infoNotifyHour) or \
103           (notification.object() is self.infoNotifyMinute):
104
105            dueSecs = ConvertTimeToSeconds(
106                 self.infoNotifyHour.intValue(),
107                self.infoNotifyMinute.intValue(),
108                self.infoNotifyAMPM.cellAtRow_column_(1,0).state())
109            #print "New dueSecs: ", dueSecs
110            #theItem.setSecsUntilDue_(dueSecs)
111        elif notification.object() is self.infoNotifyOtherHours:
112            if self.infoNotifySwitchMatrix.selectedRow() == NotifyLengthOther:
113                theItem.setSecsUntilNotify_(self.infoNotifyOtherHours.intValue() * SECS_IN_HOUR)
114            else:
115                return
116        elif notification.object() is self.infoSchedDate:
117            # Left as an exercise
118            pass
119
120        self._inspectingDocument.selectedItemModified()
121
122
123    @classmethod
124    def sharedInfoWindowController(self):
125        global _sharedInfoWindowController
126
127        if not _sharedInfoWindowController:
128            _sharedInfoWindowController = InfoWindowController.alloc().init()
129
130        return _sharedInfoWindowController
131
132
133    def init(self):
134        # XXX: Not sure if the native code works correctly if the return value
135        # from super != self.
136        self = self.initWithWindowNibName_("ToDoInfoWindow")
137        if self:
138            self.setWindowFrameAutosaveName_("Info")
139
140        return self
141
142    def dump_outlets(self):
143        print 'dummyView', self.dummyView
144        print 'infoDate', self.infoDate
145        print 'infoItem', self.infoItem
146        print 'infoNotes', self.infoNotes
147        print 'infoNotifyAMPM', self.infoNotifyAMPM
148        print 'infoNotifyHour', self.infoNotifyHour
149        print 'infoNotifyMinute', self.infoNotifyMinute
150        print 'infoNotifyOtherHours', self.infoNotifyOtherHours
151        print 'infoNotifySwitchMatrix', self.infoNotifySwitchMatrix
152        print 'infoPopUp', self.infoPopUp
153        print 'infoSchedComplet', self.infoSchedComplete
154        print 'infoSchedDate', self.infoSchedDate
155        print 'infoSchedMatrix', self.infoSchedMatrix
156        print 'infoWindowViews', self.infoWindowViews
157        print 'notesView', self.notesView
158        print 'notifyView', self.notifyView
159        print 'reschedView', self.reschedView
160
161    def windowDidLoad(self):
162        NSWindowController.windowDidLoad(self)
163
164        # XXX: The calls to retain may not be necessary.
165        self.notifyView.retain()
166        self.notifyView.removeFromSuperview()
167
168        self.reschedView.retain()
169        self.reschedView.removeFromSuperview()
170
171        self.notesView.retain()
172        self.notesView.removeFromSuperview()
173
174        self.infoWindowViews = None
175
176        self.infoNotes.setDelegate_(self)
177        self.swapInfoWindowView_(self)
178        self.setMainWindow_(NSApp().mainWindow())
179        self.updateInfoWindow()
180
181        NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(
182            self, "mainWindowChanged:",
183            NSWindowDidBecomeMainNotification,
184            None)
185
186        NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(
187            self, "mainWindowResigned:",
188            NSWindowDidResignMainNotification,
189            None)
190
191        NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(
192            self, "selectedItemChanged:",
193            ToDoItemChangedNotification,
194            None)
195
196
197
198    def __del__(self): # dealloc
199
200        NSNotificationCenter.defaultCenter().removeObserver_(self)
201
202        # Cannot to this
203        NSWindowController.dealloc(self)
204
205    def updateInfoWindow(self):
206        minute = 0
207        hour = 0
208
209        selected = self.infoPopUp.selectedItem().tag()
210        selectedItem = self._inspectingDocument.selectedItem()
211
212        if isinstance(selectedItem, ToDoItem):
213            self.infoItem.setStringValue_(selectedItem.itemName())
214            self.infoDate.setStringValue_(
215                selectedItem.day().descriptionWithCalendarFormat_timeZone_locale_("%a, %b %d %Y", NSTimeZone.localTimeZone(), None))
216
217            if selected == NOTIFY_TAG:
218                dueSecs = selectedItem.secsUntilDue()
219                hour, minutes, pmFlag = ConvertSecondsToTime(dueSecs)
220                self.infoNotifyAMPM.cellAtRow_column_(0, 0).setState_(not pmFlag)
221                self.infoNotifyAMPM.cellAtRow_column_(1, 0).setState_(pmFlag)
222                self.infoNotifyHour.setIntValue_(hour)
223                self.infoNotifyMinute.setIntValue_(minute)
224
225                notifySecs = selectedItem.secsUntilNotify()
226                clearButtonMatrix(self.infoNotifySwitchMatrix)
227
228                if notifySecs == 0:
229                    self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthNone, 0).setState_(NSOnState)
230                elif notifySecs == SECS_IN_HOUR / 4:
231                    self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthQuarter, 0).setState_(NSOnState)
232                elif notifySecs == SECS_IN_HOUR:
233                    self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthHour, 0).setState_(NSOnState)
234                elif notifySecs == SECS_IN_DAY:
235                    self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthDay, 0).setState_(NSOnState)
236                else:
237                    self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthOther, 0).setState_(NSOnState)
238                    self.infoNotifyOtherHours.setIntValue_(notifySecs / SECS_IN_HOUR)
239            elif selected == RESCHEDULE_TAG:
240                # left as an exercise
241                pass
242            elif selected == NOTES_TAG:
243                self.infoNotes.setString_(selectedItem.notes())
244        else:
245            self.infoItem.setStringValue_("")
246            self.infoDate.setStringValue_("")
247            self.infoNotifyHour.setStringValue_("")
248            self.infoNotifyMinute.setStringValue_("")
249            self.infoNotifyAMPM.cellAtRow_column_(0, 0).setState_(NSOnState)
250            self.infoNotifyAMPM.cellAtRow_column_(1, 0).setState_(NSOffState)
251            clearButtonMatrix(self.infoNotifySwitchMatrix)
252            self.infoNotifySwitchMatrix.cellAtRow_column_(NotifyLengthNone, 0).setState_(NSOnState)
253            self.infoNotifyOtherHours.setStringValue_("")
254            self.infoNotes.setString_("")
255
256    def setMainWindow_(self, mainWindow):
257        if not mainWindow:
258            return
259
260        controller = mainWindow.windowController()
261
262        if isinstance(controller.document(), ToDoDocument):
263            self._inspectingDocument = controller.document()
264        else:
265            self._inspectingDocument = None
266
267        self.updateInfoWindow()
268
269
270    def mainWindowChanged_(self, notification):
271        self.setMainWindow_(notification.object())
272
273    def mainWindowResigned_(self, notification):
274        self.setMainWindow_(None)
275
276    @objc.IBAction
277    def swapInfoWindowView_(self, sender):
278        selected = self.infoPopUp.selectedItem().tag()
279
280        if selected == NOTIFY_TAG:
281            newView = self.notifyView
282        elif selected == RESCHEDULE_TAG:
283            newView = self.reschedView
284        elif selected == NOTES_TAG:
285            newView = self.notesView
286
287        if self.dummyView.contentView() != newView:
288            self.dummyView.setContentView_(newView)
289
290    def selectedItemChanged_(self, notification):
291        self.updateInfoWindow()
292
293
294def clearButtonMatrix(matrix):
295    rows, cols = matrix.getNumberOfRows_columns_()
296
297    for i in range(rows):
298        cell = matrix.cellAtRow_column_(i, 0)
299        if cell: cell.setState_(False)
300