Package Gnumed :: Package timelinelib :: Package canvas :: Package data :: Module event
[frames] | no frames]

Source Code for Module Gnumed.timelinelib.canvas.data.event

  1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg 
  2  # 
  3  # This file is part of Timeline. 
  4  # 
  5  # Timeline is free software: you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation, either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Timeline is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>. 
 17   
 18   
 19  from timelinelib.canvas.data.base import ItemBase 
 20  from timelinelib.canvas.data.immutable import ImmutableEvent 
 21  from timelinelib.canvas.data.item import TimelineItem 
 22  from timelinelib.canvas.drawing.drawers import get_progress_color 
 23   
 24   
 25  DEFAULT_COLOR = (200, 200, 200) 
 26  EXPORTABLE_FIELDS = (_("Text"), _("Description"), _("Start"), _("End"), _("Category"), 
 27                       _("Fuzzy"), _("Locked"), _("Ends Today"), _("Hyperlink"), 
 28                       _("Progress"), _("Progress Color"), _("Done Color"), _("Alert"), 
 29                       _("Is Container"), _("Is Subevent")) 
 30   
 31   
32 -class Event(ItemBase, TimelineItem):
33
34 - def __init__(self, db=None, id_=None, immutable_value=ImmutableEvent()):
35 ItemBase.__init__(self, db, id_, immutable_value) 36 self._category = None 37 self._categories = [] 38 self._container = None 39 self._milestone = False
40
41 - def duplicate(self, target_db=None):
42 duplicate = ItemBase.duplicate(self, target_db=target_db) 43 if duplicate.db is self.db: 44 duplicate.category = self.category 45 duplicate.sort_order = None 46 return duplicate
47
48 - def save(self):
49 self._update_category_id() 50 self._update_category_ids() 51 self._update_container_id() 52 self._update_sort_order() 53 with self._db.transaction("Save event") as t: 54 t.save_event(self._immutable_value, self.ensure_id()) 55 return self
56
57 - def reload(self):
58 return self._db.find_event_with_id(self.id)
59
60 - def _update_category_id(self):
61 if self.category is None: 62 self._immutable_value = self._immutable_value.update( 63 category_id=None 64 ) 65 elif self.category.id is None: 66 raise Exception("Unknown category") 67 else: 68 self._immutable_value = self._immutable_value.update( 69 category_id=self.category.id 70 )
71
72 - def _update_category_ids(self):
73 if self._categories == list(): 74 self._immutable_value = self._immutable_value.update( 75 category_ids={} 76 ) 77 else: 78 ids = [c.id for c in self._categories] 79 # Using a dictionary because we don't have any ImmutableList class 80 dic = {k: None for k in ids} 81 self._immutable_value = self._immutable_value.update( 82 category_ids=dic 83 )
84
85 - def _update_container_id(self):
86 if self.container is None: 87 self._immutable_value = self._immutable_value.update( 88 container_id=None 89 ) 90 elif self.container.id is None: 91 raise Exception("Unknown container") 92 else: 93 self._immutable_value = self._immutable_value.update( 94 container_id=self.container.id 95 )
96
97 - def _update_sort_order(self):
98 if self.sort_order is None: 99 self.sort_order = 1 + self.db.get_max_sort_order()
100
101 - def delete(self):
102 with self._db.transaction("Delete event") as t: 103 t.delete_event(self.id) 104 self.id = None
105
106 - def __eq__(self, other):
107 return (isinstance(other, Event) and 108 self.get_fuzzy() == other.get_fuzzy() and 109 self.get_locked() == other.get_locked() and 110 self.get_ends_today() == other.get_ends_today() and 111 self.get_id() == other.get_id() and 112 self.get_time_period().start_time == other.get_time_period().start_time and 113 (self.get_time_period().end_time == other.get_time_period().end_time or self.get_ends_today()) and 114 self.get_text() == other.get_text() and 115 self.get_category() == other.get_category() and 116 self.get_description() == other.get_description() and 117 self.get_hyperlink() == other.get_hyperlink() and 118 self.get_progress() == other.get_progress() and 119 self.get_alert() == other.get_alert() and 120 self.get_icon() == other.get_icon() and 121 self.get_default_color() == other.get_default_color())
122
123 - def __ne__(self, other):
124 return not (self == other)
125
126 - def __lt__(self, other):
127 raise NotImplementedError("I don't believe this is in use.")
128
129 - def __gt__(self, other):
130 raise NotImplementedError("I don't believe this is in use.")
131
132 - def __le__(self, other):
133 raise NotImplementedError("I don't believe this is in use.")
134
135 - def __ge__(self, other):
136 raise NotImplementedError("I don't believe this is in use.")
137
138 - def __repr__(self):
139 return "%s<id=%r, text=%r, time_period=%r, ...>" % ( 140 self.__class__.__name__, 141 self.get_id(), 142 self.get_text(), 143 self.get_time_period() 144 )
145
146 - def set_end_time(self, time):
148
149 - def get_text(self):
150 return self._immutable_value.text
151
152 - def set_text(self, text):
153 self._immutable_value = self._immutable_value.update(text=text.strip()) 154 return self
155 156 text = property(get_text, set_text) 157
158 - def get_category(self):
159 return self._category
160
161 - def get_category_name(self):
162 if self.get_category(): 163 return self.get_category().get_name() 164 else: 165 return None
166
167 - def set_category(self, category):
168 self._category = category 169 return self
170 171 category = property(get_category, set_category) 172
173 - def get_categories(self):
174 return self._categories
175
176 - def set_categories(self, categories):
177 if categories: 178 if self.category: 179 if self.category in categories: 180 categories.remove(self.category) 181 else: 182 self.category = categories[0] 183 categories = categories[1:] 184 self._categories = categories
185
186 - def get_container(self):
187 return self._container
188
189 - def set_container(self, container):
190 if self._container is not None: 191 self._container.unregister_subevent(self) 192 self._container = container 193 if self._container is not None: 194 self._container.register_subevent(self) 195 return self
196 197 container = property(get_container, set_container) 198
199 - def get_fuzzy(self):
200 return self._immutable_value.fuzzy
201
202 - def set_fuzzy(self, fuzzy):
203 self._immutable_value = self._immutable_value.update(fuzzy=fuzzy) 204 return self
205 206 fuzzy = property(get_fuzzy, set_fuzzy) 207
208 - def get_locked(self):
209 return self._immutable_value.locked
210
211 - def set_locked(self, locked):
212 self._immutable_value = self._immutable_value.update(locked=locked) 213 return self
214 215 locked = property(get_locked, set_locked) 216
217 - def get_ends_today(self):
218 return self._immutable_value.ends_today
219
220 - def set_ends_today(self, ends_today):
221 if not self.locked: 222 self._immutable_value = self._immutable_value.update(ends_today=ends_today) 223 return self
224 225 ends_today = property(get_ends_today, set_ends_today) 226
227 - def get_description(self):
228 return self._immutable_value.description
229
230 - def set_description(self, description):
231 self._immutable_value = self._immutable_value.update(description=description) 232 return self
233 234 description = property(get_description, set_description) 235
236 - def get_icon(self):
237 return self._immutable_value.icon
238
239 - def set_icon(self, icon):
240 self._immutable_value = self._immutable_value.update(icon=icon) 241 return self
242 243 icon = property(get_icon, set_icon) 244 247 251 252 hyperlink = property(get_hyperlink, set_hyperlink) 253
254 - def get_alert(self):
255 return self._immutable_value.alert
256
257 - def set_alert(self, alert):
258 self._immutable_value = self._immutable_value.update(alert=alert) 259 return self
260 261 alert = property(get_alert, set_alert) 262
263 - def get_progress(self):
264 return self._immutable_value.progress
265
266 - def set_progress(self, progress):
267 self._immutable_value = self._immutable_value.update(progress=progress) 268 return self
269 270 progress = property(get_progress, set_progress) 271
272 - def get_sort_order(self):
273 return self._immutable_value.sort_order
274
275 - def set_sort_order(self, sort_order):
276 self._immutable_value = self._immutable_value.update(sort_order=sort_order) 277 return self
278 279 sort_order = property(get_sort_order, set_sort_order) 280
281 - def get_default_color(self):
282 color = self._immutable_value.default_color 283 if color is None: 284 color = DEFAULT_COLOR 285 return color
286
287 - def set_default_color(self, color):
288 self._immutable_value = self._immutable_value.update(default_color=color) 289 return self
290 291 default_color = property(get_default_color, set_default_color) 292
293 - def get_done_color(self):
294 if self.category: 295 return self.category.get_done_color() 296 else: 297 return get_progress_color(DEFAULT_COLOR)
298
299 - def get_progress_color(self):
300 category = self.category 301 if category: 302 if self.get_progress() == 100: 303 return category.get_done_color() 304 else: 305 return category.get_progress_color() 306 else: 307 return get_progress_color(DEFAULT_COLOR)
308
309 - def update(self, start_time, end_time, text, category=None, fuzzy=None, 310 locked=None, ends_today=None):
311 """Change the event data.""" 312 self.update_period(start_time, end_time) 313 self.text = text.strip() 314 self.category = category 315 if ends_today is not None: 316 if not self.locked: 317 self.ends_today = ends_today 318 if fuzzy is not None: 319 self.fuzzy = fuzzy 320 if locked is not None: 321 self.locked = locked 322 return self
323
324 - def get_data(self, event_id):
325 """ 326 Return data with the given id or None if no data with that id exists. 327 328 See set_data for information how ids map to data. 329 """ 330 if event_id == "description": 331 return self.description 332 elif event_id == "icon": 333 return self.icon 334 elif event_id == "hyperlink": 335 return self.hyperlink 336 elif event_id == "alert": 337 return self.alert 338 elif event_id == "progress": 339 return self.progress 340 elif event_id == "default_color": 341 if "default_color" in self._immutable_value: 342 return self._immutable_value.default_color 343 else: 344 return None 345 else: 346 raise Exception("should not happen")
347
348 - def set_data(self, event_id, data):
349 """ 350 Set data with the given id. 351 352 Here is how ids map to data: 353 354 description - string 355 icon - wx.Bitmap 356 """ 357 if event_id == "description": 358 self.description = data 359 elif event_id == "icon": 360 self.icon = data 361 elif event_id == "hyperlink": 362 self.hyperlink = data 363 elif event_id == "alert": 364 self.alert = data 365 elif event_id == "progress": 366 self.progress = data 367 elif event_id == "default_color": 368 self.default_color = data 369 else: 370 raise Exception("should not happen")
371
372 - def get_whole_data(self):
373 data = {} 374 for event_id in DATA_FIELDS: 375 data[event_id] = self.get_data(event_id) 376 return data
377
378 - def set_whole_data(self, data):
379 for event_id in DATA_FIELDS: 380 self.set_data(event_id, data.get(event_id, None))
381 382 data = property(get_whole_data, set_whole_data) 383
384 - def has_data(self):
385 """Return True if the event has associated data, or False if not.""" 386 for event_id in DATA_FIELDS: 387 if self.get_data(event_id) is not None: 388 return True 389 return False
390
391 - def has_balloon_data(self):
392 """Return True if the event has associated data to be displayed in a balloon.""" 393 return (self.get_data("description") is not None or 394 self.get_data("icon") is not None)
395
396 - def get_label(self, time_type):
397 """Returns a unicode label describing the event.""" 398 event_label = "%s (%s)" % ( 399 self.text, 400 time_type.format_period(self.get_time_period()), 401 ) 402 duration_label = self._get_duration_label(time_type) 403 if duration_label != "": 404 return "%s %s: %s" % (event_label, _("Duration"), duration_label) 405 else: 406 return event_label
407
408 - def _get_duration_label(self, time_type):
409 label = time_type.format_delta(self.time_span()) 410 if label == "0": 411 label = "" 412 return label
413
414 - def is_container(self):
415 return False
416
417 - def is_subevent(self):
418 return False
419
420 - def is_milestone(self):
421 return False
422
423 - def get_exportable_fields(self):
424 return EXPORTABLE_FIELDS
425
426 - def set_milestone(self, value):
427 self._milestone = value
428
429 - def get_milestone(self):
430 return self._milestone
431 432 433 DATA_FIELDS = [ 434 "description", 435 "icon", 436 "hyperlink", 437 "alert", 438 "progress", 439 "default_color", 440 ] 441