1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 from datetime import datetime
20 import re
21
22 from timelinelib.calendar.gregorian.timetype import GregorianTimeType
23 from timelinelib.calendar.coptic.coptic import CopticDateTime,\
24 julian_day_to_coptic_ymd
25 from timelinelib.calendar.coptic.monthnames import abbreviated_name_of_month
26 from timelinelib.calendar.coptic.time import CopticDelta
27 from timelinelib.calendar.coptic.time import CopticTime
28 from timelinelib.calendar.coptic.time import SECONDS_IN_DAY
29 from timelinelib.calendar.coptic.weekdaynames import abbreviated_name_of_weekday
30 from timelinelib.calendar.timetype import TimeType
31 from timelinelib.canvas.data import TimeOutOfRangeLeftError
32 from timelinelib.canvas.data import TimeOutOfRangeRightError
33 from timelinelib.canvas.data import TimePeriod
34 from timelinelib.canvas.data import time_period_center
35 from timelinelib.canvas.drawing.interface import Strip
36 from timelinelib.calendar.gregorian.gregorian import gregorian_ymd_to_julian_day
37 from timelinelib.calendar.coptic.coptic import julian_day_to_coptic_ymd
38
39
40 BC = _("BC")
44
47
50
52 match = re.search(r"^(-?\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$", time_string)
53 if match:
54 year = int(match.group(1))
55 month = int(match.group(2))
56 day = int(match.group(3))
57 hour = int(match.group(4))
58 minute = int(match.group(5))
59 second = int(match.group(6))
60 try:
61 return CopticDateTime(year, month, day, hour, minute, second).to_time()
62 except ValueError:
63 raise ValueError("Invalid time, time string = '%s'" % time_string)
64 else:
65 raise ValueError("Time not on correct format = '%s'" % time_string)
66
68 return [
69 (_("Go to &Today") + "\tCtrl+T", go_to_today_fn),
70 (_("Go to &Date...") + "\tCtrl+G", go_to_date_fn),
71 ("SEP", None),
72 (_("Backward") + "\tPgUp", backward_fn),
73 (_("Forward") + "\tPgDn", forward_fn),
74 (_("Forward One Wee&k") + "\tCtrl+K", forward_one_week_fn),
75 (_("Back One &Week") + "\tCtrl+W", backward_one_week_fn),
76 (_("Forward One Mont&h") + "\tCtrl+H", forward_one_month_fn),
77 (_("Back One &Month") + "\tCtrl+M", backward_one_month_fn),
78 (_("Forward One Yea&r") + "\tCtrl+R", forward_one_year_fn),
79 (_("Back One &Year") + "\tCtrl+Y", backward_one_year_fn),
80 ("SEP", None),
81 (_("Fit Millennium"), fit_millennium_fn),
82 (_("Fit Century"), create_strip_fitter(StripCentury)),
83 (_("Fit Decade"), create_strip_fitter(StripDecade)),
84 (_("Fit Year"), create_strip_fitter(StripYear)),
85 (_("Fit Month"), create_strip_fitter(StripMonth)),
86 (_("Fit Week"), fit_week_fn),
87 (_("Fit Day"), create_strip_fitter(StripDay)),
88 ]
89
94
95 def label_without_time(time):
96 coptic_datetime = CopticDateTime.from_time(time)
97 return u"%s %s %s" % (
98 coptic_datetime.day,
99 abbreviated_name_of_month(coptic_datetime.month),
100 format_year(coptic_datetime.year)
101 )
102
103 def time_label(time):
104 return "%02d:%02d" % time.get_time_of_day()[:-1]
105 if time_period.is_period():
106 if has_nonzero_time(time_period):
107 label = u"%s to %s" % (label_with_time(time_period.start_time),
108 label_with_time(time_period.end_time))
109 else:
110 label = u"%s to %s" % (label_without_time(time_period.start_time),
111 label_without_time(time_period.end_time))
112 else:
113 if has_nonzero_time(time_period):
114 label = u"%s" % label_with_time(time_period.start_time)
115 else:
116 label = u"%s" % label_without_time(time_period.start_time)
117 return label
118
124
127
130
132 """
133 Return a tuple (major_strip, minor_strip) for current time period and
134 window size.
135 """
136 day_period = TimePeriod(CopticTime(0, 0),CopticTime(1, 0))
137 one_day_width = metrics.calc_exact_width(day_period)
138 if one_day_width > 20000:
139 return (StripHour(), StripMinute())
140 elif one_day_width > 600:
141 return (StripDay(), StripHour())
142 elif one_day_width > 45:
143 return (StripWeek(appearance), StripWeekday())
144 elif one_day_width > 25:
145 return (StripMonth(), StripDay())
146 elif one_day_width > 1.5:
147 return (StripYear(), StripMonth())
148 elif one_day_width > 0.12:
149 return (StripDecade(), StripYear())
150 elif one_day_width > 0.012:
151 return (StripCentury(), StripDecade())
152 else:
153 return (StripCentury(), StripCentury())
154
157
160
163
177
180
183
191
194
197
198
200 return time.julian_day % 7
201
205
209
213
214
215 -def go_to_date_fn(main_frame, current_period, navigation_fn):
216 def navigate_to(time):
217 navigation_fn(lambda tp: tp.center(time))
218 main_frame.display_time_editor_dialog(
219 CopticTimeType(), current_period.mean_time(), navigate_to, _("Go to Date"))
220
221
222 -def backward_fn(main_frame, current_period, navigation_fn):
223 _move_page_smart(current_period, navigation_fn, -1)
224
225
226 -def forward_fn(main_frame, current_period, navigation_fn):
227 _move_page_smart(current_period, navigation_fn, 1)
228
229
230 -def _move_page_smart(current_period, navigation_fn, direction):
231 if _whole_number_of_years(current_period):
232 _move_page_years(current_period, navigation_fn, direction)
233 elif _whole_number_of_months(current_period):
234 _move_page_months(current_period, navigation_fn, direction)
235 else:
236 navigation_fn(lambda tp: tp.move_delta(direction * current_period.delta()))
237
240 """
241 >>> from timelinelib.test.utils import gregorian_period
242
243 >>> _whole_number_of_years(gregorian_period("11 Sep 2013", "11 Sep 2014"))
244 True
245
246 >>> _whole_number_of_years(gregorian_period("9 Sep 1776", "9 Sep 1777"))
247 True
248
249 >>> _whole_number_of_years(gregorian_period("8 Dec 1776", "8 Dec 1777"))
250 False
251
252 >>> _whole_number_of_years(gregorian_period("6 Sep 2013", "11 Sep 2014"))
253 False
254 """
255 return (CopticDateTime.from_time(period.start_time).is_first_day_in_year() and
256 CopticDateTime.from_time(period.end_time).is_first_day_in_year() and
257 _calculate_year_diff(period) > 0)
258
259
260 -def _move_page_years(curret_period, navigation_fn, direction):
261 def navigate(tp):
262 year_delta = direction * _calculate_year_diff(curret_period)
263 coptic_start = CopticDateTime.from_time(curret_period.start_time)
264 coptic_end = CopticDateTime.from_time(curret_period.end_time)
265 new_start_year = coptic_start.year + year_delta
266 new_end_year = coptic_end.year + year_delta
267 try:
268 new_start = coptic_start.replace(year=new_start_year).to_time()
269 new_end = coptic_end.replace(year=new_end_year).to_time()
270 if new_end > CopticTimeType().get_max_time():
271 raise ValueError()
272 if new_start < CopticTimeType().get_min_time():
273 raise ValueError()
274 except ValueError:
275 if direction < 0:
276 raise TimeOutOfRangeLeftError()
277 else:
278 raise TimeOutOfRangeRightError()
279 return tp.update(new_start, new_end)
280 navigation_fn(navigate)
281
286
289
290 """
291 >>> from timelinelib.test.utils import gregorian_period
292
293 >>> _whole_number_of_months(gregorian_period("9 Jan 2013", "9 Jan 2014"))
294 True
295
296 >>> _whole_number_of_months(gregorian_period("6 Jul 1776", "6 Jul 1777"))
297 True
298
299 >>> _whole_number_of_months(gregorian_period("2 Jan 2013", "2 Mar 2014"))
300 False
301
302 >>> _whole_number_of_months(gregorian_period("1 Jan 2013 12:00", "1 Mar 2014"))
303 False
304 """
305 start, end = CopticDateTime.from_time(period.start_time), CopticDateTime.from_time(period.end_time)
306 start_months = start.year * 13 + start.month
307 end_months = end.year * 13 + end.month
308 month_diff = end_months - start_months
309
310 return (start.is_first_of_month() and
311 end.is_first_of_month() and
312 month_diff > 0)
313
314
315 -def _move_page_months(curret_period, navigation_fn, direction):
316 def navigate(tp):
317 start = CopticDateTime.from_time(curret_period.start_time)
318 end = CopticDateTime.from_time(curret_period.end_time)
319 start_months = start.year * 13 + start.month
320 end_months = end.year * 13 + end.month
321 month_diff = end_months - start_months
322 month_delta = month_diff * direction
323 new_start_year, new_start_month = _months_to_year_and_month(start_months + month_delta)
324 new_end_year, new_end_month = _months_to_year_and_month(end_months + month_delta)
325 try:
326 new_start = start.replace(year=new_start_year, month=new_start_month)
327 new_end = end.replace(year=new_end_year, month=new_end_month)
328 start = new_start.to_time()
329 end = new_end.to_time()
330 if end > CopticTimeType().get_max_time():
331 raise ValueError()
332 if start < CopticTimeType().get_min_time():
333 raise ValueError()
334 except ValueError:
335 if direction < 0:
336 raise TimeOutOfRangeLeftError()
337 else:
338 raise TimeOutOfRangeRightError()
339 return tp.update(start, end)
340 navigation_fn(navigate)
341
344 years = int(months / 13)
345 month = months - years * 13
346 if month == 0:
347 month = 13
348 years -= 1
349 return years, month
350
355
360
376
380
384
389
394
405
409
413
414
415 -def fit_week_fn(main_frame, current_period, navigation_fn):
424
433 navigation_fn(navigate)
434 return fit
435
438
439 """
440 Year Name | Year integer | Decade name
441 ----------+--------------+------------
442 .. | .. |
443 200 BC | -199 | 200s BC (100 years)
444 ----------+--------------+------------
445 199 BC | -198 |
446 ... | ... | 100s BC (100 years)
447 100 BC | -99 |
448 ----------+--------------+------------
449 99 BC | -98 |
450 ... | ... | 0s BC (only 99 years)
451 1 BC | 0 |
452 ----------+--------------+------------
453 1 | 1 |
454 ... | ... | 0s (only 99 years)
455 99 | 99 |
456 ----------+--------------+------------
457 100 | 100 |
458 .. | .. | 100s (100 years)
459 199 | 199 |
460 ----------+--------------+------------
461 200 | 200 | 200s (100 years)
462 .. | .. |
463 """
464
465 - def label(self, time, major=False):
466 if major:
467 coptic_time = CopticDateTime.from_time(time)
468 return self._format_century(
469 self._century_number(
470 self._century_start_year(coptic_time.year)
471 ),
472 coptic_time.is_bc()
473 )
474 else:
475 return ""
476
483
489
491 if century_start_year > 99:
492 return century_start_year
493 elif century_start_year >= -98:
494 return 0
495 else:
496 return self._century_number(-century_start_year - 98)
497
499 return start_year + self._century_year_len(start_year)
500
502 if start_year in [-98, 1]:
503 return 99
504 else:
505 return 100
506
512
514 if year > 99:
515 return year - int(year) % 100
516 elif year >= 1:
517 return 1
518 elif year >= -98:
519 return -98
520 else:
521 return -self._century_start_year(-year + 1) - 98
522
525
526 """
527 Year Name | Year integer | Decade name
528 ----------+--------------+------------
529 .. | .. |
530 20 BC | -19 | 20s BC (10 years)
531 ----------+--------------+------------
532 19 BC | -18 |
533 18 BC | -17 |
534 17 BC | -16 |
535 16 BC | -15 |
536 15 BC | -14 | 10s BC (10 years)
537 14 BC | -13 |
538 13 BC | -12 |
539 12 BC | -11 |
540 11 BC | -10 |
541 10 BC | -9 |
542 ----------+--------------+------------
543 9 BC | -8 |
544 8 BC | -7 |
545 7 BC | -6 |
546 6 BC | -5 |
547 5 BC | -4 | 0s BC (only 9 years)
548 4 BC | -3 |
549 3 BC | -2 |
550 2 BC | -1 |
551 1 BC | 0 |
552 ----------+--------------+------------
553 1 | 1 |
554 2 | 2 |
555 3 | 3 |
556 4 | 4 |
557 5 | 5 | 0s (only 9 years)
558 6 | 6 |
559 7 | 7 |
560 8 | 8 |
561 9 | 9 |
562 ----------+--------------+------------
563 10 | 10 |
564 11 | 11 |
565 12 | 12 |
566 13 | 13 |
567 14 | 14 |
568 15 | 15 | 10s (10 years)
569 16 | 16 |
570 17 | 17 |
571 18 | 18 |
572 19 | 19 |
573 ----------+--------------+------------
574 20 | 20 | 20s (10 years)
575 .. | .. |
576 """
577
579 self.skip_s_in_decade_text = False
580
581 - def label(self, time, major=False):
582 coptic_time = CopticDateTime.from_time(time)
583 return self._format_decade(
584 self._decade_number(self._decade_start_year(coptic_time.year)),
585 coptic_time.is_bc()
586 )
587
594
600
602 self.skip_s_in_decade_text = value
603
613
615 if year > 9:
616 return int(year) - (int(year) % 10)
617 elif year >= 1:
618 return 1
619 elif year >= -8:
620 return -8
621 else:
622 return -self._decade_start_year(-year + 1) - 8
623
625 return start_year + self._decade_year_len(start_year)
626
628 if self._decade_number(start_year) == 0:
629 return 9
630 else:
631 return 10
632
634 if start_year > 9:
635 return start_year
636 elif start_year >= -8:
637 return 0
638 else:
639 return self._decade_number(-start_year - 8)
640
643
644 - def label(self, time, major=False):
646
651
655
658
659 - def label(self, time, major=False):
665
673
678
681
682 - def label(self, time, major=False):
689
697
700
703
706
710
711 - def label(self, time, major=False):
727
729 start = CopticDateTime.from_time(start)
730 end = CopticDateTime.from_time(end)
731 if start.year == end.year:
732 if start.month == end.month:
733 return "%s-%s %s %s" % (start.day, end.day,
734 abbreviated_name_of_month(start.month),
735 format_year(start.year))
736 return "%s %s-%s %s %s" % (start.day,
737 abbreviated_name_of_month(start.month),
738 end.day,
739 abbreviated_name_of_month(end.month),
740 format_year(start.year))
741 return "%s %s %s-%s %s %s" % (start.day,
742 abbreviated_name_of_month(start.month),
743 format_year(start.year),
744 end.day,
745 abbreviated_name_of_month(end.month),
746 format_year(end.year))
747
755
758
761
762 - def label(self, time, major=False):
772
777
780
783
786
787 - def label(self, time, major=False):
793
797
800
803
804 - def label(self, time, major=False):
810
814
817
824
831
838
841 def move_time(time):
842 coptic_time = CopticDateTime.from_time(time)
843 new_month = coptic_time.month + num
844 new_year = coptic_time.year
845 while new_month < 1:
846 new_month += 13
847 new_year -= 1
848 while new_month > 13:
849 new_month -= 13
850 new_year += 1
851 return coptic_time.replace(year=new_year, month=new_month).to_time()
852 try:
853 return TimePeriod(
854 move_time(period.start_time),
855 move_time(period.end_time)
856 )
857 except ValueError:
858 return None
859
871
876
879
880 - def __init__(self, name, single_name, value_fn, remainder_fn):
885
886 @property
889
890 @property
892 return self._single_name
893
894 @property
896 return self._value_fn
897
898 @property
899 - def remainder_fn(self):
900 return self._remainder_fn
901
902
903 YEARS = DurationType(_('years'), _('year'),
904 lambda ds: ds[0] // 365,
905 lambda ds: (ds[0] % 365, ds[1]))
906 MONTHS = DurationType(_('months'), _('month'),
907 lambda ds: ds[0] // 30,
908 lambda ds: (ds[0] % 30, ds[1]))
909 WEEKS = DurationType(_('weeks'), _('week'),
910 lambda ds: ds[0] // 7,
911 lambda ds: (ds[0] % 7, ds[1]))
912 DAYS = DurationType(_('days'), _('day'),
913 lambda ds: ds[0],
914 lambda ds: (0, ds[1]))
915 HOURS = DurationType(_('hours'), _('hour'),
916 lambda ds: ds[0] * 24 + ds[1] // 3600,
917 lambda ds: (0, ds[1] % 3600))
918 MINUTES = DurationType(_('minutes'), _('minute'),
919 lambda ds: ds[0] * 1440 + ds[1] // 60,
920 lambda ds: (0, ds[1] % 60))
921 SECONDS = DurationType(_('seconds'), _('second'),
922 lambda ds: ds[0] * 86400 + ds[1],
923 lambda ds: (0, 0))
971