Tasks/TaskViewer.py

changeset 945
8cd4d08fa9f6
parent 791
9ec2ac20e54e
child 960
64a6e66b4707
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
26 import UI.PixmapCache 26 import UI.PixmapCache
27 27
28 import Preferences 28 import Preferences
29 import Utilities 29 import Utilities
30 30
31
31 class Task(QTreeWidgetItem): 32 class Task(QTreeWidgetItem):
32 """ 33 """
33 Class implementing the task data structure. 34 Class implementing the task data structure.
34 """ 35 """
35 def __init__(self, description, priority = 1, filename = "", lineno = 0, 36 def __init__(self, description, priority=1, filename="", lineno=0,
36 completed = False, _time = 0, isProjectTask = False, 37 completed=False, _time=0, isProjectTask=False,
37 isBugfixTask = False, project = None, longtext = ""): 38 isBugfixTask=False, project=None, longtext=""):
38 """ 39 """
39 Constructor 40 Constructor
40 41
41 @param parent parent widget of the task (QWidget) 42 @param parent parent widget of the task (QWidget)
42 @param description descriptive text of the task (string) 43 @param description descriptive text of the task (string)
52 @param longtext explanatory text of the task (string) 53 @param longtext explanatory text of the task (string)
53 """ 54 """
54 self.description = description 55 self.description = description
55 self.longtext = longtext 56 self.longtext = longtext
56 if priority in [0, 1, 2]: 57 if priority in [0, 1, 2]:
57 self.priority = priority 58 self.priority = priority
58 else: 59 else:
59 self.priority = 1 60 self.priority = 1
60 self.filename = filename 61 self.filename = filename
61 self.lineno = lineno 62 self.lineno = lineno
62 self.completed = completed 63 self.completed = completed
66 self.project = project 67 self.project = project
67 68
68 if isProjectTask: 69 if isProjectTask:
69 self.filename = self.project.getRelativePath(self.filename) 70 self.filename = self.project.getRelativePath(self.filename)
70 71
71 QTreeWidgetItem.__init__(self, ["", "", self.description, self.filename, 72 QTreeWidgetItem.__init__(self, ["", "", self.description, self.filename,
72 (self.lineno and "{0:6d}".format(self.lineno) or "")]) 73 (self.lineno and "{0:6d}".format(self.lineno) or "")])
73 74
74 if self.completed: 75 if self.completed:
75 self.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png")) 76 self.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png"))
76 else: 77 else:
124 Public slot to update the priority. 125 Public slot to update the priority.
125 126
126 @param priority priority of the task (0=high, 1=normal, 2=low) 127 @param priority priority of the task (0=high, 1=normal, 2=low)
127 """ 128 """
128 if priority in [0, 1, 2]: 129 if priority in [0, 1, 2]:
129 self.priority = priority 130 self.priority = priority
130 else: 131 else:
131 self.priority = 1 132 self.priority = 1
132 133
133 if self.priority == 1: 134 if self.priority == 1:
134 self.setIcon(1, UI.PixmapCache.getIcon("empty.png")) 135 self.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
193 194
194 @return flag indicating the project relation status (boolean) 195 @return flag indicating the project relation status (boolean)
195 """ 196 """
196 return self._isProjectTask 197 return self._isProjectTask
197 198
199
198 class TaskFilter(object): 200 class TaskFilter(object):
199 """ 201 """
200 Class implementing a filter for tasks. 202 Class implementing a filter for tasks.
201 """ 203 """
202 def __init__(self): 204 def __init__(self):
222 224
223 def setDescriptionFilter(self, filter): 225 def setDescriptionFilter(self, filter):
224 """ 226 """
225 Public method to set the description filter. 227 Public method to set the description filter.
226 228
227 @param filter a regular expression for the description filter 229 @param filter a regular expression for the description filter
228 to set (string) or None 230 to set (string) or None
229 """ 231 """
230 if not filter: 232 if not filter:
231 self.descriptionFilter = None 233 self.descriptionFilter = None
232 else: 234 else:
234 236
235 def setFileNameFilter(self, filter): 237 def setFileNameFilter(self, filter):
236 """ 238 """
237 Public method to set the filename filter. 239 Public method to set the filename filter.
238 240
239 @param filter a wildcard expression for the filename filter 241 @param filter a wildcard expression for the filename filter
240 to set (string) or None 242 to set (string) or None
241 """ 243 """
242 if not filter: 244 if not filter:
243 self.filenameFilter = None 245 self.filenameFilter = None
244 else: 246 else:
324 not task.priority in self.prioritiesFilter: 326 not task.priority in self.prioritiesFilter:
325 return False 327 return False
326 328
327 return True 329 return True
328 330
331
329 class TaskViewer(QTreeWidget): 332 class TaskViewer(QTreeWidget):
330 """ 333 """
331 Class implementing the task viewer. 334 Class implementing the task viewer.
332 335
333 @signal displayFile(str, int) emitted to go to a file task 336 @signal displayFile(str, int) emitted to go to a file task
345 348
346 self.setRootIsDecorated(False) 349 self.setRootIsDecorated(False)
347 self.setItemsExpandable(False) 350 self.setItemsExpandable(False)
348 self.setSortingEnabled(True) 351 self.setSortingEnabled(True)
349 352
350 self.__headerItem = QTreeWidgetItem(["", "", self.trUtf8("Summary"), 353 self.__headerItem = QTreeWidgetItem(["", "", self.trUtf8("Summary"),
351 self.trUtf8("Filename"), self.trUtf8("Line"), ""]) 354 self.trUtf8("Filename"), self.trUtf8("Line"), ""])
352 self.__headerItem.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png")) 355 self.__headerItem.setIcon(0, UI.PixmapCache.getIcon("taskCompleted.png"))
353 self.__headerItem.setIcon(1, UI.PixmapCache.getIcon("taskPriority.png")) 356 self.__headerItem.setIcon(1, UI.PixmapCache.getIcon("taskPriority.png"))
354 self.setHeaderItem(self.__headerItem) 357 self.setHeaderItem(self.__headerItem)
355 358
382 self.__menu.addAction(self.trUtf8("Delete Completed &Tasks"), 385 self.__menu.addAction(self.trUtf8("Delete Completed &Tasks"),
383 self.__deleteCompleted) 386 self.__deleteCompleted)
384 self.__menu.addSeparator() 387 self.__menu.addSeparator()
385 self.__menu.addAction(self.trUtf8("P&roperties..."), self.__editTaskProperties) 388 self.__menu.addAction(self.trUtf8("P&roperties..."), self.__editTaskProperties)
386 self.__menu.addSeparator() 389 self.__menu.addSeparator()
387 self.__menuFilteredAct = self.__menu.addAction(self.trUtf8("&Filtered display")) 390 self.__menuFilteredAct = self.__menu.addAction(self.trUtf8("&Filtered display"))
388 self.__menuFilteredAct.setCheckable(True) 391 self.__menuFilteredAct.setCheckable(True)
389 self.__menuFilteredAct.setChecked(False) 392 self.__menuFilteredAct.setChecked(False)
390 self.__menuFilteredAct.triggered[bool].connect(self.__activateFilter) 393 self.__menuFilteredAct.triggered[bool].connect(self.__activateFilter)
391 self.__menu.addAction(self.trUtf8("Filter c&onfiguration..."), 394 self.__menu.addAction(self.trUtf8("Filter c&onfiguration..."),
392 self.__configureFilter) 395 self.__configureFilter)
393 self.__menu.addSeparator() 396 self.__menu.addSeparator()
394 self.__menu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns) 397 self.__menu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns)
395 self.__menu.addSeparator() 398 self.__menu.addSeparator()
396 self.__menu.addAction(self.trUtf8("Configure..."), self.__configure) 399 self.__menu.addAction(self.trUtf8("Configure..."), self.__configure)
400 self.__backMenu.addSeparator() 403 self.__backMenu.addSeparator()
401 self.backRegenerateProjectTasksItem = \ 404 self.backRegenerateProjectTasksItem = \
402 self.__backMenu.addAction(self.trUtf8("&Regenerate project tasks"), 405 self.__backMenu.addAction(self.trUtf8("&Regenerate project tasks"),
403 self.__regenerateProjectTasks) 406 self.__regenerateProjectTasks)
404 self.__backMenu.addSeparator() 407 self.__backMenu.addSeparator()
405 self.backPasteItem = self.__backMenu.addAction(self.trUtf8("&Paste"), 408 self.backPasteItem = self.__backMenu.addAction(self.trUtf8("&Paste"),
406 self.__pasteTask) 409 self.__pasteTask)
407 self.__backMenu.addSeparator() 410 self.__backMenu.addSeparator()
408 self.__backMenu.addAction(self.trUtf8("Delete Completed &Tasks"), 411 self.__backMenu.addAction(self.trUtf8("Delete Completed &Tasks"),
409 self.__deleteCompleted) 412 self.__deleteCompleted)
410 self.__backMenu.addSeparator() 413 self.__backMenu.addSeparator()
411 self.__backMenuFilteredAct = \ 414 self.__backMenuFilteredAct = \
412 self.__backMenu.addAction(self.trUtf8("&Filtered display")) 415 self.__backMenu.addAction(self.trUtf8("&Filtered display"))
413 self.__backMenuFilteredAct.setCheckable(True) 416 self.__backMenuFilteredAct.setCheckable(True)
414 self.__backMenuFilteredAct.setChecked(False) 417 self.__backMenuFilteredAct.setChecked(False)
415 self.__backMenuFilteredAct.triggered[bool].connect(self.__activateFilter) 418 self.__backMenuFilteredAct.triggered[bool].connect(self.__activateFilter)
416 self.__backMenu.addAction(self.trUtf8("Filter c&onfiguration..."), 419 self.__backMenu.addAction(self.trUtf8("Filter c&onfiguration..."),
417 self.__configureFilter) 420 self.__configureFilter)
418 self.__backMenu.addSeparator() 421 self.__backMenu.addSeparator()
419 self.__backMenu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns) 422 self.__backMenu.addAction(self.trUtf8("Resi&ze columns"), self.__resizeColumns)
420 self.__backMenu.addSeparator() 423 self.__backMenu.addSeparator()
421 self.__backMenu.addAction(self.trUtf8("Configure..."), self.__configure) 424 self.__backMenu.addAction(self.trUtf8("Configure..."), self.__configure)
456 self.__resort() 459 self.__resort()
457 self.__resizeColumns() 460 self.__resizeColumns()
458 461
459 def __taskItemActivated(self, itm, col): 462 def __taskItemActivated(self, itm, col):
460 """ 463 """
461 Private slot to handle the activation of an item. 464 Private slot to handle the activation of an item.
462 465
463 @param itm reference to the activated item (QTreeWidgetItem) 466 @param itm reference to the activated item (QTreeWidgetItem)
464 @param col column the item was activated in (integer) 467 @param col column the item was activated in (integer)
465 """ 468 """
466 fn = itm.getFilename() 469 fn = itm.getFilename()
501 else: 504 else:
502 self.pasteItem.setEnabled(False) 505 self.pasteItem.setEnabled(False)
503 506
504 self.__menu.popup(coord) 507 self.__menu.popup(coord)
505 508
506 def setProjectOpen(self, o = False): 509 def setProjectOpen(self, o=False):
507 """ 510 """
508 Public slot to set the project status. 511 Public slot to set the project status.
509 512
510 @param o flag indicating the project status 513 @param o flag indicating the project status
511 """ 514 """
512 self.projectOpen = o 515 self.projectOpen = o
513 516
514 def addTask(self, description, priority = 1, filename = "", lineno = 0, 517 def addTask(self, description, priority=1, filename="", lineno=0,
515 completed = False, _time = 0, isProjectTask = False, 518 completed=False, _time=0, isProjectTask=False,
516 isBugfixTask = False, longtext = ""): 519 isBugfixTask=False, longtext=""):
517 """ 520 """
518 Public slot to add a task. 521 Public slot to add a task.
519 522
520 @param description descriptive text of the task (string) 523 @param description descriptive text of the task (string)
521 @param priority priority of the task (0=high, 1=normal, 2=low) 524 @param priority priority of the task (0=high, 1=normal, 2=low)
522 @param filename filename containing the task (string) 525 @param filename filename containing the task (string)
523 @param lineno line number containing the task (integer) 526 @param lineno line number containing the task (integer)
524 @param completed flag indicating completion status (boolean) 527 @param completed flag indicating completion status (boolean)
525 @param _time creation time of the task (float, if 0 use current time) 528 @param _time creation time of the task (float, if 0 use current time)
526 @param isProjectTask flag indicating a task related to the current 529 @param isProjectTask flag indicating a task related to the current
527 project (boolean) 530 project (boolean)
528 @param isBugfixTask flag indicating a bugfix task (boolean) 531 @param isBugfixTask flag indicating a bugfix task (boolean)
529 @param longtext explanatory text of the task (string) 532 @param longtext explanatory text of the task (string)
530 """ 533 """
531 task = Task(description, priority, filename, lineno, completed, 534 task = Task(description, priority, filename, lineno, completed,
532 _time, isProjectTask, isBugfixTask, 535 _time, isProjectTask, isBugfixTask,
533 self.project, longtext) 536 self.project, longtext)
534 self.tasks.append(task) 537 self.tasks.append(task)
535 if self.taskFilter.showTask(task): 538 if self.taskFilter.showTask(task):
536 self.addTopLevelItem(task) 539 self.addTopLevelItem(task)
537 self.__resort() 540 self.__resort()
538 self.__resizeColumns() 541 self.__resizeColumns()
539 542
540 def addFileTask(self, description, filename, lineno, isBugfixTask = False, 543 def addFileTask(self, description, filename, lineno, isBugfixTask=False,
541 longtext = ""): 544 longtext=""):
542 """ 545 """
543 Public slot to add a file related task. 546 Public slot to add a file related task.
544 547
545 @param description descriptive text of the task (string) 548 @param description descriptive text of the task (string)
546 @param filename filename containing the task (string) 549 @param filename filename containing the task (string)
547 @param lineno line number containing the task (integer) 550 @param lineno line number containing the task (integer)
548 @param isBugfixTask flag indicating a bugfix task (boolean) 551 @param isBugfixTask flag indicating a bugfix task (boolean)
549 @param longtext explanatory text of the task (string) 552 @param longtext explanatory text of the task (string)
550 """ 553 """
551 self.addTask(description, filename = filename, lineno = lineno, 554 self.addTask(description, filename=filename, lineno=lineno,
552 isProjectTask = \ 555 isProjectTask=(
553 self.project and self.project.isProjectSource(filename), 556 self.project and self.project.isProjectSource(filename)),
554 isBugfixTask = isBugfixTask, longtext = longtext) 557 isBugfixTask=isBugfixTask, longtext=longtext)
555 558
556 def getProjectTasks(self): 559 def getProjectTasks(self):
557 """ 560 """
558 Public method to retrieve all project related tasks. 561 Public method to retrieve all project related tasks.
559 562
628 Private slot to handle the "New Task" context menu entry. 631 Private slot to handle the "New Task" context menu entry.
629 """ 632 """
630 dlg = TaskPropertiesDialog(None, self, self.projectOpen) 633 dlg = TaskPropertiesDialog(None, self, self.projectOpen)
631 if dlg.exec_() == QDialog.Accepted: 634 if dlg.exec_() == QDialog.Accepted:
632 data = dlg.getData() 635 data = dlg.getData()
633 self.addTask(data[0], data[1], completed = data[2], isProjectTask = data[3], 636 self.addTask(data[0], data[1], completed=data[2], isProjectTask=data[3],
634 longtext = data[4]) 637 longtext=data[4])
635 638
636 def __markCompleted(self): 639 def __markCompleted(self):
637 """ 640 """
638 Private slot to handle the "Mark Completed" context menu entry. 641 Private slot to handle the "Mark Completed" context menu entry.
639 """ 642 """
668 """ 671 """
669 Private slot to handle the "Paste" context menu entry. 672 Private slot to handle the "Paste" context menu entry.
670 """ 673 """
671 if self.copyTask: 674 if self.copyTask:
672 self.addTask(self.copyTask.description, 675 self.addTask(self.copyTask.description,
673 priority = self.copyTask.priority, 676 priority=self.copyTask.priority,
674 completed = self.copyTask.completed, 677 completed=self.copyTask.completed,
675 longtext = self.copyTask.longtext, 678 longtext=self.copyTask.longtext,
676 isProjectTask = self.copyTask._isProjectTask) 679 isProjectTask=self.copyTask._isProjectTask)
677 680
678 def __deleteTask(self): 681 def __deleteTask(self):
679 """ 682 """
680 Private slot to handle the "Delete Task" context menu entry. 683 Private slot to handle the "Delete Task" context menu entry.
681 """ 684 """
714 if on and not self.taskFilter.hasActiveFilter(): 717 if on and not self.taskFilter.hasActiveFilter():
715 res = E5MessageBox.yesNo(self, 718 res = E5MessageBox.yesNo(self,
716 self.trUtf8("Activate task filter"), 719 self.trUtf8("Activate task filter"),
717 self.trUtf8("""The task filter doesn't have any active filters.""" 720 self.trUtf8("""The task filter doesn't have any active filters."""
718 """ Do you want to configure the filter settings?"""), 721 """ Do you want to configure the filter settings?"""),
719 yesDefault = True) 722 yesDefault=True)
720 if not res: 723 if not res:
721 on = False 724 on = False
722 else: 725 else:
723 self.__configureFilter() 726 self.__configureFilter()
724 on = self.taskFilter.hasActiveFilter() 727 on = self.taskFilter.hasActiveFilter()
747 750
748 # remove all project tasks 751 # remove all project tasks
749 self.clearProjectTasks() 752 self.clearProjectTasks()
750 753
751 # now process them 754 # now process them
752 progress = QProgressDialog(self.trUtf8("Extracting project tasks..."), 755 progress = QProgressDialog(self.trUtf8("Extracting project tasks..."),
753 self.trUtf8("Abort"), 0, len(files)) 756 self.trUtf8("Abort"), 0, len(files))
754 progress.setMinimumDuration(0) 757 progress.setMinimumDuration(0)
755 count = 0 758 count = 0
756 759
757 for file in files: 760 for file in files:

eric ide

mercurial