~mjz/awn-extras/to-do-two

« back to all changes in this revision

Viewing changes to applets/maintained/to-do/to-do.py

  • Committer: Matt
  • Date: 2010-06-01 02:39:21 UTC
  • Revision ID: sharkbaitbobby@gmail.com-20100601023921-dboizxmmjtcugule
Full read/write, even across multiple applets!
Handle to-do.xml not existing, having errors, etc etc etc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
 
42
42
 
43
43
class App(awn.AppletSimple):
44
 
    #last_num_items = -1
45
 
    #surface = None
46
 
    #last_size = -1
47
44
    progress_buttons = []
48
45
    widgets = {}
49
46
    popup_open = False
63
60
        self.dialog.add_accel_group(self.accel)
64
61
 
65
62
        self.client = awn.config_get_default_for_applet(self)
66
 
        #self.list_id = self.client.get_string(group, 'list_id')
67
 
        self.list_id = '7'
68
63
 
69
64
        self.backend = backends.FileBackend()
70
65
 
71
 
        if self.list_id is None or self.list_id.strip() == '':
 
66
        self.list_id = self.client.get_string(group, 'list_id')
 
67
        if self.list_id is None or self.list_id.strip() == '' or self.list_id not in self.backend:
72
68
            self.list = self.backend.create_list()
73
69
            self.list_id = self.list['id']
 
70
            self.client.set_string(group, 'list_id', self.list_id)
74
71
 
75
72
        else:
76
73
            self.list = self.backend[self.list_id]
77
74
 
 
75
        self.backend.current_id = self.list_id
 
76
 
78
77
        self.set_tooltip_text(self.list['name'])
79
78
 
80
79
        self.icon_theme = gtk.icon_theme_get_default()
117
116
    #The size of Awn has changed
118
117
    def size_changed(self, applet, new_size):
119
118
        self.size = new_size
120
 
        self.last_num_items = -1
121
119
        self.update_icon()
122
120
 
123
121
    #Display a right-click context menu
181
179
    #Hide the dialog
182
180
    def hide_dialog(self, *args, **argv):
183
181
        if self.popup_open and 'force' not in argv:
 
182
            self.popup_open = False
184
183
            return
185
184
 
186
185
        #The dialog is no longer displayed
210
209
        self.clear_dialog()
211
210
 
212
211
        #Make the main table
213
 
        table = gtk.Table(len(self.list), 4)
 
212
        table = gtk.Table(len(self.list) + 1, 4)
214
213
 
215
214
        #Go through the list of to-do items
216
215
        i = 0
232
231
                icon = gtk.image_new_from_pixbuf(self.icon_theme.load_icon('list-remove', 16, 16))
233
232
                remove.add(icon)
234
233
                remove.set_relief(gtk.RELIEF_NONE)
235
 
                remove.item = child
236
 
                remove.connect('clicked', self.remove_item)
 
234
                remove.connect('clicked', self.remove_group, child)
237
235
 
238
236
                expand = gtk.Expander(child['name'])
239
237
                if child['details'].strip() != '':
310
308
        icon.show()
311
309
        remove.add(icon)
312
310
        remove.set_relief(gtk.RELIEF_NONE)
313
 
        remove.item = item
314
 
        remove.connect('clicked', self.remove_item)
 
311
        remove.connect('clicked', self.remove_item, item)
315
312
 
316
313
        #Make an entry widget for the item
317
314
        entry = gtk.Entry()
323
320
            entry.set_size_request(int(self.list['width']), -1)
324
321
        entry.item = item
325
322
        entry.connect('focus-out-event', self.item_updated, item)
326
 
 
327
 
        ##Try to colorize the entry widget based on its priority
328
 
        #try:
329
 
            ##High: Red
330
 
            #if self.settings['priority'][y]==3:
331
 
                #dialog_entry.modify_base(\
332
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse(self.settings['color_high']))
333
 
                #dialog_entry.modify_text(\
334
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse( \
335
 
                  #self.settings['color_high_text']))
336
 
            ##Medium: Yellow
337
 
            #elif self.settings['priority'][y]==2:
338
 
                #dialog_entry.modify_base(\
339
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse(self.settings['color_med']))
340
 
                #dialog_entry.modify_text(\
341
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse( \
342
 
                  #self.settings['color_med_text']))
343
 
            ##Low: Green
344
 
            #elif self.settings['priority'][y]==1:
345
 
                #dialog_entry.modify_base(\
346
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse(self.settings['color_low']))
347
 
                #dialog_entry.modify_text(\
348
 
                  #gtk.STATE_NORMAL, gtk.gdk.color_parse(\
349
 
                  #self.settings['color_low_text']))
350
 
        #except:
351
 
            #pass
 
323
        entry.connect('populate-popup', self.entry_popup)
 
324
 
 
325
        pri = int(item['priority'])
 
326
        if pri != 0:
 
327
            try:
 
328
                bg = self.list['priority_colors'].split(';')[pri * 2 - 2]
 
329
                text = self.list['priority_colors'].split(';')[pri * 2 - 1]
 
330
                entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse('#' + bg))
 
331
                entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse('#' + text))
 
332
 
 
333
            #In case the user messes up the colors
 
334
            except:
 
335
                pass
352
336
 
353
337
        #Make a ProgressButton
354
338
        progress = ProgressButton(self, item)
363
347
    #(or the edit details dialog)
364
348
    def item_updated(self, widget, event, item):
365
349
        item['name'] = widget.get_text()
366
 
        self.list.write()
 
350
        self.backend.write()
367
351
 
368
352
    #An Expander widget was expanded or un-expanded
369
353
    def expanded(self, widget, expanded, group):
377
361
                    w.show()
378
362
 
379
363
            group['expanded'] = '1'
380
 
            self.list.write()
 
364
            self.backend.write()
381
365
 
382
366
        #Hide the category's widgets
383
367
        else:
389
373
                    w.hide()
390
374
 
391
375
            group['expanded'] = '0'
392
 
            self.list.write()
 
376
            self.backend.write()
393
377
 
394
378
    #Display dialog to add an item to the To-Do list
395
379
    def add_item(self, *args):
441
425
        #Entry for the name
442
426
        self.add_entry = gtk.Entry()
443
427
        self.add_entry.connect('key-press-event', self.key_press_event, self.add_item_to_list)
 
428
        self.add_entry.connect('populate-popup', self.entry_popup)
444
429
        hbox.pack_start(self.add_entry, True)
445
430
        if self.list['use_width'] == '1':
446
431
            width = int(self.list['width'])
493
478
                if self.add_group is None:
494
479
                    self.list.add(item)
495
480
 
 
481
                else:
 
482
                    self.add_group.add(item)
 
483
 
496
484
                self.edit_item(item)
497
485
 
498
486
                self.update_icon()
503
491
                self.list.add(group)
504
492
                self.edit_category(None, group)
505
493
 
 
494
            self.backend.write()
 
495
 
506
496
        #The item name is empty; return to the main dialog
507
497
        else:
508
498
            self.make_dialog()
524
514
            if width >= 25 and width <= 500:
525
515
                name_entry.set_size_request(width, -1)
526
516
        name_entry.connect('focus-out-event', self.item_updated, item)
 
517
        name_entry.connect('populate-popup', self.entry_popup)
527
518
 
528
519
        vbox.pack_start(name_entry, False)
529
520
 
569
560
        details_textview = gtk.TextView(details_textbuffer)
570
561
        details_textview.set_wrap_mode(gtk.WRAP_WORD)
571
562
        details_textview.connect('focus-out-event', self.details_focusout, item)
 
563
        details_textview.connect('populate-popup', self.entry_popup)
572
564
        details_scrolled.add_with_viewport(details_textview)
573
565
        details_scrolled.set_size_request(-1, 100)
574
566
        vbox.pack_start(details_scrolled, True, True)
592
584
 
593
585
    #When the SpinButton for progress has lost focus
594
586
    def spin_focusout(self, widget, event, item):
595
 
        item['progress'] = widget.get_value()
 
587
        item['progress'] = int(widget.get_value())
596
588
        self.update_icon()
597
589
 
598
 
        self.list.write()
 
590
        self.backend.write()
599
591
 
600
592
    #When the TextView for details has lost focus
601
593
    def details_focusout(self, widget, event, item):
602
594
        buf = widget.get_buffer()
603
595
        item['details'] = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False)
604
 
        self.list.write()
 
596
        self.backend.write()
605
597
 
606
598
    #Edit the details of a category
607
599
    def edit_category(self, button, group):
611
603
        name_entry = gtk.Entry()
612
604
        name_entry.set_text(group['name'])
613
605
        name_entry.connect('focus-out-event', self.item_updated, group)
 
606
        name_entry.connect('populate-popup', self.entry_popup)
614
607
        vbox.pack_start(name_entry, False)
615
608
 
616
609
        if self.list['use_width'] == '1':
626
619
        details_textview = gtk.TextView(details_textbuffer)
627
620
        details_textview.set_wrap_mode(gtk.WRAP_WORD)
628
621
        details_textview.connect('focus-out-event', self.details_focusout, group)
 
622
        details_textview.connect('populate-popup', self.entry_popup)
629
623
        details_scrolled.add_with_viewport(details_textview)
630
624
        details_scrolled.set_size_request(-1, 100)
631
625
        vbox.pack_start(details_scrolled, True, True)
694
688
        if opacity != self.list['alpha']:
695
689
            self.list['alpha'] = opacity
696
690
            self.update_icon()
697
 
 
698
 
    #Display a confirmation dialog about removing an item/category from the list
699
 
    #(If appropriate)
700
 
    def remove_item(self, itemid):
701
 
        if type(itemid) != int:
702
 
            itemid = itemid.iterator
703
 
 
704
 
        #If the 'item' is a category
705
 
        if self.settings['items'][itemid] == '':
706
 
            #If user wants to be warned
707
 
            if self.settings['confirm_categories'] == True:
708
 
                #Make Label
709
 
                confirm_label = gtk.Label(_("Are you sure you want to remove the category \"%s?\"\nAll of its items will be removed." % \
710
 
                  self.settings['category_name'][itemid]))
711
 
 
712
 
                #Make CheckButton
713
 
                confirm_check = gtk.CheckButton(_("Don't show this again."))
714
 
                confirm_check.key = 'confirm_categories'
715
 
                confirm_check.connect('toggled', self.confirm_check)
716
 
 
717
 
                #Cancel and OK buttons
718
 
                cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL)
719
 
                cancel_button.connect('clicked', self.make_dialog)
720
 
                remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
721
 
                remove_button.iterator = itemid
722
 
                remove_button.connect('clicked', self.remove_item_from_list)
723
 
 
724
 
                #Now put it all together
725
 
                vbox = gtk.VBox()
726
 
                hbbox = gtk.HButtonBox()
727
 
                hbbox.set_layout(gtk.BUTTONBOX_END)
728
 
                hbbox.pack_start(cancel_button, padding=12)
729
 
                hbbox.pack_start(remove_button)
730
 
                vbox.pack_start(confirm_label, False)
731
 
                vbox.pack_start(confirm_check, False)
732
 
                vbox.pack_start(hbbox, False)
733
 
                vbox.show_all()
734
 
                self.clear_dialog()
735
 
                self.add_to_dialog(vbox)
736
 
 
737
 
            #User does not want to be warned
738
 
            else:
739
 
                self.remove_item_from_list(itemid)
740
 
 
741
 
        #deletion-prone item is deletion-prone
 
691
            self.backend.write()
 
692
 
 
693
    #Display a confirmation dialog about removing an item from the list
 
694
    def remove_item(self, button, item):
 
695
        if int(self.list['confirm']) in (1, 3):
 
696
            label = gtk.Label(_("Are you sure you want to remove this item?\nThis action cannot be undone."))
 
697
 
 
698
            check = gtk.CheckButton(_("Don't show this again."))
 
699
            check.connect('toggled', self.confirm_check, backends.Item)
 
700
 
 
701
            cancel = gtk.Button(stock=gtk.STOCK_CANCEL)
 
702
            cancel.connect('clicked', self.make_dialog)
 
703
 
 
704
            remove = gtk.Button(stock=gtk.STOCK_REMOVE)
 
705
            remove.connect('clicked', self.remove_item_from_list, item)
 
706
 
 
707
            #Now put it all together
 
708
            vbox = gtk.VBox(False, 6)
 
709
            vbox.pack_start(label, False)
 
710
            vbox.pack_start(check, False)
 
711
 
 
712
            hbox = gtk.HBox(False, 6)
 
713
            hbox.pack_end(remove, False)
 
714
            hbox.pack_end(cancel, False)
 
715
            vbox.pack_end(hbox, False)
 
716
 
 
717
            vbox.show_all()
 
718
            self.clear_dialog()
 
719
            self.add_to_dialog(vbox)
 
720
 
 
721
        #User does not want to be warned
742
722
        else:
743
 
            #If user wants to be warned
744
 
            if self.settings['confirm_items'] == True:
745
 
                #Make Label
746
 
                confirm_label = gtk.Label(_("Are you sure you want to remove this item?"))
747
 
 
748
 
                #Make CheckButton
749
 
                confirm_check = gtk.CheckButton(_("Don't show this again."))
750
 
                confirm_check.key = 'confirm_items'
751
 
                confirm_check.connect('toggled', self.confirm_check)
752
 
 
753
 
                #Cancel and OK buttons
754
 
                cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL)
755
 
                cancel_button.connect('clicked', self.make_dialog)
756
 
                remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
757
 
                remove_button.iterator = itemid
758
 
                remove_button.connect('clicked', self.remove_item_from_list)
759
 
 
760
 
                #Now put it all together
761
 
                vbox = gtk.VBox()
762
 
                hbbox = gtk.HButtonBox()
763
 
                hbbox.set_layout(gtk.BUTTONBOX_END)
764
 
                hbbox.pack_start(cancel_button, padding=12)
765
 
                hbbox.pack_start(remove_button)
766
 
                vbox.pack_start(confirm_label, False)
767
 
                vbox.pack_start(confirm_check, False)
768
 
                vbox.pack_start(hbbox, False)
769
 
                vbox.show_all()
770
 
                self.clear_dialog()
771
 
                self.add_to_dialog(vbox)
772
 
 
773
 
            #User does not want to be warned
774
 
            else:
775
 
                self.remove_item_from_list(itemid)
 
723
            self.remove_item_from_list(None, item)
776
724
 
777
725
    #Remove an item from the list of items
778
 
    def remove_item_from_list(self, itemid):
779
 
        if type(itemid)!=int:
780
 
            itemid = itemid.iterator
781
 
 
782
 
        #List of items in this category
783
 
        list_of_items = [itemid]
784
 
 
785
 
        #If this is a category and it has items in it,
786
 
        #remove its items first
787
 
        if self.settings['items'][itemid]=='':#Means it's a category
788
 
            #Remove this category's items
789
 
            y = 0
790
 
            for x in self.settings['category']:
791
 
                if x == itemid:
792
 
                    list_of_items.append(y)
793
 
                y+=1
794
 
 
795
 
            #Remove this category from the list of expanded categories
796
 
            if itemid in self.settings['expanded']:
797
 
                tmp_list_expanded = self.settings['expanded']
798
 
                tmp_list_expanded.remove(itemid)
799
 
                self.settings['expanded'] = tmp_list_expanded
800
 
 
801
 
        tmp_list_names = []
802
 
        tmp_list_priority = []
803
 
        tmp_list_progress = []
804
 
        tmp_list_details = []
805
 
        tmp_list_category = []
806
 
        tmp_list_category_name = []
807
 
        tmp_list_expanded = []
808
 
 
809
 
        y = 0
810
 
        for x in self.settings['items']:
811
 
            if y not in list_of_items:
812
 
                tmp_list_names.append(x)
813
 
            y+=1
814
 
 
815
 
        y = 0
816
 
        for x in self.settings['priority']:
817
 
            if y not in list_of_items:
818
 
                tmp_list_priority.append(x)
819
 
            y+=1
820
 
 
821
 
        y = 0
822
 
        for x in self.settings['progress']:
823
 
            if y not in list_of_items:
824
 
                tmp_list_progress.append(x)
825
 
            y+=1
826
 
 
827
 
        y = 0
828
 
        for x in self.settings['details']:
829
 
            if y not in list_of_items:
830
 
                tmp_list_details.append(x)
831
 
            y+=1
832
 
 
833
 
        #Please, for your own sake, do not write code like this next section.
834
 
        i = 0
835
 
        for item_category in self.settings['category']:
836
 
            if i not in list_of_items:
837
 
                if i > list_of_items[-1] and item_category != -1:
838
 
                    if len(list_of_items) == 1:
839
 
                        #Check if the iterated item is in a category lower than or equal to
840
 
                        #the item being removed's category (lower = lower in list, higher #)
841
 
                        if item_category <= self.settings['category'][list_of_items[0]]:
842
 
                            #It is; just append normally
843
 
                            tmp_list_category.append(item_category)
844
 
                        else:
845
 
                            tmp_list_category.append(item_category-1)
846
 
                    else:
847
 
                        tmp_list_category.append(item_category-len(list_of_items))
848
 
                else:
849
 
                    tmp_list_category.append(item_category)
850
 
            i+=1
851
 
 
852
 
        y = 0
853
 
        for x in self.settings['category_name']:
854
 
            if y not in list_of_items:
855
 
                tmp_list_category_name.append(x)
856
 
            y+=1
857
 
 
858
 
        y = 0
859
 
        for cat in self.settings['expanded']:
860
 
            if cat >= self.settings['category'][list_of_items[-1]]:
861
 
                tmp_list_expanded.append(cat-len(list_of_items))
862
 
            else:
863
 
                tmp_list_expanded.append(cat)
864
 
            y += 1
865
 
 
866
 
        self.settings['items'] = tmp_list_names
867
 
        self.settings['priority'] = tmp_list_priority
868
 
        self.settings['progress'] = tmp_list_progress
869
 
        self.settings['details'] = tmp_list_details
870
 
        self.settings['category'] = tmp_list_category
871
 
        self.settings['category_name'] = tmp_list_category_name
872
 
        self.settings['expanded'] = tmp_list_expanded
873
 
 
874
 
        #The icon is automatically changed, but the dialog is not
875
 
        self.make_dialog()
 
726
    def remove_item_from_list(self, button, item):
 
727
        if item.group is not None:
 
728
            item.group.remove(item)
 
729
 
 
730
        else:
 
731
            self.list.remove(item)
 
732
 
 
733
        self.make_dialog()
 
734
        self.backend.write()
 
735
 
 
736
    #Display a confirmation dialog about removing an group from the list
 
737
    def remove_group(self, button, group):
 
738
        if int(self.list['confirm']) in (2, 3):
 
739
            label = gtk.Label(_("Are you sure you want to remove this category?\nAll of its items will be permanently lost."))
 
740
 
 
741
            check = gtk.CheckButton(_("Don't show this again."))
 
742
            check.connect('toggled', self.confirm_check, backends.Group)
 
743
 
 
744
            cancel = gtk.Button(stock=gtk.STOCK_CANCEL)
 
745
            cancel.connect('clicked', self.make_dialog)
 
746
 
 
747
            remove = gtk.Button(stock=gtk.STOCK_REMOVE)
 
748
            remove.connect('clicked', self.remove_group_from_list, group)
 
749
 
 
750
            #Now put it all together
 
751
            vbox = gtk.VBox(False, 6)
 
752
            vbox.pack_start(label, False)
 
753
            vbox.pack_start(check, False)
 
754
 
 
755
            hbox = gtk.HBox(False, 6)
 
756
            hbox.pack_end(remove, False)
 
757
            hbox.pack_end(cancel, False)
 
758
            vbox.pack_end(hbox, False)
 
759
 
 
760
            vbox.show_all()
 
761
            self.clear_dialog()
 
762
            self.add_to_dialog(vbox)
 
763
 
 
764
        #User does not want to be warned
 
765
        else:
 
766
            self.remove_group_from_list(None, group)
 
767
 
 
768
    def remove_group_from_list(self, button, group):
 
769
        for item in group:
 
770
            group.remove(item)
 
771
 
 
772
        self.list.remove(group)
 
773
 
 
774
        self.make_dialog()
 
775
        self.backend.write()
876
776
 
877
777
    #When a CheckButton for "Don't show this again." is toggled
878
 
    def confirm_check(self, button):
879
 
        self.settings[button.key] = not button.get_active()
 
778
    def confirm_check(self, button, _type):
 
779
        previous = int(self.list['confirm'])
 
780
        new = 0
 
781
 
 
782
        if _type == backends.Group:
 
783
            item = (previous & 1 != 0)
 
784
            group = not button.get_active()
 
785
 
 
786
        else:
 
787
            item = not button.get_active()
 
788
            group = (previous & 2 != 0)
 
789
 
 
790
        print 'prev confirm:', previous
 
791
        self.list['confirm'] = item + 2 * group
 
792
        print 'new confirm:', self.list['confirm']
 
793
 
 
794
        self.backend.write()
 
795
 
 
796
    def entry_popup(self, entry, menu):
 
797
        self.popup_open = True
880
798
 
881
799
 
882
800
class ProgressButton(gtk.Button):
934
852
    def scroll(self, widget, event):
935
853
        #Scrolling up
936
854
        if event.direction == gtk.gdk.SCROLL_UP:
937
 
            self.item['progress'] = int(self.item['progress']) +  5
 
855
            self.item['progress'] = int(self.item['progress']) + 5
938
856
            if self.item['progress'] > 100:
939
857
                self.item['progress'] = 100
940
858
 
941
 
            self.applet.list.write()
 
859
            self.applet.backend.write()
942
860
            self.update()
943
861
 
944
862
        #Scrolling down
945
863
        elif event.direction == gtk.gdk.SCROLL_DOWN:
946
 
            self.item['progress'] = int(self.item['progress']) -  5
 
864
            self.item['progress'] = int(self.item['progress']) - 5
947
865
            if self.item['progress'] < 0:
948
866
                self.item['progress'] = 0
949
867
 
950
 
            self.applet.list.write()
 
868
            self.applet.backend.write()
951
869
            self.update()
952
870
 
953
871
    #Why does this not work the way it should???