Tasks/TaskViewer.py

changeset 0
de9c2efb9d02
child 12
1d8dd9706f46
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2005 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a task viewer and associated classes.
8
9 Tasks can be defined manually or automatically. Automatically
10 generated tasks are derived from a comment with a special
11 introductory text. This text is configurable.
12 """
13
14 import os
15 import sys
16 import time
17
18 from PyQt4.QtCore import *
19 from PyQt4.QtGui import *
20
21 from E4Gui.E4Application import e4App
22
23 from TaskPropertiesDialog import TaskPropertiesDialog
24 from TaskFilterConfigDialog import TaskFilterConfigDialog
25
26 import UI.PixmapCache
27
28 import Preferences
29 import Utilities
30
31 class Task(QTreeWidgetItem):
32 """
33 Class implementing the task data structure.
34 """
35 def __init__(self, description, priority = 1, filename = "", lineno = 0,
36 completed = False, _time = 0, isProjectTask = False,
37 isBugfixTask = False, ppath = "", longtext = ""):
38 """
39 Constructor
40
41 @param parent parent widget of the task (QWidget)
42 @param description descriptive text of the task (string)
43 @param priority priority of the task (0=high, 1=normal, 2=low)
44 @param filename filename containing the task (string)
45 @param lineno line number containing the task (integer)
46 @param completed flag indicating completion status (boolean)
47 @param _time creation time of the task (float, if 0 use current time)
48 @param isProjectTask flag indicating a task related to the current project
49 (boolean)
50 @param isBugfixTask flag indicating a bugfix task (boolean)
51 @param ppath the project path (string)
52 @param longtext explanatory text of the task (string)
53 """
54 self.description = description
55 self.longtext = longtext
56 if priority in [0, 1, 2]:
57 self.priority = priority
58 else:
59 self.priority = 1
60 self.filename = filename
61 self.lineno = lineno
62 self.completed = completed
63 self.created = _time and _time or time.time()
64 self._isProjectTask = isProjectTask
65 self.isBugfixTask = isBugfixTask
66 self.ppath = ppath
67
68 if isProjectTask:
69 self.filename = self.filename.replace(self.ppath + os.sep, "")
70
71 QTreeWidgetItem.__init__(self, ["", "", self.description, self.filename,
72 (self.lineno and "%6d" % self.lineno or "")])
73
74 if self.completed:
75 self.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png"))
76 else:
77 self.setIcon(0, UI.PixmapCache.getIcon("empty.png"))
78
79 if self.priority == 1:
80 self.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
81 elif self.priority == 0:
82 self.setIcon(1, UI.PixmapCache.getIcon("taskPrioHigh.png"))
83 elif self.priority == 2:
84 self.setIcon(1, UI.PixmapCache.getIcon("taskPrioLow.png"))
85 else:
86 self.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
87
88 self.colorizeTask()
89 self.setTextAlignment(4, Qt.AlignRight)
90
91 def colorizeTask(self):
92 """
93 Public slot to set the colors of the task item.
94 """
95 for col in range(5):
96 if self.isBugfixTask:
97 self.setTextColor(col, Preferences.getTasks("TasksBugfixColour"))
98 else:
99 self.setTextColor(col, Preferences.getTasks("TasksColour"))
100 if self._isProjectTask:
101 self.setBackgroundColor(col, Preferences.getTasks("TasksProjectBgColour"))
102 else:
103 self.setBackgroundColor(col, Preferences.getTasks("TasksBgColour"))
104
105 def setDescription(self, description):
106 """
107 Public slot to update the description.
108
109 @param longtext explanatory text of the task (string)
110 """
111 self.description = description
112 self.setText(2, self.description)
113
114 def setLongText(self, longtext):
115 """
116 Public slot to update the longtext field.
117
118 @param longtext descriptive text of the task (string)
119 """
120 self.longtext = longtext
121
122 def setPriority(self, priority):
123 """
124 Public slot to update the priority.
125
126 @param priority priority of the task (0=high, 1=normal, 2=low)
127 """
128 if priority in [0, 1, 2]:
129 self.priority = priority
130 else:
131 self.priority = 1
132
133 if self.priority == 1:
134 self.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
135 elif self.priority == 0:
136 self.setIcon(1, UI.PixmapCache.getIcon("taskPrioHigh.png"))
137 elif self.priority == 2:
138 self.setIcon(1, UI.PixmapCache.getIcon("taskPrioLow.png"))
139 else:
140 self.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
141
142 def setCompleted(self, completed):
143 """
144 Public slot to update the completed flag.
145
146 @param completed flag indicating completion status (boolean)
147 """
148 self.completed = completed
149 if self.completed:
150 self.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png"))
151 else:
152 self.setIcon(0, UI.PixmapCache.getIcon("empty.png"))
153
154 def isCompleted(self):
155 """
156 Public slot to return the completion status.
157
158 @return flag indicating the completion status (boolean)
159 """
160 return self.completed
161
162 def getFilename(self):
163 """
164 Public method to retrieve the tasks filename.
165
166 @return filename (string)
167 """
168 if self._isProjectTask and self.filename:
169 return os.path.join(self.ppath, self.filename)
170 else:
171 return self.filename
172
173 def getLineno(self):
174 """
175 Public method to retrieve the tasks linenumber.
176
177 @return linenumber (integer)
178 """
179 return self.lineno
180
181 def setProjectTask(self, pt):
182 """
183 Public method to set the project relation flag.
184
185 @param pt flag indicating a project task (boolean)
186 """
187 self._isProjectTask = pt
188 self.colorizeTask()
189
190 def isProjectTask(self):
191 """
192 Public slot to return the project relation status.
193
194 @return flag indicating the project relation status (boolean)
195 """
196 return self._isProjectTask
197
198 class TaskFilter(object):
199 """
200 Class implementing a filter for tasks.
201 """
202 def __init__(self):
203 """
204 Constructor
205 """
206 self.active = False
207
208 self.descriptionFilter = None
209 self.filenameFilter = None
210 self.typeFilter = None # standard (False) or bugfix (True)
211 self.scopeFilter = None # global (False) or project (True)
212 self.statusFilter = None # uncompleted (False) or completed (True)
213 self.prioritiesFilter = None # list of priorities [0 (high), 1 (normal), 2 (low)]
214
215 def setActive(self, enabled):
216 """
217 Public method to activate the filter.
218
219 @param enabled flag indicating the activation state (boolean)
220 """
221 self.active = enabled
222
223 def setDescriptionFilter(self, filter):
224 """
225 Public method to set the description filter.
226
227 @param filter a regular expression for the description filter
228 to set (string) or None
229 """
230 if not filter:
231 self.descriptionFilter = None
232 else:
233 self.descriptionFilter = QRegExp(filter)
234
235 def setFileNameFilter(self, filter):
236 """
237 Public method to set the filename filter.
238
239 @param filter a wildcard expression for the filename filter
240 to set (string) or None
241 """
242 if not filter:
243 self.filenameFilter = None
244 else:
245 self.filenameFilter = QRegExp(filter)
246 self.filenameFilter.setPatternSyntax(QRegExp.Wildcard)
247
248 def setTypeFilter(self, type_):
249 """
250 Public method to set the type filter.
251
252 @param type_ flag indicating a bugfix task (boolean) or None
253 """
254 self.typeFilter = type_
255
256 def setScopeFilter(self, scope):
257 """
258 Public method to set the scope filter.
259
260 @param scope flag indicating a project task (boolean) or None
261 """
262 self.scopeFilter = scope
263
264 def setStatusFilter(self, status):
265 """
266 Public method to set the status filter.
267
268 @param status flag indicating a completed task (boolean) or None
269 """
270 self.statusFilter = status
271
272 def setPrioritiesFilter(self, priorities):
273 """
274 Public method to set the priorities filter.
275
276 @param priorities list of task priorities (list of integer) or None
277 """
278 self.prioritiesFilter = priorities
279
280 def hasActiveFilter(self):
281 """
282 Public method to check for active filters.
283
284 @return flag indicating an active filter was found (boolean)
285 """
286 return self.descriptionFilter is not None or \
287 self.filenameFilter is not None or \
288 self.typeFilter is not None or \
289 self.scopeFilter is not None or \
290 self.statusFilter is not None or \
291 self.prioritiesFilter is not None
292
293 def showTask(self, task):
294 """
295 Public method to check, if a task should be shown.
296
297 @param task reference to the task object to check (Task)
298 @return flag indicating whether the task should be shown (boolean)
299 """
300 if not self.active:
301 return True
302
303 if self.descriptionFilter and \
304 self.descriptionFilter.indexIn(task.description) == -1:
305 return False
306
307 if self.filenameFilter and \
308 not self.filenameFilter.exactMatch(task.filename):
309 return False
310
311 if self.typeFilter is not None and \
312 self.typeFilter != task.isBugfixTask:
313 return False
314
315 if self.scopeFilter is not None and \
316 self.scopeFilter != task._isProjectTask:
317 return False
318
319 if self.statusFilter is not None and \
320 self.statusFilter != task.completed:
321 return False
322
323 if self.prioritiesFilter is not None and \
324 not task.priority in self.prioritiesFilter:
325 return False
326
327 return True
328
329 class TaskViewer(QTreeWidget):
330 """
331 Class implementing the task viewer.
332
333 @signal displayFile(string, integer) emitted to go to a file task
334 """
335 def __init__(self, parent, project):
336 """
337 Constructor
338
339 @param parent the parent (QWidget)
340 @param project reference to the project object
341 """
342 QTreeWidget.__init__(self, parent)
343
344 self.setRootIsDecorated(False)
345 self.setItemsExpandable(False)
346 self.setSortingEnabled(True)
347
348 self.__headerItem = QTreeWidgetItem(["", "", self.trUtf8("Summary"),
349 self.trUtf8("Filename"), self.trUtf8("Line"), ""])
350 self.__headerItem.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png"))
351 self.__headerItem.setIcon(1, UI.PixmapCache.getIcon("taskPriority.png"))
352 self.setHeaderItem(self.__headerItem)
353
354 self.header().setSortIndicator(2, Qt.AscendingOrder)
355 self.__resizeColumns()
356
357 self.tasks = []
358 self.copyTask = None
359 self.projectOpen = False
360 self.project = project
361
362 self.taskFilter = TaskFilter()
363 self.taskFilter.setActive(False)
364
365 self.__menu = QMenu(self)
366 self.__menu.addAction(self.trUtf8("&New Task..."), self.__newTask)
367 self.__menu.addSeparator()
368 self.regenerateProjectTasksItem = \
369 self.__menu.addAction(self.trUtf8("&Regenerate project tasks"),
370 self.__regenerateProjectTasks)
371 self.__menu.addSeparator()
372 self.gotoItem = self.__menu.addAction(self.trUtf8("&Go To"), self.__goToTask)
373 self.__menu.addSeparator()
374 self.copyItem = self.__menu.addAction(self.trUtf8("&Copy"), self.__copyTask)
375 self.pasteItem = self.__menu.addAction(self.trUtf8("&Paste"), self.__pasteTask)
376 self.deleteItem = self.__menu.addAction(self.trUtf8("&Delete"), self.__deleteTask)
377 self.__menu.addSeparator()
378 self.markCompletedItem = self.__menu.addAction(self.trUtf8("&Mark Completed"),
379 self.__markCompleted)
380 self.__menu.addAction(self.trUtf8("Delete Completed &Tasks"),
381 self.__deleteCompleted)
382 self.__menu.addSeparator()
383 self.__menu.addAction(self.trUtf8("P&roperties..."), self.__editTaskProperties)
384 self.__menu.addSeparator()
385 self.__menuFilteredAct = self.__menu.addAction(self.trUtf8("&Filtered display"))
386 self.__menuFilteredAct.setCheckable(True)
387 self.__menuFilteredAct.setChecked(False)
388 self.connect(self.__menuFilteredAct, SIGNAL("triggered(bool)"),
389 self.__activateFilter)
390 self.__menu.addAction(self.trUtf8("Filter c&onfiguration..."),
391 self.__configureFilter)
392 self.__menu.addSeparator()
393 self.__menu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns)
394 self.__menu.addSeparator()
395 self.__menu.addAction(self.trUtf8("Configure..."), self.__configure)
396
397 self.__backMenu = QMenu(self)
398 self.__backMenu.addAction(self.trUtf8("&New Task..."), self.__newTask)
399 self.__backMenu.addSeparator()
400 self.backRegenerateProjectTasksItem = \
401 self.__backMenu.addAction(self.trUtf8("&Regenerate project tasks"),
402 self.__regenerateProjectTasks)
403 self.__backMenu.addSeparator()
404 self.backPasteItem = self.__backMenu.addAction(self.trUtf8("&Paste"),
405 self.__pasteTask)
406 self.__backMenu.addSeparator()
407 self.__backMenu.addAction(self.trUtf8("Delete Completed &Tasks"),
408 self.__deleteCompleted)
409 self.__backMenu.addSeparator()
410 self.__backMenuFilteredAct = \
411 self.__backMenu.addAction(self.trUtf8("&Filtered display"))
412 self.__backMenuFilteredAct.setCheckable(True)
413 self.__backMenuFilteredAct.setChecked(False)
414 self.connect(self.__backMenuFilteredAct, SIGNAL("triggered(bool)"),
415 self.__activateFilter)
416 self.__backMenu.addAction(self.trUtf8("Filter c&onfiguration..."),
417 self.__configureFilter)
418 self.__backMenu.addSeparator()
419 self.__backMenu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns)
420 self.__backMenu.addSeparator()
421 self.__backMenu.addAction(self.trUtf8("Configure..."), self.__configure)
422
423 self.setContextMenuPolicy(Qt.CustomContextMenu)
424 self.connect(self, SIGNAL("customContextMenuRequested(const QPoint &)"),
425 self.__showContextMenu)
426 self.connect(self, SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
427 self.__taskItemActivated)
428
429 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
430
431 def __resort(self):
432 """
433 Private method to resort the tree.
434 """
435 self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder())
436
437 def __resizeColumns(self):
438 """
439 Private method to resize the list columns.
440 """
441 self.header().resizeSections(QHeaderView.ResizeToContents)
442 self.header().setStretchLastSection(True)
443
444 def __refreshDisplay(self):
445 """
446 Private method to refresh the display.
447 """
448 for task in self.tasks:
449 index = self.indexOfTopLevelItem(task)
450 if self.taskFilter.showTask(task):
451 # show the task
452 if index == -1:
453 self.addTopLevelItem(task)
454 else:
455 # hide the task
456 if index != -1:
457 self.takeTopLevelItem(index)
458 self.__resort()
459 self.__resizeColumns()
460
461 def __taskItemActivated(self, itm, col):
462 """
463 Private slot to handle the activation of an item.
464
465 @param itm reference to the activated item (QTreeWidgetItem)
466 @param col column the item was activated in (integer)
467 """
468 fn = itm.getFilename()
469 if fn:
470 self.emit(SIGNAL("displayFile"), fn, itm.getLineno())
471 else:
472 self.__editTaskProperties()
473
474 def __showContextMenu(self, coord):
475 """
476 Private slot to show the context menu of the list.
477
478 @param coord the position of the mouse pointer (QPoint)
479 """
480 itm = self.itemAt(coord)
481 coord = self.mapToGlobal(coord)
482 if itm is None:
483 self.backRegenerateProjectTasksItem.setEnabled(self.projectOpen)
484 if self.copyTask:
485 self.backPasteItem.setEnabled(True)
486 else:
487 self.backPasteItem.setEnabled(False)
488 self.__backMenu.popup(coord)
489 else:
490 self.regenerateProjectTasksItem.setEnabled(self.projectOpen)
491 if itm.getFilename():
492 self.gotoItem.setEnabled(True)
493 self.deleteItem.setEnabled(True)
494 self.markCompletedItem.setEnabled(False)
495 self.copyItem.setEnabled(False)
496 else:
497 self.gotoItem.setEnabled(False)
498 self.deleteItem.setEnabled(True)
499 self.markCompletedItem.setEnabled(True)
500 self.copyItem.setEnabled(True)
501 if self.copyTask:
502 self.pasteItem.setEnabled(True)
503 else:
504 self.pasteItem.setEnabled(False)
505
506 self.__menu.popup(coord)
507
508 def setProjectOpen(self, o = False):
509 """
510 Public slot to set the project status.
511
512 @param o flag indicating the project status
513 """
514 self.projectOpen = o
515
516 def addTask(self, description, priority = 1, filename = "", lineno = 0,
517 completed = False, _time = 0, isProjectTask = False,
518 isBugfixTask = False, longtext = ""):
519 """
520 Public slot to add a task.
521
522 @param description descriptive text of the task (string)
523 @param priority priority of the task (0=high, 1=normal, 2=low)
524 @param filename filename containing the task (string)
525 @param lineno line number containing the task (integer)
526 @param completed flag indicating completion status (boolean)
527 @param _time creation time of the task (float, if 0 use current time)
528 @param isProjectTask flag indicating a task related to the current
529 project (boolean)
530 @param isBugfixTask flag indicating a bugfix task (boolean)
531 @param longtext explanatory text of the task (string)
532 """
533 task = Task(description, priority, filename, lineno, completed,
534 _time, isProjectTask, isBugfixTask,
535 self.project and self.project.ppath or "",
536 longtext)
537 self.tasks.append(task)
538 if self.taskFilter.showTask(task):
539 self.addTopLevelItem(task)
540 self.__resort()
541 self.__resizeColumns()
542
543 def addFileTask(self, description, filename, lineno, isBugfixTask = False,
544 longtext = ""):
545 """
546 Public slot to add a file related task.
547
548 @param description descriptive text of the task (string)
549 @param filename filename containing the task (string)
550 @param lineno line number containing the task (integer)
551 @param isBugfixTask flag indicating a bugfix task (boolean)
552 @param longtext explanatory text of the task (string)
553 """
554 self.addTask(description, filename = filename, lineno = lineno,
555 isProjectTask = \
556 self.project and self.project.isProjectSource(filename),
557 isBugfixTask = isBugfixTask, longtext = longtext)
558
559 def getProjectTasks(self):
560 """
561 Public method to retrieve all project related tasks.
562
563 @return copy of tasks (list of Task)
564 """
565 tasks = [task for task in self.tasks if task.isProjectTask()]
566 return tasks[:]
567
568 def getGlobalTasks(self):
569 """
570 Public method to retrieve all non project related tasks.
571
572 @return copy of tasks (list of Task)
573 """
574 tasks = [task for task in self.tasks if not task.isProjectTask()]
575 return tasks[:]
576
577 def clearTasks(self):
578 """
579 Public slot to clear all tasks from display.
580 """
581 self.tasks = []
582 self.clear()
583
584 def clearProjectTasks(self):
585 """
586 Public slot to clear project related tasks.
587 """
588 for task in self.tasks[:]:
589 if task.isProjectTask():
590 if self.copyTask == task:
591 self.copyTask = None
592 index = self.indexOfTopLevelItem(task)
593 self.takeTopLevelItem(index)
594 self.tasks.remove(task)
595 del task
596
597 def clearFileTasks(self, filename):
598 """
599 Public slot to clear all tasks related to a file.
600
601 @param filename name of the file (string)
602 """
603 for task in self.tasks[:]:
604 if task.getFilename() == filename:
605 if self.copyTask == task:
606 self.copyTask = None
607 index = self.indexOfTopLevelItem(task)
608 self.takeTopLevelItem(index)
609 self.tasks.remove(task)
610 del task
611
612 def __editTaskProperties(self):
613 """
614 Private slot to handle the "Properties" context menu entry
615 """
616 task = self.currentItem()
617 dlg = TaskPropertiesDialog(task, self, self.projectOpen)
618 ro = task.getFilename() != ""
619 if ro:
620 dlg.setReadOnly()
621 if dlg.exec_() == QDialog.Accepted and not ro:
622 data = dlg.getData()
623 task.setDescription(data[0])
624 task.setPriority(data[1])
625 task.setCompleted(data[2])
626 task.setProjectTask(data[3])
627 task.setLongText(data[4])
628
629 def __newTask(self):
630 """
631 Private slot to handle the "New Task" context menu entry.
632 """
633 dlg = TaskPropertiesDialog(None, self, self.projectOpen)
634 if dlg.exec_() == QDialog.Accepted:
635 data = dlg.getData()
636 self.addTask(data[0], data[1], completed = data[2], isProjectTask = data[3],
637 longtext = data[4])
638
639 def __markCompleted(self):
640 """
641 Private slot to handle the "Mark Completed" context menu entry.
642 """
643 task = self.currentItem()
644 task.setCompleted(True)
645
646 def __deleteCompleted(self):
647 """
648 Private slot to handle the "Delete Completed Tasks" context menu entry.
649 """
650 for task in self.tasks[:]:
651 if task.isCompleted():
652 if self.copyTask == task:
653 self.copyTask = None
654 index = self.indexOfTopLevelItem(task)
655 self.takeTopLevelItem(index)
656 self.tasks.remove(task)
657 del task
658 ci = self.currentItem()
659 if ci:
660 ind = self.indexFromItem(ci, self.currentColumn())
661 self.scrollTo(ind, QAbstractItemView.PositionAtCenter)
662
663 def __copyTask(self):
664 """
665 Private slot to handle the "Copy" context menu entry.
666 """
667 task = self.currentItem()
668 self.copyTask = task
669
670 def __pasteTask(self):
671 """
672 Private slot to handle the "Paste" context menu entry.
673 """
674 if self.copyTask:
675 self.addTask(self.copyTask.description,
676 priority = self.copyTask.priority,
677 completed = self.copyTask.completed,
678 longtext = self.copyTask.longtext,
679 isProjectTask = self.copyTask._isProjectTask)
680
681 def __deleteTask(self):
682 """
683 Private slot to handle the "Delete Task" context menu entry.
684 """
685 task = self.currentItem()
686 if self.copyTask == task:
687 self.copyTask = None
688 index = self.indexOfTopLevelItem(task)
689 self.takeTopLevelItem(index)
690 self.tasks.remove(task)
691 del task
692 ci = self.currentItem()
693 if ci:
694 ind = self.indexFromItem(ci, self.currentColumn())
695 self.scrollTo(ind, QAbstractItemView.PositionAtCenter)
696
697 def __goToTask(self):
698 """
699 Private slot to handle the "Go To" context menu entry.
700 """
701 task = self.currentItem()
702 self.emit(SIGNAL('displayFile'), task.getFilename(), task.getLineno())
703
704 def handlePreferencesChanged(self):
705 """
706 Public slot to react to changes of the preferences.
707 """
708 for task in self.tasks:
709 task.colorizeTask()
710
711 def __activateFilter(self, on):
712 """
713 Private slot to handle the "Filtered display" context menu entry.
714
715 @param on flag indicating the filter state (boolean)
716 """
717 if on and not self.taskFilter.hasActiveFilter():
718 res = QMessageBox.information(None,
719 self.trUtf8("Activate task filter"),
720 self.trUtf8("""The task filter doesn't have any active filters."""
721 """ Do you want to configure the filter settings?"""),
722 QMessageBox.StandardButtons(\
723 QMessageBox.No | \
724 QMessageBox.Yes),
725 QMessageBox.Yes)
726 if res != QMessageBox.Yes:
727 on = False
728 else:
729 self.__configureFilter()
730 on = self.taskFilter.hasActiveFilter()
731
732 self.taskFilter.setActive(on)
733 self.__menuFilteredAct.setChecked(on)
734 self.__backMenuFilteredAct.setChecked(on)
735 self.__refreshDisplay()
736
737 def __configureFilter(self):
738 """
739 Private slot to handle the "Configure filter" context menu entry.
740 """
741 dlg = TaskFilterConfigDialog(self.taskFilter)
742 if dlg.exec_() == QDialog.Accepted:
743 dlg.configureTaskFilter(self.taskFilter)
744 self.__refreshDisplay()
745
746 def __regenerateProjectTasks(self):
747 """
748 Private slot to handle the "Regenerated project tasks" context menu entry.
749 """
750 todoMarkers = Preferences.getTasks("TasksMarkers").split()
751 bugfixMarkers = Preferences.getTasks("TasksMarkersBugfix").split()
752 files = self.project.pdata["SOURCES"]
753
754 # remove all project tasks
755 self.clearProjectTasks()
756
757 # now process them
758 progress = QProgressDialog(self.trUtf8("Extracting project tasks..."),
759 self.trUtf8("Abort"), 0, len(files))
760 progress.setMinimumDuration(0)
761 count = 0
762
763 for file in files:
764 progress.setLabelText(\
765 self.trUtf8("Extracting project tasks...\n{0}").format(file))
766 progress.setValue(count)
767 QApplication.processEvents()
768 if progress.wasCanceled():
769 break
770
771 fn = os.path.join(self.project.ppath, file)
772 # read the file and split it into textlines
773 try:
774 f = open(fn, 'rb')
775 text, encoding = Utilities.decode(f.read())
776 lines = text.splitlines()
777 f.close()
778 except IOError:
779 count += 1
780 self.progress.setValue(count)
781 continue
782
783 # now search tasks and record them
784 lineIndex = 0
785 for line in lines:
786 lineIndex += 1
787 shouldContinue = False
788 # normal tasks first
789 for tasksMarker in todoMarkers:
790 index = line.find(tasksMarker)
791 if index > -1:
792 task = line[index:]
793 self.addFileTask(task, fn, lineIndex, False)
794 shouldContinue = True
795 break
796 if shouldContinue:
797 continue
798
799 # bugfix tasks second
800 for tasksMarker in bugfixMarkers:
801 index = line.find(tasksMarker)
802 if index > -1:
803 task = line[index:]
804 self.addFileTask(task, fn, lineIndex, True)
805 shouldContinue = True
806 break
807
808 count += 1
809
810 progress.setValue(len(files))
811
812 def __configure(self):
813 """
814 Private method to open the configuration dialog.
815 """
816 e4App().getObject("UserInterface").showPreferences("tasksPage")

eric ide

mercurial