changeset 7:0359329a1c26

Navigation buttons. Version of the data structure.
author Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>
date Thu, 11 Nov 2010 23:22:35 +0100
parents 2fc6b47dbe70
children 55df0b15706b
files Generic/durusdatabase.py Generic/fiebdc.py Generic/globalVars.py Gtk/gui.py Gtk/importFiebdc.py mo/es/LC_MESSAGES/pyArq-Presupuestos.mo mo/pyArq-Presupuestos.es.po mo/pyArq-Presupuestos.pot
diffstat 8 files changed, 829 insertions(+), 446 deletions(-) [+]
line wrap: on
line diff
--- a/Generic/durusdatabase.py	Sat Nov 06 22:33:32 2010 +0100
+++ b/Generic/durusdatabase.py	Thu Nov 11 23:22:35 2010 +0100
@@ -27,7 +27,7 @@
 from durus.connection import Connection
 # pyArq Presupuestos Modules
 from Generic import utils
-
+from Generic import globalVars
 class DurusFile(object):
     def __init__(self, file, new):
         self.__file = file
@@ -41,10 +41,16 @@
         self.__connection.get_storage().close()
 
     def getBudget(self):
-        return self.__root["budget"]
+        if self.__root.has_key("baseversion") and \
+           globalVars.baseversion == self.__root["baseversion"]:
+            return self.__root["budget"]
+        else:
+            print _("Incorrent Base version")
+            return None
 
     def setBudget(self, budget):
         self.__root["budget"] = budget
+        self.__root["baseversion"] = globalVars.baseversion
         self.__connection.commit()
 
 class Read(object):
--- a/Generic/fiebdc.py	Sat Nov 06 22:33:32 2010 +0100
+++ b/Generic/fiebdc.py	Thu Nov 11 23:22:35 2010 +0100
@@ -2045,7 +2045,7 @@
             _buffer = _last_record + _buffer2
         _file.close()
         if self.__cancel:
-            print _("Cancelled process")
+            print _("Process terminated")
             return None
         else:
             print utils.mapping(_("Time to load: $1 seconds"),
--- a/Generic/globalVars.py	Sat Nov 06 22:33:32 2010 +0100
+++ b/Generic/globalVars.py	Thu Nov 11 23:22:35 2010 +0100
@@ -23,10 +23,14 @@
 import os
 # path: Paths where find the program files needed
 
-version = "pyArq-Presupuestos v0.0.0"
+version = "pyArq Presupuestos v0.0.0"
+changeset = 7
+baseversion = 0
 path = {
     "HOME" : "",
     "APPDATA" : "",
+    "DURUS-DATABASE": "/pyArq-Presupuestos/durus/",
+    "BUDGET": "/pyArq-Presupuestos/budget/",
     "ICON" : "/images/pyArq-Presupuestos.svg",
     "CHAPTER-ICON" : "/images/chapter.svg",
     "UNIT-ICON" : "/images/unit.svg",
@@ -48,8 +52,6 @@
     "ARROW-ICON": "/images/arrow.svg",
     "IMAGE-ICON": "/images/image.svg",
     "DXF-ICON": "/images/dxf.svg",
-    "DURUS-DATABASE": "/pyArq-Presupuestos/durus/",
-    "BUDGET": "/pyArq-Presupuestos/budget/",
     "THROBBER-ICON": "/images/throbber.png",
     "THROBBER-GIF": "/images/throbber.gif",
     "BUDGET-ICON": "/images/budget.svg",
--- a/Gtk/gui.py	Sat Nov 06 22:33:32 2010 +0100
+++ b/Gtk/gui.py	Thu Nov 11 23:22:35 2010 +0100
@@ -31,7 +31,7 @@
 viewes or more gtk.Paned.
 The view can have diferente type of widgets to show the budget information.
 The DecompositionList class show the decompositon list information of a record
-The Measure class show de measure information of a record
+The Measure class show the measure information of a record
 The TextWindow class show the long description of a record
 The Sheet class class show the sheet of condition information of a record
 
@@ -82,30 +82,17 @@
         Creates and shows the main window.
         This is the interface base class.
     Constructor:
-        gui.MainWindow(): Returns the newly created main window instance
+        gui.MainWindow()
     Ancestry:
     +-- object
       +-- MainWindow
     Atributes:
         "window": Main window widget ("gtk.Window" object)
-        "__budget_temp_list": Temporal list of budgets
-        "__budget_list": List of budgets ("base.Budget" objects)
-        "__page_list": List of pages ("Page" object)
-        "__notebook": Notebook widget ("gtk.Notebook" object)
-        "__general_action_group": the "General" action group
     Methods:
-        __init__(self)
-        _main(self)
-        _addBudget(self, budget)
-        _appendPage(self)
-        _testBudgetList(self)
-        _menuitemImportFiebdc(self, widget)
-        _menuitemImportPriceDatabase(self, widget)
-        _menuitemOpenPriceDatabase(self, widget)
-        _menuitemOpen
-        _menuitemClose(self, widget)
-        _delete_event(self, widget, event)
-        _destroy(self, widget)
+        removePage
+        getNotebook
+        getPageList
+        getBudgetList
     """
     # TODO:* Can choose open budget in new window
     # TODO:* gtk.Action for menu and toolbar
@@ -119,6 +106,13 @@
       </menu>
       <menu action="View">
       </menu>
+      <menu action="Go">
+        <menuitem action="GoUp"/>
+        <menuitem action="GoDown"/>
+        <menuitem action="GoPrevious"/>
+        <menuitem action="GoPosterior"/>
+        <menuitem action="GoToRoot"/>
+      </menu>
       <menu action="Test">
         <menuitem action="ImportFiebdcPriceDatabase"/>
         <menuitem action="OpenPriceDatabase"/>
@@ -126,9 +120,13 @@
     </menubar>
     <toolbar name="ToolBar">
       <toolitem action="ImportFiebdc"/>
-      <separator/>
       <toolitem action="Close"/>
       <separator name="sep1"/>
+      <toolitem action="GoUp"/>
+      <toolitem action="GoDown"/>
+      <toolitem action="GoPrevious"/>
+      <toolitem action="GoPosterior"/>
+      <toolitem action="GoToRoot"/>
     </toolbar>
     </ui>'''
 
@@ -137,7 +135,14 @@
         
         Initialize the atributes "__budget_list" and "__page_list" without data.
         Creates the widgets "window" and "__notebook".
+        
+        self.__budget_temp_list: Temporal list of budgets
+        self.__budget_list: List of budgets ("base.Budget" objects)
+        self.__page_list: List of pages ("Page" object)
+        self.__notebook: Notebook widget ("gtk.Notebook" object)
+        self.__general_action_group: "General" action group
         """
+        #TODO: action group for Navigation buttons
         self.__budget_temp_list = []
         self.__budget_list = []
         self.__page_list = []
@@ -165,6 +170,17 @@
              ("Close", gtk.STOCK_CLOSE, _("_Close"), None, _('Close'),
                 self._menuitemClose),
              ("View", None, _("_View")),
+             ("Go", None, _("_Go")),
+             ("GoUp", gtk.STOCK_GO_UP, _("_Up Record"),"",
+                _("Go up record"), self._menuitemGoUp),
+             ("GoDown", gtk.STOCK_GO_DOWN, _("_Down Record"),"",
+                _("Go down record"), self._menuitemGoDown),
+             ("GoPrevious", gtk.STOCK_GO_BACK, _("_Previous Record"),"",
+                _("Go Previous record"), self._menuitemGoPrevious),
+             ("GoPosterior", gtk.STOCK_GO_FORWARD, _("_Posterior Record"),"",
+                _("Go posterior record"), self._menuitemGoPosterior),
+             ("GoToRoot", gtk.STOCK_GOTO_TOP, _("_Root"),"",
+                _("Go to root"), self._menuitemGoToRoot),
              ("Test", None, _("_Test")),
              ('ImportFiebdcPriceDatabase', gtk.STOCK_OPEN,
                 _("Import Fiebdc _price database"), "", _("Import database"),
@@ -219,7 +235,7 @@
         page widget in the notebook widget.
         """
         _last_budget = self.__budget_list[-1]
-        _page = Page(_last_budget)
+        _page = Page(self, _last_budget)
         self.__notebook.append_page(_page.widget, _page.title)
         self.__page_list.append(_page)
 
@@ -230,7 +246,7 @@
         widget: the widget where the event is emitted from
         Callback to open a budget file.
         
-        Creates and shows a window to open a budget file.
+        Creates and shows a file selection window to open a budget file.
         """
         _budget = base.Budget()
         self.__budget_temp_list.append(_budget)
@@ -246,9 +262,9 @@
         """def _menuitemImportPriceDatabase(self, widget)
         
         widget: the widget where the event is emitted from
-        Callback to open a budget file.
-        
-        Creates and shows a window to open a price database file.
+        Callback to open a price database file.
+        
+        Creates and shows a file selection window to open a price database file.
         """
         _budget = base.Budget()
         self.__budget_temp_list.append(_budget)
@@ -266,7 +282,7 @@
         widget: the widget where the event is emitted from
         Callback to open a price database from a durus file.
         
-        Creates and shows a window to open a durus database
+        Creates and shows a file selection window to open a durus database
         """
         _budget = None
         self.__budget_temp_list.append(_budget)
@@ -286,19 +302,121 @@
         Callback to close a budget file.
         """
         _page_num = self.__notebook.get_current_page()
+        if _page_num != -1:
+            _page = self.__page_list[_page_num]
+            if isinstance(_page, EmptyPage) and _page.filetype == "durus":
+                print _("Cancel reading Durus database has not been implemented.")
+            else:
+                _page.close()
+
+    def removePage(self, page_num):
+        """def removePage(self, page_num)
+        
+        page_num: The number Page to be removed
+        
+        Removes a page from notebook and page_list.
+        Removes the budget from the budget_list if necessary.
+        """
+        _page = self.__page_list[page_num]
+        if isinstance(_page, Page):
+            #not loading budget
+            self.__budget_list.pop(page_num)
+        self.__page_list.pop(page_num)
+        _page.clear()
+        self.__notebook.remove_page(page_num)
+
+    def _menuitemGoToRoot(self, widget):
+        """def _menuitemGoToRoot(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to go to root record.
+        """
+        _page_num = self.__notebook.get_current_page()
         if _page_num == -1:
             return
-        #_page = self.__page_list.pop(_page_num)
         _page = self.__page_list[_page_num]
         if isinstance(_page, Page):
             #not loading budget
-            self.__budget_list.pop(_page_num)
-        if isinstance(_page, EmptyPage) and _page.filetype == "durus":
-            print _("Cancel reading Durus database has not been implemented.")
-        else:
-            self.__page_list.pop(_page_num)
-            _page.clear()
-            self.__notebook.remove_page(_page_num)
+            _page.propagateMessageFrom("change_active", (-1,), (0,))
+
+    def _menuitemGoUp(self, widget):
+        """def _menuitemGoUp(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to go to up record.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num != -1:
+            _page = self.__page_list[_page_num]
+            if isinstance(_page, Page):
+                #not loading budget
+                _active_path = _page.activePathRecord
+                if len(_active_path) > 1 and _active_path[-1] > 0:
+                    _budget = self.__budget_list[_page_num]
+                    _up_path = _active_path[:-1] + (_active_path[-1] - 1,)
+                    if _budget.hasPath(_up_path):
+                        _page.propagateMessageFrom("change_active", (-1,),
+                                                   _up_path)
+
+    def _menuitemGoDown(self, widget):
+        """def _menuitemGoToDown(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to go to down record.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num != -1:
+            _page = self.__page_list[_page_num]
+            if isinstance(_page, Page):
+                #not loading budget
+                _active_path = _page.activePathRecord
+                if len(_active_path) > 1:
+                    _budget = self.__budget_list[_page_num]
+                    _up_path = _active_path[:-1] + (_active_path[-1] + 1,)
+                    if _budget.hasPath(_up_path):
+                        _page.propagateMessageFrom("change_active", (-1,),
+                                                   _up_path)
+
+    def _menuitemGoPrevious(self, widget):
+        """def _menuitemGoPrevious(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to go to previous record.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num != -1:
+            _page = self.__page_list[_page_num]
+            if isinstance(_page, Page):
+                #not loading budget
+                _previous_path = _page.previousPathRecord
+                if _previous_path is not None:
+                    _budget = self.__budget_list[_page_num]
+                    if _budget.hasPath(_previous_path):
+                        _page.propagateMessageFrom("change_active", (-1,),
+                                                   _previous_path)
+
+    def _menuitemGoPosterior(self, widget):
+        """def _menuitemPosterior(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to go to posterior record.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num != -1:
+            _page = self.__page_list[_page_num]
+            if isinstance(_page, Page):
+                #not loading budget
+                _posterior_path = _page.posteriorPathRecord
+                if _posterior_path is not None:
+                    _budget = self.__budget_list[_page_num]
+                    if _budget.hasPath(_posterior_path):
+                        _page.propagateMessageFrom("change_active", (-1,),
+                                                   _posterior_path)
 
     def _delete_event(self, widget, event):
         """_delete_event(self, widget, event)
@@ -328,20 +446,87 @@
         gtk.main_quit()
 
     def getNotebook(self):
+        """def getNotebook(self)
+        
+        Return the notebook widget
+        """
         return self.__notebook
+
     def getPageList(self):
+        """def getPageList(self)
+        
+        Return the page list
+        """
         return self.__page_list
+
     def getBudgetList(self):
+        """def getBudgetList(self)
+        
+        Return the budget list
+        """
         return self.__budget_list
 
 class EmptyPage(object):
-    """
+    """gui.EmptyPage:
+    
+    Description:
+    It creates and shows a page in the notebook while a budget is loaded.
+    The page show the pyarq logo, loading time and a progress bar.
+    Constructor:
+        gui.EmptyPage(self, mainWindow, readFileMethod, budget, filename,
+                 cancelMethod, filetype):
+    Ancestry:
+    +-- object
+      +-- EmptyPage
+    Atributes:
+        __mainWindow: gui.Mainwindow object
+        __readFileMethod: Method to read the selected file
+        __budget: base.Budget object
+        __filename: "file"
+        __cancelMethod: Method to cancel the read method
+        __filetype: "budget", "database" or "durus"
+        __children: the read thread
+        __progress: 0 to 1 progress
+        __widget: main widget, a gtk.VBox object
+        __main_item: None
+        __throbber: a gtk.Image
+        __animationThobber: a gtk.gdk.PixbufAnimation
+        __quietThobber: a pixbuf
+        __budget_icon: a gtk.gdk.pixbuf
+        __title: a gtk.HBox
+        __statusbar: a gtk.Statusbar
+        __statuscontext: the statusbar context
+        __progress_bar: a gtk.ProgressBar
+
+    Methods:
+        __init__
+        run
+        progress
+        stopLoading
+        _launchChildren
+        _launchTimeout
+        _updateProgressBar
+        _updateLabel
+        _autoClose
+        threadFinishedSignal
+        threadCanceled
+        close
+        clear
+        getWidget
+        getTitle
+        getFiletype
     """
     def __init__(self, mainWindow, readFileMethod, budget, filename,
                  cancelMethod, filetype):
         """def __init__(self, mainWindow, readFileMethod, budget, filename,
                         cancelMethod, filetype)
         
+        mainWindow: gui.Mainwindow object
+        readFileMethod: Method to read the selected file
+        budget: base.Budget object
+        filename: "file"
+        cancelMethod: Method to cancel the read method
+        filetype: "budget", "database" or "durus"
         """
         self.__mainWindow = mainWindow
         self.__readFileMethod = readFileMethod
@@ -494,7 +679,7 @@
         self.__budget = budget
         self.__children = None
         self.stopLoading()
-        _page = Page(self.__budget)
+        _page = Page(self.__mainWindow, self.__budget)
         _children = self.__widget.get_children()
         for _child in _children:
             self.__widget.remove(_child)
@@ -512,13 +697,20 @@
         """
         self.__children = None
         self.stopLoading()
-
+        _page_num = self.__mainWindow.getNotebook().page_num(self.widget)
+        self.__mainWindow.removePage(_page_num)
+    def close(self):
+        """def close(self)
+        
+        Clos page canceling children
+        """
+        self.__children.cancel()
     def clear(self):
         """def clear(self)
         
-        Cancel thread
+        clear vars
         """
-        self.__children.cancel()
+        pass
         
     def getWidget(self):
         """def getWidget(self)
@@ -555,14 +747,15 @@
     The page can show the budget information in several panes ordered
     according to "panes_list" information.
     Constructor:
-        gui.Page(budget, active_code=None):
-        budget: budget to be showed in this page (base.Budget object)
-        active_code: the code of the active record 
-        Returns the newly created Page instance
+        gui.Page(mainWindow, budget, active_code=None)
+            mainwindow: MainWindow object
+            budget: base.Budget object
+            active_code: Active record code
     Ancestry:
     +-- object
       +-- Page
     Atributes:
+        "widget": Read. Notebook page Widget. (a gtk.VBox instance)
         "budget": Read-Write. Budget to show in the page. (base.obra object)
         "panes_list": Read. info list for create the panes
             ej: [ "v", pane1, pane2 ] , [ "h", pane1, pane2 ]
@@ -573,55 +766,51 @@
                 * "Measure": its creates a "Measure" objetc
                 * "FileView": its creates a "FileView" objet
                 * "CompanyView": its creates a "CompanyView" object
-        "widget": Read. Notebook page Widget. (a gtk.VBox instance)
         "title": Read. Notebook page title (gtk.Label object)
-        "__active_path_record": The active path record
-        "__main_item": main item in the page, can be a View object or a Paned 
-            object
+        "activePathRecord": Read. The active path record
+        "previousPathRecord": Read. The previous path record
+        "posteriorPathRecord" Read. The posterior path record
     Methods:
-        __init__(self, budget=None, active_code=None)
-        propagateMessageFrom(self, message, path, arg=None)
-        sendMessageTo(self, pane, message, path, arg=None)
-        clear(self)
-        getItem(self,path)
-        setMainItem(self, item)
-        itemsFactory(self, list_paned, path=(0,))
-        setActivePathRecord(self, path_record)
-        getTitle(self)
-        getWidget(self)
-        setBudget(self, budget)
-        getBudget(self)
-        getPanesList(self)
+        propagateMessageFrom
+        sendMessageTo
+        close
+        clear
+        getItem
     """
     # TODO:  * The panes can be ordered as the user wishes 
     # TODO:  * Panes in windows
     # TODO:  * pane types
     # TODO:      * General budget properties (is better a dialog?)
 
-    def __init__(self, budget, path_record=(0,)):
+    def __init__(self, mainWindow, budget, path_record=(0,)):
         """def __init__(self, budget=None, active_code=None)
         
+        mainWindow: MainWindow object
         budget: "base.Budget" object
-        active_code: the code of the active record
-        Sets the atributes
-            * __panes_list: info to create the panes
-            * budget (base.Budget object)
-            * active_code
+        path_record: the active path record
         """
         #TODO: __panes_list should come from config file...
+        self.__mainWindow = mainWindow
         self.__widget = gtk.VBox()
         self.__panes_list = [ "v", "DecompositionList", [ "v", "Measure",
             "RecordDescription" ]]
         self.__main_item = None
+        self.__active_path_record = ()
+        self.__history_back = []
+        self.__history_forward = []
         self.setBudget(budget)
-        self.setActivePathRecord(path_record)
+        self._setActivePathRecord(path_record)
         self.__widget.show()
 
-    def propagateMessageFrom(self, message, path, arg=None):
-        """def propagateMessageFrom(self, message, path, arg=None)
+    def propagateMessageFrom(self, message, pane_path, arg=None):
+        """def propagateMessageFrom(self, message, pane_path, arg=None)
         
         message: string message
-        path: tuple that represents the pane path which emits the message
+                * "change_active": change active code
+                * "autoclose"
+                * "split h"
+                * "split v"
+        pane_path: tuple that represents the pane path which emits the message
         arg: arguments for the message
              if message is "change_active" arg is the path record
         
@@ -629,25 +818,38 @@
         """
         _budget = self.__budget
         if message == "change_active" and _budget.hasPath(arg):
-            self.sendMessageTo(self.__main_item, message, path, arg)
+            self.sendMessageTo(self.__main_item, message, pane_path, arg)
+            self._setActivePathRecord(arg)
         elif message == "autoclose":
-            self._closeItem(path)
+            self._closeItem(pane_path)
         elif message == "split h":
-            self._splitItem(path, "h")
+            self._splitItem(pane_path, "h")
         elif message == "split v":
-            self._splitItem(path, "v")
+            self._splitItem(pane_path, "v")
             
-    def sendMessageTo(self, pane, message, path, arg=None):
-        """def sendMessageTo(self, pane,message, path, arg=None)
+    def sendMessageTo(self, pane, message, pane_path, arg=None):
+        """def sendMessageTo(self, pane, message, pane_path, arg=None)
         pane: the receiver pane
         message: string message
-        path: tuple that represents the pane path which emits the message
+        pane_path: tuple that represents the pane pane_path which emits the message
         arg: arguments for the message
         
         Sends a message to a pane
         """
-        if not pane.path == path:
-            pane.runMessage(message, path, arg)
+        if not pane.path == pane_path:
+            pane.runMessage(message, pane_path, arg)
+
+    def close(self):
+        """def close(self)
+        
+        Close Page
+        """
+        _page_list = self.__mainWindow.getPageList()
+        if self in _page_list:
+            _page_num = _page_list.index(self)
+            self.__mainWindow.removePage(_page_num)
+        else:
+            raise IndexError, _("The page is not in the page list")
 
     def clear(self):
         """def clear(self)
@@ -663,20 +865,20 @@
         del self.__active_path_record
         del self.__main_item
 
-    def getItem(self,path):
-        """def getItem(self, path
-        
-        Return the item whith the path "path", it can return a Paned instance
-        or a View instance
+    def getItem(self,pane_path):
+        """def getItem(self, pane_path)
+        
+        Return the item whith the path "pane_path", it can return a Paned
+        instance or a View instance
         """
         _item = self.__main_item
-        if len(path) == 1:
+        if len(pane_path) == 1:
             return _item
         else:
-            return _item.getItem(path[1:])
+            return _item.getItem(pane_path[1:])
 
-    def setMainItem(self, item):
-        """setMainItem(self,item)
+    def _setMainItem(self, item):
+        """_setMainItem(self,item)
         
         Sets a new main item in the page
         """
@@ -688,46 +890,46 @@
         _main_widget.show()
         self.__widget.pack_start(_main_widget, True, True, 0)
 
-    def _splitItem(self, path, orientation):
-        """_splitItem(self, path, orientation)
-        
-        Splits the item that is identifies by the path and the orientation
+    def _splitItem(self, pane_path, orientation):
+        """_splitItem(self, pane_path, orientation)
+        
+        Splits the item that is identifies by the pane_path and the orientation
         """
-        _item = self.getItem(path)
-        _parent = self.getItem(path[:-1])
-        _item.setPath(path+ (0,))
-        _item_clone0 = _item.getClone(path + (0,))
-        _item_clone1 = _item.getClone(path + (1,))
-        _paned = Paned(orientation, path, _item_clone0, _item_clone1)
-        if len(path) > 1:
-            _parent.setItem(path[-1], [_paned])
+        _item = self.getItem(pane_path)
+        _parent = self.getItem(pane_path[:-1])
+        _item.setPath(pane_path+ (0,))
+        _item_clone0 = _item.getClone(pane_path + (0,))
+        _item_clone1 = _item.getClone(pane_path + (1,))
+        _paned = Paned(orientation, pane_path, _item_clone0, _item_clone1)
+        if len(pane_path) > 1:
+            _parent.setItem(pane_path[-1], [_paned])
         else:
-            self.setMainItem(_paned)
-        
-    def _closeItem(self, path):
-        """_closeItem(self, path)
-        
-        Closes the item that is identifies by the path
+            self._setMainItem(_paned)
+        
+    def _closeItem(self, pane_path):
+        """_closeItem(self, pane_path)
+        
+        Closes the item that is identifies by the pane_path
         """
-        _item = self.getItem(path)
-        if len(path) > 1:
+        _item = self.getItem(pane_path)
+        if len(pane_path) > 1:
             # There are more than one item
-            _parent = self.getItem(path[:-1])
+            _parent = self.getItem(pane_path[:-1])
             _brothers = [ _brother for _brother in _parent]
             _brothers.remove(_item)
             _brother = _brothers[0]
             
             _parent.widget.remove(_brother.widget)
-            _brother.path = path[:-1]
-            if len(path) > 2:
-                _grandparent = self.getItem(path[:-2])
-                _grandparent.setItem(path[-2], [_brother])
+            _brother.pane_path = pane_path[:-1]
+            if len(pane_path) > 2:
+                _grandparent = self.getItem(pane_path[:-2])
+                _grandparent.setItem(pane_path[-2], [_brother])
                 _parent.widget.destroy()
                 _parent.clear()
                 _item.clear()
             else:
                 _grandparent = self
-                _grandparent.setMainItem(_brother)
+                _grandparent._setMainItem(_brother)
                 _parent.widget.destroy()
                 _parent.clear()
                 _item.clear()
@@ -735,8 +937,8 @@
             # Thre is only one item in the page, it can not be closed
             pass
 
-    def itemsFactory(self, list_paned, path=(0,)):
-        """def itemsFactory(self, list_paned, path(0,))
+    def _itemsFactory(self, list_paned, pane_path=(0,)):
+        """def _itemsFactory(self, list_paned, pane_path(0,))
         
         list_paned: list in "__panes_list" format
             [ "v" or "h", panel1_type, panel2_type]
@@ -748,7 +950,7 @@
                 * "Sheet of Conditions"
                 * "FileView"
                 * "CompanyView"
-        path: tuple that represents the item path in the page
+        pane_path: tuple that represents the item path in the page
         
         Creates the items and widgets and returns the main item
         """
@@ -761,26 +963,26 @@
                 list_paned[1] = [list_paned[1]]
             if not isinstance(list_paned[2],list):
                 list_paned[2] = [list_paned[2]]
-            _item1 = self.itemsFactory(list_paned[1],path + (0,))
-            _item2 = self.itemsFactory(list_paned[2],path + (1,)) 
-            _item = Paned(list_paned[0], path, _item1, _item2)
+            _item1 = self._itemsFactory(list_paned[1],pane_path + (0,))
+            _item2 = self._itemsFactory(list_paned[2],pane_path + (1,)) 
+            _item = Paned(list_paned[0], pane_path, _item1, _item2)
         elif list_paned[0] == "DecompositionList":
             _item = View( "DecompositionList", self.__budget,
-                weakref.ref(self), path, self.__active_path_record)
+                weakref.ref(self), pane_path, self.__active_path_record)
         elif list_paned[0] == "RecordDescription":
             _item = View( "RecordDescription", self.__budget,weakref.ref(self),
-                path, self.__active_path_record)
+                pane_path, self.__active_path_record)
         elif list_paned[0] == "Measure":
-            _item = View( "Measure", self.__budget, weakref.ref(self), path,
+            _item = View( "Measure", self.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         elif list_paned[0] == "Sheet of Conditions":
-            _item  = Sheet(sef.__budget, weakref.ref(self), path,
+            _item  = Sheet(sef.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         elif list_paned[0] == "FileView":
-            _item  = FileView(sef.__budget, weakref.ref(self), path,
+            _item  = FileView(sef.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         elif list_paned[0] == "CompanyView":
-            _item  = CompanyView(sef.__budget, weakref.ref(self), path,
+            _item  = CompanyView(sef.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         else:
             _item = None
@@ -788,23 +990,75 @@
                   (str(list_paned[0]),))
         return _item
 
-    def setActivePathRecord(self, path_record):
-        """def setActivePathRecord(self, path_record)
+    def _setActivePathRecord(self, path_record):
+        """def _setActivePathRecord(self, path_record)
         
         path_record: the active record path
         
         Sets the active record path
         """
-        if self.__budget.hasPath(path_record):
-            self.__active_path_record = path_record
+        if path_record != self.__active_path_record:
+            if self.__budget.hasPath(path_record):
+                self.__active_path_record = path_record
+                self._appendHistory(path_record)
+            else:
+                raise ValueError, utils.mapping(_("The budget does not have "\
+                    "the path record: $1"), (str(path_record),))
+    def _appendHistory(self, path):
+        """def _appendHistory(self, path))
+        
+        path: the old active path record
+        
+        Sets the old active path record
+        """
+        if len(self.__history_back) > 1 and self.__history_back[-2] == path:
+            # append forward history and pop back history
+            _path = self.__history_back.pop()
+            self.__history_forward.append(_path)
+            if len(self.__history_forward) > 1000:
+                self.__history_forward.pop(0)
         else:
-            raise ValueError, utils.mapping(_("The budget does not have the "\
-                  "path record: $1"), (str(path_record),))
+            # append back history and pop or delete forward history
+            if len(self.__history_forward) > 1 and \
+               self.__history_forward[-1] == path:
+                self.__history_forward.pop()
+            else:
+                self.__history_forward[:] = []
+            self.__history_back.append(path)
+            if len(self.__history_back) > 1000:
+                self.__history_back.pop(0)
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        Return the Active Path Record
+        """
+        return self.__active_path_record
+    
+    def getPreviousPathRecord(self):
+        """def getPreviousPathRecord(self)
+        
+        Return the Previous Path Record
+        """
+        if len(self.__history_back) > 1: 
+            return self.__history_back[-2]
+        else:
+            return None
+
+    def getPosteriorPathRecord(self):
+        """def getPosteriorPathRecord(self)
+        
+        Return the Posterior Path Record
+        """
+        if len(self.__history_forward) > 0: 
+            return self.__history_forward[-1]
+        else:
+            return None
 
     def getTitle(self):
-        """def getTtle(self)
-        
-        Return the title of the page, a gtk.Label objetc
+        """def getTitle(self)
+        
+        Return the page title, a gtk.Label objetc
         """
         return self.__title
     
@@ -828,12 +1082,12 @@
             self.clear()
             return
         self.__budget = budget
-        self.setActivePathRecord((0,))
-        ## Todo: change page title
+        self._setActivePathRecord((0,))
+        # Todo: change page title
         self.__title = gtk.Label(self.__budget.getCode(
                        self.__active_path_record))
         _panes_list = self.__panes_list
-        self.__main_item = self.itemsFactory(_panes_list)
+        self.__main_item = self._itemsFactory(_panes_list)
         _main_widget = self.__main_item.getWidget()
         _main_widget.show()
         self.__widget.pack_start(_main_widget, True, True, 0)
@@ -860,6 +1114,12 @@
                       "Page Title")
     panes_list = property(getPanesList, None, None,
                       "Info list for create the panes")
+    activePathRecord = property(getActivePathRecord, None, None,
+                      "Active Path Record")
+    previousPathRecord = property(getPreviousPathRecord, None, None,
+                      "Previous Active Path Record")
+    posteriorPathRecord = property(getPosteriorPathRecord, None, None,
+                      "Posterior Active Path Record")
 
 class View(object):
     """gui.View:
@@ -4399,4 +4659,6 @@
         
         return the main widget (gtk.ScrolledWindow)
         """
-        return self.__widget
\ No newline at end of file
+        return self.__widget
+    widget = property(getWidget, None, None,
+        "main widget")
\ No newline at end of file
--- a/Gtk/importFiebdc.py	Sat Nov 06 22:33:32 2010 +0100
+++ b/Gtk/importFiebdc.py	Thu Nov 11 23:22:35 2010 +0100
@@ -400,7 +400,7 @@
         budget: base.Budget object
         filename: "file"
         cancelMethod: Method to cancel the read method
-        feletype: "budget", "database" or "durus"
+        filetype: "budget", "database" or "durus"
         Sets the instance atributes.
         """
         super(Thread, self).__init__()
Binary file mo/es/LC_MESSAGES/pyArq-Presupuestos.mo has changed
--- a/mo/pyArq-Presupuestos.es.po	Sat Nov 06 22:33:32 2010 +0100
+++ b/mo/pyArq-Presupuestos.es.po	Thu Nov 11 23:22:35 2010 +0100
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: pyArq-Presupuestos 0.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-10-31 20:54+0100\n"
+"POT-Creation-Date: 2010-11-11 23:10+0100\n"
 "PO-Revision-Date: 2010-01-11 12:24+0100\n"
 "Last-Translator: Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso."
 "es>\n"
@@ -27,7 +27,7 @@
 
 #: ../Generic/base.py:373
 msgid "Synonyms ($1) must be a list, code: $2"
-msgstr "Sinónimos ($1) debe ser una lista, código: $2"
+msgstr "«Synonyms» ($1) debe ser una lista, código: $2"
 
 #: ../Generic/base.py:377
 msgid "Invalid Code in synomyms list ($1) code: $2"
@@ -35,11 +35,11 @@
 
 #: ../Generic/base.py:408
 msgid "Unit ($1) must be a string: $2"
-msgstr "Unidad ($1) debe ser una cadena: $2"
+msgstr "«Unit» ($1) debe ser una cadena: $2"
 
 #: ../Generic/base.py:422
 msgid "Summary ($1) must be a string: $1"
-msgstr "Resumen ($1) debe ser una cadena: $1"
+msgstr "«Summary» ($1) debe ser una cadena: $1"
 
 #: ../Generic/base.py:439
 msgid "Prices ($1) must be a list: $2"
@@ -47,7 +47,7 @@
 
 #: ../Generic/base.py:460
 msgid "Price ($1) must be a list with two items: $2"
-msgstr "«Prece» ($1) debe ser una lista con dos elementos: $2"
+msgstr "«Price» ($1) debe ser una lista con dos elementos: $2"
 
 #: ../Generic/base.py:465
 msgid "Price must be a float number: $1"
@@ -64,7 +64,7 @@
 
 #: ../Generic/base.py:496
 msgid "Parents ($1) must be a list: $2"
-msgstr "Padres ($1) debe ser una lista: $2"
+msgstr "«Parents» ($1) debe ser una lista: $2"
 
 #: ../Generic/base.py:500 ../Generic/base.py:512
 msgid "Invalid parent code ($1) in the record: $2"
@@ -72,7 +72,7 @@
 
 #: ../Generic/base.py:528
 msgid "children ($1) must be a list, record: $2"
-msgstr "Hijos ($1) debe ser una lista, registro: $2"
+msgstr "«children» ($1) debe ser una lista, registro: $2"
 
 #: ../Generic/base.py:532
 msgid "child ($1) must be a Decomposition object, record: $2"
@@ -80,11 +80,11 @@
 
 #: ../Generic/base.py:580
 msgid "Text ($1) must be a string, record: $2"
-msgstr "Texto ($1) debe ser una cadena, registro: $2"
+msgstr "«Text» ($1) debe ser una cadena, registro: $2"
 
 #: ../Generic/base.py:593
 msgid "sheet must be a Sheet instance"
-msgstr "sheet debe ser una instancia de Sheet"
+msgstr "«sheet» debe ser una instancia de Sheet"
 
 #: ../Generic/base.py:606
 msgid "files must be a list: $1"
@@ -108,7 +108,7 @@
 
 #: ../Generic/base.py:666
 msgid "Label must be a string"
-msgstr "Label debe ser una cadena de texto."
+msgstr "«Label» debe ser una cadena de texto."
 
 #: ../Generic/base.py:894
 msgid "Position must be a integer"
@@ -128,7 +128,7 @@
 
 #: ../Generic/base.py:920
 msgid "Real cost atribute must be a list or None"
-msgstr "El atributo «Real cost» debe ser listo o «None»"
+msgstr "El atributo «Real cost» debe ser una lista o «None»"
 
 #: ../Generic/base.py:926
 msgid "Cost goals atribute must be a list or None"
@@ -184,7 +184,7 @@
 
 #: ../Generic/base.py:1322
 msgid "Invalid Measure Units ($1)"
-msgstr "Unidades de medición no vacías ($1)"
+msgstr "Unidades de medición no válidas ($1)"
 
 #: ../Generic/base.py:1334
 msgid "Invalid Measure length ($1)"
@@ -204,7 +204,7 @@
 
 #: ../Generic/base.py:1372
 msgid "There is invalid charactersin formula ($1)"
-msgstr "Hay caracteres inválidos en la fórmula ($1)"
+msgstr "Hay caracteres no válidos en la fórmula ($1)"
 
 #: ../Generic/base.py:1437 ../Generic/base.py:2406
 msgid "'a' value must be a float number"
@@ -228,15 +228,15 @@
 
 #: ../Generic/base.py:1727
 msgid "sheet_dict must be a dictionay"
-msgstr "sheet_dict debe ser un diccionario."
+msgstr "«sheet_dict» debe ser un diccionario."
 
 #: ../Generic/base.py:1744 ../Generic/base.py:1750
 msgid "sheet field must be a string"
-msgstr "El ambito del pliego debe ser una cadena de texto"
+msgstr "«sheet field» debe ser una cadena de texto"
 
 #: ../Generic/base.py:1746
 msgid "section_dict must be a dictionary"
-msgstr "section_dict debe ser un dicionario"
+msgstr "«section_dict» debe ser un dicionario"
 
 #: ../Generic/base.py:1752
 msgid "sheet section must be a string"
@@ -244,7 +244,7 @@
 
 #: ../Generic/base.py:1754
 msgid "sheet paragraph must be a string"
-msgstr "El parrafo del pliego debe ser una cadena de texto"
+msgstr "«sheet paragraph» debe ser una cadena de texto"
 
 #: ../Generic/base.py:1992
 msgid "Owner must be a string"
@@ -253,11 +253,11 @@
 #: ../Generic/base.py:2008
 #, python-format
 msgid "Invalid Date: %s"
-msgstr "Fecha inválida: %s"
+msgstr "Fecha no válida: %s"
 
 #: ../Generic/base.py:2019
 msgid "Comment must be a string"
-msgstr "El comentario debe ser una cadena"
+msgstr "«Comment» debe ser una cadena"
 
 #: ../Generic/base.py:2035
 msgid "Budget type must be 1, 2, 3 or 4."
@@ -336,11 +336,11 @@
 
 #: ../Generic/base.py:2627
 msgid "Path item must be a integer"
-msgstr "El elemento del camino debe ser un número entero"
+msgstr "El elemento de la ruta debe ser un número entero"
 
 #: ../Generic/base.py:2632
 msgid "Path must be a not empty tuple: $1"
-msgstr "El camino debe ser una tupla no vacía: $1"
+msgstr "«Path» debe ser una tupla no vacía: $1"
 
 #: ../Generic/base.py:2683
 msgid "The sheet code must be a string"
@@ -381,7 +381,7 @@
 #: ../Generic/base.py:2728 ../Generic/base.py:2752 ../Generic/base.py:2882
 #: ../Generic/base.py:2906 ../Generic/base.py:2928
 msgid "The record_code code must be a string"
-msgstr "record_code debe ser una cadena de texto"
+msgstr "«record_code» debe ser una cadena de texto"
 
 #: ../Generic/base.py:2730
 msgid "The field must be a string"
@@ -396,8 +396,8 @@
 "Error: The budget do not have this record code and can not be added the "
 "sheet text in the field $1. Record Code: $2"
 msgstr ""
-"Error: El presupuesto no tiene ese codigo de registro y no puede añadirse el "
-"texto del pliego en el ambito $1. Código del registro: $2"
+"Error: El presupuesto no tiene ese código de registro y no puede añadirse el "
+"texto del pliego en el ámbito $1. Código del registro: $2"
 
 #: ../Generic/base.py:2754
 msgid "The filename must be a string"
@@ -533,15 +533,27 @@
 
 #: ../Generic/base.py:3403
 msgid "Invalid type ($1),the type must be (empty string,0,1,2,3)"
-msgstr "Tipo inválido ($1), el tipo debe ser (cadena vacía, 0, 1, 2, 3)"
+msgstr "Tipo no válido ($1), el tipo debe ser (cadena vacía, 0, 1, 2, 3)"
 
 #: ../Generic/base.py:3412
 msgid ""
 "Invalid subtype ($1), The subtype must one in (empty string, EA, EU, EC, EF, "
 "OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
 msgstr ""
-"Subtipo inválido ($1), el subtipo debe ser uno de (cadena vacía, EA, EU, EC, "
-"EF, OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
+"Subtipo no válido ($1), el subtipo debe ser uno de (cadena vacía, EA, EU, "
+"EC, EF, OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
+
+#: ../Generic/durusdatabase.py:48
+msgid "Incorrent Base version"
+msgstr "Versión de la Base incorrecta"
+
+#: ../Generic/durusdatabase.py:77
+msgid "Loading file: $1:"
+msgstr "Cargando archivo: $1"
+
+#: ../Generic/durusdatabase.py:82
+msgid "Loadig time: $1 seconds"
+msgstr "Tiempo de carga: $1 segundos"
 
 #: ../Generic/fiebdc.py:151
 msgid "Invalid code, it must be a string"
@@ -635,47 +647,47 @@
 msgid "PyArq hates parametric DLLs"
 msgstr "PyArq odia las DLLs paramétricas"
 
-#: ../Generic/fiebdc.py:1980
+#: ../Generic/fiebdc.py:1979
 msgid "Loading file $1"
 msgstr "Cargando archivo $1"
 
-#: ../Generic/fiebdc.py:2000
+#: ../Generic/fiebdc.py:1999
 msgid "This codepage do not exist in FIEBDC3! Default codepage: $1"
 msgstr "¡Esta codificación no existe en FIEBDC3! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2004
+#: ../Generic/fiebdc.py:2003
 msgid "This V record dot have a codepage! Default codepage: $1"
 msgstr "¡Este registro V no define codificación! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2008
+#: ../Generic/fiebdc.py:2007
 msgid "Not 'V' record in File! Default codepage: $1"
 msgstr "¡No hay registro «V» en el archivo! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2049
-msgid "Cancelled process"
+#: ../Generic/fiebdc.py:2048
+msgid "Process terminated"
 msgstr "Proceso cancelado"
 
-#: ../Generic/fiebdc.py:2052
+#: ../Generic/fiebdc.py:2051
 msgid "Time to load: $1 seconds"
 msgstr "Tiempo de carga: $1 segundos"
 
-#: ../Generic/fiebdc.py:2054
+#: ../Generic/fiebdc.py:2053
 msgid "Records/Valid Records: $1/$2"
 msgstr "Registro/Registros válidos: $1/$2"
 
-#: ../Generic/fiebdc.py:2057
+#: ../Generic/fiebdc.py:2056
 msgid "$1 unsuported record type O: Comercial Relationship"
 msgstr "$1 tipo de registro no soportado O: Releción comercial"
 
-#: ../Generic/fiebdc.py:2060
+#: ../Generic/fiebdc.py:2059
 msgid "This file is not a valid FIBDC3 file"
 msgstr "El archivo no es un archivo FIEBDC3 válido"
 
-#: ../Generic/fiebdc.py:2097
+#: ../Generic/fiebdc.py:2096
 msgid "Testing budget ..."
 msgstr "Comprobando presupuesto ..."
 
-#: ../Generic/fiebdc.py:2115
+#: ../Generic/fiebdc.py:2114
 msgid "End Test"
 msgstr "Comprobación finalizada"
 
@@ -687,179 +699,220 @@
 msgid "pyArq-Presupuestos running on $1"
 msgstr "pyArq-Presupuestos ejecutandose en $1"
 
-#: ../Gtk/gui.py:163
+#: ../Gtk/gui.py:167
 msgid "_File"
 msgstr "_Archivo"
 
-#: ../Gtk/gui.py:164
+#: ../Gtk/gui.py:168
 msgid "_Import Fiebdc"
 msgstr "_Importar Fiebdc"
 
-#: ../Gtk/gui.py:165
+#: ../Gtk/gui.py:169
 msgid "Import FIEBDC"
 msgstr "Importar FIEBDC"
 
-#: ../Gtk/gui.py:166
+#: ../Gtk/gui.py:170
 msgid "_Close"
 msgstr "_Cerrar"
 
-#: ../Gtk/gui.py:166
+#: ../Gtk/gui.py:170
 msgid "Close"
 msgstr "Cerrar"
 
-#: ../Gtk/gui.py:168
+#: ../Gtk/gui.py:172
 msgid "_View"
 msgstr "_Ver"
 
-#: ../Gtk/gui.py:169
+#: ../Gtk/gui.py:173
+msgid "_Go"
+msgstr "_Ir"
+
+#: ../Gtk/gui.py:174
+msgid "_Up Record"
+msgstr "Registro _Superior"
+
+#: ../Gtk/gui.py:175
+msgid "Go up record"
+msgstr "Ir al registro superior"
+
+#: ../Gtk/gui.py:176
+msgid "_Down Record"
+msgstr "Registro _Inferior"
+
+#: ../Gtk/gui.py:177
+msgid "Go down record"
+msgstr "Ir al registro inferior"
+
+#: ../Gtk/gui.py:178
+msgid "_Previous Record"
+msgstr "Registro _Previo"
+
+#: ../Gtk/gui.py:179
+msgid "Go Previous record"
+msgstr "Ir al registro previo"
+
+#: ../Gtk/gui.py:180
+msgid "_Posterior Record"
+msgstr "Registro P_osterior"
+
+#: ../Gtk/gui.py:181
+msgid "Go posterior record"
+msgstr "Ir al registro posterior"
+
+#: ../Gtk/gui.py:182
+msgid "_Root"
+msgstr "_Raiz"
+
+#: ../Gtk/gui.py:183
+msgid "Go to root"
+msgstr "Ir a la raiz"
+
+#: ../Gtk/gui.py:184
 msgid "_Test"
 msgstr "_Pruebas"
 
-#: ../Gtk/gui.py:171
+#: ../Gtk/gui.py:186
 msgid "Import Fiebdc _price database"
 msgstr "Importar base de _precios Fiebdc"
 
-#: ../Gtk/gui.py:171
+#: ../Gtk/gui.py:186
 msgid "Import database"
 msgstr "Importar base de datos"
 
-#: ../Gtk/gui.py:173
+#: ../Gtk/gui.py:188
 msgid "_Open price database"
 msgstr "_Abrir base de precios"
 
-#: ../Gtk/gui.py:174
+#: ../Gtk/gui.py:189
 msgid "Open Database"
 msgstr "Abrir base de datos"
 
-#: ../Gtk/gui.py:245
-msgid "Saving file: $1"
-msgstr "Guardando archivo: $1"
+#: ../Gtk/gui.py:308
+msgid "Cancel reading Durus database has not been implemented."
+msgstr ""
+"La interrupción de la lectura de bases de datos Durus no ha sido implementada"
 
-#: ../Gtk/gui.py:250
-msgid "Saving time: $1 seconds"
-msgstr "Tiempo de guardado: $1 segundos"
-
-#: ../Gtk/gui.py:318
-msgid "Loading file: $1:"
-msgstr "Cargando archivo: $1"
-
-#: ../Gtk/gui.py:446 ../Gtk/importFiebdc.py:224
+#: ../Gtk/gui.py:589 ../Gtk/importFiebdc.py:222
 msgid "Time: 0s"
 msgstr "Tiempo: 0s"
 
-#: ../Gtk/gui.py:510 ../Gtk/importFiebdc.py:303
+#: ../Gtk/gui.py:656 ../Gtk/importFiebdc.py:301
 msgid "Time: $1"
 msgstr "Tiempo: $1"
 
-#: ../Gtk/gui.py:787
+#: ../Gtk/gui.py:852
+msgid "The page is not in the page list"
+msgstr "La pestaña no está en la lista de pestañas"
+
+#: ../Gtk/gui.py:958
 msgid "The value must be a list"
 msgstr "El valor debe ser una lista"
 
-#: ../Gtk/gui.py:790
+#: ../Gtk/gui.py:961
 msgid "Incorrect len"
 msgstr "Longuitud incorrecta"
 
-#: ../Gtk/gui.py:818
+#: ../Gtk/gui.py:989
 msgid "Incorrect item $1"
 msgstr "Elemento incorrecto $1"
 
-#: ../Gtk/gui.py:832
+#: ../Gtk/gui.py:1005
 msgid "The budget does not have the path record: $1"
 msgstr "El presupuesto no tiene el registro con camino: $1"
 
-#: ../Gtk/gui.py:967
+#: ../Gtk/gui.py:1196
 msgid "Decomposition"
 msgstr "Descomposición"
 
-#: ../Gtk/gui.py:968 ../Gtk/gui.py:1984
+#: ../Gtk/gui.py:1197 ../Gtk/gui.py:2213
 msgid "Description"
 msgstr "Descripción"
 
-#: ../Gtk/gui.py:969 ../Gtk/gui.py:1986
+#: ../Gtk/gui.py:1198 ../Gtk/gui.py:2215
 msgid "Measure"
 msgstr "Medición"
 
-#: ../Gtk/gui.py:970
+#: ../Gtk/gui.py:1199
 msgid "Sheet of Conditions"
 msgstr "Pliego de condicones"
 
-#: ../Gtk/gui.py:971
+#: ../Gtk/gui.py:1200
 msgid "Files"
 msgstr "Archivos"
 
-#: ../Gtk/gui.py:972
+#: ../Gtk/gui.py:1201
 msgid "Companies"
 msgstr "Entidades"
 
-#: ../Gtk/gui.py:1156
+#: ../Gtk/gui.py:1385
 msgid "Split View Left/Right"
 msgstr "Partir vista Izquierda/Derecha"
 
-#: ../Gtk/gui.py:1160
+#: ../Gtk/gui.py:1389
 msgid "Split View Top/Bottom"
 msgstr "Partir vista Arriba/Abajo"
 
-#: ../Gtk/gui.py:1164
+#: ../Gtk/gui.py:1393
 msgid "Close view"
 msgstr "Cerrar vista"
 
-#: ../Gtk/gui.py:1333
+#: ../Gtk/gui.py:1562
 msgid "The item must be a widget object."
 msgstr "El elemento debe ser un objeto «widget»."
 
-#: ../Gtk/gui.py:1339
+#: ../Gtk/gui.py:1568
 msgid "Invalid orientation."
 msgstr "Orientación no válida"
 
-#: ../Gtk/gui.py:1714 ../Gtk/gui.py:2348 ../Gtk/gui.py:3758
+#: ../Gtk/gui.py:1943 ../Gtk/gui.py:2577 ../Gtk/gui.py:3987
 msgid "Argument must be a Budget object"
 msgstr "El argumento debe ser un objeto «Budget»"
 
-#: ../Gtk/gui.py:1723
+#: ../Gtk/gui.py:1952
 msgid "DecompositionList.__init__: Record path can not be None"
 msgstr "«DecompositionList.__init__:» La ruta del registro no puede ser «None»"
 
-#: ../Gtk/gui.py:1754
+#: ../Gtk/gui.py:1983
 msgid "a"
 msgstr "a"
 
-#: ../Gtk/gui.py:1981 ../Gtk/gui.py:3818
+#: ../Gtk/gui.py:2210 ../Gtk/gui.py:4047
 msgid "Code"
 msgstr "Código"
 
-#: ../Gtk/gui.py:1982
+#: ../Gtk/gui.py:2211
 msgid "Unit"
 msgstr "Unidad"
 
-#: ../Gtk/gui.py:1988
+#: ../Gtk/gui.py:2217
 msgid "Price"
 msgstr "Precio"
 
-#: ../Gtk/gui.py:1990
+#: ../Gtk/gui.py:2219
 msgid "Amount"
 msgstr "Importe"
 
-#: ../Gtk/gui.py:2002 ../Gtk/gui.py:2480
+#: ../Gtk/gui.py:2231 ../Gtk/gui.py:2709
 msgid "Invalid path"
-msgstr "Camino no válido"
+msgstr "Ruta no válida"
 
-#: ../Gtk/gui.py:2353
+#: ../Gtk/gui.py:2582
 msgid "Record path must be a tuple"
 msgstr "La posición del registro debe ser una tupla"
 
-#: ../Gtk/gui.py:2497
+#: ../Gtk/gui.py:2726
 msgid "measure must be a Measure object. Type: $1"
 msgstr "«measure» debe ser un objeto «Measure». Tipo: $1"
 
-#: ../Gtk/gui.py:2508 ../Gtk/gui.py:3833 ../Gtk/gui.py:4160
+#: ../Gtk/gui.py:2737 ../Gtk/gui.py:4062 ../Gtk/gui.py:4389
 msgid "Type"
 msgstr "Tipo"
 
-#: ../Gtk/gui.py:2509
+#: ../Gtk/gui.py:2738
 msgid "Comment"
 msgstr "Comentario"
 
-#: ../Gtk/gui.py:2510
+#: ../Gtk/gui.py:2739
 msgid ""
 "N\n"
 "(a)"
@@ -867,7 +920,7 @@
 "N\n"
 "(a)"
 
-#: ../Gtk/gui.py:2511
+#: ../Gtk/gui.py:2740
 msgid ""
 "Length\n"
 "(b)"
@@ -875,7 +928,7 @@
 "Longitud\n"
 "(b)"
 
-#: ../Gtk/gui.py:2512
+#: ../Gtk/gui.py:2741
 msgid ""
 "Width\n"
 "(c)"
@@ -883,7 +936,7 @@
 "Anchura\n"
 "(c)"
 
-#: ../Gtk/gui.py:2513
+#: ../Gtk/gui.py:2742
 msgid ""
 "Height\n"
 "(d)"
@@ -891,11 +944,11 @@
 "Altura\n"
 "(d)"
 
-#: ../Gtk/gui.py:2514
+#: ../Gtk/gui.py:2743
 msgid "Formula"
 msgstr "Fórmula"
 
-#: ../Gtk/gui.py:2515
+#: ../Gtk/gui.py:2744
 #, python-format
 msgid ""
 "Parcial\n"
@@ -904,79 +957,79 @@
 "Parcial\n"
 "[%s]"
 
-#: ../Gtk/gui.py:2516
+#: ../Gtk/gui.py:2745
 msgid "Subtotal"
 msgstr "Subtotal"
 
-#: ../Gtk/gui.py:2924 ../Gtk/gui.py:2946
+#: ../Gtk/gui.py:3153 ../Gtk/gui.py:3175
 msgid "Description text of the record $1"
 msgstr "Texto descriptivo del registro $1"
 
-#: ../Gtk/gui.py:3103
+#: ../Gtk/gui.py:3332
 msgid "Sheet of Conditions of the record $1"
 msgstr "Pliego de condiciones del registro $1"
 
-#: ../Gtk/gui.py:3123
+#: ../Gtk/gui.py:3352
 msgid "Field"
 msgstr "Ámbito"
 
-#: ../Gtk/gui.py:3145
+#: ../Gtk/gui.py:3374
 msgid "Section"
 msgstr "Sección"
 
-#: ../Gtk/gui.py:3298
+#: ../Gtk/gui.py:3527
 msgid "Sheet2 of Conditions of the record $1"
 msgstr "Pliego2 de condiciones del registro $1"
 
-#: ../Gtk/gui.py:3674
+#: ../Gtk/gui.py:3903
 msgid "$1 text"
 msgstr "Texto de $1"
 
-#: ../Gtk/gui.py:3819
+#: ../Gtk/gui.py:4048
 msgid "Code that define the company"
 msgstr "Código que define la entidad"
 
-#: ../Gtk/gui.py:3820
+#: ../Gtk/gui.py:4049
 msgid "Summary"
 msgstr "Resumen"
 
-#: ../Gtk/gui.py:3821
+#: ../Gtk/gui.py:4050
 msgid "Summary of the company name"
 msgstr "Resumen del nombre de la entidad"
 
-#: ../Gtk/gui.py:3822 ../Gtk/gui.py:3838
+#: ../Gtk/gui.py:4051 ../Gtk/gui.py:4067
 msgid "Name"
 msgstr "Nombre"
 
-#: ../Gtk/gui.py:3823
+#: ../Gtk/gui.py:4052
 msgid "Complete name"
 msgstr "Nombre completo"
 
-#: ../Gtk/gui.py:3824
+#: ../Gtk/gui.py:4053
 msgid "CIF"
 msgstr "CIF"
 
-#: ../Gtk/gui.py:3825
+#: ../Gtk/gui.py:4054
 msgid "Fiscal identifier number"
 msgstr "Número de identificación fiscal"
 
-#: ../Gtk/gui.py:3826
+#: ../Gtk/gui.py:4055
 msgid "Web"
 msgstr "Web"
 
-#: ../Gtk/gui.py:3827
+#: ../Gtk/gui.py:4056
 msgid "Company web page"
 msgstr "Página web de la entidad"
 
-#: ../Gtk/gui.py:3828
+#: ../Gtk/gui.py:4057
 msgid "Email"
 msgstr "Email"
 
-#: ../Gtk/gui.py:3829
+#: ../Gtk/gui.py:4058
 msgid "Company email"
 msgstr "Correo electrónico de la entidad"
 
-#: ../Gtk/gui.py:3834
+#: ../Gtk/gui.py:4063
 msgid ""
 "Type of Office:\n"
 "                           C: Central office\n"
@@ -988,154 +1041,158 @@
 "                           D: Delegación\n"
 "                           R: Representante"
 
-#: ../Gtk/gui.py:3839
+#: ../Gtk/gui.py:4068
 msgid "Office name"
 msgstr "Nombre de la oficina"
 
-#: ../Gtk/gui.py:3840
+#: ../Gtk/gui.py:4069
 msgid "Address"
 msgstr "Dirección"
 
-#: ../Gtk/gui.py:3841
+#: ../Gtk/gui.py:4070
 msgid "Postal code"
 msgstr "Código postal"
 
-#: ../Gtk/gui.py:3842
+#: ../Gtk/gui.py:4071
 msgid "Town"
 msgstr "Ciudad"
 
-#: ../Gtk/gui.py:3843
+#: ../Gtk/gui.py:4072
 msgid "Province"
 msgstr "Provincia"
 
-#: ../Gtk/gui.py:3844
+#: ../Gtk/gui.py:4073
 msgid "Country"
 msgstr "Ciudad"
 
-#: ../Gtk/gui.py:3845
+#: ../Gtk/gui.py:4074
 msgid "Phone"
 msgstr "Teléfono"
 
-#: ../Gtk/gui.py:3846
+#: ../Gtk/gui.py:4075
 msgid "Phone numbers of the office"
 msgstr "Teléfono de la officina"
 
-#: ../Gtk/gui.py:3847
+#: ../Gtk/gui.py:4076
 msgid "Fax"
 msgstr "Fax"
 
-#: ../Gtk/gui.py:3848
+#: ../Gtk/gui.py:4077
 msgid "Fax numbers of the office"
 msgstr "Fax de la oficina"
 
-#: ../Gtk/gui.py:3849
+#: ../Gtk/gui.py:4078
 msgid "Contact person"
 msgstr "Persona de contacto"
 
-#: ../Gtk/gui.py:3850
+#: ../Gtk/gui.py:4079
 msgid "Contact persons in the office"
 msgstr "Persona de contacto en la oficina"
 
-#: ../Gtk/gui.py:3854
+#: ../Gtk/gui.py:4083
 msgid "Unknow Option Type"
 msgstr "Tipo de opcion desconocida"
 
-#: ../Gtk/gui.py:4098
+#: ../Gtk/gui.py:4327
 msgid "Boolean"
 msgstr "Booleano"
 
-#: ../Gtk/gui.py:4099
+#: ../Gtk/gui.py:4328
 msgid "Integer"
 msgstr "Entero"
 
-#: ../Gtk/gui.py:4100
+#: ../Gtk/gui.py:4329
 msgid "Text"
 msgstr "Texto"
 
-#: ../Gtk/gui.py:4101
+#: ../Gtk/gui.py:4330
 msgid "Color"
 msgstr "Color"
 
-#: ../Gtk/gui.py:4102
+#: ../Gtk/gui.py:4331
 msgid "List"
 msgstr "Lista"
 
-#: ../Gtk/gui.py:4134
+#: ../Gtk/gui.py:4363
 msgid "Option name"
 msgstr "Nombre de Opción"
 
-#: ../Gtk/gui.py:4147
+#: ../Gtk/gui.py:4376
 msgid "Value"
 msgstr "Valor"
 
-#: ../Gtk/gui.py:4185
+#: ../Gtk/gui.py:4414
 msgid "Description:"
 msgstr "Descripción:"
 
-#: ../Gtk/gui.py:4347
+#: ../Gtk/gui.py:4576
 msgid "Option values must be strings"
 msgstr "Los valores de la opción deben ser cadenas"
 
-#: ../Gtk/gui.py:4349
+#: ../Gtk/gui.py:4578
 msgid "Option must be a tuple with 4 items"
 msgstr "La opcion debe ser una tupla de 4 elementos"
 
-#: ../Gtk/gui.py:4351
+#: ../Gtk/gui.py:4580
 msgid "Option list must be a list"
 msgstr "La lista de opciones debe ser una lista lista"
 
-#: ../Gtk/gui.py:4371
+#: ../Gtk/gui.py:4600
 msgid "Icorrect type, must be boolean"
 msgstr "Tipo erroneo, debe ser booleano"
 
-#: ../Gtk/gui.py:4376
+#: ../Gtk/gui.py:4605
 msgid "Icorrect type, must be integer"
 msgstr "Tipo erroneo, debe ser un número entero"
 
-#: ../Gtk/gui.py:4389
+#: ../Gtk/gui.py:4618
 msgid "Icorrect type, must be string"
 msgstr "Tipo erroneo, debe ser una cadena de texto"
 
-#: ../Gtk/gui.py:4402
+#: ../Gtk/gui.py:4631
 msgid "Icorrect type, must be list"
 msgstr "Tipo erroneo, debe ser una lista"
 
-#: ../Gtk/gui.py:4408
+#: ../Gtk/gui.py:4637
 msgid "Icorrect type, must be a parseable color"
 msgstr "Tipo erroneo, debe ser un color parseable"
 
-#: ../Gtk/gui.py:4416
+#: ../Gtk/gui.py:4645
 msgid "Type must be boolean, integer, string or color"
 msgstr "El tipo debe ser booleano, entero, cadena de texto o color"
 
-#: ../Gtk/gui.py:4419
+#: ../Gtk/gui.py:4648
 msgid "Value must be in the option dict"
 msgstr "El valor debe estar en el diccionario de opciones"
 
-#: ../Gtk/gui.py:4421
+#: ../Gtk/gui.py:4650
 msgid "Values must be a dict"
 msgstr "El valor debe ser un dicionario"
 
-#: ../Gtk/gui.py:4479
-msgid "No file selected"
-msgstr "Ningún fichero seleccionado"
-
-#: ../Gtk/gui.py:4481
-msgid "The filename must have durus extension"
-msgstr "El nombre del archivo debe tener extensión «durus»"
-
-#: ../Gtk/importFiebdc.py:89
+#: ../Gtk/importFiebdc.py:91
 msgid "Open File"
 msgstr "Abrir archivo"
 
-#: ../Gtk/importFiebdc.py:139
+#: ../Gtk/importFiebdc.py:137
 msgid "The file must have 'bc3' extension"
 msgstr "El archivo debe tener extensión «bc3»"
 
-#: ../Gtk/importFiebdc.py:212
+#: ../Gtk/importFiebdc.py:139
+msgid "The file must have 'durus' extension"
+msgstr "El nombre del archivo debe tener extensión «durus»"
+
+#: ../Gtk/importFiebdc.py:210
 msgid "Loading file ..."
 msgstr "Cargando archivo ..."
 
-#: ../Gtk/importFiebdc.py:236
+#: ../Gtk/importFiebdc.py:234
 msgid "Cancel"
 msgstr "Cancelar"
+
+#: ../Gtk/importFiebdc.py:439
+msgid "Saving file: $1"
+msgstr "Guardando archivo: $1"
+
+#: ../Gtk/importFiebdc.py:444
+msgid "Saving time: $1 seconds"
+msgstr "Tiempo de guardado: $1 segundos"
--- a/mo/pyArq-Presupuestos.pot	Sat Nov 06 22:33:32 2010 +0100
+++ b/mo/pyArq-Presupuestos.pot	Thu Nov 11 23:22:35 2010 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-10-31 20:54+0100\n"
+"POT-Creation-Date: 2010-11-11 23:10+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -517,6 +517,18 @@
 "OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
 msgstr ""
 
+#: ../Generic/durusdatabase.py:48
+msgid "Incorrent Base version"
+msgstr ""
+
+#: ../Generic/durusdatabase.py:77
+msgid "Loading file: $1:"
+msgstr ""
+
+#: ../Generic/durusdatabase.py:82
+msgid "Loadig time: $1 seconds"
+msgstr ""
+
 #: ../Generic/fiebdc.py:151
 msgid "Invalid code, it must be a string"
 msgstr ""
@@ -599,47 +611,47 @@
 msgid "PyArq hates parametric DLLs"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1980
+#: ../Generic/fiebdc.py:1979
 msgid "Loading file $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2000
+#: ../Generic/fiebdc.py:1999
 msgid "This codepage do not exist in FIEBDC3! Default codepage: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2004
+#: ../Generic/fiebdc.py:2003
 msgid "This V record dot have a codepage! Default codepage: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2008
+#: ../Generic/fiebdc.py:2007
 msgid "Not 'V' record in File! Default codepage: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2049
-msgid "Cancelled process"
+#: ../Generic/fiebdc.py:2048
+msgid "Process terminated"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2052
+#: ../Generic/fiebdc.py:2051
 msgid "Time to load: $1 seconds"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2054
+#: ../Generic/fiebdc.py:2053
 msgid "Records/Valid Records: $1/$2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2057
+#: ../Generic/fiebdc.py:2056
 msgid "$1 unsuported record type O: Comercial Relationship"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2060
+#: ../Generic/fiebdc.py:2059
 msgid "This file is not a valid FIBDC3 file"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2097
+#: ../Generic/fiebdc.py:2096
 msgid "Testing budget ..."
 msgstr ""
 
-#: ../Generic/fiebdc.py:2115
+#: ../Generic/fiebdc.py:2114
 msgid "End Test"
 msgstr ""
 
@@ -651,286 +663,326 @@
 msgid "pyArq-Presupuestos running on $1"
 msgstr ""
 
-#: ../Gtk/gui.py:163
+#: ../Gtk/gui.py:167
 msgid "_File"
 msgstr ""
 
-#: ../Gtk/gui.py:164
+#: ../Gtk/gui.py:168
 msgid "_Import Fiebdc"
 msgstr ""
 
-#: ../Gtk/gui.py:165
+#: ../Gtk/gui.py:169
 msgid "Import FIEBDC"
 msgstr ""
 
-#: ../Gtk/gui.py:166
+#: ../Gtk/gui.py:170
 msgid "_Close"
 msgstr ""
 
-#: ../Gtk/gui.py:166
+#: ../Gtk/gui.py:170
 msgid "Close"
 msgstr ""
 
-#: ../Gtk/gui.py:168
+#: ../Gtk/gui.py:172
 msgid "_View"
 msgstr ""
 
-#: ../Gtk/gui.py:169
-msgid "_Test"
-msgstr ""
-
-#: ../Gtk/gui.py:171
-msgid "Import Fiebdc _price database"
-msgstr ""
-
-#: ../Gtk/gui.py:171
-msgid "Import database"
-msgstr ""
-
 #: ../Gtk/gui.py:173
-msgid "_Open price database"
+msgid "_Go"
 msgstr ""
 
 #: ../Gtk/gui.py:174
+msgid "_Up Record"
+msgstr ""
+
+#: ../Gtk/gui.py:175
+msgid "Go up record"
+msgstr ""
+
+#: ../Gtk/gui.py:176
+msgid "_Down Record"
+msgstr ""
+
+#: ../Gtk/gui.py:177
+msgid "Go down record"
+msgstr ""
+
+#: ../Gtk/gui.py:178
+msgid "_Previous Record"
+msgstr ""
+
+#: ../Gtk/gui.py:179
+msgid "Go Previous record"
+msgstr ""
+
+#: ../Gtk/gui.py:180
+msgid "_Posterior Record"
+msgstr ""
+
+#: ../Gtk/gui.py:181
+msgid "Go posterior record"
+msgstr ""
+
+#: ../Gtk/gui.py:182
+msgid "_Root"
+msgstr ""
+
+#: ../Gtk/gui.py:183
+msgid "Go to root"
+msgstr ""
+
+#: ../Gtk/gui.py:184
+msgid "_Test"
+msgstr ""
+
+#: ../Gtk/gui.py:186
+msgid "Import Fiebdc _price database"
+msgstr ""
+
+#: ../Gtk/gui.py:186
+msgid "Import database"
+msgstr ""
+
+#: ../Gtk/gui.py:188
+msgid "_Open price database"
+msgstr ""
+
+#: ../Gtk/gui.py:189
 msgid "Open Database"
 msgstr ""
 
-#: ../Gtk/gui.py:245
-msgid "Saving file: $1"
+#: ../Gtk/gui.py:308
+msgid "Cancel reading Durus database has not been implemented."
 msgstr ""
 
-#: ../Gtk/gui.py:250
-msgid "Saving time: $1 seconds"
-msgstr ""
-
-#: ../Gtk/gui.py:318
-msgid "Loading file: $1:"
-msgstr ""
-
-#: ../Gtk/gui.py:446 ../Gtk/importFiebdc.py:224
+#: ../Gtk/gui.py:589 ../Gtk/importFiebdc.py:222
 msgid "Time: 0s"
 msgstr ""
 
-#: ../Gtk/gui.py:510 ../Gtk/importFiebdc.py:303
+#: ../Gtk/gui.py:656 ../Gtk/importFiebdc.py:301
 msgid "Time: $1"
 msgstr ""
 
-#: ../Gtk/gui.py:787
+#: ../Gtk/gui.py:852
+msgid "The page is not in the page list"
+msgstr ""
+
+#: ../Gtk/gui.py:958
 msgid "The value must be a list"
 msgstr ""
 
-#: ../Gtk/gui.py:790
+#: ../Gtk/gui.py:961
 msgid "Incorrect len"
 msgstr ""
 
-#: ../Gtk/gui.py:818
+#: ../Gtk/gui.py:989
 msgid "Incorrect item $1"
 msgstr ""
 
-#: ../Gtk/gui.py:832
+#: ../Gtk/gui.py:1005
 msgid "The budget does not have the path record: $1"
 msgstr ""
 
-#: ../Gtk/gui.py:967
+#: ../Gtk/gui.py:1196
 msgid "Decomposition"
 msgstr ""
 
-#: ../Gtk/gui.py:968 ../Gtk/gui.py:1984
+#: ../Gtk/gui.py:1197 ../Gtk/gui.py:2213
 msgid "Description"
 msgstr ""
 
-#: ../Gtk/gui.py:969 ../Gtk/gui.py:1986
+#: ../Gtk/gui.py:1198 ../Gtk/gui.py:2215
 msgid "Measure"
 msgstr ""
 
-#: ../Gtk/gui.py:970
+#: ../Gtk/gui.py:1199
 msgid "Sheet of Conditions"
 msgstr ""
 
-#: ../Gtk/gui.py:971
+#: ../Gtk/gui.py:1200
 msgid "Files"
 msgstr ""
 
-#: ../Gtk/gui.py:972
+#: ../Gtk/gui.py:1201
 msgid "Companies"
 msgstr ""
 
-#: ../Gtk/gui.py:1156
+#: ../Gtk/gui.py:1385
 msgid "Split View Left/Right"
 msgstr ""
 
-#: ../Gtk/gui.py:1160
+#: ../Gtk/gui.py:1389
 msgid "Split View Top/Bottom"
 msgstr ""
 
-#: ../Gtk/gui.py:1164
+#: ../Gtk/gui.py:1393
 msgid "Close view"
 msgstr ""
 
-#: ../Gtk/gui.py:1333
+#: ../Gtk/gui.py:1562
 msgid "The item must be a widget object."
 msgstr ""
 
-#: ../Gtk/gui.py:1339
+#: ../Gtk/gui.py:1568
 msgid "Invalid orientation."
 msgstr ""
 
-#: ../Gtk/gui.py:1714 ../Gtk/gui.py:2348 ../Gtk/gui.py:3758
+#: ../Gtk/gui.py:1943 ../Gtk/gui.py:2577 ../Gtk/gui.py:3987
 msgid "Argument must be a Budget object"
 msgstr ""
 
-#: ../Gtk/gui.py:1723
+#: ../Gtk/gui.py:1952
 msgid "DecompositionList.__init__: Record path can not be None"
 msgstr ""
 
-#: ../Gtk/gui.py:1754
+#: ../Gtk/gui.py:1983
 msgid "a"
 msgstr ""
 
-#: ../Gtk/gui.py:1981 ../Gtk/gui.py:3818
+#: ../Gtk/gui.py:2210 ../Gtk/gui.py:4047
 msgid "Code"
 msgstr ""
 
-#: ../Gtk/gui.py:1982
+#: ../Gtk/gui.py:2211
 msgid "Unit"
 msgstr ""
 
-#: ../Gtk/gui.py:1988
+#: ../Gtk/gui.py:2217
 msgid "Price"
 msgstr ""
 
-#: ../Gtk/gui.py:1990
+#: ../Gtk/gui.py:2219
 msgid "Amount"
 msgstr ""
 
-#: ../Gtk/gui.py:2002 ../Gtk/gui.py:2480
+#: ../Gtk/gui.py:2231 ../Gtk/gui.py:2709
 msgid "Invalid path"
 msgstr ""
 
-#: ../Gtk/gui.py:2353
+#: ../Gtk/gui.py:2582
 msgid "Record path must be a tuple"
 msgstr ""
 
-#: ../Gtk/gui.py:2497
+#: ../Gtk/gui.py:2726
 msgid "measure must be a Measure object. Type: $1"
 msgstr ""
 
-#: ../Gtk/gui.py:2508 ../Gtk/gui.py:3833 ../Gtk/gui.py:4160
+#: ../Gtk/gui.py:2737 ../Gtk/gui.py:4062 ../Gtk/gui.py:4389
 msgid "Type"
 msgstr ""
 
-#: ../Gtk/gui.py:2509
+#: ../Gtk/gui.py:2738
 msgid "Comment"
 msgstr ""
 
-#: ../Gtk/gui.py:2510
+#: ../Gtk/gui.py:2739
 msgid ""
 "N\n"
 "(a)"
 msgstr ""
 
-#: ../Gtk/gui.py:2511
+#: ../Gtk/gui.py:2740
 msgid ""
 "Length\n"
 "(b)"
 msgstr ""
 
-#: ../Gtk/gui.py:2512
+#: ../Gtk/gui.py:2741
 msgid ""
 "Width\n"
 "(c)"
 msgstr ""
 
-#: ../Gtk/gui.py:2513
+#: ../Gtk/gui.py:2742
 msgid ""
 "Height\n"
 "(d)"
 msgstr ""
 
-#: ../Gtk/gui.py:2514
+#: ../Gtk/gui.py:2743
 msgid "Formula"
 msgstr ""
 
-#: ../Gtk/gui.py:2515
+#: ../Gtk/gui.py:2744
 #, python-format
 msgid ""
 "Parcial\n"
 "[%s]"
 msgstr ""
 
-#: ../Gtk/gui.py:2516
+#: ../Gtk/gui.py:2745
 msgid "Subtotal"
 msgstr ""
 
-#: ../Gtk/gui.py:2924 ../Gtk/gui.py:2946
+#: ../Gtk/gui.py:3153 ../Gtk/gui.py:3175
 msgid "Description text of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:3103
+#: ../Gtk/gui.py:3332
 msgid "Sheet of Conditions of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:3123
+#: ../Gtk/gui.py:3352
 msgid "Field"
 msgstr ""
 
-#: ../Gtk/gui.py:3145
+#: ../Gtk/gui.py:3374
 msgid "Section"
 msgstr ""
 
-#: ../Gtk/gui.py:3298
+#: ../Gtk/gui.py:3527
 msgid "Sheet2 of Conditions of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:3674
+#: ../Gtk/gui.py:3903
 msgid "$1 text"
 msgstr ""
 
-#: ../Gtk/gui.py:3819
+#: ../Gtk/gui.py:4048
 msgid "Code that define the company"
 msgstr ""
 
-#: ../Gtk/gui.py:3820
+#: ../Gtk/gui.py:4049
 msgid "Summary"
 msgstr ""
 
-#: ../Gtk/gui.py:3821
+#: ../Gtk/gui.py:4050
 msgid "Summary of the company name"
 msgstr ""
 
-#: ../Gtk/gui.py:3822 ../Gtk/gui.py:3838
+#: ../Gtk/gui.py:4051 ../Gtk/gui.py:4067
 msgid "Name"
 msgstr ""
 
-#: ../Gtk/gui.py:3823
+#: ../Gtk/gui.py:4052
 msgid "Complete name"
 msgstr ""
 
-#: ../Gtk/gui.py:3824
+#: ../Gtk/gui.py:4053
 msgid "CIF"
 msgstr ""
 
-#: ../Gtk/gui.py:3825
+#: ../Gtk/gui.py:4054
 msgid "Fiscal identifier number"
 msgstr ""
 
-#: ../Gtk/gui.py:3826
+#: ../Gtk/gui.py:4055
 msgid "Web"
 msgstr ""
 
-#: ../Gtk/gui.py:3827
+#: ../Gtk/gui.py:4056
 msgid "Company web page"
 msgstr ""
 
-#: ../Gtk/gui.py:3828
+#: ../Gtk/gui.py:4057
 msgid "Email"
 msgstr ""
 
-#: ../Gtk/gui.py:3829
+#: ../Gtk/gui.py:4058
 msgid "Company email"
 msgstr ""
 
-#: ../Gtk/gui.py:3834
+#: ../Gtk/gui.py:4063
 msgid ""
 "Type of Office:\n"
 "                           C: Central office\n"
@@ -938,154 +990,158 @@
 "                           R: Performer"
 msgstr ""
 
-#: ../Gtk/gui.py:3839
+#: ../Gtk/gui.py:4068
 msgid "Office name"
 msgstr ""
 
-#: ../Gtk/gui.py:3840
+#: ../Gtk/gui.py:4069
 msgid "Address"
 msgstr ""
 
-#: ../Gtk/gui.py:3841
+#: ../Gtk/gui.py:4070
 msgid "Postal code"
 msgstr ""
 
-#: ../Gtk/gui.py:3842
+#: ../Gtk/gui.py:4071
 msgid "Town"
 msgstr ""
 
-#: ../Gtk/gui.py:3843
+#: ../Gtk/gui.py:4072
 msgid "Province"
 msgstr ""
 
-#: ../Gtk/gui.py:3844
+#: ../Gtk/gui.py:4073
 msgid "Country"
 msgstr ""
 
-#: ../Gtk/gui.py:3845
+#: ../Gtk/gui.py:4074
 msgid "Phone"
 msgstr ""
 
-#: ../Gtk/gui.py:3846
+#: ../Gtk/gui.py:4075
 msgid "Phone numbers of the office"
 msgstr ""
 
-#: ../Gtk/gui.py:3847
+#: ../Gtk/gui.py:4076
 msgid "Fax"
 msgstr ""
 
-#: ../Gtk/gui.py:3848
+#: ../Gtk/gui.py:4077
 msgid "Fax numbers of the office"
 msgstr ""
 
-#: ../Gtk/gui.py:3849
+#: ../Gtk/gui.py:4078
 msgid "Contact person"
 msgstr ""
 
-#: ../Gtk/gui.py:3850
+#: ../Gtk/gui.py:4079
 msgid "Contact persons in the office"
 msgstr ""
 
-#: ../Gtk/gui.py:3854
+#: ../Gtk/gui.py:4083
 msgid "Unknow Option Type"
 msgstr ""
 
-#: ../Gtk/gui.py:4098
+#: ../Gtk/gui.py:4327
 msgid "Boolean"
 msgstr ""
 
-#: ../Gtk/gui.py:4099
+#: ../Gtk/gui.py:4328
 msgid "Integer"
 msgstr ""
 
-#: ../Gtk/gui.py:4100
+#: ../Gtk/gui.py:4329
 msgid "Text"
 msgstr ""
 
-#: ../Gtk/gui.py:4101
+#: ../Gtk/gui.py:4330
 msgid "Color"
 msgstr ""
 
-#: ../Gtk/gui.py:4102
+#: ../Gtk/gui.py:4331
 msgid "List"
 msgstr ""
 
-#: ../Gtk/gui.py:4134
+#: ../Gtk/gui.py:4363
 msgid "Option name"
 msgstr ""
 
-#: ../Gtk/gui.py:4147
+#: ../Gtk/gui.py:4376
 msgid "Value"
 msgstr ""
 
-#: ../Gtk/gui.py:4185
+#: ../Gtk/gui.py:4414
 msgid "Description:"
 msgstr ""
 
-#: ../Gtk/gui.py:4347
+#: ../Gtk/gui.py:4576
 msgid "Option values must be strings"
 msgstr ""
 
-#: ../Gtk/gui.py:4349
+#: ../Gtk/gui.py:4578
 msgid "Option must be a tuple with 4 items"
 msgstr ""
 
-#: ../Gtk/gui.py:4351
+#: ../Gtk/gui.py:4580
 msgid "Option list must be a list"
 msgstr ""
 
-#: ../Gtk/gui.py:4371
+#: ../Gtk/gui.py:4600
 msgid "Icorrect type, must be boolean"
 msgstr ""
 
-#: ../Gtk/gui.py:4376
+#: ../Gtk/gui.py:4605
 msgid "Icorrect type, must be integer"
 msgstr ""
 
-#: ../Gtk/gui.py:4389
+#: ../Gtk/gui.py:4618
 msgid "Icorrect type, must be string"
 msgstr ""
 
-#: ../Gtk/gui.py:4402
+#: ../Gtk/gui.py:4631
 msgid "Icorrect type, must be list"
 msgstr ""
 
-#: ../Gtk/gui.py:4408
+#: ../Gtk/gui.py:4637
 msgid "Icorrect type, must be a parseable color"
 msgstr ""
 
-#: ../Gtk/gui.py:4416
+#: ../Gtk/gui.py:4645
 msgid "Type must be boolean, integer, string or color"
 msgstr ""
 
-#: ../Gtk/gui.py:4419
+#: ../Gtk/gui.py:4648
 msgid "Value must be in the option dict"
 msgstr ""
 
-#: ../Gtk/gui.py:4421
+#: ../Gtk/gui.py:4650
 msgid "Values must be a dict"
 msgstr ""
 
-#: ../Gtk/gui.py:4479
-msgid "No file selected"
-msgstr ""
-
-#: ../Gtk/gui.py:4481
-msgid "The filename must have durus extension"
-msgstr ""
-
-#: ../Gtk/importFiebdc.py:89
+#: ../Gtk/importFiebdc.py:91
 msgid "Open File"
 msgstr ""
 
-#: ../Gtk/importFiebdc.py:139
+#: ../Gtk/importFiebdc.py:137
 msgid "The file must have 'bc3' extension"
 msgstr ""
 
-#: ../Gtk/importFiebdc.py:212
+#: ../Gtk/importFiebdc.py:139
+msgid "The file must have 'durus' extension"
+msgstr ""
+
+#: ../Gtk/importFiebdc.py:210
 msgid "Loading file ..."
 msgstr ""
 
-#: ../Gtk/importFiebdc.py:236
+#: ../Gtk/importFiebdc.py:234
 msgid "Cancel"
 msgstr ""
+
+#: ../Gtk/importFiebdc.py:439
+msgid "Saving file: $1"
+msgstr ""
+
+#: ../Gtk/importFiebdc.py:444
+msgid "Saving time: $1 seconds"
+msgstr ""