Browse Source

Implemented remaining bulk operations

annotate, denotate, toggle-complete, delete
Michał Góral 4 months ago
parent
commit
91c7d60ae0
2 changed files with 70 additions and 57 deletions
  1. 52
    44
      src/twc/widgets/agenda.py
  2. 18
    13
      src/twc/widgets/completions.py

+ 52
- 44
src/twc/widgets/agenda.py View File

@@ -451,11 +451,12 @@ class AgendaView:
451 451
 
452 452
     @property
453 453
     def selected_tasks(self):
454
-        if not self._selected:
455
-            return self.current_task
456
-
457
-        positions = sorted(pos for pos in self._selected)
458
-        return [self._cache[pos].task for pos in positions]
454
+        if self._selected:
455
+            positions = sorted(pos for pos in self._selected)
456
+            return [self._cache[pos].task for pos in positions]
457
+        if self.is_task(self.pos):
458
+            return [self._cache[self.pos].task]
459
+        return []
459 460
 
460 461
     @property
461 462
     def current_agenda(self):
@@ -489,10 +490,13 @@ class AgendaView:
489 490
         return None
490 491
 
491 492
     @property
492
-    def _selected_cache(self):
493
-        if not self._selected:
494
-            return [self._current_cache]
495
-
493
+    def _selected_caches(self):
494
+        if self._selected:
495
+            positions = sorted(pos for pos in self._selected)
496
+            return [self._cache[pos] for pos in positions]
497
+        if self.pos >= 0:
498
+            return [self._cache[self.pos]]
499
+        return []
496 500
 
497 501
     async def _add(self, controller):
498 502
         controller.commandline.command = 'add'
@@ -520,20 +524,19 @@ class AgendaView:
520 524
 
521 525
         with controller.focused(controller.commandline):
522 526
             args = await controller.commandline.read_command(
523
-                compl=task_modify(task, self.tw))
527
+                compl=task_modify(tasks, self.tw))
524 528
 
525 529
         if not args:
526 530
             return
527 531
 
528
-        result = twutils.execute_command(self.tw, 'modify', args, flt=task)
532
+        result = twutils.execute_command(self.tw, 'modify', args, flt=tasks)
529 533
         if not result.report_failure():
530 534
             self.refresh()
531 535
 
532 536
     async def _annotate(self, controller):
533
-        task_cache = self._current_cache
534
-        if not task_cache or not task_cache.task:
537
+        caches = self._selected_caches
538
+        if not caches:
535 539
             return
536
-        task = task_cache.task
537 540
 
538 541
         controller.commandline.command = 'annotate'
539 542
         controller.commandline.set_help(tr('New annotation'))
@@ -544,22 +547,24 @@ class AgendaView:
544 547
         if not annotation:
545 548
             return
546 549
 
547
-        task.t.add_annotation(annotation)
548
-        task_cache.invalidate()
550
+        for cache in caches:
551
+            cache.task.t.add_annotation(annotation)
552
+            cache.invalidate()
549 553
 
550 554
     async def _denotate(self, controller):
551
-        task_cache = self._current_cache
552
-        if not task_cache or not task_cache.task:
555
+        caches = self._selected_caches
556
+        if not caches:
553 557
             return
554
-        task = task_cache.task
555 558
 
556
-        if not task.t['annotations']:
559
+        tasks = _to_tasks(caches)
560
+        task_annotations = annotations(tasks)
561
+
562
+        if not task_annotations:
557 563
             return
558 564
 
559 565
         controller.commandline.command = 'denotate'
560 566
         controller.commandline.set_help(tr('Text of existing annotation'))
561 567
 
562
-        task_annotations = annotations(task)
563 568
         with controller.focused(controller.commandline):
564 569
             annotation = await controller.commandline.read_command(
565 570
                 compl=task_annotations)
@@ -567,41 +572,40 @@ class AgendaView:
567 572
         if not annotation:
568 573
             return
569 574
 
570
-        if annotation not in task_annotations:
571
-            eprint(tr('Task not annotated with "{}"').format(annotation))
572
-            return
573
-
574
-        task.t.remove_annotation(annotation)
575
-        task_cache.invalidate()
575
+        for cache in caches:
576
+            if annotation in annotations(cache.task):
577
+                cache.task.t.remove_annotation(annotation)
578
+                cache.invalidate()
576 579
 
577 580
     def _edit(self, tasks):
578 581
         twutils.edit_tasks(tasks)
579 582
         self.refresh()
580 583
 
581 584
     def _toggle_complete(self, controller):
582
-        task_cache = self._current_cache
583
-        if not task_cache or not task_cache.task:
585
+        caches = self._selected_caches
586
+        if not caches:
584 587
             return
585
-        task = task_cache.task
586 588
 
587
-        if task.t.completed or task.t.deleted:
588
-            twutils.execute_command(
589
-                self.tw, 'modify', 'status:pending', flt=task)
590
-            task.t.refresh()
591
-        else:
592
-            task.t.done()
593
-            task.t.save()
594
-        task_cache.invalidate()
589
+        for cache in caches:
590
+            task = cache.task
591
+            if task.t.completed or task.t.deleted:
592
+                twutils.execute_command(
593
+                    self.tw, 'modify', 'status:pending', flt=task)
594
+                task.t.refresh()
595
+            else:
596
+                task.t.done()
597
+                task.t.save()
598
+            cache.invalidate()
595 599
 
596 600
     def _delete(self, controller):
597
-        task_cache = self._current_cache
598
-        if not task_cache or not task_cache.task:
601
+        caches = self._selected_caches
602
+        if not caches:
599 603
             return
600
-        task = task_cache.task
601 604
 
602
-        task.t.delete()
603
-        task.t.save()
604
-        task_cache.invalidate()
605
+        for cache in caches:
606
+            cache.task.t.delete()
607
+            cache.task.t.save()
608
+            cache.invalidate()
605 609
 
606 610
     async def _sync(self, controller):
607 611
         pprint(tr('Tasks synchronizing...'))
@@ -760,3 +764,7 @@ class AgendaView:
760 764
 
761 765
     def __pt_container__(self):
762 766
         return self.window
767
+
768
+
769
+def _to_tasks(caches):
770
+    return list(cache.task for cache in caches)

+ 18
- 13
src/twc/widgets/completions.py View File

@@ -15,6 +15,8 @@
15 15
 # You should have received a copy of the GNU General Public License
16 16
 # along with TWC. If not, see <http://www.gnu.org/licenses/>.
17 17
 
18
+import itertools
19
+
18 20
 from twc.twutils import execute_command
19 21
 
20 22
 
@@ -55,8 +57,13 @@ def tags(tw):
55 57
     return completions
56 58
 
57 59
 
58
-def annotations(task):
59
-    return set(ann['description'] for ann in task.t['annotations'])
60
+def annotations(tasks):
61
+    if not isinstance(tasks, list):
62
+        tasks = [tasks]
63
+
64
+    get_annotations = (task.t['annotations'] for task in tasks)
65
+    return set(ann['description']
66
+               for ann in itertools.chain.from_iterable(get_annotations))
60 67
 
61 68
 
62 69
 def task_add(tw):
@@ -67,19 +74,17 @@ def task_add(tw):
67 74
     return completions
68 75
 
69 76
 
70
-def task_modify(task, tw):
77
+def task_modify(tasks, tw):
78
+    if not isinstance(tasks, list):
79
+        tasks = [tasks]
80
+
71 81
     completions = keywords()
72 82
     completions.extend(udas(tw))
73 83
 
74
-    # tags
75
-    missing_tags = set()
76
-    for comma_sep_tags in execute_command(tw, '_unique', 'tags').verified_out():
77
-        taglist = comma_sep_tags.split(',')
78
-        for tag in taglist:
79
-            if tag not in task.t['tags']:
80
-                missing_tags.add('+{}'.format(tag))
81
-    completions.extend(missing_tags)
82
-    completions.extend('-{}'.format(tag) for tag in task.t['tags'])
83
-    completions.append(task.t['description'])
84
+    get_tags = (task.t['tags'] for task in tasks)
85
+    all_tasks_tags = set(itertools.chain.from_iterable(get_tags))
86
+
87
+    completions.extend('-{}'.format(tag) for tag in all_tasks_tags)
88
+    completions.extend(task.t['description'] for task in tasks)
84 89
     completions.sort()
85 90
     return completions

Loading…
Cancel
Save