1 from action import Action
4 from datetime import date
6 from observable import *
7 from filtered_list import FilteredList,StatusFilteredList
9 from log.logging import logger
12 class ProjectStatus(Status):
15 # def __eq__(self,other):
17 class Inactive(ProjectStatus):
19 super(Inactive,self).__init__(u'review',4,'!')
21 def update(self,project):
22 # if project.has_active_actions():
29 class Active(ProjectStatus):
32 super(Active,self).__init__(u'active',1)
34 def update(self,project):
35 if not project.has_active_actions():
41 class Tickled(ProjectStatus):
42 def __init__(self,date=date.tomorrow()):
43 super(Tickled,self).__init__(u'tickled',3,'/')
46 def update(self,project):
47 if self.date <= date.now():
53 return super(Tickled,self).__str__()+" for %s"%self.date
58 unprocessed = ProjectStatus(u'unprocessed',0)
60 done = ProjectStatus(u'done',2,'+')
63 someday = ProjectStatus(u'someday',5,'~')
64 info = ProjectStatus(u'info',0)
68 class Project(ObservableItem,ItemWithStatus):
69 """Projects in the GTD terminology are things that need more than one
71 In MobileGTD a project consists of a name, a set of actions and a set of infos.
72 A Project also has a state. This can be one of the following:
73 - unprocessed: New, has not yet been processed in any way by MobileGTD
74 - active: It is planned to work on the project before the next Review cycle
75 - done: The project has been finished
76 - tickled: The project has been postponed to a certain date
77 - inactive: The project has been paused
80 def __init__(self,name,status = inactive):
81 assert type(name) == unicode
82 logger.log(u'Creating project %s (%s)'%(name,status))
83 ItemWithStatus.__init__(self,status)
85 self.actions=StatusFilteredList([])
86 self.infos=FilteredList([])
87 self.update_methods = {'status':self.action_changed_status,
88 'description':self.action_changed_content,
89 'info':self.action_changed_content,
90 'context':self.action_changed_content,
91 'text':self.info_changed}
92 super(Project,self).__init__()
93 for o in Project.observers:
94 o.notify(self.__class__,'new_project',self,None)
95 logger.log(u'Now, its project %s (%s)'%(name,status))
98 def add_action(self,a):
100 a.observers.append(self)
101 self.actions.append(a)
102 self.notify_observers('add_action',a)
103 if a.status == action.unprocessed:
104 a.status = action.active
106 def remove_action(self,a):
107 a.status = action.done
108 a.observers.remove(self)
109 self.actions.remove(a)
110 self.notify_observers('remove_action',a)
112 def add_info(self,info,position=None):
113 info.observers.append(self)
114 self.infos.append(info)
115 self.notify_observers('add_info', info)
117 def remove_info(self,info):
118 info.observers.remove(self)
119 self.infos.remove(info)
120 self.notify_observers('remove_info', info)
124 for a in self.actions_with_status(action.inactive):
125 a.status = action.active
127 def deactivate(self):
128 self.status = inactive
129 for a in self.actions_with_status(action.active):
130 a.status = action.inactive
132 def actions_with_status(self,status):
133 return self.actions.with_property(lambda a:a.status == status)
135 def active_actions(self):
136 return self.actions_with_status(action.active)
138 def has_active_actions(self):
139 return len(self.active_actions()) > 0
141 def notify(self,action,attribute,new=None,old=None):
142 self.update_methods[attribute](action,new)
144 def info_changed(self,info,text):
145 self.notify_observers('changed_info', info)
147 def action_changed_content(self,action,content):
148 self.notify_observers('changed_action',action)
150 def action_changed_status(self,a,status):
151 self.notify_observers('changed_action', new=a, old=None)
153 def last_modification_date(self):
154 return datetime.date.now()
156 def __eq__(self, other):
157 return self.name == other.name and self.status == other.status
159 def __ne__(self,project):
160 return not self.__eq__(project)
165 def status_symbol_and_name(self):
166 return self.status_symbol()+self.name
168 return u'Project %s (@%s, %s actions, %s infos)'%("Moeject",self.status.name.capitalize(),len(self.actions),len(self.infos))