1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import os.path
20
21 import wx
22 import webbrowser
23
24 from timelinelib.db.exceptions import TimelineIOError
25 from timelinelib.editors.event import EventEditor
26 from timelinelib.repositories.dbwrapper import DbWrapperEventRepository
27 from timelinelib.wxgui.components.categorychoice import CategoryChoice
28 from timelinelib.wxgui.dialogs.containereditor import ContainerEditorDialog
29 from timelinelib.wxgui.utils import BORDER
30 from timelinelib.wxgui.utils import _display_error_message
31 from timelinelib.wxgui.utils import _set_focus_and_select
32 from timelinelib.wxgui.utils import time_picker_for
33 import timelinelib.wxgui.utils as gui_utils
34
35
37
38 - def __init__(self, parent, config, title, timeline,
39 start=None, end=None, event=None):
50
52 properties_box = self._create_properties_box()
53 self._create_checkbox_add_more(properties_box)
54 self._create_buttons(properties_box)
55 self.SetSizerAndFit(properties_box)
56
58 properties_box = wx.BoxSizer(wx.VERTICAL)
59 self._create_propeties_controls(properties_box)
60 return properties_box
61
63 groupbox = wx.StaticBox(self, wx.ID_ANY, _("Event Properties"))
64 main_box_content = wx.StaticBoxSizer(groupbox, wx.VERTICAL)
65 self._create_detail_content(main_box_content)
66 self._create_notebook_content(main_box_content)
67 sizer.Add(main_box_content, flag=wx.EXPAND|wx.ALL,
68 border=BORDER, proportion=1)
69
70 - def _create_detail_content(self, properties_box_content):
71 details = self._create_details()
72 properties_box_content.Add(details, flag=wx.ALL|wx.EXPAND,
73 border=BORDER)
74
76 grid = wx.FlexGridSizer(4, 2, BORDER, BORDER)
77 grid.AddGrowableCol(1)
78 self._create_time_details(grid)
79 self._create_checkboxes(grid)
80 self._create_text_field(grid)
81 self._create_categories_listbox(grid)
82 self._create_container_listbox(grid)
83 return grid
84
86 grid.Add(wx.StaticText(self, label=_("When:")),
87 flag=wx.ALIGN_CENTER_VERTICAL)
88 self.dtp_start = self._create_time_picker()
89 self.lbl_to = wx.StaticText(self, label=_("to"))
90 self.dtp_end = self._create_time_picker()
91 when_box = wx.BoxSizer(wx.HORIZONTAL)
92 when_box.Add(self.dtp_start, proportion=1)
93 when_box.AddSpacer(BORDER)
94 flag = wx.ALIGN_CENTER_VERTICAL|wx.RESERVE_SPACE_EVEN_IF_HIDDEN
95 when_box.Add(self.lbl_to, flag=flag)
96 when_box.AddSpacer(BORDER)
97 when_box.Add(self.dtp_end, proportion=1,
98 flag=wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
99 grid.Add(when_box)
100
104
106 grid.AddStretchSpacer()
107 when_box = wx.BoxSizer(wx.HORIZONTAL)
108 self.chb_period = self._create_period_checkbox(when_box)
109 if self.timeline.get_time_type().is_date_time_type():
110 self.chb_show_time = self._create_show_time_checkbox(when_box)
111 self.chb_fuzzy = self._create_fuzzy_checkbox(when_box)
112 self.chb_locked = self._create_locked_checkbox(when_box)
113 self.chb_ends_today = self._create_ends_today_checkbox(when_box)
114 grid.Add(when_box)
115
117 grid.AddStretchSpacer()
118 container_box = wx.BoxSizer(wx.HORIZONTAL)
119 grid.Add(container_box)
120 self._create_containers_listbox(grid)
121
123 self.lst_containers = wx.Choice(self, wx.ID_ANY)
124 label = wx.StaticText(self, label=_("Container:"))
125 grid.Add(label, flag=wx.ALIGN_CENTER_VERTICAL)
126 grid.Add(self.lst_containers)
127 self.Bind(wx.EVT_CHOICE, self._lst_containers_on_choice,
128 self.lst_containers)
129
131 new_selection_index = e.GetSelection()
132 if new_selection_index > self.last_real_container_index:
133 self.lst_containers.SetSelection(self.current_container_selection)
134 if new_selection_index == self.add_container_item_index:
135 self._add_container()
136 elif new_selection_index == self.edit_container_item_index:
137 self._edit_containers()
138 else:
139 self.current_container_selection = new_selection_index
140 self._enable_disable_checkboxes()
141
143 self._enable_disable_ends_today()
144 self._enable_disable_locked()
145
147 enable = (self._container_not_selected() and
148 not self.chb_locked.GetValue() and
149 self.controller.start_is_in_history())
150 self.chb_ends_today.Enable(enable)
151
153 enable = self._container_not_selected()
154 self.chb_locked.Enable(enable)
155
157 index = self.lst_containers.GetSelection()
158 return (index == 0)
159
163 def handle_success(dialog):
164 if dialog.GetReturnCode() == wx.ID_OK:
165 try:
166 self._fill_containers_listbox(dialog.get_edited_container())
167 except TimelineIOError, e:
168 gui_utils.handle_db_error_in_dialog(self, e)
169 gui_utils.show_modal(create_container_editor,
170 gui_utils.create_dialog_db_error_handler(self),
171 handle_success)
172
174 handler = self._chb_period_on_checkbox
175 return self._create_chb(box, _("Period"), handler)
176
178 self._show_to_time(e.IsChecked())
179
181 handler = self._chb_show_time_on_checkbox
182 return self._create_chb(box, _("Show time"), handler)
183
187
189 handler = None
190 return self._create_chb(box, _("Fuzzy"), handler)
191
193 handler = self._chb_show_time_on_locked
194 return self._create_chb(box, _("Locked"), handler)
195
197 self._enable_disable_ends_today()
198
200 handler = None
201 return self._create_chb(box, _("Ends today"), handler)
202
204 chb = wx.CheckBox(self, label=label)
205 if handler is not None:
206 self.Bind(wx.EVT_CHECKBOX, handler, chb)
207 box.Add(chb)
208 return chb
209
210 - def _create_text_field(self, grid):
211 self.txt_text = wx.TextCtrl(self, wx.ID_ANY, name="text")
212 grid.Add(wx.StaticText(self, label=_("Text:")),
213 flag=wx.ALIGN_CENTER_VERTICAL)
214 grid.Add(self.txt_text, flag=wx.EXPAND)
215
217 self.lst_category = CategoryChoice(self, self.timeline)
218 label = wx.StaticText(self, label=_("Category:"))
219 grid.Add(label, flag=wx.ALIGN_CENTER_VERTICAL)
220 grid.Add(self.lst_category)
221 self.Bind(wx.EVT_CHOICE, self.lst_category.on_choice, self.lst_category)
222
223 - def _create_notebook_content(self, properties_box_content):
224 notebook = self._create_notebook()
225 properties_box_content.Add(notebook, border=BORDER,
226 flag=wx.ALL|wx.EXPAND, proportion=1)
227
229 self.event_data = []
230 notebook = wx.Notebook(self, style=wx.BK_DEFAULT)
231 for data_id in self.timeline.supported_event_data():
232 self._add_editor(notebook, data_id)
233 return notebook
234
236 editor_class_decription = self._get_editor_class_description(data_id)
237 if editor_class_decription is None:
238 return
239 editor = self._create_editor(notebook, editor_class_decription)
240 self.event_data.append((data_id, editor))
241
251
253 name, editor_class = editor_class_decription
254 panel = wx.Panel(notebook)
255 editor = editor_class(panel, self)
256 notebook.AddPage(panel, name)
257 sizer = wx.BoxSizer(wx.VERTICAL)
258 sizer.Add(editor, flag=wx.EXPAND, proportion=1)
259 panel.SetSizer(sizer)
260 return editor
261
263 label = _("Add more events after this one")
264 self.chb_add_more = wx.CheckBox(self, label=label)
265 properties_box.Add(self.chb_add_more, flag=wx.ALL, border=BORDER)
266
271
274
276 self.lbl_to.Show(show)
277 self.dtp_end.Show(show)
278
280
281
282
283 self.lst_containers.Clear()
284 self.lst_containers.Append("", None)
285 selection_set = False
286 current_item_index = 1
287 if select_container != None and select_container not in self.timeline.get_containers():
288 self.lst_containers.Append(select_container.text, select_container)
289 self.lst_containers.SetSelection(current_item_index)
290 current_item_index += 1
291 selection_set = True
292 for container in self.timeline.get_containers():
293 self.lst_containers.Append(container.text, container)
294 if not selection_set:
295 if container == select_container:
296 self.lst_containers.SetSelection(current_item_index)
297 selection_set = True
298 current_item_index += 1
299
300 self.last_real_container_index = current_item_index - 1
301 self.add_container_item_index = self.last_real_container_index + 2
302 self.edit_container_item_index = self.last_real_container_index + 3
303 self.lst_containers.Append("", None)
304 self.lst_containers.Append(_("Add new"), None)
305 if not selection_set:
306 self.lst_containers.SetSelection(0)
307 self.current_container_selection = self.lst_containers.GetSelection()
308 self._enable_disable_checkboxes()
309
314
319
324 return self.chb_period.IsChecked()
325
330
335
339 self.chb_locked.SetValue(locked)
340 self._enable_disable_ends_today()
341
343 return self.chb_ends_today.GetValue()
346
349
351 return self.txt_text.GetValue().strip()
352
355
357 return self.lst_category.get()
358
361
363 selection = self.lst_containers.GetSelection()
364 if selection != -1:
365 container = self.lst_containers.GetClientData(selection)
366 else:
367 container = None
368 return container
369
371 for data_id, editor in self.event_data:
372 if event_data.has_key(data_id):
373 data = event_data[data_id]
374 if data is not None:
375 editor.set_data(data)
376
378 event_data = {}
379 for data_id, editor in self.event_data:
380 data = editor.get_data()
381 if data != None:
382 event_data[data_id] = editor.get_data()
383 return event_data
384
386 self.chb_add_more.Show(visible)
387 self.chb_add_more.SetValue(False)
390
392 controls = {"start" : self.dtp_start, "text" : self.txt_text}
393 if controls.has_key(control_name):
394 controls[control_name].SetFocus()
395 else:
396 self.dtp_start.SetFocus()
397
399 self._display_invalid_input(message, self.dtp_start)
400
402 self._display_invalid_input(message, self.dtp_end)
403
405 self._display_invalid_input(message, self.txt_text)
406
410
413
415 _display_error_message(message, self)
416
418 self.controller.clear()
419 for data_id, editor in self.event_data:
420 editor.clear_data()
421
423
424 self.EndModal(wx.ID_OK)
425
426
428
430 wx.TextCtrl.__init__(self, parent, style=wx.TE_MULTILINE)
431
437
440
443
444
446
448 wx.Panel.__init__(self, parent)
449 self.MAX_SIZE = (128, 128)
450
451 self.img_icon = wx.StaticBitmap(self, size=self.MAX_SIZE)
452 label = _("Images will be scaled to fit inside a %ix%i box.")
453 description = wx.StaticText(self, label=label % self.MAX_SIZE)
454 btn_select = wx.Button(self, wx.ID_OPEN)
455 btn_clear = wx.Button(self, wx.ID_CLEAR)
456 self.Bind(wx.EVT_BUTTON, self._btn_select_on_click, btn_select)
457 self.Bind(wx.EVT_BUTTON, self._btn_clear_on_click, btn_clear)
458
459 sizer = wx.GridBagSizer(5, 5)
460 sizer.Add(description, wx.GBPosition(0, 0), wx.GBSpan(1, 2))
461 sizer.Add(btn_select, wx.GBPosition(1, 0), wx.GBSpan(1, 1))
462 sizer.Add(btn_clear, wx.GBPosition(1, 1), wx.GBSpan(1, 1))
463 sizer.Add(self.img_icon, wx.GBPosition(0, 2), wx.GBSpan(2, 1))
464 self.SetSizerAndFit(sizer)
465
466 self.bmp = None
467
470
473
476
478 self.bmp = bmp
479 if self.bmp == None:
480 self.img_icon.SetBitmap(wx.EmptyBitmap(1, 1))
481 else:
482 self.img_icon.SetBitmap(bmp)
483 self.GetSizer().Layout()
484
487
489 dialog = wx.FileDialog(self, message=_("Select Icon"),
490 wildcard="*", style=wx.FD_OPEN)
491 if dialog.ShowModal() == wx.ID_OK:
492 path = dialog.GetPath()
493 if os.path.exists(path):
494 image = wx.EmptyImage(0, 0)
495 success = image.LoadFile(path)
496
497 if success:
498
499 (w, h) = image.GetSize()
500 (W, H) = self.MAX_SIZE
501 if w > W:
502 factor = float(W) / float(w)
503 w = w * factor
504 h = h * factor
505 if h > H:
506 factor = float(H) / float(h)
507 w = w * factor
508 h = h * factor
509 image = image.Scale(w, h, wx.IMAGE_QUALITY_HIGH)
510 self.set_icon(image.ConvertToBitmap())
511 dialog.Destroy()
512
515
516
518
520 wx.Panel.__init__(self, parent)
521 self.editor = editor
522 self._create_gui()
523 self._initialize_data()
524
526 self._create_controls()
527 self._layout_controls()
528
530 self._set_initial_time()
531 self._set_initial_text()
532 self._set_visible(False)
533
535 if self.editor.event is not None:
536 self.dtp_start.set_value(self.editor.event.time_period.start_time)
537 else:
538 self.dtp_start.set_value(self.editor.start)
539
541 self.text_data.SetValue("")
542
544 self.btn_add = self._create_add_button()
545 self.btn_clear = self._create_clear_button()
546 self.url_panel = self._create_input_controls()
547
549 self._layout_input_controls(self.url_panel)
550 sizer = wx.GridBagSizer(5, 5)
551 sizer.Add(self.btn_add, wx.GBPosition(0, 0), wx.GBSpan(1, 1))
552 sizer.Add(self.btn_clear, wx.GBPosition(0, 1), wx.GBSpan(1, 1))
553 sizer.Add(self.url_panel, wx.GBPosition(1, 0), wx.GBSpan(4, 5))
554 self.SetSizerAndFit(sizer)
555
560
565
572
582
584 if self.url_visible:
585 time = self.dtp_start.get_value()
586 text = self.text_data.GetValue()
587 return (time, text)
588 else:
589 return None
590
592 if data == None:
593 self._set_visible(False)
594 else:
595 self._set_visible(True)
596 time, text = data
597 self.dtp_start.set_value(time)
598 self.text_data.SetValue(text)
599
601 self._set_visible(True)
602
605
607 self._set_initial_time()
608 self._set_initial_text()
609 self._set_visible(False)
610
612 self.url_visible = value
613 self.url_panel.Show(self.url_visible)
614 self.btn_add.Enable(not value)
615 self.btn_clear.Enable(value)
616 self.GetSizer().Layout()
617
618
620
622 wx.Panel.__init__(self, parent)
623 self.editor = editor
624 self._create_gui()
625 self._initialize_data()
626
628 self._create_controls()
629 self._layout_controls()
630
632 self._set_initial_text()
633 self._set_visible(False)
634
636 self.text_data.SetValue("")
637
639 self.btn_add = self._create_add_button()
640 self.btn_clear = self._create_clear_button()
641 self.btn_test = self._create_test_button()
642 self.url_panel = self._create_input_controls()
643
645 self._layout_input_controls(self.url_panel)
646 sizer = wx.GridBagSizer(5, 5)
647 sizer.Add(self.btn_add, wx.GBPosition(0, 0), wx.GBSpan(1, 1))
648 sizer.Add(self.btn_clear, wx.GBPosition(0, 1), wx.GBSpan(1, 1))
649 sizer.Add(self.btn_test, wx.GBPosition(0, 2), wx.GBSpan(1, 1))
650 sizer.Add(self.url_panel, wx.GBPosition(1, 0), wx.GBSpan(4, 5))
651 self.SetSizerAndFit(sizer)
652
657
662
667
672
679
681 if self.url_visible:
682 return self.text_data.GetValue()
683 else:
684 return None
685
687 if data == None:
688 self._set_visible(False)
689 else:
690 self._set_visible(True)
691 self.text_data.SetValue(data)
692
694 self._set_visible(True)
695
698
701
703 self._set_initial_text()
704 self._set_visible(False)
705
707 self.url_visible = value
708 self.url_panel.Show(self.url_visible)
709 self.btn_add.Enable(not value)
710 self.btn_clear.Enable(value)
711 self.btn_test.Enable(value)
712 self.GetSizer().Layout()
713
714
723 gui_utils.show_modal(create_event_editor, handle_db_error)
724
725
730 gui_utils.show_modal(create_event_editor, handle_db_error)
731