comparison Gtk/gui.py @ 11:fe9c55f86698

Improvements in navigation buttons
author Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>
date Wed, 24 Nov 2010 22:56:02 +0100
parents d2cbc0278b30
children 60bc5117926c
comparison
equal deleted inserted replaced
10:d2cbc0278b30 11:fe9c55f86698
72 if globalVars.desktop["autodetect"]: 72 if globalVars.desktop["autodetect"]:
73 openwith.autodetect_desktop() 73 openwith.autodetect_desktop()
74 print utils.mapping(_("pyArq-Presupuestos running on $1"), 74 print utils.mapping(_("pyArq-Presupuestos running on $1"),
75 (globalVars.desktop["desktop"],)) 75 (globalVars.desktop["desktop"],))
76 76
77 # Add MenutoolButton to Uimanager
78 class MenuToolAction(gtk.Action):
79 __gtype_name__ = "MenuToolAction"
80
81 gobject.type_register(MenuToolAction)
82 MenuToolAction.set_tool_item_type(gtk.MenuToolButton)
83
77 84
78 class MainWindow(object): 85 class MainWindow(object):
79 """gui.MainWindow: 86 """gui.MainWindow:
80 87
81 Description: 88 Description:
85 gui.MainWindow() 92 gui.MainWindow()
86 Ancestry: 93 Ancestry:
87 +-- object 94 +-- object
88 +-- MainWindow 95 +-- MainWindow
89 Atributes: 96 Atributes:
90 notebook: Read. notebook widget
91 pageList: Read. page list
92 budgetList: Read. budget list
93 Methods: 97 Methods:
94 removePage 98 changeHistorySignal
99 changeActiveSignal
100 appendEmptyPage
101 updatePage
102 closePage
95 """ 103 """
96 # TODO:* Can choose open budget in new window 104 # TODO:* Can choose open budget in new window
97 # TODO:* gtk.Action for menu and toolbar
98 # TODO:* Can choose show more than one notebook in the same window or 105 # TODO:* Can choose show more than one notebook in the same window or
99 # TODO: can show basedata notebook in a side pane 106 # TODO: can show basedata notebook in a side pane
100 __ui = '''<ui> 107 __ui = '''<ui>
101 <menubar name="MenuBar"> 108 <menubar name="MenuBar">
102 <menu action="File"> 109 <menu action="File">
104 <menuitem action="Close"/> 111 <menuitem action="Close"/>
105 </menu> 112 </menu>
106 <menu action="View"> 113 <menu action="View">
107 </menu> 114 </menu>
108 <menu action="Go"> 115 <menu action="Go">
109 <menuitem action="GoUp"/>
110 <menuitem action="GoDown"/>
111 <menuitem action="GoPrevious"/> 116 <menuitem action="GoPrevious"/>
112 <menuitem action="GoPosterior"/> 117 <menuitem action="GoPosterior"/>
118 <menuitem action="GoUp"/>
113 <menuitem action="GoToRoot"/> 119 <menuitem action="GoToRoot"/>
114 </menu> 120 </menu>
115 <menu action="Test"> 121 <menu action="Test">
116 <menuitem action="ImportFiebdcPriceDatabase"/> 122 <menuitem action="ImportFiebdcPriceDatabase"/>
117 <menuitem action="OpenPriceDatabase"/> 123 <menuitem action="OpenPriceDatabase"/>
119 </menubar> 125 </menubar>
120 <toolbar name="ToolBar"> 126 <toolbar name="ToolBar">
121 <toolitem action="ImportFiebdc"/> 127 <toolitem action="ImportFiebdc"/>
122 <toolitem action="Close"/> 128 <toolitem action="Close"/>
123 <separator name="sep1"/> 129 <separator name="sep1"/>
130 <toolitem action="GoPrevMenu"/>
131 <toolitem action="GoPostMenu"/>
124 <toolitem action="GoUp"/> 132 <toolitem action="GoUp"/>
125 <toolitem action="GoDown"/>
126 <toolitem action="GoPrevious"/>
127 <toolitem action="GoPosterior"/>
128 <toolitem action="GoToRoot"/> 133 <toolitem action="GoToRoot"/>
129 </toolbar> 134 </toolbar>
130 </ui>''' 135 </ui>'''
131 136
132 def __init__(self): 137 def __init__(self):
133 """__init__() 138 """__init__()
134 139
135 Initialize the atributes "__budget_list" and "__page_list" without data. 140 Initialize the atributes self.__page_list without data.
136 Creates the widgets "window" and "__notebook". 141 Creates the widgets "window" and "__notebook".
137 142
138 self.__window: gtk.Window object 143 self.__window: gtk.Window object
139 self.__budget_temp_list: Temporal list of budgets 144 self.__uimanager: gtk.UIManager object
140 self.__budget_list: List of budgets ("base.Budget" objects)
141 self.__page_list: List of pages ("Page" object) 145 self.__page_list: List of pages ("Page" object)
142 self.__notebook: Notebook widget ("gtk.Notebook" object) 146 self.__notebook: Notebook widget ("gtk.Notebook" object)
143 self.__general_action_group: "General" action group 147 self.__general_action_group: "General" action group
144 """ 148 self.__navigation_action_group: "Navigation" action group
145 #TODO: action group for Navigation buttons 149 """
146 self.__budget_temp_list = []
147 self.__budget_list = []
148 self.__page_list = [] 150 self.__page_list = []
149 # Main window 151 # Main window
150 self.__window = gtk.Window(gtk.WINDOW_TOPLEVEL) 152 self.__window = gtk.Window(gtk.WINDOW_TOPLEVEL)
151 self.__window.set_default_size(771, 570) 153 self.__window.set_default_size(771, 570)
152 self.__window.set_title("Presupuestos") 154 self.__window.set_title("Presupuestos")
156 # Vertical box 158 # Vertical box
157 _vbox1 = gtk.VBox(False, 0) 159 _vbox1 = gtk.VBox(False, 0)
158 self.__window.add(_vbox1) 160 self.__window.add(_vbox1)
159 _vbox1.show() 161 _vbox1.show()
160 #Uimanager 162 #Uimanager
161 _uimanager = gtk.UIManager() 163 self.__uimanager = gtk.UIManager()
162 _accelgroup = _uimanager.get_accel_group() 164 _accelgroup = self.__uimanager.get_accel_group()
163 self.__window.add_accel_group(_accelgroup) 165 self.__window.add_accel_group(_accelgroup)
164 _general_action_group = gtk.ActionGroup("General") 166 self.__general_action_group = gtk.ActionGroup("General")
165 self.__general_action_group = _general_action_group 167 self.__general_action_group.add_actions(
166 _general_action_group.add_actions(
167 [("File", None, _("_File"), None), 168 [("File", None, _("_File"), None),
168 ("ImportFiebdc", gtk.STOCK_OPEN, _('_Import Fiebdc'), "", 169 ("ImportFiebdc", gtk.STOCK_OPEN, _('_Import Fiebdc'), "",
169 _('Import FIEBDC'), self._menuitemImportFiebdc), 170 _('Import FIEBDC'), self._menuitemImportFiebdc),
170 ("Close", gtk.STOCK_CLOSE, _("_Close"), None, _('Close'), 171 ("Close", gtk.STOCK_CLOSE, _("_Close"), None, _('Close'),
171 self._menuitemClose), 172 self._menuitemClose),
172 ("View", None, _("_View")), 173 ("View", None, _("_View")),
173 ("Go", None, _("_Go")), 174 ("Go", None, _("_Go")),
174 ("GoUp", gtk.STOCK_GO_UP, _("_Up Record"),"",
175 _("Go up record"), self._menuitemGoUp),
176 ("GoDown", gtk.STOCK_GO_DOWN, _("_Down Record"),"",
177 _("Go down record"), self._menuitemGoDown),
178 ("GoPrevious", gtk.STOCK_GO_BACK, _("_Previous Record"),"",
179 _("Go Previous record"), self._menuitemGoPrevious),
180 ("GoPosterior", gtk.STOCK_GO_FORWARD, _("_Posterior Record"),"",
181 _("Go posterior record"), self._menuitemGoPosterior),
182 ("GoToRoot", gtk.STOCK_GOTO_TOP, _("_Root"),"",
183 _("Go to root"), self._menuitemGoToRoot),
184 ("Test", None, _("_Test")), 175 ("Test", None, _("_Test")),
185 ('ImportFiebdcPriceDatabase', gtk.STOCK_OPEN, 176 ('ImportFiebdcPriceDatabase', gtk.STOCK_OPEN,
186 _("Import Fiebdc _price database"), "", _("Import database"), 177 _("Import Fiebdc _price database"), "", _("Import database"),
187 self._menuitemImportPriceDatabase ), 178 self._menuitemImportPriceDatabase ),
188 ("OpenPriceDatabase", gtk.STOCK_OPEN, _('_Open price database'), 179 ("OpenPriceDatabase", gtk.STOCK_OPEN, _('_Open price database'),
189 "", _('Open Database'), self._menuitemOpenPriceDatabase), 180 "", _('Open Database'), self._menuitemOpenPriceDatabase),
190 ]) 181 ])
191 _uimanager.insert_action_group(_general_action_group, 0) 182 self.__navigation_action_group = gtk.ActionGroup("Navigation")
192 _uimanager.add_ui_from_string(self.__ui) 183 self.__navigation_action_group.add_actions(
193 _menu_bar = _uimanager.get_widget("/MenuBar") 184 [("Go", None, _("_Go")),
185 ("GoPrevious", gtk.STOCK_GO_BACK, _("_Back"),"",
186 _("Go to the previous visited item"),
187 self._menuitemGoPrevious),
188 ("GoPosterior", gtk.STOCK_GO_FORWARD, _("_Forward"),"",
189 _("Go to the next visited item"), self._menuitemGoPosterior),
190 ("GoUp", gtk.STOCK_GO_UP, _("_Up Item"),"",
191 _("Go up item"), self._menuitemGoUp),
192 ("GoToRoot", gtk.STOCK_GOTO_TOP, _("_Root"),"",
193 _("Go to root"), self._menuitemGoToRoot),
194 ])
195 self.__navigation_action_group.add_action(
196 MenuToolAction("GoPrevMenu", None ,
197 _("Go to the previous visited item"),
198 gtk.STOCK_GO_BACK))
199 self.__navigation_action_group.add_action(
200 MenuToolAction("GoPostMenu", None ,
201 _("Go to the next visited item"),
202 gtk.STOCK_GO_FORWARD))
203 self.__navigation_action_group.set_sensitive(False)
204 self.__navigation_action_group.get_action("GoPostMenu").set_sensitive(
205 False)
206 self.__navigation_action_group.get_action("GoPrevMenu").set_sensitive(
207 False)
208 self.__uimanager.insert_action_group(self.__general_action_group, 0)
209 self.__uimanager.insert_action_group(self.__navigation_action_group, 1)
210 self.__uimanager.add_ui_from_string(self.__ui)
211 _menu_bar = self.__uimanager.get_widget("/MenuBar")
194 _vbox1.pack_start(_menu_bar, False, False, 0) 212 _vbox1.pack_start(_menu_bar, False, False, 0)
195 _toolbar = _uimanager.get_widget("/ToolBar") 213 _toolbar = self.__uimanager.get_widget("/ToolBar")
196 _toolbar.get_settings().set_long_property("gtk-toolbar-icon-size", 214 _toolbar.get_settings().set_long_property("gtk-toolbar-icon-size",
197 gtk.ICON_SIZE_SMALL_TOOLBAR, "pyArq-Presupuestos:toolbar") 215 gtk.ICON_SIZE_SMALL_TOOLBAR, "pyArq-Presupuestos:toolbar")
198 _vbox1.pack_start(_toolbar, False, False, 0) 216 _vbox1.pack_start(_toolbar, False, False, 0)
217 # menuToolButton go prev
218 _go_prev_button = self.__uimanager.get_widget(
219 "/ToolBar/GoPrevMenu")
220 _go_prev_button.set_arrow_tooltip_text(_("Back history"))
221 _go_prev_button.connect('clicked', self._menuitemGoPrevious)
222 # menuToolButton go pos
223 _go_post_button = self.__uimanager.get_widget(
224 "/ToolBar/GoPostMenu")
225 _go_post_button.set_arrow_tooltip_text(_("Forward history"))
226 _go_post_button.connect('clicked', self._menuitemGoPosterior)
199 # Notebook 227 # Notebook
200 self.__notebook = gtk.Notebook() 228 self.__notebook = gtk.Notebook()
201 _vbox1.pack_start(self.__notebook, True, True, 0) 229 _vbox1.pack_start(self.__notebook, True, True, 0)
202 self.__notebook.set_tab_pos(gtk.POS_TOP) 230 self.__notebook.set_tab_pos(gtk.POS_TOP)
203 self.__notebook.set_show_tabs(True) 231 self.__notebook.set_show_tabs(True)
204 self.__notebook.set_show_border(True) 232 self.__notebook.set_show_border(True)
205 self.__notebook.set_scrollable(True) 233 self.__notebook.set_scrollable(True)
234 self.__notebook.connect("switch-page", self._switch_page)
206 self.__notebook.show() 235 self.__notebook.show()
207 self._main() 236 self._main()
237 #TODO: create budget object in mainwindow?
238
239 def changeHistorySignal(self):
240 """changeHistorySignal()
241
242 A pane emit the updateHistory signal.
243
244 Nothing to do now
245 """
246 pass
247
248 def changeActiveSignal(self):
249 """changeActiveSignal()
250
251 A pane emit the change-active signal.
252
253 Chech buttons sensitive
254 """
255 self._checkButtonsSensitive(self.__notebook.get_current_page())
256
257 def _checkButtonsSensitive(self, page_num):
258 """_checkButtonsSensitive(page_num)
259
260 page_num: page number in notebook
261
262 Check and if necessary update the sensitive state of the navigation
263 buttons.
264 """
265 _page = self.__page_list[page_num]
266 if isinstance(_page, Page) and \
267 self.__navigation_action_group.get_sensitive():
268 # GoToRoot and GoUp actions
269 _goto_root = self.__navigation_action_group.get_action("GoToRoot")
270 _go_up = self.__navigation_action_group.get_action("GoUp")
271 if len(_page.activePathRecord) == 1 and \
272 _goto_root.get_sensitive():
273 _goto_root.set_sensitive(False)
274 _go_up.set_sensitive(False)
275 elif len(_page.activePathRecord) != 1 and \
276 not _goto_root.get_sensitive():
277 _goto_root.set_sensitive(True)
278 _go_up.set_sensitive(True)
279 # GoPrevMenu action
280 _go_Previous = self.__navigation_action_group.get_action(
281 "GoPrevious")
282 _go_prev = self.__navigation_action_group.get_action("GoPrevMenu")
283 if _page.previousPathRecord is None:
284 if _go_prev.get_sensitive():
285 _go_prev.set_sensitive(False)
286 _go_Previous .set_sensitive(False)
287 else:
288 if not _go_prev.get_sensitive():
289 _go_prev.set_sensitive(True)
290 _go_Previous.set_sensitive(True)
291 # GoPostMenu action
292 _go_Posterior = self.__navigation_action_group.get_action(
293 "GoPosterior")
294 _go_post = self.__navigation_action_group.get_action("GoPostMenu")
295 if _page.posteriorPathRecord is None:
296 if _go_post.get_sensitive():
297 _go_post.set_sensitive(False)
298 _go_Posterior.set_sensitive(False)
299 else:
300 if not _go_post.get_sensitive():
301 _go_post.set_sensitive(True)
302 _go_Posterior.set_sensitive(True)
303
304 def _switch_page(self, notebook, page, page_num,):
305 """_switch_page(notebook, page, page_num)
306
307 Method connected to the "switch-page" signal of the notebook widget
308
309 It changes the sensitive state of the navigation action group
310 """
311 _page = self.__page_list[page_num]
312 if isinstance(_page, EmptyPage) and \
313 self.__navigation_action_group.get_sensitive():
314 self.__navigation_action_group.set_sensitive(False)
315 elif isinstance(_page, Page):
316 if not self.__navigation_action_group.get_sensitive():
317 self.__navigation_action_group.set_sensitive(True)
318 self._checkButtonsSensitive(page_num)
319 _go_prev = self.__uimanager.get_widget("/ToolBar/GoPrevMenu")
320 _go_prev.set_menu(_page.back_menu)
321 _go_post = self.__uimanager.get_widget("/ToolBar/GoPostMenu")
322 _go_post.set_menu(_page.forward_menu)
208 323
209 def _main(self): 324 def _main(self):
210 """main() 325 """main()
211 326
212 Shows window and starts the GTK+ event processing loop. 327 Shows window and starts the GTK+ event processing loop.
213 """ 328 """
214 self.__window.show() 329 self.__window.show()
215 gtk.main() 330 gtk.main()
216 331
217 def _addBudget(self, budget): 332 def appendEmptyPage(self, emptyPage):
218 """_addBudget(budget) 333 """appendEmptyPage(widget, label)
219 334
220 budget: "base.Budget" object 335 Append a empty page to the notebook.
221 336 """
222 Appends a budget in the "__budget_list" 337 self.__page_list.append(emptyPage)
223 """ 338 self.__notebook.append_page(emptyPage.widget, emptyPage.title)
224 if not budget is None: 339 # TODO: reordenable and detachable Pages
225 _budget = budget 340 #self.__notebook.set_tab_reorderable(emptyPage.widget, True)
226 if _budget in self.__budget_temp_list: 341 #self.__notebook.set_tab_detachable(emptyPage.widget, True)
227 self.__budget_temp_list.remove(_budget) 342
228 self.__budget_list.append(_budget) 343 def updatePage(self, empty_page, page):
229 344 """updatePage(page)
230 def _appendPage(self): 345
231 """_appendPage() 346 Update emptyPage to Page.
232 347 """
233 Creates a new page (instance of "Page class") from the last budget in 348 _page_num = self.__notebook.page_num(empty_page.widget)
234 __budget_list, appends this page in the "__page_list" and shows the 349 self.__page_list[_page_num] = page
235 page widget in the notebook widget. 350 if self.__notebook.get_current_page() == _page_num:
236 """ 351 _go_prev = self.__uimanager.get_widget("/ToolBar/GoPrevMenu")
237 _last_budget = self.__budget_list[-1] 352 _go_prev.set_menu(page.back_menu)
238 _page = Page(self, _last_budget) 353 _go_post = self.__uimanager.get_widget("/ToolBar/GoPostMenu")
239 self.__notebook.append_page(_page.widget, _page.title) 354 _go_post.set_menu(page.forward_menu)
240 self.__page_list.append(_page) 355 if not self.__navigation_action_group.get_sensitive():
241 356 self.__navigation_action_group.set_sensitive(True)
357 self._checkButtonsSensitive(_page_num)
242 358
243 def _menuitemImportFiebdc(self, widget): 359 def _menuitemImportFiebdc(self, widget):
244 """_menuitemImportFiebdc(widget) 360 """_menuitemImportFiebdc(widget)
245 361
246 widget: the widget where the event is emitted from 362 widget: the widget where the event is emitted from
247 Callback to open a budget file. 363 Callback to open a budget file.
248 364
249 Creates and shows a file selection window to open a budget file. 365 Creates and shows a file selection window to open a budget file.
250 """ 366 """
251 _budget = base.Budget() 367 _budget = base.Budget()
252 self.__budget_temp_list.append(_budget)
253 _budget_file = fiebdc.Read() 368 _budget_file = fiebdc.Read()
254 _read_method = _budget_file.readFile 369 _read_method = _budget_file.readFile
255 _filename = "file" 370 _filename = "file"
256 _filetype = "budget" 371 _filetype = "budget"
257 _exit_method = _budget_file.cancel 372 _exit_method = _budget_file.cancel
262 """_menuitemImportPriceDatabase(widget) 377 """_menuitemImportPriceDatabase(widget)
263 378
264 widget: the widget where the event is emitted from 379 widget: the widget where the event is emitted from
265 Callback to open a price database file. 380 Callback to open a price database file.
266 381
267 Creates and shows a file selection window to open a price database file. 382 Creates and shows a file selection window to open a price database
383 file.
268 """ 384 """
269 _budget = base.Budget() 385 _budget = base.Budget()
270 self.__budget_temp_list.append(_budget)
271 _budget_file = fiebdc.Read() 386 _budget_file = fiebdc.Read()
272 _read_method = _budget_file.readFile 387 _read_method = _budget_file.readFile
273 _filename = "file" 388 _filename = "file"
274 _filetype = "database" 389 _filetype = "database"
275 _exit_method = _budget_file.cancel 390 _exit_method = _budget_file.cancel
283 Callback to open a price database from a durus file. 398 Callback to open a price database from a durus file.
284 399
285 Creates and shows a file selection window to open a durus database 400 Creates and shows a file selection window to open a durus database
286 """ 401 """
287 _budget = None 402 _budget = None
288 self.__budget_temp_list.append(_budget)
289 _budget_file = durusdatabase.Read() 403 _budget_file = durusdatabase.Read()
290 _read_method = _budget_file.readFile 404 _read_method = _budget_file.readFile
291 _filename = "file" 405 _filename = "file"
292 _filetype = "durus" 406 _filetype = "durus"
293 _exit_method = _budget_file.cancel 407 _exit_method = _budget_file.cancel
303 """ 417 """
304 _page_num = self.__notebook.get_current_page() 418 _page_num = self.__notebook.get_current_page()
305 if _page_num != -1: 419 if _page_num != -1:
306 _page = self.__page_list[_page_num] 420 _page = self.__page_list[_page_num]
307 if isinstance(_page, EmptyPage) and _page.filetype == "durus": 421 if isinstance(_page, EmptyPage) and _page.filetype == "durus":
308 print _("Cancel reading Durus database has not been implemented.") 422 print _("Cancel reading Durus database has not been "
423 "implemented.")
309 else: 424 else:
310 _page.close() 425 _page.close()
311 426
312 def removePage(self, page_num): 427 def closePage(self, page):
313 """removePage(page_num) 428 """closePage(page)
314 429
315 page_num: The number Page to be removed 430 page: EmptyPage or Page object
316 431
317 Removes a page from notebook and page_list. 432 Removes a page from notebook and page_list.
318 Removes the budget from the budget_list if necessary. 433 Hide navigation action group if necessary
319 """ 434 """
320 _page = self.__page_list[page_num] 435 if page in self.__page_list:
321 if isinstance(_page, Page): 436 _page_num = self.__page_list.index(page)
322 #not loading budget 437 self.__page_list.pop(_page_num)
323 self.__budget_list.pop(page_num) 438 page.clear()
324 self.__page_list.pop(page_num) 439 self.__notebook.remove_page(_page_num)
325 _page.clear() 440 if len(self.__page_list) == 0:
326 self.__notebook.remove_page(page_num) 441 self.__navigation_action_group.set_sensitive(False)
442 else:
443 raise IndexError, _("The page is not in the page list")
444
327 445
328 def _menuitemGoToRoot(self, widget): 446 def _menuitemGoToRoot(self, widget):
329 """_menuitemGoToRoot(widget) 447 """_menuitemGoToRoot(widget)
330 448
331 widget: the widget where the event is emitted from 449 widget: the widget where the event is emitted from
351 if _page_num != -1: 469 if _page_num != -1:
352 _page = self.__page_list[_page_num] 470 _page = self.__page_list[_page_num]
353 if isinstance(_page, Page): 471 if isinstance(_page, Page):
354 #not loading budget 472 #not loading budget
355 _active_path = _page.activePathRecord 473 _active_path = _page.activePathRecord
356 if len(_active_path) > 1 and _active_path[-1] > 0:
357 _budget = self.__budget_list[_page_num]
358 _up_path = _active_path[:-1] + (_active_path[-1] - 1,)
359 if _budget.hasPath(_up_path):
360 _page.propagateMessageFrom("change_active", (-1,),
361 _up_path)
362
363 def _menuitemGoDown(self, widget):
364 """_menuitemGoToDown(widget)
365
366 widget: the widget where the event is emitted from
367
368 Callback to go to down record.
369 """
370 _page_num = self.__notebook.get_current_page()
371 if _page_num != -1:
372 _page = self.__page_list[_page_num]
373 if isinstance(_page, Page):
374 #not loading budget
375 _active_path = _page.activePathRecord
376 if len(_active_path) > 1: 474 if len(_active_path) > 1:
377 _budget = self.__budget_list[_page_num] 475 _budget = _page.budget
378 _up_path = _active_path[:-1] + (_active_path[-1] + 1,) 476 _up_path = _active_path[:-1]
379 if _budget.hasPath(_up_path): 477 if _budget.hasPath(_up_path):
380 _page.propagateMessageFrom("change_active", (-1,), 478 _page.propagateMessageFrom("change_active", (-1,),
381 _up_path) 479 _up_path)
382 480
383 def _menuitemGoPrevious(self, widget): 481 def _menuitemGoPrevious(self, widget):
392 _page = self.__page_list[_page_num] 490 _page = self.__page_list[_page_num]
393 if isinstance(_page, Page): 491 if isinstance(_page, Page):
394 #not loading budget 492 #not loading budget
395 _previous_path = _page.previousPathRecord 493 _previous_path = _page.previousPathRecord
396 if _previous_path is not None: 494 if _previous_path is not None:
397 _budget = self.__budget_list[_page_num] 495 _budget = _page.budget
398 if _budget.hasPath(_previous_path): 496 if _budget.hasPath(_previous_path):
399 _page.propagateMessageFrom("change_active", (-1,), 497 _page.propagateMessageFrom("change_active", (-1,),
400 _previous_path) 498 _previous_path)
401 499
402 def _menuitemGoPosterior(self, widget): 500 def _menuitemGoPosterior(self, widget):
411 _page = self.__page_list[_page_num] 509 _page = self.__page_list[_page_num]
412 if isinstance(_page, Page): 510 if isinstance(_page, Page):
413 #not loading budget 511 #not loading budget
414 _posterior_path = _page.posteriorPathRecord 512 _posterior_path = _page.posteriorPathRecord
415 if _posterior_path is not None: 513 if _posterior_path is not None:
416 _budget = self.__budget_list[_page_num] 514 _budget = _page.budget
417 if _budget.hasPath(_posterior_path): 515 if _budget.hasPath(_posterior_path):
418 _page.propagateMessageFrom("change_active", (-1,), 516 _page.propagateMessageFrom("change_active", (-1,),
419 _posterior_path) 517 _posterior_path)
420 518
421 def _delete_event(self, widget, event): 519 def _delete_event(self, widget, event):
442 signal returns True or when the program call the destroy() method of 540 signal returns True or when the program call the destroy() method of
443 the gtk.Window widget. 541 the gtk.Window widget.
444 The window is closed and the GTK+ event processing loop is ended. 542 The window is closed and the GTK+ event processing loop is ended.
445 """ 543 """
446 gtk.main_quit() 544 gtk.main_quit()
447
448 def _getNotebook(self):
449 """_getNotebook()
450
451 Return the notebook widget
452 """
453 return self.__notebook
454
455 def _getPageList(self):
456 """_getPageList()
457
458 Return the page list
459 """
460 return self.__page_list
461
462 def _getBudgetList(self):
463 """_getBudgetList()
464
465 Return the budget list
466 """
467 return self.__budget_list
468
469 notebook = property(_getNotebook, None, None,
470 "notebook object")
471 pageList = property(_getPageList, None, None,
472 "Page list")
473 budgetList = property(_getBudgetList, None, None,
474 "Budget list")
475 545
476 546
477 class EmptyPage(object): 547 class EmptyPage(object):
478 """gui.EmptyPage: 548 """gui.EmptyPage:
479 549
553 self.__throbber.set_from_file(globalVars.getAppPath("THROBBER-ICON")) 623 self.__throbber.set_from_file(globalVars.getAppPath("THROBBER-ICON"))
554 self.__throbber.show() 624 self.__throbber.show()
555 self.__animationThobber = gtk.gdk.PixbufAnimation( 625 self.__animationThobber = gtk.gdk.PixbufAnimation(
556 globalVars.getAppPath("THROBBER-GIF")) 626 globalVars.getAppPath("THROBBER-GIF"))
557 self.__quietThobber = self.__throbber.get_pixbuf() 627 self.__quietThobber = self.__throbber.get_pixbuf()
558 self.__budget_icon = gtk.gdk.pixbuf_new_from_file_at_size( 628 self.__budget_icon = gtk.gdk.pixbuf_new_from_file(
559 globalVars.getAppPath("BUDGET-ICON"), 16, 16) 629 globalVars.getAppPath("BUDGET-ICON"))
560 _filename = os.path.basename(filename) 630 _filename = os.path.basename(filename)
561 _rootfilename = os.path.splitext(_filename)[0] 631 _rootfilename = os.path.splitext(_filename)[0]
562 if not _rootfilename == "": 632 if not _rootfilename == "":
563 _filename = _rootfilename 633 _filename = _rootfilename
564 _titleLabel = gtk.Label(_filename) 634 _titleLabel = gtk.Label(_filename)
705 _page = Page(self.__mainWindow, self.__budget) 775 _page = Page(self.__mainWindow, self.__budget)
706 _children = self.__widget.get_children() 776 _children = self.__widget.get_children()
707 for _child in _children: 777 for _child in _children:
708 self.__widget.remove(_child) 778 self.__widget.remove(_child)
709 self.__widget.pack_start(_page.widget, True, True, 0) 779 self.__widget.pack_start(_page.widget, True, True, 0)
710 _noteBook = self.__mainWindow.notebook 780 self.__mainWindow.updatePage(self, _page)
711 _pageIndex = _noteBook.page_num(self.__widget)
712 self.__mainWindow.pageList[_pageIndex] = _page
713 781
714 def threadCanceled(self): 782 def threadCanceled(self):
715 """threadCanceled() 783 """threadCanceled()
716 784
717 Sets the __children atribute to None 785 Sets the __children atribute to None
718 This causes that the timeouts is ended. 786 This causes that the timeouts is ended.
719 This method is called from thread when is canceled 787 This method is called from thread when is canceled
720 TODO: it must called threadFinished or somethig
721 """ 788 """
722 self.__children = None 789 self.__children = None
723 self.stopLoading() 790 self.stopLoading()
724 _page_num = self.__mainWindow.notebook.page_num(self.widget) 791 self.__mainWindow.closePage(self)
725 self.__mainWindow.removePage(_page_num)
726 792
727 def close(self): 793 def close(self):
728 """close() 794 """close()
729 795
730 Close page canceling children 796 Close page canceling children
796 * "CompanyView": its creates a "CompanyView" object 862 * "CompanyView": its creates a "CompanyView" object
797 title: Read. Notebook page title (gtk.Label object) 863 title: Read. Notebook page title (gtk.Label object)
798 activePathRecord: Read. The active path record 864 activePathRecord: Read. The active path record
799 previousPathRecord: Read. The previous path record 865 previousPathRecord: Read. The previous path record
800 posteriorPathRecord Read. The posterior path record 866 posteriorPathRecord Read. The posterior path record
867 back_menu: back menu to show in menutoolbutton
868 forward_menu: forward menu to show in menutoolbutton
801 Methods: 869 Methods:
802 propagateMessageFrom 870 propagateMessageFrom
803 sendMessageTo 871 sendMessageTo
804 close 872 close
805 clear 873 clear
814 """__init__(mainWindow, budget, path_record=(0,)) 882 """__init__(mainWindow, budget, path_record=(0,))
815 883
816 mainWindow: MainWindow object 884 mainWindow: MainWindow object
817 budget: "base.Budget" object 885 budget: "base.Budget" object
818 path_record: the active path record 886 path_record: the active path record
887
888 self.__mainWindow: MainWindow object
889 self.__widget: a gtk.VBox
890 self.__panes_list:
891 self.__main_item:
892 self.__active_path_record:
893 self.__history_back:
894 self.__history_forward:
895 self.__back_menu: a gtk.Menu
896 self.__forward_menu: a gtk.Menu
819 """ 897 """
820 #TODO: __panes_list should come from config file... 898 #TODO: __panes_list should come from config file...
821 self.__mainWindow = mainWindow 899 self.__mainWindow = mainWindow
822 self.__widget = gtk.VBox() 900 self.__widget = gtk.VBox()
823 self.__panes_list = [ "v", "DecompositionList", [ "v", "Measure", 901 self.__panes_list = [ "v", "DecompositionList", [ "v", "Measure",
824 "RecordDescription" ]] 902 "RecordDescription" ]]
825 self.__main_item = None 903 self.__main_item = None
826 self.__active_path_record = () 904 self.__active_path_record = ()
827 self.__history_back = [] 905 self.__history_back = []
828 self.__history_forward = [] 906 self.__history_forward = []
907 self.__back_menu = gtk.Menu()
908 self.__back_menu.show()
909 self.__forward_menu = gtk.Menu()
910 self.__forward_menu.show()
829 self.budget = budget 911 self.budget = budget
830 self._setActivePathRecord(path_record) 912 self._setActivePathRecord(path_record)
831 self.__widget.show() 913 self.__widget.show()
914 self.__budget_icon = gtk.gdk.pixbuf_new_from_file(
915 globalVars.getAppPath("BUDGET-ICON"))
916 self.__chapter_icon = gtk.gdk.pixbuf_new_from_file(
917 globalVars.getAppPath("CHAPTER-ICON"))
918 self.__unit_icon = gtk.gdk.pixbuf_new_from_file(
919 globalVars.getAppPath("UNIT-ICON") )
920 self.__material_icon = gtk.gdk.pixbuf_new_from_file(
921 globalVars.getAppPath("MATERIAL-ICON") )
922 self.__machinery_icon = gtk.gdk.pixbuf_new_from_file(
923 globalVars.getAppPath("MACHINERY-ICON"))
924 self.__labourforce_icon = gtk.gdk.pixbuf_new_from_file(
925 globalVars.getAppPath("LABOURFORCE-ICON"))
832 926
833 def propagateMessageFrom(self, message, pane_path, arg=None): 927 def propagateMessageFrom(self, message, pane_path, arg=None):
834 """propagateMessageFrom(message, pane_path, arg=None) 928 """propagateMessageFrom(message, pane_path, arg=None)
835 929
836 message: string message 930 message: string message
846 """ 940 """
847 _budget = self.__budget 941 _budget = self.__budget
848 if message == "change_active" and _budget.hasPath(arg): 942 if message == "change_active" and _budget.hasPath(arg):
849 self.sendMessageTo(self.__main_item, message, pane_path, arg) 943 self.sendMessageTo(self.__main_item, message, pane_path, arg)
850 self._setActivePathRecord(arg) 944 self._setActivePathRecord(arg)
945 self.__mainWindow.changeActiveSignal()
851 elif message == "autoclose": 946 elif message == "autoclose":
852 self._closeItem(pane_path) 947 self._closeItem(pane_path)
853 elif message == "split h": 948 elif message == "split h":
854 self._splitItem(pane_path, "h") 949 self._splitItem(pane_path, "h")
855 elif message == "split v": 950 elif message == "split v":
870 def close(self): 965 def close(self):
871 """close() 966 """close()
872 967
873 Close Page 968 Close Page
874 """ 969 """
875 _page_list = self.__mainWindow.pageList 970 self.__mainWindow.closePage(self)
876 if self in _page_list:
877 _page_num = _page_list.index(self)
878 self.__mainWindow.removePage(_page_num)
879 else:
880 raise IndexError, _("The page is not in the page list")
881 971
882 def clear(self): 972 def clear(self):
883 """clear() 973 """clear()
884 974
885 Clear atributes 975 Clear atributes
886 """ 976 """
887 self.propagateMessageFrom("clear", (0,)) 977 self.propagateMessageFrom("clear", (0,))
888
889 del self.__budget 978 del self.__budget
890 del self.__panes_list 979 del self.__panes_list
891 del self.__widget 980 del self.__widget
892 del self.__title 981 del self.__title
893 del self.__active_path_record 982 del self.__active_path_record
1034 "the path record: $1"), (str(path_record),)) 1123 "the path record: $1"), (str(path_record),))
1035 1124
1036 def _appendHistory(self, path): 1125 def _appendHistory(self, path):
1037 """_appendHistory(path)) 1126 """_appendHistory(path))
1038 1127
1039 path: the old active path record 1128 path: the new active path record
1040 1129
1041 Sets the old active path record 1130 Append the new active path record to history lists and update menus
1042 """ 1131 """
1043 if len(self.__history_back) > 1 and self.__history_back[-2] == path: 1132 if len(self.__history_back) > 1 and path in self.__history_back[:-1]:
1044 # append forward history and pop back history 1133 # the new active record is in back history list
1045 _path = self.__history_back.pop() 1134 # then append forward history and pop back history
1046 self.__history_forward.append(_path) 1135 _items_num = len(self.__history_back) - \
1047 if len(self.__history_forward) > 1000: 1136 self.__history_back.index(path) -1
1048 self.__history_forward.pop(0) 1137 for _item in range(_items_num):
1138 _record_path = self.__history_back.pop()
1139 _first_menuitem = self.__back_menu.get_children()[0]
1140 self.__back_menu.remove(_first_menuitem)
1141 self.__history_forward.append(_record_path)
1142 _menuitem = self._menuItemFactory(_record_path)
1143 _menuitem.connect_object("activate", self._menuHistoryForward,
1144 _record_path, _menuitem)
1145 self.__forward_menu.prepend(_menuitem)
1146 while len(self.__history_forward) > 100:
1147 # list too long
1148 self.__history_forward.pop(0)
1149 _last_menuitem = self.__forward_menu.get_children()[-1]
1150 self.__forward_menu.remove(_last_menuitem)
1049 else: 1151 else:
1050 # append back history and pop or delete forward history 1152 # the new active record not is in back history list
1051 if len(self.__history_forward) > 1 and \ 1153 if len(self.__history_forward) > 1 and \
1052 self.__history_forward[-1] == path: 1154 path in self.__history_forward:
1053 self.__history_forward.pop() 1155 # the new active record is in history forward list
1156 # then append back history and pop forward history
1157 _items_num = len(self.__history_forward) - \
1158 self.__history_forward.index(path)
1159 for _item in range(_items_num):
1160 _record_path = self.__history_forward.pop()
1161 _first_menuitem = self.__forward_menu.get_children()[0]
1162 self.__forward_menu.remove(_first_menuitem)
1163 self.__history_back.append(_record_path)
1164 if len(self.__history_back) > 1:
1165 _menuitem = self._menuItemFactory(
1166 self.__history_back[-2])
1167 _menuitem.connect_object("activate",
1168 self._menuHistoryBack, self.__history_back[-2],
1169 _menuitem)
1170 self.__back_menu.prepend(_menuitem)
1054 else: 1171 else:
1172 # the new active record not is in history forward list
1173 # then append back history and clear forward history
1055 self.__history_forward[:] = [] 1174 self.__history_forward[:] = []
1056 self.__history_back.append(path) 1175 for _child in self.__forward_menu.get_children():
1057 if len(self.__history_back) > 1000: 1176 self.__forward_menu.remove(_child)
1177 self.__history_back.append(path)
1178 if len(self.__history_back) > 1:
1179 _menuitem = self._menuItemFactory(self.__history_back[-2])
1180 _menuitem.connect_object("activate", self._menuHistoryBack,
1181 self.__history_back[-2], _menuitem)
1182 self.__back_menu.prepend(_menuitem)
1183 while len(self.__history_back) > 100:
1184 # list too long
1058 self.__history_back.pop(0) 1185 self.__history_back.pop(0)
1186 _last_menuitem = self.__back_menu.get_children()[-1]
1187 self.__back_menu.remove(_last_menuitem)
1188 self.__mainWindow.changeHistorySignal()
1189
1190 def _getImage(self, record):
1191 """_getImage(record)
1192
1193 record: record object
1194
1195 Returns an image depending on the type of record
1196 """
1197 _hierarchy = record.recordType.hierarchy
1198 _type = record.recordType.type
1199 _subtype = record.recordType.subtype
1200 if _hierarchy == 0:
1201 _icon = self.__budget_icon
1202 elif _hierarchy == 1:
1203 _icon = self.__chapter_icon
1204 else:
1205 if _type == 0:
1206 _icon = self.__unit_icon
1207 elif _type == 1:
1208 _icon = self.__labourforce_icon
1209 elif _type == 2:
1210 _icon = self.__machinery_icon
1211 else:
1212 _icon = self.__material_icon
1213 _image = gtk.Image()
1214 _image.set_from_pixbuf(_icon)
1215 return _image
1216
1217 def _menuFactory(self):
1218 """_menuFactory()
1219
1220 record: record object
1221
1222 Creates menus for history back an history forward tool buttons
1223 """
1224
1225 # Back Menu
1226 # clear menu
1227 for _child in self.__back_menu.get_children():
1228 self.__back_menu.remove(_child)
1229 # pupulate menu
1230 if len(self.__history_back) > 1:
1231 for _record_path in self.__history_back[:-1]:
1232 _menuitem = self._menuItemFactory(_record_path)
1233 _menuitem.connect_object("activate", self._menuHistoryBack,
1234 _record_path, _menuitem)
1235 self.__back_menu.prepend(_menuitem)
1236 # Forward Menu
1237 # clear menu
1238 for _child in self.__forward_menu.get_children():
1239 self.__forward_menu.remove(_child)
1240 # pupulate menu
1241 if len(self.__history_forward) > 0:
1242 for _record_path in self.__history_forward[:]:
1243 _menuitem = self._menuItemFactory(_record_path)
1244 _menuitem.connect_object("activate", self._menuHistoryForward,
1245 _record_path, _menuitem)
1246 self.__forward_menu.prepend(_menuitem)
1247
1248 def _menuItemFactory(self, record_path):
1249 """_menuItemFactory(record_path):
1250
1251 record_path: record path
1252
1253 Creates and return a menuItem to go to the record
1254 """
1255 _code = self.budget.getCode(record_path)
1256 _record = self.budget.getRecord(_code)
1257 _summary = _record.summary
1258 _text = _code + " " + _summary
1259 if len(_text) > 30:
1260 _text = _text[:27] + "..."
1261 _image = self._getImage(_record)
1262 _menuitem = gtk.ImageMenuItem(_text)
1263 _menuitem.set_image(_image)
1264 _menuitem.show()
1265 return _menuitem
1266
1267 def _menuHistoryBack(self, record_path, menu_item):
1268 """_menuHistoryBack(record_path, menu_item)
1269
1270 Go to the record selected in History Back menu
1271 """
1272 if self.budget.hasPath(record_path):
1273 self.propagateMessageFrom("change_active", (-1,), record_path)
1274
1275 def _menuHistoryForward(self, record_path, menu_item):
1276 """_menuHistoryForward(record_path, menu_item)
1277
1278 Go to the record selected in History Forward menu
1279 """
1280 if self.budget.hasPath(record_path):
1281 self.propagateMessageFrom("change_active", (-1,), record_path)
1059 1282
1060 def _getActivePathRecord(self): 1283 def _getActivePathRecord(self):
1061 """_getActivePathRecord() 1284 """_getActivePathRecord()
1062 1285
1063 Return the Active Path Record 1286 Return the Active Path Record
1081 """ 1304 """
1082 if len(self.__history_forward) > 0: 1305 if len(self.__history_forward) > 0:
1083 return self.__history_forward[-1] 1306 return self.__history_forward[-1]
1084 else: 1307 else:
1085 return None 1308 return None
1309
1310 def _getBackMenu(self):
1311 """_getBackMenu()
1312
1313 Return the Back Menu
1314 """
1315 return self.__back_menu
1316
1317 def _getForwardMenu(self):
1318 """_getForwardMenu()
1319
1320 Return the Forward Menu
1321 """
1322 return self.__forward_menu
1086 1323
1087 def _getTitle(self): 1324 def _getTitle(self):
1088 """_getTitle() 1325 """_getTitle()
1089 1326
1090 Return the page title, a gtk.Label objetc 1327 Return the page title, a gtk.Label objetc
1147 "Active Path Record") 1384 "Active Path Record")
1148 previousPathRecord = property(_getPreviousPathRecord, None, None, 1385 previousPathRecord = property(_getPreviousPathRecord, None, None,
1149 "Previous Active Path Record") 1386 "Previous Active Path Record")
1150 posteriorPathRecord = property(_getPosteriorPathRecord, None, None, 1387 posteriorPathRecord = property(_getPosteriorPathRecord, None, None,
1151 "Posterior Active Path Record") 1388 "Posterior Active Path Record")
1152 1389 back_menu = property(_getBackMenu, None, None,
1390 "Back Menu")
1391 forward_menu = property(_getForwardMenu, None, None,
1392 "Forward Menu")
1153 1393
1154 class View(object): 1394 class View(object):
1155 """gui.View: 1395 """gui.View:
1156 1396
1157 Description: 1397 Description: