Module calendarentryeditor
|
|
1
2
3
4
5
6
7
8
9
10 from __future__ import with_statement
11 import calendar
12 import copy
13 import datetime
14 import time
15
16 import wx
17 import wx.lib
18 import wx.lib.masked.textctrl
19 import wx.lib.intctrl
20 import wx.lib.scrolledpanel as scrolled
21
22 import bpcalendar
23 import field_color
24 import helpids
25 import phonebookentryeditor as pb_editor
26 import pubsub
27 import guihelper
28 import guiwidgets
29
30 widgets_list=[]
31
33 _repeat_type= {
34 'daily': 1,
35 'weekly': 2,
36 'monthly': 3,
37 'yearly': 4 }
38 _repeat_options=('None', 'Daily', 'Weekly', 'Monthly', 'Yearly')
39 _dow=('Sun', 'Mon', 'Tues', 'Wed', 'Thu', 'Fri', 'Sat')
40 _monthly_nth_day=('First', 'Second', 'Third', 'Fourth', 'Last')
41 _daily_option_index=0
42 _weekly_option_index=1
43 _monthly_option_index=2
44 _weekly_wkst_str=(None, 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
45 _weekly_wkst_idx=(7, 1, 2, 3, 4, 5, 6)
46
48 global widgets_list
49 pb_editor.DirtyUIBase.__init__(self, parent)
50
51 self._main_bs=wx.BoxSizer(wx.VERTICAL)
52
53 hbs_1=wx.BoxSizer(wx.HORIZONTAL)
54 self._repeat_option_rb = wx.RadioBox(
55 self, -1, "Repeat Types:", wx.DefaultPosition, wx.DefaultSize,
56 self._repeat_options, 1, wx.RA_SPECIFY_COLS)
57 widgets_list.append((self._repeat_option_rb, 'repeat'))
58 wx.EVT_RADIOBOX(self, self._repeat_option_rb.GetId(), self.OnRepeatType)
59 hbs_1.Add(self._repeat_option_rb, 0, wx.LEFT, 5)
60
61 self._option_bs=wx.BoxSizer(wx.VERTICAL)
62 _box=wx.StaticBox(self, -1, 'Daily Options:')
63 widgets_list.append((_box, 'repeat'))
64 vbs=wx.StaticBoxSizer(_box, wx.VERTICAL)
65 hbs=wx.BoxSizer(wx.HORIZONTAL)
66 self._dl_every_nday=wx.RadioButton(self, -1, 'Every ', style=wx.RB_GROUP)
67 self._dl_every_nday.SetValue(True)
68 self._dl_every_wday=wx.RadioButton(self, -1, 'Every Weekday')
69 wx.EVT_RADIOBUTTON(self, self._dl_every_nday.GetId(), self.OnDirtyUI)
70 wx.EVT_RADIOBUTTON(self, self._dl_every_wday.GetId(), self.OnDirtyUI)
71 hbs.Add(self._dl_every_nday, 0, wx.LEFT, 0)
72 self._dl_interval=wx.TextCtrl(self, -1, '1')
73 wx.EVT_TEXT(self, self._dl_interval.GetId(), self.OnDirtyUI)
74 hbs.Add(self._dl_interval, 0, wx.LEFT, 0)
75 hbs.Add(wx.StaticText(self, -1, ' day(s)'), 0, wx.LEFT, 0)
76 vbs.Add(hbs, 0, wx.LEFT|wx.TOP, 10)
77 vbs.Add(self._dl_every_wday, 0, wx.LEFT, 10)
78 self._option_bs.Add(vbs, 0, wx.LEFT, 5)
79 self._daily_option_bs=vbs
80
81 _box=wx.StaticBox(self, -1, 'Weekly Options:')
82 widgets_list.append((_box, 'repeat'))
83 vbs=wx.StaticBoxSizer(_box, wx.VERTICAL)
84 hbs=wx.BoxSizer(wx.HORIZONTAL)
85 hbs.Add(wx.StaticText(self, -1, 'Every '),0, wx.LEFT, 0)
86 self._wl_interval=wx.TextCtrl(self, -1, '1')
87 wx.EVT_TEXT(self, self._wl_interval.GetId(), self.OnDirtyUI)
88 hbs.Add(self._wl_interval, 0, wx.LEFT, 0)
89 hbs.Add(wx.StaticText(self, -1, ' week(s)'), 0, wx.LEFT, 0)
90 vbs.Add(hbs, 0, wx.LEFT|wx.TOP, 10)
91 vbs.Add(wx.StaticText(self, -1, 'On:'), 0, wx.LEFT, 10)
92 hbs=wx.GridSizer(2, 4)
93 self._wl_dow={}
94 for i, n in enumerate(self._dow):
95 self._wl_dow[i]=wx.CheckBox(self, -1, n)
96 wx.EVT_CHECKBOX(self, self._wl_dow[i].GetId(), self.OnDirtyUI)
97 hbs.Add(self._wl_dow[i], 0, wx.LEFT|wx.TOP, 5)
98 vbs.Add(hbs, 0, wx.LEFT, 5)
99 hbs=wx.BoxSizer(wx.HORIZONTAL)
100 hbs.Add(wx.StaticText(self, -1, 'Week starts on:'), 0, wx.LEFT, 10)
101 self._wl_wkst=wx.ComboBox(self, -1, value=self._dow[0],
102 choices=self._dow, style=wx.CB_READONLY)
103 wx.EVT_COMBOBOX(self, self._wl_wkst.GetId(), self.OnDirtyUI)
104 hbs.Add(self._wl_wkst, 0, wx.LEFT, 5)
105 vbs.Add(hbs, 0, wx.TOP, 10)
106 self._option_bs.Add(vbs, 0, wx.LEFT, 5)
107 self._weekly_option_bs=vbs
108
109 _box=wx.StaticBox(self, -1, 'Monthly Options:')
110 widgets_list.append((_box, 'repeat'))
111 vbs=wx.StaticBoxSizer(_box, wx.VERTICAL)
112 hbs=wx.BoxSizer(wx.HORIZONTAL)
113 hbs.Add(wx.StaticText(self, -1, 'Every '),0, wx.LEFT, 0)
114 self._ml_interval=wx.TextCtrl(self, -1, '1')
115 wx.EVT_TEXT(self, self._ml_interval.GetId(), self.OnDirtyUI)
116 hbs.Add(self._ml_interval, 0, wx.LEFT, 0)
117 hbs.Add(wx.StaticText(self, -1, ' month(s)'), 0, wx.LEFT, 0)
118 vbs.Add(hbs, 0, wx.LEFT|wx.TOP, 10)
119 vbs.Add(wx.StaticText(self, -1, 'On:'), 0, wx.LEFT, 10)
120 self._ml_every_nday=wx.RadioButton(self, -1, 'Every nth day', style=wx.RB_GROUP)
121 self._ml_every_nday.SetValue(True)
122 self._ml_every_wday=wx.RadioButton(self, -1, 'Every ')
123 wx.EVT_RADIOBUTTON(self, self._ml_every_nday.GetId(), self.OnDirtyUI)
124 wx.EVT_RADIOBUTTON(self, self._ml_every_wday.GetId(), self.OnDirtyUI)
125 vbs.Add(self._ml_every_nday, 0, wx.LEFT|wx.TOP, 10)
126 hbs=wx.BoxSizer(wx.HORIZONTAL)
127 hbs.Add(self._ml_every_wday, 0, wx.LEFT, 0)
128 self._ml_nth_day=wx.ComboBox(self, -1, value=self._monthly_nth_day[0],
129 choices=self._monthly_nth_day,
130 style=wx.CB_READONLY)
131 self._ml_wday=wx.ComboBox(self, -1, value=self._dow[0],
132 choices=self._dow, style=wx.CB_READONLY)
133 wx.EVT_COMBOBOX(self, self._ml_nth_day.GetId(), self.OnDirtyUI)
134 wx.EVT_COMBOBOX(self, self._ml_wday.GetId(), self.OnDirtyUI)
135 hbs.Add(self._ml_nth_day, 0, wx.LEFT, 5)
136 hbs.Add(self._ml_wday, 0, wx.LEFT, 5)
137 vbs.Add(hbs, 0, wx.LEFT|wx.TOP, 10)
138
139 self._option_bs.Add(vbs, 0, wx.LEFT, 5)
140 self._monthly_option_bs=vbs
141
142 hbs_1.Add(self._option_bs, 0, wx.LEFT, 5)
143 self._main_bs.Add(hbs_1, 0, wx.LEFT|wx.TOP, 5)
144
145 _box=wx.StaticBox(self, -1, 'Excluded Dates:')
146 widgets_list.append((_box, 'repeat'))
147 hbs=wx.StaticBoxSizer(_box, wx.HORIZONTAL)
148 self._exception_list=wx.ListBox(self, -1)
149 hbs.Add(self._exception_list, 1, wx.LEFT|wx.TOP|wx.EXPAND, 5)
150 exception_del=wx.Button(self, -1, 'Include')
151 wx.EVT_BUTTON(self, exception_del.GetId(), self.OnIncludeException)
152 hbs.Add(exception_del, 0, wx.LEFT|wx.TOP, 5)
153 self._main_bs.Add(hbs, 1, wx.LEFT|wx.TOP|wx.EXPAND, 5)
154
155 self.SetSizer(self._main_bs)
156 self.SetAutoLayout(True)
157 self._main_bs.Fit(self)
158 self.OnRepeatType(None)
159
202
203 - def Set(self, data):
204 self.ignore_dirty=True
205 self.populate(data)
206 self.dirty=self.ignore_dirty=False
207
251
275
289
298
299
301 _dict_key_index=0
302 _label_index=1
303 _class_index=2
304 _get_index=3
305 _set_index=4
306 _w_index=5
307 color_field_name='general'
309 global widgets_list
310
311 pb_editor.DirtyUIBase.__init__(self, parent)
312
313 self._fields=[
314 ['description', 'Summary:', DVTextControl, None, None, None],
315 ['location', 'Location:', DVTextControl, None, None, None],
316 ['allday', 'All-Day:', wx.CheckBox, None, None, None],
317 ['start', 'From:', DVDateTimeControl, None, self._set_start_datetime, None],
318 ['end', 'To:', DVDateTimeControl, None, self._set_end_datetime, None],
319 ['priority', 'Priority:', None, self._get_priority, self._set_priority, None],
320 ['alarm', 'Alarm:', DVIntControl, None, None, None],
321 ['vibrate', 'Vibrate:', wx.CheckBox, None, None, None],
322 ]
323
324 vbs=wx.StaticBoxSizer(wx.StaticBox(self, -1), wx.VERTICAL)
325
326 self._w={}
327 gs=wx.FlexGridSizer(-1,2,5,5)
328 gs.AddGrowableCol(1)
329 for n in self._fields:
330 desc=n[self._label_index]
331 t=wx.StaticText(self, -1, desc, style=wx.ALIGN_LEFT)
332 widgets_list.append((t, n[self._dict_key_index]))
333 gs.Add(t)
334 if desc=='Priority:':
335 c=wx.ComboBox(self, -1, "", (-1, -1), (-1, -1),
336 ['<None>', '1 - Highest', '2', '3', '4', '5 - Normal',
337 '6', '7' ,'8', '9', '10 - Lowest'], wx.CB_DROPDOWN)
338 else:
339 c=n[self._class_index](self, -1)
340 gs.Add(c, 0, wx.EXPAND, 0)
341 n[self._w_index]=self._w[n[self._dict_key_index]]=c
342 vbs.Add(gs, 0, wx.EXPAND|wx.ALL, 5)
343
344 wx.EVT_CHECKBOX(self, self._w['allday'].GetId(), self.OnAllday)
345 wx.EVT_CHECKBOX(self, self._w['vibrate'].GetId(), self.OnDirtyUI)
346 wx.EVT_COMBOBOX(self, self._w['priority'].GetId(), self.OnDirtyUI)
347
348 self.SetSizer(vbs)
349 self.SetAutoLayout(True)
350 vbs.Fit(self)
351
354
360
380
381 - def Set(self, data):
395
396 - def Get(self, data):
407
420
423
426
427
429
430
431
432 unnamed="Select:"
433
435 global widgets_list
436
437 pb_editor.DirtyUIBase.__init__(self, parent)
438 self.static_box=wx.StaticBox(self, -1, "Category")
439 hs=wx.StaticBoxSizer(self.static_box, wx.HORIZONTAL)
440
441 self.categories=[]
442 self.category=wx.ListBox(self, -1, choices=self.categories)
443 pubsub.subscribe(self.OnUpdateCategories, pubsub.ALL_CATEGORIES)
444 pubsub.publish(pubsub.REQUEST_CATEGORIES)
445
446 vbs=wx.BoxSizer(wx.VERTICAL)
447 vbs.Add(wx.StaticText(self, -1, 'Master Category'), 0,
448 wx.TOP|wx.LEFT, 5)
449 vbs.Add(self.category, 1, wx.EXPAND|wx.ALL, 5)
450 hs.Add(vbs, 1, wx.EXPAND|wx.ALL, 5)
451
452 vbs=wx.BoxSizer(wx.VERTICAL)
453 self.but=wx.Button(self, wx.NewId(), "Manage Categories:")
454 add_btn=wx.Button(self, -1, 'Add ->')
455 del_btn=wx.Button(self, -1, '<- Remove')
456 vbs.Add(self.but, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
457 vbs.Add(add_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
458 vbs.Add(del_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
459 hs.Add(vbs, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
460 wx.EVT_BUTTON(self, add_btn.GetId(), self.OnAddCategory)
461 wx.EVT_BUTTON(self, del_btn.GetId(), self.OnDelCategory)
462
463 vbs=wx.BoxSizer(wx.VERTICAL)
464 vbs.Add(wx.StaticText(self, -1, 'Selected Category:'), 0,
465 wx.TOP|wx.LEFT, 5)
466 self._my_category=wx.ListBox(self, -1)
467 vbs.Add(self._my_category, 1, wx.EXPAND|wx.ALL, 5)
468 hs.Add(vbs, 1, wx.EXPAND|wx.ALL, 5)
469 wx.EVT_BUTTON(self, self.but.GetId(), self.OnManageCategories)
470
471 self.SetSizer(hs)
472 hs.Fit(self)
473
478
492
494 self.ignore_dirty=self.dirty=False
495 r=[]
496 count=self._my_category.GetCount()
497 if count==0:
498 return r
499 for i in range(count):
500 r.append({ 'category': self._my_category.GetString(i) })
501 return r
502
503 - def Set(self, data):
504 self.ignore_dirty=True
505 self._my_category.Clear()
506 if data is None or len(data)==0:
507
508 return
509 for n in data:
510 v=n.get('category', None)
511 if v is not None:
512 self._my_category.Append(v)
513 self.ignore_dirty=self.dirty=False
514
525
527 v=self._my_category.GetSelection()
528 if v==wx.NOT_FOUND:
529
530 return
531 self.ignore_dirty=True
532 self._my_category.Delete(v)
533 self.ignore_dirty=False
534 self.OnDirtyUI(evt)
535
536
538
539
540
541 ANSWER_ORIGINAL=1
542 ANSWER_THIS=2
543 ANSWER_CANCEL=3
544 _dict_key_index=0
545 _label_index=1
546 _get_index=2
547 _set_index=3
548 _w_index=4
549
550 _general_page=0
551 _repeat_page=1
552 _notes_page=2
553 _categories_page=3
554 _wallpapers_page=4
555 _ringtones_page=5
556 _last_page=6
557 _items=[
558 ("General", None, GeneralEditor, None),
559 ("Repeat", 'repeat', RepeatEditor, None),
560 ("Notes", "notes", pb_editor.MemoEditor, 'memo'),
561 ("Categories", "categories", CategoryEditor, 'category'),
562 ("Wallpapers", "wallpapers", pb_editor.WallpaperEditor, 'wallpaper'),
563 ("Ringtones", "ringtones", pb_editor.RingtoneEditor, 'ringtone'),
564 ]
565 color_field_name='calendar'
566
568 global widgets_list
569 wx.Dialog.__init__(self, parent, -1, 'Calendar Entry Editor',
570 wx.DefaultPosition,
571 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
572
573 self.cw=parent
574
575
576
577 self.entries=[]
578 self.entrymap=[]
579 self._current_entry=None
580
581
582
583
584
585
586 self.dirty=None
587 self.ignoredirty=True
588
589
590 vbs=wx.BoxSizer(wx.VERTICAL)
591
592 self._prev_btn=wx.BitmapButton(self, wx.NewId(), wx.ArtProvider.GetBitmap(guihelper.ART_ARROW_LEFT), name="Previous Day")
593 self._next_btn=wx.BitmapButton(self, wx.NewId(), wx.ArtProvider.GetBitmap(guihelper.ART_ARROW_RIGHT), name="Next Day")
594 self.title=wx.StaticText(self, -1, "Date here", style=wx.ALIGN_CENTRE|wx.ST_NO_AUTORESIZE)
595
596
597 hbs1=wx.BoxSizer(wx.HORIZONTAL)
598 hbs1.Add(self._prev_btn, 0, wx.EXPAND)
599 hbs1.Add(self.title, 1, wx.EXPAND)
600 hbs1.Add(self._next_btn, 0, wx.EXPAND)
601 vbs.Add(hbs1, 0, wx.TOP|wx.EXPAND, 10)
602
603
604 self.listbox=wx.ListBox(self, wx.NewId(), style=wx.LB_SINGLE|wx.LB_HSCROLL|wx.LB_NEEDED_SB)
605 self._add_btn=wx.Button(self, wx.ID_NEW)
606 hbs2=wx.BoxSizer(wx.HORIZONTAL)
607 hbs2.Add(self._add_btn, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, border=5)
608
609
610 lbs=wx.BoxSizer(wx.VERTICAL)
611 lbs.Add(self.listbox, 1, wx.EXPAND|wx.BOTTOM, border=5)
612 lbs.Add(hbs2, 0, wx.EXPAND)
613
614
615 self._nb=wx.Notebook(self, -1)
616 self._widgets=[]
617 for i, (name, key, klass, color_name) in enumerate(self._items):
618 if name in ('Ringtones', 'Wallpapers'):
619 self._widgets.append(klass(self._nb, parent, False))
620 else:
621 self._widgets.append(klass(self._nb, parent))
622 self._nb.AddPage(self._widgets[i], name)
623 if color_name:
624 widgets_list.append((self._widgets[i].static_box, color_name))
625
626
627 self._delete_btn=wx.Button(self, wx.ID_DELETE)
628 self._revert_btn=wx.Button(self, wx.ID_REVERT_TO_SAVED)
629 self._save_btn=wx.Button(self, wx.ID_SAVE)
630
631 hbs4=wx.BoxSizer(wx.HORIZONTAL)
632 hbs4.Add(self._delete_btn, 1, wx.ALIGN_CENTRE|wx.LEFT, border=10)
633 hbs4.Add(self._revert_btn, 1, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT, border=10)
634 hbs4.Add(self._save_btn, 1, wx.ALIGN_CENTRE|wx.RIGHT, border=10)
635
636
637 vbs2=wx.BoxSizer(wx.VERTICAL)
638 vbs2.Add(self._nb, 1, wx.EXPAND|wx.BOTTOM, border=5)
639 vbs2.Add(hbs4, 0, wx.EXPAND|wx.ALIGN_CENTRE)
640
641
642 hbs3=wx.BoxSizer(wx.HORIZONTAL)
643 hbs3.Add(lbs, 1, wx.EXPAND|wx.ALL, 5)
644 hbs3.Add(vbs2, 2, wx.EXPAND|wx.ALL, 5)
645 vbs.Add(hbs3, 1, wx.EXPAND)
646
647 vbs.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL), 0, wx.EXPAND|wx.ALL, 5)
648 vbs.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
649
650 self.SetSizer(vbs)
651 self.SetAutoLayout(True)
652 vbs.Fit(self)
653
654 self._delete_btn.Enable(False)
655
656 wx.EVT_LISTBOX(self, self.listbox.GetId(), self.OnListBoxItem)
657 wx.EVT_LISTBOX_DCLICK(self, self.listbox.GetId(), self.OnListBoxItem)
658 wx.EVT_BUTTON(self, wx.ID_SAVE, self.OnSaveButton)
659 wx.EVT_BUTTON(self, wx.ID_REVERT_TO_SAVED, self.OnRevertButton)
660 wx.EVT_BUTTON(self, wx.ID_NEW, self.OnNewButton)
661 wx.EVT_BUTTON(self, wx.ID_DELETE, self.OnDeleteButton)
662 wx.EVT_BUTTON(self, self._prev_btn.GetId(), self.OnPrevDayButton)
663 wx.EVT_BUTTON(self, self._next_btn.GetId(), self.OnNextDayButton)
664
665 wx.EVT_BUTTON(self, wx.ID_OK, self.OnOk)
666 wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel)
667 wx.EVT_BUTTON(self, wx.ID_HELP, lambda _: wx.GetApp().displayhelpid(helpids.ID_EDITING_CALENDAR_EVENTS))
668
669 for w in self._widgets:
670 pb_editor.EVT_DIRTY_UI(self, w.GetId(), self.OnMakeDirty)
671 self.ignoredirty=False
672 self.setdirty(False)
673 guiwidgets.set_size("CalendarEntryEditor", self, 52, 1.0)
674 field_color.reload_color_info(self, widgets_list)
675 pubsub.subscribe(self.OnPhoneChanged, pubsub.PHONE_MODEL_CHANGED)
676
681
683 """Callback for when user clicks on an event in the listbox"""
684 self._current_entry=self.getcurrententry()
685 if self._current_entry:
686 self.updatefields(self._current_entry)
687 self.setdirty(False)
688 self._delete_btn.Enable(True)
689
690 - def getcurrententry(self):
691 """Returns the entry currently being viewed
692
693 @Note: this returns the unedited form of the entry"""
694 i=self.listbox.GetSelection()
695 if i==-1:
696 return None
697 return self.getentry(i)
698
699 - def getentry(self, num):
700 """maps from entry number in listbox to an entry in entries
701
702 @type num: int
703 @rtype: entry(dict)"""
704 return self.entries[self.entrymap[num]]
705
770
771 - def OnOk(self, evt):
778
784
790
796
824
829
834
835 - def setdate(self, year, month, day, entry=None):
836 """Sets the date we are editing entries for
837
838 @Note: The list of entries is updated"""
839 d=time.strftime("%A %d %B %Y", (year,month,day,0,0,0, calendar.weekday(year,month,day),1, 0))
840 self.date=year,month,day
841 self.title.SetLabel(d)
842 self.refreshentries()
843 self.updatelistbox(entry and entry.id or None)
844 self.updatefields(entry)
845
847 """re-requests the list of entries for the currently visible date from the main calendar"""
848 self.entries=self.cw.getentrydata(*self.date)
849
851 """
852 Updates the contents of the listbox. It will re-sort the contents.
853
854 @param entrytoselect: The integer id of an entry to select. Note that
855 this is an event id, not an index
856 """
857 self.listbox.Clear()
858 selectitem=-1
859 self.entrymap=[]
860 self._current_entry=None
861
862 for index, entry in enumerate(self.entries):
863 if entry.allday:
864 e=( entry.start[3:5], entry.end[3:5], entry.description, index)
865 else:
866 e=(None, None, entry.description, index)
867 self.entrymap.append(e)
868
869 self.entrymap.sort()
870
871 self.entrymap=[index for ign0, ign1, ign2, index in self.entrymap]
872
873 for curpos, index in enumerate(self.entrymap):
874 e=self.entries[index]
875 if e.id==entrytoselect:
876 selectitem=curpos
877 self.listbox.Append(e.summary)
878
879
880 if selectitem>=0:
881 self.listbox.SetSelection(selectitem)
882 self.OnListBoxItem()
883 else:
884
885 self.updatefields(None)
886
887
888 if len(self.entries)==0:
889 self._delete_btn.Enable(False)
890
912
913
915 """A public function you can call that will set the dirty flag"""
916 if self.dirty or self.ignoredirty or not self.IsShown():
917
918 return
919 self.setdirty(True)
920
922 """Set the dirty flag
923
924 The various buttons in the dialog are enabled/disabled as appropriate
925 for the new state.
926
927 @type val: Bool
928 @param val: True to mark edit fields as different from entry (ie
929 editing has taken place)
930 False to make them as the same as the entry (ie no
931 editing or the edits have been discarded)
932 """
933 if self.ignoredirty:
934 return
935 self.dirty=val
936 if self.dirty:
937
938
939
940
941 self._save_btn.Enable(True)
942 self._revert_btn.Enable(True)
943
944 self._prev_btn.Enable(False)
945 self._next_btn.Enable(False)
946 self._add_btn.Enable(False)
947
948 self.listbox.Enable(False)
949 else:
950
951
952
953 self._save_btn.Enable(False)
954 self._revert_btn.Enable(False)
955
956
957 self._delete_btn.Enable(len(self.entries)>0)
958 self._prev_btn.Enable(True)
959 self._next_btn.Enable(True)
960 self._add_btn.Enable(True)
961
962
963 self.listbox.Enable(True)
964
966 """Asks the user if they wish to delete the original (repeating) entry, or this instance
967
968 @return: An C{ANSWER_} constant
969 """
970 return self._AskAboutRecurringEvent("Delete recurring event?", "Do you want to delete all the recurring events, or just this one?", "Delete")
971
973 """Asks the user if they wish to change the original (repeating) entry, or this instance
974
975 @return: An C{ANSWER_} constant
976 """
977 return self._AskAboutRecurringEvent("Change recurring event?", "Do you want to change all the recurring events, or just this one?", "Change")
978
989
990
991
992
994 """A datetime control customised to work in the dayview editor"""
996 self._allday=False
997 self._datetime_format="EUDATETIMEYYYYMMDD.HHMM"
998 self._date_format='EUDATEYYYYMMDD.'
999 wx.Panel.__init__(self, parent, -1)
1000 self.c=wx.lib.masked.textctrl.TextCtrl(\
1001 self, id, "", autoformat=self._datetime_format,
1002 emptyInvalid=True,
1003 emptyBackgroundColour='Red',
1004 invalidBackgroundColour='Red')
1005 bs=wx.BoxSizer(wx.HORIZONTAL)
1006 bs.Add(self.c,0,wx.EXPAND)
1007 self.SetSizer(bs)
1008 self.SetAutoLayout(True)
1009 bs.Fit(self)
1010 wx.EVT_TEXT(self.c, id, parent.OnMakeDirty)
1011
1013 if v is None:
1014 self.c.SetValue("")
1015 return
1016 if self._allday:
1017 str="%04d%02d%02d" % tuple(v[:3])
1018 else:
1019 ap="AM"
1020 v=list(v)
1021 if v[3]>12:
1022 v[3]-=12
1023 ap="PM"
1024 elif v[3]==0:
1025 v[3]=12
1026 elif v[3]==12:
1027 ap="PM"
1028 v=v+[ap]
1029
1030
1031 str="%04d%02d%02d%02d%02d%s" % tuple(v)
1032 self.c.SetValue( str )
1033 self.c.Refresh()
1034
1036
1037
1038 str=self.c.GetValue()
1039 digits="0123456789"
1040
1041
1042 res=[]
1043 val=None
1044 for i in str:
1045 if i in digits:
1046 if val is None: val=0
1047 val*=10
1048 val+=int(i)
1049 else:
1050 if val is not None:
1051 res.append(val)
1052 val=None
1053 if val is not None:
1054 res.append(val)
1055 if len(res)==3:
1056 res += [0,0]
1057 elif len(res)==5:
1058
1059 if str[-2]=='P' or str[-2]=='p':
1060 if res[3]!=12:
1061 res[3]+=12
1062 elif res[3]==12:
1063 res[3]=0
1064
1065 return res
1066
1071
1073 if allday==self._allday and v is None:
1074 return
1075 if v is None:
1076 v=self.GetValue()
1077 if allday != self._allday:
1078 self._allday=allday
1079 if self._allday:
1080 self.c.SetCtrlParameters(autoformat=self._date_format)
1081 else:
1082 self.c.SetCtrlParameters(autoformat=self._datetime_format)
1083 self.SetValue(v)
1084
1085
1087
1089 wx.lib.intctrl.IntCtrl.__init__(self, parent, id, limited=True)
1090 wx.lib.intctrl.EVT_INT(self, id, parent.OnMakeDirty)
1091
1093 if v is None:
1094 v=-1
1095 wx.lib.intctrl.IntCtrl.SetValue(self,int(v))
1096
1097
1098 -class DVTextControl(wx.TextCtrl):
1099 - def __init__(self, parent, id, value=""):
1100 if value is None:
1101 value=""
1102 wx.TextCtrl.__init__(self, parent, id, value)
1103 wx.EVT_TEXT(self, id, parent.OnMakeDirty)
1104
1105 - def SetValue(self, v):
1106 if v is None: v=""
1107 wx.TextCtrl.SetValue(self,v)
1108
1109
1110
1111
1112
1113
1114
1116 """Ask the user what they want to do about a recurring event
1117
1118 You should only use this as a modal dialog. ShowModal() will
1119 return one of:
1120
1121 - ID_THIS: change just this event
1122 - ID_ALL: change all events
1123 - ID_CANCEL: user cancelled dialog"""
1124 ID_THIS=1
1125 ID_ALL=2
1126 ID_CANCEL=3
1127 ID_HELP=4
1128
1129 - def __init__(self, parent, caption, text, prefix):
1130 """Constructor
1131
1132 @param parent: frame to parent this to
1133 @param caption: caption of the dialog (eg C{"Change recurring event?"})
1134 @param text: text displayed in the dialog (eg C{"This is a recurring event. What would you like to change?"})
1135 @param prefix: text prepended to the buttons (eg the button says " this" so the prefix would be "Change" or "Delete")
1136 """
1137 wx.Dialog.__init__(self, parent, -1, caption,
1138 style=wx.CAPTION)
1139
1140
1141 vbs=wx.BoxSizer(wx.VERTICAL)
1142
1143
1144 t=wx.StaticText(self, -1, text)
1145 vbs.Add(t, 1, wx.EXPAND|wx.ALL,10)
1146
1147
1148 vbs.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 3)
1149
1150
1151 buttonsizer=wx.BoxSizer(wx.HORIZONTAL)
1152 for id, label in (self.ID_THIS, "%s %s" % (prefix, "this")), \
1153 (self.ID_ALL, "%s %s" % (prefix, "all")), \
1154 (self.ID_CANCEL, "Cancel"), \
1155 (self.ID_HELP, "Help"):
1156 b=wx.Button(self, id, label)
1157 wx.EVT_BUTTON(self, id, self._onbutton)
1158 buttonsizer.Add(b, 5, wx.ALIGN_CENTER|wx.ALL, 5)
1159
1160
1161 vbs.Add(buttonsizer, 0, wx.EXPAND|wx.ALL,2)
1162 self.SetSizer(vbs)
1163 self.SetAutoLayout(True)
1164 vbs.Fit(self)
1165
1166
1172