23 |
23 |
24 class TimeTrackerWidget(QWidget, Ui_TimeTrackerWidget): |
24 class TimeTrackerWidget(QWidget, Ui_TimeTrackerWidget): |
25 """ |
25 """ |
26 Class implementing the time tracker widget. |
26 Class implementing the time tracker widget. |
27 """ |
27 """ |
|
28 |
28 DurationColumn = 1 |
29 DurationColumn = 1 |
29 TaskColumn = 2 |
30 TaskColumn = 2 |
30 CommentColumn = 3 |
31 CommentColumn = 3 |
31 |
32 |
32 def __init__(self, tracker, parent=None): |
33 def __init__(self, tracker, parent=None): |
33 """ |
34 """ |
34 Constructor |
35 Constructor |
35 |
36 |
36 @param tracker reference to the time tracker |
37 @param tracker reference to the time tracker |
37 @type TimeTracker |
38 @type TimeTracker |
38 @param parent reference to the parent widget |
39 @param parent reference to the parent widget |
39 @type QWidget |
40 @type QWidget |
40 """ |
41 """ |
41 super().__init__(parent) |
42 super().__init__(parent) |
42 self.setupUi(self) |
43 self.setupUi(self) |
43 |
44 |
44 self.__tracker = tracker |
45 self.__tracker = tracker |
45 |
46 |
46 @pyqtSlot(str) |
47 @pyqtSlot(str) |
47 def on_taskCombo_editTextChanged(self, txt): |
48 def on_taskCombo_editTextChanged(self, txt): |
48 """ |
49 """ |
49 Private slot handling changes of the task description of the current |
50 Private slot handling changes of the task description of the current |
50 entry. |
51 entry. |
51 |
52 |
52 @param txt new task description |
53 @param txt new task description |
53 @type str |
54 @type str |
54 """ |
55 """ |
55 itm = self.entriesList.topLevelItem(0) |
56 itm = self.entriesList.topLevelItem(0) |
56 if itm: |
57 if itm: |
57 itm.setText(self.TaskColumn, txt) |
58 itm.setText(self.TaskColumn, txt) |
58 self.entriesList.resizeColumnToContents(self.TaskColumn) |
59 self.entriesList.resizeColumnToContents(self.TaskColumn) |
59 |
60 |
60 entry = self.__tracker.getCurrentEntry() |
61 entry = self.__tracker.getCurrentEntry() |
61 if entry: |
62 if entry: |
62 entry.setTask(txt) |
63 entry.setTask(txt) |
63 |
64 |
64 @pyqtSlot(str) |
65 @pyqtSlot(str) |
65 def on_commentCombo_editTextChanged(self, txt): |
66 def on_commentCombo_editTextChanged(self, txt): |
66 """ |
67 """ |
67 Private slot handling changes of the comment of the current entry. |
68 Private slot handling changes of the comment of the current entry. |
68 |
69 |
69 @param txt new comment |
70 @param txt new comment |
70 @type str |
71 @type str |
71 """ |
72 """ |
72 itm = self.entriesList.topLevelItem(0) |
73 itm = self.entriesList.topLevelItem(0) |
73 if itm: |
74 if itm: |
74 itm.setText(self.CommentColumn, txt) |
75 itm.setText(self.CommentColumn, txt) |
75 self.entriesList.resizeColumnToContents(self.CommentColumn) |
76 self.entriesList.resizeColumnToContents(self.CommentColumn) |
76 |
77 |
77 entry = self.__tracker.getCurrentEntry() |
78 entry = self.__tracker.getCurrentEntry() |
78 if entry: |
79 if entry: |
79 entry.setComment(txt) |
80 entry.setComment(txt) |
80 |
81 |
81 @pyqtSlot(bool) |
82 @pyqtSlot(bool) |
82 def on_pauseButton_toggled(self, checked): |
83 def on_pauseButton_toggled(self, checked): |
83 """ |
84 """ |
84 Private slot to pause the current timing. |
85 Private slot to pause the current timing. |
85 |
86 |
86 @param checked flag indicating the checked status of the button |
87 @param checked flag indicating the checked status of the button |
87 @type bool |
88 @type bool |
88 """ |
89 """ |
89 if checked: |
90 if checked: |
90 self.__tracker.pauseTrackerEntry() |
91 self.__tracker.pauseTrackerEntry() |
91 |
92 |
92 entry = self.__tracker.getCurrentEntry() |
93 entry = self.__tracker.getCurrentEntry() |
93 duration = entry.getDuration() |
94 duration = entry.getDuration() |
94 |
95 |
95 itm = self.entriesList.topLevelItem(0) |
96 itm = self.entriesList.topLevelItem(0) |
96 itm.setText(self.DurationColumn, |
97 itm.setText(self.DurationColumn, self.tr("{0} min").format(duration)) |
97 self.tr("{0} min").format(duration)) |
|
98 self.entriesList.resizeColumnToContents(self.DurationColumn) |
98 self.entriesList.resizeColumnToContents(self.DurationColumn) |
99 |
99 |
100 self.durationSpinBox.setValue(duration) |
100 self.durationSpinBox.setValue(duration) |
101 else: |
101 else: |
102 self.__tracker.continueTrackerEntry() |
102 self.__tracker.continueTrackerEntry() |
103 |
103 |
104 @pyqtSlot() |
104 @pyqtSlot() |
105 def on_newButton_clicked(self): |
105 def on_newButton_clicked(self): |
106 """ |
106 """ |
107 Private slot to end the current timer and start a new one. |
107 Private slot to end the current timer and start a new one. |
108 """ |
108 """ |
109 # stop the current tracker |
109 # stop the current tracker |
110 eid, duration = self.__tracker.stopTrackerEntry() |
110 eid, duration = self.__tracker.stopTrackerEntry() |
111 if eid > -1: |
111 if eid > -1: |
112 itm = self.entriesList.topLevelItem(0) |
112 itm = self.entriesList.topLevelItem(0) |
113 itm.setText(self.DurationColumn, |
113 itm.setText(self.DurationColumn, self.tr("{0} min").format(duration)) |
114 self.tr("{0} min").format(duration)) |
|
115 itm.setData(0, Qt.ItemDataRole.UserRole, eid) |
114 itm.setData(0, Qt.ItemDataRole.UserRole, eid) |
116 else: |
115 else: |
117 itm = self.entriesList.takeTopLevelItem(0) |
116 itm = self.entriesList.takeTopLevelItem(0) |
118 del itm |
117 del itm |
119 self.__resizeColumns() |
118 self.__resizeColumns() |
120 |
119 |
121 # start a new one |
120 # start a new one |
122 self.__tracker.startTrackerEntry() |
121 self.__tracker.startTrackerEntry() |
123 |
122 |
124 @pyqtSlot(QPoint) |
123 @pyqtSlot(QPoint) |
125 def on_entriesList_customContextMenuRequested(self, pos): |
124 def on_entriesList_customContextMenuRequested(self, pos): |
126 """ |
125 """ |
127 Private slot to create the context menu and show it. |
126 Private slot to create the context menu and show it. |
128 |
127 |
129 @param pos position the menu should be shown at |
128 @param pos position the menu should be shown at |
130 @type QPoint |
129 @type QPoint |
131 """ |
130 """ |
132 menu = QMenu() |
131 menu = QMenu() |
133 |
132 |
134 act = menu.addAction(self.tr("Edit"), self.__editEntry) |
133 act = menu.addAction(self.tr("Edit"), self.__editEntry) |
135 act.setEnabled( |
134 act.setEnabled( |
136 len(self.entriesList.selectedItems()) == 1 and |
135 len(self.entriesList.selectedItems()) == 1 |
137 self.entriesList.selectedItems()[0].data( |
136 and self.entriesList.selectedItems()[0].data(0, Qt.ItemDataRole.UserRole) |
138 0, Qt.ItemDataRole.UserRole) > -1 |
137 > -1 |
139 ) |
138 ) |
140 menu.addAction(self.tr("Add"), self.__addEntry) |
139 menu.addAction(self.tr("Add"), self.__addEntry) |
141 act = menu.addAction(self.tr("Delete"), self.__deleteSelectedEntries) |
140 act = menu.addAction(self.tr("Delete"), self.__deleteSelectedEntries) |
142 act.setEnabled( |
141 act.setEnabled( |
143 (len(self.entriesList.selectedItems()) == 1 and |
142 ( |
144 self.entriesList.selectedItems()[0].data( |
143 len(self.entriesList.selectedItems()) == 1 |
145 0, Qt.ItemDataRole.UserRole) > -1) or |
144 and self.entriesList.selectedItems()[0].data( |
146 len(self.entriesList.selectedItems()) > 1 |
145 0, Qt.ItemDataRole.UserRole |
|
146 ) |
|
147 > -1 |
|
148 ) |
|
149 or len(self.entriesList.selectedItems()) > 1 |
147 ) |
150 ) |
148 menu.addSeparator() |
151 menu.addSeparator() |
149 menu.addAction(self.tr("Save"), self.__saveEntries) |
152 menu.addAction(self.tr("Save"), self.__saveEntries) |
150 menu.addSeparator() |
153 menu.addSeparator() |
151 menu.addAction(self.tr("Import"), self.__importEntries) |
154 menu.addAction(self.tr("Import"), self.__importEntries) |
152 act = menu.addAction(self.tr("Export Selected"), |
155 act = menu.addAction(self.tr("Export Selected"), self.__exportSelectedEntries) |
153 self.__exportSelectedEntries) |
|
154 act.setEnabled(len(self.entriesList.selectedItems()) > 0) |
156 act.setEnabled(len(self.entriesList.selectedItems()) > 0) |
155 menu.addAction(self.tr("Export All"), self.__exportEntries) |
157 menu.addAction(self.tr("Export All"), self.__exportEntries) |
156 menu.addSeparator() |
158 menu.addSeparator() |
157 menu.addAction(self.tr("Remove duplicates"), self.__removeDuplicates) |
159 menu.addAction(self.tr("Remove duplicates"), self.__removeDuplicates) |
158 menu.addAction(self.tr("Merge duplicates"), self.__mergeDuplicates) |
160 menu.addAction(self.tr("Merge duplicates"), self.__mergeDuplicates) |
159 menu.exec(QCursor.pos()) |
161 menu.exec(QCursor.pos()) |
160 |
162 |
161 def __addEntry(self): |
163 def __addEntry(self): |
162 """ |
164 """ |
163 Private slot to manually add an entry. |
165 Private slot to manually add an entry. |
164 """ |
166 """ |
165 from .TimeTrackerEntryDialog import TimeTrackerEntryDialog |
167 from .TimeTrackerEntryDialog import TimeTrackerEntryDialog |
166 |
168 |
167 tasks = [self.taskCombo.itemText(index) |
169 tasks = [ |
168 for index in range(self.taskCombo.count())] |
170 self.taskCombo.itemText(index) for index in range(self.taskCombo.count()) |
169 comments = [self.commentCombo.itemText(index) |
171 ] |
170 for index in range(self.commentCombo.count())] |
172 comments = [ |
|
173 self.commentCombo.itemText(index) |
|
174 for index in range(self.commentCombo.count()) |
|
175 ] |
171 dlg = TimeTrackerEntryDialog(self.__tracker, None, tasks, comments) |
176 dlg = TimeTrackerEntryDialog(self.__tracker, None, tasks, comments) |
172 if dlg.exec() == QDialog.DialogCode.Accepted: |
177 if dlg.exec() == QDialog.DialogCode.Accepted: |
173 self.__tracker.addTrackerEntry(*dlg.getData()) |
178 self.__tracker.addTrackerEntry(*dlg.getData()) |
174 |
179 |
175 def __editEntry(self): |
180 def __editEntry(self): |
176 """ |
181 """ |
177 Private slot to edit the selected tracker entry. |
182 Private slot to edit the selected tracker entry. |
178 """ |
183 """ |
179 itm = self.entriesList.selectedItems()[0] |
184 itm = self.entriesList.selectedItems()[0] |
181 if eid > -1: |
186 if eid > -1: |
182 # the current entry is edited via the elements of this widget |
187 # the current entry is edited via the elements of this widget |
183 entry = self.__tracker.getEntry(eid) |
188 entry = self.__tracker.getEntry(eid) |
184 if entry is not None: |
189 if entry is not None: |
185 from .TimeTrackerEntryDialog import TimeTrackerEntryDialog |
190 from .TimeTrackerEntryDialog import TimeTrackerEntryDialog |
186 |
191 |
187 tasks = [self.taskCombo.itemText(index) |
192 tasks = [ |
188 for index in range(self.taskCombo.count())] |
193 self.taskCombo.itemText(index) |
189 comments = [self.commentCombo.itemText(index) |
194 for index in range(self.taskCombo.count()) |
190 for index in range(self.commentCombo.count())] |
195 ] |
191 dlg = TimeTrackerEntryDialog( |
196 comments = [ |
192 self.__tracker, entry, tasks, comments) |
197 self.commentCombo.itemText(index) |
|
198 for index in range(self.commentCombo.count()) |
|
199 ] |
|
200 dlg = TimeTrackerEntryDialog(self.__tracker, entry, tasks, comments) |
193 if dlg.exec() == QDialog.DialogCode.Accepted: |
201 if dlg.exec() == QDialog.DialogCode.Accepted: |
194 start, duration, task, comment = dlg.getData() |
202 start, duration, task, comment = dlg.getData() |
195 |
203 |
196 entry.setStartDateTime(start) |
204 entry.setStartDateTime(start) |
197 entry.setDuration(duration) |
205 entry.setDuration(duration) |
198 entry.setTask(task) |
206 entry.setTask(task) |
199 entry.setComment(comment) |
207 entry.setComment(comment) |
200 self.__tracker.entryChanged() |
208 self.__tracker.entryChanged() |
201 |
209 |
202 data = entry.getEntryData() |
210 data = entry.getEntryData() |
203 itm.setText(0, self.tr("{0}, {1}", "date, time") |
211 itm.setText( |
204 .format(data["start_date"], |
212 0, |
205 data["start_time"])) |
213 self.tr("{0}, {1}", "date, time").format( |
|
214 data["start_date"], data["start_time"] |
|
215 ), |
|
216 ) |
206 itm.setText(1, self.tr("{0} min").format(data["duration"])) |
217 itm.setText(1, self.tr("{0} min").format(data["duration"])) |
207 itm.setText(2, data["task"]) |
218 itm.setText(2, data["task"]) |
208 itm.setText(3, data["comment"]) |
219 itm.setText(3, data["comment"]) |
209 self.__resizeColumns() |
220 self.__resizeColumns() |
210 |
221 |
211 def __deleteSelectedEntries(self): |
222 def __deleteSelectedEntries(self): |
212 """ |
223 """ |
213 Private slot to delete the selected tracker entries. |
224 Private slot to delete the selected tracker entries. |
214 """ |
225 """ |
215 res = EricMessageBox.yesNo( |
226 res = EricMessageBox.yesNo( |
216 self, |
227 self, |
217 self.tr("Delete Selected Entries"), |
228 self.tr("Delete Selected Entries"), |
218 self.tr("""Do you really want to delete the selected""" |
229 self.tr("""Do you really want to delete the selected""" """ entries?"""), |
219 """ entries?""")) |
230 ) |
220 if res: |
231 if res: |
221 for item in self.entriesList.selectedItems(): |
232 for item in self.entriesList.selectedItems(): |
222 eid = item.data(0, Qt.ItemDataRole.UserRole) |
233 eid = item.data(0, Qt.ItemDataRole.UserRole) |
223 if eid > -1: |
234 if eid > -1: |
224 # the current entry must not be deleted |
235 # the current entry must not be deleted |
225 self.entriesList.takeTopLevelItem( |
236 self.entriesList.takeTopLevelItem( |
226 self.entriesList.indexOfTopLevelItem(item)) |
237 self.entriesList.indexOfTopLevelItem(item) |
|
238 ) |
227 self.__tracker.deleteTrackerEntry(eid) |
239 self.__tracker.deleteTrackerEntry(eid) |
228 del item |
240 del item |
229 |
241 |
230 def __saveEntries(self): |
242 def __saveEntries(self): |
231 """ |
243 """ |
232 Private slot to save the tracker entries. |
244 Private slot to save the tracker entries. |
233 """ |
245 """ |
234 self.__tracker.saveTrackerEntries() |
246 self.__tracker.saveTrackerEntries() |
235 |
247 |
236 def __importEntries(self): |
248 def __importEntries(self): |
237 """ |
249 """ |
238 Private slot to import tracker entries. |
250 Private slot to import tracker entries. |
239 """ |
251 """ |
240 path = ( |
252 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() |
241 Preferences.getMultiProject("Workspace") or |
|
242 Utilities.getHomeDir() |
|
243 ) |
|
244 fname = EricFileDialog.getOpenFileName( |
253 fname = EricFileDialog.getOpenFileName( |
245 None, |
254 None, |
246 self.tr("Import Time Tracker Entries"), |
255 self.tr("Import Time Tracker Entries"), |
247 path, |
256 path, |
248 self.tr("Time Tracker Files (*.ttj);;All Files (*)")) |
257 self.tr("Time Tracker Files (*.ttj);;All Files (*)"), |
|
258 ) |
249 if fname: |
259 if fname: |
250 fname = Utilities.toNativeSeparators(fname) |
260 fname = Utilities.toNativeSeparators(fname) |
251 if not os.path.exists(fname): |
261 if not os.path.exists(fname): |
252 EricMessageBox.critical( |
262 EricMessageBox.critical( |
253 self, |
263 self, |
254 self.tr("Import Time Tracker Entries"), |
264 self.tr("Import Time Tracker Entries"), |
255 self.tr("<p>The file <b>{0}</b> does not exist.</p>") |
265 self.tr("<p>The file <b>{0}</b> does not exist.</p>").format(fname), |
256 .format(fname)) |
266 ) |
257 return |
267 return |
258 |
268 |
259 self.__tracker.importTrackerEntries(fname) |
269 self.__tracker.importTrackerEntries(fname) |
260 |
270 |
261 def __exportEntries(self, ids=None): |
271 def __exportEntries(self, ids=None): |
262 """ |
272 """ |
263 Private method to export all or selected entries. |
273 Private method to export all or selected entries. |
264 |
274 |
265 @param ids list of IDs to export or all if empty |
275 @param ids list of IDs to export or all if empty |
266 @type list of int |
276 @type list of int |
267 """ |
277 """ |
268 path = ( |
278 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() |
269 Preferences.getMultiProject("Workspace") or |
|
270 Utilities.getHomeDir() |
|
271 ) |
|
272 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
279 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
273 self, |
280 self, |
274 self.tr("Export Time Tracker Entries"), |
281 self.tr("Export Time Tracker Entries"), |
275 path, |
282 path, |
276 self.tr("Time Tracker Files (*.ttj);;All Files (*)"), |
283 self.tr("Time Tracker Files (*.ttj);;All Files (*)"), |
277 None, |
284 None, |
278 EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite)) |
285 EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite), |
|
286 ) |
279 if fname: |
287 if fname: |
280 ext = QFileInfo(fname).suffix() |
288 ext = QFileInfo(fname).suffix() |
281 if not ext: |
289 if not ext: |
282 ex = selectedFilter.split("(*")[1].split(")")[0] |
290 ex = selectedFilter.split("(*")[1].split(")")[0] |
283 if ex: |
291 if ex: |
284 fname += ex |
292 fname += ex |
285 if QFileInfo(fname).exists(): |
293 if QFileInfo(fname).exists(): |
286 res = EricMessageBox.yesNo( |
294 res = EricMessageBox.yesNo( |
287 self, |
295 self, |
288 self.tr("Export Time Tracker Entries"), |
296 self.tr("Export Time Tracker Entries"), |
289 self.tr("<p>The file <b>{0}</b> already exists." |
297 self.tr( |
290 " Overwrite it?</p>").format(fname), |
298 "<p>The file <b>{0}</b> already exists." " Overwrite it?</p>" |
291 icon=EricMessageBox.Warning) |
299 ).format(fname), |
|
300 icon=EricMessageBox.Warning, |
|
301 ) |
292 if not res: |
302 if not res: |
293 return |
303 return |
294 fname = Utilities.toNativeSeparators(fname) |
304 fname = Utilities.toNativeSeparators(fname) |
295 self.__tracker.saveTrackerEntries(filePath=fname, ids=ids) |
305 self.__tracker.saveTrackerEntries(filePath=fname, ids=ids) |
296 |
306 |
297 def __exportSelectedEntries(self): |
307 def __exportSelectedEntries(self): |
298 """ |
308 """ |
299 Private slot to export the selected tracker entries. |
309 Private slot to export the selected tracker entries. |
300 """ |
310 """ |
301 ids = [] |
311 ids = [] |
302 for itm in self.entriesList.selectedItems(): |
312 for itm in self.entriesList.selectedItems(): |
303 eid = itm.data(0, Qt.ItemDataRole.UserRole) |
313 eid = itm.data(0, Qt.ItemDataRole.UserRole) |
304 if eid > -1: |
314 if eid > -1: |
305 ids.append(eid) |
315 ids.append(eid) |
306 |
316 |
307 if ids: |
317 if ids: |
308 self.__exportEntries(ids=ids) |
318 self.__exportEntries(ids=ids) |
309 |
319 |
310 def __removeDuplicates(self): |
320 def __removeDuplicates(self): |
311 """ |
321 """ |
312 Private slot to remove duplicate entries. |
322 Private slot to remove duplicate entries. |
313 """ |
323 """ |
314 res = EricMessageBox.yesNo( |
324 res = EricMessageBox.yesNo( |
315 self, |
325 self, |
316 self.tr("Remove Duplicate Tracker Entries"), |
326 self.tr("Remove Duplicate Tracker Entries"), |
317 self.tr("""Are you sure you want to remove duplicate""" |
327 self.tr( |
318 """ tracker entries? Only the one with the longest""" |
328 """Are you sure you want to remove duplicate""" |
319 """ duration will be kept.""")) |
329 """ tracker entries? Only the one with the longest""" |
|
330 """ duration will be kept.""" |
|
331 ), |
|
332 ) |
320 if res: |
333 if res: |
321 self.__tracker.removeDuplicateTrackerEntries() |
334 self.__tracker.removeDuplicateTrackerEntries() |
322 |
335 |
323 def __mergeDuplicates(self): |
336 def __mergeDuplicates(self): |
324 """ |
337 """ |
325 Private slot to merge duplicate entries. |
338 Private slot to merge duplicate entries. |
326 """ |
339 """ |
327 res = EricMessageBox.yesNo( |
340 res = EricMessageBox.yesNo( |
328 self, |
341 self, |
329 self.tr("Merge Duplicate Tracker Entries"), |
342 self.tr("Merge Duplicate Tracker Entries"), |
330 self.tr("""Are you sure you want to merge duplicate""" |
343 self.tr( |
331 """ tracker entries? The durations of duplicate""" |
344 """Are you sure you want to merge duplicate""" |
332 """ ones will be added.""")) |
345 """ tracker entries? The durations of duplicate""" |
|
346 """ ones will be added.""" |
|
347 ), |
|
348 ) |
333 if res: |
349 if res: |
334 self.__tracker.mergeDuplicateTrackerEntries() |
350 self.__tracker.mergeDuplicateTrackerEntries() |
335 |
351 |
336 def __insertEntry(self, entry, index=-1): |
352 def __insertEntry(self, entry, index=-1): |
337 """ |
353 """ |
338 Private method to insert a tracker entry into the list. |
354 Private method to insert a tracker entry into the list. |
339 |
355 |
340 @param entry reference to the tracker entry |
356 @param entry reference to the tracker entry |
341 @type TimeTrackEntry |
357 @type TimeTrackEntry |
342 @param index index the entry is to be inserted; -1 for at the end |
358 @param index index the entry is to be inserted; -1 for at the end |
343 @type int |
359 @type int |
344 """ |
360 """ |
345 data = entry.getEntryData() |
361 data = entry.getEntryData() |
346 itm = QTreeWidgetItem( |
362 itm = QTreeWidgetItem( |
347 [self.tr("{0}, {1}", "date, time").format(data["start_date"], |
363 [ |
348 data["start_time"]), |
364 self.tr("{0}, {1}", "date, time").format( |
349 self.tr("{0} min").format(data["duration"]), |
365 data["start_date"], data["start_time"] |
350 data["task"], |
366 ), |
351 data["comment"]] |
367 self.tr("{0} min").format(data["duration"]), |
|
368 data["task"], |
|
369 data["comment"], |
|
370 ] |
352 ) |
371 ) |
353 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight) |
372 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight) |
354 itm.setData(0, Qt.ItemDataRole.UserRole, data["id"]) |
373 itm.setData(0, Qt.ItemDataRole.UserRole, data["id"]) |
355 if index == -1: |
374 if index == -1: |
356 self.entriesList.addTopLevelItem(itm) |
375 self.entriesList.addTopLevelItem(itm) |
357 else: |
376 else: |
358 self.entriesList.insertTopLevelItem(index, itm) |
377 self.entriesList.insertTopLevelItem(index, itm) |
359 |
378 |
360 def __resizeColumns(self): |
379 def __resizeColumns(self): |
361 """ |
380 """ |
362 Private slot to resize the columns of the entries list. |
381 Private slot to resize the columns of the entries list. |
363 """ |
382 """ |
364 for column in range(self.entriesList.columnCount()): |
383 for column in range(self.entriesList.columnCount()): |
365 self.entriesList.resizeColumnToContents(column) |
384 self.entriesList.resizeColumnToContents(column) |
366 |
385 |
367 def showTrackerEntries(self, entries): |
386 def showTrackerEntries(self, entries): |
368 """ |
387 """ |
369 Public method to show the tracker entries of the current project. |
388 Public method to show the tracker entries of the current project. |
370 |
389 |
371 @param entries list of tracker entries |
390 @param entries list of tracker entries |
372 @type list of TimeTrackEntry |
391 @type list of TimeTrackEntry |
373 """ |
392 """ |
374 self.taskCombo.addItem("") |
393 self.taskCombo.addItem("") |
375 self.commentCombo.addItem("") |
394 self.commentCombo.addItem("") |
376 |
395 |
377 tasks = [] |
396 tasks = [] |
378 comments = [] |
397 comments = [] |
379 |
398 |
380 for entry in entries: |
399 for entry in entries: |
381 self.__insertEntry(entry) |
400 self.__insertEntry(entry) |
382 task = entry.getTask() |
401 task = entry.getTask() |
383 if task and task not in tasks: |
402 if task and task not in tasks: |
384 tasks.append(task) |
403 tasks.append(task) |
385 comment = entry.getComment() |
404 comment = entry.getComment() |
386 if comment and comment not in comments: |
405 if comment and comment not in comments: |
387 comments.append(comment) |
406 comments.append(comment) |
388 |
407 |
389 self.__resizeColumns() |
408 self.__resizeColumns() |
390 if tasks: |
409 if tasks: |
391 self.taskCombo.addItems(sorted(tasks)) |
410 self.taskCombo.addItems(sorted(tasks)) |
392 if comments: |
411 if comments: |
393 self.commentCombo.addItems(sorted(comments)) |
412 self.commentCombo.addItems(sorted(comments)) |
394 |
413 |
395 def setCurrentEntry(self, entry): |
414 def setCurrentEntry(self, entry): |
396 """ |
415 """ |
397 Public method to set the current entry. |
416 Public method to set the current entry. |
398 |
417 |
399 @param entry current entry |
418 @param entry current entry |
400 @type TimeTrackEntry |
419 @type TimeTrackEntry |
401 """ |
420 """ |
402 self.__insertEntry(entry, 0) |
421 self.__insertEntry(entry, 0) |
403 self.__resizeColumns() |
422 self.__resizeColumns() |
404 |
423 |
405 data = entry.getEntryData() |
424 data = entry.getEntryData() |
406 self.startDateTimeEdit.setDateTime(entry.getStartDateTime()) |
425 self.startDateTimeEdit.setDateTime(entry.getStartDateTime()) |
407 self.durationSpinBox.setValue(data["duration"]) |
426 self.durationSpinBox.setValue(data["duration"]) |
408 self.taskCombo.setEditText(data["task"]) |
427 self.taskCombo.setEditText(data["task"]) |
409 self.commentCombo.setEditText(data["comment"]) |
428 self.commentCombo.setEditText(data["comment"]) |
410 |
429 |
411 def clear(self): |
430 def clear(self): |
412 """ |
431 """ |
413 Public method to clear all the data. |
432 Public method to clear all the data. |
414 """ |
433 """ |
415 self.entriesList.clear() |
434 self.entriesList.clear() |