1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import getpass
20 import os
21
22 from timelinelib.wxgui.dialogs.slideshow.view import open_slideshow_dialog
23 from timelinelib.wxgui.utils import display_error_message
24 from timelinelib.wxgui.utils import display_warning_message
25 from timelinelib.wxgui.utils import get_user_ack
26
27
30
31
33
34 - def __init__(self, main_frame, db_open_fn, config):
35 self._main_frame = main_frame
36 self._db_open_fn = db_open_fn
37 self._config = config
38 self._timeline = None
39
40 - def on_started(self, application_arguments):
45
47 self.open_timeline(path)
48
50 if os.path.exists(path):
51 self.open_timeline(path)
52 else:
53 display_error_message(_("File '%s' does not exist.") % path, self._main_frame)
54
56 self.open_timeline(":tutorial:")
57
58 - def open_numeric_tutorial_timeline(self, *args, **kwargs):
59 self.open_timeline(":numtutorial:")
60
61 - def open_timeline(self, path, timetype=None, save_current_data=True):
62 if save_current_data:
63 self._main_frame.save_current_timeline_data()
64 try:
65 self._timeline = self._db_open_fn(path, timetype=timetype)
66 except Exception as e:
67 self._main_frame.DisplayErrorMessage(
68 _("Unable to open timeline '%s'.") % path + "\n\n" + str(e)
69 )
70 else:
71 self._config.append_recently_opened(path)
72 self._main_frame.update_open_recent_submenu()
73 self._timeline.path = path
74 self._main_frame.display_timeline(self._timeline)
75 self._timelinepath = path
76 self._last_changed = self._get_modification_date()
77 self._main_frame.update_navigation_menu_items()
78 self._main_frame.enable_disable_menus()
79 self._main_frame.create_timeline_context_menu()
80 self._main_frame._create_main_menu_bar()
81 if path == ":numtutorial:":
82 self._main_frame._fit_all_events()
83
85 try:
86 self._timeline.set_readonly()
87 self._main_frame.set_timeline_readonly()
88 except:
89 pass
90
92 return self._config.get_week_start() == "monday"
93
94 - def ok_to_edit(self):
95 if self._timeline is None:
96 return True
97 if self._timeline.is_read_only():
98 return False
99 if self._locked():
100 display_warning_message("The Timeline is Locked by someone else.\nTry again later")
101 return False
102 if self._timeline_path_doesnt_exists_yet():
103 self._lock()
104 return True
105 last_changed = self._get_modification_date()
106 if last_changed > self._last_changed:
107 ack = get_user_ack(
108 _("Someoneelse has changed the Timeline.\nYou have two choices!\n 1. Set Timeline in Read-Only mode.\n 2. Synchronize Timeline.\n\nDo you want to Synchronize?"))
109 if ack:
110 self.reload_from_disk()
111 else:
112 self.set_timeline_in_readonly_mode()
113 return False
114 if last_changed > 0:
115 self._lock()
116 return True
117
118 - def start_slide_show(self, canvas):
120
122 return not os.path.exists(self._timelinepath)
123
124 - def edit_ends(self):
125 if self._the_lock_is_mine():
126 self._last_changed = self._get_modification_date()
127 self._unlock()
128
130 return self._timeline is not None and self._timeline.is_read_only()
131
133 try:
134 return os.path.getmtime(self._timelinepath)
135 except:
136 return 0
137
139 timeline_canvas = self._main_frame.main_panel.timeline_panel.timeline_canvas
140 vp = timeline_canvas.GetViewProperties()
141 displayed_period = vp.get_displayed_period()
142 self.open_timeline(self._timelinepath, save_current_data=False)
143 vp.set_displayed_period(displayed_period)
144 timeline_canvas.Redraw()
145
146 - def select_all(self):
147 timeline_canvas = self._main_frame.main_panel.timeline_panel.timeline_canvas
148 timeline_canvas.SelectAllEvents()
149
151 fp = None
152 if not self._timeline.get_should_lock():
153 return
154 try:
155 ts = self._get_timestamp_string()
156 path = self._get_lockpath()
157 fp = open(path, "w")
158 fp.write("%s\n%s\n%s" % (getpass.getuser(), ts, os.getpid()))
159 except Exception:
160 msg = _(
161 "Unable to take lock on %s\nThis means you can't edit the timeline.\nCheck if you have write access to this directory.") % self._timelinepath
162 display_warning_message(msg, self._main_frame)
163 raise LockedException()
164 finally:
165 if fp is not None:
166 fp.close()
167
168 - def _get_lockpath(self):
169 return "%s.lock" % self._timelinepath
170
172 now = self._timeline.time_type.now()
173 return self._timeline.time_type.time_string(now)
174
176 lockpath = self._get_lockpath()
177 return os.path.exists(lockpath)
178
180 lockpath = self._get_lockpath()
181 if os.path.exists(lockpath):
182 try:
183 os.remove(lockpath)
184 except WindowsError as ex:
185 if ex.winerror == 32:
186 self._report_other_process_uses_lockfile(lockpath)
187 else:
188 raise ex
189
191 message = _("""The lockfile used to protect the timeline from concurrent updates is opened by another program or process.
192 This lockfile must be removed in order be able to continue editing the timeline!
193 The lockfile is found at: %s""") % lockpath
194 display_warning_message(message)
195
197 fp = None
198 try:
199 user = getpass.getuser()
200 pid = os.getpid()
201 lockpath = self._get_lockpath()
202 fp = open(lockpath, "r")
203 lines = fp.readlines()
204 lines = [line.strip() for line in lines]
205 return lines[0] == user and lines[2] == "%s" % pid
206 except:
207 return False
208 finally:
209 if fp is not None:
210 fp.close()
211