diff Gtk/gui.py @ 1:2ac1551ad2ab version 0.0.0

add code
author Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>
date Sun, 31 Oct 2010 20:07:33 +0100
parents
children a221c14c3c31
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Gtk/gui.py	Sun Oct 31 20:07:33 2010 +0100
@@ -0,0 +1,4509 @@
+# -*- coding: utf-8 -*-
+## File gui.py
+## This file is part of pyArq-Presupuestos.
+##
+## Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez
+##                         <miguelangel@obraencurso.es>
+##
+## pyArq-Presupuestos is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## pyArq-Presupuestos is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+"""Gui module
+
+The MainWindow class contain the toplevel WINDOW,
+this window have a notebook with a page for each budget.
+Each budget or notebook page is showed by the Page class, this class contain
+the main widget showed in a page notebook.
+The main widget can show the budget information in several panes.
+This panes are ordened in gtk.Paned represented for the class Paned which can
+have 2 viewes represented for the View class or other gtk.Paned that have other
+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 TextWindow class show the long description of a record
+The Sheet class class show the sheet of condition information of a record
+
+The views can send signal to the others.
+All the viewes ordered in panes can be or not be connected to the others,
+if there are connecteded to the others when the user change the active code in
+one of the panes the active code change in the others.
+
+"""
+# TODO: Config file
+
+# Standar Modules
+import os
+import time
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+import weakref
+
+# pyArq-Presupuestos Modules
+from Gtk import importFiebdc
+from Generic import base
+from Generic import fiebdc
+from Generic import durusdatabase
+from Generic import utils
+from Generic import globals
+from Generic import openwith
+
+# Load default icon
+if os.path.exists(globals.getAppPath("ICON")):
+    icon = gtk.gdk.pixbuf_new_from_file(globals.getAppPath("ICON"))
+    gtk.window_set_default_icon_list(icon)
+else:
+    print utils.mapping(_("The icon file does not exist. '$1'"),
+          (globals.getAppPath("ICON"),))
+
+# Autodetect desktop
+if globals.desktop["autodetect"] is True:
+    openwith.autodetect_desktop()
+    print utils.mapping(_("pyArq-Presupuestos running on $1"),
+                        (globals.desktop["desktop"],))
+
+class MainWindow(object):
+    """gui.MainWindow:
+    
+    Description:
+        Creates and shows the main window.
+        This is the interface base class.
+    Constructor:
+        gui.MainWindow(): Returns the newly created main window instance
+    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)
+        _menuitemText(self, widget)
+        _delete_event(self, widget, event)
+        _destroy(self, widget)
+    """
+    # TODO:* Can choose open budget in new window
+    # TODO:* gtk.Action for menu and toolbar
+    # TODO:* Can choose show more than one notebook in the same window or
+    # TODO:  can show basedata notebook in a side pane
+    __ui = '''<ui>
+    <menubar name="MenuBar">
+      <menu action="File">
+        <menuitem action="ImportFiebdc"/>
+        <menuitem action="Close"/>
+      </menu>
+      <menu action="View">
+        <menuitem action="Text"/>
+      </menu>
+      <menu action="Test">
+        <menuitem action="ImportFiebdcPriceDatabase"/>
+        <menuitem action="OpenPriceDatabase"/>
+      </menu>
+    </menubar>
+    <toolbar name="ToolBar">
+      <toolitem action="ImportFiebdc"/>
+      <separator/>
+      <toolitem action="Close"/>
+      <separator name="sep1"/>
+    </toolbar>
+    </ui>'''
+
+    def __init__(self):
+        """def __init__(self)
+        
+        Initialize the atributes "__budget_list" and "__page_list" without data.
+        Creates the widgets "window" and "__notebook".
+        """
+        self.__budget_temp_list = []
+        self.__budget_list = []
+        self.__page_list = []
+        # Main window
+        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+        self.window.set_default_size(771, 570)
+        self.window.set_title("Presupuestos")
+        self.window.set_border_width(0)
+        self.window.connect("destroy", self._destroy)
+        self.window.connect("delete_event", self._delete_event)
+        # Vertical box
+        _vbox1 = gtk.VBox(False, 0)
+        self.window.add(_vbox1)
+        _vbox1.show()
+        #Uimanager
+        _uimanager = gtk.UIManager()
+        _accelgroup = _uimanager.get_accel_group()
+        self.window.add_accel_group(_accelgroup)
+        _general_action_group = gtk.ActionGroup("General")
+        self.__general_action_group = _general_action_group
+        _general_action_group.add_actions(
+            [("File", None, _("_File"), None),
+             ("ImportFiebdc", gtk.STOCK_OPEN, _('_Import Fiebdc'), "", 'NPI',
+                self._menuitemImportFiebdc),
+             ("Close", gtk.STOCK_CLOSE, _("_Close"), None, 'NPI',
+                self._menuitemClose),
+             ("View", None, _("_View")),
+             ("Text", None, _("_Text"), None, 'NPI',
+                self._menuitemText),
+             ("Test", None, _("_Test")),
+             ('ImportFiebdcPriceDatabase', gtk.STOCK_OPEN,
+                _("Import Fiebdc _price database"), "", "NPI",
+                self._menuitemImportPriceDatabase ),
+             ("OpenPriceDatabase", gtk.STOCK_OPEN, _('_Open price database'),
+                "", 'NPI', self._menuitemOpenPriceDatabase),
+            ])
+        _uimanager.insert_action_group(_general_action_group, 0)
+        _uimanager.add_ui_from_string(self.__ui)
+        _menu_bar = _uimanager.get_widget("/MenuBar")
+        _vbox1.pack_start(_menu_bar, False, False, 0)
+        _toolbar = _uimanager.get_widget("/ToolBar")
+        _toolbar.get_settings().set_long_property("gtk-toolbar-icon-size",
+            gtk.ICON_SIZE_SMALL_TOOLBAR, "pyArq-Presupuestos:toolbar")
+        _vbox1.pack_start(_toolbar, False, False, 0)
+        # Notebook
+        self.__notebook = gtk.Notebook()
+        _vbox1.pack_start(self.__notebook, True, True, 0)
+        self.__notebook.set_tab_pos(gtk.POS_TOP)
+        self.__notebook.set_show_tabs(True)
+        self.__notebook.set_show_border(True)
+        self.__notebook.set_scrollable(True)
+        self.__notebook.show()
+        self._main()
+        
+    def _main(self):
+        """def main(self)
+        
+        Shows window and starts the GTK+ event processing loop.
+        """
+        self.window.show()
+        gtk.main()
+        
+    def _addBudget(self, budget):
+        """def _addBudget(self, budget)
+        
+        budget: "base.Budget" object
+        
+        Appends a budget in the "__budget_list"
+        """
+        if budget != None:
+            _budget = budget
+            if _budget in self.__budget_temp_list:
+                self.__budget_temp_list.remove(_budget)
+            self.__budget_list.append(_budget)
+
+    def _appendPage(self):
+        """def _appendPage(self)
+        
+        Creates a new page (instance of "Page class") from the last budget in
+        __budget_list, appends this page in the "__page_list" and shows the
+        page widget in the notebook widget.
+        """
+        _last_budget = self.__budget_list[-1]
+        _page = Page(_last_budget)
+        self.__notebook.append_page(_page.widget, _page.title)
+        self.__page_list.append(_page)
+
+    def _testBudgetList2(self):
+        """def _testBudgetList2(self)
+        
+        Test if the number of budgets ("__budget_list") is greater
+        than the number of pages ("__page_list"), if it is greater 
+        appendPage method is called to create a page to show the new budget
+        and save the budget in a durus file.
+        """
+        if len(self.__budget_list) > len(self.__page_list):
+            self._appendPage()
+            #-# in test mode
+            # TODO: It must be in a thread
+            _last_budget = self.__budget_list[-1]
+            _path = globals.getHomePath("DURUS-DATABASE")
+            _file_whit_path_bc3 = _last_budget.filename
+            _filename_bc3 = _file_whit_path_bc3.split("/")[-1]
+            _filename = _filename_bc3.split(".")[-2]
+            _file = _path + _filename + ".durus"
+            print utils.mapping(_("Saving file: $1"), (_file,))
+            _time = time.time()
+            _durus_file = durusdatabase.DurusFile(_file,True)
+            _durus_file.setBudget(_last_budget)
+            _durus_file.close()
+            print utils.mapping(_("Saving time: $1 seconds"),
+                  (("%.2f" %(time.time()-_time) ),))
+            #-#
+            return False
+        return True
+
+    def _menuitemImportFiebdc(self, widget):
+        """def _menuitemImportFiebdc(self, widget)
+        
+        widget: the widget where the event is emitted from
+        Callback to open a budget file.
+        Inits a timeout to test if a budgets is appended to "__budget_list"
+        calling _testBudgetList method if it is true.
+        
+        Creates and shows a window to open a budget file.
+        """
+        _budget = base.Budget()
+        self.__budget_temp_list.append(_budget)
+        _budget_file = fiebdc.Read()
+        _read_method = _budget_file.readFile
+        _filename = "file"
+        _exit_method = _budget_file.cancel
+        _file_window = importFiebdc.FileSelectionWindow(self,
+            _read_method, _budget, _filename, _exit_method)
+
+    def _menuitemImportPriceDatabase(self, widget):
+        """def _menuitemImportPriceDatabase(self, widget)
+        
+        widget: the widget where the event is emitted from
+        Callback to open a budget file.
+        Inits a timeout to test if a budgets is appended to "__budget_list"
+        calling _testBudgetList method if it is true.
+        
+        Creates and shows a window to open a budget file.
+        """
+        #TODO: change timeout, it is deprecated
+        #TODO: the .durus file must be direted saved
+        gobject.timeout_add(100, self._testBudgetList2)
+        _budget = base.Budget()
+        self.__budget_temp_list.append(_budget)
+        _budget_file = fiebdc.Read()
+        _read_method = _budget_file.readFile
+        _filename = "file"
+        _exit_method = _budget_file.cancel
+        _file_window = importFiebdc.FileSelectionWindow(self,
+            _read_method, _budget, _filename, _exit_method)
+
+    def _menuitemOpenPriceDatabase(self, widget):
+        """def _menuitemImportPriceDatabase(self, widget)
+        
+        widget: the widget where the event is emitted from
+        Callback to open a budget file.
+        Inits a timeout to test if a budgets is appended to "__budget_list"
+        calling _testBudgetList method if it is true.
+        
+        Creates and shows a window to open a budget file.
+        """
+        _openDialog = OpenDurusDatabase(self._OpenDurusDatabase)
+        _openDialog.main()
+
+    def _OpenDurusDatabase(self, file):
+        """def _menuitemImportFiebdc(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to open a budget file from a durus file.
+        """
+        _file = file
+        print utils.mapping(_("Loading file: $1:"), (_file,))
+        _time = time.time()
+        _durus_file = durusdatabase.DurusFile(_file,False)
+        _budget = _durus_file.getBudget()
+        _durus_file.close()
+        print utils.mapping(("Loadig time: $1 seconds"),
+             (("%.2f" %(time.time()-_time)),))
+        self.__budget_list.append(_budget)
+        _page = Page(_budget)
+        self.__notebook.append_page(_page.widget, _page.title)
+        self.__page_list.append(_page)
+
+    def _menuitemClose(self, widget):
+        """def _menuitemClose(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Callback to close a budget file.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num == -1:
+            return
+        _page = self.__page_list.pop(_page_num)
+        if isinstance(_page, Page):
+            #not loading budget
+            self.__budget_list.pop(_page_num)
+        _page.clear()
+        self.__notebook.remove_page(_page_num)
+
+    def _menuitemText(self, widget):
+        """_menuitemText(self, widget)
+        
+        widget: the widget where the event is emitted from
+        
+        Creates and shows a window showing text description
+        using a instance of TextWindow class.
+        """
+        _page_num = self.__notebook.get_current_page()
+        if _page_num == -1:
+            return
+        _budget = self.__budget_list[_page_num]
+        _page = self.__page_list[_page_num]
+        _code = _page.getActiveCode()
+        _concepto = _budget.getRecord(_code)
+        _text = _concepto.text
+        _window = TextWindow(_code, _text)
+        _window.main()
+
+    def _delete_event(self, widget, event):
+        """_delete_event(self, widget, event)
+        
+        widget: the widget where the event is emitted from
+        event: the "gtk.gdk.Event"
+        
+        Method connected to "delete_event" signal of main window widget
+        This signal is emitted when a user press the close titlebar button.
+        It Returns True so the signal "destroy" is emitted.
+        """
+        for _page in self.__page_list:
+            _page.clear()
+        return False # -> destroy
+
+    def _destroy(self, widget):
+        """_destroy(self, widget)
+        
+        widget: the widget where the event is emitted from
+        Method connected to "destroy" signal of main window widget
+        
+        This signal is emited when the method connected to "delete_event"
+        signal returns True or when the program call the destroy() method of
+        the gtk.Window widget.
+        The window is closed and the GTK+ event processing loop is ended.
+        """
+        gtk.main_quit()
+
+    def getNotebook(self):
+        return self.__notebook
+    def getPageList(self):
+        return self.__page_list
+    def getBudgetList(self):
+        return self.__budget_list
+
+class EmptyPage(object):
+    """
+    """
+    def __init__(self, mainWindow, readFileMethod, budget, filename,
+                 cancelMethod):
+        """def __init__(self, mainWindow, readFileMethod, budget, filename,
+                        cancelMethod)
+        
+        """
+        self.__mainWindow = mainWindow
+        self.__readFileMethod = readFileMethod
+        self.__budget = budget
+        self.__filename = filename
+        self.__cancelMethod = cancelMethod
+        self.__children = None
+        self.__cancel = [False, False]
+        self.__progress = 0.0
+        self.__widget = gtk.VBox()
+        self.__main_item = None
+        self.__widget.show()
+        self.__throbber = gtk.Image()
+        self.__throbber.set_from_file(globals.getAppPath("THROBBER-ICON"))
+        self.__throbber.show()
+        self.__animationThobber = gtk.gdk.PixbufAnimation(
+                                  globals.getAppPath("THROBBER-GIF"))
+        self.__quietThobber = self.__throbber.get_pixbuf()
+        self.__budget_icon = gtk.gdk.pixbuf_new_from_file_at_size(
+                             globals.getAppPath("BUDGET-ICON"), 16, 16)
+        _filename = os.path.basename(filename)
+        _rootfilename = os.path.splitext(_filename)[0]
+        if not _rootfilename == "":
+            _filename = _rootfilename
+        _titleLabel = gtk.Label(_filename)
+        _titleLabel.show()
+        self.__title = gtk.HBox()
+        self.__title.add(self.__throbber)
+        self.__title.add(_titleLabel)
+        self.__statusbar = gtk.Statusbar()
+        self.__statuscontext = self.__statusbar.get_context_id("Statusbar")
+        self.__statusbar.show()
+        _align = gtk.Alignment(0.5, 0.5, 0, 0)
+        _iconVbox = gtk.VBox()
+        _pyArqIcon = gtk.Image()
+        _pyArqIcon.set_from_file(globals.getAppPath("PYARQ-ICON"))
+        _pyArqIcon.show()
+        _iconVbox.pack_start(_pyArqIcon, True, True, 0)
+        _link = gtk.LinkButton("http://pyarq.obraencurso.es",
+                               "http://pyarq.obraencurso.es")
+        _iconVbox.pack_start(_link, True, True, 0)
+        _link.show()
+        _iconVbox.show()
+        _align.add(_iconVbox)
+        _align.show()
+        self.__widget.pack_start(_align, True, True, 0)
+        _progressframe = gtk.Frame()
+        _progressframe.set_shadow_type(gtk.SHADOW_IN)
+        _progressframe.show()
+        self.__progress_bar = gtk.ProgressBar()
+        self.__progress_bar.show()
+        _progressframe.add(self.__progress_bar)
+        self.__statusbar.pack_start(_progressframe, False, False, 0)
+        self.__widget.pack_end(self.__statusbar, False, True, 0)
+        self.__main_item = None
+
+    def run(self):
+        self.__statusbar.push(self.__statuscontext, _("Time: 0s"))
+        self.__throbber.set_from_animation(self.__animationThobber)
+        self._launchChildren()
+        self._launchTimeout()
+
+    def progress(self, percent):
+        _progress = str(int(round(100 * percent,0)))
+        self.__progress = percent
+
+    def stopLoading(self):
+        self.__throbber.set_from_pixbuf(self.__budget_icon)
+        self.__progress_bar.hide()
+        self.__statusbar.pop(self.__statuscontext)
+
+    def _launchChildren(self):
+        """_launchChildren(self)
+        
+        Launch the thread to read the file
+        """
+        if self.__children is None:
+            self.__children = importFiebdc.Thread(self, self.__mainWindow,
+                self.__readFileMethod, self.__budget, self.__filename,
+                self.__cancelMethod)
+            self.__children.start()
+
+    def _launchTimeout(self):
+        """def _launchTimeout(self)
+        
+        Launch the timeouts: 
+            1- update progress bar
+            2- update time label
+            3- If the other timetouts are stoped the window is closed
+        """
+        gobject.timeout_add(500, self._updateProgressBar)
+        gobject.timeout_add(1000, self._updateLabel, time.time())
+        self.__cancel = [False, False]
+        gobject.timeout_add(1000, self._autoClose)
+
+    def _updateProgressBar(self):
+        """def _updateProgressBar(self)
+        
+        update progress bar in a timeout
+        If the thread end or is canceled the timeout is stoped
+        """
+        if  self.__children is None or self.__children.isCanceled() == True:
+            self.__cancel[0] = True
+            return False
+        else:
+            self.__progress_bar.set_fraction(self.__progress)
+            _text = "%s%%" %str(int(round(100 * self.__progress,0)))
+            self.__progress_bar.set_text(_text)
+            return True
+
+    def _updateLabel(self, _time):
+        """def _updateProgressBar(self)
+        
+        update time label in a timeout
+        If the thread end or is canceled the timeout is stoped
+        """
+        if  self.__children is None or self.__children.isCanceled() == True:
+            self.__cancel[1] = True
+            return False
+        else:
+            _time = time.time() - _time
+            _text = utils.mapping(_("Time: $1"), ("%.0f" %_time,))
+            self.__statusbar.pop(self.__statuscontext)
+            self.__statusbar.push(self.__statuscontext, _text)
+            return True
+
+    def _autoClose(self):
+        """def _updateProgressBar(self)
+        
+        If the time label and progress bar timeouts are stoped the window is 
+        closed and ist tiemeout is stoped
+        """
+        if self.__cancel == [ True, True ]:
+            return False
+        else:
+            return True
+
+    def closeWindow(self):
+        """def closeWindow(self)
+        
+        Sets the __children atribute to None
+        This causes that the timeouts is ended.
+        This method is called from thread when it is finished
+        TODO: it must called threadFinished or somethig
+        """
+        self.__children = None
+        self.stopLoading()
+        _page = Page(self.__budget)
+        _children = self.__widget.get_children()
+        for _child in _children:
+            self.__widget.remove(_child)
+        self.__widget.pack_start(_page.widget, True, True, 0)
+        _noteBook = self.__mainWindow.getNotebook()
+        _pageIndex = _noteBook.page_num(self.__widget)
+        self.__mainWindow.getPageList()[_pageIndex] = _page
+    def threadCanceled(self):
+        """def threadCanceled(self)
+        
+        Sets the __children atribute to None
+        This causes that the timeouts is ended.
+        This method is called from thread when is canceled
+        TODO: it must called threadFinished or somethig
+        """
+        self.__children = None
+        self.stopLoading()
+
+    def clear(self):
+        """def clear(self)
+        
+        Cancel thread
+        """
+        self.__children.cancel()
+        
+    def getWidget(self):
+        """def getWidget(self)
+        
+        Return de main widget to show in the page
+        """
+        return self.__widget
+
+    def getTitle(self):
+        """def getTtle(self)
+        
+        Return the title of the page, a gtk.Label objetc
+        """
+        return self.__title
+
+    widget = property(getWidget, None, None,
+                      "Main widget showed in the pane")
+    title = property(getTitle, None, None,
+                      "Page Title")
+
+class Page(object):
+    """gui.Page:
+    
+    Description:
+    It creates and shows a page in the notebook from a budget object.
+    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
+    Ancestry:
+    +-- object
+      +-- Page
+    Atributes:
+        "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 ]
+                [ "v", [ "h", pane1, pane2 ], [ "h", pane1, pane2 ] ]
+            pane types:
+                * "DecompositionList": its creates a "DecompositionList" object 
+                * "RecordDescription" : its creates a "Description" objetc
+                * "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
+    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)
+    """
+    # 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, budget=None, active_code=None)
+        
+        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
+        """
+        #TODO: __panes_list should come from config file...
+        self.__widget = gtk.VBox()
+        self.__panes_list = [ "v", "DecompositionList", [ "v", "Measure",
+            "RecordDescription" ]]
+        self.__main_item = None
+        self.setBudget(budget)
+        self.setActivePathRecord(path_record)
+        self.__widget.show()
+
+    def propagateMessageFrom(self, message, path, arg=None):
+        """def propagateMessageFrom(self, message, path, arg=None)
+        
+        message: string message
+        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
+        
+        The panes are connectted to this method to send messages to other panes
+        """
+        _budget = self.__budget
+        if message == "change_active" and _budget.hasPath(arg):
+            self.sendMessageTo(self.__main_item, message, path, arg)
+        elif message == "autoclose":
+            self._closeItem(path)
+        elif message == "split h":
+            self._splitItem(path, "h")
+        elif message == "split v":
+            self._splitItem(path, "v")
+            
+    def sendMessageTo(self, pane, message, path, arg=None):
+        """def sendMessageTo(self, pane,message, path, arg=None)
+        pane: the receiver pane
+        message: string message
+        path: tuple that represents the 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)
+
+    def clear(self):
+        """def clear(self)
+        
+        Clear atributes
+        """
+        self.propagateMessageFrom("clear", (0,))
+        
+        del self.__budget
+        del self.__panes_list
+        del self.__widget
+        del self.__title
+        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
+        """
+        _item = self.__main_item
+        if len(path) == 1:
+            return _item
+        else:
+            return _item.getItem(path[1:])
+
+    def setMainItem(self, item):
+        """setMainItem(self,item)
+        
+        Sets a new main item in the page
+        """
+        if not self.__main_item is None:
+            _old_main_widget = self.__main_item.widget
+            self.__widget.remove(_old_main_widget)
+        self.__main_item = item
+        _main_widget = self.__main_item.widget
+        _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
+        """
+        _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])
+        else:
+            self.setMainItem(_paned)
+        
+    def _closeItem(self, path):
+        """_closeItem(self, path)
+        
+        Closes the item that is identifies by the path
+        """
+        _item = self.getItem(path)
+        if len(path) > 1:
+            # There are more than one item
+            _parent = self.getItem(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])
+                _parent.widget.destroy()
+                _parent.clear()
+                _item.clear()
+            else:
+                _grandparent = self
+                _grandparent.setMainItem(_brother)
+                _parent.widget.destroy()
+                _parent.clear()
+                _item.clear()
+        else:
+            # 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,))
+        
+        list_paned: list in "__panes_list" format
+            [ "v" or "h", panel1_type, panel2_type]
+            which contains the info for create the widgets. 
+            panel types:
+                * "DecompositionList"
+                * "RecordDescription"
+                * "Measure"
+                * "Sheet of Conditions"
+                * "FileView"
+                * "CompanyView"
+        path: tuple that represents the item path in the page
+        
+        Creates the items and widgets and returns the main item
+        """
+        if not isinstance(list_paned , list):
+            raise ValueError, _("The value must be a list")
+        if list_paned[0] == "v" or  list_paned[0] == "h":
+            if len(list_paned) != 3:
+                raise ValueError, _("Incorrect len")
+            if not isinstance(list_paned[1],list):
+                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)
+        elif list_paned[0] == "DecompositionList":
+            _item = View( "DecompositionList", self.__budget,
+                weakref.ref(self), path, self.__active_path_record)
+        elif list_paned[0] == "RecordDescription":
+            _item = View( "RecordDescription", self.__budget,weakref.ref(self),
+                path, self.__active_path_record)
+        elif list_paned[0] == "Measure":
+            _item = View( "Measure", self.__budget, weakref.ref(self), path,
+                self.__active_path_record)
+        elif list_paned[0] == "Sheet of Conditions":
+            _item  = Sheet(sef.__budget, weakref.ref(self), path,
+                self.__active_path_record)
+        elif list_paned[0] == "FileView":
+            _item  = FileView(sef.__budget, weakref.ref(self), path,
+                self.__active_path_record)
+        elif list_paned[0] == "CompanyView":
+            _item  = CompanyView(sef.__budget, weakref.ref(self), path,
+                self.__active_path_record)
+        else:
+            _item = None
+            raise ValueError, utils.mapping(_("Incorrect item $1"),
+                  (str(list_paned[0]),))
+        return _item
+
+    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
+        else:
+            raise ValueError, utils.mapping(_("The budget does not have the "\
+                  "path record: $1"), (str(path_record),))
+
+    def getTitle(self):
+        """def getTtle(self)
+        
+        Return the title of the page, a gtk.Label objetc
+        """
+        return self.__title
+    
+    def getWidget(self):
+        """def getWidget(self)
+        
+        Return de main widget to show in the pane
+        """
+        return self.__widget
+    
+    def setBudget(self, budget):
+        """def setBudget(self, budget)
+        
+        budget: a base.Budget object
+        
+        Sets the budget and the active code atributes,
+        creates the page title and the widgets in the pane and
+        shows the main widget.
+        """
+        if budget is None:
+            self.clear()
+            return
+        self.__budget = budget
+        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)
+        _main_widget = self.__main_item.getWidget()
+        _main_widget.show()
+        self.__widget.pack_start(_main_widget, True, True, 0)
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        Return de budget, a "base.Budget" object.
+        """
+        return self.__budget
+    
+    def getPanesList(self):
+        """def getPanesList(self)
+        
+        Return the panes list, info list for create the panes.
+        """
+        return self.__panes_list
+    
+    budget = property(getBudget, setBudget, None,
+                      "Budget to show, base.Budget object")
+    widget = property(getWidget, None, None,
+                      "Main widget showed in the pane")
+    title = property(getTitle, None, None,
+                      "Page Title")
+    panes_list = property(getPanesList, None, None,
+                      "Info list for create the panes")
+
+class View(object):
+    """gui.View:
+    
+    Description:
+        It creates a view to show the budget info
+    Constructor:
+        View(view_type, budget, wr_page, path, active_path_record)
+    Ancestry:
+    +-- object
+      +-- Paned
+    Atributes:
+        "path": the tuple that identifies the view in the main notebook page
+        "widget": the main gtk widget to show in a view object,
+            a gtk.VBox object
+        "__view_type": the object type to show
+            * DecompositionList
+            * Description
+            * Measure
+            * Sheet of conditions
+            * FileView
+            * CompanyView
+        "__wr_page": weak reference to the page where the view must be showed
+        "__budget": the budget to show
+        "__view ": the object to show:
+            * DecompositionList object
+            * Description object
+            * Measure object
+            * Sheet object
+            * FileView object
+            * Comapany View
+        "__connected": boolean value, True means that the View object sends and
+            receives signals from/to others views
+        "__connected_button": a button to switch __connected True or False
+    Methods:
+        __init__(self)
+        getItem(self, path)
+        _closeItem(self, close_button)
+        _change_combo(self, combobox)
+        propagateMessgeFrom(self, message, path, arg=None)
+        runMessage(self, message, path, arg=None)
+        getWidget(self)
+        getPath(self)
+        setPath(self)
+        getClone(self, newpath)
+        clear(self)
+    """
+    def __init__(self, view_type, budget, wr_page, path, active_path_record):
+
+        """def __init__(self, view_type, budget, wr_page, path,
+                        active_path_record)
+        view_type: the object type to show
+            * DecompositionList
+            * Description
+            * Measure
+            * Sheet
+            * FileView
+            * CompanyView
+        budget: the budget to show
+        wr_page: weak reference to the page where the view must be showed
+        path: the position or path of the view in the page notebook
+        active_path_record: the record path that must be showed
+        
+        Creates and shows a new view
+        """
+        self.__active_path_record = active_path_record
+        self.__view_type = view_type
+        self.__wr_page = wr_page
+        self.__budget = budget
+        self.__path = path
+        self.__connected = True
+        # view_type liststore
+        _liststore = gtk.ListStore(str)
+        _liststore.append([_("Decomposition")]) #0
+        _liststore.append([_("Description")]) #1
+        _liststore.append([_("Measure")]) #2
+        _liststore.append([_("Sheet of Conditions")]) #3
+        _liststore.append([_("Files")]) #4
+        _liststore.append([_("Companies")]) #5
+        _combobox = gtk.ComboBox(_liststore)
+        _cell = gtk.CellRendererText()
+        _combobox.pack_start(_cell, True)
+        _combobox.add_attribute(_cell, 'text', 0)
+        _vbox = gtk.VBox()
+        _vbox.show()
+        _toolitem = gtk.ToolItem()
+        _toolitem.set_expand(True)
+        _toolitem.add(_vbox)
+        _toolitem.show()
+        self.__widget = gtk.Toolbar()
+        self.__widget.insert(_toolitem, 0)
+        _hbox = gtk.HBox()
+        if view_type == "DecompositionList":
+            self.__view = DecompositionList(budget, weakref.ref(self),
+                          path, active_path_record)
+            _combobox.set_active(0)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("DECOMPOSITION-ICON"))
+        elif view_type == "RecordDescription":
+            self.__view = Description(budget, weakref.ref(self),
+                          path, active_path_record)
+            _combobox.set_active(1)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("DESCRIPTION-ICON"))
+        elif view_type == "Measure":
+            self.__view = Measure(budget, weakref.ref(self),
+                          path, active_path_record)
+            _combobox.set_active(2)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("MEASURE-ICON"))
+        elif view_type == "Sheet of Conditions":
+            self.__view = Sheet(budget, weakref.ref(self),
+                          path, active_path_record)
+            _combobox.set_active(3)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+        elif view_type == "FileView":
+            self.__view = FileView(budget, weakref.ref(self),
+                          path, active_path_record)
+            _combobox.set_active(4)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+        elif view_type == "CompanyView":
+            self.__view = CompanyView(budget, weakref.ref(self), path,
+                          active_path_record)
+            _combobox.set_active(5)
+            _view_icon = gtk.Image()
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+            
+        else:
+            raise ValueError, _(utils.mapping("Invalid type of View: $1",
+                  view_type))
+        _view_icon.show()
+        _combobox.connect("changed", self._change_combo)
+        _combobox.show()
+        _vbox.pack_start(_hbox,False)
+        _vbox.pack_start(self.__view.widget, True, True)
+        _hbox.pack_start(_view_icon, False, False,0)
+        _hbox.pack_start(_combobox, False, False,0)
+        _invisible = gtk.HBox()
+        _invisible.show()
+        _hbox.pack_start(_invisible, True, False,0)
+        _icon_menu = gtk.Image()
+        _icon_menu.set_from_file(globals.getAppPath("MENU-ICON"))
+        _icon_menu.show()
+        _menu_button = gtk.ToolButton()
+        _menu_button.set_icon_widget(_icon_menu)
+        _menu_button.connect("clicked", self._menu_view)
+        _menu_button.show()
+        _icon_connected = gtk.Image()
+        _icon_connected.set_from_file(globals.getAppPath("CONNECTED-ICON"))
+        _icon_connected.show()
+        _hbox.pack_start(_menu_button, False, False, 0)
+        self.__connected_button = gtk.ToolButton()
+        self.__connected_button.set_icon_widget(_icon_connected)
+        self.__connected_button.connect("clicked", self._connected)
+        self.__connected_button.show()
+        _hbox.pack_start(self.__connected_button, False, False, 0)
+        _icon_close = gtk.Image()
+        _icon_close.set_from_file(globals.getAppPath("CLOSE-ICON"))
+        _icon_close.show()
+        _close_button = gtk.ToolButton()
+        _close_button.set_icon_widget(_icon_close)
+        _close_button.connect("clicked", self._closeItem)
+        _close_button.show()
+        _hbox.pack_start(_close_button, False, False, 0)
+        _hbox.show()
+        self.__widget.show()
+
+    def getItem(self, path):
+        """def getItem(self, path)
+        
+        Return itself.
+        """
+        return self
+
+    def _closeItem(self, close_button):
+        """_closeItem(self, widget)
+        
+        Method connected to the "clicked" signal of the _close_button widget
+        Send the "autoclose" message to the page to close this view
+        """
+        self.propagateMessageFrom( "autoclose", self.__path)
+
+    def _change_combo(self, combobox):
+        """_change_combo(self, combobox)
+        
+        Method connected to the "changed" signal of the _combobox widget
+        It changes the view type to the type selected in the combobox
+        """
+        _index = combobox.get_active()
+        _budget = self.__view.budget
+        _wr_page = self.__view.page
+        _path = self.__view.path
+        _path_record = self.__view.active_path_record
+        _toolitem = self.__widget.get_nth_item(0)
+        _vbox= _toolitem.get_children()[0]
+        _hbox = _vbox.get_children()[0]
+        _combobox = _hbox.get_children()[1]
+        _hbox.remove(_combobox)
+        _invisible = _hbox.get_children()[1]
+        _hbox.remove(_invisible)
+        _menu_button = _hbox.get_children()[1]
+        _hbox.remove(_menu_button)
+        _connected_button = _hbox.get_children()[1]
+        _hbox.remove(_connected_button)
+        _close_button = _hbox.get_children()[1]
+        _hbox.remove(_close_button)
+        _vbox.remove(self.__view.widget)
+        _vbox.remove(_hbox)
+        _hbox.destroy()
+        _view_icon = gtk.Image()
+        if _index == 0:
+            self.__view = DecompositionList(_budget, _wr_page, _path,
+                          _path_record)
+                        
+            _view_icon.set_from_file(globals.getAppPath("DECOMPOSITION-ICON"))
+            self.__view_type = "DecompositionList"
+        elif _index == 1:
+            self.__view = Description(_budget, _wr_page, _path,
+                         _path_record)
+            _view_icon.set_from_file(globals.getAppPath("DESCRIPTION-ICON"))
+            self.__view_type = "RecordDescription"
+        elif _index == 2:
+            self.__view = Measure(_budget, _wr_page, _path,
+                         _path_record)
+            _view_icon.set_from_file(globals.getAppPath("MEASURE-ICON"))
+            self.__view_type = "Measure"
+        elif _index == 3:
+            self.__view = Sheet(_budget, _wr_page, _path,
+                         _path_record)
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+            self.__view_type = "Sheet of Conditions"
+        elif _index == 4:
+            self.__view = FileView(_budget, _wr_page, _path,
+                         _path_record)
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+            self.__view_type = "FileView"
+        elif _index == 5:
+            self.__view = CompanyView(_budget, _wr_page, _path,
+                          _path_record)
+            _view_icon.set_from_file(globals.getAppPath("SHEET-ICON"))
+            self.__view_type = "CompanyView"
+        _view_icon.show()
+        _hbox = gtk.HBox()
+        _hbox.pack_start(_view_icon, False, False,0)
+        _hbox.pack_start(_combobox, False, False,0)
+        _hbox.pack_start(_invisible, True, False,0)
+        _hbox.pack_start(_menu_button, False, False, 0)
+        _hbox.pack_start(_connected_button, False, False, 0)
+        _hbox.pack_start(_close_button, False, False, 0)
+        _hbox.show()
+        _vbox.pack_start(_hbox, False, False, 0)
+        _vbox.pack_start(self.__view.widget, True, True, 0)
+
+    def _menu_view(self, widget):
+        """_menu_view(self, widget)
+        
+        Method connected to the "clicked" signal of the __connected_button
+        It shows a popup menu with some options
+        """
+        _menu_view = gtk.Menu()
+        _item_leftright = gtk.MenuItem("Split View Left/Right")
+        _menu_view.append(_item_leftright)
+        _item_leftright.connect_object("activate", self._split_view, "h")
+        _item_leftright.show()
+        _item_topbottom = gtk.MenuItem("Split View Top/Bottom")
+        _menu_view.append(_item_topbottom)
+        _item_topbottom.connect_object("activate", self._split_view, "v")
+        _item_topbottom.show()
+        _item_close = gtk.MenuItem("close view")
+        _menu_view.append(_item_close)
+        _item_close.connect_object("activate", self._closeItem, None)
+        _item_close.show()
+        _menu_view.popup(None, None, None, 0, 0)
+        
+    def _split_view(self, orientation):
+        """_menu_view(self, orientation)
+        
+        orientation: orientation split, "h" or "v"
+        
+        Method connected to the "activate" signal of the _item_leftright and
+        _item_topbottom menu items.
+        It sends the "split" message to the page to splits the view in the
+        specified orientation
+        """
+        self.propagateMessageFrom( "split " + orientation, self.__path)
+
+    def _connected(self, widget):
+        """_connected(self, widget)
+        
+        Method connected to the "clicked" signal of the _menu_button
+        It changes the __connected atribute to True or False, if the 
+        _connected atribute is False the view do not send and receive messages
+        to/from others views
+        """
+        if self.__connected:
+            _icon = gtk.Image()
+            _icon.set_from_file(globals.getAppPath("DISCONNECTED-ICON"))
+            _icon.show()
+            self.__connected_button.set_icon_widget(_icon)
+            self.__connected = False
+        else:
+            _icon = gtk.Image()
+            _icon.set_from_file(globals.getAppPath("CONNECTED-ICON"))
+            _icon.show()
+            self.__connected_button.set_icon_widget(_icon)
+            self.__connected = True
+
+    def propagateMessageFrom(self, message, path, arg=None):
+        """def propagateMessageFrom(self, message, path, arg=None)
+        
+        message: string message
+        path: tuple that represents the pane path which emits the message
+        arg: arguments for the message
+        The panes are connectted to this method to send messages to other panes
+        """
+        if self.__connected or message == "autoclose" or \
+           message == "split h" or message == "split v":
+            self.__wr_page().propagateMessageFrom(message, path, arg)
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        if self.__connected:
+            self.__view.runMessage(message, path, arg)
+            if message == "change_active":
+                if self.__budget.hasPath(arg):
+                    _path_record = arg
+                    self.__active_path_record = _path_record
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        Return de pane widget
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__view.path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        set the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+        self.__view.path = path
+
+    def getClone(self, new_path):
+        """getClone(self, new_path)
+        
+        new_path: the path that identifies the clone view in the page
+        
+        return a clone of itself
+        """
+        return View(self.__view_type, self.__budget, self.__wr_page,
+                       new_path, self.__active_path_record)
+
+    def clear(self):
+        """clear(self)
+        
+        Clear the intance atributes
+        """
+        del self.__wr_page
+        del self.__budget
+        del self.__path
+        del self.__widget
+        del self.__view
+        del self.__connected
+        del self.__connected_button
+    
+    path = property(getPath, setPath, None,
+        "path that identifies the item in the notebook page")
+    widget = property(getWidget, None, None, "View widget")
+
+class Paned(object):
+    """gui.Paned:
+    
+    Description:
+    It creates and shows gtk.Hpaned or gtk.Vpaned to show in page budget
+    Constructor:
+        Paned(orientation, widget1, widget2)
+        orientation: The orientation of the pane separator, can be "v" or "h"
+        widget1: the top or left pane widget
+        widget2: the botton or right pane widget
+        Returns the newly created Paned instance
+    Ancestry:
+    +-- object
+      +-- Paned
+    Atributes:
+        "widget": Pane widget("gtk.VPaned" or "gtk.HPaned" object)
+        "__orientation": The orientation of de gtk.Paned, can be "v" or "h"
+        "__items": list of items showed in the paned, its can be View or Paned
+            instances
+        "__path": the paned path in the page
+    Methods:
+        __init__(self)
+        __getitem__(self, item)
+        getClone(self, new_path)
+        getItem(self, path)
+        runMessage(self, messge, path, arg=None)
+        getWidget(self)
+        {get/set}Path
+        clear(self)
+    """
+    # TODO:  *control the position paned separator. Now is always 200 pixels
+    # TODO:     can be with a float(0.0-1.0) aspect ratio
+    # TODO:          0.0 no space for widget1
+    # TODO:          1.0 all the space for widget1
+    # TODO:  *control the position pane separator when the size of the window
+    # TODO:     change with the same ascpect ratio
+
+    def __init__(self, orientation, path, item1, item2):
+        """def __init__(self, oritentation, path, item1, item2)
+        
+        orientation: The orientation of de gtk.Paned, can be "v" or "h"
+        path: the paned path in the page
+        item1: the top or left pane object
+        item2: the bottom or right pane object
+        
+        Creates and shows a new gtk.Paned
+        """
+        self.__orientation = orientation
+        if not isinstance(item1.widget, gtk.Widget) or \
+           not isinstance(item2.widget, gtk.Widget):
+            raise ValueError, _("The item must be a widget object.")
+        if orientation == "v":
+            self.__widget = gtk.VPaned()
+        elif orientation == "h":
+            self.__widget = gtk.HPaned()
+        else:
+            raise ValueError, _("Invalid orientation.")
+        self.__widget.pack1(item1.widget,True,False)
+        self.__widget.pack2(item2.widget,True,False)
+        self.__widget.set_position(200)
+        self.__widget.show()
+        self.__items = [item1, item2]
+        self.__path = path
+
+    def __getitem__(self, item):
+        """__getitem__(self, item)
+        
+        Called to implement evaluation of self[key].
+        The accepted keys should be integers 0 or 1.
+        """
+        return self.__items[item]
+
+    def getClone(self, new_path):
+        """getClone(self, new_path)
+        
+        Return a clone Paned instance with the path new_path
+        """
+        return Paned(self.__orientation, new_path,
+                     self.__items[0].getClone(new_path + (0,)),
+                     self.__items[1].getClone(new_path + (1,)))
+
+    def getItem(self,path):
+        """def getItem(self, path)
+        
+        Return the item whith the specified path.
+        """
+        _item = self.__items[path[0]]
+        if len(path) == 1:
+            return _item
+        else:
+            return _item.getItem(path[1:])
+        
+    def setItem(self, path, item_list):
+        """def setItem(self, path, item_list)
+        
+        Sets the first item in the item_list whith the especified path and
+        remove the old item in this position.
+        """
+        item = item_list[0]
+        if path == 0 or path == 1:
+            _old_item = self.__items[path]
+            self.__widget.remove(_old_item.widget)
+            self.__items[path] = item
+            if path == 0:
+                self.__widget.pack1(item.widget,True,False)
+            else:
+                self.__widget.pack2(item.widget,True,False)
+            return True
+        return False
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, page_path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        page_path: tuple that identifies the pane in the notebook page
+        arg: arguments
+        
+        This method receives a message and send this to the items of the paned
+        """
+        for _item in self.__items:
+            if not _item.path == path:
+                _item.runMessage(message, path, arg)
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        Return de gtk.Paned widget
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        Return de Paned path in the notebook page
+        """
+        return self.__path
+    
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+        self.__items[0].path = path + (0,)
+        self.__items[1].path = path + (1,)
+    
+    def clear(self):
+        del self.__widget
+        del self.__orientation
+        del self.__items
+        del self.__path
+
+    widget = property(getWidget, None, None, "gtk.Paned widget")
+    path = property(getPath, setPath, None, "Pane path in the notebook page")
+
+class TreeView(object):
+    """gui.Treeviev:
+    
+    Description:
+        It creates the columns in a treeview, is the base class for 
+        DescompositionList and Measure classes 
+    Constructor:
+        TreView(args)
+        args: list of tuples, the tuple items are:
+            0.type:
+                * index column
+                * float column
+                * text column
+                * calculated column
+                * calculated text
+                * type column
+            1. clicked method
+            2. width
+            3. text color
+            4. backgruound colors
+            5. model column index
+    Ancestry:
+    +-- object
+      +-- TreeView
+    Atributes:
+        "columns": list of columns (gtk.TreeViewColumn isntances)
+    Methods:
+        __init__(self)
+        __getitem__(self, item)
+        createColumn(self, args)
+        createTextBaseColumn(self,args)
+        createBaseColumn(self,args)
+    """
+
+    def __init__(self, args):
+        """__init__(self, args)
+        
+        args: list of tuples, the tuple items are:
+            0.type:
+                * index column
+                * float column
+                * text column
+                * calculated column
+                * Calculated text
+                * type column
+            1. clicked method
+            2. width
+            3. text color
+            4. backgruound colors
+            5. model column index
+        
+        Create the columns form the args info calling creatheColumn to create
+        each column
+        """
+        self.columns = [ self.createColumn(arg) for arg in args ]
+        self.columns.append(self.createColumn(("END",)))
+    
+    def createColumn(self, args):
+        """createColumn(self, args)
+        
+        args: tuple with the args
+            0.type:
+                * index column
+                * float column
+                * text column
+                * calculated column
+                * calculated text
+                * type column
+            1. clicked method
+            2. width
+            3. text color
+            4. backgruound colors
+            5. model column index
+        
+        Return a column created whith the arg info
+        """
+        if args[0] == "INDEX":
+            _index_column = self.createBaseColumn(args)
+            _text_index_cell = gtk.CellRendererText()
+            _text_index_cell.set_property('foreground-gdk',
+                gtk.gdk.color_parse(globals.color["TEXT"]))
+            _pixbuf_index_cell = gtk.CellRendererPixbuf()
+            _arrow_icon = gtk.gdk.pixbuf_new_from_file(
+                globals.getAppPath("ARROW-ICON"))
+            _pixbuf_index_cell.set_property("pixbuf", _arrow_icon)
+            _index_column.pack_start(_text_index_cell, True)
+            _index_column.pack_start(_pixbuf_index_cell, True)
+            _index_column.set_cell_data_func(_text_index_cell,
+                self.colorCell,
+                [gtk.gdk.color_parse(globals.color["INDEX-UNEVEN"]),
+                gtk.gdk.color_parse(globals.color["INDEX-EVEN"])])
+            return _index_column
+        elif args[0] == "TEXT":
+            _column, _cell = self.createTextBaseColumn(args)
+            _column.add_attribute(_cell, 'text', args[5])
+            return _column
+        elif args[0] == "FLOAT":
+            _column, _cell = self.createTextBaseColumn(args)
+            _column.add_attribute(_cell, 'text', args[5])
+            _column.get_cell_renderers()[0].set_property('xalign', 1.0)
+            return _column
+        elif args[0] == "CALCULATED":
+            _column, cell = self.createTextBaseColumn(args)
+            _column.get_cell_renderers()[0].set_property('xalign', 1.0)
+            return _column
+        elif args[0] == "CALCULATEDTEXT":
+            _column, cell = self.createTextBaseColumn(args)
+            return _column
+        elif args[0] == "TYPE":
+            _column = self.createBaseColumn(args)
+            _type_cell1 = gtk.CellRendererPixbuf()
+            _type_cell2 = gtk.CellRendererText()
+            _type_cell2.set_property('foreground-gdk', args[3])
+            _column.pack_start(_type_cell1, True)
+            _column.pack_start(_type_cell2, True)
+            _column.add_attribute(_type_cell2, 'text', args[5])
+            _column.set_cell_data_func(_type_cell1,
+                self.colorCell, args[4])
+            _column.set_cell_data_func(_type_cell2,
+                self.colorCell, args[4])
+            return _column
+        elif args[0] == "PIXBUF":
+            _column = self.createBaseColumn(args)
+            _type_cell1 = gtk.CellRendererPixbuf()
+            _column.pack_start(_type_cell1, True)
+            _column.set_cell_data_func(_type_cell1,
+                self.colorCell, args[4])
+            return _column
+        elif args[0] == "END":
+            _end_column = gtk.TreeViewColumn()
+            _end_column.set_clickable(False)
+            _end_cell = gtk.CellRendererText()
+            _end_cell.set_property('cell-background-gdk',
+                gtk.gdk.color_parse(globals.color["UNEVEN"]))
+            _end_column.pack_start(_end_cell, True)
+            return _end_column
+        return None
+
+    def createTextBaseColumn(self,args):
+        """createTextBaseColumn(self,args)
+        
+        args: tuple with the args
+            0.type:
+                * float column
+                * text column
+                * calculated column
+                * calculated text
+            1. clicked method
+            2. width
+            3. text color
+            4. backgruound colors
+            5. model column index
+        
+        Return a column and its CellREndererText
+        """
+        _column = self.createBaseColumn(args)
+        _cell = gtk.CellRendererText()
+        _cell.set_property('foreground-gdk', args[3])
+        _column.pack_start(_cell, True)
+        _column.set_cell_data_func(_cell, self.colorCell, args[4])
+        return _column, _cell
+
+    def createBaseColumn(self,args):
+        """createBaseColumn(self,args)
+        
+        args: tuple with the args
+            0.type:
+                * index column
+                * float column
+                * text column
+                * calculated column
+                * calculated text column
+                * type column
+            1. clicked method
+            2. width
+            3. text color
+            4. backgruound colors
+            5. model column index
+        
+        Return a column
+        """
+        _column = gtk.TreeViewColumn()
+        _column.set_clickable(True)
+        _column.connect("clicked", args[1])
+        _column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        _column.set_fixed_width(args[2])
+        _column.set_resizable(True)
+        return _column
+
+class DecompositionList(TreeView):
+    """gui.DecompositionList:
+    
+    Description:
+        Class to show a budget Decomposition List
+    Constructor:
+        DecompositionList(budget, page, path)
+        budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the view path in the Page
+        Returns the newly created DecompositionList instance
+    Ancestry:
+    +-- object
+      +-- TreeView
+        +-- DecompositionList
+    Atributes:
+        "budget": Budget to show, base.obra instance.
+        "widget or __scrolled_window": Window that contains the table,
+            (gtk.ScrolledWindow)
+        "path": Pane page identifier
+        "page": weak reference from Page instance which creates this class
+        "__active_color": background color of the active cell, a
+            gtk.gdk.Color object
+        "__chapter_background_colors": background colors of the Code
+            column cells when there is a chapter record,
+            list of gtk.gdk.Color objects [even cell, uneven cell]
+        "__methond_message": Method to send messages to the page
+        "__liststore": list model which store the list data
+            (gtk.ListStore object)
+        "__treeview": widget for displaying decomposition lists (gtk.TreeView)
+        "__index_column": Index column (gtk.TreeViewColumn object)
+        "__code_column": Record code column (gtk.TreeViewColumn)
+        "__unit_column": Unit of measure column (gtk.TreeViewColumn)
+        "__description_column": record's short description column 
+            (gtk.TreeViewColumn)
+        "__measure_column": Measure column (gtk.TreeViewColumn)
+        "__price_column": Price column (gtk.TreeViewColumn)
+        "__amount_column": Amount column(gtk.TreeViewColumn)
+        "__end_column": End empty column (gtk.TreeViewColumn)
+        "__treeselection": active selection
+        "__selection_control": state of the selection control (True/False)
+        "__cursor": cursor position in the table
+    Methods:
+        __init__(self, budget)
+        treeviewCursorChanged(self, treeview)
+        treeviewClickedEvent(self, widget, event)
+        treeviewKeyPressEvent(self, widget, event)
+        moveCursor(self, treeview, step, count)
+        controlSelection(self, selection)
+        selectAll(self, column)
+        setColumnsHeaders(self)
+        setListstoreValues(self, puntero, treeiter=None)
+        colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        _claculateAmount(self, row_path, tree_model)
+        showParentRecord(self, column)
+        showMessageRecord(self, camino,_code):
+        showRowRecord(self, treeview, path, column)
+        runMessage(self, messagem path, arg=None)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/seg}Page
+        getBudget(self)
+        getActivePathRecord(self)
+    """
+
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path)
+        
+        budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the path of the List in the Page
+        
+        Sets the init atributes
+        Creates the init list values in self.__liststore from the budget 
+            showing the top record descomposition
+        Creates the list in self.__treeview
+            * Creates the columns and cell
+            * Sets te the column headers values
+            * Sets the selection properties
+            * Connects the events
+        """
+        # TODO: to group all columns in a dicctionary
+        # Budget
+        if not isinstance(budget, base.Budget):
+            raise ValueError, _("Argument must be a Budget object")
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        # ListStore
+        self.__liststore = gtk.ListStore(object
+            #, int, int, str, str, str, str, str,str
+            )
+        if path_record is None:
+            print _("DecompositionList.__init__: Record path can not be None")
+            path_record = (0,)
+        self.__active_path_record = path_record
+        self.setListstoreValues(self.__active_path_record)
+        # Treeview
+        self.__treeview = gtk.TreeView(self.__liststore)
+        self.__treeview.set_enable_search(False)
+        self.__treeview.set_reorderable(False)
+        self.__treeview.set_headers_clickable(True)
+        self.__treeview.show()
+        # Scrolled_window
+        self.__scrolled_window = gtk.ScrolledWindow()
+        self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
+                                        gtk.POLICY_AUTOMATIC)
+        self.__scrolled_window.add(self.__treeview)
+        # colors
+        _text_color = gtk.gdk.color_parse(globals.color["TEXT"])
+        _background_color = [
+            gtk.gdk.color_parse(globals.color["UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["EVEN"])]
+        self.__chapter_background_colors = [
+            gtk.gdk.color_parse(globals.color["CHAPTER-UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["CHAPTER-EVEN"])]
+        super(DecompositionList,self).__init__(
+            [("INDEX",self.selectAll,42),
+            ("CALCULATEDTEXT", self.showParentRecord, 
+             gtk.Label("A"*10).size_request()[0] +10,
+             _text_color, _background_color),
+            ("PIXBUF", self.showParentRecord, 26, _text_color,
+             _background_color),
+            ("CALCULATEDTEXT", self.showParentRecord,
+            gtk.Label(_("a"*4)).size_request()[0] +10,
+            _text_color, _background_color),
+            ("CALCULATEDTEXT", self.showParentRecord,
+            gtk.Label("a"*30).size_request()[0] +10,
+            _text_color, _background_color),
+            ("CALCULATED", self.showParentRecord,
+            gtk.Label("a"*10).size_request()[0] +10,
+            _text_color, _background_color),
+            ("CALCULATED", self.showParentRecord,
+            gtk.Label("a"*10).size_request()[0] +10,
+            _text_color, _background_color),
+            ("CALCULATED", self.showParentRecord,
+            gtk.Label("a"*10).size_request()[0] +10,
+            gtk.gdk.color_parse(globals.color["CALCULATED-TEXT"]),
+            _background_color),
+            ])
+        self.__index_column = self.columns[0]
+        self.__code_column = self.columns[1]
+        self.__type_column = self.columns[2]
+        self.__unit_column = self.columns[3]
+        self.__description_column = self.columns[4]
+        self.__measure_column = self.columns[5]
+        self.__price_column = self.columns[6]
+        self.__amount_column = self.columns[7]
+        self.__end_column = self.columns[8]
+        # Index column
+        self.__treeview.append_column(self.__index_column)
+        # Code column
+        self.__treeview.append_column(self.__code_column)
+        # Type column
+        self.__treeview.append_column(self.__type_column)
+        self.chapter_icon = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("CHAPTER-ICON"))
+        self.unit_icon  = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("UNIT-ICON") )
+        self.material_icon  = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("MATERIAL-ICON") )
+        self.machinery_icon = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("MACHINERY-ICON"))
+        self.labourforce_icon = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("LABOURFORCE-ICON"))
+        self.__type_column.get_cell_renderers()[0].set_property("pixbuf",
+            self.labourforce_icon)
+        
+        # Unit column
+        self.__treeview.append_column(self.__unit_column)
+        # Description column
+        self.__treeview.append_column(self.__description_column)
+        # Measure Column
+        self.__treeview.append_column(self.__measure_column)
+        # Price column
+        self.__treeview.append_column(self.__price_column)
+        # Amount column
+        self.__treeview.append_column(self.__amount_column)
+        # End Column
+        self.__treeview.append_column(self.__end_column)
+        # Connect
+        self.__treeview.connect("row-activated", self.showRowRecord)
+        self.__treeview.connect("move-cursor", self.moveCursor)
+        self.__treeview.connect("key-press-event", self.treeviewKeyPressEvent)
+        self.__treeview.connect("button-press-event", self.treeviewClickedEvent)
+        self.__treeview.connect("cursor-changed", self.treeviewCursorChanged)
+        # control selection
+        self.__treeselection = self.__treeview.get_selection()
+        self.__treeselection.set_mode(gtk.SELECTION_MULTIPLE)
+        self.__treeselection.set_select_function(self.controlSelection)
+        self.__selection_control = True
+        if len(self.__liststore) > 0:
+            self.__treeview.set_cursor_on_cell((0,),self.__unit_column,
+                self.__unit_column.get_cell_renderers()[0],True)
+        self.__treeview.grab_focus()
+        self.__cursor = self.__treeview.get_cursor()
+        # Show
+        self.setColumnsHeaders()
+        self.__scrolled_window.show()
+
+    def treeviewCursorChanged(self, treeview):
+        """def treeviewCursorChanged(self, treeview)
+        
+        treeview: treewiew widget
+        Method connected to "cursor-changed" signal
+        The "cursor-changed" signal is emitted when the cursor moves or is set
+        Sets the new cursor position in self.__cursor, it is used to avoid 
+        unnecessary changes in cursor position.
+        """
+        event = gtk.get_current_event()
+        (_cursor_path, _column) = treeview.get_cursor()
+        if event is None or event.type !=  gtk.gdk.BUTTON_RELEASE:
+            if not _column is self.__index_column:
+                self.__cursor = treeview.get_cursor()
+    
+    def treeviewClickedEvent(self, widget, event):
+        """def treeviewClickedEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: clicked event
+        Method connected to "button-press-event" signal
+        The "button-press-event" signal is emitted when a mouse button is
+        pressed.
+        Returns TRUE to stop other handlers from being invoked for the event.
+        Returns FALSE to propagate the event further.
+        
+        The events in end column are ignored.
+        If the user click in a row of the index column the cursor is moved to
+        this row but not to the index column
+        """
+        if event.button == 1:
+            path_at_pos = self.__treeview.get_path_at_pos(int(event.x),
+                                                        int(event.y))
+            if not path_at_pos is None: 
+                _path_cursor, _column, _x, _y = path_at_pos
+                if _column == self.columns[-1]:
+                    return True
+                if _column is self.columns[0]:
+                    self.__cursor[0] == _path_cursor
+        return False
+
+    def treeviewKeyPressEvent(self, widget, event):
+        """def treeviewKeyPressEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: Key Press event
+        Method connected to "key-press-event" signal
+        The "key-press-event" signal is emitted when the user presses a key
+        on the keyboard.
+        Returns :TRUE to stop other handlers from being invoked for the event.
+        Returns :FALSE to propagate the event further.
+        
+        If the user press the right cursor button and the cursor is in the
+        amount column or pres the left cursor button and the cursor is
+        in the code column the event is estoped, else the event is propagated. 
+        """
+        (_cursor_path, _column) = self.__treeview.get_cursor()
+        if (event.keyval == gtk.keysyms.Right \
+            and _column == self.columns[-2]) \
+            or (event.keyval == gtk.keysyms.Left \
+            and _column == self.columns[1]):
+            return True
+        return False
+
+    def moveCursor(self, treeview, step, count):
+        """def treeviewKeyPressEvent(self, widget, event)
+        
+        treeview: the treeview that received the signal
+        step: the movement step size
+        count: the number of steps to take
+        
+        Method connected to "move-cursor" signal
+        The "move-cursor" signal is emitted when the user moves the cursor
+        using the Right, Left, Up or Down arrow keys or the Page Up,
+        Page Down, Home and End keys.
+        
+        Returns :TRUE if the signal was handled.
+        """
+        return False
+
+    def controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: treeselection
+        
+        Method connected to set_selection_function() 
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        The selection only run if the user click in the index column, else
+        the previous selection is erased.
+        """
+        _column = self.__treeview.get_cursor()[1]
+        if _column is self.columns[0] \
+            or self.__selection_control == False:
+            return True
+        else:
+            self.__selection_control = False
+            self.__treeselection.unselect_all()
+            self.__selection_control = True
+            return False
+
+    def selectAll(self, column):
+        """def selectAll(self, column)
+        
+        column: index column
+        Method connected to "clicked" event in the index column
+        If the user clickes in the index column header selecs or deselects 
+        all rows
+        """
+        (_model, _pathlist) = self.__treeselection.get_selected_rows()
+        # it avoid to set cursor in the index column
+        self.__treeview.set_cursor(self.__cursor[0], self.__cursor[1])
+        self.__selection_control = False
+        if len(_pathlist) == 0:
+            # select all
+            self.__treeselection.select_all()
+        else:
+            # unselect all
+            self.__treeselection.unselect_all()
+        self.__selection_control = True
+
+    def setColumnsHeaders(self):
+        """def setColumnsHeaders(self)
+        
+        Sets the headers column values
+        """
+        _path_record = self.__active_path_record
+        _number = _path_record[-1]
+        _budget = self.__budget
+        _code = _budget.getCode(_path_record)
+        _decomposition = _budget.getDecomposition(_path_record)
+        _stryield = _budget.getStrYield(_decomposition.budgetMeasures[0],
+                                        _budget.getRecord(_code).recordType)
+        _record = _budget.getRecord(_code)
+        _unit = _record.unit
+        _description = _record.summary
+        _price = _budget.getStrPriceFromRecord(self.budget.getActiveTitle(),
+                                               _record)
+        # TODO: round to decimal places in amount
+        _amount = float(_stryield) * float(_price)
+        if len(_path_record) == 1: # root record
+            _amount = _price
+        else:
+            _parent_code = self.budget.getCode(self.__active_path_record[:-1])
+            _parent_record = self.__budget.getRecord(_parent_code)
+            _amount = _budget.getStrAmount(self.__active_path_record)
+        
+        self.__code_column.set_title(_("Code") + chr(10) + "[" + _code + "]")
+        self.__unit_column.set_title(_("Unit") + chr(10) + "[" + _unit + "]")
+        self.__description_column.set_title(
+           _("Description") + chr(10) + "[" + _description + "]")
+        self.__measure_column.set_title(
+            _("Measure") + chr(10) + "[" + _stryield + "]")
+        self.__price_column.set_title(
+            _("Price") + chr(10) + "[" + _price + "]")
+        self.__amount_column.set_title(
+            _("Amount") + chr(10) + "[" + str(_amount) + "]")
+
+        
+    def setListstoreValues(self, path_record):
+        """def setListstoreValues(self, path_record)
+        
+        path_record: Record path in the budget
+        Sets the liststore record values from a path record
+        """
+        self.__liststore.clear()
+        _budget = self.__budget
+        if not _budget.hasPath(path_record):
+            raise ValueError, _("Invalid path")
+        else:
+            _parent_code = _budget.getCode(path_record)
+            for N,_code in enumerate(_budget.getchildren(_parent_code)):
+                _decomposition = _budget.getNDecomposition(_parent_code, N)
+                _record = _budget.getRecord(_code)
+                _values = [_record,
+                           #_record.hierarchy,
+                           #_record.type,
+                           #_record.subtype,
+                           #_code,
+                           #_record.unit,
+                           #_record.summary,
+                           #_decomposition.yield_,
+                           #_decomposition.budget[0].yield_,
+                           #_record.prices[_budget.getActiveTitle()].prices]
+                           #_record.getPrice(_budget.getActiveTitle())
+                           ]
+                _treeiter = self.__liststore.append(_values)
+
+    def colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
+        """def colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        
+        column: the gtk.TreeViewColumn in the treeview
+        cell_renderer: a gtk.CellRenderer
+        tree_model: the gtk.TreeModel
+        iter: gtk.TreeIter pointing at the row
+        lcolor: list with 2 gtk colors for even and uneven record
+        
+        Method connected to "set_cell_data_func" of many column
+        The set_cell_data_func() method sets the data function (or method) 
+        to use for the column gtk.CellRenderer specified by cell_renderer.
+        This function (or method) is used instead of the standard attribute
+        mappings for setting the column values, and should set the attributes
+        of the cell renderer as appropriate. func may be None to remove the
+        current data function. The signature of func is:
+        -def celldatafunction(column, cell, model, iter, user_data)
+        -def celldatamethod(self, column, cell, model, iter, user_data)
+        where column is the gtk.TreeViewColumn in the treeview, cell is the
+        gtk.CellRenderer for column, model is the gtk.TreeModel for the
+        treeview and iter is the gtk.TreeIter pointing at the row.
+        
+        The method sets cell background color and text for all columns.
+        """
+        _row_path = tree_model.get_path(iter)
+        _number = _row_path[-1]
+        _record = tree_model[_row_path][0]
+        if column is self.__index_column:
+            cell_renderer.set_property('text', str(_number + 1))
+            self.__index_column.get_cell_renderers()[1].set_property(
+                'cell-background-gdk', lcolor[_number % 2])
+        elif column is self.__code_column:
+            # if the record is a chapter
+            if tree_model.get_value(iter, 0).recordType.hierarchy == 1: 
+                lcolor = self.__chapter_background_colors
+            _code = _record.code
+            cell_renderer.set_property('text', _code)
+        elif column is self.__unit_column:
+            _unit = _record.unit
+            cell_renderer.set_property('text', _unit)
+        elif column is self.__description_column:
+            _summary = _record.summary
+            cell_renderer.set_property('text', _summary)
+        elif column is self.__measure_column:
+            _parent_code = self.budget.getCode(self.__active_path_record)
+            _parent_record = self.__budget.getRecord(_parent_code)
+            _decomposition = _parent_record.children[_number]
+            _stryield = self.__budget.getStrYield(
+                _decomposition.budgetMeasures[0], _parent_record.recordType)
+            cell_renderer.set_property('text', _stryield)
+        elif column is self.__price_column:
+            _price = self.budget.getStrPriceFromRecord(
+                       self.budget.getActiveTitle(), _record)
+            cell_renderer.set_property('text', _price)
+        elif column is self.__amount_column:
+            _parent_code = self.budget.getCode(self.__active_path_record)
+            _parent_record = self.__budget.getRecord(_parent_code)
+            _amount = self.budget.getStrAmount(
+                        self.__active_path_record + (_number,))
+            cell_renderer.set_property('text', str(_amount))
+        elif column is self.__type_column:
+            _hierarchy = tree_model[_row_path][0].recordType.hierarchy
+            _type = tree_model[_row_path][0].recordType.type
+            _subtype = tree_model[_row_path][0].recordType.subtype
+            if _hierarchy == 1:
+                cell_renderer.set_property("pixbuf",self.chapter_icon)
+            else:
+                if _type == 0:
+                    cell_renderer.set_property("pixbuf",self.unit_icon)
+                elif _type == 1:
+                    cell_renderer.set_property("pixbuf",
+                        self.labourforce_icon)
+                elif _type == 2:
+                    cell_renderer.set_property("pixbuf",
+                        self.machinery_icon)
+                else:
+                    cell_renderer.set_property("pixbuf",self.material_icon)
+        if self.__treeview.get_cursor() == (_row_path,column):
+            cell_renderer.set_property('cell-background-gdk',
+                gtk.gdk.color_parse(globals.color["ACTIVE"]))
+        else:
+            cell_renderer.set_property('cell-background-gdk',
+                lcolor[_number % 2])
+
+    def showParentRecord(self, column):
+        """def showParentRecord(self, column)
+        
+        column: the column that is clicked
+        Method connected to "clicked" event of many columns
+        Show the parent record
+        """
+        _budget = self.__budget
+        if len(self.__active_path_record) == 1:
+            # The active record is the root record
+            # This avoid to move the cursor to the clicked column
+            self.__treeview.set_cursor(self.__cursor[0], self.__cursor[1])
+        else:
+            _path_record = self.__active_path_record[:-1]
+            _parent = self.__active_path_record[-1]
+            self.__active_path_record = _path_record
+            self.setColumnsHeaders()
+            self.setListstoreValues(self.__active_path_record)
+            arg = ( _path_record )
+            _page = self.__page()
+            _page.propagateMessageFrom("change_active", self.__path, arg)
+            self.__treeview.set_cursor(_parent, self.__cursor[1])
+            self.__cursor = self.__treeview.get_cursor()
+
+    def showMessageRecord(self, record_path):
+        """def showMessageRecord(self, record_path)
+        
+        record_path: the path of  the record to show
+        Method connected to "change_active" message
+        Show the record especified in the "change_active" message
+        """
+        _budget = self.__budget
+        self.__active_path_record = record_path
+        self.setColumnsHeaders()
+        self.setListstoreValues(self.__active_path_record)
+        self.__treeview.set_cursor((0,))
+
+    def showRowRecord(self, treeview, treeview_path, column):
+        """def showRowRecord(self, treeview, treeview_path, column)
+        
+        treeview: treview to show
+        treeview_path: the path of the record to show
+        code: the code of the record to show
+        
+        Method connected to "row-activated" event
+        The "row-activated" signal is emitted when the row_activated() method
+        is called or the user double clicks a treeview row.
+        "row-activated" is also emitted when a non-editable row is selected
+        and one of the keys: Space, Shift+Space, Return or Enter is pressed.
+        Show the especified record
+        """
+        if not (column is self.__end_column) and \
+           not (column is self.__index_column):
+            _budget = self.__budget
+            _model = treeview.get_model()
+            _iter = _model.get_iter(treeview_path)
+            _code = _model.get_value(_iter, 0).code
+            #_code = _model.get_value(_iter, 4)
+            _path_record = self.__active_path_record + treeview_path
+            if self.__budget.hasPath(_path_record):
+                # if this record path is valid
+                self.__active_path_record = _path_record
+                self.setColumnsHeaders()
+                self.setListstoreValues(self.__active_path_record)
+                self.__treeview.set_cursor((0,))
+                _arg = ( _path_record )
+                _page = self.__page()
+                _page.propagateMessageFrom("change_active", self.__path,
+                                       _arg )
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                _path_record = arg
+                self.showMessageRecord( _path_record)
+        elif message == "clear":
+            self._clear()
+
+    def _clear(self):
+        """def _clear(self)
+        
+        it deletes the __budget value
+        this would not be necessary if there were not circular references,
+        which are pending to fix
+        """
+        del self.__budget 
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__scrolled_window
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+
+    def getPage(self):
+        """def getPage(self)
+        
+        return the Page
+        """
+        return self.__page
+
+    def setPage(self,page):
+        """def setPage(self)
+        
+        set the Page
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the Budget objet
+        """
+        return self.__budget
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+
+    widget = property(getWidget, None, None,
+        "Pane configuration list")
+    path = property(getPath, setPath, None,
+        "path that identifie the item in the page notebook")
+    page = property(getPage, setPage, None,
+        "weak reference from Page instance which creates this class")
+    budget =  property(getBudget, None, None,
+        "Budget object")
+    active_path_record =  property(getActivePathRecord, None, None,
+        "Active path record")
+
+class Measure(TreeView):
+    """gui.Measure:
+    
+    Description:
+        Class to show a Measure List
+    Constructor:
+        Measure(budget, page, path)
+        budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the path of the List in the Page
+        Returns the newly created DecompositionList instance
+    Ancestry:
+    +-- object
+      +-- TreeView
+        +-- DecompositionList
+    Atributes:
+        "budget": Budget to show, base.obra instance.
+        "__active_path_record": path of the active record in the budget
+        "widget or __scrolled_window": Window that contains the table,
+            (gtk.ScrolledWindow)
+        "path": Pane page identifier
+        "page": weak reference from Page instance which creates this class
+        "__active_color": The background color of the active cell as a
+            gtk.gdk.Color object
+        "__chapter_background_colors": The background colors of the Code
+            column cells when there is a chapter record
+            as a list of gtk.gdk.Color objects [even cell, uneven cell]
+        "__methond_message": Method to send messages to the page
+        "__liststore": list model which store the list data
+            (gtk.ListStore object)
+        "__treeview": widget for displaying decomposition lists (gtk.TreeView)
+        "__index_column": Index column (gtk.TreeViewColumn object)
+        "__code_column": Record code column (gtk.TreeViewColumn)
+        "__unit_column": Unit of measure column (gtk.TreeViewColumn)
+        "__description_column": record's short description column 
+            (gtk.TreeViewColumn)
+        "__measure_column": Measure column (gtk.TreeViewColumn)
+        "__price_column": Price column (gtk.TreeViewColumn)
+        "__amount_column": Amount column(gtk.TreeViewColumn)
+        "__end_column": End empty column (gtk.TreeViewColumn)
+        "__treeselection": active selection
+        "__selection_control": state of the selection control (True/False)
+        "__cursor": Situation of the cursor in the table
+    Methods:
+        __init__(self, budget, page, path, path_record=(0,))
+        setListstoreValues(self, path_record)
+        setColumnsHeaders(self)
+        controlSelection(self, selection)
+        showMessageRecord(self, record_path)
+        treeviewCursorChanged(self, treeview)
+        moveCursor(self, treeview, step, count)
+        treeviewClickedEvent(self, widget, event)
+        treeviewKeyPressEvent(self, widget, event)
+        runMessage(self, message, path, arg=None)
+        selectAll(self, column)
+        colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/set}Page
+        getBudget(self)
+        getActivePathRecord(self)
+    """
+
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path, path_record=(0,))
+        
+        budget: budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the path of the List in the Page
+        path_record: path of the active record in the budget
+        
+        Sets the init atributes
+        Creates the init list values in self.__liststore from the budget 
+            showing the top record from the record with path path_record
+        Creates the list in self.__treeview
+            * Creates the columns and cell
+            * Sets te the column headers values
+            * Sets the selection properties
+            * Connects the events
+        """
+        # Seting init args
+        if not isinstance(budget, base.Budget):
+            raise ValueError, _("Argument must be a Budget object")
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        if not isinstance(path_record, tuple):
+            print _("Record path must be a tuple")
+            path_record = (0,)
+        self.__active_path_record = path_record
+        # ListStore
+        self.__liststore = gtk.ListStore(object)
+        self.setListstoreValues(self.__active_path_record)
+        # Treeview
+        self.__treeview = gtk.TreeView(self.__liststore)
+        self.__treeview.set_enable_search(False)
+        self.__treeview.set_reorderable(False)
+        self.__treeview.set_headers_clickable(True)
+        self.__treeview.show()
+        # Scrolled_window
+        self.__scrolled_window = gtk.ScrolledWindow()
+        self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
+            gtk.POLICY_AUTOMATIC)
+        self.__scrolled_window.add(self.__treeview)
+        # colors
+        _text_color = gtk.gdk.color_parse(globals.color["TEXT"])
+        _calculated_text =gtk.gdk.color_parse(globals.color["CALCULATED-TEXT"])
+        _background_color = [
+            gtk.gdk.color_parse(globals.color["UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["EVEN"])]
+        self.__chapter_background_colors = [
+            gtk.gdk.color_parse(globals.color["CHAPTER-UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["CHAPTER-EVEN"])]
+        super(Measure,self).__init__(
+            [("INDEX",self.selectAll,42),
+            ("PIXBUF", self.passMethod,
+             gtk.Label("A"*4).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATEDTEXT", self.passMethod, 
+             gtk.Label("A"*12).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*5).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*7).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*7).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*7).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATEDTEXT", self.passMethod, 
+             gtk.Label("A"*12).size_request()[0] +10,
+             _text_color, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*7).size_request()[0] +10,
+             _calculated_text, _background_color),
+            ("CALCULATED", self.passMethod, 
+             gtk.Label("A"*7).size_request()[0] +10,
+             _calculated_text, _background_color),
+            ])
+        self.__index_column = self.columns[0]
+        self.__linetype_column = self.columns[1]
+        self.__comment_column = self.columns[2]
+        self.__units_column = self.columns[3]
+        self.__length_column = self.columns[4]
+        self.__width_column = self.columns[5]
+        self.__height_column = self.columns[6]
+        self.__formula_column = self.columns[7]
+        self.__parcial_column = self.columns[8]
+        self.__subtotal_column = self.columns[9]
+        self.__end_column = self.columns[10]
+        # Index column
+        self.__treeview.append_column(self.__index_column)
+        # Linetype column
+        self.__treeview.append_column(self.__linetype_column)
+        self.calculatedline_icon = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("CALCULATEDLINE-ICON"))
+        self.normalline_icon  = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("NORMALLINE-ICON") )
+        self.parcialline_icon  = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("PARCIALLINE-ICON") )
+        self.acumulatedline_icon = gtk.gdk.pixbuf_new_from_file(
+            globals.getAppPath("ACUMULATEDLINE-ICON"))
+        # Comment column
+        self.__treeview.append_column(self.__comment_column)
+        # Units column
+        self.__treeview.append_column(self.__units_column)
+        # Length column
+        self.__treeview.append_column(self.__length_column)
+        # Width_column
+        self.__treeview.append_column(self.__width_column)
+        # Height column
+        self.__treeview.append_column(self.__height_column)
+        # Formula column
+        self.__treeview.append_column(self.__formula_column)
+        # Parcial column
+        self.__treeview.append_column(self.__parcial_column)
+        # Subtotal column
+        self.__treeview.append_column(self.__subtotal_column)
+        # End Column
+        self.__treeview.append_column(self.__end_column)
+        # Connect
+        self.__treeview.connect("move-cursor", self.moveCursor)
+        self.__treeview.connect("key-press-event", self.treeviewKeyPressEvent)
+        self.__treeview.connect("button-press-event", self.treeviewClickedEvent)
+        self.__treeview.connect("cursor-changed", self.treeviewCursorChanged)
+        # control selection
+        self.__treeselection = self.__treeview.get_selection()
+        self.__treeselection.set_mode(gtk.SELECTION_MULTIPLE)
+        self.__treeselection.set_select_function(self.controlSelection)
+        self.__selection_control = True
+        self.__treeview.set_cursor_on_cell((1,), self.columns[1],
+            self.columns[1].get_cell_renderers()[0],True)
+        self.__treeview.grab_focus()
+        self.__cursor = self.__treeview.get_cursor()
+        # Show
+        self.setColumnsHeaders()
+        self.__scrolled_window.show()
+    
+    def passMethod(self, args):
+        pass
+
+    def setListstoreValues(self, path_record):
+        """def setListstoreValues(self, path_record)
+        
+        path_record: Record path in the budget
+        Sets the liststore record values from a path record
+        """
+        self.__liststore.clear()
+        _budget = self.__budget
+        if not _budget.hasPath(path_record):
+            raise ValueError, _("Invalid path")
+        else:
+            _measure = _budget.getMeasure(path_record)
+            if isinstance(_measure, base.Measure):
+                _lines = _measure.lines
+                for _line in _lines:
+                    _values = [
+                        _line,
+##                        _line.type,
+##                        _line.comment,
+##                        _line.units,
+##                        _line.length,
+##                        _line.width,
+##                        _line.height
+                        ]
+                    _treeiter = self.__liststore.append(_values)
+            else:
+                raise ValueError, utils.mapping(_("measure must be a Measure "\
+                      "object. Type: $1"), (type(_measure),))
+    def setColumnsHeaders(self):
+        """def setColumnsHeaders(self)
+        
+        Sets the headers column values
+        """
+        _measure = self.__budget.getMeasure(self.__active_path_record)
+        _DS = self.__budget.getDecimals("DS")
+        _total = _measure.measure
+        _total_str = ("%." + str(_DS) + "f" ) % _total
+        self.columns[1].set_title(_("Type"))  # Σ parcial Σ total
+        self.columns[2].set_title(_("Comment"))
+        self.columns[3].set_title(_("N\n(a)"))
+        self.columns[4].set_title(_("Length\n(b)"))
+        self.columns[5].set_title(_("Width\n(c)"))
+        self.columns[6].set_title(_("Height\n(d)"))
+        self.columns[7].set_title(_("Formula"))
+        self.columns[8].set_title(_("Parcial\n[%s]" % _total_str))
+        self.columns[9].set_title(_("Subtotal"))
+    def controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: treeselection
+        
+        Method connected to set_selection_function() 
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        The selection only run if the user click in the index column, else
+        the previous selection is erased.
+        """
+        _column = self.__treeview.get_cursor()[1]
+        if _column is self.columns[0] \
+            or self.__selection_control == False:
+            return True
+        else:
+            self.__selection_control = False
+            self.__treeselection.unselect_all()
+            self.__selection_control = True
+            return False 
+
+    def showMessageRecord(self, record_path):
+        """def showMessageRecord(self, record_path)
+        
+        record_path: the path of the record to show
+        Method connected to "change_active" message
+        Show the record especified in the "change_active" message
+        """
+        _budget = self.__budget
+        self.__active_path_record = record_path
+        self.setColumnsHeaders()
+        self.setListstoreValues(self.__active_path_record)
+        self.__treeview.set_cursor((0,))
+
+    def treeviewCursorChanged(self, treeview):
+        """def treeviewCursorChanged(self, treeview)
+        
+        treeview: treewiew widget
+        Method connected to "cursor-changed" signal
+        The "cursor-changed" signal is emitted when the cursor moves or is set
+        Sets the new cursor position in self.__cursor, it is used to avoid 
+        unnecessary changes in cursor position.
+        """
+        event = gtk.get_current_event()
+        (_cursor_path, _column) = treeview.get_cursor()
+        if event is None or event.type !=  gtk.gdk.BUTTON_RELEASE:
+            if not _column is self.__index_column:
+                self.__cursor = treeview.get_cursor()
+
+    def moveCursor(self, treeview, step, count):
+        """def treeviewKeyPressEvent(self, widget, event)
+        
+        treeview: the treeview that received the signal
+        step: the movement step size
+        count: the number of steps to take
+        
+        Method connected to "move-cursor" signal
+        The "move-cursor" signal is emitted when the user moves the cursor
+        using the Right, Left, Up or Down arrow keys or the Page Up,
+        Page Down, Home and End keys.
+        
+        Returns :TRUE if the signal was handled.
+        """
+        return False
+
+    def treeviewClickedEvent(self, widget, event):
+        """def treeviewClickedEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: clicked event
+        Method connected to "button-press-event" signal
+        The "button-press-event" signal is emitted when a mouse button is
+        pressed.
+        Returns TRUE to stop other handlers from being invoked for the event.
+        Returns FALSE to propagate the event further.
+        
+        The events in end column are ignored.
+        If the user click in a row of the index column the cursor is moved to
+        this row but not to the index column
+        """
+        if event.button == 1:
+            path_at_pos = self.__treeview.get_path_at_pos(int(event.x),
+                                                        int(event.y))
+            if not path_at_pos is None: 
+                _path_cursor, _column, _x, _y = path_at_pos
+                if _column == self.columns[-1]:
+                    return True
+                if _column is self.columns[0]:
+                    self.__cursor[0] == _path_cursor
+        return False
+
+    def treeviewKeyPressEvent(self, widget, event):
+        """def treeviewKeyPressEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: Key Press event
+        Method connected to "key-press-event" signal
+        The "key-press-event" signal is emitted when the user presses a key
+        on the keyboard.
+        Returns :TRUE to stop other handlers from being invoked for the event.
+        Returns :FALSE to propagate the event further.
+        
+        If the user press the right cursor button and the cursor is in the
+        amount column or pres the left cursor button and the cursor is
+        in the code column the event is estoped, else the event is propagated. 
+        """
+        (_cursor_path, _column) = self.__treeview.get_cursor()
+        if (event.keyval == gtk.keysyms.Right \
+            and _column == self.columns[-2]) \
+            or (event.keyval == gtk.keysyms.Left \
+            and _column == self.columns[1]):
+            return True
+        return False
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                _path_record = arg
+                self.showMessageRecord( _path_record)
+        elif message == "clear":
+            self._clear()
+
+    def selectAll(self, column):
+        """def selectAll(self, column)
+        
+        column: index column
+        Method connected to "clicked" event in the index column
+        If the user clickes in the index column header selecs or deselects 
+        all rows
+        """
+        (_model, _pathlist) = self.__treeselection.get_selected_rows()
+        # it avoid to set cursor in the index column
+        self.__treeview.set_cursor(self.__cursor[0], self.__cursor[1])
+        self.__selection_control = False
+        if len(_pathlist) == 0:
+            # select all
+            self.__treeselection.select_all()
+        else:
+            # unselect all
+            self.__treeselection.unselect_all()
+        self.__selection_control = True
+
+    def colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
+        """def colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        
+        column: the gtk.TreeViewColumn in the treeview
+        cell_renderer: a gtk.CellRenderer
+        tree_model: the gtk.TreeModel
+        iter: gtk.TreeIter pointing at the row
+        lcolor: list with 2 gtk colors for even and uneven record
+        
+        Method connected to "set_cell_data_func" of many column
+        The set_cell_data_func() method sets the data function (or method) 
+        to use for the column gtk.CellRenderer specified by cell_renderer.
+        This function (or method) is used instead of the standard attribute
+        mappings for setting the column values, and should set the attributes
+        of the cell renderer as appropriate. func may be None to remove the
+        current data function. The signature of func is:
+        -def celldatafunction(column, cell, model, iter, user_data)
+        -def celldatamethod(self, column, cell, model, iter, user_data)
+        where column is the gtk.TreeViewColumn in the treeview, cell is the
+        gtk.CellRenderer for column, model is the gtk.TreeModel for the
+        treeview and iter is the gtk.TreeIter pointing at the row.
+        
+        The method sets cell background color for all columns
+        and text for index and amount columns.
+        """
+        _row_path = tree_model.get_path(iter)
+        _number = _row_path[-1]
+        if column is self.__index_column:
+            cell_renderer.set_property('text', str(_number + 1))
+            self.__index_column.get_cell_renderers()[1].set_property(
+                'cell-background-gdk', lcolor[_number % 2])
+        elif column is self.__linetype_column:
+            _measure = tree_model[_row_path][0]
+            _type = _measure.lineType
+            if _type == 0:
+                cell_renderer.set_property("pixbuf",self.normalline_icon)
+            elif _type == 1:
+                cell_renderer.set_property("pixbuf",self.parcialline_icon)
+            elif _type == 2:
+                cell_renderer.set_property("pixbuf",
+                        self.acumulatedline_icon)
+            else: #elif _type == 3:
+                cell_renderer.set_property("pixbuf",
+                        self.calculatedline_icon)
+                
+        elif column is self.__comment_column:
+            _measure = tree_model[_row_path][0]
+            _comment = str(_measure.comment)
+            cell_renderer.set_property('text', _comment)
+        elif column is self.__units_column:
+            _measure = tree_model[_row_path][0]
+            _units = _measure.units
+            if isinstance(_units, float):
+                _DN = self.__budget.getDecimals("DN")
+                _units = ("%." + str(_DN) + "f" ) % _units
+            cell_renderer.set_property('text', _units)
+        elif column is self.__length_column:
+            _measure = tree_model[_row_path][0]
+            _length = _measure.length
+            if isinstance(_length, float):
+                _DD = self.__budget.getDecimals("DD")
+                _length = ("%." + str(_DD) + "f" ) % _length
+            cell_renderer.set_property('text', _length)
+        elif column is self.__width_column:
+            _measure = tree_model[_row_path][0]
+            _width = _measure.width
+            if isinstance(_width, float):
+                _DD = self.__budget.getDecimals("DD")
+                _width = ("%." + str(_DD) + "f" ) % _width
+            cell_renderer.set_property('text', _width)
+        elif column is self.__height_column:
+            _measure = tree_model[_row_path][0]
+            _height = _measure.height
+            if isinstance(_height, float):
+                _DD = self.__budget.getDecimals("DD")
+                _height = ("%." + str(_DD) + "f" ) % _height
+            cell_renderer.set_property('text', _height)
+        elif column is self.__formula_column:
+            _measure = tree_model[_row_path][0]
+            _formula = _measure.formula
+            cell_renderer.set_property('text', _formula)
+        elif column is self.__parcial_column:
+            _measure_line = tree_model[_row_path][0]
+            _parcial = _measure_line.parcial
+            _type = _measure_line.lineType
+            if _type == 1 or _type == 2:
+                _parcial = ""
+            else:
+                if isinstance(_parcial, float):
+                    _DS = self.__budget.getDecimals("DS")
+                    _parcial = ("%." + str(_DS) + "f" ) % _parcial
+            cell_renderer.set_property('text', _parcial)
+        elif column is self.__subtotal_column:
+            _measure_line = tree_model[_row_path][0]
+            _type = _measure_line.lineType
+            if _type == 1 or _type == 2:
+                if _type == 1:
+                    _color = gtk.gdk.color_parse(
+                               globals.color["SUBTOTAL-PARCIAL"])
+                    _subtotal = _measure_line.parcial_subtotal
+                else: #elif _type == 2:
+                    _color = gtk.gdk.color_parse(globals.color["SUBTOTAL"])
+                    _subtotal = _measure_line.acumulated_subtotal
+                lcolor = [_color, _color]
+                if isinstance(_subtotal, float):
+                    _DS = self.__budget.getDecimals("DS")
+                    _subtotal= ("%." + str(_DS) + "f" ) % _subtotal
+                cell_renderer.set_property('text', _subtotal)
+            else:
+                cell_renderer.set_property('text', "")
+
+        if self.__treeview.get_cursor() == (_row_path,column):
+            cell_renderer.set_property('cell-background-gdk',
+                gtk.gdk.color_parse(globals.color["ACTIVE"]))
+        else:
+            cell_renderer.set_property('cell-background-gdk',
+                lcolor[_number % 2])
+
+    def _clear(self):
+        """def _clear(self)
+        
+        it deletes the __budget value
+        this would not be necessary if there were not circular references,
+        which are pending to fix
+        """
+        del self.__budget
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__scrolled_window
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+    def getPage(self):
+        """def getPage(self)
+        
+        return the Page
+        """
+        return self.__page
+
+    def setPage(self,page):
+        """def setPage(self)
+        
+        set the Page
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the Budget objet
+        """
+        return self.__budget
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+
+    widget = property(getWidget, None, None,
+        "Pane configuration list")
+    path = property(getPath, setPath, None,
+        "Path that identifies the item in the page notebook")
+    page = property(getPage, setPage, None,
+        "Weak reference from Page instance which creates this class")
+    budget =  property(getBudget, None, None,
+        "Budget object")
+    active_path_record =  property(getActivePathRecord, None, None,
+        "Active Code")
+
+class Description(object):
+    """gui.Description
+    
+    Description:
+        Class to show a description text of a record in a pane
+    Constructor:
+        Description(budget, code)
+        budget: budget
+        code: code record
+    Ancestry:
+    +-- object
+      +-- Description
+    Atributes:
+        "widget": the main widget (gtk.ScrolledWindow object)
+        "path": the tuple that identifies the pane in the notebook page
+            TODO
+        "budget": The budget (base.obra objetc)
+        "active_code": The active code of the record
+        "__textbuffer": The textbuffer of the textview that contain
+            the record text.
+        "__label": The gtk.label with the title of the pane
+    Methods:
+        __init__(self, budget, code)
+        setActiveCode(self, code)
+        runMessage(self, message, nt, arg=None)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/seg}Page
+        getBudget(self)
+        getActviCode(self)
+    """
+    # TODO: make standar: "DecompositonList and Description"
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path, path_record=(0,))
+        
+        budget: the budget (base.obra object)
+        page: weak reference from Page instance which creates this class
+        path: the path position of the description in the page
+        path_record: the path of the active record
+        
+        Creates an shows the scroledwindow that contain the description text
+        of the record to be showed in a pane.
+        """
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        self.__active_path_record = path_record
+        _budget = budget
+        _text = _budget.getRecord(self.__budget.getCode(
+                self.__active_path_record)).text
+        _scrollwindow = gtk.ScrolledWindow()
+        _scrollwindow.set_policy(gtk.POLICY_AUTOMATIC,
+                                 gtk.POLICY_AUTOMATIC)
+        _textview = gtk.TextView()
+        _textview.set_wrap_mode(gtk.WRAP_WORD)
+        self.__textbuffer = _textview.get_buffer()
+        self.__textbuffer.set_text(_text)
+        _textview.show()
+        _hbox = gtk.HBox()
+        _hbox.pack_start(_textview, True, True, 5)
+        _hbox.show()
+        _vbox = gtk.VBox()
+        self.__label = gtk.Label(utils.mapping(_("Description text of the "\
+                     "record $1"), (self.__budget.getCode(
+                    self.__active_path_record),)))
+        self.__label.set_alignment(0, 0)
+        self.__label.show()
+        _vbox.pack_start(self.__label, False, False, 5)
+        _vbox.pack_start(_hbox, True, True, 5)
+        _vbox.show()
+        _scrollwindow.add_with_viewport(_vbox)
+        _scrollwindow.show()
+        self.__widget = _scrollwindow
+
+
+    def setActivePathRecord(self, path_record):
+        """def setActivePathRecord(self, path_record))
+        
+        path_record: active path record
+        Set the new path code to show its description text.
+        """
+        _budget = self.__budget
+        self.__active_path_record = path_record
+        _code = _budget.getCode(self.__active_path_record)
+        self.__label.set_text(utils.mapping(_("Description text of the record "\
+            "$1"), (_code,)))
+        _text = _budget.getRecord(_code).text
+        self.__textbuffer.set_text(_text)
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                self.setActivePathRecord(arg)
+        elif message == "clear":
+            self._clear()
+
+    def _clear(self):
+        """def _clear(self)
+        
+        Delete all instance atributes
+        """
+        del self.__widget
+        del self.__path
+        del self.__budget
+        del self.__active_code
+        del self.__textbuffer
+        del self.__label
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+
+    def getPage(self):
+        """def getPage(self)
+        
+        return the weak reference from Page instance
+        """
+        return self.__page
+
+    def setPage(self, page):
+        """def setPage(self)
+        
+        set the weak reference from Page instance
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the budget object
+        """
+        return self.__budget
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+
+    path = property(getPath, setPath, None,
+        "Path that identifie the item in the page notebook")
+    widget = property(getWidget, None, None,
+        "The main widget (gtk.ScrolledWindow)")
+    page = property(getPage, setPage, None,
+        "Weak reference from Page instance which creates this class")
+    budget = property(getBudget, None, None,
+        "Budget object")
+    active_path_record = property(getActivePathRecord, None, None,
+        "Active Path Record")
+
+class Sheet(object):
+    """gui.Sheet
+    
+    Description:
+        Class to show a sheeet of conditions text of a record in a pane
+    Constructor:
+        Sheet(budget, code)
+        budget: budget object
+        code: code record
+    Ancestry:
+    +-- object
+      +-- Sheet
+    Atributes:
+        "widget": the main widget (gtk.ScrolledWindow object)
+        "path": the tuple that identifies the pane in the notebook page
+        "budget": The budget (base.obra objetc)
+        "active_path_record": The active path record
+        "page": weak reference from Page instance which creates this class
+
+        "__textbuffer": The textbuffer of the textview that contain
+            the record text.
+        "__label": The gtk.label with the title of the pane
+        "__field_liststore": the field liststore
+        "__field_treeview": the field treeview
+        "__field_selection": the field selected in field treview
+        "__section_liststore": the section liststore
+        "__section_treeview": the section treeview
+        "__section_selection": the section selected in the section treeview
+    Methods:
+        __init__(self, budget, code)
+        setFields(self)
+        setSection(self)
+        setText(self)
+        field_controlSelection(self, selection)
+        section_controlSelection(self, selection)
+        runMessage(self, message, nt, arg=None)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/set}Page
+        getBudget(self)
+        getActviPathRecord(self)
+    """
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path, path_record=(0,))
+        
+        budget: the budget (base.obra object)
+        page: weak reference from Page instance which creates this class
+        path: the path position of the description in the page
+        path_record: the path of the active record
+        Creates an shows the scroledwindow that contain the description text
+        of the record to be showed in a pane.
+        """
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        self.__active_path_record = path_record
+        _budget = budget
+        
+        _main_box = gtk.VBox()
+        
+        self.__label = gtk.Label(utils.mapping(_("Sheet of Conditions of the "\
+                       "record $1"), (self.__budget.getCode(
+                       self.__active_path_record),)))
+        self.__label.set_alignment(0, 0)
+        self.__label.show()
+        
+        _frame = gtk.Frame()
+        _frame.set_shadow_type(gtk.SHADOW_IN)
+        _frame_box = gtk.VBox()
+        _list_box = gtk.HBox()
+        
+        self.__field_liststore = gtk.ListStore(str, str)
+        self.__field_treeview = gtk.TreeView(self.__field_liststore)
+        _field_treeselection = self.__field_treeview.get_selection()
+        _field_treeselection.set_mode(gtk.SELECTION_SINGLE)
+        self.__field_selection = None
+        _field_treeselection.set_select_function(
+            self.field_controlSelection)
+        self.__field_treeview.show()
+        _fieldcode_cell = gtk.CellRendererText()
+        _field_column = gtk.TreeViewColumn(_("Field"))
+        _field_column.pack_start(_fieldcode_cell, False)
+        _field_cell = gtk.CellRendererText()
+        _field_column.pack_end(_field_cell, True)
+        _field_column.add_attribute(_fieldcode_cell, "text", 0)
+        _field_column.add_attribute(_field_cell, "text", 1)
+        self.__field_treeview.append_column(_field_column)
+        _field_scrollwindow = gtk.ScrolledWindow()
+        _field_scrollwindow.set_policy(gtk.POLICY_AUTOMATIC,
+                                 gtk.POLICY_AUTOMATIC)
+        _field_scrollwindow.add(self.__field_treeview)
+        _field_scrollwindow.show()
+        
+        self.__section_liststore = gtk.ListStore(str, str)
+        self.__section_treeview = gtk.TreeView(self.__section_liststore)
+        _section_treeselection = self.__section_treeview.get_selection()
+        _section_treeselection.set_mode(gtk.SELECTION_SINGLE)
+        self.__section_selection = None
+        _section_treeselection.set_select_function(
+            self.section_controlSelection)
+        self.__section_treeview.show()
+        _sectioncode_cell = gtk.CellRendererText()
+        _section_column = gtk.TreeViewColumn(_("Section"))
+        _section_column.pack_start(_sectioncode_cell, False)
+        _section_column.add_attribute(_sectioncode_cell, "text", 0)
+        _section_cell = gtk.CellRendererText()
+        _section_column.pack_end(_section_cell, True)
+        _section_column.add_attribute(_section_cell, "text", 1)
+        self.__section_treeview.append_column(_section_column)
+        _section_scrollwindow = gtk.ScrolledWindow()
+        _section_scrollwindow.set_policy(gtk.POLICY_AUTOMATIC,
+                                 gtk.POLICY_AUTOMATIC)
+        _section_scrollwindow.add(self.__section_treeview)
+        _section_scrollwindow.show()
+        
+        _list_box.pack_start(_field_scrollwindow, True, True, 5)
+        _list_box.pack_start(_section_scrollwindow, True, True, 5)
+        _list_box.show()
+        
+        _scrollwindow = gtk.ScrolledWindow()
+        _scrollwindow.set_policy(gtk.POLICY_AUTOMATIC,
+                                 gtk.POLICY_AUTOMATIC)
+        _textview = gtk.TextView()
+        _textview.set_wrap_mode(gtk.WRAP_WORD)
+        self.__textbuffer = _textview.get_buffer()
+        _textview.show()
+        _hbox = gtk.HBox()
+        _hbox.pack_start(_textview, True, True, 5)
+        _hbox.show()
+        
+        _frame_box.pack_start(self.__label, False, False, 5)
+        _frame_box.pack_start(_list_box, False, False, 5)
+        _frame_box.show()
+        _frame.add(_frame_box)
+        _frame.show()
+        _main_box.pack_start(_frame, False)
+        
+
+        _vbox = gtk.VBox()
+        _vbox.pack_start(_hbox, True, True, 5)
+        _vbox.show()
+        _main_box.pack_start(_scrollwindow, True, True, 5)
+        _main_box.show()
+        
+        _scrollwindow.add_with_viewport(_vbox)
+        _scrollwindow.show()
+        self.__widget = _main_box
+        
+        self.setFields()
+
+    def setFields(self):
+        """setFields(self)
+        
+        Set the fields items in the field treeview
+        """
+        _record = self.__budget.getRecord(self.__budget.getCode(
+                  self.__active_path_record))
+        _sheet = _record.getSheet()
+        _field_list = _sheet.getFields()
+        self.__field_liststore.clear()
+        for _field in _field_list:
+            _field_text = self.__budget.getSheetField(_field)
+            _iter = self.__field_liststore.append([_field, _field_text])
+        _treeselection = self.__field_treeview.get_selection()
+        _treeselection.select_path(0)
+
+    def setSection(self):
+        """setSection(self)
+        
+        Set the section items in the section treeview
+        """
+        self.__section_liststore.clear()
+        if not self.__field_selection is None:
+            _record = self.__budget.getRecord(self.__budget.getCode(
+                  self.__active_path_record))
+            _sheet = _record.getSheet()
+            _section_list = _sheet.getSections(self.__field_selection)
+            for _section in _section_list:
+                _section_text = self.__budget.getSheetSection(_section)
+                _iter = self.__section_liststore.append([_section, _section_text])
+            _treeselection = self.__section_treeview.get_selection()
+            _treeselection.select_path(0)
+
+    def setText(self):
+        """setText(self)
+        
+        Set the text in the textview
+        """
+        if not self.__section_selection is None and\
+           not self.__field_selection is None:
+            _record = self.__budget.getRecord(self.__budget.getCode(
+                  self.__active_path_record))
+            _sheet = _record.getSheet()
+            _paragraph_code = _sheet.getParagraph(self.__field_selection,
+                                                  self.__section_selection)
+            _paragraph = self.__budget.getSheetParagraph(_paragraph_code)
+            self.__textbuffer.set_text(_paragraph)
+        else:
+            self.__textbuffer.set_text("")
+
+    def field_controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: treeselection
+        
+        Method connected to set_selection_function() in field treeview
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        When a user select a row in the field treeview the section treeview is
+        reloaded to show the sections of this field and already the text sheet.
+        """
+        _treeiter = self.__field_liststore.get_iter(selection)
+        self.__field_selection = self.__field_liststore.get_value(_treeiter, 0)
+        self.setSection()
+        return True
+
+    def section_controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: treeselection
+        
+        Method connected to set_selection_function() in sector treeview
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        When a user select a row in the field treeview the text sheet for this
+        section in showed
+        """
+        _treeiter = self.__section_liststore.get_iter(selection)
+        self.__section_selection = self.__section_liststore.get_value(_treeiter, 0)
+        self.setText()
+        return True
+
+    def setActivePathRecord(self, path_record):
+        """def setActivePathRecord(self, path_record))
+        
+        path_record: active path record
+        
+        Set the new path code to show its sheet of condition text.
+        """
+        self.__field_selection = None
+        self.__field_liststore.clear()
+        self.__section_selection = None
+        self.__section_liststore.clear()
+        self.__textbuffer.set_text("")
+        _budget = self.__budget
+        self.__active_path_record = path_record
+        _code = _budget.getCode(self.__active_path_record)
+        self.__label.set_text(utils.mapping(_("Sheet2 of Conditions of the "\
+                     "record $1"), (_code,)))
+        self.setFields()
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                self.setActivePathRecord(arg)
+        elif message == "clear":
+            self._clear()
+
+    def _clear(self):
+        """def _clear(self)
+        
+        Deletes all the instance atributes
+        """
+        del self.__page
+        del self.__widget
+        del self.__path
+        del self.__budget
+        del self.__active_code
+        del self.__textbuffer
+        del self.__label
+        del self.__textbuffer
+        del self.__label
+        del self.__field_liststore
+        del self.__field_treeview
+        del self.__field_selection
+        del self.__section_liststore
+        del self.__section_treeview
+        del self.__section_selection
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__page
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+
+    def getPage(self):
+        """def getPage(self)
+        
+        return the weak reference from Page instance
+        """
+        return self.__page
+
+    def setPage(self, page):
+        """def setPage(self)
+        
+        set the weak reference from Page instance
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the budget object
+        """
+        return self.__budget
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+
+    path = property(getPath, setPath, None,
+        "Path that identifie the item in the page notebook")
+    widget = property(getWidget, None, None,
+                      "Lista de configuracion de vistas")
+    page = property(getPage, setPage, None,
+        "Weak reference from Page instance which creates this class")
+    budget = property(getBudget, None, None,
+        "Budget object")
+    active_path_record = property(getActivePathRecord, None, None,
+        "Active Path Record")
+
+class FileView(object):
+    """gui.FileView
+    
+    Description:
+        Class to show the file icons of a record in a pane
+    Constructor:
+        Description(budget, code)
+        budget: budget
+        code: code record
+    Ancestry:
+    +-- object
+      +-- Description
+    Atributes:
+        "widget": the main widget (gtk.ScrolledWindow object)
+        "__icon_box": the box that contains the icon
+        "path": the tuple that identifies the pane in the notebook page
+        "budget": The budget (base.obra objetc)
+        "active_code": The active code of the record
+    Methods:
+        __init__(self, budget, code)
+        setActiveCode(self, code)
+        runMessage(self, message, nt, arg=None)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/seg}Page
+        getBudget(self)
+        getActviCode(self)
+    """
+
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path, path_record=(0,))
+        
+        budget: the budget (base.obra object)
+        page: weak reference from Page instance which creates this class
+        path: the path position of the description in the page
+        path_record: the path of the active record
+        
+        Creates an shows the scroledwindow that contain icon files
+        of the record to be showed in a pane.
+        """
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        self.__active_path_record = path_record
+        self.__active_code = budget.getCode(self.__active_path_record)
+        _budget = budget
+        _record = self.__budget.getRecord(self.__budget.getCode(
+                    self.__active_path_record))
+                    
+        self.__icon_box = self.getIconBox(_record)
+        _scrollwindow = gtk.ScrolledWindow()
+        _scrollwindow.set_policy(gtk.POLICY_ALWAYS,
+                                 gtk.POLICY_NEVER)
+        
+        self.__icon_box.show()
+        _scrollwindow.add_with_viewport(self.__icon_box)
+        _scrollwindow.show()
+        self.__widget = _scrollwindow
+
+    def getIconBox(self, record):
+        """getIconBox(self, record)
+        
+        record: the active record object
+        
+        Creates and returns the box whith te icon files of the active record.
+        """
+        ## TODO: add others filetypes: avi, pdf, ppt...
+        _files = record.getFiles()
+        _hbox = gtk.HBox()
+        _frame = gtk.Frame()
+        _frame.set_shadow_type(gtk.SHADOW_IN)
+        for _file in _files:
+            _path = os.path.dirname(self.__budget.filename)
+            _file_path = os.path.join(_path, _file.name)
+            _filetype = utils.getFiletype(_file_path)
+            _box = gtk.VBox()
+            if _filetype == "image":
+                _event_box = gtk.EventBox()
+                try:
+                    _image_pixbuf = gtk.gdk.pixbuf_new_from_file(_file_path)
+                    _image_pixbuf = _image_pixbuf.scale_simple(64, 64,
+                                    gtk.gdk.INTERP_BILINEAR)
+                except:
+                    _image_pixbuf = gtk.gdk.pixbuf_new_from_file(
+                                    globals.getAppPath("IMAGE-ICON"))
+                    _image_pixbuf = _image_pixbuf.scale_simple(64, 64,
+                                    gtk.gdk.INTERP_BILINEAR)
+                _image_icon = gtk.Image()
+                _image_icon.set_from_pixbuf(_image_pixbuf)
+                _image_icon.show()
+                _event_box.add(_image_icon) 
+                _box.pack_start(_event_box, False, False, 5)
+                _event_box.connect("button-press-event", self.launchFile,
+                                   "image", _file_path)
+                _event_box.show()
+                
+            elif _filetype == "dxf":
+                _event_box = gtk.EventBox()
+                _dxf_icon = gtk.Image()
+                _dxf_pixbuf = gtk.gdk.pixbuf_new_from_file(
+                                    globals.getAppPath("DXF-ICON"))
+                _dxf_pixbuf = _dxf_pixbuf.scale_simple(64, 64,
+                              gtk.gdk.INTERP_BILINEAR)
+                _dxf_icon.set_from_pixbuf(_dxf_pixbuf)
+                _dxf_icon.show()
+                _event_box.add(_dxf_icon)
+                _box.pack_start(_event_box, False, False, 5)
+                _event_box.connect("button-press-event", self.launchFile, 
+                                   "dxf", _file_path)
+                _event_box.show()
+            _label_event_box = gtk.EventBox()
+            _label = gtk.Label(_file.name)
+            _label_event_box.add(_label)
+            _label_event_box.show()
+            _label.show()
+            _box.pack_start(_label_event_box, False, False, 5)
+            _box.show()
+            _hbox.pack_start(_box, False, False, 5)
+        _hbox.show()
+        _frame.add(_hbox)
+        return _frame
+
+    def launchFile(self, widget, event, kind, file_path):
+        """launchFile(self, widget, event, kind, file_path)
+        
+        widget: the widget that emit the signal
+        event: the event that emit the signal
+        king: kind of file
+        file_path: the path file to be launch
+        
+        Launch the file if a double click emit the signal.
+        Method connected to "button-press-event" signal in images event box
+        """
+        if event.type is gtk.gdk._2BUTTON_PRESS:
+            openwith.launch_file(kind, file_path)
+
+    def setActivePathRecord(self, path_record):
+        """def setActivePathRecord(self, path_record))
+        
+        path_record: active path record
+        Set the new path code to show its description text.
+        """
+        _budget = self.__budget
+        self.__active_path_record = path_record
+        _code = _budget.getCode(self.__active_path_record)
+        _record = self.__budget.getRecord(_code)
+        self.__icon_box.destroy()
+        self.__icon_box =  self.getIconBox(_record)
+        self.__icon_box.show()
+        self.__widget.add_with_viewport(self.__icon_box)
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                self.setActivePathRecord(arg)
+        elif message == "clear":
+            self._clear()
+
+    def _clear(self):
+        """def _clear(self)
+        
+        Delete all instance atributes
+        """
+        del self.__hbox
+        del self.__widget
+        del self.__path
+        del self.__budget
+        del self.__active_code
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+
+    def getPage(self):
+        """def getPage(self)
+        
+        return the weak reference from Page instance
+        """
+        return self.__page
+
+    def setPage(self, page):
+        """def setPage(self)
+        
+        set the weak reference from Page instance
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the budget object
+        """
+        return self.__budget
+
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+
+    path = property(getPath, setPath, None,
+        "Path that identifie the item in the page notebook")
+    widget = property(getWidget, None, None,
+        "The main widget (gtk.ScrolledWindow)")
+    page = property(getPage, setPage, None,
+        "Weak reference from Page instance which creates this class")
+    budget = property(getBudget, None, None,
+        "Budget object")
+    active_path_record = property(getActivePathRecord, None, None,
+        "Active Path Record")
+
+
+class TextWindow(object):
+    """gui.TextWindow
+    
+    Description:
+        Class to show a description text of a record in a new gtk window
+    Constructor:
+        TextWindow(code, text)
+        code: code of the record
+        text: description text of the record
+    Ancestry:
+    +-- object
+      +-- TextWindow
+    Atributes:
+    Methods:
+        __init__(self, code, text)
+        main(self)
+        destroy(self, widget)
+    """
+
+    def __init__(self, code, text):
+        """def __init__(self, code, text)
+        
+        code: code of the record
+        text: description text of the record
+        Creates an shows the window.
+        """
+        _window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+        _window.set_resizable(True)
+        _window.set_default_size(700, 300)
+        _window.set_title(utils.mapping(_("$1 text"), (code,)))
+        _window.set_border_width(0)
+        _box1 = gtk.VBox(False, 0)
+        _window.add(_box1)
+        _box1.show()
+        _sw = gtk.ScrolledWindow()
+        _sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        _textview = gtk.TextView()
+        _textview.set_wrap_mode(gtk.WRAP_WORD)
+        _textbuffer = _textview.get_buffer()
+        _sw.add(_textview)
+        _sw.show()
+        _textview.show()
+        _box1.pack_start(_sw)
+        _textbuffer.set_text(text)
+        _window.connect("destroy", self.destroy)
+        _window.show()
+
+    def main(self):
+        """def main(self) 
+        
+        Starts the GTK+ event processing loop.
+        """
+        gtk.main()
+
+    def destroy(self, widget):
+        """destroy(self, widget)
+        widget: the widget where the event is emitted from
+        Method connected to "destroy" signal of window widget
+        This signal is emited when the method connected to "delete_event"
+        signal returns True or when the program call the destroy() method of
+        the gtk.Window widget.
+        The window is closed and the GTK+ event processing loop is ended.
+        """
+        gtk.main_quit()
+
+class CompanyView(object):
+    """gui.CompanyView:
+    
+    Description:
+        Class to show the company records of a budget
+    Constructor:
+        CompanyView(budget, page, path)
+        budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the path of the List in the Page
+        Returns the newly created CompanyView instance
+    Ancestry:
+    +-- object
+      +-- CompanyView
+    Atributes:
+        "budget": Budget to show, base.obra instance.
+        "active_path_record"
+        "widget": Window that contains the main widget,
+            (gtk.ScrolledWindow)
+        "path": Pane page identifier
+        "page": weak reference from Page instance which creates this class
+        "__methond_message": Method to send messages to the page
+    Methods:
+        __init__(self, budget, page, path, path_record=(0,))
+        runMessage(self, message, path, arg=None)
+        _clear(self)
+        getWidget(self)
+        {get/set}Path
+        {get/set}Page
+        getBudget(self)
+        getActivePathRecord(self)
+    """
+
+    def __init__(self, budget, page, path, path_record=(0,)):
+        """def __init__(self, budget, page, path, path_record=(0,))
+        
+        budget: budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        path: tuple that represents the path of the List in the Page
+        path_record: path of the active record in the budget
+        
+        Sets the init atributes
+        Creates the 
+
+        """
+        self.__selection = None
+        # Seting init args
+        if not isinstance(budget, base.Budget):
+            raise ValueError, _("Argument must be a Budget object")
+        self.__budget = budget
+        self.__page = page
+        self.__path = path
+        self.__active_path_record = path_record
+        # HVox
+        self.__hbox = gtk.HPaned()
+        self.__hbox.set_position(230)
+        # TreeStore
+        self.__treestore = gtk.TreeStore(str, str)
+        self.setTreeStoreValues()
+        # Select Treeview
+        self.__select_treeview = gtk.TreeView(self.__treestore)
+        self.__select_treeview.set_enable_search(False)
+        self.__select_treeview.set_reorderable(False)
+        self.__select_treeview.set_headers_visible(False)
+        self.__select_treeview.show()
+        # Scrolled_window
+        self.__scrolled_window = gtk.ScrolledWindow()
+        self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
+            gtk.POLICY_AUTOMATIC)
+        self.__scrolled_window.add(self.__select_treeview)
+        # colors
+        _text_color = gtk.gdk.color_parse(globals.color["TEXT"])
+        _background_color = [
+            gtk.gdk.color_parse(globals.color["UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["EVEN"])]
+        self.__code_column = gtk.TreeViewColumn()
+        self.__code_column.set_clickable(True)
+        self.__code_column.set_fixed_width(200)
+        _code_cell = gtk.CellRendererText()
+        _code_cell.set_property('foreground-gdk', _text_color)
+        self.__code_column.pack_start(_code_cell, True)
+        self.__code_column.add_attribute(_code_cell, 'text', 0)
+        _summary_cell = gtk.CellRendererText()
+        _summary_cell.set_property('foreground-gdk', _text_color)
+        self.__code_column.pack_start(_summary_cell, True)
+        self.__code_column.add_attribute(_summary_cell, 'text', 1)
+        # Index column
+        self.__select_treeview.append_column(self.__code_column)
+        # control selection
+        self.__treeselection = self.__select_treeview.get_selection()
+        self.__treeselection.set_mode(gtk.SELECTION_SINGLE)
+        self.__treeselection.set_select_function(self.controlSelection)
+        # Show
+        self.setColumnsHeaders()
+        self.__scrolled_window.show()
+        # Option View
+        self.__option_View = OptionView("")
+        # Selection
+        self.__select_treeview.set_cursor((0,), None, False)
+        self.__select_treeview.grab_focus()
+        #
+        self.__hbox.add1(self.__scrolled_window)
+        self.__hbox.add2(self.__option_View.widget)
+        self.__hbox.show()
+        self.__widget = self.__hbox
+
+    def setOptions(self, type):
+        if type == "company":
+            _options = [("code", _("Code"), "string",
+                         _("""Code that define the company""")),
+                        ("summary", _("Summary"), "string",
+                         _("""Summary of the company name""")),
+                        ("name", _("Name"), "string",
+                         _("""Complete name""")),
+                        ("cif", _("CIF"), "string",
+                         _("""Fiscal identifier number""")),
+                        ("web", _("Web"), "string",
+                         _("""Company web page""")),
+                        ("email", _("Email"), "string",
+                         _("""Company email""")),
+                        ]
+            self.__option_View.setOptions(_options)
+        elif type == "office":
+            _options = [("type", _("Type"), "string",
+                         _("""Type of Office:
+                           C: Central office
+                           D: Local office
+                           R: Performer""")),
+                        ("subname", _("Name"), "string",
+                         _("Office name")),
+                        ("address", _("Address"), "string",""),
+                        ("postal code", _("Postal code"), "string",""),
+                        ("town", _("Town"), "string",""),
+                        ("province", _("Province"), "string",""),
+                        ("country", _("Country"), "string",""),
+                        ("phone", _("Phone"), "list",
+                         _("Phone numbers of the office")),
+                        ("fax", _("Fax"), "list",
+                         _("Fax numbers of the office")),
+                        ("contact person", _("Contact person"), "string",
+                         _("Contact persons in the office")),
+                       ]
+            self.__option_View.setOptions(_options)
+        else:
+            print _("Unknow Option Type")
+    def setOptionValues(self, company_key):
+        self.__option_View.setValues(_values)
+
+    def setTreeStoreValues(self):
+        """def setListstoreValues(self)
+        
+        Sets the treestore values from  the budget
+        """
+        _budget = self.__budget
+        _company_keys = _budget.getCompanyKeys()
+        for _company_key in _company_keys:
+            _company = _budget.getCompany(_company_key)
+            _values = [_company_key, _company.summary]
+            _treeiter = self.__treestore.append(None, _values)
+            _offices = _company.offices
+            for _office in _offices:
+                # TODO: Test offices
+                _values = [_office.officeType, _office.subname]
+                self.__treestore.append(_treeiter, _values)
+
+    def setColumnsHeaders(self):
+        """def setColumnsHeaders(self)
+        
+        Sets the headers column values
+        """
+        #self.columns[1].set_title(_("Type"))  # Σ parcial Σ total
+        #self.columns[2].set_title(_("Comment"))
+        #self.columns[3].set_title(_("N"))
+        #self.columns[4].set_title(_("Length"))
+        #self.columns[5].set_title(_("Width"))
+        #self.columns[6].set_title(_("Height"))
+        pass
+
+    def controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: selection
+        
+        Method connected to set_selection_function() 
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        The selection changes the company/office in the option treeview
+        """
+        if len(selection) == 1:
+            # The selection is a company
+            _company_key = self.__treestore[selection][0]
+            _company = self.__budget.getCompany(_company_key)
+            _selection = "company"
+            _values = _company.values
+        else:
+            # The selection is a office
+            _company_key = self.__treestore[selection[:1]][0]
+            _company = self.__budget.getCompany(_company_key)
+            _selection = "office"
+            _office = _company.offices[selection[1]]
+            _values = _office.values
+        if not self.__selection == _selection:
+            self.__selection = _selection
+            self.setOptions(_selection)
+        self.__option_View.setValues(_values)
+
+        return True
+
+    def showMessageRecord(self, record_path):
+        """def showMessageRecord(self, record_path)
+        
+        record_path: the path of the record to show
+        Method connected to "change_active" message
+        Show the record especified in the "change_active" message
+        """
+        self.__active_path_record = record_path
+
+    def runMessage(self, message, path, arg=None):
+        """def runMessage(self, message, path, arg=None)
+        
+        message: the message type
+            "change_active": change the active record
+            "clear": clear instance
+        path: tuple that identifies the pane in the notebook page
+        arg: tuple whit two items:
+            0: record path in the budget
+            1: record code
+        This method receives a message and executes its corresponding action
+        """
+        _budget = self.__budget
+        if message == "change_active":
+            if _budget.hasPath(arg):
+                _path_record = arg
+                self.showMessageRecord( _path_record)
+            pass
+        elif message == "clear":
+            self._clear()
+
+    def colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
+        """def colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        
+        column: the gtk.TreeViewColumn in the treeview
+        cell_renderer: a gtk.CellRenderer
+        tree_model: the gtk.TreeModel
+        iter: gtk.TreeIter pointing at the row
+        lcolor: list with 2 gtk colors for even and uneven record
+        
+        Method connected to "set_cell_data_func" of many column
+        The set_cell_data_func() method sets the data function (or method) 
+        to use for the column gtk.CellRenderer specified by cell_renderer.
+        This function (or method) is used instead of the standard attribute
+        mappings for setting the column values, and should set the attributes
+        of the cell renderer as appropriate. func may be None to remove the
+        current data function. The signature of func is:
+        -def celldatafunction(column, cell, model, iter, user_data)
+        -def celldatamethod(self, column, cell, model, iter, user_data)
+        where column is the gtk.TreeViewColumn in the treeview, cell is the
+        gtk.CellRenderer for column, model is the gtk.TreeModel for the
+        treeview and iter is the gtk.TreeIter pointing at the row.
+        
+        The method sets cell background color for all columns
+        and text for index and amount columns.
+        """
+        _row_path = tree_model.get_path(iter)
+        _number = _row_path[-1]
+        if column is self.__index_column:
+            cell_renderer.set_property('text', str(_number + 1))
+            self.__index_column.get_cell_renderers()[1].set_property(
+                'cell-background-gdk', lcolor[_number % 2])
+        if self.__treeview.get_cursor() == (_row_path,column):
+            cell_renderer.set_property('cell-background-gdk',
+                gtk.gdk.color_parse(globals.color["ACTIVE"]))
+        else:
+            cell_renderer.set_property('cell-background-gdk',
+                lcolor[_number % 2])
+
+    def _clear(self):
+        """def _clear(self)
+        
+        it deletes the __budget value
+        this would not be necessary if there were not circular references,
+        which are pending to fix
+        """
+        del self.__budget
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__widget
+
+    def getPath(self):
+        """def getPath(self)
+        
+        return the tuple that identifies the pane in the notebook page
+        """
+        return self.__path
+
+    def setPath(self, path):
+        """def setPath(self)
+        
+        sets the tuple that identifies the pane in the notebook page
+        """
+        self.__path = path
+    def getPage(self):
+        """def getPage(self)
+        
+        return the Page
+        """
+        return self.__page
+
+    def setPage(self,page):
+        """def setPage(self)
+        
+        set the Page
+        """
+        self.__page = page
+
+    def getBudget(self):
+        """def getBudget(self)
+        
+        return the Budget objet
+        """
+        return self.__budget
+    
+    def getActivePathRecord(self):
+        """def getActivePathRecord(self)
+        
+        return the Active Path Record
+        """
+        return self.__active_path_record
+    
+    active_path_record =  property(getActivePathRecord, None, None,
+        "Active path record")
+    widget = property(getWidget, None, None,
+        "main widget")
+    path = property(getPath, setPath, None,
+        "Path that identifies the item in the page notebook")
+    page = property(getPage, setPage, None,
+        "Weak reference from Page instance which creates this class")
+    budget =  property(getBudget, None, None,
+        "Budget object")
+
+
+class OptionView(object):
+    """gui.OptionView:
+    
+    Description:
+        It creates a treeview whith the column "Option Name" "Value"
+        and "Type" to show and edit Options
+    Constructor:
+        OptionView(option_list)
+        option_list: list of options
+            (option_name, type)
+    Ancestry:
+    +-- object
+      +-- OptionView
+    Atributes:
+        "__liststore"
+        "__treeview"
+        "__option_column"
+        "__value_column"
+        "__type_column"
+        "__treeselection"
+        "__widget": Main windget
+        "__option_list"
+        "__option_dict"
+        "__description_label"
+        "option_types"
+        "widget": __widget
+    Methods:
+        __init__(self, option_list)
+        createColumn(self, args)
+        createTextBaseColumn(self,args)
+        createBaseColumn(self,args)
+    """
+
+    def __init__(self, option_list):
+        """__init__(self, option_list)
+        
+        """
+        self.__option_dict = {}
+        self.__option_list = []
+        self.option_types = {"boolean" : _("Boolean"),
+                             "integer": _("Integer"),
+                             "string":  _("Text"),
+                             "color" : _("Color"),
+                             "list" : _("List")}
+        # ListStore
+        self.__liststore = gtk.ListStore(str, str, str, str, str)
+        # Treeview
+        self.__treeview = gtk.TreeView(self.__liststore)
+        self.__treeview.set_enable_search(False)
+        self.__treeview.set_reorderable(False)
+        self.__treeview.set_headers_clickable(False)
+        # vbox
+        _vbox = gtk.VBox()
+        # Scrolled_window
+        _scrolled_window = gtk.ScrolledWindow()
+        _scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
+                                        gtk.POLICY_AUTOMATIC)
+        _scrolled_window.add(self.__treeview)
+        _scrolled_window.show()
+        _vbox.pack_start(_scrolled_window)
+        # colors
+        _text_color = gtk.gdk.color_parse(globals.color["TEXT"])
+        _background_color = [
+            gtk.gdk.color_parse(globals.color["UNEVEN"]),
+            gtk.gdk.color_parse(globals.color["EVEN"])]
+        # Option Column
+        self.__option_column = gtk.TreeViewColumn()
+        self.__option_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.__option_column.set_fixed_width(150)
+        self.__option_column.set_resizable(True)
+        _option_cell = gtk.CellRendererText()
+        _option_cell.set_property('foreground-gdk', _text_color)
+        self.__option_column.pack_start(_option_cell, True)
+        self.__option_column.set_cell_data_func(_option_cell, self.colorCell,
+                                                _background_color)
+        self.__option_column.set_title(_("Option name"))
+        self.__option_column.add_attribute(_option_cell, 'text', 1)
+        self.__treeview.append_column(self.__option_column)
+        # Value Column
+        self.__value_column = gtk.TreeViewColumn()
+        self.__value_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.__value_column.set_fixed_width(275)
+        self.__value_column.set_resizable(True)
+        _value_cell = gtk.CellRendererText()
+        _value_cell.set_property('foreground-gdk', _text_color)
+        self.__value_column.pack_start(_value_cell, True)
+        self.__value_column.set_cell_data_func(_value_cell, self.colorCell,
+                                               _background_color)
+        self.__value_column.set_title(_("Value"))
+        self.__value_column.add_attribute(_value_cell, 'text', 2)
+        self.__treeview.append_column(self.__value_column)
+        # Type Column
+        self.__type_column = gtk.TreeViewColumn()
+        self.__type_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.__type_column.set_fixed_width(70)
+        self.__type_column.set_resizable(True)
+        _type_cell = gtk.CellRendererText()
+        _type_cell.set_property('foreground-gdk', _text_color)
+        self.__type_column.pack_start(_type_cell, True)
+        self.__type_column.set_cell_data_func(_type_cell, self.colorCell,
+                                               _background_color)
+        self.__type_column.set_title(_("Type"))
+        self.__treeview.append_column(self.__type_column)
+        # End Column
+        _end_column = gtk.TreeViewColumn()
+        _end_column.set_clickable(False)
+        _end_cell = gtk.CellRendererText()
+        _end_cell.set_property('cell-background-gdk',
+            gtk.gdk.color_parse(globals.color["UNEVEN"]))
+        _end_column.pack_start(_end_cell, True)
+        self.__treeview.append_column(_end_column)
+        # Connect
+        self.__treeview.connect("key-press-event", self.treeviewKeyPressEvent)
+        self.__treeview.connect("button-press-event", self.treeviewClickedEvent)
+        # control selection
+        self.__treeselection = self.__treeview.get_selection()
+        self.__treeselection.set_mode(gtk.SELECTION_MULTIPLE)
+        self.__treeselection.set_select_function(self.controlSelection)
+        # labels
+        _frame = gtk.Frame()
+        _frame.set_shadow_type(gtk.SHADOW_OUT)
+        _vbox2 = gtk.VBox()
+        _frame.add(_vbox2)
+        _alignement = gtk.Alignment(xalign=0, yalign=0, xscale=0, yscale=0)
+        _alignement.set_padding(0, 0, 12, 0)
+        _label = gtk.Label()
+        _label.set_markup("<b>" + _("Description:") + "</b>")
+        _label.show()
+        _alignement.add(_label)
+        _alignement.show()
+        _alignement2 = gtk.Alignment(xalign=0, yalign=0, xscale=0, yscale=0)
+        _alignement2.set_padding(0, 0, 24, 0)
+        self.__description_label  = gtk.Label()
+        self.__description_label.show()
+        _alignement2.add(self.__description_label)
+        _alignement2.show()
+        _vbox2.pack_start(_alignement, False)
+        _vbox2.pack_start(_alignement2, False)
+        _vbox2.show()
+        _frame.show()
+        _vbox.pack_start(_frame, False)
+        # Show
+        self.__treeview.show()
+        _vbox.show()
+        self.__widget = _vbox
+
+    def treeviewKeyPressEvent(self, widget, event):
+        """def treeviewKeyPressEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: Key Press event
+        Method connected to "key-press-event" signal
+        The "key-press-event" signal is emitted when the user presses a key
+        on the keyboard.
+        Returns :TRUE to stop other handlers from being invoked for the event.
+        Returns :FALSE to propagate the event further.
+        
+        If the user press the right cursor button and the cursor is in the
+        value column or pres the left cursor button and the cursor is
+        in the value column the event is estoped, else the event is propagated. 
+        """
+        (_cursor_path, _column) = self.__treeview.get_cursor()
+        if (event.keyval == gtk.keysyms.Right \
+           and _column == self.__value_column) \
+           or (event.keyval == gtk.keysyms.Left \
+           and _column == self.__value_column):
+            return True
+        else:
+            _description = self.__liststore[_cursor_path][4]
+            self.__description_label.set_text(_description)
+            return False
+
+    def treeviewClickedEvent(self, widget, event):
+        """def treeviewClickedEvent(self, widget, event)
+        
+        widget: treewiew widget
+        event: clicked event
+        Method connected to "button-press-event" signal
+        The "button-press-event" signal is emitted when a mouse button is
+        pressed.
+        Returns TRUE to stop other handlers from being invoked for the event.
+        Returns FALSE to propagate the event further.
+        
+        The cursos is moved to value column.
+        """
+        path_at_pos = self.__treeview.get_path_at_pos(int(event.x),
+                                                      int(event.y))
+        if not path_at_pos is None:
+            _path_cursor, _column, _x, _y = path_at_pos
+            _description = self.__liststore[_path_cursor][4]
+            self.__description_label.set_text(_description)
+            if _column == self.__value_column:
+                return False
+            else:
+                self.__treeview.set_cursor(_path_cursor,self.__value_column,
+                                           True)
+                self.__treeview.grab_focus()
+                return True
+        return True
+    
+    def controlSelection(self, selection):
+        """def controlSelection(self, selection)
+        
+        selection: treeselection
+        
+        Method connected to set_selection_function() 
+        This method is called before any node is selected or unselected,
+        giving some control over which nodes are selected.
+        The selection function should return TRUE if the state
+        of the node may be toggled, and FALSE if the state of the node should
+        be left unchanged.
+        
+        Return False so none row is selected
+        """
+        return False
+
+
+    def colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
+        """def colorCell(self, column, cell_renderer, tree_model, iter, lcolor)
+        
+        column: the gtk.TreeViewColumn in the treeview
+        cell_renderer: a gtk.CellRenderer
+        tree_model: the gtk.TreeModel
+        iter: gtk.TreeIter pointing at the row
+        lcolor: list with 2 gtk colors for even and uneven record
+        
+        Method connected to "set_cell_data_func" of the column
+        The set_cell_data_func() method sets the data function (or method) 
+        to use for the column gtk.CellRenderer specified by cell_renderer.
+        This function (or method) is used instead of the standard attribute
+        mappings for setting the column values, and should set the attributes
+        of the cell renderer as appropriate. func may be None to remove the
+        current data function. The signature of func is:
+        -def celldatafunction(column, cell, model, iter, user_data)
+        -def celldatamethod(self, column, cell, model, iter, user_data)
+        where column is the gtk.TreeViewColumn in the treeview, cell is the
+        gtk.CellRenderer for column, model is the gtk.TreeModel for the
+        treeview and iter is the gtk.TreeIter pointing at the row.
+        
+        The method sets cell background color for all columns
+        and text for type column.
+        """
+        _row_path = tree_model.get_path(iter)
+        _number = _row_path[-1]
+        if self.__treeview.get_cursor() == (_row_path,column):
+            cell_renderer.set_property('cell-background-gdk',
+                gtk.gdk.color_parse(globals.color["ACTIVE"]))
+        else:
+            cell_renderer.set_property('cell-background-gdk',
+                lcolor[_number % 2])
+        if column is self.__type_column:
+            _type = self.option_types[tree_model[_row_path][3]]
+            cell_renderer.set_property('text', _type)
+
+    def setOptions(self, option_list):
+        """setOptions(self, option_list)
+        
+        option_list: list of tuples
+            (option, option name, type)
+            option: option identifier
+            option name: a string with the option name
+            Description: a string with the option description
+            type: can be "boolean"
+                         "integer"
+                         "string"
+                         "color"
+        Sets the Options in the treeview rows
+        """
+        self.__option_dict = {}
+        self.__option_list = []
+        self.__liststore.clear()
+        if isinstance(option_list, list):
+            for _option in option_list:
+                if isinstance(_option, tuple) and len(_option) == 4:
+                    _option_key = _option[0]
+                    _option_name = _option[1]
+                    _option_type = _option[2]
+                    _option_description = _option[3]
+                    if isinstance(_option_key, str) and \
+                       (isinstance(_option_name, str) or\
+                       isinstance(_option_name, unicode))and \
+                       _option_type in self.option_types.keys():
+                        self.__liststore.append([_option_key, _option_name, "",
+                            _option_type, _option_description])
+                        self.__option_dict[_option_key] = [_option_name, "",
+                            _option_type, _option_description]
+                        self.__option_list.append(_option_key)
+                    else:
+                        print _("Option values must be strings")
+                else:
+                    print _("Option must be a tuple with 4 items")
+        else:
+            print _("Option list must be a list")
+            return
+    def setValues(self, values):
+        """setValues(self, values)
+        
+        values: dictionary {option : value}
+
+        Sets the Options values
+        """
+        if isinstance(values, dict):
+            for _option, _value in values.iteritems():
+                if _option in self.__option_dict:
+                    _type = self.__option_dict[_option][2]
+                    if _type == "boolean":
+                        if isinstance(_value, bool):
+                            _num = self.__option_list.index(_option)
+                            _iter = self.__liststore.get_iter((_num,))
+                            self.__liststore.set_value(_iter, 2, _value)
+                            self.__option_dict[_option][1] = _value
+                        else:
+                            print _("Icorrect type, must be boolean")
+                    elif _type == "integer":
+                        try:
+                            _value = int(_value)
+                        except ValueError:
+                            print _("Icorrect type, must be integer")
+                        else:
+                            _num = self.__option_list.index(_option)
+                            _iter = self.__liststore.get_iter((_num,))
+                            self.__liststore.set_value(_iter, 2, _value)
+                            self.__option_dict[_option][1] = _value
+                    elif _type == "string":
+                        if isinstance(_value, str):
+                            _num = self.__option_list.index(_option)
+                            _iter = self.__liststore.get_iter((_num,))
+                            self.__liststore.set_value(_iter, 2, _value)
+                            self.__option_dict[_option][1] = _value
+                        else:
+                            print _("Icorrect type, must be string")
+                    elif _type == "list":
+                        if isinstance(_value, list):
+                            _num = self.__option_list.index(_option)
+                            _iter = self.__liststore.get_iter((_num,))
+                            _str_value = ""
+                            for _item_value in _value:
+                                _str_value = _str_value + _item_value + ","
+                            if _str_value[-1] == ",":
+                                _str_value = _str_value[:-1]
+                            self.__liststore.set_value(_iter, 2, _str_value)
+                            self.__option_dict[_option][1] = _value
+                        else:
+                            print _("Icorrect type, must be list")
+                    elif _type == "color":
+                        if isinstance(_value, str):
+                            try:
+                                _color = gtk.gdk.color_parse(_value)
+                            except ValueError:
+                                print _("Icorrect type, must be a parseable " \
+                                        "color")
+                            else:
+                                _num = self.__option_list.index(_option)
+                                _iter = self.__liststore.get_iter((_num,))
+                                self.__liststore.set_value(_iter, 2, _value)
+                                self.__option_dict[_option][1] = _value
+                    else:
+                        print _("Type must be boolean, integer, string or "\
+                                "color")
+                else:
+                    print _("Value must be in the option dict")
+        else:
+            print _("Values must be a dict")
+        self.__treeview.set_cursor((0),self.__value_column, False)
+        self.__treeview.grab_focus()
+        (_cursor_path, _column) = self.__treeview.get_cursor()
+        _description = self.__liststore[_cursor_path][4]
+        self.__description_label.set_text(_description)
+
+    def getWidget(self):
+        """def getWidget(self)
+        
+        return the main widget (gtk.ScrolledWindow)
+        """
+        return self.__widget
+    widget = property(getWidget, None, None,
+        "The main widget (gtk.ScrolledWindow)")
+
+
+class OpenDurusDatabase(object):
+    """gui.OpenFiebdc
+    
+    Description:
+        Class to show a dialog to open a durus price database
+    Constructor:
+       OpenDurusDatabase()
+    Ancestry:
+    +-- object
+      +-- OpenDurusDatabase
+    Atributes:
+        "_openMethod": The method to open the file
+        "__file": the filename to open
+        "__window": the File Selection window
+    Methods:
+        __init__(self)
+        setActiveCode(self, code)
+    """
+    def __init__(self, openMethod):
+        self.__openMethod = openMethod
+        self.__file = None
+        self.__window = gtk.FileSelection("Abrir Archivo")
+        self.__window.connect("destroy", self.destroy)
+        self.__window.ok_button.connect("clicked", self._openFile)
+        self.__window.cancel_button.connect("clicked", 
+            lambda w: self.__window.destroy())
+        self.__window.set_filename(globals.getHomePath("DURUS-DATABASE"))
+        self.__window.show()
+
+    def destroy(self, widget):
+        gtk.main_quit()
+
+    def main(self):
+        gtk.main()
+
+    def _openFile(self, w):
+        self.__file = self.__window.get_filename()
+        _filename = os.path.basename(self.__file)
+        _filename_list = _filename.split(".")
+        _filename_ext = _filename_list[-1]
+        if _filename == "":
+            print _("No file selected")
+        elif len(_filename_list) < 2 or _filename_ext != "durus":
+            print _("The filename must have durus extension")
+        else:
+            try:
+                self.__openMethod(self.__window.get_filename())
+                self.__window.destroy()
+            except IOError:
+                print utils.mapping("IOError, $1", (self.__file,))