changeset 23:65e7ae0d0e63

GTK2 to GTK3
author Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>
date Thu, 02 May 2019 16:31:17 +0200
parents 7bd4ca56607d
children 2b393934f1db
files .hgignore Generic/__init__.py Generic/base.py Generic/durusdatabase.py Generic/fiebdc.py Generic/globalVars.py Generic/openwith.py Generic/utils.py Gtk/__init__.py Gtk/gui.py Gtk/importFiebdc.py __init__.py images/close.svg images/throbber.gif images/throbber.png images/throbber.svg mo/es/LC_MESSAGES/pyArq-Presupuestos.mo mo/pyArq-Presupuestos.es.po mo/pyArq-Presupuestos.pot pyArq-Presupuestos.py
diffstat 20 files changed, 3643 insertions(+), 3333 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Sep 30 17:16:50 2014 +0200
+++ b/.hgignore	Thu May 02 16:31:17 2019 +0200
@@ -3,4 +3,3 @@
 *.bak
 *.pyc
 *.sh
-durus/*
--- a/Generic/__init__.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/__init__.py	Thu May 02 16:31:17 2019 +0200
@@ -23,7 +23,6 @@
 __all__ = [
     'base',
     'config',
-    #'durusdatabase',
     'fiebdc',
     'globalVars',
     'openwith',
--- a/Generic/base.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/base.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File base.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -134,7 +134,11 @@
                 * Description
    +-- __synonyms: synonyms dictionary. TODO
    +-- __root: root record code
-   +-- __decimals: decimals dictionay = { int : Decimals }
+   +-- __decimals:  List with the decimal places used to round the 
+-            result of the calculations with prices and measures
+-            The values are Decimals objects 
+-            The <0> objets is the default Decimals (seted in FIEBDC-3),
+-            The others keys are for the diferent groups of Prices
       * Decimals:
         +-- DN: Number of decimal places of the field "equal-size parts" in the
             measure lines.
@@ -242,9 +246,25 @@
         +-- cif: CIF
         +-- web: web page
         +-- email: email
+   +-- __comment
+   +-- __date
+   +-- __budgetType" A integer. Type of data in budget
+                     0 -> Undefined
+                     1 -> Base data.
+                     2 -> Budget.
+                     3 -> Certificate.
+                     4 -> Base date update.
+   +-- __budgetCerficateOrder" Only valid if budgetType is 3.
+   +-- __budgetCerficateDate" Only valid if budgetType is 3
+   +-- __tec_info": Dictionary whith tecnical information
+                    {ti_code : ["desciption text", "unit"]}
+   +-- __labels": Label dictionary { "label": [ "code", ], }
 """
 
 # Modules
+# python 2/3 compatibility
+#from __future__ import absolute_import, division, print_function, unicode_literals
+
 import re
 import datetime
 import os
@@ -253,6 +273,26 @@
 from Generic import fiebdc
 from Generic import utils
 
+
+# Translatable global Vars
+
+authors = ["Miguel Ángel Bárcena Rodríguez"]
+copyright = "Copyright \xc2\xa9 2019 Autoras de Pyarq Presupuestos"
+website = "http://pyarq.obraencurso.es/pyarq-Presupuestos"
+website_label = "pyarq Presupuestos Web"
+comments = _("""
+A free program of measurements, budgets and control of construction sites.
+In beta development, still there is not a fully functional version.
+""")
+help = _(
+"""
+Usage:
+    pyarqPresupuestos [file]...
+
+Help Options:
+    -h, --help     Show this help
+""")
+
 class Record(object):
     """base.Record:
     
@@ -265,23 +305,23 @@
     +-- object
       +-- Record
     Atributes:
-        "code": Code string
-        "recordType": RecordType object
-        "synonyms": List of synonym codes.
-        "parents":List of parent codes
-        "children": Decomposition list,
+        "code": Write/Read. Code string
+        "recordType": Write/Read. RecordType object
+        "synonyms": Write/Read. List of synonym codes.
+        "parents": Write/Read. List of parent codes
+        "children": Write/Read. Decomposition list,
                   list of "Decomposition" instances
-        "unit": measure unit of the record
-        "summary": Short description of the record
-        "prices": List of prices/dates
-        "text": Long Description of the record
-        "sheet": Sheet of conditions object
-        "files": List of file object
-        "labels": List of record labels
+        "unit": Write/Read. measure unit of the record
+        "summary": Write/Read. Short description of the record
+        "prices": Read. List of prices/dates
+        "text": Write/Read. Long Description of the record
+        "sheet": Write/Read. Sheet of conditions object
+        "files": Write/Read. List of file object
+        "labels": Write/Read. List of record labels
     Methods:
-        __getstate__(self)
-        __setstate__(self, tuple)
-        __init__(self, filename=None, budget=None)
+        isPercentage
+        percentageMasq
+        hasPercentageMasq(masq)
         {get/set}Code
         {get/set}Synonyms
         {get/set}RecordType
@@ -289,7 +329,6 @@
         {get/set}Summary
         {get/set}Prices
         addPrice
-        _validate_price_date
         getPrice
         getAmount
         getDate
@@ -351,23 +390,42 @@
         self.files = []
         self.labels = []
 
+    def isPercentage(self):
+        if "%" in self.__code or "&" in self.__code:
+            return True
+        else:
+            return False
+
+    def percentageMasq(self):
+        if "%" in self.__code:
+            return self.__code.split("%")[0]
+        elif "&" in self.__code:
+            return self.__code.split("&")[0]
+
+    def hasPercentageMasq(self, masq):
+        if len(self.__code) >= len(masq):
+            _part_code = self.__code[:len(masq)]
+            if _part_code == masq:
+                return True
+        return False
+
     def getCode(self):
         return self.__code
 
     def setCode(self, code):
-        """setCode(self,code)
+        """setCode(code)
         
         Sets the code, must be a valid code
         """
         if not utils.is_valid_code(code)[0]:
-            raise ValueError, utils.mapping(_("Invalid code: $1"),(str(code),))
+            raise ValueError( utils.mapping(_("Invalid code: $1"),(str(code),)) )
         self.__code = code
 
     def getSynonyms(self):
         return self.__synonyms
 
     def setSynonyms(self,synonyms):
-        """setSynonyms(self,synonyms)
+        """setSynonyms(synonyms)
         
         Sets the synonyms codes of the record.
         synonyms must fulfill:
@@ -375,19 +433,19 @@
             - the items must be valid codes
         """
         if not isinstance(synonyms, list):
-            raise TypeError, utils.mapping(_("Synonyms ($1) must be a list, " \
-                  "code: $2"), (str(synonyms), self.__code))
+            raise TypeError( utils.mapping(_("Synonyms ($1) must be a list, " \
+                  "code: $2"), (str(synonyms), str(self.__code))) )
         for code in synonyms:
             if not utils.is_valid_code(code)[0]:
-                raise ValueError, utils.mapping(_("Invalid Code in synomyms "\
-                      "list ($1) code: $2"), (str(code), self.__code))
+                raise ValueError( utils.mapping(_("Invalid Code in synomyms "\
+                      "list ($1) code: $2"), (str(code), str(self.__code))) )
         self.__synonyms = synonyms
 
     def getRecordType(self):
         return self.__recordType
 
     def setRecordType(self, recordType):
-        """setRecordType(self, recordType)
+        """setRecordType(recordType)
         
         Set the record type.
         recordType (hierarchy, type,subtype)
@@ -404,35 +462,35 @@
         return self.__unit
 
     def setUnit(self,unit):
-        """setUnit(self,unit)
+        """setUnit(unit)
         
         Set the unit of measure
         The unit must be a string.
         """
         if not isinstance(unit, str):
-            raise TypeError, utils.mapping(_("Unit ($1) must be a string: $2"),
-                  (str(unit), self.__code))
+            raise TypeError( utils.mapping(_("Unit ($1) must be a string: $2"),
+                  (str(unit), str(self.__code))) )
         self.__unit = unit
 
     def getSummary(self):
         return self.__summary
 
     def setSummary(self,summary):
-        """setSummary(self,summary)
+        """setSummary(summary)
         
         Set the summary of a record
         The summary must be a string.
         """
         if not isinstance(summary, str):
-            raise TypeError, utils.mapping(_("Summary ($1) must be a string: "\
-                  "$1"), (str(summary), self.__code))
+            raise TypeError( utils.mapping(_("Summary ($1) must be a string: "\
+                  "$1"), (str(summary), str(self.__code))) )
         self.__summary = summary
 
     def getPrices(self):
         return self.__prices
 
     def setPrices(self, prices, decimals):
-        """setPrice(self, prices, decimals)
+        """setPrice(prices, decimals)
         
         Set the price list of the record.
         prices must fulfill:
@@ -441,8 +499,8 @@
             - the first item: price must be a float
         """
         if not isinstance(prices, list):
-            raise TypeError, utils.mapping(_("Prices ($1) must be a list: $2"),
-                  (str(prices), self.__code))
+            raise TypeError( utils.mapping(_("Prices ($1) must be a list: $2"),
+                  (str(prices), str(self.__code))) )
         for index in range(len(prices)):
             _price_date = prices[index]
             _price_date = self._validate_price_date(_price_date, decimals)
@@ -450,7 +508,7 @@
         self.__prices = prices
 
     def addPrice(self, price_date, decimals):
-        """addPrice(self, price_date, decimals)
+        """addPrice(price_date, decimals)
         
         Add a price to the price list of the record.
         price must fulfill:
@@ -462,14 +520,14 @@
 
     def _validate_price_date(self, price_date, decimals):
         if not isinstance(price_date, list) and len(price_date) == 2:
-            raise ValueError, utils.mapping(_("Price ($1) must be a list"\
-                  " with two items: $2"), (str(price_date), self.__code))
+            raise ValueError( utils.mapping(_("Price ($1) must be a list"\
+                  " with two items: $2"), (str(price_date), str(self.__code))) )
         _price = price_date[0]
         _date = price_date[1]
         if not isinstance(_price, float):
-            raise TypeError, utils.mapping(_("Price must be a float "\
-                      "number: $1"), (str(_price),))
-        _D = decimals.getD(self.recordType)
+            raise TypeError( utils.mapping(_("Price must be a float "\
+                      "number: $1"), (str(_price),)) )
+        _D = abs(decimals.getD(self.recordType))
         _price = round(_price, _D)
         price_date[0] = _price
         # TODO: validate date
@@ -477,20 +535,20 @@
 
     def getPrice(self, index_price):
         if len(self.__prices) <= index_price:
-            raise IndexError, _("The record do not have this Price. Code: %s"
-                                % self.__code)
+            raise IndexError( _("The record do not have this Price. Code: %s"
+                                % self.__code) )
         return self.__prices[index_price][0]
 
     def getDate(self, index_price):
         if len(self.__prices) <= index_price:
-            raise IndexError, _("The record do not have this Price")
-        return self.__prices[index_price][1]
+            raise IndexError( _("The record do not have this Price") )
+        return self.__prices[index_price][1] 
 
     def getParents(self):
         return self.__parents
 
     def setParents(self,parents):
-        """setParents(self,parents)
+        """setParents(parents)
         
         Sets the list of parents codes of the record.
         parents must fulfill
@@ -498,31 +556,31 @@
             - the items must be valid codes
         """
         if not isinstance(parents, list):
-            raise TypeError, utils.mapping(_("Parents ($1) must be a list: $2"),
-                  (str(parents), self.__code))
+            raise TypeError( utils.mapping(_("Parents ($1) must be a list: $2"),
+                  (str(parents), str(self.__code))) )
         for parent in parents:
             if not utils.is_valid_code(parent)[0]:
-                raise ValueError, utils.mapping(_("Invalid parent code ($1) " \
-                      "in the record: $2"), (str(padre), self.__code))
+                raise ValueError(utils.mapping(_("Invalid parent code ($1) " \
+                      "in the record: $2"), (str(padre), str(self.__code))) )
         self.__parents = parents
 
     def appendParent(self, parent):
-        """appendParent(self, parent)
+        """appendParent(parent)
         
         parent must be a valid code
         Append a parent to the list of parents codes of the record.
 
         """
         if not utils.is_valid_code(parent)[0]:
-            raise ValueError, utils.mapping(_("Invalid parent code ($1) " \
-                  "in the record: $2"), (str(parent), self.__code))
+            raise ValueError( utils.mapping(_("Invalid parent code ($1) " \
+                  "in the record: $2"), (str(parent), str(self.__code))) )
         self.__parents.append(parent)
 
     def getchildren(self):
         return self.__children
 
     def setchildren(self,children):
-        """setchildren(self,children)
+        """setchildren(children)
         
         Sets the list of children of a record
         children must fulfill
@@ -530,13 +588,13 @@
             - the items must be instances of Decomposition class
         """
         if not isinstance(children, list):
-            raise TypeError, utils.mapping(_("children ($1) must be a list, "\
-                  "record: $2"), (str(children), self.__code))
+            raise TypeError( utils.mapping(_("children ($1) must be a list, "\
+                  "record: $2"), (str(children), str(self.__code))) )
         for _child in children:
             if not isinstance(_child, Decomposition):
-                raise ValueError, utils.mapping(_("child ($1) must be a "\
+                raise ValueError( utils.mapping(_("child ($1) must be a "\
                       "Decomposition object, record: $2"),
-                      (str(_child), self.__code))
+                      (str(_child), str(self.__code))) )
             _record_code = self.code
             for _measure_list in [_child.budgetMeasures, _child.certification,
                                   _child.real_cost, _child.cost_goals,
@@ -548,7 +606,7 @@
 
     def appendChild(self, child_code, decimals, factor=0.0, yield_=0.0,
                     measure=0.0, measure_list=None, type_=None, label=None):
-        """appendChildren(self, child_code, factor=0.0, yield_=0.0,
+        """appendChildren(child_code, factor=0.0, yield_=0.0,
                     measure=0.0, measure_list=None, type_=None, label=None))
         
         position:
@@ -582,40 +640,39 @@
         return self.__text
 
     def setText(self,text):
-        """setText(self,text)
+        """setText(text)
         
         Sets the text of the record
         It must be a string
         """
         if not isinstance(text, str):
-            raise TypeError, utils.mapping(_("Text ($1) must be a string, "\
-                  "record: $2"), (str(text), self.__code))
+            raise TypeError( utils.mapping(_("Text ($1) must be a string, "\
+                  "record: $2"), (str(text), str(self.__code))) )
         self.__text = text
 
     def getSheet(self):
         return self.__sheet
 
     def setSheet(self, sheet):
-        """setSheet(self, sheet)
+        """setSheet(sheet)
         
         Sets the sheet of condition object
         """
         if not isinstance(sheet, Sheet):
-            raise ValueError, _("sheet must be a Sheet instance")
+            raise ValueError( _("sheet must be a Sheet instance") )
         self.__sheet = sheet
 
     def getFiles(self):
         return self.__files
 
     def setFiles(self, files):
-        """setFiles(self, files)
+        """setFiles(files)
         
         Sets the files list
         """
-        # TODO: only sets files and File object format (durusdatabase)
         if not isinstance(files, list):
-            raise ValueError, utils.mapping(_("files must be a list: $1"),
-                                              str(files))
+            raise ValueError( utils.mapping(_("files must be a list: $1"),
+                                              str(files)) )
         _files = []
         for file in files:
             if isinstance(file, File):
@@ -625,22 +682,21 @@
                 _type = file[1]
                 _description = file[2]
                 if not os.path.exists(file[0]):
-                    raise ValueError, _("Incorrect path")
+                    raise ValueError( _("Incorrect path") )
                 _file = File(file_path, type_, description)
                 _files.append(_file)
             else:
-                raise ValueError, utils.mapping(_(
-                      "file must be a list or a File object: $1"),str(file))
+                raise ValueError( utils.mapping(_(
+                      "file must be a list or a File object: $1"),str(file)) )
         self.__files = _files
-        
 
     def addFile(self, file_path, type_, description):
-        """addFile(self, file_path, type_, description)
+        """addFile(file_path, type_, description)
         
         Add a file to a record instance
         """
         if not os.path.exists(file_path):
-            raise ValueError, _("Incorrect path")
+            raise ValueError( _("Incorrect path") )
         _name = os.path.basename(file_path)
         _isin = False
         for _ofile in self.__files:
@@ -654,32 +710,32 @@
         return self.__labels
 
     def setLabels(self, labels):
-        """setLabels(self, labels)
+        """setLabels(labels)
         
         Sets the labels list of a record
         """
         if not isinstance(labels, list):
-            raise ValueError, _("labels must be a list")
+            raise ValueError( _("labels must be a list") )
         _labels = []
         for _label in labels:
             if isinstance(_label, str):
                 _labels.append(_label)
             else:
-                raise ValueError, _("label must be a string")
+                raise ValueError( _("label must be a string") )
         self.__labels = _labels
 
     def addLabel(self, label):
-        """addLabel(self, label)
+        """addLabel(label)
         
         Add a label to a record instance
         """
         if not isinstance(label, str):
-            raise ValueError, _("Label must be a string")
+            raise ValueError( _("Label must be a string") )
         if not label in self.__labels:
             self.__labels.append(label)
 
     def getChildPositions(self, child_code):
-        """getChildPath(self, child_code):
+        """getChildPath(child_code):
         
         Try to return positions of a childcode
         """
@@ -723,6 +779,7 @@
     labels = property(getLabels, setLabels, None,
         """Label list""")
 
+
 class ParametricRecord(Record):
     """base.ParametricRecord:
     
@@ -784,7 +841,7 @@
         self.__vars = tuple[17]
         self.__parametric_summary = tuple[18]
         self.__parametric_text = tuple[19]
-    
+
     def __init__(self, budget, code, synonyms, hierarchy, unit, summary,
                  prices, type_, subtype, parents=None, text=None):
         if parents is None:
@@ -813,6 +870,7 @@
 
     def setSelectComment(self, select_comment):
         self.__select_comment = select_comment
+
     def getVar(self, var):
         if var in self.__vars:
             return self.__vars[var]
@@ -851,6 +909,7 @@
         """Seclect comment
         """)
 
+
 class Decomposition(object):
     """base.Decomposition:
     
@@ -872,10 +931,6 @@
         "cost_goals": list of cost goals of construction for months measures
         "cost_planned": list of costs planned and amended cost planned measures
     Methods:
-        __getstate__(self)
-        __setstate__(self, tuple)
-        __init__( position, code, budgetMeasures, certification=None,
-                 real_cost=None, cost_goals=None, cost_planned=None)
         {get/set}position
         {get/set}Code
         {get/set}BudgetMeasures
@@ -884,6 +939,7 @@
         {get/set}CostGoals
         {get/set}CostPlanned
     """
+
     __slots__ = ["_Decomposition__position",
                  "_Decomposition__code",
                  "_Decomposition__budgetMeasures",
@@ -892,10 +948,12 @@
                  "_Decomposition__cost_goals",
                  "_Decomposition__cost_planned",
                 ]
+
     def __getstate__ (self):
         return (self.__position, self.__code, self.__budgetMeasures,
                 self.__certification, self.__real_cost, self.__cost_goals,
                 self.__cost_planned)
+
     def __setstate__(self,tuple):
         self.__position = tuple[0]
         self.__code = tuple[1]
@@ -914,50 +972,65 @@
         self.real_cost = real_cost
         self.cost_goals = cost_goals
         self.cost_planned = cost_planned
+
     def getPosition(self):
         return self.__position
+
     def setPosition(self, position):
         if not isinstance(position, int):
-            raise ValueError, _("Position must be a integer")
+            raise ValueError( _("Position must be a integer") )
         self.__position = position
+
     def getCode(self):
         return self.__code
+
     def setCode(self, code):
         self.__code = code
+
     def getBudgetMeasures(self):
         return self.__budgetMeasures
+
     def setBudgetMeasures(self, budgetMeasures):
         if not isinstance(budgetMeasures, list):
-            raise ValueError, _("BudgetMeasures atribute must be a list")
+            raise ValueError( _("BudgetMeasures atribute must be a list") )
         for _measure in budgetMeasures:
             if not isinstance(_measure, Measure):
-                raise ValueError, _("BudgetMeasures item must be a Measure "/
-                                    "object")
+                raise ValueError( _("BudgetMeasures item must be a Measure "/
+                                    "object") )
         self.__budgetMeasures = budgetMeasures
+
     def getCertification(self):
         return self.__certification
+
     def setCertification(self, certification):
         if not (certification is None or isinstance(certification, list)):
-            raise ValueError, _("Certification atribute must be a list or None")
+            raise ValueError( _("Certification atribute must be a list or None") )
         self.__certification = certification
+
     def getRealCost(self):
         return self.__real_cost
+
     def setRealCost(self, real_cost):
         if not (real_cost is None or  isinstance(real_cost, list)):
-            raise ValueError, _("Real cost atribute must be a list or None")
+            raise ValueError( _("Real cost atribute must be a list or None") )
         self.__real_cost = real_cost
+
     def getCostGoals(self):
         return self.__cost_goals
+
     def setCostGoals(self, cost_goals):
         if not (cost_goals is None or  isinstance(cost_goals, list)):
-            raise ValueError, _("Cost goals atribute must be a list or None")
+            raise ValueError( _("Cost goals atribute must be a list or None") )
         self.__cost_goals = cost_goals
+
     def getCostPlanned(self):
         return self.__cost_planned
+
     def setCostPlanned(self, cost_planned):
         if not (cost_planned is None or  isinstance(cost_planned, list)):
-            raise ValueError, _("Cost Planned atribute must be a list or None")
+            raise ValueError( _("Cost Planned atribute must be a list or None") )
         self.__cost_planned = cost_planned
+
     position = property(getPosition, setPosition, None,
         """Postion of the record in the budget
         """)
@@ -1000,10 +1073,6 @@
         "yield":
         "fixed": If fixed is True the yield is not calculated from measure
     Methods:
-        __getstate__()
-        __setstate__(tuple)
-        __init__(decimals, recordType, measure, lines,
-                 label, factor, yield_)
         getMeasure()
         setMeasure(measure, decimals)
         {get/set}Lines
@@ -1018,15 +1087,18 @@
         calculateMeasure(decimals)
         updateYield(decimals)
     """
+
     __slots__ = ["_Measure__measure",
                  "_Measure__lines",
                  "_Measure__label",
                  "_Measure__factor",
                  "_Measure__yield_",
                  "_Measure__fixed"]
+
     def __getstate__ (self):
         return (self.__measure, self.__lines, self.__label,
                 self.__factor, self.__yield_, self.__fixed)
+
     def __setstate__(self,tuple):
         self.__measure = tuple[0]
         self.__lines = tuple[1]
@@ -1034,6 +1106,7 @@
         self.__factor = tuple[3]
         self.__yield_ = tuple[4]
         self.__fixed = tuple[5]
+
     def __init__(self, decimals, recordType, measure, lines,
                  label, factor, yield_):
         self.setMeasure(measure, decimals)
@@ -1045,45 +1118,50 @@
 
     def getMeasure(self):
         return self.__measure
+
     def setMeasure(self, measure, decimals):
         if not isinstance(measure, float):
-            raise ValueError, utils.mapping(_("Measure must be a float "\
-                  "number. Type: $1"), (type(measure),))
+            raise ValueError( utils.mapping(_("Measure must be a float "\
+                  "number. Type: $1"), (type(measure),)) )
         # TODO: test after
-        _DS = decimals.DS
+        _DS = abs(decimals.DS)
         measure = round(measure, _DS)
         self.__measure = measure
 
     def getLines(self):
         return self.__lines
+
     def setLines(self, lines):
         if not isinstance(lines, list):
-            raise ValueError, _("Lines must be a list")
+            raise ValueError( _("Lines must be a list") )
         for _line in lines:
             if not isinstance(_line, MeasureLine):
-                raise ValueError, _("Line must be a MeasureLine objetc")
+                raise ValueError( _("Line must be a MeasureLine objetc") )
         self.__lines = lines
+
     def getLabel(self):
         return self.__label
+
     def setLabel(self, label):
         self.__label = label
+
     def setFactor(self, factor, decimals, recordType):
         if not isinstance(factor, float):
-            raise ValueError, utils.mapping(_("Factor must be a float number "\
-                  "|$1|"), (factor,))
+            raise ValueError( utils.mapping(_("Factor must be a float number "\
+                  "|$1|"), (str(factor),)) )
         # TODO: test after
-        _DF = decimals.getDF(recordType)
+        _DF = abs(decimals.getDF(recordType))
         factor = round(factor, _DF)
         self.__factor = factor
 
     def getFactor(self):
         return self.__factor
-    
+
     def setYield(self, yield_, decimals, recordType):
         if not isinstance(yield_, float):
-            raise ValueError, _("Yield must be a float number")
+            raise ValueError( _("Yield must be a float number") )
         # TODO: test after
-        _DR = decimals.getDR(recordType)
+        _DR = abs(decimals.getDR(recordType))
         yield_ = round(yield_, _DR)
         self.__yield_ = yield_
 
@@ -1092,7 +1170,7 @@
 
     def setFixed(self, fixed, decimals):
         if not isinstance(fixed, bool):
-            raise ValueError, _("Fixed must be boolean object")
+            raise ValueError( _("Fixed must be boolean object") )
         self.__fixed = fixed
         self.updateYield(decimals)
 
@@ -1162,8 +1240,8 @@
         elif type_ == "A":
             self.lines.extend(_lines)
         else:
-            raise ValueError, utils.mapping(_("Type must be M or A. Type: $1"),
-                                            (type_,))
+            raise ValueError( utils.mapping(_("Type must be M or A. Type: $1"),
+                                            (str(type_),)) )
         self.calculateMeasure(decimals, recordType)
 
     def calculateMeasure(self, decimals, recordType):
@@ -1181,8 +1259,9 @@
                     line.setParcialSubtotal(_parcialSubtotal, decimals)
                     _parcial_total = _acumulated_total
             self.setMeasure(_acumulated_total, decimals)
-            _DR = decimals.getDR(recordType)
+            _DR = abs(decimals.getDR(recordType))
             self.updateYield(decimals, recordType)
+
     def updateYield(self, decimals, recordType):
         if not self.fixed:
             self.setYield(self.measure, decimals, recordType)
@@ -1217,10 +1296,6 @@
         "parcial_subtotal"
         "acumulated_subtotal"
     Methods:
-        __getstate__(self)
-        __setstate__(self, tuple)
-        __init__(self, decimals, type_, comment, units, length, width, height,
-                 formula)
         {get/set}LineType
         {get/set}Comment
         {get/set}Units
@@ -1234,6 +1309,7 @@
         calculateParcial
         eval_formula
     """
+
     __slots__ = ["_MeasureLine__lineType",
                  "_MeasureLine__comment",
                  "_MeasureLine__units",
@@ -1245,10 +1321,12 @@
                  "_MeasureLine__parcial_subtotal",
                  "_MeasureLine__acumulated_subtotal",
                 ]
+
     def __getstate__ (self):
         return (self.__lineType, self.__comment, self.__units,
                 self.__length, self.__width, self.__height, self.__formula,
                 self.__parcial)
+
     def __setstate__(self,tuple):
         self.__lineType = tuple[0]
         self.__comment = tuple[1]
@@ -1259,6 +1337,7 @@
         self.__formula = tuple[6]
         self.__parcial = tuple[7]
         #self.calculateParcial()
+
     def __init__(self, decimals, type_, comment, units, length, width, height,
                  formula):
         self.__parcial = 0.0
@@ -1272,43 +1351,56 @@
         self.setHeight(height, decimals)
         self.setFormula(formula, decimals)
         #self.calculateParcial()
+
     def getLineType(self):
         return self.__lineType
+
     def getComment(self):
         return self.__comment
+
     def getUnits(self):
         return self.__units
+
     def getLength(self):
         return self.__length
+
     def getWidth(self):
         return self.__width
+
     def getHeight(self):
         return self.__height
+
     def getFormula(self):
         return self.__formula
+
     def getParcial(self):
         return self.__parcial
+
     def getParcialSubtotal(self):
         return self.__parcial_subtotal
+
     def getAcumulatedSubtotal(self):
         return self.__acumulated_subtotal
+
     def setParcialSubtotal(self, parcial_subtotal, decimals):
         if not isinstance(parcial_subtotal, float):
-            raise ValueError, utils.mapping(_(" Parcial Subtotal must be a "\
-                      "float number. Parcial: $1"), (str(parcial_subtotal),))
-        _DS = decimals.DS
+            raise ValueError( utils.mapping(_(" Parcial Subtotal must be a "\
+                      "float number. Parcial: $1"), (str(parcial_subtotal),)) )
+        _DS = abs(decimals.DS)
         parcial_subtotal = round(parcial_subtotal, _DS)
         self.__parcial_subtotal = parcial_subtotal
+
     def setAcumulatedSubtotal(self, acumulated_subtotal, decimals):
         if not isinstance(acumulated_subtotal, float):
-            raise ValueError, utils.mapping(_(" Acumulated Subtotal must be "\
+            raise ValueError( utils.mapping(_(" Acumulated Subtotal must be "\
                       "a float number. Parcial: $1"),
-                     (str(acumulated_subtotal),))
-        _DS = decimals.DS
+                     (str(acumulated_subtotal),)) )
+        _DS = abs(decimals.DS)
         acumulated_subtotal = round(acumulated_subtotal, _DS)
         self.__acumulated_subtotal = acumulated_subtotal
+
     def calculateParcial(self, decimals):
-        _DS = decimals.DS
+        _DS = abs(decimals.DS)
         if self.lineType == 1 or self.lineType == 2:
             _parcial = 0.0
         elif self.lineType == 0: # self.formula == "":
@@ -1336,69 +1428,75 @@
 
     def setLineType(self, type_):
         if not type_ in [0, 1, 2, 3]:
-            raise ValueError, utils.mapping(_("Invalid measure line type ($1)"),
-                  (str(type_),))
+            raise ValueError( utils.mapping(_("Invalid measure line type ($1)"),
+                  (str(type_),)) )
         self.__lineType = type_
+
     def setComment(self, comment):
         if not isinstance(comment, str):
-            raise ValueError, utils.mapping(_("Measure Comment must be a "\
-                  "string ($1)"), (str(comment),))
+            raise ValueError( utils.mapping(_("Measure Comment must be a "\
+                  "string ($1)"), (str(comment),)) )
         self.__comment = comment
+
     def setUnits(self, units, decimals):
         if units != "":
             if not isinstance(units, float):
-                raise ValueError, utils.mapping(_("Invalid Measure Units ($1)"),
-                      (str(units),))
-            _DN = decimals.DN
+                raise ValueError( utils.mapping(_("Invalid Measure Units ($1)"),
+                      (str(units),)) )
+            _DN = abs(decimals.DN)
             units = round(units, _DN)
         self.__units = units
         try:
             self.calculateParcial(decimals)
         except AttributeError:
             pass
+
     def setLength(self, length, decimals):
         if length != "":
             if not isinstance(length, float):
-                raise ValueError, utils.mapping(_("Invalid Measure length ($1)"),
-                      (str(units),))
-            _DD = decimals.DD
+                raise ValueError( utils.mapping(_("Invalid Measure length ($1)"),
+                      (str(units),)) )
+            _DD = abs(decimals.DD)
             length = round(length, _DD)
         self.__length = length
         try:
             self.calculateParcial(decimals)
         except AttributeError:
             pass
+
     def setWidth(self, width, decimals):
         if width != "":
             if not isinstance(width, float):
-                raise ValueError, utils.mapping(_("Invalid Measure Width ($1)"),
-                      (str(units),))
-            _DD = decimals.DD
+                raise ValueError( utils.mapping(_("Invalid Measure Width ($1)"),
+                      (str(units),)) )
+            _DD = abs(decimals.DD)
             width = round(width, _DD)
         self.__width = width
         try:
             self.calculateParcial(decimals)
         except AttributeError:
             pass
+
     def setHeight(self, height, decimals):
         if height != "":
             if not isinstance(height, float):
-                raise ValueError, utils.mapping(_("Invalid Measure Height ($1)"),
-                      (str(height),))
-            _DD = decimals.DD
+                raise ValueError( utils.mapping(_("Invalid Measure Height ($1)"),
+                      (str(height),)) )
+            _DD = abs(decimals.DD)
             height = round(height, _DD)
         self.__height = height
         try:
             self.calculateParcial(decimals)
         except AttributeError:
             pass
+
     def setFormula(self, formula, decimals):
         if not isinstance(formula, str):
-            raise ValueError, utils.mapping(_("Formula must be a "\
-                  "string ($1)"), (str(formula),))
+            raise ValueError( utils.mapping(_("Formula must be a "\
+                  "string ($1)"), (str(formula),)) )
         if re.match(".*[^0123456789\.()\+\-\*/\^abcdp ].*", formula):
-            raise ValueError, utils.mapping(_("There is invalid characters"\
-                  "in formula ($1)"), (str(formula),))
+            raise ValueError( utils.mapping(_("There is invalid characters"\
+                  "in formula ($1)"), (str(formula),)) )
         self.__formula = formula
         try:
             self.calculateParcial(decimals)
@@ -1437,6 +1535,7 @@
                                 None, None,
     """Parcial subtotal
     """)
+
     def eval_formula(self):
         """eval_formula()
         
@@ -1462,19 +1561,19 @@
         try:
             a = float(a)
         except:
-            raise ValueError, _("'a' value must be a float number")
+            raise ValueError( _("'a' value must be a float number") )
         try:
             b = float(b)
         except:
-            raise ValueError, _("'b' value must be a float number")
+            raise ValueError( _("'b' value must be a float number") )
         try:
             c = float(c)
         except:
-            raise ValueError, _("'c' value must be a float number")
+            raise ValueError( _("'c' value must be a float number") )
         try:
             d = float(d)
         except:
-            raise ValueError, _("'d' value must be a float number")
+            raise ValueError( _("'d' value must be a float number") )
         # spaces are erased
         formula.replace(" ","")
         # operators and varibles are replaced
@@ -1502,7 +1601,8 @@
         try:
             return eval(_formula2, _g)
         except:
-            raise ValueError, _("Invalid formula")
+            raise ValueError( _("Invalid formula") )
+
 
 class Decimals(object):
     """base.Decimals:
@@ -1587,13 +1687,6 @@
             Default: 2 decimal places.
         "DIVISA": monetary unit.
     Methods:
-        __init__(DN=2, DD=2, DSP=2, DS=2,
-                 DFC=3, DFPU=3, DFUO=3, DFA=3,
-                 DRC=3, DRPU=3, DRUO=3, DRA=3,
-                 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2,
-                 DIR=2, DIRC=2, DCD=2,
-                 DIVISA="EUR")
-        __getitem__(key)
         haskey(key)
         getD(recordtype)
         getDF(recordType)
@@ -1601,6 +1694,7 @@
         getDI(recordType)
     """
     # TODO: get/set methods
+
     def __init__(self,
                  DN=2, DD=2, DSP=2, DS=2,
                  DFC=3, DFPU=3, DFUO=3, DFA=3, 
@@ -1632,10 +1726,13 @@
         self.DIRC = DIRC
         self.DCD = DCD
         self.DIVISA = DIVISA
+
     def __getitem__(self, key):
         return self.__dict__[key]
+
     def haskey(self, key):
         return key in self.__dict__
+
     def getD(self, recordType):
         # DP: budget.
         # DC: chapter and subcharter. 
@@ -1662,6 +1759,7 @@
             else: # unit  type 0, subtipe ["EU", "EC", "EF", "PA"]
                 _decimal = self.DUO
         return _decimal
+
     def getDF(self, recordType):
         # Factor: DF
         #   ->DFP: Budget
@@ -1681,6 +1779,7 @@
             else: # unit  EU EC EF PA
                 _decimal = self.DFUO
         return _decimal
+
     def getDR(self, recordType):
         # Yield: DR
         #   ->DRP: Budget
@@ -1700,6 +1799,7 @@
             else: # unit
                 _decimal = self.DRUO
         return _decimal
+
     def getDI(self, recordType):
         # DIRC: budget, chapter and subcharter. 
         # DIR: unit, auxiliar element.
@@ -1716,6 +1816,7 @@
             _decimal = self.DIR
         return _decimal
 
+
 class Sheet(object):
     """base.Sheet:
     Description:
@@ -1731,9 +1832,6 @@
             <Section key>: must be in Budget.SheetSections
             <Paragraph key>: must be in Budget.SheetParagraph
     Methods:
-        __getstate__(self)
-        __setstate__(self, tuple)
-        __init__(self, sheet_dict={})
         {get/set}Sheet_dict
         getFields
         getSections
@@ -1742,108 +1840,121 @@
         addSection
     """
     __slots__ = ["_Sheet__sheet_dict"]
+
     def __getstate__ (self):
         return (self.__sheet_dict,)
+
     def __setstate__(self,tuple):
         self.__sheet_dict = tuple[0]
+
     def __init__(self):
         self.__sheet_dict = {}
+
     def getSheet_dict(self):
         return self.__sheet_dict
+
     def setSheet_dict(self, sheet_dict):
         if not isinstance(sheet_dict, dict):
-            raise ValueError, _("sheet_dict must be a dictionay")
+            raise ValueError( _("sheet_dict must be a dictionay") )
         self.__sheet_dict = sheet_dict
+
     def getFields(self):
         return self.sheet_dict.keys()
+
     def getSections(self, field):
         if field in self.__sheet_dict:
             return self.__sheet_dict[field].keys()
         else:
             return None
+
     def getParagraph(self, field, section):
         if (field in self.__sheet_dict and
             section in self.__sheet_dict[field]):
             return self.__sheet_dict[field][section]
         else:
             return None
+
     def addField(self, field, section_dict):
         if not isinstance(field, str):
-            raise ValueError, _("sheet field must be a string")
+            raise ValueError( _("sheet field must be a string") )
         if not isinstance(section_dict, dict):
-            raise ValueError, _("section_dict must be a dictionary")
+            raise ValueError( _("section_dict must be a dictionary") )
         self.__sheet_dict[field] = section_dict
+
     def addSection(self, field, section, paragraph):
         if not isinstance(field, str):
-            raise ValueError, _("sheet field must be a string")
+            raise ValueError( _("sheet field must be a string") )
         if not isinstance(section, str):
-            raise ValueError, _("sheet section must be a string")
+            raise ValueError( _("sheet section must be a string") )
         if not isinstance(paragraph, str):
-            raise ValueError, _("sheet paragraph must be a string")
+            raise ValueError( _("sheet paragraph must be a string") )
         if not field in self.__sheet_dict:
             self.addField(field, { })
         _field = self.__sheet_dict[field]
         _field[section] = paragraph
+
     sheet_dict = property(getSheet_dict, setSheet_dict, None,
     """Sheet dictionary { <Field key> : { <Section key> : <Paragraph key>}""")
 
+
 class Budget(object):
     """base.Budget:
     
     Description:
-        Budget objetc
+        Budget object
+        +-- __records: dictionary records { code : Record }
+        +-- __synonyms: synonyms dictionary. TODO { "code" : ["synonym",],}
+            Each record code can have synonym codes.
+        +-- __root: the root record code
+        +-- __decimals: List with the decimal places used to round the 
+-            result of the calculations with prices and measures
+-            The values are Decimals objects 
+-            The <0> objets is the default Decimals (seted in FIEBDC-3),
+-            The others keys are for the diferent groups of Prices
+        +-- __percentages: percentages dictionary:
+                      { "CI"  : "",
+                        "GG"  : "",
+                        "BI"  : "",
+                        "BAJA": "",
+                        "IVA" : ""}
+        +-- __file_owner
+        +-- __title_list: titles list: [ "Header", ["Title1", "Title2", ... ] ]
+            List with the Headers and list of Titles for prices and
+            decimal places.
+            The Headers is the type of hierarchy of the prices
+            Each Title have a group of Prices and a Decimals definition
+            The records can have diferent prices for diferent ages, geografical
+            places, ...
+        +-- __title_index: A integer. The active group of Prices and Decimals.
+        +-- __sheet_sections: sheet sections dictionary { sheet_code : sheet_title }
+        +-- __sheet_fields: sheet fields dictionary { field_code : field_title }
+        +-- __sheet_paragraphs: sheet paragraphs dictionary 
+                           { paragraph_code : paragraph_text}
+        +-- __companys: Dictionary whith companys object
+                   { company_code: company_object }
+        
+        +-- __comment
+-       +-- __date
+-       +-- __budgetType" A integer. Type of data in budget
+-                0 -> Undefined
+-                1 -> Base data.
+-                2 -> Budget.
+-                3 -> Certificate.
+-                4 -> Base date update.
+-       +-- __budgetCerficateOrder" Only valid if budgetType is 3.
+-       +-- __budgetCerficateDate" Only valid if budgetType is 3
+-       +-- __tec_info": Dictionary whith tecnical information
+-                        {ti_code : ["desciption text", "unit"]}
+-       +-- __labels": Label dictionary { "label": [ "code", ], }
+        
+        
     Constructor:
         base.Budget()
     Ancestry:
     +-- object
       +-- Budget
     Atributes:
-        "filename": file name of the budget file (FIEBDC)
-        "__records": Dictionary with the budget records.
-            { "code" : Record object, }
-        "__synonyms": Dictionary with the records synonums.
-            { "code" : ["synonym",],}
-            Each record code can have synonym codes.
-        "__root": The root record code.
-        "__title_list": List with the Headers and list of Titles for prices and
-            decimal places.
-            [ "Header", ["Title1", "Title2", ... ] ]
-            The records can have diferent prices for diferent ages, geografical
-            places, ...
-            The Headers is the type of hierarchy of the prices
-            Each Title have a group of Prices and a Decimals definition
-        "__decimals": List with the decimal places used to round the 
-            result of the calculations with prices and measures
-            The values are Decimals objects 
-            The <0> objets is the default Decimals (seted in FIEBDC-3),
-            The others keys are for the diferent groups of Prices
-        "__percentages": Dictionary with the percentages
-            keys:
-                "CI"    Indirect Cost
-                "GG"    General expenses
-                "BI"    Industrial benefit
-                "BAJA"  Low (what this do here?)
-                "IVA"   Tax
-        "__file_owner"
-        "__comment"
-        "__date"
-        "__budgetType" A integer. Type of data in budget
-                0 -> Undefined
-                1 -> Base data.
-                2 -> Budget.
-                3 -> Certificate.
-                4 -> Base date update.
-        "__budgetCerficateOrder" Only valid if budgetType is 3.
-        "__budgetCerficateDate" Only valid if budgetType is 3
-        "__title_index": A integer. The active group of Prices and Decimals.
-        "__sheet_sections": Dictionary whith de sheet sections
-        "__sheet_fields": Dictionary whith sheet fields
-        "__sheet_paragraphs": Dictionary whith sheet paragraphs
-        "__companys": Dictionary whith companys object
-                         { company_code: company_object }
-        "__tec_info": Dictionary whith tecnical information
-                        {ti_code : ["desciption text", "unit"]}
-        "__labels": Label dictionary { "label": [ "code", ], }
+        No public Atributes
     Methods:
         iter
         iterPreOrder
@@ -1911,31 +2022,70 @@
         setParametricText
     """
 
-
     def __init__(self):
         """__init__(self)
         
         Initialize the budget atributes
         """
+        # title_index: A integer. The active group of Prices and Decimals.
+        # TODO: change title_index
         self.__title_index = 0
+        # List with the decimal places used to round the 
+        # result of the calculations with prices and measures
+        # The values are Decimals objects 
+        # The <0> objets is the default Decimals (seted in FIEBDC-3),
+        # The others keys are for the diferent groups of Prices
         self.__decimals = [Decimals(), Decimals()]
+        # Dictionary with the percentages
+        #    keys:
+        #        "CI"    Indirect Cost
+        #        "GG"    General expenses
+        #        "BI"    Industrial benefit
+        #        "BAJA"  Low (what this do here?)
+        #        "IVA"   Tax
         self.__percentages = { "CI" : "" ,"GG": "", "BI": "",
                                "BAJA": "", "IVA" : ""}
+        # List with the Headers and list of Titles for prices and
+        #    decimal places.
+        #    [ "Header", ["Title1", "Title2", ... ] ]
+        #    The records can have diferent prices for diferent ages, geografical
+        #    places, ...
+        #    The Headers is the type of hierarchy of the prices
+        #    Each Title have a group of Prices and a Decimals definition
         self.__title_list = [ "", [ ] ]
+        # The root record code.
         self.__root = None
         self.__file_owner = ""
         self.__comment = ""
-        self.__budgetCerficateOrder = None
-        self.__budgetCerficateDate = None
+        self.__budgetCerficateOrder = None  # Only valid if budgetType is 3.
+        self.__budgetCerficateDate = None   # Only valid if budgetType is 3.
         self.__date = (0,0,0)
+        # budgetType: A integer. Type of data in budget
+        #        0 -> Undefined
+        #        1 -> Base data.
+        #        2 -> Budget.
+        #        3 -> Certificate.
+        #        4 -> Base date update.
         self.__budgetType = 0
+        # Dictionary with the budget records: { "code" : Record object, }
         self.__records = { }
+        # Dictionary with the records synonyms.
+        #    { "code" : ["synonym",],}
+        #    Each record code can have synonym codes.
         self.__synonyms = { }
+        # sheet_sections: Dictionary whith de sheet sections
         self.__sheet_sections = { }
+        # sheet_fields: Dictionary whith sheet fields
         self.__sheet_fields = { }
+        # sheet_paragraphs: Dictionary whith sheet paragraphs
         self.__sheet_paragraphs = { }
+        # companys: Dictionary whith companys object
+        #           { company_code: company_object }
         self.__companys = { }
+        # tec_info: Dictionary whith tecnical information
+        #           {ti_code : ["desciption text", "unit"]}
         self.__tec_info = { }
+        # labels: Label dictionary { "label": [ "code", ], }
         self.__labels = { }
 
     def __getstate__(self):
@@ -1964,6 +2114,7 @@
     def iter(self):
         for record in self.__records:
             yield record
+
     def iterPreOrder(self, recordCode, codes=None):
         if codes is None:
             codes = []
@@ -1973,6 +2124,7 @@
                 codes.append(_child)
                 self.iterPreOrder(_child, codes)
         return codes
+
     def iterPostOrder(self, recordCode, codes=None):
         if codes is None:
             codes = []
@@ -2012,6 +2164,7 @@
         _children = _record.children
         _child_code = [ _child.code for _child in _children ]
         return _child_code
+
     def setOwner(self, owner):
         """setOwner(self, owner)
         
@@ -2021,7 +2174,7 @@
         if isinstance(owner, basestring):
             self.__file_owner = owner
         else:
-            raise  TypeError, _("Owner must be a string")
+            raise  TypeError( _("Owner must be a string") )
 
     def setDate(self, date):
         """setOwner(self, date)
@@ -2037,7 +2190,7 @@
                 datetime.date(*date)
             self.__date = date
         else:
-            raise  TypeError, utils.mapping(_("Invalid Date: $1"),(str(date),))    
+            raise  TypeError( utils.mapping(_("Invalid Date: $1"),(str(date),)) )
 
     def setComment(self, comment):
         """setOwner(self, comment)
@@ -2048,7 +2201,7 @@
         if isinstance(comment, basestring):
             self.__comment = comment
         else:
-            raise  TypeError, _("Comment must be a string")
+            raise  TypeError( _("Comment must be a string") )
 
     def setBudgeType(self, budget_type):
         """setOwner(self, budget_type)
@@ -2064,8 +2217,8 @@
         if budget_type in [1, 2, 3, 4]:
             self.__budgetType = budget_type
         else:
-            raise  ValueError, _("Budget type must be 1, 2, 3 or 4.")
-                                            
+            raise  ValueError( _("Budget type must be 1, 2, 3 or 4.") )
+
     def setCertificateOrder(self, certificate_order, certificate_date):
         """setOwner(self, budget_type)
         
@@ -2076,7 +2229,7 @@
         if isinstance(certificate_order, int):
             self.__budgetCerficateOrder = certificate_order
         else:
-            raise  ValueError, _("Certificate order must be a integer.")
+            raise  ValueError( _("Certificate order must be a integer.") )
 
     def setCertificateDater(self, certificate_date):
         """setCertidicateDate(self, certificate_date)
@@ -2091,7 +2244,7 @@
             datetime.date(*certificate_date)
             self.__budgetCerficateDate = certificate_date
         else:
-            raise  ValueError, _("Budget certificate Date must be a valid Date.")
+            raise  ValueError( _("Budget certificate Date must be a valid Date.") )
 
     def setTitleList(self, title_list):
         """setTitleList(self, title_list)
@@ -2105,7 +2258,7 @@
                 title_list[1][i] = str(title_list[1][i])
             self.__title_list = title_list
         else:
-            raise TypeError, _("Invalid title list format")
+            raise TypeError( _("Invalid title list format") )
 
     def getTitleList(self):
         """ getTitleList(self)
@@ -2134,7 +2287,7 @@
         elif N < len(self.__decimals):
             _default_decimals = self.__decimals[N]
         else:
-            raise IndexError, _("Invalid Index Title")
+            raise IndexError( _("Invalid Index Title") )
         for _decimal in dictionary:
             if dictionary[_decimal] == "":
                 dictionary[_decimal] = eval("_default_decimals." + _decimal)
@@ -2151,6 +2304,7 @@
                             dictionary["DIRC"], dictionary["DCD"],
                             dictionary["DIVISA"])
         self.__decimals[N] = decimals
+
     def getDecimals(self, decimal=None, N=None):
         """getDecimals(self,decimal="All",N=None)
         
@@ -2170,7 +2324,7 @@
         elif self.__decimals[N+1].haskey(decimal):
             return self.__decimals[N+1][decimal]
         else:
-            raise KeyError, _("Decimal Key error")
+            raise KeyError( _("Decimal Key error") )
 
     def setPercentages(self, dictionary):
         """setPercentages(self, dictionary):
@@ -2208,7 +2362,7 @@
         elif key in self.__percentages:
             return self.__percentages[key]
         else:
-            raise KeyError, _("Invalid Percentage key")
+            raise KeyError( _("Invalid Percentage key") )
 
     def getAllParents(self,code):
         """getAllParents(self,code)
@@ -2280,12 +2434,12 @@
 
     def getStrYield(self, measure, recordType):
         #_DR = measure.getDR(self.getDecimals())
-        _DR = self.getDecimals().getDR(recordType)
+        _DR = abs(self.getDecimals().getDR(recordType))
         _yield = ("%." + str(_DR) + "f" ) % measure.yield_
         return _yield
 
     def getStrFactor(self, measure, recorType):
-        _DF = self.getDecimals().getDF(recordType)
+        _DF = abs(self.getDecimals().getDF(recordType))
         #_DF = measure.getDF(self.getDecimals())
         _factor = ("%." + str(_DF) + "f" ) % measure.factor
         return _factor
@@ -2325,29 +2479,29 @@
         if code is None: # No-estructured measures
             code = self.getRoot()
             if code == None: # No root
-                print "No-estructured measures. Adding root record", 
-                self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)],
-                                     0, "")       
+                print( "No-estructured measures. Adding root record " +  
+                str(self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)],
+                                     0, "") ))
                 code = self.getRoot()
 
         if not utils.is_valid_code(code)[0]:
-            raise ValueError, utils.mapping(_("Invalid parent code: $1"),
-                                            (code,))
+            raise ValueError( utils.mapping(_("Invalid parent code: $1"),
+                                            (str(code),)) )
         if not utils.is_valid_code(child_code)[0]:
-            raise ValueError, utils.mapping(_("Invalid child code: $1 $2"),
-                                           (code,child_code))
+            raise ValueError( utils.mapping(_("Invalid child code: $1 $2"),
+                                           (str(code),str(child_code))) )
         if not isinstance(position, int):
-            raise ValueError, utils.mapping(_("Invalid position in measure "\
-                  "$1, in code $2"), (parent_code, position))
+            raise ValueError( utils.mapping(_("Invalid position in measure "\
+                  "$1, in code $2"), (str(parent_code), str(position))) )
         # Test circular references
         _all_parent_list = self.getAllParents(code) + [ code ]
         _all_child_list = self.getAllchildren(child_code) + [ child_code ]
         for _parent_code in _all_parent_list:
             if _parent_code in _all_child_list:
                 # TODO: change return to except
-                print utils.mapping(_("Circular Decomposition, parent code: "\
+                print(utils.mapping(_("Circular Decomposition, parent code: "\
                       "$1, child code: $2, repeated code: $3"),
-                      (code, child_code, _parent_code))
+                      (str(code), str(child_code), str(_parent_code))) )
                 return
 
         # Creating reference to parent code in child record
@@ -2370,15 +2524,15 @@
                 positions = _record.getChildPositions(child_code)
                 if len(positions) == 1:
                     position = positions[0]
-                    print utils.mapping(_("No-estructured measure or empty position. Parent Code: "\
-                          "$1, Child code: $2, Position: $3"),(code, child_code, position))
+                    print(utils.mapping(_("No-estructured measure or empty position. Parent Code: "\
+                          "$1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) )
                 else:
                     position = _child_number
-                    print utils.mapping(_("No-estructured measure or empty position. "\
+                    print(utils.mapping(_("No-estructured measure or empty position. "\
                           "Repeated child in unspecified position. "\
                           "It is impossible to determine the position. "\
                           "New child is added in the decomposition. "\
-                          "Parent code: $1, Child code: $2, Position: $3"),(code, child_code, position))
+                          "Parent code: $1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) )
             if position == _child_number:
                 # The record do not have the child
                 if not isinstance(factor, float): factor = 1.0
@@ -2414,21 +2568,21 @@
                     _measure.label = label
             else:
                 # TODO: change return for except
-                print utils.mapping(_("Error: Invalid child position in "
+                print(utils.mapping(_("Error: Invalid child position in "
                       "decomposition. Parent code: $1 Child code: $2 "\
-                      "Position: $3"), (code, child_code, position))
+                      "Position: $3"), (str(code), str(child_code), str(position))) )
                 return
         else:
             if child_code == "" : 
-                print utils.mapping(_("Error: Empty child code. Parent code: "\
-                      "$1 Position: $2"), (code, position))
+                print(utils.mapping(_("Error: Empty child code. Parent code: "\
+                      "$1 Position: $2"), (str(code), str(position))) )
                 return
             if position == -1:
                 position = 0
             elif position != 0:
-                print utils.mapping(_("Error: Invalid child position in "\
+                print(utils.mapping(_("Error: Invalid child position in "\
                       "decomposition. Parent code: $1 Child code: $2 "\
-                      "Position: $3"), (code, child_code, position))
+                      "Position: $3"), (str(code), str(child_code), str(position))) )
                 return
             if not isinstance(factor, float):
                 factor = 1.0
@@ -2461,19 +2615,19 @@
         try:
             a = float(a)
         except:
-            raise ValueError, _("'a' value must be a float number")
+            raise ValueError( _("'a' value must be a float number") )
         try:
             b = float(b)
         except:
-            raise ValueError, _("'b' value must be a float number")
+            raise ValueError( _("'b' value must be a float number") )
         try:
             c = float(c)
         except:
-            raise ValueError, _("'c' value must be a float number")
+            raise ValueError( _("'c' value must be a float number") )
         try:
             d = float(d)
         except:
-            raise ValueError, _("'d' value must be a float number")
+            raise ValueError( _("'d' value must be a float number") )
         # spaces are erased
         sre.sub("[ ]","",formula)
         # operators and varibles are replaced
@@ -2501,7 +2655,7 @@
         try:
             return eval(_formula2, _g)
         except:
-            raise ValueError, _("Invalid formula")
+            raise ValueError( _("Invalid formula") )
 
     def getText(self,code):
         """getText(self,code)
@@ -2512,7 +2666,7 @@
         if code in self.__records:
             return self.__records[code].text
         else:
-            raise IndexError, _("Invalid code")
+            raise IndexError( _("Invalid code") )
 
     def setText(self,code,text):
         """setText(self,code,text)
@@ -2522,7 +2676,7 @@
         Sests the description text of a record
         """
         if not utils.is_valid_code(code)[0]:
-            raise ValueError, utils.mapping(_("Invalid record: $1"), (code,))
+            raise ValueError( utils.mapping(_("Invalid record: $1"), (str(code),)) )
         if not code in self.__records:
             _record = self.setRecord(code, [], "", "", "", [], [],
                                      "", "")
@@ -2585,7 +2739,7 @@
             if self.__root is None:
                 self.__root = code
             else:
-                print _("Only can be one root record")
+                print(_("Only can be one root record") )
                 return
                 # TODO: If the root is created in settree. No-estructured measures
                 # TODO  Rewrite root values
@@ -2659,9 +2813,22 @@
         """
         record.addPrice(price_date, self.getDecimals())
 
-    def getStrPriceFromRecord(self, index_price, record):
-        _price = record.getPrice(index_price)
-        _D = self.getDecimals().getD(record.recordType)
+    def getStrPriceFromRecord(self, index_price, record, path):
+        if record.isPercentage():
+            _percentageMasq = record.percentageMasq()
+            _parent_code = self.getCode(path[:-1])
+            _N_record = path[-1]
+            _amount_sum = 0.0
+            for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]):
+                _child_record = self.getRecord(_code)
+                if _child_record.hasPercentageMasq(_percentageMasq):
+                    _path = path[:-1] + (N,)
+                    _amount = self.getAmount(_path)
+                    _amount_sum = _amount_sum + _amount
+            _price = _amount_sum
+        else:
+            _price = record.getPrice(index_price)
+        _D = abs(self.getDecimals().getD(record.recordType))
         _price = ("%." + str(_D) + "f" ) % _price
         return _price
 
@@ -2681,16 +2848,16 @@
                         try:
                             _child = _children_list[i]
                         except:
-                            raise ValueError, _("This record does not exits")
+                            raise ValueError( _("This record does not exits") )
                         _code = _child.code
                     else:
-                        raise ValueError, _("Path item must be a integer")
+                        raise ValueError( _("Path item must be a integer") )
                 return _code
             else:
-                raise ValueError, _("This record does not exits")
+                raise ValueError( _("This record does not exits") )
         else:
-            raise ValueError, utils.mapping(_("Path must be a not empty "\
-                  "tuple: $1"), (str(path),))
+            raise ValueError( utils.mapping(_("Path must be a not empty "\
+                  "tuple: $1"), (str(path),)) )
 
     def getAmount(self, path):
         """def getAmount(self,path)
@@ -2698,6 +2865,7 @@
         path: record path
         Calculate the record amount
         """
+        
         if len(path) == 1:
             # root: amount is the root price
             _root = self.getRecord(self.getRoot())
@@ -2713,10 +2881,25 @@
             _yield = _decomposition.budgetMeasures[0].yield_
             _child_code = _decomposition.code
             _child_record = self.getRecord(_child_code)
-            _price = _child_record.getPrice(self.getActiveTitle())
-            _DR = self.getDecimals().getDR(_parent_record.recordType)
+            _code = self.getCode(path)
+            _record = self.getRecord(_code)
+            if _record.isPercentage():
+                _percentageMasq = _record.percentageMasq()
+                _N_record = path[-1]
+                _amount_sum = 0.0
+                for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]):
+                    _child_record = self.getRecord(_code)
+                    if _child_record.hasPercentageMasq(_percentageMasq):
+                        _path = path[:-1] + (N,)
+                        _amount = self.getAmount(_path)
+                        _amount_sum = _amount_sum + _amount
+                _price = _amount_sum
+            else:
+                _price = _child_record.getPrice(self.getActiveTitle())
+            
+            _DR = abs(self.getDecimals().getDR(_parent_record.recordType))
             _total_yield = round(_factor * _yield, _DR)
-            _DI = self.getDecimals().getDI(_parent_record.recordType)
+            _DI = abs(self.getDecimals().getDI(_parent_record.recordType))
             _amount = round(_total_yield * _price, _DI)
             return _amount
 
@@ -2728,74 +2911,86 @@
         """
         if len(path) == 1: #root
             _root = self.getRecord(self.getRoot())
-            _amount = self.getStrPriceFromRecord(self.__title_index, _root)
+            _amount = self.getStrPriceFromRecord(self.__title_index, _root, path)
             return _amount
         else:
             _parent_code = self.getCode(path[:-1])
             _parent_record = self.getRecord(_parent_code)
             _amount = self.getAmount(path)
-            _DI = self.getDecimals().getDI(_parent_record.recordType)
+            _DI = abs(self.getDecimals().getDI(_parent_record.recordType))
             _amount = ("%." + str(_DI) + "f") % _amount
             return _amount
 
     def setSheetSection(self,sheet_code,sheet_title):
         if not isinstance(sheet_code, str):
-            raise ValueError, _("The sheet code must be a string")
+            raise ValueError( _("The sheet code must be a string") )
         if not isinstance(sheet_title, str):
-            raise ValueError, _("The sheet title must be a string")
+            raise ValueError( _("The sheet title must be a string") )
         self.__sheet_sections[sheet_code] = sheet_title
+
     def hasSheetSection(self, section):
         return section in self.__sheet_sections
+
     def getSheetSection(self, section):
         return self.__sheet_sections[section]
+
     def setSheetSections(self,dictionary): 
         if not isinstance(dictionary, dict):
-            raise ValueError, _("The sheet sections must be a dictionary")
+            raise ValueError( _("The sheet sections must be a dictionary") )
         for sheet_code in dictionary.keys():
             self.setSheetSection(sheet_code, dictionary[sheet_code])
+
     def setSheetField(self, field_code, field_title):
         if not isinstance(field_code, str):
-            raise ValueError, _("The field code must be a string")
+            raise ValueError( _("The field code must be a string") )
         if not isinstance(field_title, str):
-            raise ValueError, _("The field title must be a string")
+            raise ValueError( _("The field title must be a string") )
         self.__sheet_fields[field_code] = field_title
+
     def hasSheetField(self, field):
         return field in self.__sheet_fields
+
     def getSheetField(self, field):
         return self.__sheet_fields[field]
+
     def setSheetFields(self, field_dict):
         if not isinstance(field_dict, dict):
-            raise ValueError, _("The sheet field must be a dictionary")
+            raise ValueError( _("The sheet field must be a dictionary") )
         for field_code in field_dict.keys():
             self.setSheetField( field_code, field_dict[field_code])
+
     def setSheetParagraph(self, paragraph_code, paragraph_text):
         if not isinstance(paragraph_code, str):
-            raise ValueError, _("The paragraph code must be a string")
+            raise ValueError( _("The paragraph code must be a string") )
         if not isinstance(paragraph_text, str):
-            raise ValueError, _("The paragraph text must be a string")
+            raise ValueError( _("The paragraph text must be a string") )
         self.__sheet_paragraphs[paragraph_code] = paragraph_text
+
     def hasSheetParagraph(self, paragraph):
         return paragraph in self.__sheet_paragraphs
+
     def getSheetParagraph(self, paragraph):
         return self.__sheet_paragraphs[paragraph]
+
     def setSheetParagraphs(self, paragraph_dict):
         if not isinstance(paragraph_dict, dict):
-            raise ValueError, _("The paragraph dict must be a dictionary")
+            raise ValueError( _("The paragraph dict must be a dictionary") )
         for paragraph_code in paragraph_dict.keys():
             self.setSheetParagraph( paragraph_code, paragraph_dict[paragraph_code])
+
     def setSheetRecord(self, record_code, field, section_dict):
         if not isinstance(record_code, str):
-            raise ValueError, _("The record_code code must be a string")
+            raise ValueError( _("The record_code code must be a string") )
         if not isinstance(field, str):
-            raise ValueError, _("The field must be a string")
+            raise ValueError( _("The field must be a string") )
         if not isinstance(section_dict, dict):
-            raise ValueError, _("The section dict must be a dictionary")
+            raise ValueError( _("The section dict must be a dictionary") )
         #-#
         # TODO: Add a empty record?
         if not self.hasRecord(record_code):
-            print utils.mapping(_("Error: The budget do not have this record "\
+            print(utils.mapping(_("Error: The budget do not have this record "\
                 "code and can not be added the sheet text in the field $1. "\
-                "Record Code: $2"), ( field, record_code))
+                "Record Code: $2"), ( str(field), str(record_code))) )
             return
         #-#
         if not self.hasSheetField(field):
@@ -2807,45 +3002,48 @@
                 self.setSheetSection(section, "")
             _sheet = self.getRecord(record_code).getSheet()
             _sheet.addSection(field, section, paragraph)
+
     def addFile(self, record_code, filepath, type_, description):
         if not isinstance(record_code, str):
-            raise ValueError, _("The record_code code must be a string")
-        if not isinstance(filepath, str):
-            raise ValueError, _("The filename must be a string")
+            raise ValueError( _("The record_code code must be a string") )
+        #-# str and unicode
+        if not isinstance(filepath, str) and not isinstance(filepath, unicode):
+            raise ValueError( _("The filename must be a string") )
         #-#
         # TODO: Add a empty record?
         if not self.hasRecord(record_code):
-            print utils.mapping(_("Error: The budget do not have the record "\
+            print(utils.mapping(_("Error: The budget do not have the record "\
                 "code $1 and can not be added the file: $2"),
-                (record_code, filepath))
+                (str(record_code), str(filepath))) )
             return
         #-#
         _record = self.getRecord(record_code)
         _record.addFile(filepath, type_, description)
+
     def setCompany(self, company_code, sumamary, name, offices,
                    cif, web, email):
         if not isinstance(company_code, str):
-            raise ValueError, _("The company code must be a string")
+            raise ValueError( _("The company code must be a string") )
         if not isinstance(sumamary, str):
-            raise ValueError, _("The summary must be a string")
+            raise ValueError( _("The summary must be a string") )
         if not isinstance(name, str):
-            raise ValueError, _("The name must be a string")
+            raise ValueError( _("The name must be a string") )
         if not isinstance(offices, list):
-            raise ValueError, _("The name must be a list")
+            raise ValueError( _("The name must be a list") )
         _offices = []
         for _office in offices:
             if not isinstance(_office, list):
-                raise ValueError, _("The office must be a list")
+                raise ValueError( _("The office must be a list") )
             if not len(_office) == 10:
-                raise ValueError, _("The office must be a 10 items list")
+                raise ValueError( _("The office must be a 10 items list") )
             for _item in _office[:7] + _office[9:10]:
                 if not isinstance(_item, str):
-                    raise ValueError, _("This office item must be a "\
-                                        "string")
+                    raise ValueError( _("This office item must be a "\
+                                        "string") )
             for _item in _office[7:8]:
                 if not isinstance(_item, list):
-                    raise ValueError, _("This office item must be a "\
-                                        "list")
+                    raise ValueError( _("This office item must be a "\
+                                        "list") )
             _offices.append(Office(_office[0],
                                   _office[1],
                                   _office[2],
@@ -2857,31 +3055,36 @@
                                   _office[8],
                                   _office[9]))
         if not isinstance(cif, str):
-            raise ValueError, _("The name must be a string")
+            raise ValueError( _("The name must be a string") )
         if not isinstance(web, str):
-            raise ValueError, _("The web must be a string")
+            raise ValueError( _("The web must be a string") )
         if not isinstance(email, str):
-            raise ValueError, _("The email must be a string")
+            raise ValueError( _("The email must be a string") )
         
         self.__companys[company_code] = Company(company_code, sumamary, name,
                                                 _offices, cif, web, email)
     def getCompany(self, company_code):
         return self.__companys[company_code]
+
     def getCompanyKeys(self):
         return self.__companys.keys()
+
     def addTecInfo(self, ti_code, text, unit):
         if not isinstance(ti_code, str):
-            raise ValueError, _("The tecnical info code must be a string")
+            raise ValueError( _("The tecnical info code must be a string") )
         if not isinstance(text, str):
-            raise ValueError, _("The tecnical info description must be a "\
-                                "string")
+            raise ValueError( _("The tecnical info description must be a "\
+                                "string") )
         if not isinstance(unit, str):
-            raise ValueError, _("The tecnical info unit must be a string")
+            raise ValueError( _("The tecnical info unit must be a string") )
         self.__tec_info[ti_code] = [text, unit]
+
     def hasTecInfo(self, ti_code):
         return ti_code in self.__tec_info
+
     def getTecInfo(self, ti_code):
         return self.__tec_info[ti_code]
+
     def setTecnicalInformation(self, record_code, ti_dict):
         """setTecnicalInformation(record_code, ti_dict)
         
@@ -2891,6 +3094,7 @@
         """
         # TODO: setTecnicalInformation
         pass
+
     def changeCode(self, record_code, new_record_code):
         """changeCode(self, record_code, new_record_code):
         
@@ -2923,7 +3127,7 @@
         Add a label to a record
         """
         if not isinstance(label,str):
-            raise ValueError, _("The label must be a string")
+            raise ValueError( _("The label must be a string") )
         if self.hasRecord(record_code):
             _record = self.__records[record_code]
             _record.addLabel(label)
@@ -2933,27 +3137,28 @@
                 _codes = self.__labels[label]
                 if not record_code in _codes:
                     _codes.append(record_code)
+
     def setParametricSelectComment(self, record_code, comment):
         """setParametricSelectComment(self, record_code, comment)
         
         Sets Paramtric Record Select Comment
         """
         if not isinstance(record_code, str):
-            raise ValueError, _("The record_code code must be a string")
+            raise ValueError( _("The record_code code must be a string") )
         if not isinstance(comment, str):
-            raise ValueError, _("The parametric select comment must be a "\
-                                "string")
+            raise ValueError( _("The parametric select comment must be a "\
+                                "string") )
         if not self.hasRecord(record_code):
-            print utils.mapping(_("Error: The budget do not have the record "\
+            print(utils.mapping(_("Error: The budget do not have the record "\
                 "code $1 and can not be added the Parametric select comment: "\
                 "$2"),
-                (record_code, comment))
+                (str(record_code), str(comment))) )
             return
         _record = self.getRecord(record_code)
         if not isinstance(_record, ParametricRecord):
-            print utils.mapping(_("Error: The Record $1 is not a "\
+            print(utils.mapping(_("Error: The Record $1 is not a "\
                 "Parametric Record and can not have Parametric comment"),
-                (record_code,))
+                (str(record_code),)) )
         else:
             _record.select_comment = comment
 
@@ -2963,19 +3168,19 @@
         Sets parametric record summary
         """
         if not isinstance(record_code, str):
-            raise ValueError, _("The record_code code must be a string")
+            raise ValueError( _("The record_code code must be a string") )
         if not isinstance(summary, str):
-            raise ValueError, _("The summary record must be a string")
+            raise ValueError( _("The summary record must be a string") )
         if not self.hasRecord(record_code):
-            print utils.mapping(_("Error: The budget do not have the record "\
+            print(utils.mapping(_("Error: The budget do not have the record "\
                 "code $1 and can not be seted the summary: $2"),
-                (record_code, summary))
+                (str(record_code), str(summary))) )
             return
         _record = self.getRecord(record_code)
         if not isinstance(_record, ParametricRecord):
-            print utils.mapping(_("Error: The Record $1 is not a "\
+            print(utils.mapping(_("Error: The Record $1 is not a "\
                 "Parametric Record and can not have Parametric summary"),
-                (record_code,))
+                (str(record_code),)) )
         else:
             self.getRecord(record_code).parametric_summary = summary
 
@@ -2985,22 +3190,23 @@
         Sets parametric record text
         """
         if not isinstance(record_code, str):
-            raise ValueError, _("The record_code code must be a string")
+            raise ValueError( _("The record_code code must be a string") )
         if not isinstance(text, str):
-            raise ValueError, _("The text record must be a string")
+            raise ValueError( _("The text record must be a string") )
         if not self.hasRecord(record_code):
-            print utils.mapping(_("Error: The budget do not have the record "\
+            print(utils.mapping(_("Error: The budget do not have the record "\
                 "code $1 and can not be seted the text: $2"),
-                (record_code, text))
+                (str(record_code), str(text))) )
             return
         _record = self.getRecord(record_code)
         if not isinstance(_record, ParametricRecord):
-            print utils.mapping(_("Error: The Record $1 is not a "\
+            print(utils.mapping(_("Error: The Record $1 is not a "\
                 "Parametric Record and can not have Parametric text"),
-                (record_code,))
+                (str(record_code),)) )
         else:
             self.getRecord(record_code).parametric_text = text
 
+
 class Office(object):
     """base.Office:
     
@@ -3044,6 +3250,7 @@
         {get/set}ContactPerson
         getValues
     """
+
     __slots__ = ["_Office__officeType",
                  "_Office__subname",
                  "_Office__address",
@@ -3055,6 +3262,7 @@
                  "_Office__fax",
                  "_Office__contact_person",
                  ]
+
     def __getstate__ (self):
         return ( self.__officeType,
                  self.__subname,
@@ -3066,6 +3274,7 @@
                  self.__phone,
                  self.__fax,
                  self.__contact_person)
+
     def __setstate__(self,tuple):
         self.__officeType = tuple[0]
         self.__subname = tuple[1]
@@ -3090,46 +3299,67 @@
         self.phone = phone
         self.fax = fax
         self.contact_person = contact_person
+
     def getOfficeType(self):
         return self.__officeType
+
     def setOfficeType(self, type_):
         self.__officeType = type_
+
     def getSubname(self):
         return self.__subname
+
     def setSubname(self, subname):
         self.__subname = subname
+
     def getAddress(self):
         return self.__address
+
     def setAddress(self, address):
         self.__address = address
+
     def getPostalCode(self):
         return self.__postal_code
+
     def setPostalCode(self, postal_code):
         self.__postal_code = postal_code
+
     def getTown(self):
         return self.__town
+
     def setTown(self, town):
         self.__town = town
+
     def getProvince(self):
         return self.__province
+
     def setProvince(self, province):
         self.__province = province
+
     def getCountry(self):
         return self.__country
+
     def setCountry(self, country):
         self.__country = country
+
     def getPhone(self):
         return self.__phone
+
     def setPhone(self, phone):
         self.__phone = phone
+
     def getFax(self):
         return self.__fax
+
     def setFax(self, fax):
         self.__fax = fax
+
     def getContactPerson(self):
         return self.__contact_person
+
     def setContactPerson(self, contact_person):
         self.__contact_person = contact_person
+
     def getValues(self):
         return {"officeType": self.officeType,
                 "subname": self.subname,
@@ -3142,6 +3372,7 @@
                 "fax": self.fax,
                 "contact person": self.contact_person,
                }
+
     officeType = property(getOfficeType, setOfficeType, None,
     """Type of office
     """)
@@ -3176,6 +3407,7 @@
     """Dictionary with comapany values
     """)
 
+
 class Company(object):
     """base.Company:
     
@@ -3210,6 +3442,7 @@
         {get/set}Email
         getValues
     """
+
     __slots__ = ["_Company__code",
                  "_Company__summary",
                  "_Company__name",
@@ -3218,6 +3451,7 @@
                  "_Company__web",
                  "_Company__email",
                  ]
+
     def __getstate__ (self):
         return ( self.__code,
                  self.__summary,
@@ -3226,6 +3460,7 @@
                  self.__cif,
                  self.__web,
                  self.__email)
+
     def __setstate__(self,tuple):
         self.__code = tuple[0]
         self.__summary = tuple[1]
@@ -3243,34 +3478,49 @@
         self.cif = cif
         self.web = web
         self.email = email
+
     def getCode(self):
         return self.__code
+
     def setCode(self, code):
         self.__code = code
+
     def getSummary(self):
         return self.__summary
+
     def setSummary(self, summary):
         self.__summary = summary
+
     def getName(self):
         return self.__name
+
     def setName(self, name):
         self.__name = name
+
     def getOffices(self):
         return self.__offices
+
     def setOffices(self, offices):
         self.__offices = offices
+
     def getCif(self):
         return self.__cif
+
     def setCif(self, cif):
         self.__cif = cif
+
     def getWeb(self):
         return self.__web
+
     def setWeb(self, web):
         self.__web = web
+
     def getEmail(self):
         return self.__email
+
     def setEmail(self, email):
         self.__email = email
+
     def getValues(self):
         return {"code": self.code,
                 "summary": self.summary,
@@ -3278,6 +3528,7 @@
                 "cif": self.cif,
                 "web": self.web,
                 "email": self.email}
+
     code = property(getCode, setCode, None,
     """Company code 
     """)
@@ -3303,6 +3554,7 @@
     """Dictionary with comapany values
     """)
 
+
 class File(object):
     """base.Company:
     
@@ -3326,41 +3578,52 @@
         {get/set}Description
         getValues
     """
+
     __slots__ = ["_File__name",
                  "_File__fileType",
                  "_File__description",
-
                  ]
+
     def __getstate__ (self):
         return (self.__name,
                 self.__description,
                 self.__fileType,
                )
+
     def __setstate__(self,tuple):
         self.__name = tuple[0]
         self.__fileType = tuple[1]
         self.__description = tuple[2]
+
     def __init__(self, name, type_, description):
         self.name = name
         self.fileType = type_
         self.description = description
+
     def getName(self):
         return self.__name
+
     def setName(self, name):
         self.__name = name
+
     def getFileType(self):
         return self.__fileType
+
     def setFileType(self, type_):
         self.__fileType = type_
+
     def getDescription(self):
         return self.__description
+
     def setDescription(self, description):
         self.__description = description
+
     def getValues(self):
         return {"name": self.name,
                 "fileType": self.fileType,
                 "description": self.description,
                }
+
     name = property(getName, setName, None,
     """File name
     """)
@@ -3374,6 +3637,7 @@
     """Dictionary with file values
     """)
 
+
 class RecordType(object):
     """base.RecordType:
     
@@ -3432,51 +3696,62 @@
         {get/set}Type
         {get/set}Subtype
     """
+
     __slots__ = ["_RecordType__hierarchy",
                  "_RecordType__type",
                  "_RecordType__subtype",
                  ]
+
     def __getstate__ (self):
         return (self.__hierarchy,
                 self.__type,
                 self.__subtype,
                )
+
     def __setstate__(self,tuple):
         self.__hierarchy = tuple[0]
         self.__type = tuple[1]
         self.__subtype = tuple[2]
+
     def __init__(self, hierarchy, type_, subtype):
         self.hierarchy = hierarchy
         self.type = type_
         self.subtype = subtype
+
     def getHierarchy(self):
         return self.__hierarchy
+
     def setHierarchy(self, hierarchy):
         if not hierarchy in [-1, 0 , 1 ,2, ""]:
-            raise ValueError, utils.mapping(_("Invalid Hierarchy ($1) "\
-                  "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),))
+            raise ValueError( utils.mapping(_("Invalid Hierarchy ($1) "\
+                  "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),)) )
         elif hierarchy == "":
-            print "Hierarchy temporarily set to an empty string"
+            print("Hierarchy temporarily set to an empty string")
         #TODO Check empty Hierarchy in Generic.fiebdc.Read._testBudget
         self.__hierarchy = hierarchy
+
     def getType(self):
         return self.__type
+
     def setType(self, type_):
         if not type_ in  ["", 0, 1, 2, 3] :
-            raise ValueError, utils.mapping(_("Invalid type ($1),"\
-                  "the type must be (empty string,0,1,2,3)"),(str(type_)),)
+            raise ValueError( utils.mapping(_("Invalid type ($1),"\
+                  "the type must be (empty string,0,1,2,3)"),(str(type_)),) )
         self.__type = type_
+
     def getSubtype(self):
         return self.__subtype
+
     def setSubtype(self, subtype):
         if not subtype in ["", "OB", "PU", "EA", "EU", "EC", "EF", "PA", "H",
                            "Q", "%", "MC", "MCr", "MM", "MS", "ME", "MCu",
                            "Mal","ML","M"]:
-            raise ValueError, utils.mapping(_("Invalid subtype ($1), The "\
+            raise ValueError( utils.mapping(_("Invalid subtype ($1), The "\
                   "subtype must one in (empty string, EA, "\
                   "EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, "\
-                  "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),))
+                  "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),)) )
         self.__subtype = subtype
+
     hierarchy = property(getHierarchy, setHierarchy, None,
     """Record Hierarchy
            -1 -> temporarily unfixed
--- a/Generic/durusdatabase.py	Tue Sep 30 17:16:50 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-## File durus.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/>.
-
-# Modules
-import os.path
-import time
-# Durus Modules
-from durus.file_storage import FileStorage
-from durus.connection import Connection
-# pyArq Presupuestos Modules
-from Generic import utils
-from Generic import globalVars
-class DurusFile(object):
-    def __init__(self, file, new):
-        self.__file = file
-        if new:
-            if os.path.exists(self.__file):
-                os.remove(self.__file)
-        self.__connection = Connection(FileStorage(self.__file))
-        self.__root = self.__connection.get_root()
-
-    def close(self):
-        self.__connection.get_storage().close()
-
-    def getBudget(self):
-        if self.__root.has_key("baseversion") and \
-           globalVars.baseversion == self.__root["baseversion"]:
-            return self.__root["budget"]
-        else:
-            print _("Incorrent Base version")
-            return None
-
-    def setBudget(self, budget):
-        self.__root["budget"] = budget
-        self.__root["baseversion"] = globalVars.baseversion
-        self.__connection.commit()
-
-class Read(object):
-    def __init__(self, filename=None, budget=None):
-        self.__budget = budget
-        self.__filename = filename
-        self.__cancel = False
-
-    def cancel(self):
-        """def cancel(self)
-        
-        It do nothing
-        """
-        # TODO: Cancel reading Durus database.
-        self.__cancel = True
-        
-    def readFile(self, budget=None, filename=None, interface=None):
-        if not filename is None:
-            self.__filename = filename
-        if self.__filename is None or self.__cancel == True:
-            return None
-        if not os.path.exists(self.__filename):
-            return None
-        print utils.mapping(_("Loading file: $1:"), (self.__filename,))
-        _time = time.time()
-        _durus_file = DurusFile(self.__filename, False)
-        self.__budget = _durus_file.getBudget()
-        _durus_file.close()
-        print utils.mapping(_("Loadig time: $1 seconds"),
-             (("%.2f" %(time.time()-_time)),))
-        return self.__budget
--- a/Generic/fiebdc.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/fiebdc.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File fiebdc.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -38,49 +38,45 @@
     
     Description:
         Reads and parses a fiebdc file
+        +-- __budget: budget ("base.Budget" object)
+        +-- __file_format: File format of the fiebdc file
+        +-- __format_list: List of file format that can be readed
+        +-- __character_sets_dict: Dictionary with the character sets supported
+        +-- __character_set: character_set of the file
+        +-  __generator: program which the file is created
+        +-- __cancel: Boolean value, True mean that the read process must stop
+        +-- __filename: The filename of the fiebdc file that is readed
+        +-- __pattern: re compiled pattern dict
+        +-- __statistics: Statistics object, records number
     Constructor:
         fiebdc.Read(filename=None, budget=None)
     Ancestry:
     +-- object
       +-- Read
     Atributes:
-        "__budget": budget ("base.Budget" object)
-        "__file_format": File format of the fiebdc file
-        "__format_list": List of file format that can be readed
-        "__character_sets_dict": Dictionary with the character sets supported
-        "__character_set": character_set of the file
-        "__generator": program which the file is created
-        "__cancel": Boolean value, True mean that the read process must stop
-        "__filename": The filename of the fiebdc file that is readed
-        "__pattern": re compiled pattern dict
-        "__statistics": Statistics object, records number
+        No public Atributes
     Methods:
-        __init__(self, filename=None, budget=None)
-        cancel(self)
-        eraseControlCharacters(self, string)
-        validateCode(self, code)
-        parseDate(self, date)
-        parseRecord(self,record)
-        _parseV(self, field_list)
-        _parseC(self, field_list)
-        _parseDY(self, field_list)
-        _parseMN(self, field_list)
-        _parseT(self, field_list)
-        _parseK(self, field_list)
-        _parseW(self, field_list)
-        _parseL(self, field_list)
-        _parseQ(self, field_list)
-        _parseJ(self, field_list)
-        _parseG(self, field_list)
-        _parseE(self, field_list)
-        _parseX(self, field_list)
-        _parseF(self, field_list)
-        readFile(self, budget=None, filename=None)
+        cancel()
+        eraseControlCharacters(string)
+        validateCode(code)
+        parseDate(date)
+        parseRecord(record)
+        readFile(budget=None, filename=None)
     """
     def __init__(self, filename=None, budget=None):
-        """def __init__(self, filename=None, budget=None)
+        """def __init__(filename=None, budget=None)
         
         Sets the instance attributes
+        __budget: budget ("base.Budget" object)
+        __file_format: File format of the fiebdc file
+        __format_list: List of file format that can be readed
+        __character_sets_dict: Dictionary with the character sets supported
+        __character_set: character_set of the file
+        __generator: program which the file is created
+        __cancel: Boolean value, True mean that the read process must stop
+        __filename: The filename of the fiebdc file that is readed
+        __pattern: re compiled pattern dict
+        __statistics: Statistics object, records number
         """
         self.__budget = budget
         self.__filename = filename
@@ -96,7 +92,7 @@
                                       "850" : "850",
                                       "437" : "cp437"}
         self.__file_format = "FIEBDC-3/2007"
-        self.__generator = globalVars.version
+        self.__generator = globalVars.name + " " + globalVars.version
         self.__character_set = "850"
         self.__pattern = {
             "control_tilde" : re.compile(u"((\r\n)| |\t)+~"),
@@ -121,14 +117,14 @@
         self.__statistics = Statistics()
 
     def cancel(self):
-        """def cancel(self)
+        """def cancel()
         
         Sets the "__cancel" attribute to True, It stops the read process.
         """
         self.__cancel = True
 
     def eraseControlCharacters(self, string):
-        """eraseControlCharacters(self,string)
+        """eraseControlCharacters(string)
         
         Return a copy of the string with the blank characters (32),
         tabs (9) and end of line (13 and 10) before of the separators
@@ -145,23 +141,23 @@
         return string
 
     def validateCode(self, code):
-        """validateCode(self, code)
+        """validateCode(code)
         
         Test if the code have invalid characters and try to erase it,
         if it is posible return a valid code else return a empty string.
         """
         if not isinstance(code, unicode):
-            print _("Invalid code, it must be a unicode string")
+            print(_("Invalid code, it must be a unicode string") )
             return u""
         # Valid chararcter: A-Z a-z 0-9 ñ Ñ . $ # % & _ 
         # "valid_code" : "[^A-Za-z0-9ñÑ.$#%&_]"
-        _ucode = self.__pattern["valid_code"].sub(u"", code)
+        _ucode = self.__pattern["valid_code"].sub(u"_", code)
         if _ucode != code:
             try:
-                print utils.mapping(_("The code '$1' have invalid characters."),
-                               (code.encode("utf8"),))
+                print(utils.mapping(_("The code '$1' have invalid characters, replaced by '$2'."),
+                               (code.encode("utf8"),_ucode.encode("utf8"))) )
             except:
-                print utils.mapping(_("The code '$1' have invalid characters and can not be encoded in utf8."), (code,))
+                print(utils.mapping(_("The code '$1' have invalid characters and can not be encoded in utf8."), (code,)) )
             
             if len(_ucode) == 0:
                 _normalize_code = ''.join((c for c in unicodedata.normalize('NFD', _ucode) if unicodedata.category(c) != 'Mn'))
@@ -173,25 +169,30 @@
                     _hexdigest_code = _hash_code.hexdigest()
                     _ucode = self.__pattern["valid_code"].sub(u"", _hexdigest_code)
             code = _ucode
+        if code == u"##":
+            # root code is an empty code : set to ROOT
+            return u"ROOT"
         # the lasts characters can not be <#> or <##>
         # <##> -> root record in FIEFDC-3
         # <#> -> chapter record in FIEFDC-3
         if len(code) > 0:
             while code[-1] == u"#":
                 code = code[:-1]
+                if len(code) == 0:
+                    return code
             if len(code) > 20:
                 code = code[:20]
             # only one charecter # % or &
             if sum([code.count(c) for c in u'#%&']) > 1:
-                print utils.mapping(_("The code '$1' contains special "\
-                                      "characters repeated."),(code.encode("utf8"),))
+                print(utils.mapping(_("The code '$1' contains special "\
+                                      "characters repeated."),(code.encode("utf8"),)) )
                 _i = min([code.find(c) for c in u'#%&'])
                 code = code[:_i+1] + \
                         self.__pattern["special_char"].sub(u"", code[_i+1:])
         return code
 
     def parseDate(self, date):
-        """parseDate(self, date)
+        """parseDate(date)
         
         date: in the format:
             uneven len: add a Leading 0
@@ -233,8 +234,8 @@
                 _d = 0
         return (_y, _m, _d)
 
-    def parseRecord(self,record):
-        """parseRecord(self,record)
+    def parseRecord(self, record, interface):
+        """parseRecord(record, interface)
         
         record: the record line readed from the file whith the format:
             type|field|field|subfield\subfield|...
@@ -317,6 +318,7 @@
             A: Labels
                 1- Record Code
                 2- <Label\>
+            interface:
         """
         # TODO:  ~L ~J RTF and HTML files
         # TODO:  test ~Q ~J ~G
@@ -331,13 +333,13 @@
             self._parseV(_field_list)
         elif _field_list[0] == u"C":
             self.__statistics.C += 1
-            self._parseC(_field_list)
+            self._parseC(_field_list, interface)
         elif _field_list[0] == u"D":
             self.__statistics.D += 1
-            self._parseDY(_field_list)
+            self._parseDY(_field_list, interface)
         elif _field_list[0] == u"Y":
             self.__statistics.Y += 1
-            self._parseDY(_field_list)
+            self._parseDY(_field_list, interface)
         elif _field_list[0] == u"M":
             self.__statistics.M += 1
             self._parseMN(_field_list)
@@ -386,10 +388,11 @@
             self.__statistics.A += 1
             self._parseA(_field_list)
         else:
+            print(utils.mapping(_("FIEBDC. Unknow record: $1"),(record[:100],)))
             self.__statistics.unknow += 1
 
     def _parseV(self, field_list):
-        """_parseV(self, field_list)
+        """_parseV(field_list)
         
         field_list: field list of the record
             0- V :Property and Version
@@ -404,11 +407,11 @@
             9- [Date budget certificate]
         """
         if self.__statistics.records != 1:
-            print utils.mapping(_("The 'V' record (Property and Version) "\
+            print(utils.mapping(_("The 'V' record (Property and Version) "\
                     "must be the first record in the file but it is the "\
-                    "number: $1"), (self.__statistics.records,))
-            print _("The default values were taken and this V record is "\
-                  "ignored")
+                    "number: $1"), (str(self.__statistics.records),)) )
+            print(_("The default values were taken and this V record is "\
+                  "ignored") )
             return
         # _____number of fields_____
         # Any INFORMATION after last field separator is ignored
@@ -441,7 +444,7 @@
         _file_format = _version_date[0]
         if _file_format in self.__format_list:
             self.__file_format = _file_format
-            print utils.mapping(_("FIEBDC format: $1"),(_file_format,))
+            print(utils.mapping(_("FIEBDC format: $1"),(_file_format,)) )
 
         if len(_version_date) > 1:
             _date = _version_date[1]
@@ -451,7 +454,7 @@
                     self.__budget.setDate(_parsed_date)
         # _____Generator_____
         # ignored field
-        print utils.mapping(_("FIEBDC file generated by $1"),(_generator,))
+        print(utils.mapping(_("FIEBDC file generated by $1"),(_generator,)) )
         # _____Header_Title_____
         _header_title = _header_title.split(u"\\")
         _header_title = [_title.strip() for _title in _header_title]
@@ -499,7 +502,7 @@
         self.__statistics.valid = self.__statistics.valid + 1
 
     def _parseK(self, field_list):
-        """_parseK(self, field_list)
+        """_parseK(field_list)
         
         field_list: field list of the record
             0- K: Coefficients
@@ -740,8 +743,8 @@
                                            (_decimal_index//13))
         self.__statistics.valid = self.__statistics.valid +1
 
-    def _parseC(self, field_list):
-        """_parseC(self, field_list)
+    def _parseC(self, field_list, interface):
+        """_parseC(field_list)
         
         field_list: field list of the record
             0- C: Record
@@ -774,9 +777,9 @@
         if len(_codes) > 0:
             # parse the hierarchy of the first code
             # hierarchy: 0->root, 1->Chapter/subchapter, 2->other
-            if len(_codes[0]) > 2 and _codes[0][-2:] == u"##":
+            if len(_codes[0]) > 1 and _codes[0][-2:] == u"##":
                 _hierarchy = 0
-            elif len(_codes[0]) > 1 and _codes[0][-1:] == u"#":
+            elif len(_codes[0]) > 0 and _codes[0][-1:] == u"#":
                 _hierarchy = 1
             else:
                 _hierarchy = 2
@@ -792,7 +795,7 @@
             _code = _codes[0]
             _synonyms = [synonym.encode("utf8") for synonym in _codes]
         else:
-            print _("Record C without a valid code")
+            print(_("Record C without a valid code") )
             return
         # _____Unit_____
         # nothing to do
@@ -804,6 +807,7 @@
             _dates = _dates[:-1]
         if len(_prices) > 0 and _prices[-1] == u"\\":
             _prices = _prices[:-1]
+        interface.updateGui()
         _dates = _dates.split(u"\\")
         _prices = _prices.split(u"\\")
         # number of prices = number of titles in "V" line
@@ -860,6 +864,7 @@
         #                    1 -> None,H
         #                    2 -> None,Q,%
         #                    3 -> None,MC,MCr,MM,MS,ME,MCu,Mal,ML,M
+        interface.updateGui()
         if _hierarchy == 0:
             if _type == u"OB":
                 _subtype = _type
@@ -868,8 +873,8 @@
                 _subtype = u""
                 _type = 0
             else:
-                print utils.mapping(_("Incorrect type ($1) in the code $2"),
-                      (_type.encode("utf8"), _code.encode("utf8")))
+                print(utils.mapping(_("Incorrect type ($1) in the code $2"),
+                      (_type.encode("utf8"), _code.encode("utf8"))) )
                 _type = 0
                 _subtype = u""
         elif _hierarchy == 1:
@@ -880,8 +885,8 @@
                 _subtype = u""
                 _type = 0
             else:
-                print utils.mapping(_("Incorrect type ($1) in the code $2"),
-                      (_type.encode("utf8"), _code.encode("utf8")))
+                print(utils.mapping(_("Incorrect type ($1) in the code $2"),
+                      (_type.encode("utf8"), _code.encode("utf8"))) )
                 _type = 0
                 _subtype = u""
         else:
@@ -908,8 +913,8 @@
                 _subtype = u""
                 _type = 0
             else:
-                print utils.mapping(_("Incorrect type ($1) in the code $2"),
-                      (_type.encode("utf8"), _code.encode("utf8")))
+                print(utils.mapping(_("Incorrect type ($1) in the code $2"),
+                      (_type.encode("utf8"), _code.encode("utf8"))) )
                 _type = 0
                 _subtype = u""
         self.__budget.setRecord(_code.encode("utf8"), _synonyms, _hierarchy,
@@ -917,8 +922,8 @@
             _prices, _dates, _type, _subtype.encode("utf8"))
         self.__statistics.valid = self.__statistics.valid + 1
     
-    def _parseDY(self, field_list):
-        """_parseDY(self, field_list)
+    def _parseDY(self, field_list, interface):
+        """_parseDY(field_list)
         
         field_list: field list of the record
             0- D or Y: DECOMPOSITION or ADD DECOMPOSITION
@@ -939,6 +944,7 @@
         _record_type = field_list[0]
         _code = self.delete_control_space(field_list[1])
         _children = self.delete_control_space(field_list[2])
+        interface.updateGui()
         # _____Code_____
         # "#" and "##" characters at the end of the code are erased
         # invalid characters are also erased
@@ -948,6 +954,7 @@
         _children = _children.split(u"\\")
         _children_list = [ ]
         _child_index = 0
+        interface.updateGui()
         while _child_index < len(_children)-3:
             # _____subfields_____
             _child_code = _children[_child_index]
@@ -960,22 +967,22 @@
                 try:
                     _factor = float(_factor)
                 except ValueError:
-                    print utils.mapping(_("ValueError loadig the "\
+                    print(utils.mapping(_("ValueError loadig the "\
                           "descomposition of the record $1, the factor "\
                           "of the child $2 must be a float number and "\
                           "can not be $3, seted default value 1.0"),
-                          (_code.encode("utf8"), _child_code.encode("utf8"), _factor.encode("utf8")))
+                          (_code.encode("utf8"), _child_code.encode("utf8"), _factor.encode("utf8"))) )
                     _factor = 1.0
             #____yield___
             if _yield != u"":
                 try:
                     _yield = float(_yield)
                 except ValueError:
-                    print utils.mapping(_("ValueError loading the "\
+                    print(utils.mapping(_("ValueError loading the "\
                           "descomposition of the record $1, the yield of "\
                           "the child $2, must be a float number and can"\
                           "not be $3,  seted default value 1.0"),
-                           (_code.encode("utf8"), _child_code.encode("utf8"), _factor.encode("utf8")))
+                           (_code.encode("utf8"), _child_code.encode("utf8"), _factor.encode("utf8"))) )
                     _yield = 1.0
             if _child_code != u"" and _code != u"":
                 _children_list.append([_child_code, _factor, _yield ])
@@ -986,10 +993,11 @@
             self.__budget.setTree(_code.encode("utf8"), _child_code.encode("utf8"), _position, _factor, 
                 _yield, "", "", "", "")
             _child_index = _child_index + 3
+            interface.updateGui()
         self.__statistics.valid = self.__statistics.valid +1
 
     def _parseT(self, field_list):
-        """_parseT(self, field_list)
+        """_parseT(field_list)
         
         field_list: field list of the record
             0- T: Text
@@ -1017,7 +1025,7 @@
         self.__statistics.valid = self.__statistics.valid + 1
 
     def _parseMN(self, field_list):
-        """_parseMN(self, field_list)
+        """_parseMN(field_list)
         
         field_list: field list of the record
             0- M or N: MEASURE or ADD MEASURE
@@ -1059,12 +1067,12 @@
             _child_code =  self.validateCode(_code_list[0])
             _parent_code = None
         else:
-            print utils.mapping(_("Invalid codes in $1 record, codes $2"),
-                  (_record_type.encode("utf8"), _codes.encode("utf8")))
+            print(utils.mapping(_("Invalid codes in $1 record, codes $2"),
+                  (_record_type.encode("utf8"), _codes.encode("utf8"))) )
             return
         if _child_code == u"":
-            print utils.mapping(_("Empty child code in $1 record, codes: "\
-                  "$2"), (_record_type.encode("utf8"), _codes.encode("utf8")))
+            print(utils.mapping(_("Empty child code in $1 record, codes: "\
+                  "$2"), (_record_type.encode("utf8"), _codes.encode("utf8"))) )
             return
         if _parent_code == None:
             # Empty parent code. No-estructured measures.
@@ -1083,8 +1091,8 @@
             try:
                 _path = int(_path)
             except ValueError:
-                print utils.mapping(_("Invalid path in $1 record, "\
-                      "codes $2"), (_record_type.encode("utf8"), _codes.encode("utf8")))
+                print(utils.mapping(_("Invalid path in $1 record, "\
+                      "codes $2"), (_record_type.encode("utf8"), _codes.encode("utf8"))) )
                 return
             if _path > 0:
                 _path -= 1
@@ -1094,9 +1102,9 @@
         try:
             _total = float(_total)
         except ValueError:
-            print utils.mapping(_("Invalid Total Measure value in $1 "\
+            print(utils.mapping(_("Invalid Total Measure value in $1 "\
                   "record, codes $2. Total fixed to 0."),
-                  (_record_type.encode("utf8"), _codes.encode("utf8")))
+                  (_record_type.encode("utf8"), _codes.encode("utf8"))) )
             _total = 0
         # _____Measure lines_____
         _lines = _lines.split(u"\\")
@@ -1115,9 +1123,9 @@
             if _linetype == 3:
                 # "formula": ".*[^0123456789\.()\+\-\*/\^abcdp ].*"
                 if self.__pattern["formula"].match(_comment):
-                    print utils.mapping(_("The comment is not a formula or "\
+                    print(utils.mapping(_("The comment is not a formula or "\
                           "its have invalid characters, in the $1 record, "\
-                          "codes $2"), (_record_type.encode("utf8"), _codes.encode("utf8")))
+                          "codes $2"), (_record_type.encode("utf8"), _codes.encode("utf8"))) )
                     return
                 else:
                     _formula = _comment.encode("utf8")
@@ -1141,8 +1149,8 @@
                 if _width != u"": _width = float(_width)
                 if _height != u"": _height = float(_height)
             except ValueError:
-                print utils.mapping(_("The measure values are not float "\
-                      "numbers, code $1"), (_codes.encode("utf8"),))
+                print(utils.mapping(_("The measure values are not float "\
+                      "numbers, code $1"), (_codes.encode("utf8"),)) )
                 return
             # Prevent subfield units remains empty.
             if (_units == u"" and (_length != u"" or _width != u""
@@ -1156,7 +1164,7 @@
         self.__statistics.valid = self.__statistics.valid + 1
 
     def _parseW(self, field_list):
-        """_parseW(self, field_list)
+        """_parseW(field_list)
         
         field_list: field list of the record
             0- W: Geografical field
@@ -1195,7 +1203,7 @@
         self.__statistics.valid = self.__statistics.valid +1
     
     def _parseL(self, field_list):
-        """_parseL(self, field_list)
+        """_parseL(field_list)
         
         field_list: field list of the record
             0- L: Sheet of Conditions 1
@@ -1259,7 +1267,7 @@
             _scodes_text = field_list[1]
             if _scodes_text == u"":
                 # TODO: rtf and html files
-                print "Html and rtf files not yet implemented in ~L record"
+                print("Html and rtf files not yet implemented in ~L record" )
             else:
                 # _____Section-code_Section-text_____
                 # last \ is erased
@@ -1288,7 +1296,7 @@
                 self.__statistics.valid = self.__statistics.valid +1
     
     def _parseQ(self, field_list):
-        """_parseQ(self, field_list)
+        """_parseQ(field_list)
         
         field_list: field list of the record
             0- Q: Sheet of Conditions 2
@@ -1349,7 +1357,7 @@
         self.__statistics.valid = self.__statistics.valid +1
     
     def _parseJ(self, field_list):
-        """_parseJ(self, field_list)
+        """_parseJ(field_list)
         
         field_list: field list of the record
             0- J: Sheet of Conditions 3
@@ -1374,13 +1382,13 @@
         _paragraph_text = field_list[1]
         if _paragraph_text == u"":
             # TODO: rtf and html files
-            print "Html and rtf files not yet implemented in ~J record"
+            print("Html and rtf files not yet implemented in ~J record" )
         else:
             self.__budget.setSheetParagraph(paragraph_code.encode("utf8"), paragraph_text.encode("utf8"))
             self.__statistics.valid = self.__statistics.valid +1
     
     def _parseG(self, field_list):
-        """_parseG(self, field_list)
+        """_parseG(field_list)
         
         field_list: field list of the record
             0- G: Grafic info
@@ -1412,7 +1420,7 @@
         _tested_grafic_file_list = []
         for _grafic_file in _grafic_file_list:
             _str_grafic_file = _grafic_file.encode("utf8")
-            _path = os.path.dirname(self.__filename)
+            _path = os.path.dirname(self.__filename).encode("utf8")
             _grafic_file_path = os.path.join(_path, _str_grafic_file)
             if os.path.exists(_grafic_file_path):
                 _tested_grafic_file_list.append(_grafic_file_path)
@@ -1441,15 +1449,15 @@
                 elif os.path.exists(_grafic_file_path_ll):
                     _tested_grafic_file_list.append(_grafic_file_path_ll)
                 else:
-                    print utils.mapping(_("The file $1 do not exist"),
-                        (_grafic_file_path,))
+                    print(utils.mapping(_("The file $1 do not exist"),
+                        (_grafic_file_path.decode("utf8"),)) )
         if len(_grafic_file_list) > 0:
             for _grafic_file in _tested_grafic_file_list:
                 self.__budget.addFile(_record_code.encode("utf8"), _grafic_file, "img", "")
             self.__statistics.valid = self.__statistics.valid +1
     
     def _parseE(self, field_list):
-        """_parseE(self, field_list)
+        """_parseE(field_list)
         
         field_list: field list of the record
             0- E: Company
@@ -1548,7 +1556,7 @@
         self.__statistics.valid = self.__statistics.valid +1
     
     def _parseX(self, field_list):
-        """_parseX(self, field_list)
+        """_parseX(field_list)
         
         field_list: field list of the record
             A)
@@ -1603,14 +1611,15 @@
         self.__statistics.valid = self.__statistics.valid +1
 
     def _parseF(self, field_list):
-        """_parseF(self, field_list)
+        """_parseF(field_list)
         
         field_list: field list of the record
             0- F: Files
             1- Record code
             2- { Type \ { Filenames; } \ [Description] }
         """
-
+        print("parseF")
+        print(field_list)
         # _____Number of fields_____
         # The record must have at least 3 fields
         if len(field_list) < 3:
@@ -1638,23 +1647,24 @@
             _files_list.extend[u""]*(3 - len(_files_list)%3)
         _file_index = 0
         _tested_files_list = []
+        print(_files_list)
         while _file_index < len(_files_list)-3:
             _type = _files_list[_file_index].replace(u" ",u"")
-##            _types = {
-##                "0": _("others"),
-##                "1": _("características técnicas y de fabricación"),
-##                "2": _("manual de colocación, uso y mantenimiento"),
-##                "3": _("certificado/s de elementos y sistemas"),
-##                "4": _("normativa y bibliografía"),
-##                "5": _("tarifa de precios"),
-##                "6": _("condiciones de venta"),
-##                "7": _("carta de colores"),
-##                "8": _("ámbito de aplicación y criterios selección"),
-##                "9": _("cálculo de elementos y sistemas"),
-##                "10": _("presentación, datos generales, objetivos, etc. de "\
-##                        "empresa"),
-##                "11": _("certificado/s de empresa"),
-##                "12": _("obras realizadas")}
+            ## _types = {
+            ##           "0": _("others"),
+            ##           "1": _("características técnicas y de fabricación"),
+            ##           "2": _("manual de colocación, uso y mantenimiento"),
+            ##           "3": _("certificado/s de elementos y sistemas"),
+            ##           "4": _("normativa y bibliografía"),
+            ##           "5": _("tarifa de precios"),
+            ##           "6": _("condiciones de venta"),
+            ##           "7": _("carta de colores"),
+            ##           "8": _("ámbito de aplicación y criterios selección"),
+            ##           "9": _("cálculo de elementos y sistemas"),
+            ##          "10": _("presentación, datos generales, objetivos, " \
+            ##                  "etc. de empresa"),
+            ##          "11": _("certificado/s de empresa"),
+            ##          "12": _("obras realizadas")}
             _types = [u"0", u"1", u"2", u"3", u"4", u"5", u"6", u"7", u"8", u"9", u"10",
                       u"11", u"12"]
             if not _type in _types:
@@ -1662,11 +1672,15 @@
             _filenames = _files_list[_file_index + 1]
             _description = _files_list[_file_index + 2]
             _file_index += 3
+            print(u"type: " + _type)
+            print(u"filenames: " + _filenames)
+            print(u"_description: " + _description)
             if len(_filenames) and _filenames[-1] == u";":
                 _files = _files[:-1]
-            _filenames_list = _files.split(u";")
+            _filenames_list = _filenames.split(u";")
+            
             _path = os.path.dirname(self.__filename)
-            for _filename in filenames_list:
+            for _filename in _filenames_list:
                 _file_path = os.path.join(_path, _filename.encode("utf8"))
                 if os.path.exists(_file_path):
                     _tested_files_list.append([_file_path, _type.encode("utf8"),
@@ -1700,15 +1714,15 @@
                         _tested_files_list.append([_file_path_ll, _type.encode("utf8"),
                                                    _description.encode("utf8")])
                     else:
-                        print utils.mapping(_("The file $1 do not exist"),
-                            (_file_path,))
+                        print(utils.mapping(_("The file $1 do not exist"),
+                            (_file_path,)) )
         if len(_tested_files_list) > 0:
-            for _file in _tested_file_list:
-                self.__budget.addFile(_record_code.encode("utf8"), _file[0], file[1], file[2])
+            for _file in _tested_files_list:
+                self.__budget.addFile(_record_code.encode("utf8"), _file[0], _file[1], _file[2])
         self.__statistics.valid = self.__statistics.valid +1
 
     def _parseB(self, field_list):
-        """_parseB(self, field_list)
+        """_parseB(field_list)
         
         field_list: field list of the record
             0- B: Change code
@@ -1737,7 +1751,7 @@
         self.__statistics.valid = self.__statistics.valid + 1
 
     def _parseA(self, field_list):
-        """_parseA(self, field_list)
+        """_parseA(field_list)
         
         field_list: field list of the record
             0- A: Labels
@@ -1774,7 +1788,7 @@
         self.__statistics.valid = self.__statistics.valid + 1
 
     def _parseP(self, field_list):
-        """_parseP(self, field_list)
+        """_parseP(field_list)
         
         field_list: Parametric record
             A) Global paremetric record
@@ -1806,14 +1820,14 @@
                     field_list = field_list[0:3]
                 field_list = field_list[1:]
                 if len(field_list) != 2:
-                    print _("PyArq hates parametric DLLs")
+                    print(_("PyArq hates parametric DLLs") )
                     return
         else:
             return
         # _____Description_____
         _description = field_list[1]
         if _description == u"":
-            print _("PyArq hates parametric DLLs")
+            print(_("PyArq hates parametric DLLs") )
             return
         # Adding last end of line
         _description = _description + u"\r\n"
@@ -1878,19 +1892,19 @@
                     # parse data
                     if len(_line) > 2 and _line[:2] == u"::":
                         # Delete spaces out " delimiter
-                        #print "__PRECIO__" + _line[2:]
+                        #print("__PRECIO__" + _line[2:])
                         pass
                     elif len(_line) > 2 and _line[:2] == u"%:":
                         # Delete spaces out " delimiter
-                        #print "__%AUX__" + _line[2:]
+                        #print("__%AUX__" + _line[2:])
                         pass
                     elif len(_line) > 3 and _line[:2] == u"%%:":
                         # Delete spaces out " delimiter
-                        #print "__%%AUX__" + _line[2:]
+                        #print("__%%AUX__" + _line[2:] )
                         pass
                     elif self.__pattern["var"].search(_line):
                         # Delete spaces out " delimiter
-                        #print "line =", _line
+                        #print( "line =", _line )
                         while _line.count(u'"') % 2 == 1 and \
                               index + _pass_line + 1 < len(_lines) -1:
                             _line = _line + _lines[index + _pass_line + 1]
@@ -1898,10 +1912,10 @@
                         _search = self.__pattern["var"].search(_line)
                         if _search is not None:
                             _var = _search.groups()[0] + u" = " + _search.groups()[1]
-                            #print "__VAR__" + str(_var)
+                            #print("__VAR__" + str(_var) )
                             pass
                         else:
-                            #print "no __VAR__", _line
+                            #print( "no __VAR__", _line )
                             pass
                     elif self.__pattern["descomposition"].search(_line):
                         # Delete spaces out " delimiter
@@ -1909,73 +1923,73 @@
                         _search = self.__pattern["descomposition"].search(_line)
                         if _search is not None:
                             _var = _search.groups()[0] + u":" + _search.groups()[1]
-                            #print "__Descomposición__" + str(_var)
+                            #print( "__Descomposición__" + str(_var) )
                             pass
                         else:
-                            #print "no __Descomposición__", _line
+                            #print("no __Descomposición__", _line )
                             pass
                     else:
-                        print "Parametric: code: " + _family_code.encode("utf8")
-                        print "******* Desconocido *** : " + _line
-                        if index-10 > 0: print "-11 :", _lines[index-11].encode("utf8")
-                        if index-10 > 0: print "-10 :", _lines[index-10].encode("utf8")
-                        if index-9 > 0: print "-9 :", _lines[index-9].encode("utf8")
-                        if index-8 > 0: print "-8 :", _lines[index-8].encode("utf8")
-                        if index-7 > 0: print "-7 :", _lines[index-7].encode("utf8")
-                        if index-6 > 0: print "-6 :", _lines[index-6].encode("utf8")
-                        if index-5 > 0: print "-5 :", _lines[index-5].encode("utf8")
-                        if index-4 > 0: print "-4 :", _lines[index-4].encode("utf8")
-                        if index-3 > 0: print "-3 :", _lines[index-3].encode("utf8")
-                        if index-2 > 0: print "-2 :", _lines[index-2].encode("utf8")
-                        if index-1 > 0: print "-1 :", _lines[index-1].encode("utf8")
-                        print "-0 :", _lines[index-0]
+                        print("Parametric: code: " + _family_code.encode("utf8") )
+                        print("******* Desconocido *** : " + _line )
+                        if index-10 > 0: print("-11 : " + _lines[index-11].encode("utf8") )
+                        if index-10 > 0: print("-10 : " + _lines[index-10].encode("utf8") )
+                        if index-9 > 0: print("-9 : " + _lines[index-9].encode("utf8") )
+                        if index-8 > 0: print("-8 : " + _lines[index-8].encode("utf8") )
+                        if index-7 > 0: print("-7 : " + _lines[index-7].encode("utf8") )
+                        if index-6 > 0: print("-6 : " + _lines[index-6].encode("utf8") )
+                        if index-5 > 0: print("-5 : " + _lines[index-5].encode("utf8") )
+                        if index-4 > 0: print("-4 : " + _lines[index-4].encode("utf8") )
+                        if index-3 > 0: print("-3 : " + _lines[index-3].encode("utf8") )
+                        if index-2 > 0: print("-2 : " + _lines[index-2].encode("utf8") )
+                        if index-1 > 0: print("-1 : " + _lines[index-1].encode("utf8") )
+                        print("-0 :" + _lines[index-0] )
                         pass
                 else:
                     _parameter_list = _line.split(u"\\")[1:-1]
                     if len(_parameter_list) >= 2:
                         if _parameter_list[0] == u"C" or \
                            _parameter_list[0] == u"COMENTARIO":
-                            #print "__COMENTARIO__" + _parameter_list[1]
+                            #print( "__COMENTARIO__" + _parameter_list[1])
                             self.__budget.setParametricSelectComment(
                                 _family_code.encode("utf8"), _parameter_list[1].encode("utf8"))
                         elif _parameter_list[0] == u"R" or \
                            _parameter_list[0] == u"RESUMEN":
-                            #print "__RESUMEN__" + _parameter_list[1]
+                            #print( "__RESUMEN__" + _parameter_list[1])
                             self.__budget.setParametricSummary(_family_code.encode("utf8"),
                                 _parameter_list[1].encode("utf8"))
                         elif _parameter_list[0] == u"T" or \
                            _parameter_list[0] == u"TEXTO":
-                            #print "__TEXTO__" + _parameter_list[1]
+                            #print( "__TEXTO__" + _parameter_list[1])
                             self.__budget.setParametricText(_family_code.encode("utf8"),
                                 _parameter_list[1].encode("utf8"))
                         elif _parameter_list[0] == u"P" or \
                            _parameter_list[0] == u"PLIEGO":
-                            #print "__PLIEGO__" + str(_parameter_list[1:])
+                            #print( "__PLIEGO__" + str(_parameter_list[1:]) )
                             pass
                         elif _parameter_list[0] == u"K" or \
                            _parameter_list[0] == u"CLAVES":
-                            #print "__CLAVES__" + str(_parameter_list[1:])
+                            #print( "__CLAVES__" + str(_parameter_list[1:]) )
                             pass
                         elif _parameter_list[0] == u"F" or \
                            _parameter_list[0] == u"COMERCIAL":
-                            #print "__COMERCIAL__" + str(_parameter_list[1:])
+                            #print( "__COMERCIAL__" + str(_parameter_list[1:]) )
                             pass
                         else:
-                            #print "==PARAMETRO==" + str(_parameter_list[:])
+                            #print( "==PARAMETRO==" + str(_parameter_list[:]) )
                             pass
                 _final_description = _final_description + _line + u"\r\n"
                 
-                #print _line
+                #print( _line )
         # Delete last empty line
         _description = _final_description[:-2]
         _lines = _description.split(u"\r\n")
         for _line in _lines:
             pass
-            #print _line
+            #print( _line )
         self.__statistics.valid = self.__statistics.valid + 1
 
     def readFile(self, budget=None, filename=None, interface=None):
-        """readFile(self, budget=None, filename=None)
+        """readFile(budget=None, filename=None)
         
         filename: the filename of the fiebdc file
         budget: base.obra object
@@ -1985,7 +1999,8 @@
                       readFile_progress(percent)
                       readFile_end()
                       readFile_cancel()
-        Return the budget objetc or None if the file can be readed
+                      updateGui()
+        Return  None
         """
         if not filename is None and not budget is None:
             self.__filename = filename
@@ -2002,14 +2017,19 @@
         try:
             _file =  open(self.__filename, 'r')
         except IOError:
-            print utils.mapping("IOError: $1", (self.__filename,))
+            print( utils.mapping("IOError: $1", (self.__filename,)) )
+            return None
+        _filesize = float(os.path.getsize(self.__filename))
+        if _filesize == 0.0:
+            print( utils.mapping("Empty File: $1", (self.__filename,)) )
+            # Todo: Create empty budget
             return None
         self.__budget.filename = self.__filename
         interface.readFile_send_message(utils.mapping(_("Loading file $1"),
                          (self.__filename,)))
-        _filesize = float(os.path.getsize(self.__filename))
         interface.readFile_progress(_file.tell() / _filesize)
         _buffer = _file.read(1000)
+        interface.updateGui()
         # set codepage from V record
         _record_list = _buffer.split("~")
         registro_V = _record_list[1]
@@ -2043,6 +2063,7 @@
                   "Not 'V' record in File! Default character encoding: "\
                   "$1"), (self.__character_set,)))
         _buffer = unicode(_buffer, self.__character_set)
+        interface.updateGui()
         # Any INFORMATION between the beginning of the file and the
         # beginning of the first registry “~” is ignored
         #"after_first_tilde" : "^[^~]*~"
@@ -2056,11 +2077,12 @@
             _record_list = _buffer.split(u"~")
             # The last record can be incomplete unless it is the last one of
             # the file
-            if len(_record_list) > 1:
+            #if len(_record_list) > 1:
+            if (_file.tell() / _filesize) != 1.0:
                 # not the end
                 _last_record = _record_list.pop()
             else:
-                # the end record
+                # The last record
                 # The blank characters (32), tabs (9) and end of line
                 # (13 and 10) at the end of the file are ignored.
                 #"end_control" : "((\r\n)| |\t)+$"
@@ -2070,11 +2092,14 @@
             for record in _record_list:
                 if self.__cancel:
                     break
-                self.parseRecord(record)
+                self.parseRecord(record, interface)
+                interface.updateGui()
             interface.readFile_progress(_file.tell() / _filesize)
             _buffer2 = _file.read(100000)
+            interface.updateGui()
             _buffer2 = unicode(_buffer2, self.__character_set)
             _buffer = _last_record + _buffer2
+            interface.updateGui()
         _file.close()
         if self.__cancel:
             interface.readFile_cancel()
@@ -2084,22 +2109,22 @@
             if self.__statistics.O > 0:
                 interface.readFile_send_message(
                     utils.mapping(_("$1 unsuported record type O: "\
-                    "Comercial Relationship"), (self.__statistics.O,)))
+                    "Comercial Relationship"), (str(self.__statistics.O,))))
             if self.__statistics.valid == 0:
                 interface.readFile_send_message(_("This file is not a valid FIBDC3 file"))
                 return None
             interface.readFile_end()
-            self._testBudget(self.__budget)
-            return self.__budget
+            self._testBudget(self.__budget, interface)
+            return None
 
-    def _testBudget(self, budget):
-        """testBudget(self,budget)
+    def _testBudget(self, budget, interface):
+        """testBudget(budget)
         
         budget: base.obra object
         Test and repair budget object after read it from bc3 file
         """
         # TODO: more to do here
-        print _("Testing budget ...")
+        print( _("Testing budget ...") )
         # Add price to records without price
         _iter = budget.iter()
         _titlelist = budget.getTitleList()[1]
@@ -2117,7 +2142,8 @@
                     _root = budget.getRecord(budget.getRoot())
                     _price = [0.0, _root.getDate(_len_prices + _index)]
                     budget.addPriceToRecord(_price,_record)
-        print _("End Test")
+            interface.updateGui()
+        print( _("End Test") )
 
     def delete_control_space(self, text):
         text = self.delete_control(text)
@@ -2141,6 +2167,7 @@
     +-- object
       +-- Interface
     Atributes:
+        "endSuccessfully": True/False
         "__progress": The progress percentage
         "__statistics": The record statistics 
     Methods:
@@ -2150,11 +2177,13 @@
         readFile_set_statistics(statistics)
         readFile_end()
         readFile_cancel()
+        updateGui()
         
     """
     def __init__(self):
         self.__progress = 0.0
         self.__statistics = Statistics()
+        self.endSuccessfully = False
 
     def readFile_set_statistics(self, statistics):
         """readFile_set_statistics(statistics)
@@ -2170,9 +2199,9 @@
         
         message: mesage from readFile method
         
-        print message
+        print( message )
         """
-        print message
+        print( message )
 
     def readFile_progress(self, percent):
         """progress(percent)
@@ -2188,14 +2217,26 @@
         
         The readFile method end successfully
         """
-        print self.__statistics
+        self.endSuccessfully == True
+        print(self.__statistics)
+        print("progreso = " + str(self.__progress))
 
     def readFile_cancel(self):
         """readFile_cancel()
         
         The readFile method is canceled
         """
-        print _("Process terminated")
+        self.endSuccessfully == False
+        print( _("Process terminated") )
+        print("progreso = " + str(self.__progress))
+
+    def updateGui(self):
+        """updateGui(self)
+        
+        Some interfaces need update gui while doing some time intensive
+        computation. Do it here.
+        """
+        pass
 
 class Statistics(object):
     """fiebdc.Statistics
@@ -2264,10 +2305,14 @@
             self.time = 0.0
 
     def __str__(self):
+        return self.str().encode("utf8")
+
+    def str(self):
+
         return utils.mapping(_("Time to load: $1 seconds"),
                 (("%.2f" %(self.time)),)) + "\n" + \
                utils.mapping(_("Records/Valid Records: $1/$2"), 
-               (self.records, self.valid)) + "\n" +\
+               (str(self.records), str(self.valid))) + "\n" +\
                "V: %s\n" %(self.V,) + \
                "C: %s\n" %(self.C,) + \
                "D: %s\n" %(self.D,) + \
--- a/Generic/globalVars.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/globalVars.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File globalVars.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -20,20 +20,26 @@
 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # module for global variables
+# not translatable strings here _("strig")
+
 import os
 import sys
 
-version = "pyArq Presupuestos v0.0.0"
-changeset = 22
+name = "pyArq Presupuestos"
+version = "v0.0.0"
+changeset = "c23"
 baseversion = 0
 
 # path: Paths where find the program files needed
 path = {
     "HOME" : "",
     "APPDATA" : "",
-    #"DURUS-DATABASE": "/pyArq-Presupuestos/durus/",
     "BUDGET": "/pyArq-Presupuestos/budget/",
     "ICON" : "/images/pyArq-Presupuestos.png",
+    "ICON16" : "/images/pyArq-Presupuestos-16.svg",
+    "ICON32" : "/images/pyArq-Presupuestos-32.svg",
+    "ICON64" : "/images/pyArq-Presupuestos-64.svg",
+    "ICON128" : "/images/pyArq-Presupuestos-128.svg",
     "CHAPTER-ICON" : "/images/chapter.png",
     "UNIT-ICON" : "/images/unit.png",
     "MATERIAL-ICON" : "/images/material.png",
@@ -43,10 +49,14 @@
     "CONNECTED-ICON": "/images/connected.png",
     "DISCONNECTED-ICON": "/images/disconnected.png",
     "CLOSE-ICON": "/images/close.png",
+    "HORIZONTAL": "/images/horizontal.svg",
+    "VERTICAL": "/images/vertical.svg",
     "DESCRIPTION-ICON": "/images/description.png",
     "SHEET-ICON": "/images/sheet.png",
     "DECOMPOSITION-ICON" : "/images/decomposition.png",
     "MEASURE-ICON" : "/images/measure.png",
+    "FILEVIEW-ICON" : "/images/fileview.png",
+    "COMPANY-ICON" : "/images/company.png",
     "ACUMULATEDLINE-ICON" : "/images/acumulatedline.png",
     "PARCIALLINE-ICON" : "/images/parcialline.png",
     "NORMALLINE-ICON" : "/images/normalline.png",
@@ -54,33 +64,37 @@
     "ARROW-ICON": "/images/arrow.png",
     "IMAGE-ICON": "/images/image.png",
     "DXF-ICON": "/images/dxf.png",
-    "THROBBER-ICON": "/images/throbber.png",
-    "THROBBER-GIF": "/images/throbber.gif",
+    "PDF-ICON": "/images/pdf.png",
     "BUDGET-ICON": "/images/budget.png",
     "PYARQ-ICON": "/images/pyArq.png",
     }
 
 color = {
-    "ACTIVE" : "#CDD7FF",           # blue
-    "INDEX-EVEN" : "#C4C4C4",       # dark grey
-    "INDEX-UNEVEN" : "#DDDDDD",     # grey
-    "EVEN" : "#E6E6E6",             # dark white
-    "UNEVEN": "#FFFFFF",            # white
-    "CHAPTER-EVEN": "#D8E6E6",      # dark cian
-    "CHAPTER-UNEVEN": "#F0FFFF",    # cian
-    "TEXT": "#000000",              # black
-    "CALCULATED-TEXT": "#FF00FF",   # 
-    "SUBTOTAL": "#FAC8C8",
-    "SUBTOTAL-PARCIAL": "#ADD8E6",
+    "ACTIVE" : "#CDD7FF",           # Lavender Blue       (205,215,255,1)
+    "INDEX-EVEN" : "#C4C4C4",       # Silver, dark grey   (196,196,196,1)
+    "INDEX-UNEVEN" : "#DDDDDD",     # Gainsboro, grey     (221,221,221,1)
+    "EVEN" : "#E6E6E6",             # Whisper, dark white (230,230,230,1)
+    "UNEVEN": "#FFFFFF",            # White               (255,255,255,1)
+    "CHAPTER-EVEN": "#D8E6E6",      # Zircon, dark cian   (216,230,230,1)
+    "CHAPTER-UNEVEN": "#F0FFFF",    # Azure, cian         (240,255,255,1)
+    "TEXT": "#000000",              # Black               (  0,  0,  0,1)
+    "CALCULATED-TEXT": "#FF00FF",   # Magenta             (255,  0,255,1)
+    "SUBTOTAL": "#FAC8C8",          # Coral Candy         (250,200,200,1)
+    "SUBTOTAL-PARCIAL": "#ADD8E6",  # Light Blue          (173,216,230,1)
     }
 
 desktop = {
-    "autodetect" : True,
-    "desktop" : "",
-    "browser" : "firefox",
-    "mailapp" : "evolution",
-    "imageapp" : "gthumb",
-    "cadapp" : "qcad",
+    "autodetect" : True,    # True: try to autodect desktop
+    "desktop" : "",         # "linux", "macosx" or "windows"
+    "browser" : "",         # "firefox"
+    "mailapp" : "",         # "evolution"
+    "imageapp" : "",        # "gthumb"
+    "wmfapp" : "",          # "inkscape"
+    "cadapp" : "",          # "librecad"
+    "videoapp" : "",        # "vlc"
+    "officeapp" : "",       # "libreoffice"
+    "txtapp" : "",          # "gedit"
+    "rtfapp" : "",          # "libreoffice"
     }
 
 def getAppPath(key):
--- a/Generic/openwith.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/openwith.py	Thu May 02 16:31:17 2019 +0200
@@ -3,10 +3,10 @@
 ## File openwith.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2013 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                    <miguelangel@obraencurso.es>
 ##
-## This file is based in gtkgui_helpers.py and common/helpers.py from gajim
+## This file is based in common/helpers.py from gajim
 ##
 ## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
 ## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
@@ -33,72 +33,39 @@
 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 ##
 # Modules
+
+# python 2/3 compatibility
+from __future__ import absolute_import, division, print_function, unicode_literals
+
 import subprocess
 import os
+import platform
+import sys
 
 # pyArq-Presupuestos modules
-import globalVars
-
-# from gtkgui_helpers.py 
-def autodetect_desktop():
-    # recognize the environment and sets it in globalVars
-    if os.name == 'nt':
-        globalVars.desktop["desktop"] = "windows"
-    else:
-        _processes = get_running_processes()
-        if 'gnome-session' in _processes:
-            globalVars.desktop["desktop"] = "gnome"
-        elif 'startkde' in _processes:
-            globalVars.desktop["desktop"] = "kde"
-        elif 'startxfce4' in _processes or 'xfce4-session' in _processes:
-            globalVars.desktop["desktop"] = "xfce"
-        elif 'startlxde' in _processes or 'lxsession' in _processes:
-            globalVars.desktop["desktop"] = "lxde"
-        elif 'awesome' in _processes:
-            globalVars.desktop["desktop"] = "awesome"
-        elif 'dwm' in _processes:
-            globalVars.desktop["desktop"] = "dwm"
-        elif 'startfluxbox' in _processes:
-            globalVars.desktop["desktop"] = "fluxbox"
-        elif 'fvwm2' in _processes:
-            globalVars.desktop["desktop"] = "fvwm"
-        else:
-            globalVars.desktop["desktop"] = ""
+from Generic import globalVars
 
-def get_running_processes():
-    '''returns running processes or None (if not /proc exists)'''
-    if os.path.isdir('/proc'):
-        # under Linux: checking if 'gnome-session' or
-        # 'startkde' programs were run before gajim, by
-        # checking /proc (if it exists)
-        #
-        # if something is unclear, read `man proc`;
-        # if /proc exists, directories that have only numbers
-        # in their names contain data about processes.
-        # /proc/[xxx]/exe is a symlink to executable started
-        # as process number [xxx].
-        # filter out everything that we are not interested in:
-        files = os.listdir('/proc')
-
-        # files that doesn't have only digits in names...
-        files = filter(str.isdigit, files)
-
-        # files that aren't directories...
-        files = [f for f in files if os.path.isdir('/proc/' + f)]
-
-        # processes owned by somebody not running gajim...
-        # (we check if we have access to that file)
-        files = [f for f in files if os.access('/proc/' + f +'/exe', os.F_OK)]
-
-        # be sure that /proc/[number]/exe is really a symlink
-        # to avoid TBs in incorrectly configured systems
-        files = [f for f in files if os.path.islink('/proc/' + f + '/exe')]
-
-        # list of processes
-        processes = [os.path.basename(os.readlink('/proc/' + f +'/exe')) for f in files]
-
-        return processes
-    return []
+def autodetect_desktop():
+    """
+    recognize the environment and sets it in globalVars
+    os.name:
+             python2  'posix', 'nt', 'os2', 'ce', 'java', 'riscos'.
+             python3  'posix', 'nt', 'java'.
+    sys.platform
+              unix: return by uname 
+              Linux          'linux', 'linux2'
+              Windows        'win32'
+              Windows/Cygwin 'cygwin'
+              Mac OS X       'darwin'
+    """
+    if os.name == "nt":
+        globalVars.desktop["desktop"] = "windows"
+    elif sys.platform == "darwin":
+        globalVars.desktop["desktop"] = "macosx"
+    elif sys.platform.startswith('linux'):
+        globalVars.desktop["desktop"] = "linux"
+    else:
+        globalVars.desktop["desktop"] = sys.platform
 
 # from common/helpers.py
 
@@ -113,33 +80,69 @@
     return command
 
 def launch_file(kind, uri):
-    # kind = "url" ,"mail", "image", "dxf"
+    """
+    kind = "url" ,"mail", "image", "dxf", "wmf", "pdf",  video", 
+           "office-document", "office-presentation", "office-spreadsheet",
+           "html", "rtf", "txt", ""
+    Linux: xdg-open supports:
+        Xfce (exo-open "$1"),
+        Gnome (gvfs-open "$1", gnome-open "$1" with fallback to generic open),
+        KDE (kde-open "$1" with fallback to kfmclient exec "$1"),
+        Mate (gvfs-open "$1", mate-open $1),
+        LXDE (pcmanfm $1 with fallback to generic open),
+        Enlightenment (enlightenment_open $1),
+        Cinnamon (open_gnome3 $1, which is gvfs-open "$1" with fallback to generic open),
+        Cygwin (cygstart "$1"),
+        Darwin (open "$1").
+        
+
+    """
+    # TODO: test in Mac os X
+    # TODO: test in Windows
+    # TODO: configured apps in windows?
+    
+    if kind == "mail" and not uri.startswith("mailto:"):
+        uri = "mailto:" + uri
+    
     _desktop = globalVars.desktop["desktop"]
+    
     if _desktop == "windows":
         try:
             os.startfile(uri) # if pywin32 is installed we open
         except Exception:
             pass
     else:
-        if kind == 'mail' and not uri.startswith('mailto:'):
-            uri = 'mailto:' + uri
-        if _desktop == "gnome":
-            command = 'gnome-open'
-        elif _desktop == "kde":
-            command = 'kfmclient exec'
-        elif _desktop == "xfce":
-            command = 'exo-open'
+        # if app is configured in globarVars use it
+        if kind in ("url", "html") and globalVars.desktop["browser"] != "":
+            command = globalVars.desktop["browser"]
+        elif kind == "mail" and globalVars.desktop["mailapp"] != "":
+            command = globalVars.desktop["mailapp"]
+        elif kind == "image" and globalVars.desktop["imageapp"] != "":
+            command = globalVars.desktop["imageapp"]
+        elif kind == "wmf" and globalVars.desktop["wmfapp"] != "":
+            command = globalVars.desktop["wmfapp"]
+        elif kind == "dxf" and globalVars.desktop["cadapp"]  != "":
+            command = globalVars.desktop["cadapp"]
+        elif kind == "video" and globalVars.desktop["videoapp"]  != "":
+            command = globalVars.desktop["videoapp"]
+        elif kind in ("office-document", "office-presentation",
+                      "office-spreadsheet") and \
+             globalVars.desktop["officeapp"]  != "":
+            command = globalVars.desktop["officeapp"]
+        elif kind == "txt" and globalVars.desktop["txtapp"] != "":
+            command = globalVars.desktop["txtapp"]
+        elif kind == "rtf" and globalVars.desktop["rtfapp"] != "":
+            command = globalVars.desktop["rtfapp"]
+        # if no app is configured
+        elif _desktop == "macosx":
+            command = "open"
+        elif _desktop == "linux":
+            command = "xdg-open"
         else:
-            if kind == 'url':
-                command = globalVars.desktop["browser"]
-            elif kind == 'mail':
-                command = globalVars.desktop["mailapp"]
-            elif kind == 'image':
-                command = globalVars.desktop["imageapp"]
-            elif kind == 'dxf':
-                command = globalVars.desktop["cadapp"]
-            else:  # if no app is configured
-                return
+            # if no desktop is detected
+            # try xdg-open and cross your fingers 
+            command = "xdg-open"
+
         command = build_command(command, uri)
         try:
             exec_command(command)
--- a/Generic/utils.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Generic/utils.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File utils.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2013 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -22,6 +22,38 @@
 # Modules
 import re 
 import imghdr
+import os.path
+
+# add svg to imghdr
+def test_svg(h, f):
+    """SVG """
+    if  isinstance(f,file):
+        _pos = f.tell()
+        f.seek(0)
+        _h = f.read(32)
+        f.seek(-32, 2)
+        _l = f.read(32)
+        f.seek(_pos)
+    else:
+        _h = h
+        _l = h[-32:]
+    if "<?xml" in _h and "</svg>" in  _l:
+        return 'svg'
+imghdr.tests.append(test_svg)
+
+# add ico to imghdr
+def test_ico(h, f):
+    """ico image file"""
+    if h[:4] == "\x00\x00\x01\x00":
+        return 'ico'
+imghdr.tests.append(test_ico)
+
+# add wmf to imghdr
+def test_pdf(h, f):
+    """pdf file"""
+    if h[:4] == "%PDF":
+        return 'pdf'
+imghdr.tests.append(test_pdf)
 
 # add wmf to imghdr
 def test_wmf(h, f):
@@ -57,18 +89,19 @@
 imghdr.tests.append(test_dxf)
 
 
-def mapping(string, tuple):
+def mapping(string, tuple_strings):
     """mapping(string, tuple)
     
     string: a message string
-    tuple: a truple with string items
+    tuple_strings: a truple with string items
     Return the string replacing the $[n] words whith its corresponding value
     from the tuple.
     It is used because the gettext module can not #-#supotr#-# strings as:
         "Invalid type (%s) in record: %s" %(type, record)
     """
-    for _index in range(len(tuple)):
-        string = string.replace("$" + str(_index+1), str(tuple[_index]))
+    for _index in range(len(tuple_strings)):
+        string = string.replace("$" + str(_index+1), tuple_strings[_index])
+        #string = string.replace("$" + str(_index+1), str(tuple[_index]))
     return string
 
 def eliminate_duplicates(list):
@@ -111,10 +144,9 @@
     """
     _is_valid = True
     if not isinstance(code, str):
-        print "Not a string, code:", code, type(code)
+        print("Not a string, code: " + code + type(code) )
         return False, False
     if code == "":
-
         return False, False
     try:
         _unicode_code = unicode(code, "utf8",'replace')
@@ -123,28 +155,28 @@
         _unicode_code = unicode(_code_cp850, "cp850",'replace')
 
     except UnicodeError:
-        print "Unicode Error, code:", code
+        print ("Unicode Error, code: " +  code )
         return False, False
     if _code_utf8 != code:
-        print "Not in cp950, code:", code
+        print ("Not in cp950, code: " +  code )
         _is_valid = False
         if _code_utf8 == "":
             return False, False
         code = _code_utf8
     _code2 = re.sub("[\t \n\r~|\\\]","",code)
     if _code2 != code:
-        print "Control characters in code:", code
+        print("Control characters in code: " + code )
         if _code2 == "":
             return False, False
         _is_valid = False
         code = _code2
     if code[-1] == "#":
-        print "# in code:", code
+        print("# in code: " + code )
         _is_valid =  False
         while code[-1] == "#":
             code = code[:-1]
     if code == "":
-        print "Empty code"
+        print("Empty code")
         return False, False
     return _is_valid, code
 
@@ -154,20 +186,48 @@
     filename: the filename to test
     h: raw string, if h is not None the filename is ignored and h is assumed
     to contain the byte stream to test
+    
+    valid types:
+     "image", "wmf", "dxf", "pdf" , "video",
+     "office-document", "office-presentation", "office-spreadsheet",
+     "html", "rtf", "txt"
     """
+    _ext = os.path.splitext(filename)[1][1:].lower()
+    
+    _video_types = ["avi", "mp4", "m4p", "m4v2", "m4v","amv", "mpg", "m2v",
+                    "mp2", "mpe", "mpv", "mpeg", "ogg", "ogv", "webm", "mkv",
+                    "ogm", "flv", "f4v", "f4p", "f4a", "f4b", "vob", "drc",
+                    "mts", "m2ts", "mov", "qt", "wmv", "yuv", "rm", "rmvb",
+                    "asf", "svi", "3gp", "3g2", "mxf", "roq", "nsv"]
+    _document_types = ["doc", "docx", "odt"]
+    _spreadsheet_types = ["xls", "xlsx", "ods"]
+    _presentation_types = ["pps", "ppsx", "ppt", "pptx", "odp"]
+    _html_types = ["html", "xhtml"]
+    if _ext in _video_types:
+        return "video"
+    elif _ext in _document_types:
+        return "office-document"
+    elif _ext in _spreadsheet_types:
+        return "office-spreadsheet"
+    elif _ext in _presentation_types:
+        return "office-presentation"
+    elif _ext in _html_types:
+        return "html"
+    elif _ext == "rtf":
+        return "rtf"
+    elif _ext == "txt":
+        return "txt"
     _type = imghdr.what(filename, h)
-    _image_types = ["rgb", "gif", "pbm", "pgm", "ppm", "tiff", "rast", "xbm",
-                    "jpeg", "bmp", "png", "wmf"]
-    if _type in _image_types:
+    _image_types = ["rgb", "gif", "pbm", "pgm", "ppm" ,"tiff", "tif", "rast",
+                    "xbm", "jpeg", "jpg", "bmp", "png", "webp", "exr",
+                    "ico", "svg"]
+    if _type in _image_types and _ext in _image_types:
         return "image"
-    elif _type == "dxf":
+    elif _type == "wmf" and _ext == "wmf":
+        return "wmf"
+    elif _type == "dxf" and _ext == "dxf":
         return "dxf"
-##    _video_types = ["avi", "mpg", "mkv", "ogm"]
-##    elif _type in _video_types:
-##        return "video"
-##    elif _type == "pdf":
-##        return "pdf"
-##    elif _type == "ppt" or _type == "odp":
-##        return "presentation"
-    else:
-        return None
+
+    elif _type == "pdf" and _ext == "pdf":
+        return "pdf"
+    return None
--- a/Gtk/__init__.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Gtk/__init__.py	Thu May 02 16:31:17 2019 +0200
@@ -2,7 +2,7 @@
 ##
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
--- a/Gtk/gui.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Gtk/gui.py	Thu May 02 16:31:17 2019 +0200
@@ -2,7 +2,7 @@
 ## File gui.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -26,9 +26,9 @@
 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.
+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 the measure information of a record
@@ -42,44 +42,235 @@
 """
 # TODO: Config file
 
+# Modules
+
+# python 2/3 compatibility
+from __future__ import absolute_import, division, print_function, unicode_literals
+
 # Standar Modules
+import sys
 import os
 import time
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
+
+# gui
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+from gi.repository import GdkPixbuf
+from gi.repository import Gio
+from gi.repository import GLib
+from gi.repository import Gdk
+from gi.repository import Pango
+
 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 globalVars
 from Generic import openwith
 
 # Load default icon
-if os.path.exists(globalVars.getAppPath("ICON")):
-    icon = gtk.gdk.pixbuf_new_from_file(globalVars.getAppPath("ICON"))
-    gtk.window_set_default_icon_list(icon)
+_icons = [ "ICON16", "ICON32","ICON64","ICON128"]
+_pixbufIcons = []
+for _icon in _icons:
+    if os.path.exists(globalVars.getAppPath(_icon)):
+        _pixbufIcon = GdkPixbuf.Pixbuf.new_from_file(globalVars.getAppPath(_icon))
+        _pixbufIcons.append(_pixbufIcon)
+    else:
+        print(utils.mapping(_("The icon file does not exist. '$1'"),
+          (str(globalVars.getAppPath(_icon)),)) )
+if len(_pixbufIcons) > 0:
+    Gtk.Window.set_default_icon_list(_pixbufIcons)
+
 else:
-    print utils.mapping(_("The icon file does not exist. '$1'"),
-          (globalVars.getAppPath("ICON"),))
+    print(utils.mapping(_("The icon file does not exist. '$1'"),
+          (str(globalVars.getAppPath("ICON")),)) )
 
 # Autodetect desktop
 if globalVars.desktop["autodetect"]:
     openwith.autodetect_desktop()
-    print utils.mapping(_("pyArq-Presupuestos running on $1"),
-                        (globalVars.desktop["desktop"],))
-
-# Add MenutoolButton to Uimanager
-class MenuToolAction(gtk.Action):
-       __gtype_name__ = "MenuToolAction"
-
-gobject.type_register(MenuToolAction)
-MenuToolAction.set_tool_item_type(gtk.MenuToolButton)
+    print(utils.mapping(_("pyArq-Presupuestos running on $1"),
+                        (globalVars.desktop["desktop"],)))
+
+
+class App(Gtk.Application):
+    """gui.App:
+    
+    Description:
+        This is the Gtk application base class.
+    Constructor:
+        App()
+    Ancestry:
+    +-- Gtk.Application https://lazka.github.io/pgi-docs/Gtk-3.0/classes/Application.html
+      +-- App
+    Atributes:
+    Methods:
+        do_activate
+        do_startup
+        do_open
+    """
+
+    def __init__(self, *args, **kwargs):
+        """__init__()
+        
+        Sets the application id and application_name.
+        """
+        self.filesToOpen = []
+        self._application_id = "es.obraencurso.pyarq.presupuestos"
+        super(App, self).__init__(application_id=self._application_id,
+                                  flags=Gio.ApplicationFlags.HANDLES_OPEN,
+                                  **kwargs)
+        GLib.set_prgname(self._application_id)
+
+    def do_open(self, files, n_files, hint):
+        """do_open(files, n_files, hint)
+        
+        Set the filename list to open.
+        """
+        self.filesToOpen = files
+        self.activate()
+        self.filesToOpen = []
+        return 0
+
+    def do_activate(self):
+        """do_activate()
+        
+        Shows new appplication windows.
+        """
+        _mainWindow = MainWindow(self, self.filesToOpen )
+        _mainWindow.window.present_with_time(GLib.get_monotonic_time() / 1000)
+
+    def do_startup(self):
+        """do_startup()
+        
+        Sets the app actions.
+        """
+        Gtk.Application.do_startup(self)
+        # App Actions
+        action = Gio.SimpleAction.new("newWindow", None)
+        action.connect("activate", self._on_newWindow)
+        self.add_action(action)
+
+        action = Gio.SimpleAction.new("acell_newWindow", None)
+        action.connect("activate", self._on_control_n)
+        self.add_action(action)
+
+        action = Gio.SimpleAction.new("about", None)
+        action.connect("activate", self._on_about)
+        self.add_action(action)
+
+        action = Gio.SimpleAction.new("quit", None)
+        action.connect("activate", self._on_quit)
+        self.add_action(action)
+        
+        action = Gio.SimpleAction.new("acell_quit", None)
+        action.connect("activate", self._on_control_q)
+        self.add_action(action)
+        
+        # App menu
+        _app_menu = Gio.Menu()
+        _section_window = Gio.Menu()
+        _section_window.append(_("_New window"), "app.newWindow")
+        _section_window.append(_("_Close window"), "win.CloseWindow")
+        _app_menu.append_section(None,_section_window)
+        self.set_accels_for_action('win.acell_close', ["<Primary>x"])
+        self.set_accels_for_action('app.acell_newWindow', ["<Primary>n"])
+        _section_general = Gio.Menu()
+        _section_general.append(_("About") + " " + globalVars.name, "app.about")
+        _app_menu.append_section(None,_section_general)
+        _section_quit = Gio.Menu()
+        _section_quit.append(_("_Quit application"), "app.quit")
+        self.set_accels_for_action('app.acell_quit', ["<Primary>q"])
+        _app_menu.append_section(None,_section_quit)
+        self.set_app_menu(_app_menu)
+        # TODO : from gui config
+        win_menu = False
+        # Win Menu
+        if win_menu:
+            _win_menu = Gio.Menu()
+            _win_submenu_file = Gio.Menu.new()
+            _import_fiebdc = Gio.MenuItem.new(_("_Import Fiebdc"), "win.ImportFiebdc")
+            _import_fiebdc.set_icon(Gio.Icon.new_for_string("document-open"))
+            _win_submenu_file.append_item(_import_fiebdc)
+        
+            _close_tab = Gio.MenuItem.new(_("_Close tab"), "win.CloseTab")
+            _close_tab.set_icon(Gio.Icon.new_for_string("window-close"))
+            _win_submenu_file.append_item(_close_tab)
+        
+            _win_menu.append_submenu(_("_File"), _win_submenu_file)
+            _win_submenu_go = Gio.Menu.new()
+            _back = Gio.MenuItem.new(_("_Back"), "win.GoPrevious")
+            _back.set_icon(Gio.Icon.new_for_string("go-previous"))
+            _win_submenu_go.append_item(_back)
+            _forward = Gio.MenuItem.new(_("_Forward"), "win.GoPosterior")
+            _forward.set_icon(Gio.Icon.new_for_string("go-next"))
+            _win_submenu_go.append_item(_forward)
+            _up = Gio.MenuItem.new(_("_Up Item"), "win.GoUp")
+            _up.set_icon(Gio.Icon.new_for_string("go-up"))
+            _win_submenu_go.append_item(_up)
+            _root = Gio.MenuItem.new(_("_Root"), "win.GoToRoot")
+            _root.set_icon(Gio.Icon.new_for_string("go-top"))
+            _win_submenu_go.append_item(_root)
+            _win_menu.append_submenu(_("_Go"), _win_submenu_go)
+            self.set_menubar(_win_menu)
+
+    def _on_newWindow(self, action, param):
+        """on_newWindow(action, param)
+        
+        Shows new appplication windows.
+        """
+        _mainWindow = MainWindow(self, [])
+        _mainWindow.window.present_with_time(GLib.get_monotonic_time() / 1000)
+
+    def _on_about(self, action, param):
+        """_on_about(action, param)
+        
+        Shows About dialog.
+        """
+        _aboutDialog = Gtk.AboutDialog(modal=False)
+        _aboutDialog.set_program_name(globalVars.name)
+        _aboutDialog.set_copyright(base.copyright)
+        _aboutDialog.set_authors(base.authors)
+        _aboutDialog.set_version(globalVars.version + globalVars.changeset)
+        _aboutDialog.set_website(base.website)
+        _aboutDialog.set_website_label(base.website_label)
+        _aboutDialog.set_license_type(Gtk.License(3))
+        _aboutDialog.set_comments(base.comments)
+        _aboutDialog.connect("response", self._on_close_aboutdialog)
+        _aboutDialog.present_with_time(GLib.get_monotonic_time() / 1000)
+
+    def _on_close_aboutdialog(self, action, parameter):
+        """on_close_aboutdialog(action, param)
+        
+        Close About dialog.
+        """
+        action.destroy()
+
+    def _on_control_q(self, action, param):
+        """on_control_q(action, param)
+        
+        Quit app.
+        """
+        print("Control q -> Quit app")
+        self.quit()
+
+    def _on_quit(self, action, param):
+        """_on_quit(action, param)
+        
+        Quit app.
+        """
+        self.quit()
+
+    def _on_control_n(self, action, param):
+        """on_control_n(action, param)
+        
+        Shows new appplication windows.
+        """
+        print("Control n -> New window")
+        self._on_newWindow(action, param)
 
 
 class MainWindow(object):
@@ -89,11 +280,12 @@
         Creates and shows the main window.
         This is the interface base class.
     Constructor:
-        gui.MainWindow()
+        MainWindow(app, files)
     Ancestry:
     +-- object
       +-- MainWindow
     Atributes:
+        self.window: Gtk.ApplicationWindow object
     Methods:
         changeHistorySignal
         changeActiveSignal
@@ -104,138 +296,178 @@
     # TODO:* Can choose open budget in new window
     # 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">
-      </menu>
-      <menu action="Go">
-        <menuitem action="GoPrevious"/>
-        <menuitem action="GoPosterior"/>
-        <menuitem action="GoUp"/>
-        <menuitem action="GoToRoot"/>
-      </menu>
-    </menubar>
-    <toolbar name="ToolBar">
-      <toolitem action="ImportFiebdc"/>
-      <toolitem action="Close"/>
-      <separator name="sep1"/>
-      <toolitem action="GoPrevMenu"/>
-      <toolitem action="GoPostMenu"/>
-      <toolitem action="GoUp"/>
-      <toolitem action="GoToRoot"/>
-    </toolbar>
-    </ui>'''
-
-    #<menu action="Test">
-    #  <menuitem action="ImportFiebdcPriceDatabase"/>
-    #  <menuitem action="OpenPriceDatabase"/>
-    #</menu>
-
-    def __init__(self):
-        """__init__()
+
+    def __init__(self, app, files):
+        """__init__(app, files)
         
         Initialize the atributes self.__page_list without data.
         Creates the widgets "window" and "__notebook".
         
-        self.__window: gtk.Window object
-        self.__uimanager: gtk.UIManager object
+        app: Gtk.Application instance
+        files: Gio.file list from command line
+        
+        self.window: Gtk.ApplicationWindow object
         self.__page_list: List of pages ("Page" object)
-        self.__notebook: Notebook widget ("gtk.Notebook" object)
+        self.__notebook: Notebook widget ("Gtk.Notebook" object)
         self.__general_action_group: "General" action group
         self.__navigation_action_group: "Navigation" action group
+        self.__navigation_is_enabled: True/False
+        self.__goBack_button
         """
         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)
+        self.window = Gtk.ApplicationWindow(application=app)
+        self.window.set_default_size(771, 570)
+        self.window.set_title("Presupuestos")
+        self.window.set_border_width(5)
+        self.window.connect("delete_event", self._delete_event)
+        # HeaderBar
+        _hb = Gtk.HeaderBar()
+        _hb.set_show_close_button(True)
+        _hb.props.title = "Presupuestos"
+        self.window.set_titlebar(_hb)
+        _hb.show()
+        # Actions
+        # General Actions
+        self.__general_action_group = Gio.SimpleActionGroup.new()
+        # CloseWindow Action
+        _action = Gio.SimpleAction.new("CloseWindow", None)
+        _action.connect("activate", self._menuitemClose)
+        self.window.add_action(_action)
+        self.__general_action_group.insert(_action)
+        # CloseWindow from acell Action
+        _action = Gio.SimpleAction.new("acell_close", None)
+        _action.connect("activate", self._on_control_x)
+        self.window.add_action(_action)
+        self.__general_action_group.insert(_action)
+        # ImportFiebdc Action
+        _action = Gio.SimpleAction.new("ImportFiebdc", None)
+        _action.connect("activate", self._on_menuitemImportFiebdc)
+        self.window.add_action(_action)
+        self.__general_action_group.insert(_action)
+        # CloseTab action
+        self.__closeTab_action = Gio.SimpleAction.new("CloseTab", None)
+        self.__closeTab_action.connect("activate", self._on_CloseTab)
+        self.window.add_action(self.__closeTab_action)
+        self.__general_action_group.insert(self.__closeTab_action)
+        # Navigation Actions
+        self.__navigation_is_enabled = False
+        self.__navigation_action_group = Gio.SimpleActionGroup.new()
+        # Go Previous action
+        self.__GoPrevious_action = Gio.SimpleAction.new("GoPrevious", None)
+        self.__GoPrevious_action.connect("activate", self._menuitemGoPrevious)
+        self.window.add_action(self.__GoPrevious_action)
+        self.__general_action_group.insert(self.__GoPrevious_action)
+        self.__GoPrevious_action.set_enabled(False)
+        # Go posterior action
+        self.__GoPosterior_action = Gio.SimpleAction.new("GoPosterior", None)
+        self.__GoPosterior_action.connect("activate", self._menuitemGoPosterior)
+        self.window.add_action(self.__GoPosterior_action)
+        self.__general_action_group.insert(self.__GoPosterior_action)
+        self.__GoPosterior_action.set_enabled(False)
+        # Go Up action
+        self.__GoUp_action = Gio.SimpleAction.new("GoUp", None)
+        self.__GoUp_action.connect("activate", self._menuitemGoUp)
+        self.window.add_action(self.__GoUp_action)
+        self.__general_action_group.insert(self.__GoUp_action)
+        self.__GoUp_action.set_enabled(False)
+        # Go to Root action
+        self.__GoToRoot_action = Gio.SimpleAction.new("GoToRoot", None)
+        self.__GoToRoot_action.connect("activate", self._menuitemGoToRoot)
+        self.window.add_action(self.__GoToRoot_action)
+        self.__general_action_group.insert(self.__GoToRoot_action)
+        self.__GoToRoot_action.set_enabled(False)
+        # Vertical Grid
+        _vbox1 = Gtk.Grid()
+        _vbox1.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        self.window.add(_vbox1)
         _vbox1.show()
-        #Uimanager
-        self.__uimanager = gtk.UIManager()
-        _accelgroup = self.__uimanager.get_accel_group()
-        self.__window.add_accel_group(_accelgroup)
-        self.__general_action_group = gtk.ActionGroup("General")
-        self.__general_action_group.add_actions(
-            [("File", None, _("_File"), None),
-             ("ImportFiebdc", gtk.STOCK_OPEN, _('_Import Fiebdc'), "",
-                _('Import FIEBDC'), self._menuitemImportFiebdc),
-             ("Close", gtk.STOCK_CLOSE, _("_Close"), None, _('Close'),
-                self._menuitemClose),
-             ("View", None, _("_View")),
-             ("Go", None, _("_Go")),
-             ("Test", None, _("_Test")),
-             #('ImportFiebdcPriceDatabase', gtk.STOCK_OPEN,
-             #   _("Import Fiebdc _price database"), "", _("Import database"),
-             #   self._menuitemImportPriceDatabase ),
-             #("OpenPriceDatabase", gtk.STOCK_OPEN, _('_Open price database'),
-             #   "", _('Open Database'), self._menuitemOpenPriceDatabase),
-            ])
-        self.__navigation_action_group = gtk.ActionGroup("Navigation")
-        self.__navigation_action_group.add_actions(
-            [("Go", None, _("_Go")),
-             ("GoPrevious", gtk.STOCK_GO_BACK, _("_Back"),"",
-                _("Go to the previous visited item"),
-                  self._menuitemGoPrevious),
-             ("GoPosterior", gtk.STOCK_GO_FORWARD, _("_Forward"),"",
-                _("Go to the next visited item"), self._menuitemGoPosterior),
-             ("GoUp", gtk.STOCK_GO_UP, _("_Up Item"),"",
-                _("Go up item"), self._menuitemGoUp),
-             ("GoToRoot", gtk.STOCK_GOTO_TOP, _("_Root"),"",
-                _("Go to root"), self._menuitemGoToRoot),
-            ])
-        self.__navigation_action_group.add_action(
-            MenuToolAction("GoPrevMenu", None ,
-                           _("Go to the previous visited item"),
-                           gtk.STOCK_GO_BACK))
-        self.__navigation_action_group.add_action(
-             MenuToolAction("GoPostMenu", None ,
-                           _("Go to the next visited item"),
-                           gtk.STOCK_GO_FORWARD))
-        self.__navigation_action_group.set_sensitive(False)
-        self.__navigation_action_group.get_action("GoPostMenu").set_sensitive(
-            False)
-        self.__navigation_action_group.get_action("GoPrevMenu").set_sensitive(
-            False)
-        self.__uimanager.insert_action_group(self.__general_action_group, 0)
-        self.__uimanager.insert_action_group(self.__navigation_action_group, 1)
-        self.__uimanager.add_ui_from_string(self.__ui)
-        _menu_bar = self.__uimanager.get_widget("/MenuBar")
-        _vbox1.pack_start(_menu_bar, False, False, 0)
-        _toolbar = self.__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)
-        # menuToolButton go prev
-        _go_prev_button = self.__uimanager.get_widget(
-            "/ToolBar/GoPrevMenu")
-        _go_prev_button.set_arrow_tooltip_text(_("Back history"))
-        _go_prev_button.connect('clicked', self._menuitemGoPrevious)
-        # menuToolButton go pos
-        _go_post_button = self.__uimanager.get_widget(
-            "/ToolBar/GoPostMenu")
-        _go_post_button.set_arrow_tooltip_text(_("Forward history"))
-        _go_post_button.connect('clicked', self._menuitemGoPosterior)
+        # Toolbar
+        _toolbar = Gtk.Toolbar()
+        _toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
+        # Import Fiebdc
+        _gtk_image = Gtk.Image.new_from_icon_name("document-open",1)
+        _gtk_image.show()
+        _ImportFiebdc_button = Gtk.ToolButton.new(_gtk_image , _("Import Fiebdc"))
+        _ImportFiebdc_button.set_tooltip_text(_("Import Fiebdc"))
+        _ImportFiebdc_button.set_is_important(False)        # label not shown
+        _toolbar.insert(_ImportFiebdc_button, -1)
+        _ImportFiebdc_button.show()
+        _ImportFiebdc_button.set_action_name("win.ImportFiebdc")
+        # Close tab
+        _gtk_image = Gtk.Image.new_from_icon_name("window-close",1)
+        _gtk_image.show()
+        _closeTabButton = Gtk.ToolButton.new(_gtk_image , _("_Close tab"))
+        _closeTabButton.set_tooltip_text(_("Close tab"))
+        _closeTabButton.set_is_important(False)        # label not shown
+        _toolbar.insert(_closeTabButton, -1)
+        _closeTabButton.show()
+        _closeTabButton.set_action_name("win.CloseTab")
+        # Separator item
+        _separator = Gtk.SeparatorToolItem()
+        _separator.show()
+        _toolbar.insert(_separator, -1)
+        # Go Back
+        _gtk_image = Gtk.Image.new_from_icon_name("go-previous",1)
+        _gtk_image.show()
+        self.__goBack_button = Gtk.MenuToolButton.new(_gtk_image ,_("Back"))
+        self.__goBack_button.set_tooltip_text(_("Back"))
+        self.__goBack_button.set_is_important(False)        # label not shown
+        _toolbar.insert(self.__goBack_button, -1)
+        self.__goBack_button.show()
+        self.__goBack_button.set_action_name("win.GoPrevious")
+        # Go Forward
+        _gtk_image = Gtk.Image.new_from_icon_name("go-next",1)
+        _gtk_image.show()
+        self.__goForward_button = Gtk.MenuToolButton.new(_gtk_image ,_("Forward"))
+        self.__goForward_button.set_tooltip_text(_("Forward"))
+        self.__goForward_button.set_is_important(False)        # label not shown
+        _toolbar.insert(self.__goForward_button, -1)
+        self.__goForward_button.show()
+        self.__goForward_button.set_action_name("win.GoPosterior")
+         # Go Up Item
+        _gtk_image = Gtk.Image.new_from_icon_name("go-up",1)
+        _gtk_image.show()
+        _goUP_button = Gtk.ToolButton.new(_gtk_image ,_("Up Item"))
+        _goUP_button.set_tooltip_text(_("Up Item"))
+        _goUP_button.set_is_important(False)        # label not shown
+        _toolbar.insert(_goUP_button, -1)
+        _goUP_button.show()
+        _goUP_button.set_action_name("win.GoUp")
+         # Go Root Item
+        _gtk_image = Gtk.Image.new_from_icon_name("go-top",1)
+        _gtk_image.show()
+        _goRoot_button = Gtk.ToolButton.new(_gtk_image ,_("Root"))
+        _goRoot_button.set_tooltip_text(_("Root"))
+        _goRoot_button.set_is_important(False)        # label not shown
+        _toolbar.insert(_goRoot_button, -1)
+        _goRoot_button.show()
+        _goRoot_button.set_action_name("win.GoToRoot")
+        # Pack and show
+        _toolbar.set_hexpand(True) # with extra horizontal space
+        _toolbar.show()
+        _vbox1.add(_toolbar)
         # Notebook
-        self.__notebook = gtk.Notebook()
-        _vbox1.pack_start(self.__notebook, True, True, 0)
-        self.__notebook.set_tab_pos(gtk.POS_TOP)
+        self.__notebook = Gtk.Notebook()
+        _vbox1.add(self.__notebook)
+        self.__notebook.set_tab_pos(Gtk.PositionType(2)) # Up
+        self.__notebook.set_property("expand", True) # widget expand all space
         self.__notebook.set_show_tabs(True)
         self.__notebook.set_show_border(True)
         self.__notebook.set_scrollable(True)
         self.__notebook.connect("switch-page", self._switch_page)
         self.__notebook.show()
         self._main()
-        #TODO: create budget object in mainwindow?
+        if len(files) > 0:
+            for file in files:
+                _budget = base.Budget()
+                _budget_file = fiebdc.Read()
+                _read_method = _budget_file.readFile
+                _filename = file.get_path()
+                _filetype = "budget"
+                _exit_method = _budget_file.cancel
+                _file_window = FileSelectionWindow(self,
+                    _read_method, _budget, _filename, _exit_method, _filetype)
 
     def changeHistorySignal(self):
         """changeHistorySignal()
@@ -260,78 +492,84 @@
         
         page_num: page number in notebook
         
-        Check and if necessary update the sensitive state of the navigation
+        Check and if necessary update the enabled state of the navigation
         buttons.
         """
         _page = self.__page_list[page_num]
         if isinstance(_page, Page) and \
-           self.__navigation_action_group.get_sensitive():
+           self.__navigation_is_enabled:
             # GoToRoot and GoUp actions
-            _goto_root = self.__navigation_action_group.get_action("GoToRoot")
-            _go_up = self.__navigation_action_group.get_action("GoUp")
+            _goto_root = self.__GoToRoot_action
+            _go_up = self.__GoUp_action
             if len(_page.activePathRecord) == 1 and \
-               _goto_root.get_sensitive():
-                _goto_root.set_sensitive(False)
-                _go_up.set_sensitive(False)
+               _goto_root.get_enabled():
+                _goto_root.set_enabled(False)
+                _go_up.set_enabled(False)
             elif len(_page.activePathRecord) != 1 and \
-               not _goto_root.get_sensitive():
-                _goto_root.set_sensitive(True)
-                _go_up.set_sensitive(True)
+               not _goto_root.get_enabled():
+                _goto_root.set_enabled(True)
+                _go_up.set_enabled(True)
             # GoPrevMenu action
-            _go_Previous = self.__navigation_action_group.get_action(
-                "GoPrevious")
-            _go_prev = self.__navigation_action_group.get_action("GoPrevMenu")
+            _go_Previous = self.__GoPrevious_action
+            _go_prev = self.__GoPrevious_action
             if _page.previousPathRecord is None:
-                if _go_prev.get_sensitive():
-                    _go_prev.set_sensitive(False)
-                    _go_Previous .set_sensitive(False)
+                if _go_prev.get_enabled():
+                    _go_prev.set_enabled(False)
+                    self.__goBack_button.props.menu = None
             else:
-                if not _go_prev.get_sensitive():
-                    _go_prev.set_sensitive(True)
-                    _go_Previous.set_sensitive(True)
+                if not _go_prev.get_enabled():
+                    _go_prev.set_enabled(True)
+                    self.__goBack_button.set_menu(_page.back_menu)
             # GoPostMenu action
-            _go_Posterior = self.__navigation_action_group.get_action(
-                "GoPosterior")
-            _go_post = self.__navigation_action_group.get_action("GoPostMenu")
+            _go_Posterior = self.__GoPosterior_action
             if _page.posteriorPathRecord is None:
-                if _go_post.get_sensitive():
-                    _go_post.set_sensitive(False)
-                    _go_Posterior.set_sensitive(False)
+                if _go_Posterior.get_enabled():
+                    _go_Posterior.set_enabled(False)
+                    self.__goForward_button.props.menu = None
             else:
-                if not _go_post.get_sensitive():
-                    _go_post.set_sensitive(True)
-                    _go_Posterior.set_sensitive(True)
+                if not _go_Posterior.get_enabled():
+                    _go_Posterior.set_enabled(True)
+                    self.__goForward_button.set_menu(_page.forward_menu)
+
+    def _disable_navigation(self):
+        self.__GoPrevious_action.set_enabled(False)
+        self.__GoPosterior_action.set_enabled(False)
+        self.__GoUp_action.set_enabled(False)
+        self.__GoToRoot_action.set_enabled(False)
+        self.__navigation_is_enabled = False
 
     def _switch_page(self, notebook, page, page_num,):
         """_switch_page(notebook, page, page_num)
          
         Method connected to the "switch-page" signal of the notebook widget
         
-        It changes the sensitive state of the navigation action group
-        """
+        It shows/hides closeTabButton
+        and changes the sensitive state of the navigation action group
+        """
+        for _page_num, _page in enumerate(self.__page_list):
+            if _page_num == page_num:
+                _page.closeTabButton.show()
+            else:
+                _page.closeTabButton.hide()
         _page = self.__page_list[page_num]
+        
         if isinstance(_page, EmptyPage) and \
-           self.__navigation_action_group.get_sensitive():
-            self.__navigation_action_group.set_sensitive(False)
+            self.__navigation_is_enabled:
+            self._disable_navigation()
         elif isinstance(_page, Page):
-            if not self.__navigation_action_group.get_sensitive():
-                self.__navigation_action_group.set_sensitive(True)
-            self._checkButtonsSensitive(page_num)
-            _go_prev = self.__uimanager.get_widget("/ToolBar/GoPrevMenu")
-            _go_prev.set_menu(_page.back_menu)
-            _go_post = self.__uimanager.get_widget("/ToolBar/GoPostMenu")
-            _go_post.set_menu(_page.forward_menu)
+            if not self.__navigation_is_enabled:
+                self.__navigation_is_enabled = True
+                self._checkButtonsSensitive(page_num)
 
     def _main(self):
         """main()
         
-        Shows window and starts the GTK+ event processing loop.
-        """
-        self.__window.show()
-        gtk.main()
+        Shows window.
+        """
+        self.window.show()
 
     def appendEmptyPage(self, emptyPage):
-        """appendEmptyPage(widget, label)
+        """appendEmptyPage(emptyPage)
         
         Append a empty page to the notebook.
         """
@@ -349,18 +587,19 @@
         _page_num = self.__notebook.page_num(empty_page.widget)
         self.__page_list[_page_num] = page
         if self.__notebook.get_current_page() == _page_num:
-            _go_prev = self.__uimanager.get_widget("/ToolBar/GoPrevMenu")
-            _go_prev.set_menu(page.back_menu)
-            _go_post = self.__uimanager.get_widget("/ToolBar/GoPostMenu")
-            _go_post.set_menu(page.forward_menu)
-            if not self.__navigation_action_group.get_sensitive():
-                self.__navigation_action_group.set_sensitive(True)
+            if not self.__navigation_is_enabled:
+                self.__navigation_is_enabled = True
                 self._checkButtonsSensitive(_page_num)
 
-    def _menuitemImportFiebdc(self, widget):
-        """_menuitemImportFiebdc(widget)
-        
-        widget: the widget where the event is emitted from
+    def _on_control_x(self, action, param):
+        print("Control x -> Close window")
+        self.window.destroy()
+
+    def _on_menuitemImportFiebdc(self, action, parameter):
+        """_on_menuitemImportFiebdc(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
         Callback to open a budget file.
         
         Creates and shows a file selection window to open a budget file.
@@ -368,61 +607,33 @@
         _budget = base.Budget()
         _budget_file = fiebdc.Read()
         _read_method = _budget_file.readFile
-        _filename = "file"
+        _filename = ""
         _filetype = "budget"
         _exit_method = _budget_file.cancel
-        _file_window = importFiebdc.FileSelectionWindow(self,
+        _file_window = FileSelectionWindow(self,
             _read_method, _budget, _filename, _exit_method, _filetype)
 
-    #def _menuitemImportPriceDatabase(self, widget):
-    #    """_menuitemImportPriceDatabase(widget)
-    #    
-    #    widget: the widget where the event is emitted from
-    #    Callback to open a price database file.
-    #    
-    #    Creates and shows a file selection window to open a price database
-    #    file.
-    #    """
-    #    _budget = base.Budget()
-    #    _budget_file = fiebdc.Read()
-    #    _read_method = _budget_file.readFile
-    #    _filename = "file"
-    #    _filetype = "database"
-    #    _exit_method = _budget_file.cancel
-    #    _file_window = importFiebdc.FileSelectionWindow(self,
-    #        _read_method, _budget, _filename, _exit_method, _filetype)
-
-    #def _menuitemOpenPriceDatabase(self, widget):
-    #    """_menuitemOpenPriceDatabase(widget)
-    #    
-    #    widget: the widget where the event is emitted from
-    #    Callback to open a price database from a durus file.
-    #    
-    #    Creates and shows a file selection window to open a durus database
-    #    """
-    #    _budget = None
-    #    _budget_file = durusdatabase.Read()
-    #    _read_method = _budget_file.readFile
-    #    _filename = "file"
-    #    _filetype = "durus"
-    #    _exit_method = _budget_file.cancel
-    #    _file_window = importFiebdc.FileSelectionWindow(self,
-    #        _read_method, _budget, _filename, _exit_method, _filetype)
-
-    def _menuitemClose(self, widget):
-        """_menuitemClose(widget)
-        
-        widget: the widget where the event is emitted from
-        
-        Callback to close a budget file.
+    def _menuitemClose(self, action, parameter):
+        """_menuitemClose(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
+        
+        Callback to close the main window.
+        """
+        self.window.destroy()
+
+    def _on_CloseTab(self, action, parameter):
+        """_on_CloseTab(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
+        
+        Callback to close tab.
         """
         _page_num = self.__notebook.get_current_page()
         if _page_num != -1:
             _page = self.__page_list[_page_num]
-            #if isinstance(_page, EmptyPage) and _page.filetype == "durus":
-            #    print _("Cancel reading Durus database has not been "
-            #            "implemented.")
-            #else:
             _page.close()
 
     def closePage(self, page):
@@ -439,15 +650,15 @@
             page.clear()
             self.__notebook.remove_page(_page_num)
             if len(self.__page_list) == 0:
-                self.__navigation_action_group.set_sensitive(False)
+                self._disable_navigation()
         else:
-            raise IndexError, _("The page is not in the page list")
-
-
-    def _menuitemGoToRoot(self, widget):
-        """_menuitemGoToRoot(widget)
-        
-        widget: the widget where the event is emitted from
+            raise IndexError( _("The page is not in the page list") )
+
+    def _menuitemGoToRoot(self, action, parameter):
+        """_menuitemGoToRoot(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
         
         Callback to go to root record.
         """
@@ -456,13 +667,14 @@
             return
         _page = self.__page_list[_page_num]
         if isinstance(_page, Page):
-            #not loading budget
+            # not loading budget
             _page.propagateMessageFrom("change_active", (-1,), (0,))
 
-    def _menuitemGoUp(self, widget):
-        """_menuitemGoUp(widget)
-        
-        widget: the widget where the event is emitted from
+    def _menuitemGoUp(self, action, parameter):
+        """_menuitemGoUp(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
         
         Callback to go to up record.
         """
@@ -470,7 +682,7 @@
         if _page_num != -1:
             _page = self.__page_list[_page_num]
             if isinstance(_page, Page):
-                #not loading budget
+                # not loading budget
                 _active_path = _page.activePathRecord
                 if len(_active_path) > 1:
                     _budget = _page.budget
@@ -479,10 +691,11 @@
                         _page.propagateMessageFrom("change_active", (-1,),
                                                    _up_path)
 
-    def _menuitemGoPrevious(self, widget):
-        """_menuitemGoPrevious(widget)
-        
-        widget: the widget where the event is emitted from
+    def _menuitemGoPrevious(self, action, parameter):
+        """_menuitemGoPrevious(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
         
         Callback to go to previous record.
         """
@@ -490,7 +703,7 @@
         if _page_num != -1:
             _page = self.__page_list[_page_num]
             if isinstance(_page, Page):
-                #not loading budget
+                # not loading budget
                 _previous_path = _page.previousPathRecord
                 if _previous_path is not None:
                     _budget = _page.budget
@@ -498,10 +711,11 @@
                         _page.propagateMessageFrom("change_active", (-1,),
                                                    _previous_path)
 
-    def _menuitemGoPosterior(self, widget):
-        """_menuitemPosterior(widget)
-        
-        widget: the widget where the event is emitted from
+    def _menuitemGoPosterior(self, action, parameter):
+        """_menuitemPosterior(action, parameter)
+        
+        action: the action  where the event is emitted from
+        parameter: None
         
         Callback to go to posterior record.
         """
@@ -509,7 +723,7 @@
         if _page_num != -1:
             _page = self.__page_list[_page_num]
             if isinstance(_page, Page):
-                #not loading budget
+                # not loading budget
                 _posterior_path = _page.posteriorPathRecord
                 if _posterior_path is not None:
                     _budget = _page.budget
@@ -521,7 +735,7 @@
         """_delete_event(widget, event)
         
         widget: the widget where the event is emitted from
-        event: the "gtk.gdk.Event"
+        event: the "Gdk.Event"
         
         Method connected to "delete_event" signal of main window widget
         This signal is emitted when a user press the close titlebar button.
@@ -531,18 +745,97 @@
             _page.clear()
         return False # -> destroy
 
-    def _destroy(self, widget):
-        """_destroy(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()
+
+class FileSelectionWindow(object):
+    """gui.FileSelectionWindow:
+    
+    Description:
+        Class to show the selection file window
+    Constructor:
+        FileSelectionWindow(mainWindow, readFileMethod, budget,
+            filename, cancelMethod, filetype)
+    Ancestry:
+    +-- object
+      +-- FileSelectionWindow
+    Atributes:
+        No public Atributes
+    Methods:
+        No public Methods
+    """
+
+    def __init__(self, mainWindow, readFileMethod, budget, filename,
+                 cancelMethod, filetype):
+        """__init__(mainWindow, readFileMethod, budget,
+                    filename, cancelMethod, filetype)
+        
+        mainWindow: MainWindow object
+        readFileMethod: Method to read the selected file
+        budget: base.Budget object
+        filename: "file"
+        cancelMethod: Method to cancel the read method
+        fileytpe: "budget" or "database".
+        Sets the init atributes, creates the file selection window
+        Connects the events:
+            * clicked ok button: _openFile
+            * clicked cancel button: destroy window
+            * destroy event: _destroy
+        """
+        # TODO: Add file filter
+        self.__mainWindow = mainWindow
+        self.__readFileMethod = readFileMethod
+        self.__budget = budget
+        self.__filetype = filetype
+        self.__cancelMethod = cancelMethod
+        self.__file = None
+        self.__filename = filename
+        if self.__filename == "":
+            self.__dialog = Gtk.FileChooserNative.new(_("Open File"),
+                mainWindow.window, Gtk.FileChooserAction.OPEN, _("Open File"),
+                _("Cancel") )
+            self.__dialog.set_current_folder(globalVars.getHomePath("BUDGET"))
+            _response = self.__dialog.run()
+            if _response in [ Gtk.ResponseType.OK, Gtk.ResponseType.ACCEPT,
+                              Gtk.ResponseType.YES, Gtk.ResponseType.APPLY]:
+                self._openFile(self.__dialog.get_filename())
+            elif _response == Gtk.ResponseType.CANCEL:
+                self.__dialog.destroy()
+        else:
+            self.__dialog = None
+            self._openFile(self.__filename)
+
+    def _launchProgressWindow(self, file):
+        """_launchProgressWindow(file)
+        
+        Launch the progress window
+        """
+        self.__filename = file
+        _emptyPage = EmptyPage(self.__mainWindow, self.__readFileMethod,
+                               self.__budget, self.__filename,
+                               self.__cancelMethod, self.__filetype)
+        self.__mainWindow.appendEmptyPage(_emptyPage)
+        _emptyPage.run()
+
+    def _openFile(self, filename):
+        """_openFile(filename)
+        
+        filename: the filename to open
+        If the selected file has a bc3 extension 
+        _launchProgressWindow is called
+        """
+        _file = filename
+        if sys.getfilesystemencoding():
+            _file = _file.decode(sys.getfilesystemencoding())
+        self.__file = _file
+        _filename = os.path.basename(self.__file)
+        _filename_ext = _filename.split(".")[-1]
+        if (self.__filetype == "budget" or self.__filetype == "database") and \
+            _filename_ext != "bc3" and _filename_ext != "BC3":
+            print(_("The file must have 'bc3' extension") )
+        else:
+            if self.__dialog is not None:
+                self.__dialog.destroy()
+            # TODO: the file exits? is it not binary?, can it be readed?
+            self._launchProgressWindow(self.__file)
 
 
 class EmptyPage(object):
@@ -552,21 +845,22 @@
     It creates and shows a page in the notebook while a budget is loaded.
     The page show the pyarq logo, loading time and a progress bar.
     Constructor:
-        gui.EmptyPage(mainWindow, readFileMethod, budget, filename,
+        EmptyPage(mainWindow, readFileMethod, budget, filename,
                  cancelMethod, filetype):
-            mainWindow: gui.Mainwindow object
+            mainWindow: Mainwindow object
             readFileMethod: Method to read the selected file
             budget: base.Budget object
             filename: "file"
             cancelMethod: Method to cancel the read method
-            filetype: "budget", "database" or "durus"
+            filetype: "budget", "database"
     Ancestry:
     +-- object
       +-- EmptyPage
     Atributes:
         widget: Read. Main widget showed in the pane
         title: Read. Page Title
-        filetype: Read. budget, basedata or durus
+        filetype: Read. budget or basedata
+        endSuccessfully: Read-Write. False/True
     Methods:
         run
         readFile_progress
@@ -575,8 +869,10 @@
         readFile_end
         readFile_cancel
         stopLoading
+        updateGui
         threadFinishedSignal
         threadCanceled
+        on_close_button
         close
         clear
     """
@@ -586,34 +882,34 @@
         """__init__(mainWindow, readFileMethod, budget, filename,
                         cancelMethod, filetype)
         
-        mainWindow: gui.Mainwindow object
+        mainWindow: Mainwindow object
         readFileMethod: Method to read the selected file
         budget: base.Budget object
         filename: "file"
         cancelMethod: Method to cancel the read method
-        filetype: "budget", "database" or "durus"
-        
-        self.__mainWindow: gui.Mainwindow object
+        filetype: "budget" or "database"
+        
+        self.__mainWindow: Mainwindow object
+        self.endSuccessfully False/True
         self.__readFileMethod: Method to read the selected file
         self.__budget: base.Budget object
         self.__filename: "file"
         self.__cancelMethod: Method to cancel the read method
-        self.__filetype: "budget", "database" or "durus"
+        self.__filetype: "budget" or "database"
         self.__children: the read thread
         self.__progress: 0 to 1 progress
         self.__statistics: record statistics
-        self.__widget: main widget, a gtk.VBox object
+        self.__widget: main widget, a vertial Gtk.Grid object
         self.__main_item: None
-        self.__throbber: a gtk.Image
-        self.__animationThobber: a gtk.gdk.PixbufAnimation
-        self.__quietThobber: a pixbuf
-        self.__budget_icon: a gtk.gdk.pixbuf
-        self.__title: a gtk.HBox
-        self.__statusbar: a gtk.Statusbar
+        self.__throbber: Gtk.Spinner()
+        self.__budget_icon: Gtk.Image()
+        self.__title: a horizontal Gtk.Grid
+        self.__statusbar: a Gtk.Statusbar
         self.__statuscontext: the statusbar context
-        self.__progress_bar: a gtk.ProgressBar
+        self.__progress_bar: a Gtk.ProgressBar
         """
         self.__mainWindow = mainWindow
+        self.endSuccessfully = False
         self.__readFileMethod = readFileMethod
         self.__budget = budget
         self.__filename = filename
@@ -623,51 +919,68 @@
         self.__cancel = [False, False]
         self.__progress = 0.0
         self.__statistics = None
-        self.__widget = gtk.VBox()
+        self.__widget = Gtk.Grid()
+        self.__widget.set_orientation(Gtk.Orientation(1)) # 1 Vertical
         self.__main_item = None
         self.__widget.show()
-        self.__throbber = gtk.Image()
-        self.__throbber.set_from_file(globalVars.getAppPath("THROBBER-ICON"))
+        # Throbber
+        self.__throbber = Gtk.Spinner()
         self.__throbber.show()
-        self.__animationThobber = gtk.gdk.PixbufAnimation(
-                                  globalVars.getAppPath("THROBBER-GIF"))
-        self.__quietThobber = self.__throbber.get_pixbuf()
-        self.__budget_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__budget_icon = Gtk.Image()
+        _budget_pixbuf = GdkPixbuf.Pixbuf.new_from_file(
                              globalVars.getAppPath("BUDGET-ICON"))
+        self.__budget_icon.set_from_pixbuf(_budget_pixbuf)
         _filename = os.path.basename(filename)
         _rootfilename = os.path.splitext(_filename)[0]
         if not _rootfilename == "":
             _filename = _rootfilename
-        _titleLabel = gtk.Label(_filename)
+        if len(_filename) > 28:
+            _titleLabel = Gtk.Label(_filename[:25] + "...")
+            _titleLabel.set_tooltip_text(_filename)
+        else:
+            _titleLabel = Gtk.Label(_filename)
         _titleLabel.show()
-        self.__title = gtk.HBox()
+        self.__title = Gtk.Grid()
+        self.__title.set_column_spacing(4)
+        self.__title.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
+        self.__title.add(self.__budget_icon)
         self.__title.add(self.__throbber)
         self.__title.add(_titleLabel)
-        self.__statusbar = gtk.Statusbar()
+        # Close tab
+        _gtk_image = Gtk.Image()
+        _gtk__pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                  "window-close-symbolic", 16, 0)
+        _gtk_image.set_from_pixbuf(_gtk__pixbuf)
+        _gtk_image.show()
+        self.closeTabButton = Gtk.ToolButton.new(_gtk_image , _("_Close tab"))
+        self.closeTabButton.set_tooltip_text(_("Close tab"))
+        self.closeTabButton.set_is_important(False)        # label not shown
+        self.__title.add(self.closeTabButton)
+        self.closeTabButton.hide()
+        self.__closeTabId = self.closeTabButton.connect("clicked", self.on_close_button)
+        # Statusbar
+        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()
+        _iconVbox = Gtk.Grid()
+        _iconVbox.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        _iconVbox.props.halign = Gtk.Align(3) # 3 Center
+        _iconVbox.props.valign = Gtk.Align(3) # 3 Center
+        _iconVbox.set_property("expand", True) # widget expand all space
+        _pyArqIcon = Gtk.Image()
         _pyArqIcon.set_from_file(globalVars.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)
+        _iconVbox.add(_pyArqIcon)
+        _link = Gtk.LinkButton.new("http://pyarq.obraencurso.es")
+        _iconVbox.add(_link)
         _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.__widget.add(_iconVbox)
+        self.__progress_bar = Gtk.ProgressBar()
+        self.__progress_bar.set_show_text(True)
         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.__statusbar.pack_start(self.__progress_bar, False, False, 0)
+        self.__widget.add(self.__statusbar)
         self.__main_item = None
 
     def run(self):
@@ -676,7 +989,7 @@
         Launch clildren and timeouts
         """
         self.__statusbar.push(self.__statuscontext, _("Time: 0s"))
-        self.__throbber.set_from_animation(self.__animationThobber)
+        self.__throbber.start()
         self._launchChildren()
         self._launchTimeout()
 
@@ -695,9 +1008,9 @@
         
         message: mesage from readFile method
         
-        print message
-        """
-        print message
+        print( message )
+        """
+        print( message )
 
     def readFile_set_statistics(self, statistics):
         """readFile_set_statistics(statistics)
@@ -713,21 +1026,24 @@
         
         The readFile method end successfully
         """
-        print self.__statistics
+        self.endSuccessfully = True
+        print( self.__statistics.str() )
 
     def readFile_cancel(self):
         """readFile_cancel()
         
         The readFile method is canceled
         """
-        print _("Process terminated")
+        self.endSuccessfully = False
+        print(_("Process terminated") )
 
     def stopLoading(self):
         """stopLoading()
         
         Stop progressbar
         """
-        self.__throbber.set_from_pixbuf(self.__budget_icon)
+        self.__throbber.destroy()
+        self.__budget_icon.show()
         self.__progress_bar.hide()
         self.__statusbar.pop(self.__statuscontext)
 
@@ -750,12 +1066,15 @@
             2- update time label
             3- If the other timetouts are stoped the window is closed
         """
-        gobject.timeout_add(1000, self._updateLabel, time.time())
-        gobject.timeout_add(500, self._updateProgressBar)
+        GLib.timeout_add(1000, self._updateLabel, time.time())
+        GLib.timeout_add(500, self._updateProgressBar)
         self.__cancel = [False, False]
-        #self.__cancel = [True, False]
-        gobject.timeout_add(1000, self._autoClose)
-
+        GLib.timeout_add(1000, self._autoClose)
+
+    def updateGui(self):
+        while Gtk.events_pending():
+            Gtk.main_iteration()
+    
     def _updateProgressBar(self):
         """_updateProgressBar()
         
@@ -772,7 +1091,7 @@
             return True
 
     def _updateLabel(self, _time):
-        """_updateProgressBar(_time)
+        """_updateLabel(_time)
         
         update time label in a timeout
         If the thread end or is canceled the timeout is stoped
@@ -788,11 +1107,12 @@
             return True
 
     def _autoClose(self):
-        """_updateProgressBar()
+        """_autoClose()
         
         If the time label and progress bar timeouts are stoped the window is 
         closed and ist tiemeout is stoped
         """
+        #_autoClose timeout do nothig
         if self.__cancel == [ True, True ]:
             return False
         else:
@@ -808,11 +1128,13 @@
         self.__budget = budget
         self.__children = None
         self.stopLoading()
-        _page = Page(self.__mainWindow, self.__budget)
+        _page = Page(self.__mainWindow, self.__budget, self.closeTabButton)
         _children = self.__widget.get_children()
         for _child in _children:
             self.__widget.remove(_child)
-        self.__widget.pack_start(_page.widget, True, True, 0)
+        self.__widget.add(_page.widget)
+        self.closeTabButton.disconnect(self.__closeTabId)
+        self.closeTabButton.connect("clicked", _page.on_close_button)
         self.__mainWindow.updatePage(self, _page)
 
     def threadCanceled(self):
@@ -826,6 +1148,13 @@
         self.stopLoading()
         self.__mainWindow.closePage(self)
 
+    def on_close_button(self, widget):
+        """on_close_button()
+        
+        Call close
+        """
+        self.close()
+
     def close(self):
         """close()
         
@@ -836,7 +1165,7 @@
     def clear(self):
         """clear()
         
-        clear vars
+        Nothig to do now
         """
         pass
 
@@ -850,14 +1179,14 @@
     def _getTitle(self):
         """_getTitle()
         
-        Return the title of the page, a gtk.Label objetc
+        Return the title of the page, a Gtk.Label objetc
         """
         return self.__title
 
     def _getFiletype(self):
         """_getFiletipe()
         
-        Return the title of the page, a gtk.Label objetc
+        Return the title of the page, a Gtk.Label objetc
         """
         return self.__filetype
 
@@ -866,7 +1195,7 @@
     title = property(_getTitle, None, None,
                       "Page Title")
     filetype = property(_getFiletype, None, None,
-                      "Filetype: budget, basedata or durus")
+                      "Filetype: budget or basedata")
 
 
 class Page(object):
@@ -877,15 +1206,16 @@
     The page can show the budget information in several panes ordered
     according to "panes_list" information.
     Constructor:
-        gui.Page(mainWindow, budget, active_code=None)
+        Page(mainWindow, budget, closeTabButton, active_code=None)
             mainwindow: MainWindow object
             budget: base.Budget object
+            closeTabButton. button winget to close tab
             active_code: Active record code
     Ancestry:
     +-- object
       +-- Page
     Atributes:
-        widget: Read. Notebook page Widget. (a gtk.VBox instance)
+        widget: Read. Notebook page Widget. (a vertical Gtk.Grid instance)
         budget: Read-Write. Budget to show in the page. (base.obra object)
         panes_list: Read. info list for create the panes
             ej: [ "v", pane1, pane2 ] , [ "h", pane1, pane2 ]
@@ -896,7 +1226,7 @@
                 * "Measure": its creates a "Measure" objetc
                 * "FileView": its creates a "FileView" objet
                 * "CompanyView": its creates a "CompanyView" object
-        title: Read. Notebook page title (gtk.Label object)
+        title: Read. Notebook page title (Gtk.Label object)
         activePathRecord: Read. The active path record
         previousPathRecord: Read. The previous path record
         posteriorPathRecord Read. The posterior path record
@@ -905,6 +1235,7 @@
     Methods:
         propagateMessageFrom
         sendMessageTo
+        on_close_button
         close
         clear
         getItem
@@ -914,52 +1245,59 @@
     # TODO:  * pane types
     # TODO:      * General budget properties (is better a dialog?)
 
-    def __init__(self, mainWindow, budget, path_record=None):
-        """__init__(mainWindow, budget, path_record=None)
+    def __init__(self, mainWindow, budget, closeTabButton, path_record=None):
+        """__init__(mainWindow, budget, closeTabButton,  path_record=None)
         
         mainWindow: MainWindow object
         budget: "base.Budget" object
+        closeTabButton: Button widget to close tab
         path_record: the active path record
         
         self.__mainWindow: MainWindow object
-        self.__widget: a gtk.VBox
+        self.__widget: a Gtk.Grid
         self.__panes_list: 
-        self.__main_item: 
+        self.__main_item: Main item in Page. (Paned object or View object)
+        self.closeTabButton: : Button widget to close tab
         self.__active_path_record:
         self.__history_back:
         self.__history_forward:
-        self.__back_menu: a gtk.Menu
-        self.__forward_menu: a gtk.Menu
+        self.__back_menu: a Gtk.Menu
+        self.__forward_menu: a Gtk.Menu
         """
         if path_record is None:
             path_record = (0,)
-        #TODO: __panes_list should come from config file...
         self.__mainWindow = mainWindow
-        self.__widget = gtk.VBox()
+        self.closeTabButton = closeTabButton
+        self.__widget = Gtk.Grid()
+        self.__widget.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        self.__widget.props.margin = 5
+        #TODO: __panes_list should come from gui config file...
+        # "DecompositionList" "RecordDescription" "Measure" "Sheet of Conditions"
+        # "FileView" "CompanyView"
         self.__panes_list = [ "v", "DecompositionList", [ "v", "Measure",
             "RecordDescription" ]]
         self.__main_item = None
         self.__active_path_record = ()
         self.__history_back = []
         self.__history_forward = []
-        self.__back_menu = gtk.Menu()
+        self.__back_menu = Gtk.Menu()
         self.__back_menu.show()
-        self.__forward_menu = gtk.Menu()
+        self.__forward_menu = Gtk.Menu()
         self.__forward_menu.show()
-        self.budget = budget
+        self.budget = budget            # Create all items and widgets
         self._setActivePathRecord(path_record)
         self.__widget.show()
-        self.__budget_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__budget_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("BUDGET-ICON"))
-        self.__chapter_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__chapter_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("CHAPTER-ICON"))
-        self.__unit_icon  = gtk.gdk.pixbuf_new_from_file(
+        self.__unit_icon  = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("UNIT-ICON") )
-        self.__material_icon  = gtk.gdk.pixbuf_new_from_file(
+        self.__material_icon  = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("MATERIAL-ICON") )
-        self.__machinery_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__machinery_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("MACHINERY-ICON"))
-        self.__labourforce_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__labourforce_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("LABOURFORCE-ICON"))
 
     def propagateMessageFrom(self, message, pane_path, arg=None):
@@ -980,7 +1318,7 @@
         if message == "change_active" and _budget.hasPath(arg):
             self.sendMessageTo(self.__main_item, message, pane_path, arg)
             self._setActivePathRecord(arg)
-            self.__mainWindow.changeActiveSignal()
+            self.__mainWindow.changeActiveSignal() # Check sensitive buttons
         elif message == "autoclose":
             self._closeItem(pane_path)
         elif message == "split h":
@@ -997,8 +1335,10 @@
         
         Sends a message to a pane
         """
-        if not pane.pane_path == pane_path:
-            pane.runMessage(message, pane_path, arg)
+        pane.runMessage(message, pane_path, arg)
+
+    def on_close_button(self, widget):
+        self.close()
 
     def close(self):
         """close()
@@ -1043,7 +1383,7 @@
         self.__main_item = item
         _main_widget = self.__main_item.widget
         _main_widget.show()
-        self.__widget.pack_start(_main_widget, True, True, 0)
+        self.__widget.add(_main_widget)
 
     def _splitItem(self, pane_path, orientation):
         """_splitItem(pane_path, orientation)
@@ -1051,12 +1391,12 @@
         Splits the item that is identifies by the pane_path and the orientation
         """
         _item = self.getItem(pane_path)
-        _parent = self.getItem(pane_path[:-1])
-        _item.pane_path =  pane_path + (0,)
+        _item.pane_path = pane_path + (0,)
         _item_clone0 = _item.getClone(pane_path + (0,))
         _item_clone1 = _item.getClone(pane_path + (1,))
         _paned = Paned(orientation, pane_path, _item_clone0, _item_clone1)
         if len(pane_path) > 1:
+            _parent = self.getItem(pane_path[:-1])
             _parent.setItem(pane_path[-1], [_paned])
         else:
             self._setMainItem(_paned)
@@ -1112,10 +1452,10 @@
         if pane_path is None:
             pane_path = (0,)
         if not isinstance(list_paned , list):
-            raise ValueError, _("The value must be a 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")
+                raise ValueError( _("Incorrect len") )
             if not isinstance(list_paned[1],list):
                 list_paned[1] = [list_paned[1]]
             if not isinstance(list_paned[2],list):
@@ -1125,26 +1465,26 @@
             _item = Paned(list_paned[0], pane_path, _item1, _item2)
         elif list_paned[0] == "DecompositionList":
             _item = View( "DecompositionList", self.__budget,
-                weakref.ref(self), pane_path, self.__active_path_record)
+                weakref.ref(self), pane_path, self.__active_path_record, True)
         elif list_paned[0] == "RecordDescription":
             _item = View( "RecordDescription", self.__budget,weakref.ref(self),
-                pane_path, self.__active_path_record)
+                pane_path, self.__active_path_record, True)
         elif list_paned[0] == "Measure":
             _item = View( "Measure", self.__budget, weakref.ref(self), pane_path,
-                self.__active_path_record)
+                self.__active_path_record, True)
         elif list_paned[0] == "Sheet of Conditions":
-            _item  = Sheet(sef.__budget, weakref.ref(self), pane_path,
+            _item  = View("Sheet of Conditions", self.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         elif list_paned[0] == "FileView":
-            _item  = FileView(sef.__budget, weakref.ref(self), pane_path,
+            _item  = View("FileView", self.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         elif list_paned[0] == "CompanyView":
-            _item  = CompanyView(sef.__budget, weakref.ref(self), pane_path,
+            _item  = View("CompanyView", self.__budget, weakref.ref(self), pane_path,
                 self.__active_path_record)
         else:
             _item = None
-            raise ValueError, utils.mapping(_("Incorrect item $1"),
-                  (str(list_paned[0]),))
+            raise ValueError( utils.mapping(_("Incorrect item $1"),
+                  (str(list_paned[0]),)) )
         return _item
 
     def _setActivePathRecord(self, path_record):
@@ -1159,8 +1499,8 @@
                 self.__active_path_record = path_record
                 self._appendHistory(path_record)
             else:
-                raise ValueError, utils.mapping(_("The budget does not have "\
-                    "the path record: $1"), (str(path_record),))
+                raise ValueError( utils.mapping(_("The budget does not have "\
+                    "the path record: $1"), (str(path_record),)) )
 
     def _appendHistory(self, path):
         """_appendHistory(path))
@@ -1250,7 +1590,7 @@
                 _icon = self.__machinery_icon
             else:
                 _icon = self.__material_icon
-        _image = gtk.Image()
+        _image = Gtk.Image()
         _image.set_from_pixbuf(_icon)
         return _image
 
@@ -1261,7 +1601,6 @@
         
         Creates menus for history back an history forward tool buttons
         """
-
         # Back Menu
         # clear menu
         for _child in self.__back_menu.get_children():
@@ -1270,7 +1609,7 @@
         if len(self.__history_back) > 1:
             for _record_path in self.__history_back[:-1]:
                 _menuitem = self._menuItemFactory(_record_path)
-                _menuitem.connect_object("activate", self._menuHistoryBack,
+                _menuitem.connect("activate", self._menuHistoryBack,
                     _record_path, _menuitem)
                 self.__back_menu.prepend(_menuitem)
         # Forward Menu
@@ -1281,7 +1620,7 @@
         if len(self.__history_forward) > 0:
             for _record_path in self.__history_forward[:]:
                 _menuitem = self._menuItemFactory(_record_path)
-                _menuitem.connect_object("activate", self._menuHistoryForward,
+                _menuitem.connect("activate", self._menuHistoryForward,
                     _record_path, _menuitem)
                 self.__forward_menu.prepend(_menuitem)
 
@@ -1295,13 +1634,19 @@
         _code = self.budget.getCode(record_path)
         _record = self.budget.getRecord(_code)
         _summary = _record.summary
-        _text = _code + " " + _summary
+        _text = _code.decode("utf8") + " " + _summary.decode("utf8")
         if len(_text) > 30:
             _text = _text[:27] + "..."
-        _image = self._getImage(_record)
-        _menuitem = gtk.ImageMenuItem(_text)
-        _menuitem.set_image(_image)
-        _menuitem.show()
+        _icon = self._getImage(_record)
+        _grid = Gtk.Grid()
+        _grid.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
+        _grid.set_column_spacing(6)
+        _label = Gtk.Label(_text)
+        _menuitem = Gtk.MenuItem.new()
+        _grid.add(_icon)
+        _grid.add(_label)
+        _menuitem.add(_grid)
+        _menuitem.show_all()
         return _menuitem
 
     def _menuHistoryBack(self, record_path, menu_item):
@@ -1364,7 +1709,7 @@
     def _getTitle(self):
         """_getTitle()
         
-        Return the page title, a gtk.Label objetc
+        Return the page title, a Gtk.Label objetc
         """
         return self.__title
     
@@ -1390,13 +1735,13 @@
         self.__budget = budget
         self._setActivePathRecord((0,))
         # Todo: change page title
-        self.__title = gtk.Label(self.__budget.getCode(
+        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.widget
         _main_widget.show()
-        self.__widget.pack_start(_main_widget, True, True, 0)
+        self.__widget.add(_main_widget)
 
     def _getBudget(self):
         """_getBudget()
@@ -1437,7 +1782,8 @@
     Description:
         It creates a view to show the budget info
     Constructor:
-        View(view_type, budget, wr_page, pane_path, active_path_record)
+        View(view_type, budget, wr_page, pane_path, active_path_record,
+             connected)
             view_type: the object type to show
                 * DecompositionList
                 * Description
@@ -1449,14 +1795,16 @@
             wr_page: weak reference to the page where the view must be showed
             pane_path: the position or path of the view in the page notebook
             active_path_record: the record path that must be showed
+            connected: boolean value, True means that the View object sends
+            and receives signals from/to others views.
     Ancestry:
     +-- object
       +-- View
     Atributes:
         pane_path: Read-Write. The tuple that identifies the view in the main 
             notebook page
-        widget: Read. the main gtk widget to show in a view object,
-            a gtk.VBox object
+        widget: Read. the main Gtk widget to show in a view object,
+            a Gtk.Grid object
     Methods:
         getItem
         propagateMessgeFrom
@@ -1466,8 +1814,9 @@
     """
 
     def __init__(self, view_type, budget, wr_page, pane_path,
-                 active_path_record):
-        """__init__(view_type, budget, wr_page, pane_path, active_path_record)
+                 active_path_record, connected=True):
+        """__init__(view_type, budget, wr_page, pane_path, active_path_record,
+                    connected )
         view_type: the object type to show
             * DecompositionList
             * Description
@@ -1480,7 +1829,6 @@
         pane_path: the position or path of the view in the page notebook
         active_path_record: the record path that must be showed
         
-        self.__active_path_record: the record path that must be showed
         self.__view_type: the object type to show
             * DecompositionList
             * Description
@@ -1494,7 +1842,7 @@
         self.__pane_path: the position or path of the view in the page notebook
         self.__connected: boolean value, True means that the View object sends
             and receives signals from/to others views
-        self.__widget: main widget. a gtk.VBox
+        self.__widget: main widget. a Gtk.Grid
         self.__view: the object to show:
             * DecompositionList object
             * Description object
@@ -1507,101 +1855,135 @@
         
         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.__pane_path = pane_path
-        self.__connected = True
+        self.__connected = connected
         # view_type liststore
-        _liststore = gtk.ListStore(str)
+        _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 = Gtk.ComboBox.new_with_model(_liststore)
+        _cell = Gtk.CellRendererText()
         _combobox.pack_start(_cell, True)
         _combobox.add_attribute(_cell, 'text', 0)
-        self.__widget = gtk.VBox()
-        _hbox = gtk.HBox()
+        self.__widget = Gtk.Grid()
+        self.__widget.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        _hbox = Gtk.Grid()
+        _hbox.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
         if view_type == "DecompositionList":
             self.__view = DecompositionList(budget, weakref.ref(self),
                           pane_path, active_path_record)
             _combobox.set_active(0)
-            _view_icon = gtk.Image()
+            _view_icon = Gtk.Image()
             _view_icon.set_from_file(globalVars.getAppPath(
                 "DECOMPOSITION-ICON"))
         elif view_type == "RecordDescription":
             self.__view = Description(budget, weakref.ref(self),
                           pane_path, active_path_record)
             _combobox.set_active(1)
-            _view_icon = gtk.Image()
+            _view_icon = Gtk.Image()
             _view_icon.set_from_file(globalVars.getAppPath(
                 "DESCRIPTION-ICON"))
         elif view_type == "Measure":
             self.__view = Measure(budget, weakref.ref(self),
                           pane_path, active_path_record)
             _combobox.set_active(2)
-            _view_icon = gtk.Image()
+            _view_icon = Gtk.Image()
             _view_icon.set_from_file(globalVars.getAppPath("MEASURE-ICON"))
         elif view_type == "Sheet of Conditions":
             self.__view = Sheet(budget, weakref.ref(self),
                           pane_path, active_path_record)
             _combobox.set_active(3)
-            _view_icon = gtk.Image()
+            _view_icon = Gtk.Image()
             _view_icon.set_from_file(globalVars.getAppPath("SHEET-ICON"))
         elif view_type == "FileView":
             self.__view = FileView(budget, weakref.ref(self),
                           pane_path, active_path_record)
             _combobox.set_active(4)
-            _view_icon = gtk.Image()
-            _view_icon.set_from_file(globalVars.getAppPath("SHEET-ICON"))
+            _view_icon = Gtk.Image()
+            _view_icon.set_from_file(globalVars.getAppPath("FILEVIEW-ICON"))
         elif view_type == "CompanyView":
             self.__view = CompanyView(budget, weakref.ref(self), pane_path,
                           active_path_record)
             _combobox.set_active(5)
-            _view_icon = gtk.Image()
-            _view_icon.set_from_file(globalVars.getAppPath("SHEET-ICON"))
+            _view_icon = Gtk.Image()
+            _view_icon.set_from_file(globalVars.getAppPath("COMPANY-ICON"))
         else:
-            raise ValueError, _(utils.mapping("Invalid type of View: $1",
-                  view_type))
+            raise ValueError( _(utils.mapping("Invalid type of View: $1",
+                  view_type)) )
         _view_icon.show()
         _combobox.connect("changed", self._change_combo)
         _combobox.show()
-        self.__widget.pack_start(_hbox,False)
-        self.__widget.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()
+        self.__widget.add(_hbox)
+        self.__widget.add(self.__view.widget)
+        _hbox.add(_view_icon)
+        _hbox.add(_combobox)
+        _invisible = Gtk.Grid()
+        _invisible.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
+        _invisible.set_property("hexpand", True) # widget expand horizontal space
         _invisible.show()
-        _hbox.pack_start(_invisible, True, False,0)
-        _icon_menu = gtk.Image()
-        _icon_menu.set_from_file(globalVars.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(globalVars.getAppPath("CONNECTED-ICON"))
+        _hbox.add(_invisible)
+        # TODO : Set thist with config
+        add_menu = False
+        if add_menu:
+            _icon_menu = Gtk.Image()
+            _icon_menu.set_from_file(globalVars.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()
+            _hbox.add(_menu_button)
+
+        _icon_horizontal = Gtk.Image()
+        _icon_horizontal.set_from_file(globalVars.getAppPath("HORIZONTAL"))
+        _icon_horizontal.show()
+        _horizontal_button = Gtk.ToolButton()
+        _horizontal_button.set_icon_widget(_icon_horizontal)
+        _horizontal_button.connect("clicked", self._split_view, "h")
+        _horizontal_button.set_tooltip_text(_("Split View Left/Right"))
+        _horizontal_button.show()
+        _hbox.add(_horizontal_button)
+        
+        _icon_vertical = Gtk.Image()
+        _icon_vertical.set_from_file(globalVars.getAppPath("VERTICAL"))
+        _icon_vertical.show()
+        _vertical_button = Gtk.ToolButton()
+        _vertical_button.set_icon_widget(_icon_vertical)
+        _vertical_button.connect("clicked", self._split_view, "v")
+        _vertical_button.set_tooltip_text(_("Split View Top/Bottom"))
+        _vertical_button.show()
+        _hbox.add(_vertical_button)
+
+        self.__connected_button = Gtk.ToolButton()
+        _icon_connected = Gtk.Image()
+        if self.__connected:
+            _icon_connected.set_from_file(globalVars.getAppPath("CONNECTED-ICON"))
+            self.__connected_button.set_tooltip_text(_("Disconnect view"))
+        else:
+            _icon_connected.set_from_file(globalVars.getAppPath("DISCONNECTED-ICON"))
+            self.__connected_button.set_tooltip_text(_("Connect view"))
         _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()
+        _hbox.add(self.__connected_button)
+
+        _icon_close = Gtk.Image()
         _icon_close.set_from_file(globalVars.getAppPath("CLOSE-ICON"))
         _icon_close.show()
-        _close_button = gtk.ToolButton()
+        _close_button = Gtk.ToolButton()
         _close_button.set_icon_widget(_icon_close)
-        _close_button.connect("clicked", self._closeItem)
+        _close_button.connect("clicked", self._closeItem_from_button)
+        _close_button.set_tooltip_text(_("Close view"))
         _close_button.show()
-        _hbox.pack_start(_close_button, False, False, 0)
+        _hbox.add(_close_button)
         _hbox.show()
         self.__widget.show()
 
@@ -1612,8 +1994,16 @@
         """
         return self
 
-    def _closeItem(self, close_button):
-        """_closeItem(close_button)
+    def _closeItem_from_menu(self, close_menuitem):
+        """_closeItem_from_menu(close_menuitem)
+        
+        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.__pane_path)
+
+    def _closeItem_from_button(self, close_button):
+        """_closeItem_from_button(close_button)
         
         Method connected to the "clicked" signal of the _close_button widget
         Send the "autoclose" message to the page to close this view
@@ -1628,24 +2018,15 @@
         """
         _index = combobox.get_active()
         _budget = self.__view.budget
-        _wr_page = self.__view.page
+        _wr_page = self.__view.wr_page
         _pane_path = self.__view.pane_path
         _path_record = self.__view.active_path_record
-        _hbox = self.__widget.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)
+        _hbox = self.__widget.get_children()[1]
+        _view_icon = _hbox.get_child_at(0, 0)
+        _hbox.remove(_view_icon)
+        _view_icon.destroy()
         self.__widget.remove(self.__view.widget)
-        self.__widget.remove(_hbox)
-        _hbox.destroy()
-        _view_icon = gtk.Image()
+        _view_icon = Gtk.Image()
         if _index == 0:
             self.__view = DecompositionList(_budget, _wr_page, _pane_path,
                           _path_record)
@@ -1671,24 +2052,16 @@
         elif _index == 4:
             self.__view = FileView(_budget, _wr_page, _pane_path,
                          _path_record)
-            _view_icon.set_from_file(globalVars.getAppPath("SHEET-ICON"))
+            _view_icon.set_from_file(globalVars.getAppPath("FILEVIEW-ICON"))
             self.__view_type = "FileView"
         elif _index == 5:
             self.__view = CompanyView(_budget, _wr_page, _pane_path,
                           _path_record)
-            _view_icon.set_from_file(globalVars.getAppPath("SHEET-ICON"))
+            _view_icon.set_from_file(globalVars.getAppPath("COMPANY-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()
-        self.__widget.pack_start(_hbox, False, False, 0)
-        self.__widget.pack_start(self.__view.widget, True, True, 0)
+        _hbox.attach(_view_icon, 0, 0, 1, 1)
+        self.__widget.add(self.__view.widget)
 
     def _menu_view(self, widget):
         """_menu_view(widget)
@@ -1696,22 +2069,22 @@
         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 = 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.connect("activate", self._split_view, "h")
         _item_leftright.show()
-        _item_topbottom = gtk.MenuItem(_("Split View Top/Bottom"))
+        _item_topbottom = Gtk.MenuItem(_("Split view Top/Bottom"))
         _menu_view.append(_item_topbottom)
-        _item_topbottom.connect_object("activate", self._split_view, "v")
+        _item_topbottom.connect("activate", self._split_view, "v")
         _item_topbottom.show()
-        _item_close = gtk.MenuItem(_("Close view"))
+        _item_close = Gtk.MenuItem(_("Close view"))
         _menu_view.append(_item_close)
-        _item_close.connect_object("activate", self._closeItem, None)
+        _item_close.connect("activate",self._closeItem_from_menu)
         _item_close.show()
-        _menu_view.popup(None, None, None, 0, 0)
-
-    def _split_view(self, orientation):
+        _menu_view.popup_at_widget(widget, Gdk.Gravity(7), Gdk.Gravity(1), Gtk.get_current_event())
+
+    def _split_view(self, widget, orientation):
         """_menu_view(orientation)
         
         orientation: orientation split, "h" or "v"
@@ -1732,15 +2105,17 @@
         to/from others views
         """
         if self.__connected:
-            _icon = gtk.Image()
+            _icon = Gtk.Image()
             _icon.set_from_file(globalVars.getAppPath("DISCONNECTED-ICON"))
             _icon.show()
             self.__connected_button.set_icon_widget(_icon)
+            self.__connected_button.set_tooltip_text(_("Connect View"))
             self.__connected = False
         else:
-            _icon = gtk.Image()
+            _icon = Gtk.Image()
             _icon.set_from_file(globalVars.getAppPath("CONNECTED-ICON"))
             _icon.show()
+            self.__connected_button.set_tooltip_text(_("Disconnect View"))
             self.__connected_button.set_icon_widget(_icon)
             self.__connected = True
 
@@ -1770,10 +2145,6 @@
         """
         if self.__connected:
             self.__view.runMessage(message, pane_path, arg)
-            if message == "change_active":
-                if self.__budget.hasPath(arg):
-                    _path_record = arg
-                    self.__active_path_record = _path_record
 
     def _getWidget(self):
         """_getWidget()
@@ -1805,7 +2176,8 @@
         return a clone of itself
         """
         return View(self.__view_type, self.__budget, self.__wr_page,
-                       new_pane_path, self.__active_path_record)
+                       new_pane_path, self.__view.active_path_record,
+                       self.__connected)
 
     def clear(self):
         """clear()
@@ -1829,7 +2201,7 @@
     """gui.Paned:
     
     Description:
-        It creates and shows gtk.Hpaned or gtk.Vpaned to show in page budget
+        It creates and shows Gtk.Paned to show in page budget
     Constructor:
         Paned(orientation, widget1, widget2)
             orientation: The orientation of the pane separator, can be "v" or
@@ -1840,7 +2212,7 @@
     +-- object
       +-- Paned
     Atributes:
-        widget: Read. Pane widget("gtk.VPaned" or "gtk.HPaned" object)
+        widget: Read. Pane widget("Gtk.Paned" object)
         pane_path: Read-Write. The paned path in the page
     Methods:
         getClone
@@ -1857,29 +2229,31 @@
     def __init__(self, orientation, pane_path, item1, item2):
         """__init__(oritentation, pane_path, item1, item2)
         
-        orientation: The orientation of de gtk.Paned, can be "v" or "h"
+        orientation: The orientation of de Gtk.Paned, can be "v" or "h"
         pane_path: the paned path in the page
         item1: the top or left pane object
         item2: the bottom or right pane object
         
-        self.__orientation: The orientation of de gtk.Paned, can be "v" or "h"
-        self.__widget: Main widget, a gtk.VPaned o gtk.HPaned
+        self.__orientation: The orientation of de Gtk.Paned, can be "v" or "h"
+        self.__widget: Main widget, a Gtk.Paned
         self.__items: list of items showed in the paned, its can be View or
             Paned instances
         self.__pane_path: the paned path in the page
         
-        Creates and shows a new gtk.Paned
+        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 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()
+            self.__widget = Gtk.Paned.new(Gtk.Orientation(1))
+            self.__widget.set_wide_handle(True) 
         elif orientation == "h":
-            self.__widget = gtk.HPaned()
+            self.__widget = Gtk.Paned.new(Gtk.Orientation(0))
+            self.__widget.set_wide_handle(True) 
         else:
-            raise ValueError, _("Invalid orientation.")
+            raise ValueError( _("Invalid orientation.") )
         self.__widget.pack1(item1.widget,True,False)
         self.__widget.pack2(item2.widget,True,False)
         self.__widget.show()
@@ -1950,7 +2324,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        Return de gtk.Paned widget
+        Return de Gtk.Paned widget
         """
         return self.__widget
 
@@ -1980,7 +2354,7 @@
         del self.__items
         del self.__pane_path
 
-    widget = property(_getWidget, None, None, "gtk.Paned widget")
+    widget = property(_getWidget, None, None, "Gtk.Paned widget")
     pane_path = property(_getPanePath, _setPanePath, None,
         "Pane path in the notebook page")
 
@@ -2010,7 +2384,7 @@
     +-- object
       +-- TreeView
     Atributes:
-        columns: list of columns (gtk.TreeViewColumn objects)
+        columns: list of columns (Gtk.TreeViewColumn objects)
     Methods:
         createColumn
         createTextBaseColumn
@@ -2039,7 +2413,7 @@
         """
         self.columns = [ self.createColumn(arg) for arg in args ]
         self.columns.append(self.createColumn(("END",)))
-    
+
     def createColumn(self, args):
         """createColumn(args)
         
@@ -2061,19 +2435,19 @@
         """
         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(globalVars.color["TEXT"]))
-            _pixbuf_index_cell = gtk.CellRendererPixbuf()
-            _arrow_icon = gtk.gdk.pixbuf_new_from_file(
+            _text_index_cell = Gtk.CellRendererText()
+            _text_index_cell.set_property('foreground',
+                globalVars.color["TEXT"])
+            _pixbuf_index_cell = Gtk.CellRendererPixbuf()
+            _arrow_icon = GdkPixbuf.Pixbuf.new_from_file(
                 globalVars.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(globalVars.color["INDEX-UNEVEN"]),
-                gtk.gdk.color_parse(globalVars.color["INDEX-EVEN"])])
+                [globalVars.color["INDEX-UNEVEN"],
+                 globalVars.color["INDEX-EVEN"]])
             return _index_column
         elif args[0] == "TEXT":
             _column, _cell = self.createTextBaseColumn(args)
@@ -2082,20 +2456,20 @@
         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)
+            _column.get_cells()[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)
+            _column.get_cells()[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])
+            _type_cell1 = Gtk.CellRendererPixbuf()
+            _type_cell2 = Gtk.CellRendererText()
+            _type_cell2.set_property('foreground', args[3])
             _column.pack_start(_type_cell1, True)
             _column.pack_start(_type_cell2, True)
             _column.add_attribute(_type_cell2, 'text', args[5])
@@ -2106,17 +2480,17 @@
             return _column
         elif args[0] == "PIXBUF":
             _column = self.createBaseColumn(args)
-            _type_cell1 = gtk.CellRendererPixbuf()
+            _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 = Gtk.TreeViewColumn()
             _end_column.set_clickable(False)
-            _end_cell = gtk.CellRendererText()
-            _end_cell.set_property('cell-background-gdk',
-                gtk.gdk.color_parse(globalVars.color["UNEVEN"]))
+            _end_cell = Gtk.CellRendererText()
+            _end_cell.set_property('background',
+                globalVars.color["UNEVEN"])
             _end_column.pack_start(_end_cell, True)
             return _end_column
         return None
@@ -2139,8 +2513,8 @@
         Return a column and its CellREndererText
         """
         _column = self.createBaseColumn(args)
-        _cell = gtk.CellRendererText()
-        _cell.set_property('foreground-gdk', args[3])
+        _cell = Gtk.CellRendererText()
+        _cell.set_property('foreground', args[3])
         _column.pack_start(_cell, True)
         _column.set_cell_data_func(_cell, self._colorCell, args[4])
         return _column, _cell
@@ -2164,10 +2538,10 @@
         
         Return a column
         """
-        _column = gtk.TreeViewColumn()
+        _column = Gtk.TreeViewColumn()
         _column.set_clickable(True)
         _column.connect("clicked", args[1])
-        _column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        _column.set_sizing(Gtk.TreeViewColumnSizing(2)) # 2 Fixed
         _column.set_fixed_width(args[2])
         _column.set_resizable(True)
         return _column
@@ -2179,7 +2553,7 @@
     Description:
         Class to show a budget Decomposition List
     Constructor:
-        DecompositionList(budget, page, pane_path, path_record=(0,))
+        DecompositionList(budget, page, pane_path, path_record=None)
         budget: budget showed ("base.Budget" object)
         page: weak reference from Page instance which creates this class
         pane_path: tuple that represents the view path in the Page
@@ -2191,15 +2565,15 @@
         +-- DecompositionList
     Atributes:
         budget: Read. Budget to show, base.obra object.
-        widget: Read. Window that contains the table, gtk.ScrolledWindow
+        widget: Read. Window that contains the table, Gtk.ScrolledWindow
         pane_path: Read-Write. Pane page identifier
-        page: Read-Write. weak ref from Page object which creates this class
+        wr_page: Read-Write. weak ref from Page object which creates this class
         active_path_record: Read. Active path record
     Methods:
         runMessage
     """
 
-    def __init__(self, budget, page, pane_path, path_record=None):
+    def __init__(self, budget, wr_page, pane_path, path_record=None):
         """__init__(budget, page, pane_path, path_record=None)
         
         budget: budget showed ("base.Budget" object)
@@ -2208,33 +2582,33 @@
         path_record: the record path that must be showed
         
         self.__budget: budget showed ("base.Budget" object)
-        self.__page: weak reference from Page instance which creates this class
+        self.__wr_page: weak reference from Page instance which creates this class
         self.__pane_path: tuple that represents the path of the List in the Page
         self.__liststore: list model which store the list data
-            (gtk.ListStore object)
+            (Gtk.ListStore object)
         self.__active_path_record: the record path that must be showed
         self.__treeview: widget for displaying decomposition lists
-            (gtk.TreeView)
+            (Gtk.TreeView)
         self.__scrolled_window: widget to contain the treeview object
         self.__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]
+            list of color [even cell, uneven cell]
         self.__chapter_background_colors
-        self.__index_column: Index column (gtk.TreeViewColumn object)
-        self.__code_column: Record code column (gtk.TreeViewColumn)
-        self.__type_column: Record Type column (gtk.TreeViewColumn)
-        self.__unit_column: Unit of measure column (gtk.TreeViewColumn)
+        self.__index_column: Index column (Gtk.TreeViewColumn object)
+        self.__code_column: Record code column (Gtk.TreeViewColumn)
+        self.__type_column: Record Type column (Gtk.TreeViewColumn)
+        self.__unit_column: Unit of measure column (Gtk.TreeViewColumn)
         self.__description_column: record's short description column 
-            (gtk.TreeViewColumn)
-        self.__measure_column: Measure column (gtk.TreeViewColumn)
-        self.__price_column: Price column (gtk.TreeViewColumn)
-        self.__amount_column: Amount column(gtk.TreeViewColumn)
-        self.__end_column: End empty column (gtk.TreeViewColumn)
-        self.__chapter_icon: a gtk.gdk.pixbuf
-        self.__unit_icon: a gtk.gdk.pixbuf
-        self.__material_icon: a gtk.gdk.pixbuf
-        self.__machinery_icon: a gtk.gdk.pixbuf
-        self.__labourforce_icon: a gtk.gdk.pixbuf
+            (Gtk.TreeViewColumn)
+        self.__measure_column: Measure column (Gtk.TreeViewColumn)
+        self.__price_column: Price column (Gtk.TreeViewColumn)
+        self.__amount_column: Amount column(Gtk.TreeViewColumn)
+        self.__end_column: End empty column (Gtk.TreeViewColumn)
+        self.__chapter_icon: a GdkPixbuf.Pixbuf
+        self.__unit_icon: a GdkPixbuf.Pixbuf
+        self.__material_icon: a GdkPixbuf.Pixbuf
+        self.__machinery_icon: a GdkPixbuf.Pixbuf
+        self.__labourforce_icon: a GdkPixbuf.Pixbuf
         self.__treeselection: active selection
         self.__selection_control: state of the selection control (True/False)
         self.__cursor: cursor position in the table
@@ -2250,63 +2624,55 @@
         """
         # TODO: to group all columns in a dicctionary
         # Budget
-        if path_record is None:
-            parh_record = (0,)
         if not isinstance(budget, base.Budget):
-            raise ValueError, _("Argument must be a Budget object")
+            raise ValueError( _("Argument must be a Budget object") )
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = wr_page
         self.__pane_path = pane_path
         # ListStore
-        self.__liststore = gtk.ListStore(object
+        self.__liststore = Gtk.ListStore(object
             #, int, int, str, str, str, str, str,str
             )
         if path_record is None:
-            print _("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 = 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 = Gtk.ScrolledWindow()
+        self.__scrolled_window.set_property("expand", True) # widget expand all space
+        self.__scrolled_window.set_policy(Gtk.PolicyType(1),
+                                        Gtk.PolicyType(1)) # 1 Automatic
         self.__scrolled_window.add(self.__treeview)
         # colors
-        _text_color = gtk.gdk.color_parse(globalVars.color["TEXT"])
+        _text_color = globalVars.color["TEXT"]
         _background_color = [
-            gtk.gdk.color_parse(globalVars.color["UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["EVEN"])]
+            globalVars.color["UNEVEN"],
+            globalVars.color["EVEN"]]
         self.__chapter_background_colors = [
-            gtk.gdk.color_parse(globalVars.color["CHAPTER-UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["CHAPTER-EVEN"])]
+            globalVars.color["CHAPTER-UNEVEN"],
+            globalVars.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),
+             100, _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),
+             52, _text_color, _background_color),
             ("CALCULATEDTEXT", self._showParentRecord,
-            gtk.Label("a"*30).size_request()[0] +10,
-            _text_color, _background_color),
+            245, _text_color, _background_color),
             ("CALCULATED", self._showParentRecord,
-            gtk.Label("a"*10).size_request()[0] +10,
-            _text_color, _background_color),
+            90, _text_color, _background_color),
             ("CALCULATED", self._showParentRecord,
-            gtk.Label("a"*10).size_request()[0] +10,
-            _text_color, _background_color),
+            90, _text_color, _background_color),
             ("CALCULATED", self._showParentRecord,
-            gtk.Label("a"*10).size_request()[0] +10,
-            gtk.gdk.color_parse(globalVars.color["CALCULATED-TEXT"]),
+            90, globalVars.color["CALCULATED-TEXT"],
             _background_color),
             ])
         self.__index_column = self.columns[0]
@@ -2324,19 +2690,18 @@
         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(
+        self.__chapter_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("CHAPTER-ICON"))
-        self.__unit_icon  = gtk.gdk.pixbuf_new_from_file(
+        self.__unit_icon  = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("UNIT-ICON") )
-        self.__material_icon  = gtk.gdk.pixbuf_new_from_file(
+        self.__material_icon  = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("MATERIAL-ICON") )
-        self.__machinery_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__machinery_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("MACHINERY-ICON"))
-        self.__labourforce_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__labourforce_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("LABOURFORCE-ICON"))
-        self.__type_column.get_cell_renderers()[0].set_property("pixbuf",
+        self.__type_column.get_cells()[0].set_property("pixbuf",
             self.__labourforce_icon)
-        
         # Unit column
         self.__treeview.append_column(self.__unit_column)
         # Description column
@@ -2358,12 +2723,13 @@
         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_mode(Gtk.SelectionMode(3)) #  3 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)
+            _tree_path = Gtk.TreePath.new_from_indices((0,))
+            self.__treeview.set_cursor_on_cell(_tree_path ,self.__unit_column,
+                self.__unit_column.get_cells()[0],True)
         self.__treeview.grab_focus()
         self.__cursor = self.__treeview.get_cursor()
         # Show
@@ -2379,9 +2745,9 @@
         Sets the new cursor position in self.__cursor, it is used to avoid 
         unnecessary changes in cursor position.
         """
-        event = gtk.get_current_event()
+        event = Gtk.get_current_event()
         (_cursor_path, _column) = treeview.get_cursor()
-        if event is None or event.type !=  gtk.gdk.BUTTON_RELEASE:
+        if event is None or event.type !=  Gdk.EventType(7): # 7 BUTTON_RELEASE
             if not _column is self.__index_column:
                 self.__cursor = treeview.get_cursor()
 
@@ -2427,9 +2793,11 @@
         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 \
+        if (event.keyval in [Gdk.keyval_from_name("Right"),
+                             Gdk.keyval_from_name("KP_Right")]  \
             and _column == self.columns[-2]) \
-            or (event.keyval == gtk.keysyms.Left \
+            or (event.keyval in [Gdk.keyval_from_name("Left"),
+                             Gdk.keyval_from_name("KP_Left")]  \
             and _column == self.columns[1]):
             return True
         return False
@@ -2450,7 +2818,7 @@
         """
         return False
 
-    def _controlSelection(self, selection):
+    def _controlSelection(self, selection, model, path, path_currently_selected, *data):
         """_controlSelection(selection)
         
         selection: treeselection
@@ -2485,15 +2853,16 @@
         """
         (_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
+        if isinstance(self.__cursor[0],Gtk.TreePath):
+            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):
         """_setColumnsHeaders()
@@ -2511,7 +2880,7 @@
         _unit = _record.unit
         _description = _record.summary
         _price = _budget.getStrPriceFromRecord(self.budget.getActiveTitle(),
-                                               _record)
+                                               _record, _path_record)
         # TODO: round to decimal places in amount
         _amount = float(_stryield) * float(_price)
         if len(_path_record) == 1: # root record
@@ -2520,11 +2889,10 @@
             _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.__code_column.set_title(_("Code") + chr(10) + "[" + _code.decode("utf8") + "]")
+        self.__unit_column.set_title(_("Unit") + chr(10) + "[" + _unit.decode("utf8") + "]")
         self.__description_column.set_title(
-           _("Description") + chr(10) + "[" + _description + "]")
+           _("Description") + chr(10) + "[" + _description.decode("utf8") + "]")
         self.__measure_column.set_title(
             _("Measure") + chr(10) + "[" + _stryield + "]")
         self.__price_column.set_title(
@@ -2541,7 +2909,7 @@
         self.__liststore.clear()
         _budget = self.__budget
         if not _budget.hasPath(path_record):
-            raise ValueError, _("Invalid path")
+            raise ValueError( _("Invalid path") )
         else:
             _parent_code = _budget.getCode(path_record)
             for N,_code in enumerate(_budget.getchildren(_parent_code)):
@@ -2564,34 +2932,35 @@
     def _colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
         """_colorCell(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
+        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.
+        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.
+        -def celldatafunction(column, cell_renderer, tree_model, iter, lcolor)
+        -def celldatamethod(self,column,cell_renderer,tree_model, iter, lcolor)
+        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)
+        _global_row_path =  self.__active_path_record + (_row_path[0],)
         _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])
+            self.__index_column.get_cells()[1].set_property(
+                'cell-background', 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: 
@@ -2613,7 +2982,7 @@
             cell_renderer.set_property('text', _stryield)
         elif column is self.__price_column:
             _price = self.budget.getStrPriceFromRecord(
-                       self.budget.getActiveTitle(), _record)
+                       self.budget.getActiveTitle(), _record, _global_row_path)
             cell_renderer.set_property('text', _price)
         elif column is self.__amount_column:
             _parent_code = self.budget.getCode(self.__active_path_record)
@@ -2639,10 +3008,10 @@
                 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(globalVars.color["ACTIVE"]))
+            cell_renderer.set_property('cell-background',
+                globalVars.color["ACTIVE"])
         else:
-            cell_renderer.set_property('cell-background-gdk',
+            cell_renderer.set_property('cell-background',
                 lcolor[_number % 2])
 
     def _showParentRecord(self, column):
@@ -2656,15 +3025,16 @@
         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])
+            if isinstance(self.__cursor[0],Gtk.TreePath):
+                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()
+            arg = _path_record
+            _page = self.__wr_page()
             _page.propagateMessageFrom("change_active", self.__pane_path, arg)
             self.__treeview.set_cursor(_parent, self.__cursor[1])
             self.__cursor = self.__treeview.get_cursor()
@@ -2702,16 +3072,17 @@
             _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
+            _path_record = self.__active_path_record
+            for _indice  in treeview_path.get_indices():
+                _path_record =  _path_record + (_indice,)
             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()
+                _arg = _path_record
+                _page = self.__wr_page()
                 _page.propagateMessageFrom("change_active", self.__pane_path,
                                        _arg )
 
@@ -2745,7 +3116,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__scrolled_window
 
@@ -2763,19 +3134,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
+    def _getWrPage(self):
         """_getPage()
         
         return the Page
         """
-        return self.__page
-
-    def _setPage(self,page):
-        """_setPage()
-        
-        set the Page
-        """
-        self.__page = page
+        return self.__wr_page
+
+    def _setWrPage(self,wr_page):
+        """_setWrPage()
+        
+        set the wr_Page
+        """
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """_getBudget()
@@ -2795,7 +3166,7 @@
         "Pane configuration list")
     pane_path = property(_getPanePath, _setPanePath, None,
         "path that identifie the item in the page notebook")
-    page = property(_getPage, _setPage, None,
+    wr_page = property(_getWrPage, _setWrPage, None,
         "weak reference from Page instance which creates this class")
     budget =  property(_getBudget, None, None,
         "Budget object")
@@ -2809,7 +3180,7 @@
     Description:
         Class to show a Measure List
     Constructor:
-        Measure(budget, page, pane_path, path_record=(0,)
+        Measure(budget, page, pane_path, path_record=None)
         budget: budget showed ("base.Budget" object)
         page: weak reference from Page instance which creates this class
         pane_path: tuple that represents the path of the List in the Page
@@ -2820,9 +3191,9 @@
         +-- DecompositionList
     Atributes:
         budget: Read. Budget to show, base.obra instance.
-        widget: Read. Window that contains the table, gtk.ScrolledWindow
+        widget: Read. Window that contains the table, Gtk.ScrolledWindow
         pane_path: Read-Write. Pane page identifier
-        page: Read-Write. weak reference from Page instance which creates
+        wr_page: Read-Write. weak reference from Page instance which creates
               this class
         active_path_record: Read. Path of the active record in the budget
     Methods:
@@ -2833,7 +3204,7 @@
         """__init__(budget, page, pane_path, path_record=None)
         
         budget: budget: budget showed ("base.Budget" object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: tuple that represents the path of the List in the Page
         path_record: path of the active record in the budget
         
@@ -2842,29 +3213,29 @@
         self.__pane_path: tuple that represents the path of the List in the Page
         self.__active_path_record: path of the active record in the budget
         self.__liststore: list model which store the list data
-            (gtk.ListStore object)
+            (Gtk.ListStore object)
         self.__treeview:  widget to display decomposition lists
-            (gtk.TreeView)
+            (Gtk.TreeView)
         self.__scrolled_window: widget to scroll the treeview
-            gtk.ScrolledWindow()
+            Gtk.ScrolledWindow()
         self.__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]
-        self.__index_column: Index column (gtk.TreeViewColumn object)
-        self.__linetype_column: Linetype column (gtk.TreeViewColumn object)
-        self.__comment_column: Comment column (gtk.TreeViewColumn)
-        self.__unit_column: Unit column (gtk.TreeViewColumn)
-        self.__length_column: Legth column (gtk.TreeViewColumn)
-        self.__width_column: With column (gtk.TreeViewColumn)
-        self.__height_column: Height column (gtk.TreeViewColumn)
-        self.__formula_column: Formula column (gtk.TreeViewColumn)
-        self.__parcial_column: Parcial column (gtk.TreeViewColumn)
-        self.__subtotal_column: Subtotal column (gtk.TreeViewColumn)
-        self.__end_column: End empty column (gtk.TreeViewColumn
-        self.__calculatedline_icon: gtk.gdk.pixbuf
-        self.__normalline_icon: gtk.gdk.pixbuf
-        self.__parcialline_icon: gtk.gdk.pixbuf
-        self.__acumulatedline_icon: gtk.gdk.pixbuf
+            as a list of color [even cell, uneven cell]
+        self.__index_column: Index column (Gtk.TreeViewColumn object)
+        self.__linetype_column: Linetype column (Gtk.TreeViewColumn object)
+        self.__comment_column: Comment column (Gtk.TreeViewColumn)
+        self.__unit_column: Unit column (Gtk.TreeViewColumn)
+        self.__length_column: Legth column (Gtk.TreeViewColumn)
+        self.__width_column: With column (Gtk.TreeViewColumn)
+        self.__height_column: Height column (Gtk.TreeViewColumn)
+        self.__formula_column: Formula column (Gtk.TreeViewColumn)
+        self.__parcial_column: Parcial column (Gtk.TreeViewColumn)
+        self.__subtotal_column: Subtotal column (Gtk.TreeViewColumn)
+        self.__end_column: End empty column (Gtk.TreeViewColumn
+        self.__calculatedline_icon: GdkPixbuf.Pixbuf
+        self.__normalline_icon: GdkPixbuf.Pixbuf
+        self.__parcialline_icon: GdkPixbuf.Pixbuf
+        self.__acumulatedline_icon: GdkPixbuf.Pixbuf
         self.__treeselection: active selection
         self.__selection_control: state of the selection control (True/False)
         self.__cursor: Situation of the cursor in the table
@@ -2882,65 +3253,57 @@
         if path_record is None:
             path_record = (0,)
         if not isinstance(budget, base.Budget):
-            raise ValueError, _("Argument must be a Budget object")
+            raise ValueError( _("Argument must be a Budget object") )
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = page
         self.__pane_path = pane_path
         if not isinstance(path_record, tuple):
-            print _("Record path must be a tuple")
+            print(_("Record path must be a tuple") )
             path_record = (0,)
         self.__active_path_record = path_record
         # ListStore
-        self.__liststore = gtk.ListStore(object)
+        self.__liststore = Gtk.ListStore(object)
         self._setListstoreValues(self.__active_path_record)
         # Treeview
-        self.__treeview = gtk.TreeView(self.__liststore)
+        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 = Gtk.ScrolledWindow()
+        self.__scrolled_window.set_property("expand", True) # widget expand all space
+        self.__scrolled_window.set_policy(Gtk.PolicyType(1),
+                                          Gtk.PolicyType(1)) # 1 Automatic
         self.__scrolled_window.add(self.__treeview)
         # colors
-        _text_color = gtk.gdk.color_parse(globalVars.color["TEXT"])
-        _calculated_text =gtk.gdk.color_parse(globalVars.color["CALCULATED-TEXT"])
+        _text_color = globalVars.color["TEXT"]
+        _calculated_text = globalVars.color["CALCULATED-TEXT"]
         _background_color = [
-            gtk.gdk.color_parse(globalVars.color["UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["EVEN"])]
+            globalVars.color["UNEVEN"],
+            globalVars.color["EVEN"]]
         self.__chapter_background_colors = [
-            gtk.gdk.color_parse(globalVars.color["CHAPTER-UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["CHAPTER-EVEN"])]
+            globalVars.color["CHAPTER-UNEVEN"],
+            globalVars.color["CHAPTER-EVEN"]]
         super(Measure,self).__init__(
             [("INDEX",self._selectAll,42),
-            ("PIXBUF", self._passMethod,
-             gtk.Label("A"*4).size_request()[0] +10,
+            ("PIXBUF", self._passMethod, 40,
              _text_color, _background_color),
-            ("CALCULATEDTEXT", self._passMethod, 
-             gtk.Label("A"*12).size_request()[0] +10,
+            ("CALCULATEDTEXT", self._passMethod, 128,
              _text_color, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*5).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 55,
              _text_color, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*7).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 70,
              _text_color, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*7).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 70,
              _text_color, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*7).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 70,
              _text_color, _background_color),
-            ("CALCULATEDTEXT", self._passMethod, 
-             gtk.Label("A"*12).size_request()[0] +10,
+            ("CALCULATEDTEXT", self._passMethod, 120,
              _text_color, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*7).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 70,
              _calculated_text, _background_color),
-            ("CALCULATED", self._passMethod, 
-             gtk.Label("A"*7).size_request()[0] +10,
+            ("CALCULATED", self._passMethod, 70,
              _calculated_text, _background_color),
             ])
         # Colums
@@ -2959,13 +3322,13 @@
         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(
+        self.__calculatedline_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("CALCULATEDLINE-ICON"))
-        self.__normalline_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__normalline_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("NORMALLINE-ICON") )
-        self.__parcialline_icon  = gtk.gdk.pixbuf_new_from_file(
+        self.__parcialline_icon  = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("PARCIALLINE-ICON") )
-        self.__acumulatedline_icon = gtk.gdk.pixbuf_new_from_file(
+        self.__acumulatedline_icon = GdkPixbuf.Pixbuf.new_from_file(
             globalVars.getAppPath("ACUMULATEDLINE-ICON"))
         # Comment column
         self.__treeview.append_column(self.__comment_column)
@@ -2993,104 +3356,19 @@
         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_mode(Gtk.SelectionMode(3)) #  3 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)
+        if len(self.__liststore) > 0:
+            _tree_path = Gtk.TreePath.new_from_indices((1,))
+            self.__treeview.set_cursor_on_cell(_tree_path, self.columns[1],
+            self.columns[1].get_cells()[0],True)
         self.__treeview.grab_focus()
         self.__cursor = self.__treeview.get_cursor()
         # Show
         self._setColumnsHeaders()
         self.__scrolled_window.show()
 
-    def _passMethod(self, column):
-        """_passMethod(column)
-        
-        column: the column that is clicked
-        Method connected to "clicked" event of many columns
-        Do nothing
-        """
-        pass
-
-    def _setListstoreValues(self, path_record):
-        """_setListstoreValues(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 ]
-                    _treeiter = self.__liststore.append(_values)
-            else:
-                raise ValueError, utils.mapping(_("measure must be a Measure "\
-                      "object. Type: $1"), (type(_measure),))
-
-    def _setColumnsHeaders(self):
-        """_setColumnsHeaders()
-        
-        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):
-        """_controlSelection(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):
-        """_showMessageRecord(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):
         """_treeviewCursorChanged(treeview)
         
@@ -3100,28 +3378,12 @@
         Sets the new cursor position in self.__cursor, it is used to avoid 
         unnecessary changes in cursor position.
         """
-        event = gtk.get_current_event()
+        event = Gtk.get_current_event()
         (_cursor_path, _column) = treeview.get_cursor()
-        if event is None or event.type !=  gtk.gdk.BUTTON_RELEASE:
+        if event is None or event.type !=  Gdk.EventType(7): # 7 BUTTON_RELEASE
             if not _column is self.__index_column:
                 self.__cursor = treeview.get_cursor()
 
-    def _moveCursor(self, treeview, step, count):
-        """moveCursor(treeview, step, count)
-        
-        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):
         """_treeviewClickedEvent(widget, event)
         
@@ -3164,13 +3426,255 @@
         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 \
+        if (event.keyval in [Gdk.keyval_from_name("Right"),
+                             Gdk.keyval_from_name("KP_Right")] \
             and _column == self.columns[-2]) \
-            or (event.keyval == gtk.keysyms.Left \
+            or (event.keyval in [Gdk.keyval_from_name("Left"),
+                             Gdk.keyval_from_name("KP_Left")] \
             and _column == self.columns[1]):
             return True
         return False
 
+    def _moveCursor(self, treeview, step, count):
+        """moveCursor(treeview, step, count)
+        
+        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, model, path, path_currently_selected, *data):
+        """_controlSelection(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):
+        """_selectAll(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
+        if isinstance(self.__cursor[0],Gtk.TreePath):
+            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):
+        """_setColumnsHeaders()
+        
+        Sets the headers column values
+        """
+        _measure = self.__budget.getMeasure(self.__active_path_record)
+        _DS = self.__budget.getDecimals("DS")
+        _total = _measure.measure
+        _total_str = ("%." + str(abs(_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 _setListstoreValues(self, path_record):
+        """_setListstoreValues(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 ]
+                    _treeiter = self.__liststore.append(_values)
+            else:
+                raise ValueError( utils.mapping(_("measure must be a Measure "\
+                      "object. Type: $1"), (str(type(_measure)),)) )
+
+    def _colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
+        """_colorCell(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 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_cells()[1].set_property(
+                'cell-background', 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(abs(_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(abs(_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(abs(_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(abs(_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(abs(_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 = globalVars.color["SUBTOTAL-PARCIAL"]
+                    _subtotal = _measure_line.parcial_subtotal
+                else: #elif _type == 2:
+                    _color = globalVars.color["SUBTOTAL"]
+                    _subtotal = _measure_line.acumulated_subtotal
+                lcolor = [_color, _color]
+                if isinstance(_subtotal, float):
+                    _DS = self.__budget.getDecimals("DS")
+                    _subtotal= ("%." + str(abs(_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',
+                globalVars.color["ACTIVE"])
+        else:
+            cell_renderer.set_property('cell-background',
+                lcolor[_number % 2])
+
+    def _passMethod(self, column):
+        """_passMethod(column)
+        
+        column: the column that is clicked
+        Method connected to "clicked" event of many columns
+        Do nothing
+        """
+        pass
+
+    def _showMessageRecord(self, record_path):
+        """_showMessageRecord(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 runMessage(self, message, pane_path, arg=None):
         """runMessage(message, pane_path, arg=None)
         
@@ -3191,144 +3695,6 @@
         elif message == "clear":
             self._clear()
 
-    def _selectAll(self, column):
-        """_selectAll(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):
-        """_colorCell(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(
-                               globalVars.color["SUBTOTAL-PARCIAL"])
-                    _subtotal = _measure_line.parcial_subtotal
-                else: #elif _type == 2:
-                    _color = gtk.gdk.color_parse(globalVars.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(globalVars.color["ACTIVE"]))
-        else:
-            cell_renderer.set_property('cell-background-gdk',
-                lcolor[_number % 2])
-
     def _clear(self):
         """_clear()
         
@@ -3339,7 +3705,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__scrolled_window
 
@@ -3357,19 +3723,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
+    def _getWrPage(self):
         """_getPage()
         
         return the Page
         """
-        return self.__page
-
-    def _setPage(self,page):
+        return self.__wr_page
+
+    def _setWrPage(self,wr_page):
         """_setPage()
         
         set the Page
         """
-        self.__page = page
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """_getBudget()
@@ -3389,7 +3755,7 @@
         "Pane configuration list")
     pane_path = property(_getPanePath, _setPanePath, None,
         "Path that identifies the item in the page notebook")
-    page = property(_getPage, _setPage, None,
+    wr_page = property(_getWrPage, _setWrPage, None,
         "Weak reference from Page instance which creates this class")
     budget =  property(_getBudget, None, None,
         "Budget object")
@@ -3403,39 +3769,42 @@
     Description:
         Class to show a description text of a record in a pane
     Constructor:
-        Description(budget, code)
-        budget: base.Budget object
-        code: record code
+        budget: budget showed ("base.Budget" object)
+        page: weak reference from Page instance which creates this class
+        pane_path: tuple that represents the view path in the Page
+        path_record: the record path that must be showed
+        Returns the newly created DecompositionList instance
     Ancestry:
     +-- object
       +-- Description
     Atributes:
-        widget: the main widget (gtk.ScrolledWindow object)
-        pane_path: the tuple that identifies the pane in the notebook page
-        budget: The budget (base.obra objetc)
-        active_path_record: The active path record
+        budget: Read. Budget to show, base.obra object.
+        widget: the main widget (Gtk.ScrolledWindow object)
+        pane_path: Read-Write. Pane page identifier
+        wr_page: Read-Write. weak ref from Page object which creates this class
+        active_path_record: Read. Active path record
     Methods:
         runMessage
     """
-    # TODO: make standar: "DecompositonList and Description"
-
-    def __init__(self, budget, page, pane_path, path_record=None):
+    # TODO: make standard: "DecompositonList and Description"
+
+    def __init__(self, budget, wr_page, pane_path, path_record=None):
         """__init__(budget, page, pane_path, path_record=None)
         
         budget: the budget (base.obra object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: the path position of the description in the page
         path_record: the path of the active record
         
         self.__budget: the budget (base.obra object)
-        self.__page: weak reference from Page instance which creates this class
+        self.__wr_page: weak reference from Page instance which creates this class
         self.__pane_path: the path position of the description in the page
         self.__active_path_recordthe path of the active record
 
         self.__textbuffer: The textbuffer of the textview that contain
             the record text.
-        self.__label: The gtk.label with the title of the pane
-        self.__widget: the main pane widget, a gtk.ScrolledWindow()
+        self.__label: The Gtk.label with the title of the pane
+        self.__widget: the main pane widget, a Gtk.ScrolledWindow()
         
         Creates an shows the scroledwindow that contain the description text
         of the record to be showed in a pane.
@@ -3443,37 +3812,38 @@
         if path_record is None:
             path_record = (0,)
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = wr_page
         self.__pane_path = pane_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)
+        _scrollwindow = Gtk.ScrolledWindow()
+        _scrollwindow.set_property("expand", True) # widget expand all space
+        _scrollwindow.set_policy(Gtk.PolicyType(1),
+                                        Gtk.PolicyType(1)) # 1 Automatic
+        _scrollwindow.set_shadow_type(1) # NONE 0, IN 1, OUT 2, ETCHED_IN 3,ETCHED_OUT 4
+        _textview = Gtk.TextView()
+        _textview.set_wrap_mode(2) # 2 Word
+        _textview.set_hexpand(True)
+        _textview.set_vexpand(True)
         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),)))
+        _vbox = Gtk.Grid()
+        _vbox.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        self.__label = Gtk.Label(utils.mapping(_("Description text of the "\
+                     "record $1"), (str(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.add(self.__label)
+        _vbox.add(_textview)
         _vbox.show()
-        _scrollwindow.add_with_viewport(_vbox)
+        _scrollwindow.add(_vbox)
         _scrollwindow.show()
         self.__widget = _scrollwindow
 
-
     def _setActivePathRecord(self, path_record):
         """_setActivePathRecord(path_record))
         
@@ -3484,7 +3854,7 @@
         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,)))
+            "$1"), (_code.decode("utf8"),)))
         _text = _budget.getRecord(_code).text
         self.__textbuffer.set_text(_text)
 
@@ -3522,7 +3892,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__widget
 
@@ -3540,19 +3910,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
-        """_getPage()
+    def _getWrPage(self):
+        """_getWrPage()
         
         return the weak reference from Page instance
         """
-        return self.__page
-
-    def _setPage(self, page):
-        """_setPage()
+        return self.__wr_page
+
+    def _setWrPage(self, wr_page):
+        """_setWrPage()
         
         set the weak reference from Page instance
         """
-        self.__page = page
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """_getBudget()
@@ -3571,8 +3941,8 @@
     pane_path = property(_getPanePath, _setPanePath, 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,
+        "The main widget (Gtk.ScrolledWindow)")
+    wr_page = property(_getWrPage, _setWrPage, None,
         "Weak reference from Page instance which creates this class")
     budget = property(_getBudget, None, None,
         "Budget object")
@@ -3593,28 +3963,28 @@
     +-- object
       +-- Sheet
     Atributes:
-        widget: the main widget (gtk.VBox() object)
+        budget: The budget (base.obra objetc)
+        widget: the main widget (Gtk.Grid object)
         pane_path: the tuple that identifies the pane in the notebook page
-        page: weak reference from Page instance which creates this class
-        budget: The budget (base.obra objetc)
+        wr_page: weak reference from Page instance which creates this class
         active_path_record: The active path record
     Methods:
         runMessage
     """
 
-    def __init__(self, budget, page, pane_path, path_record=None):
-        """__init__(budget, page, pane_path, path_record=None)
+    def __init__(self, budget, wr_page, pane_path, path_record=None):
+        """__init__(budget, wr_page, pane_path, path_record=None)
         
         budget: the budget (base.obra object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: the path position of the description in the page
         path_record: the path of the active record
         
         self.__budget: the budget (base.obra object)
-        self.__page: weak reference from Page instance which creates this class
+        self.__wr_page: weak reference from Page instance which creates this class
         self.__pane_path: the path position of the description in the page
         self.__active_path_record: the path of the active record
-        self.__label: The gtk.label with the title of the pane
+        self.__label: The Gtk.label with the title of the pane
         self.__field_liststore: the field liststore
         self.__field_treeview: the field treeview
         self.__field_selection: the field selected in field treview
@@ -3623,7 +3993,7 @@
         self.__section_selection: the section selected in the section treeview
         self.__textbuffer: The textbuffer of the textview that contain
             the record text.
-        self.__widget: main widget, a gtk.VBox()
+        self.__widget: main widget, a Gtk.Grid()
         
         Creates an shows the scroledwindow that contain the description text
         of the record to be showed in a pane.
@@ -3631,89 +4001,101 @@
         if path_record is None:
             path_record = (0,)
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = wr_page
         self.__pane_path = pane_path
         self.__active_path_record = path_record
         _budget = budget
-        _main_box = gtk.VBox()
-        self.__label = gtk.Label(utils.mapping(_("Sheet of Conditions of the "\
+        _main_box = Gtk.Grid()
+        _main_box.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        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.set_xalign(0)
+        self.__label.set_yalign(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)
+        _frame = Gtk.Frame()
+        _frame.set_shadow_type(Gtk.ShadowType(1)) # 1 In
+        _frame_box = Gtk.Grid()
+        _frame_box.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        _list_box = Gtk.Grid()
+        _list_box.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
+        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)
+        _field_treeselection.set_mode(Gtk.SelectionMode(1)) #  1 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"))
+        _fieldcode_cell = Gtk.CellRendererText()
+        _field_column = Gtk.TreeViewColumn(_("Field"))
         _field_column.pack_start(_fieldcode_cell, False)
-        _field_cell = gtk.CellRendererText()
+        _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 = Gtk.ScrolledWindow()
+        _field_scrollwindow.set_policy(Gtk.PolicyType(1),
+                                        Gtk.PolicyType(1)) # 1 Automatic
+        _field_scrollwindow.set_property("hexpand", True) # widget expand all space
         _field_scrollwindow.add(self.__field_treeview)
+        _field_scrollwindow.set_size_request(-1, 80)
         _field_scrollwindow.show()
-        self.__section_liststore = gtk.ListStore(str, str)
-        self.__section_treeview = gtk.TreeView(self.__section_liststore)
+        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)
+        _section_treeselection.set_mode(Gtk.SelectionMode(1)) #  1 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"))
+        _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_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 = Gtk.ScrolledWindow()
+        _section_scrollwindow.set_policy(Gtk.PolicyType(1),
+                                        Gtk.PolicyType(1)) # 1 Automatic
+        _section_scrollwindow.set_property("hexpand", True) # widget expand all space
+        _section_scrollwindow.set_size_request(-1, 90)
         _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.add(_field_scrollwindow)
+        _list_box.add(_section_scrollwindow)
         _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)
+        _scrollwindow = Gtk.ScrolledWindow()
+        _scrollwindow.set_policy(Gtk.PolicyType(1),
+                                        Gtk.PolicyType(1)) # 1 Automatic
+        _scrollwindow.set_property("expand", True) # widget expand all space
+        _textview = Gtk.TextView()
+        _textview.set_wrap_mode(2) # 2 Word
+        _textview.set_property("expand", True) # widget expand all space
         self.__textbuffer = _textview.get_buffer()
         _textview.show()
-        _hbox = gtk.HBox()
-        _hbox.pack_start(_textview, True, True, 5)
+        _hbox = Gtk.Grid()
+        _hbox.set_orientation(Gtk.Orientation(0)) # 0 Horizontal
+        _hbox.add(_textview)
         _hbox.show()
-        _frame_box.pack_start(self.__label, False, False, 5)
-        _frame_box.pack_start(_list_box, False, False, 5)
+        _frame_box.add(self.__label)
+        _frame_box.add(_list_box)
         _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)
+        _main_box.add(_frame)
+        _vbox = Gtk.Grid()
+        _vbox.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+        _vbox.add(_hbox)
         _vbox.show()
-        _main_box.pack_start(_scrollwindow, True, True, 5)
+        _main_box.add(_scrollwindow)
         _main_box.show()
-        _scrollwindow.add_with_viewport(_vbox)
+        _scrollwindow.add(_vbox)
         _scrollwindow.show()
         self.__widget = _main_box
         self._setFields()
@@ -3768,10 +4150,13 @@
         else:
             self.__textbuffer.set_text("")
 
-    def _field_controlSelection(self, selection):
-        """_controlSelection(selection)
+    def _field_controlSelection(self, selection, model, path,
+                                path_currently_selected, *data):
+        """_controlSelection(selection, model, path,
+                             path_currently_selected, *data)
         
         selection: treeselection
+        path: selected path
         
         Method connected to set_selection_function() in field treeview
         This method is called before any node is selected or unselected,
@@ -3783,15 +4168,18 @@
         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)
+        _treeiter = self.__field_liststore.get_iter(path)
         self.__field_selection = self.__field_liststore.get_value(_treeiter, 0)
         self._setSection()
         return True
 
-    def _section_controlSelection(self, selection):
-        """_section_controlSelection(selection)
+    def _section_controlSelection(self, selection, model, path,
+                                  path_currently_selected, *data):
+        """_section_controlSelection(selection, model, 
+                                     path, path_currently_selected, *data)
         
         selection: treeselection
+        path: selected path
         
         Method connected to set_selection_function() in sector treeview
         This method is called before any node is selected or unselected,
@@ -3803,7 +4191,7 @@
         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)
+        _treeiter = self.__section_liststore.get_iter(path)
         self.__section_selection = self.__section_liststore.get_value(_treeiter, 0)
         self._setText()
         return True
@@ -3851,7 +4239,7 @@
         
         Deletes all the instance atributes
         """
-        del self.__page
+        del self.__wr_page
         del self.__widget
         del self.__pane_path
         del self.__budget
@@ -3870,7 +4258,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__widget
 
@@ -3888,19 +4276,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
-        """_getPage()
+    def _getWrPage(self):
+        """_getWrPage()
         
         return the weak reference from Page instance
         """
-        return self.__page
-
-    def _setPage(self, page):
-        """_setPage()
+        return self.__wr_page
+
+    def _setWrPage(self, wr_page):
+        """_setWrPage()
         
         set the weak reference from Page instance
         """
-        self.__page = page
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """_getBudget()
@@ -3920,7 +4308,7 @@
         "Path that identifie the item in the page notebook")
     widget = property(_getWidget, None, None,
                       "Lista de configuracion de vistas")
-    page = property(_getPage, _setPage, None,
+    wr_page = property(_getWrPage, _setWrPage, None,
         "Weak reference from Page instance which creates this class")
     budget = property(_getBudget, None, None,
         "Budget object")
@@ -3934,38 +4322,39 @@
     Description:
         Class to show the file icons of a record in a pane
     Constructor:
-        Description(budget, page, pane_path, path_record=(0,))
+        Description(budget, page, pane_path, path_record=None)
         budget: the budget (base.obra object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: the path position of the description in the page
         path_record: the path of the active record
     Ancestry:
     +-- object
       +-- FileView
     Atributes:
-        widget: the main widget (gtk.ScrolledWindow object)
+        widget: the main widget (Gtk.ScrolledWindow object)
         pane_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
+        budget: The budget (base.obra object)
+        active_path_record: Read.
+        wr_page: Read-Write. weak reference from Page instance which creates this class
     Methods:
         runMessage
     """
 
-    def __init__(self, budget, page, pane_path, path_record=None):
+    def __init__(self, budget, wr_page, pane_path, path_record=None):
         """__init__(budget, page, pane_path, path_record=None)
         
         budget: the budget (base.obra object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: the path position of the description in the page
         path_record: the path of the active record
         
         self.__budget: the budget (base.obra object)
-        self.__page: weak reference from Page instance which creates this class
+        self.__wr_page: weak reference from Page instance which creates this class
         self.__pane_path: the path position of the description in the page
         self.__active_path_record: the path of the active record
         self.__active_code: the code of the active record
         self.__icon_box: the box that contains the icon
-        self.__widget: main widget, a gtk.ScrolledWindow
+        self.__widget: main widget, a Gtk.ScrolledWindow
         
         Creates an shows the scroledwindow that contain icon files
         of the record to be showed in a pane.
@@ -3973,7 +4362,7 @@
         if path_record is None:
             path_record = (0,)
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = wr_page
         self.__pane_path = pane_path
         self.__active_path_record = path_record
         self.__active_code = budget.getCode(self.__active_path_record)
@@ -3982,11 +4371,10 @@
                     self.__active_path_record))
                     
         self.__icon_box = self._getIconBox(_record)
-        _scrollwindow = gtk.ScrolledWindow()
-        _scrollwindow.set_policy(gtk.POLICY_ALWAYS,
-                                 gtk.POLICY_NEVER)
+        _scrollwindow = Gtk.ScrolledWindow()
+        _scrollwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
         self.__icon_box.show()
-        _scrollwindow.add_with_viewport(self.__icon_box)
+        _scrollwindow.add(self.__icon_box)
         _scrollwindow.show()
         self.__widget = _scrollwindow
 
@@ -3997,75 +4385,138 @@
         
         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)
+        _flowbox = Gtk.FlowBox()
+        _flowbox.set_valign(Gtk.Align.START)
+        _flowbox.set_max_children_per_line(30)
+        _flowbox.set_selection_mode(Gtk.SelectionMode.NONE)
+        _flowbox.set_property("expand", True) # widget expand all space
         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(
-                                    globalVars.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)
+            _box = Gtk.Grid()
+            _box.set_orientation(Gtk.Orientation(1)) # 1 Vertical
+            if os.path.exists(_file_path):
+                _filetype = utils.getFiletype(_file_path)
+                _event_box = Gtk.LinkButton()
+                _file_icon = Gtk.Image()
+                # "image", "wmf", "dxf", "pdf" , "video",
+                # "office-document", "office-presentation", "office-spreadsheet",
+                # "html", "rtf", "txt", ""
+                # icon
+                if _filetype in ["image", "wmf"]:
+                    try:
+                        _image_pixbuf = GdkPixbuf.Pixbuf.new_from_file(_file_path)
+                        _image_pixbuf = _image_pixbuf.scale_simple(64, 64,
+                                        GdkPixbuf.InterpType(2)) # 2 BILINEAR
+                    except:
+                        _image_pixbuf = GdkPixbuf.Pixbuf.new_from_file(
+                                        globalVars.getAppPath("IMAGE-ICON"))
+                        _image_pixbuf = _image_pixbuf.scale_simple(64, 64,
+                                        GdkPixbuf.InterpType(2)) # 2 BILINEAR
+                    _file_icon.set_from_pixbuf(_image_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       _filetype, _file_path)
+                elif _filetype == "dxf":
+                    _dxf_pixbuf = GdkPixbuf.Pixbuf.new_from_file(
+                                        globalVars.getAppPath("DXF-ICON"))
+                    _dxf_pixbuf = _dxf_pixbuf.scale_simple(64, 64,
+                                  GdkPixbuf.InterpType(2)) # 2 BILINEAR
+                    _file_icon.set_from_pixbuf(_dxf_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "dxf", _file_path)
+                elif _filetype == "pdf":
+                    _pdf_pixbuf = GdkPixbuf.Pixbuf.new_from_file(
+                                        globalVars.getAppPath("PDF-ICON"))
+                    _pdf_pixbuf = _pdf_pixbuf.scale_simple(64, 64,
+                                  GdkPixbuf.InterpType(2)) # 2 BILINEAR
+                    _file_icon.set_from_pixbuf(_pdf_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "pdf", _file_path)
+                elif _filetype == "video":
+                    _video_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                    "video-x-generic", 64, 0)
+                    _file_icon.set_from_pixbuf(_video_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "video", _file_path)
+                elif _filetype == "office-document":
+                    _document_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                       "x-office-document", 64, 0)
+                    _file_icon.set_from_pixbuf(_document_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "office-document", _file_path)
+                elif _filetype == "office-presentation":
+                    _presentation_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                           "x-office-presentation", 64, 0)
+                    _file_icon.set_from_pixbuf(_presentation_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "office-presentation", _file_path)
+                elif _filetype == "office-spreadsheet":
+                    _spreadsheet_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                          "x-office-spreadsheet", 64, 0)
+                    _file_icon.set_from_pixbuf(_spreadsheet_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "office-spreadsheet", _file_path)
+                elif _filetype == "html":
+                    _html_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                   "text-html", 64, 0)
+                    _file_icon.set_from_pixbuf(_html_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "html", _file_path)
+                elif _filetype == "rtf":
+                    _rtf_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                  "text-x-generic", 64, 0)
+                    _file_icon.set_from_pixbuf(_rtf_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "rtf", _file_path)
+                elif _filetype == "txt":
+                    _txt_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                  "text-x-generic", 64, 0)
+                    _file_icon.set_from_pixbuf(_txt_pixbuf)
+                    _event_box.connect("activate-link", self._launchFile,
+                                       "txt", _file_path)
+                else:
+                    _missing_pixbuf = Gtk.IconTheme.get_default().load_icon(
+                                      "image-missing", 64, 0)
+                    _file_icon.set_from_pixbuf(_missing_pixbuf)
+                    # Is secure open no detected filetype?
+                    #_event_box.connect("activate-link", self._launchFile,
+                    #                   "", _file_path)
+                    _event_box = Gtk.EventBox()
+                _event_box.add(_file_icon)
+                _event_box.props.margin = 5 
+                _box.add(_event_box)
+                _file_icon.show()
                 _event_box.show()
-                
-            elif _filetype == "dxf":
-                _event_box = gtk.EventBox()
-                _dxf_icon = gtk.Image()
-                _dxf_pixbuf = gtk.gdk.pixbuf_new_from_file(
-                                    globalVars.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
+            _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)
+            _label_event_box.props.margin = 5
+            _box.add(_label_event_box)
             _box.show()
-            _hbox.pack_start(_box, False, False, 5)
-        _hbox.show()
-        _frame.add(_hbox)
-        return _frame
-
-    def _launchFile(self, widget, event, kind, file_path):
+            _box.props.margin = 5
+            _flowbox.add(_box)
+        _flowbox.show()
+        #_scrolled.show()
+        return _flowbox
+
+    def _launchFile(self, widget, kind, file_path):
         """_launchFile(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)
+        Launch the file if a click emit the signal.
+        Method connected to "activate-link" signal in images botton link
+        Return True: stops propagate event and avoids to raise an error
+        when opening an empty uri.
+        """
+        openwith.launch_file(kind, file_path)
+        return True
 
     def _setActivePathRecord(self, path_record):
         """_setActivePathRecord(path_record))
@@ -4078,7 +4529,7 @@
         _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 = self._getIconBox(_record)
         self.__icon_box.show()
         self.__widget.add_with_viewport(self.__icon_box)
 
@@ -4114,7 +4565,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__widget
 
@@ -4132,19 +4583,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
-        """_getPage()
+    def _getWrPage(self):
+        """_getWrPage()
         
         return the weak reference from Page instance
         """
-        return self.__page
-
-    def _setPage(self, page):
+        return self.__wr_page
+
+    def _setWrPage(self, wr_page):
         """setPage()
         
         set the weak reference from Page instance
         """
-        self.__page = page
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """getBudget()
@@ -4163,8 +4614,8 @@
     pane_path = property(_getPanePath, _setPanePath, 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,
+        "The main widget (Gtk.ScrolledWindow)")
+    wr_page = property(_getWrPage, _setWrPage, None,
         "Weak reference from Page instance which creates this class")
     budget = property(_getBudget, None, None,
         "Budget object")
@@ -4173,14 +4624,14 @@
 
 
 class CompanyView(object):
-    """gui.CompanyView:
+    """gui:CompanyView:
     
     Description:
         Class to show the company records of a budget
     Constructor:
-        CompanyView(budget, page, pane_path, path_record=(0,))
+        CompanyView(budget, wr_page, pane_path, path_record=(None)
         budget: budget showed ("base.Budget" object)
-        page: weak reference from Page instance which creates this class
+        wr_page: weak reference from Page instance which creates this class
         pane_path: tuple that represents the path of the List in the Page
         path_record: path of the active record in the budget
     Ancestry:
@@ -4188,92 +4639,94 @@
       +-- CompanyView
     Atributes:
         active_path_record: Read. Path of the active record in the budget
-        widget: Read. Window that contains the main widget, a gtk.HPaned
+        widget: Read. Window that contains the main widget, a Gtk.Paned
         pane_path: Read-Write. Pane page identifier
-        page: Read-Write. weak reference from Page instance which creates this class
+        wr_page: Read-Write. weak reference from Page instance which creates this class
         budget: Read. Budget to show, base.budget instance.
     Methods:
         runMessage
     """
 
-    def __init__(self, budget, page, pane_path, path_record=None):
-        """__init__(budget, page, pane_path, path_record=None)
-        
-        budget: budget: budget showed ("base.Budget" object)
-        page: weak reference from Page instance which creates this class
-        pane_path: tuple that represents the path of the List in the Page
+    def __init__(self, budget, wr_page, pane_path, path_record=None):
+        """__init__(budget, wr_page, pane_path, path_record=None)
+        
+        budget: budget showed ("base.Budget" object)
+        wr_page: weak reference from Page instance which creates this class
+        pane_path: tuple that represents the path of the pane in the Page
         path_record: path of the active record in the budget
         
-        self.__selection:
+        self.__selection: "company" or "office" selected treeview
         self.__budget: budget: budget showed ("base.Budget" object)
-        self.__page: weak reference from Page instance which creates this class
+        self.__wr_page: weak reference from Page instance which creates this class
         self.__pane_path: tuple that represents the path of the List in the Page
         self.__active_path_record: path of the active record in the budget
-        self.__widget: main widget, a gtk.HPaned
+        self.__widget: main widget, a Gtk.Paned
         self.__treestore: to store companys data
         self.__option_View: OptionView object
         
-        Creates an shows the scroledwindow that contain the company data.
+        Creates an shows the widgets with the company data.
         """
         if path_record is None:
             path_record = (0,)
         self.__selection = None
         # Seting init args
         if not isinstance(budget, base.Budget):
-            raise ValueError, _("Argument must be a Budget object")
+            raise ValueError( _("Argument must be a Budget object") )
         self.__budget = budget
-        self.__page = page
+        self.__wr_page = wr_page
         self.__pane_path = pane_path
         self.__active_path_record = path_record
         # main widget
-        self.__widget = gtk.HPaned()
+        self.__widget = Gtk.Paned.new(Gtk.Orientation(0)) # 0 Horizontal
         self.__widget.set_position(230)
         # TreeStore
-        self.__treestore = gtk.TreeStore(str, str)
+        self.__treestore = Gtk.TreeStore(str, str)
         self._setTreeStoreValues()
         # Select Treeview
-        _select_treeview = gtk.TreeView(self.__treestore)
+        _select_treeview = Gtk.TreeView(self.__treestore)
         _select_treeview.set_enable_search(False)
         _select_treeview.set_reorderable(False)
         _select_treeview.set_headers_visible(False)
         _select_treeview.show()
         # Scrolled_window
-        _scrolled_window = gtk.ScrolledWindow()
-        _scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
-            gtk.POLICY_AUTOMATIC)
+        _scrolled_window = Gtk.ScrolledWindow()
+        _scrolled_window.set_property("expand", True) # widget expand all space
+        _scrolled_window.set_policy(Gtk.PolicyType(1),
+                                    Gtk.PolicyType(1)) # 1 Automatic
         _scrolled_window.add(_select_treeview)
         # colors
-        _text_color = gtk.gdk.color_parse(globalVars.color["TEXT"])
+        _text_color = globalVars.color["TEXT"]
         _background_color = [
-            gtk.gdk.color_parse(globalVars.color["UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["EVEN"])]
-        _code_column = gtk.TreeViewColumn()
+            globalVars.color["UNEVEN"],
+            globalVars.color["EVEN"]]
+        _code_column = Gtk.TreeViewColumn()
         _code_column.set_clickable(True)
         _code_column.set_fixed_width(200)
-        _code_cell = gtk.CellRendererText()
-        _code_cell.set_property('foreground-gdk', _text_color)
+        _code_cell = Gtk.CellRendererText()
+        _code_cell.set_property('foreground', _text_color)
         _code_column.pack_start(_code_cell, True)
         _code_column.add_attribute(_code_cell, 'text', 0)
-        _summary_cell = gtk.CellRendererText()
-        _summary_cell.set_property('foreground-gdk', _text_color)
+        _summary_cell = Gtk.CellRendererText()
+        _summary_cell.set_property('foreground', _text_color)
         _code_column.pack_start(_summary_cell, True)
         _code_column.add_attribute(_summary_cell, 'text', 1)
         # Index column
         _select_treeview.append_column(_code_column)
         # control selection
         _treeselection = _select_treeview.get_selection()
-        _treeselection.set_mode(gtk.SELECTION_SINGLE)
+        _treeselection.set_mode(Gtk.SelectionMode(1)) #  1 SINGLE
         _treeselection.set_select_function(self._controlSelection)
         # Show
         _scrolled_window.show()
         # Option View
-        self.__option_View = OptionView("")
+        self.__option_View = OptionView()
+        # Add to main widget
+        self.__widget.add1(_scrolled_window)
+        self.__widget.add2(self.__option_View.widget)
         # Selection
         _select_treeview.set_cursor((0,), None, False)
         _select_treeview.grab_focus()
-        #
-        self.__widget.add1(_scrolled_window)
-        self.__widget.add2(self.__option_View.widget)
+        # Show
         self.__widget.show()
 
     def _setOptions(self, type):
@@ -4298,7 +4751,7 @@
                         ]
             self.__option_View.options = _options
         elif type == "office":
-            _options = [("type", _("Type"), "string",
+            _options = [("officeType", _("Type"), "string",
                          _("""Type of Office:
                            C: Central office
                            D: Local office
@@ -4319,7 +4772,7 @@
                        ]
             self.__option_View.options = _options
         else:
-            print _("Unknow Option Type")
+            print(_("Unknow Option Type") )
 
     def _setTreeStoreValues(self):
         """_setTreeStoreValues()
@@ -4338,9 +4791,8 @@
                 _values = [_office.officeType, _office.subname]
                 self.__treestore.append(_treeiter, _values)
 
-
-    def _controlSelection(self, selection):
-        """_controlSelection(selection)
+    def _controlSelection(self, selection, model, path, path_currently_selected, *data):
+        """_controlSelection(selection, model, path, path_currently_selected, *data)
         
         selection: selection
         
@@ -4353,24 +4805,23 @@
         
         The selection changes the company/office in the option treeview
         """
-        if len(selection) == 1:
+        if len(path) == 1:
             # The selection is a company
-            _company_key = self.__treestore[selection][0]
+            _company_key = self.__treestore[path][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_key = self.__treestore[path[:1]][0]
             _company = self.__budget.getCompany(_company_key)
             _selection = "office"
-            _office = _company.offices[selection[1]]
+            _office = _company.offices[path[1]]
             _values = _office.values
         if not self.__selection == _selection:
             self.__selection = _selection
-            self.options = _selection
+            self._setOptions(_selection)
         self.__option_View.values = _values
-
         return True
 
     def _showMessageRecord(self, record_path):
@@ -4406,24 +4857,24 @@
     def _colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
         """_colorCell(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
+        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.
+        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.
+        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.
@@ -4432,13 +4883,13 @@
         _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])
+            self.__index_column.get_cells()[1].set_property(
+                'cell-background', lcolor[_number % 2])
         if self.__treeview.get_cursor() == (_row_path,column):
-            cell_renderer.set_property('cell-background-gdk',
-                gtk.gdk.color_parse(globalVars.color["ACTIVE"]))
+            cell_renderer.set_property('cell-background',
+                globalVars.color["ACTIVE"])
         else:
-            cell_renderer.set_property('cell-background-gdk',
+            cell_renderer.set_property('cell-background',
                 lcolor[_number % 2])
 
     def _clear(self):
@@ -4451,7 +4902,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__widget
 
@@ -4469,19 +4920,19 @@
         """
         self.__pane_path = pane_path
 
-    def _getPage(self):
-        """_getPage()
+    def _getWrPage(self):
+        """_getWrPage()
         
         return the Page
         """
-        return self.__page
-
-    def _setPage(self,page):
-        """_setPage()
+        return self.__wr_page
+
+    def _setWrPage(self,wr_page):
+        """_setWrPage()
         
         set the Page
         """
-        self.__page = page
+        self.__wr_page = wr_page
 
     def _getBudget(self):
         """_getBudget()
@@ -4503,7 +4954,7 @@
         "main widget")
     pane_path = property(_getPanePath, _setPanePath, None,
         "Path that identifies the item in the page notebook")
-    page = property(_getPage, _setPage, None,
+    wr_page = property(_getWrPage, _setWrPage, None,
         "Weak reference from Page instance which creates this class")
     budget =  property(_getBudget, None, None,
         "Budget object")
@@ -4516,9 +4967,7 @@
         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)
+        OptionView()
     Ancestry:
     +-- object
       +-- OptionView
@@ -4527,22 +4976,23 @@
         options: Write
         values: Write
     Methods:
+        No public Methods
     """
 
-    def __init__(self, option_list):
-        """__init__(option_list)
+    def __init__(self):
+        """__init__()
         
         self.__option_dict:
             {"option key" : ["option name", "value", "option type",
                               "option_description"]}
         self.__option_list: option keys list
         self.__option_types: valid option types list
-        self.__liststore: gtk.ListStore
-        self.__treeview: gtk.TreeView
+        self.__liststore: Gtk.ListStore
+        self.__treeview: Gtk.TreeView
         self.__option_column: option column
         self.__value_column: value column
         self.__type_column: type column
-        self.__description_label: gtk.Label
+        self.__description_label: Gtk.Label
         self.__widget: Main widget
         
         Creates an shows the widget that contain the option data.
@@ -4555,33 +5005,35 @@
                              "color" : _("Color"),
                              "list" : _("List")}
         # ListStore
-        self.__liststore = gtk.ListStore(str, str, str, str, str)
+        self.__liststore = Gtk.ListStore(str, str, str, str, str)
         # Treeview
-        self.__treeview = gtk.TreeView(self.__liststore)
+        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()
+        _vbox = Gtk.Grid()
+        _vbox.set_orientation(Gtk.Orientation(1)) # 1 Vertical
         # Scrolled_window
-        _scrolled_window = gtk.ScrolledWindow()
-        _scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
-                                        gtk.POLICY_AUTOMATIC)
+        _scrolled_window = Gtk.ScrolledWindow()
+        _scrolled_window.set_property("expand", True) # widget expand all space
+        _scrolled_window.set_policy(Gtk.PolicyType(1),
+                                 Gtk.PolicyType(1)) # 1 Automatic
         _scrolled_window.add(self.__treeview)
         _scrolled_window.show()
-        _vbox.pack_start(_scrolled_window)
+        _vbox.add(_scrolled_window)
         # colors
-        _text_color = gtk.gdk.color_parse(globalVars.color["TEXT"])
+        _text_color = globalVars.color["TEXT"]
         _background_color = [
-            gtk.gdk.color_parse(globalVars.color["UNEVEN"]),
-            gtk.gdk.color_parse(globalVars.color["EVEN"])]
+            globalVars.color["UNEVEN"],
+            globalVars.color["EVEN"]]
         # Option Column
-        self.__option_column = gtk.TreeViewColumn()
-        self.__option_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.__option_column = Gtk.TreeViewColumn()
+        self.__option_column.set_sizing(Gtk.TreeViewColumnSizing(2)) # 2 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)
+        _option_cell = Gtk.CellRendererText()
+        _option_cell.set_property('foreground', _text_color)
         self.__option_column.pack_start(_option_cell, True)
         self.__option_column.set_cell_data_func(_option_cell, self._colorCell,
                                                 _background_color)
@@ -4589,12 +5041,12 @@
         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 = Gtk.TreeViewColumn()
+        self.__value_column.set_sizing(Gtk.TreeViewColumnSizing(2)) # 2 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)
+        _value_cell = Gtk.CellRendererText()
+        _value_cell.set_property('foreground', _text_color)
         self.__value_column.pack_start(_value_cell, True)
         self.__value_column.set_cell_data_func(_value_cell, self._colorCell,
                                                _background_color)
@@ -4602,23 +5054,23 @@
         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 = Gtk.TreeViewColumn()
+        self.__type_column.set_sizing(Gtk.TreeViewColumnSizing(2)) # 2 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)
+        _type_cell = Gtk.CellRendererText()
+        _type_cell.set_property('foreground', _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 = Gtk.TreeViewColumn()
         _end_column.set_clickable(False)
-        _end_cell = gtk.CellRendererText()
-        _end_cell.set_property('cell-background-gdk',
-            gtk.gdk.color_parse(globalVars.color["UNEVEN"]))
+        _end_cell = Gtk.CellRendererText()
+        _end_cell.set_property('cell-background',
+                               globalVars.color["UNEVEN"])
         _end_column.pack_start(_end_cell, True)
         self.__treeview.append_column(_end_column)
         # Connect
@@ -4627,31 +5079,30 @@
             self._treeviewClickedEvent)
         # control selection
         _treeselection = self.__treeview.get_selection()
-        _treeselection.set_mode(gtk.SELECTION_MULTIPLE)
+        _treeselection.set_mode(Gtk.SelectionMode(3)) #  3 MULTIPLE
         _treeselection.set_select_function(self._controlSelection)
         # labels
-        _frame = gtk.Frame()
-        _frame.set_shadow_type(gtk.SHADOW_OUT)
-        _vbox2 = gtk.VBox()
+        _frame = Gtk.Frame()
+        _frame.set_shadow_type(2) # NONE 0, IN 1, OUT 2, ETCHED_IN 3,ETCHED_OUT 4
+        _vbox2 = Gtk.Grid()
+        _vbox2.set_orientation(Gtk.Orientation(1)) # 1 Vertical
         _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 = Gtk.Label()
+        _label.set_xalign(0)
+        _label.set_yalign(0)
+        _label.set_margin_start(12)
         _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  = Gtk.Label()
+        self.__description_label.set_xalign(0)
+        self.__description_label.set_yalign(0)
+        self.__description_label.set_margin_start(24)
         self.__description_label.show()
-        _alignement2.add(self.__description_label)
-        _alignement2.show()
-        _vbox2.pack_start(_alignement, False)
-        _vbox2.pack_start(_alignement2, False)
+        _vbox2.add(_label)
+        _vbox2.add(self.__description_label)
         _vbox2.show()
         _frame.show()
-        _vbox.pack_start(_frame, False)
+        _vbox.add(_frame)
         # Show
         self.__treeview.show()
         _vbox.show()
@@ -4669,13 +5120,15 @@
         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
+        value column or press 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 \
+        if (event.keyval in [Gdk.keyval_from_name("Right"),
+                             Gdk.keyval_from_name("KP_Right")]  \
            and _column == self.__value_column) \
-           or (event.keyval == gtk.keysyms.Left \
+           or (event.keyval in [Gdk.keyval_from_name("Left"),
+                             Gdk.keyval_from_name("KP_Left")]  \
            and _column == self.__value_column):
             return True
         else:
@@ -4711,8 +5164,10 @@
                 return True
         return True
 
-    def _controlSelection(self, selection):
-        """_controlSelection(selection)
+    def _controlSelection(self, selection, model, path, path_currently_selected,
+                          *data):
+        """_controlSelection(selection, model, path, path_currently_selected,
+                             *data)
         
         selection: treeselection
         
@@ -4730,24 +5185,24 @@
     def _colorCell(self, column, cell_renderer, tree_model, iter, lcolor):
         """_colorCell(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
+        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 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.
+        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.
+        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.
@@ -4755,10 +5210,10 @@
         _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(globalVars.color["ACTIVE"]))
+            cell_renderer.set_property('cell-background',
+                globalVars.color["ACTIVE"])
         else:
-            cell_renderer.set_property('cell-background-gdk',
+            cell_renderer.set_property('cell-background',
                 lcolor[_number % 2])
         if column is self.__type_column:
             _type = self.__option_types[tree_model[_row_path][3]]
@@ -4788,7 +5243,9 @@
                     _option_name = _option[1]
                     _option_type = _option[2]
                     _option_description = _option[3]
-                    if isinstance(_option_key, str) and \
+                    #-# str and unicode
+                    if (isinstance(_option_key, str) or \
+                        isinstance(_option_key, unicode)) and \
                        (isinstance(_option_name, str) or\
                        isinstance(_option_name, unicode))and \
                        _option_type in self.__option_types.keys():
@@ -4798,11 +5255,11 @@
                             _option_type, _option_description]
                         self.__option_list.append(_option_key)
                     else:
-                        print _("Option values must be strings")
+                        print(_("Option values must be strings") )
                 else:
-                    print _("Option must be a tuple with 4 items")
+                    print(_("Option must be a tuple with 4 items") )
         else:
-            print _("Option list must be a list")
+            print(_("Option list must be a list") )
 
     def _setValues(self, values):
         """_setValues(values)
@@ -4822,12 +5279,12 @@
                             self.__liststore.set_value(_iter, 2, _value)
                             self.__option_dict[_option][1] = _value
                         else:
-                            print _("Icorrect type, must be boolean")
+                            print(_("Icorrect type, must be boolean") )
                     elif _type == "integer":
                         try:
                             _value = int(_value)
                         except ValueError:
-                            print _("Icorrect type, must be integer")
+                            print(_("Icorrect type, must be integer") )
                         else:
                             _num = self.__option_list.index(_option)
                             _iter = self.__liststore.get_iter((_num,))
@@ -4840,7 +5297,7 @@
                             self.__liststore.set_value(_iter, 2, _value)
                             self.__option_dict[_option][1] = _value
                         else:
-                            print _("Icorrect type, must be string")
+                            print(_("Icorrect type, must be string") )
                     elif _type == "list":
                         if isinstance(_value, list):
                             _num = self.__option_list.index(_option)
@@ -4853,27 +5310,27 @@
                             self.__liststore.set_value(_iter, 2, _str_value)
                             self.__option_dict[_option][1] = _value
                         else:
-                            print _("Icorrect type, must be list")
+                            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")
+                            if Gdk.RGBA().parse(_value):
+                                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")
+                        print(_("Type must be boolean, integer, string or "\
+                                "color") )
                 else:
-                    print _("Value must be in the option dict")
+                    print( _("Value must be in the option dict") )
+                    print(_option, _value)
         else:
-            print _("Values must be a dict")
-        self.__treeview.set_cursor((0),self.__value_column, False)
+            print( _("Values must be a dict") )
+        self.__treeview.set_cursor(Gtk.TreePath.new_from_indices((0,)),
+                                   self.__value_column, False)
         self.__treeview.grab_focus()
         (_cursor_path, _column) = self.__treeview.get_cursor()
         _description = self.__liststore[_cursor_path][4]
@@ -4882,7 +5339,7 @@
     def _getWidget(self):
         """_getWidget()
         
-        return the main widget (gtk.ScrolledWindow)
+        return the main widget (Gtk.ScrolledWindow)
         """
         return self.__widget
 
@@ -4892,3 +5349,4 @@
         "values")
     options = property(None, _setOptions, None,
         "options")
+
--- a/Gtk/importFiebdc.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/Gtk/importFiebdc.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File importFiebdc.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -20,344 +20,17 @@
 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Modules
-import sys
-import time
-import os.path
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import threading
-gobject.threads_init()
 
-# pyArq-Presupuestos Modules
-from Generic import utils
-from Generic import globalVars
-#from Generic import durusdatabase
-import gui
-
-class FileSelectionWindow(object):
-    """importFiebdc.FileSelectionWindow:
-    
-    Description:
-        Class to show the selection file window
-    Constructor:
-        importFiebdc.FileSelectionWindow(mainWindow, readFileMethod, budget,
-            filename, cancelMethod, filetype)
-    Ancestry:
-    +-- object
-      +-- FileSelectionWindow
-    Atributes:
-        "__mainWindow": gui.MainWindow object
-        "__readFileMethod": Method to read the selected file
-        "__budget": Budget object
-        "__filename": "file"
-        "__filetype": "budget" ,"database" or "durus"
-        "__cancelMethod": Method to cancel the read method
-        "__file": The selected file
-        "__window": The selection file window
-    Methods:
-        __init__(self, mainWindow, readFileMethod, budget
-                 arg_List, cancelMethod)
-        _launchProgressWindow(self, _file)
-        _openFile(self, filename)
-    """
-
-    def __init__(self, mainWindow, readFileMethod, budget, filename,
-                 cancelMethod, filetype):
-        """def __init__(self, mainWindow, readFileMethod, budget,
-                        filename, cancelMethod, filetype)
-        
-        mainWindow: gui.MainWindow object
-        readFileMethod: Method to read the selected file
-        budget: base.Budget object
-        filename: "file"
-        cancelMethod: Method to cancel the read method
-        fileytpe: "budget", "database" or "durus".
-        Sets the init atributes, creates the file selection window
-        Connects the events:
-            * clicked ok button: _openFile
-            * clicked cancel button: destroy window
-            * destroy event: _destroy
-        """
-        # TODO: Add file filter
-        self.__mainWindow = mainWindow
-        self.__readFileMethod = readFileMethod
-        self.__budget = budget
-        self.__filename = filename
-        self.__filetype = filetype
-        self.__cancelMethod = cancelMethod
-        self.__file = None
-        self.__window = gtk.FileChooserDialog(title=_("Open File"),
-            action=gtk.FILE_CHOOSER_ACTION_OPEN,
-            buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,
-                     gtk.STOCK_OPEN,gtk.RESPONSE_OK))
-        self.__window.set_default_response(gtk.RESPONSE_OK)
-        #if self.__filetype == "budget" or self.__filetype == "database":
-        self.__window.set_current_folder(globalVars.getHomePath("BUDGET"))
-        #else: # "durus"
-        #    self.__window.set_current_folder(
-        #        globalVars.getHomePath("DURUS-DATABASE"))
-        if self.__window.run() == gtk.RESPONSE_OK:
-            self._openFile(self.__window.get_filename())
-        self.__window.destroy()
-
-    def _launchProgressWindow(self, file):
-        """def _launchProgressWindow(self, file)
-        
-        Launch the progress window
-        """
-        self.__filename = file
-        _emptyPage = gui.EmptyPage(self.__mainWindow, self.__readFileMethod,
-                                   self.__budget, self.__filename,
-                                   self.__cancelMethod, self.__filetype)
-        self.__mainWindow.appendEmptyPage(_emptyPage)
-        _emptyPage.run()
-
-    def _openFile(self, filename):
-        """def _openFile(self, filename)
-        
-        filename: the filename to open
-        If the selected file has a bc3 extension 
-        _launchProgressWindow is called
-        """
-        _file = filename
-        if sys.getfilesystemencoding():
-            _file = _file.decode(sys.getfilesystemencoding())
-            #-#
-            _file = _file.encode("utf-8")
-            #-#
-        self.__file = _file
-        _filename = os.path.basename(self.__file)
-        _filename_ext = _filename.split(".")[-1]
-        if (self.__filetype == "budget" or self.__filetype == "database") and \
-            _filename_ext != "bc3" and _filename_ext != "BC3":
-            print _("The file must have 'bc3' extension")
-        #elif self.__filetype == "durus" and _filename_ext != "durus":
-        #    print _("The file must have 'durus' extension")
-        else:
-            self.__window.destroy()
-            # TODO: the file exits? is it not binary?, can it be readed?
-            self._launchProgressWindow(self.__file)
-
-
-class ProgressWindow(object):
-    """importFiebdc.ProgressWindow:
-    
-    Description:
-        Class to show the progress window and launch a thread  to read
-        the database file
-    Constructor:
-        importFiebdc.ProgressWindow(mainWindow, readFileMethod, budget,
-                 filename, cancelMethod)
-    Ancestry:
-    +-- object
-      +-- ProgressWindow
-    Atributes:
-        "__mainWindow":
-        "__readFileMethod":
-        "__budget":
-        "__filename":
-        "__cancelMethod":
-        "__children": Thread instance
-        "__cancel": list with boolean values
-        "__window": progress window widget
-        "__progress_bar": probres bar widget
-        "__label": label widget
-    Methods:
-        closeWindow(self)
-        __init__(self, mainWindow, readFileMethod, budget
-                 filename, cancelMethod)
-        closeWindow(self)
-        main(self)
-        _autoClose(self)
-        _updateLabel(self, _time)
-        _updateProgressBar(self)
-        _launchTimeout(self)
-        _launchChildren(self, mainWindow, readFileMethod, budget
-                    filename, cancelMethod)
-        _cancelChildren(self,widget=None)
-        _destroy(self, widget)
-        _delete_event(self, widget, event)
+# python 2/3 compatibility
+from __future__ import absolute_import, division, print_function, unicode_literals
 
-    """
-    def __init__(self, mainWindow, readFileMethod, budget,
-                 filename, cancelMethod):
-        """def __init__(self, mainWindow, readFileMethod, budget
-                        filename, cancelMethod)
-        
-        mainWindow: gui.MainWindow object
-        readFileMethod: Method to read the selected file
-        budget: base.Budget object
-        filenamer: "file"
-        cancelMethod: Method to cancel the read method
-        Sets the init atributes, creates the progress window
-        Connects the events:
-            * destroy signal: self._destroy
-            * delete_event signal: self._delete_event
-            * clicked cancel button: self._cancelChildren
-        """
-        self.__mainWindow = mainWindow
-        self.__readFileMethod = readFileMethod
-        self.__filename = filename
-        self.__budget = budget
-        self.__cancelMethod = cancelMethod
-        self.__children = None
-        self.__cancel = [False, False]
-        self.__window = gtk.Window()
-        self.__window.set_title(_("Loading file ..."))
-        self.__window.connect("destroy", self._destroy)
-        self.__window.connect("delete_event", self._delete_event)
-        _Vbox1 = gtk.VBox(False, 0)
-        self.__window.add(_Vbox1)
-        _align = gtk.Alignment(0.5, 0.5, 0, 0)
-        _align.show()
-        _Vbox1.pack_start(_align, False, False, 5)
-        self.__progress_bar = gtk.ProgressBar()
-        self.__progress_bar.show()
-        _align.add(self.__progress_bar)
-        self.__label = gtk.Label()
-        self.__label.set_text(_("Time: 0s"))
-        self.__label.show()
-        _Vbox1.add(self.__label)
-        self.__throbber = gtk.Image()
-        self.__throbber.set_from_file(globalVars.getAppPath("THROBBER-ICON"))
-        _Vbox1.add(self.__throbber)
-        self.__throbber.show()
-        self.__animation = gtk.gdk.PixbufAnimation(globalVars.getAppPath("THROBBER-GIF"))
-        _pixbuf = self.__throbber.get_pixbuf()
-        self.__throbber.set_from_animation(self.__animation)
-        _Hbox1 = gtk.HBox(False, 0)
-        _Vbox1.add(_Hbox1)
-        _button1 = gtk.Button(_("Cancel"))
-        _button1.connect("clicked", self._cancelChildren)
-        _button1.show()
-        _Hbox1.pack_start(_button1, True, True, 0)
-        _Hbox1.show()
-        _Vbox1.show()
-        
-    def main(self):
-        """def main(self)
-        
-        Launch the thread
-        Launch the timeouts
-        Shows window and starts the GTK+ event processing loop.
-        """
-
-        self._launchChildren()
-        self._launchTimeout()
-        self.__window.show()
-        gtk.main()
-
-    def closeWindow(self):
-        """def closeWindow(self)
-        
-        Sets the __children atribute to None
-        This causes that the timiouts is ended and then the window is
-        closed.
-        This method is called from thread when it is finished
-        """
-        self.__children = None
+# gui
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+from gi.repository import GLib
 
-    def _launchTimeout(self):
-        """def _launchTimeout(self)
-        
-        Launch the timeouts: 
-            1- update progress bar
-            2- update time labal
-            3- If the other timetouts are stoped the window is closed
-        """
-        gobject.timeout_add(100, 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.pulse()
-            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
-            self.__label.set_text(utils.mapping(_("Time: $1"),
-                ("%.0f" %_time,)))
-            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 ]:
-            self.__window.destroy()
-            return False
-        else:
-            return True
-
-    def _launchChildren(self):
-        """_launchChildren(self)
-        
-        Launch the thread to read the file
-        """
-        if self.__children is None:
-            self.__children =  Thread(self, self.__mainWindow,
-                self.__readFileMethod, self.__budget, self.__filename,
-                self.__cancelMethod)
-            self.__children.start()
-
-    def _cancelChildren(self,widget=None):
-        """_cancelChildren(self,widget=None)
-        
-        Method connected to "clicked" singal of cancel button
-        Stops the thread and close the window
-        """
-        if self.__children:
-            self.__children.cancel()
-        self.__window.destroy()
-
-    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 window widget
-        This signal is emitted when a user press the close titlebar button.
-        Stops the thread if exits.
-        Returns True so the signal "destroy" is emitted.
-        """
-        if self.__children:
-            self._cancelChildren()
-        return True
-
-    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()
+import threading
 
 class Thread(threading.Thread):
     """importFiebdc.Thread:
@@ -377,16 +50,14 @@
         "__budget
         "__filename": "file"
         "__cancelMethod": Method to cancel the read method
-        "__filetype": "budget", "database" or "durus"
+        "__filetype": "budget" or "database"
         "__cancel": Boolean value, True: the thread is stoped
     Methods:
-        __init__(self, page, mainWindow,
-                 readFileMethod, arg_tuple, cancelMethod)
-        run(self)
-        cancel(self)
-        isCanceled(self)
+        run()
+        cancel()
+        isCanceled()
+        clear()
     """
-
     def __init__(self, page, mainWindow, readFileMethod, budget,
                  filename, cancelMethod, filetype):
         """def __init__(page, mainWindow, readFileMethod, budget,
@@ -398,7 +69,8 @@
         budget: base.Budget object
         filename: "file"
         cancelMethod: Method to cancel the read method
-        filetype: "budget", "database" or "durus"
+        filetype: "budget" or "database"
+        
         Sets the instance atributes.
         """
         super(Thread, self).__init__()
@@ -412,37 +84,19 @@
         self.__cancel = False
 
     def run(self):
-        """run(self)
+        """run()
         
         
         """
-        _budget = self.__readFileMethod(self.__budget, self.__filename,
-                                        self.__page)
-        if _budget is None:
-            self.__page.threadCanceled()
+        self.__readFileMethod(self.__budget, self.__filename, self.__page)
+        if not self.__page.endSuccessfully:
+            GLib.idle_add(self.__page.threadCanceled)
         else:
-            _mainWindow = self.__mainWindow
-            self.__page.threadFinishedSignal(_budget)
-            #if self.__filetype == "database":
-            #    self.saveDurusDatabase()
+            GLib.idle_add(self.__page.threadFinishedSignal, self.__budget)
         self.clear()
-        
-    #def saveDurusDatabase(self):
-    #    _path = globalVars.getHomePath("DURUS-DATABASE")
-    #    _file_whit_path_bc3 = self.__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(self.__budget)
-    #    _durus_file.close()
-    #    print utils.mapping(_("Saving time: $1 seconds"),
-    #          (("%.2f" %(time.time()-_time) ),))
 
     def cancel(self):
-        """cancel(self)
+        """cancel()
         
         Sets the "__cancel" atribute to True and call "__cancelMethod" to stop
         read the file
@@ -451,7 +105,7 @@
         self.__cancelMethod()
 
     def isCanceled(self):
-        """isCanceled(self)
+        """isCanceled()
         
         Return True if the thread has been canceled
         """
@@ -464,4 +118,4 @@
         del self.__budget
         del self.__filename
         del self.__cancelMethod
-        del self.__cancel
+        #del self.__cancel
--- a/__init__.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/__init__.py	Thu May 02 16:31:17 2019 +0200
@@ -7,4 +7,4 @@
 #
 # this file is needed for Python's import mechanism
 #
-
+name = "pyArq-Presupuestos"
--- a/images/close.svg	Tue Sep 30 17:16:50 2014 +0200
+++ b/images/close.svg	Thu May 02 16:31:17 2019 +0200
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- Created with Inkscape (http://www.inkscape.org/) -->
+
 <svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
@@ -12,9 +13,10 @@
    height="16px"
    id="svg1872"
    sodipodi:version="0.32"
-   inkscape:version="0.45.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
    sodipodi:docname="close.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.1">
   <defs
      id="defs1874" />
   <sodipodi:namedview
@@ -35,16 +37,19 @@
      inkscape:guide-bbox="true"
      inkscape:window-width="1013"
      inkscape:window-height="592"
-     inkscape:window-x="401"
-     inkscape:window-y="350">
+     inkscape:window-x="235"
+     inkscape:window-y="35"
+     inkscape:window-maximized="0">
     <sodipodi:guide
        orientation="vertical"
        position="24.957426"
-       id="guide3733" />
+       id="guide3733"
+       inkscape:locked="false" />
     <sodipodi:guide
        orientation="vertical"
        position="13.469802"
-       id="guide3735" />
+       id="guide3735"
+       inkscape:locked="false" />
   </sodipodi:namedview>
   <metadata
      id="metadata1877">
@@ -54,6 +59,7 @@
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
       </cc:Work>
     </rdf:RDF>
   </metadata>
Binary file images/throbber.gif has changed
Binary file images/throbber.png has changed
--- a/images/throbber.svg	Tue Sep 30 17:16:50 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="16px"
-   height="16px"
-   id="svg2816"
-   version="1.1"
-   inkscape:version="0.47 r22583"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90"
-   sodipodi:docname="throbber.svg">
-  <defs
-     id="defs2818">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 8 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="16 : 8 : 1"
-       inkscape:persp3d-origin="8 : 5.3333333 : 1"
-       id="perspective2824" />
-    <inkscape:perspective
-       id="perspective3618"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4392"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4392-7"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4392-6"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4392-73"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-    <inkscape:perspective
-       id="perspective4392-2"
-       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
-       inkscape:vp_z="1 : 0.5 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 0.5 : 1"
-       sodipodi:type="inkscape:persp3d" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="10.859375"
-     inkscape:cx="3.0797409"
-     inkscape:cy="6.1241029"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:window-width="1280"
-     inkscape:window-height="950"
-     inkscape:window-x="0"
-     inkscape:window-y="25"
-     inkscape:window-maximized="1">
-    <inkscape:grid
-       type="xygrid"
-       id="grid4380" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata2821">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer">
-    <path
-       sodipodi:type="arc"
-       style="fill:#000000;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(1.9676014,0,0,1.9394929,-6.8695653,-0.34617159)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382"
-       width="16"
-       height="16"
-       x="-2.8393347e-07"
-       y="-2.3374795e-07"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#4d4d4d;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606-0"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(0.9838007,-1.7039928,1.6796501,0.96974643,-6.6627793,16.704335)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382-8"
-       width="16"
-       height="16"
-       x="-18.928202"
-       y="-5.0717974"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90"
-       transform="matrix(-0.5,-0.8660254,0.8660254,-0.5,0,0)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#808080;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606-9"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(-0.9838007,-1.7039928,1.6796501,-0.96974644,8.2067862,25.050507)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382-86"
-       width="16"
-       height="16"
-       x="-18.928204"
-       y="-5.0717978"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90"
-       transform="matrix(-0.5,-0.8660254,0.8660254,-0.5,0,0)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#b3b3b3;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606-3"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(-1.9676014,0,0,-1.9394929,22.869564,16.346171)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382-9"
-       width="16"
-       height="16"
-       x="-16"
-       y="-16"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90"
-       transform="scale(-1,-1)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#cccccc;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606-07"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(-0.9838007,1.7039928,-1.6796501,-0.96974643,22.662777,-0.7043353)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382-4"
-       width="16"
-       height="16"
-       x="2.9282029"
-       y="-10.928203"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90"
-       transform="matrix(0.5,0.8660254,-0.8660254,0.5,0,0)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#e6e6e6;stroke-width:0.99599999;stroke-miterlimit:4;stroke-dasharray:none"
-       id="path3606-5"
-       sodipodi:cx="7.5572038"
-       sodipodi:cy="1.7252818"
-       sodipodi:rx="1.016466"
-       sodipodi:ry="1.5467961"
-       d="m 8.5736698,1.7252818 a 1.016466,1.5467961 0 1 1 -2.0329321,0 1.016466,1.5467961 0 1 1 2.0329321,0 z"
-       transform="matrix(0.9838007,1.7039928,-1.6796501,0.96974644,7.7932129,-9.0505065)"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:none;stroke:none"
-       id="rect4382-5"
-       width="16"
-       height="16"
-       x="2.9282029"
-       y="-10.928203"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90"
-       transform="matrix(0.5,0.8660254,-0.8660254,0.5,0,0)" />
-  </g>
-</svg>
Binary file mo/es/LC_MESSAGES/pyArq-Presupuestos.mo has changed
--- a/mo/pyArq-Presupuestos.es.po	Tue Sep 30 17:16:50 2014 +0200
+++ b/mo/pyArq-Presupuestos.es.po	Thu May 02 16:31:17 2019 +0200
@@ -1,19 +1,19 @@
 # pyArq-Presupuestos translatión to Spanish.
-# Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez
+# Copyright (C) 2019 Miguel Ángel Bárcena Rodríguez
 # This file is distributed under the same license as the pyArq-Presupuestos
 # package.
 # Changes:
 # - Initial translation:
-# Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>, 2010-2013
+# Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>, 2010-2019
 #
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pyArq-Presupuestos 0.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-11-02 18:58+0100\n"
-"PO-Revision-Date: 2013-11-02 18:58+0100\n"
-"Last-Translator: Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es"
+"POT-Creation-Date: 2019-04-27 10:53+0200\n"
+"PO-Revision-Date: 2019-04-27 10:53+0200\n"
+"Last-Translator: Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso."
 "es>\n"
 "Language-Team: Spanish\n"
 "Language: Spannish\n"
@@ -21,309 +21,336 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../Generic/base.py:359
+#: ../Generic/base.py:283
+msgid ""
+"\n"
+"A free program of measurements, budgets and control of construction sites.\n"
+"In beta development, still there is not a fully functional version.\n"
+msgstr ""
+"\n"
+"Un programa libre de mediciones, presupuestos y control de obras de "
+"construcción.\n"
+"En estado beta de desarrollo, aún no hay una versión plenamente funcional.\n"
+
+#: ../Generic/base.py:288
+msgid ""
+"\n"
+"Usage:\n"
+"    pyarqPresupuestos [file]...\n"
+"\n"
+"Help Options:\n"
+"    -h, --help     Show this help\n"
+msgstr ""
+"\n"
+"Uso:\n"
+"    pyarqPresupuestos [fichero]...\n"
+"\n"
+"Opciones de ayuda:\n"
+"    -h, --help     Muestra esta ayuda\n"
+
+#: ../Generic/base.py:421
 msgid "Invalid code: $1"
 msgstr "Código no válido: $1"
 
-#: ../Generic/base.py:374
+#: ../Generic/base.py:436
 msgid "Synonyms ($1) must be a list, code: $2"
 msgstr "«Synonyms» ($1) debe ser una lista, código: $2"
 
-#: ../Generic/base.py:378
+#: ../Generic/base.py:440
 msgid "Invalid Code in synomyms list ($1) code: $2"
 msgstr "Código no válido es la lista de sinónimos ($1) código: $2"
 
-#: ../Generic/base.py:409
+#: ../Generic/base.py:471
 msgid "Unit ($1) must be a string: $2"
 msgstr "«Unit» ($1) debe ser una cadena: $2"
 
-#: ../Generic/base.py:423
+#: ../Generic/base.py:485
 msgid "Summary ($1) must be a string: $1"
 msgstr "«Summary» ($1) debe ser una cadena: $1"
 
-#: ../Generic/base.py:440
+#: ../Generic/base.py:502
 msgid "Prices ($1) must be a list: $2"
 msgstr "«Prices» ($1) debe ser una lista: $2"
 
-#: ../Generic/base.py:461
+#: ../Generic/base.py:523
 msgid "Price ($1) must be a list with two items: $2"
 msgstr "«Price» ($1) debe ser una lista con dos elementos: $2"
 
-#: ../Generic/base.py:466
+#: ../Generic/base.py:528
 msgid "Price must be a float number: $1"
 msgstr "Precio debe ser un número de coma flotante: $1"
 
-#: ../Generic/base.py:476
+#: ../Generic/base.py:538
 #, python-format
 msgid "The record do not have this Price. Code: %s"
 msgstr "El registro no tiene ese precio. Código: %s"
 
-#: ../Generic/base.py:482
+#: ../Generic/base.py:544
 msgid "The record do not have this Price"
 msgstr "El registro no tiene ese precio"
 
-#: ../Generic/base.py:497
+#: ../Generic/base.py:559
 msgid "Parents ($1) must be a list: $2"
 msgstr "«Parents» ($1) debe ser una lista: $2"
 
-#: ../Generic/base.py:501 ../Generic/base.py:513
+#: ../Generic/base.py:563 ../Generic/base.py:575
 msgid "Invalid parent code ($1) in the record: $2"
 msgstr "Código padre no válido ($1) en el registro: $2"
 
-#: ../Generic/base.py:529
+#: ../Generic/base.py:591
 msgid "children ($1) must be a list, record: $2"
 msgstr "«children» ($1) debe ser una lista, registro: $2"
 
-#: ../Generic/base.py:533
+#: ../Generic/base.py:595
 msgid "child ($1) must be a Decomposition object, record: $2"
 msgstr "«child» ($1) debe ser una objeto «Decomposition», registro $2"
 
-#: ../Generic/base.py:581
+#: ../Generic/base.py:649
 msgid "Text ($1) must be a string, record: $2"
 msgstr "«Text» ($1) debe ser una cadena, registro: $2"
 
-#: ../Generic/base.py:594
+#: ../Generic/base.py:662
 msgid "sheet must be a Sheet instance"
 msgstr "«sheet» debe ser una instancia de Sheet"
 
-#: ../Generic/base.py:607
+#: ../Generic/base.py:674
 msgid "files must be a list: $1"
 msgstr "«files» debe ser una lista: $1"
 
-#: ../Generic/base.py:618 ../Generic/base.py:633
+#: ../Generic/base.py:685 ../Generic/base.py:699
 msgid "Incorrect path"
 msgstr "Ruta incorrecta"
 
-#: ../Generic/base.py:623
+#: ../Generic/base.py:690
 msgid "file must be a list or a File object: $1"
 msgstr "«file» debe ser una lista o un objeto «File: $1"
 
-#: ../Generic/base.py:652
+#: ../Generic/base.py:718
 msgid "labels must be a list"
 msgstr "«labels» debe ser una lista"
 
-#: ../Generic/base.py:658
+#: ../Generic/base.py:724
 msgid "label must be a string"
 msgstr "«label» debe ser una cadena de texto."
 
-#: ../Generic/base.py:667
+#: ../Generic/base.py:733
 msgid "Label must be a string"
 msgstr "«Label» debe ser una cadena de texto."
 
-#: ../Generic/base.py:907
+#: ../Generic/base.py:981
 msgid "Position must be a integer"
 msgstr "«Position» debe ser un número entero"
 
-#: ../Generic/base.py:917
+#: ../Generic/base.py:995
 msgid "BudgetMeasures atribute must be a list"
 msgstr "El atributo «BudgetMeasures» debe ser una lista"
 
-#: ../Generic/base.py:920
+#: ../Generic/base.py:998
 msgid "BudgetMeasures item must be a Measure "
 msgstr "El atributo «BudgetMeasures» debe ser un objeto «Measure»"
 
-#: ../Generic/base.py:927
+#: ../Generic/base.py:1007
 msgid "Certification atribute must be a list or None"
 msgstr "El atributo «Certification» debe ser una lista o «None»"
 
-#: ../Generic/base.py:933
+#: ../Generic/base.py:1015
 msgid "Real cost atribute must be a list or None"
 msgstr "El atributo «Real cost» debe ser una lista o «None»"
 
-#: ../Generic/base.py:939
+#: ../Generic/base.py:1023
 msgid "Cost goals atribute must be a list or None"
 msgstr "El atributo «Cost goals» debe ser una lista o «None»"
 
-#: ../Generic/base.py:945
+#: ../Generic/base.py:1031
 msgid "Cost Planned atribute must be a list or None"
 msgstr "El atributo «Cost Planned» debe ser una lista o «None»"
 
-#: ../Generic/base.py:1036
+#: ../Generic/base.py:1124
 msgid "Measure must be a float number. Type: $1"
 msgstr "«Measure» debe ser un número de coma flotante. Tipo: $1"
 
-#: ../Generic/base.py:1047
+#: ../Generic/base.py:1136
 msgid "Lines must be a list"
 msgstr "«Lines» debe ser una lista"
 
-#: ../Generic/base.py:1050
+#: ../Generic/base.py:1139
 msgid "Line must be a MeasureLine objetc"
 msgstr "«Line» debe ser un objeto «MeasureLine»"
 
-#: ../Generic/base.py:1058
+#: ../Generic/base.py:1150
 msgid "Factor must be a float number |$1|"
 msgstr "«Factor» debe ser un número de coma flotante |$1|"
 
-#: ../Generic/base.py:1070
+#: ../Generic/base.py:1162
 msgid "Yield must be a float number"
 msgstr "«Yield» debe ser un número de coma flotante"
 
-#: ../Generic/base.py:1081
+#: ../Generic/base.py:1173
 msgid "Fixed must be boolean object"
 msgstr "«Fixed» debe ser un objeto booleano"
 
-#: ../Generic/base.py:1151
+#: ../Generic/base.py:1243
 msgid "Type must be M or A. Type: $1"
 msgstr "«Type» debe ser M o A. Type: $1"
 
-#: ../Generic/base.py:1283
+#: ../Generic/base.py:1387
 msgid " Parcial Subtotal must be a float number. Parcial: $1"
 msgstr "«Parcial Subtotal» debe ser un número de coma flotante. Parcial: $1"
 
-#: ../Generic/base.py:1290
+#: ../Generic/base.py:1395
 msgid " Acumulated Subtotal must be a float number. Parcial: $1"
 msgstr " «Acumulate Subtotal» debe ser un número de coma flotante. Parcial: $1"
 
-#: ../Generic/base.py:1325
+#: ../Generic/base.py:1431
 msgid "Invalid measure line type ($1)"
 msgstr "Tipo de línea de medición no válido ($1)"
 
-#: ../Generic/base.py:1330
+#: ../Generic/base.py:1437
 msgid "Measure Comment must be a string ($1)"
 msgstr "El comentario de la medición debe ser una cadena ($1)"
 
-#: ../Generic/base.py:1336
+#: ../Generic/base.py:1444
 msgid "Invalid Measure Units ($1)"
 msgstr "Unidades de medición no válidas ($1)"
 
-#: ../Generic/base.py:1348
+#: ../Generic/base.py:1457
 msgid "Invalid Measure length ($1)"
 msgstr "Longitud de medición no válida ($1)"
 
-#: ../Generic/base.py:1360
+#: ../Generic/base.py:1470
 msgid "Invalid Measure Width ($1)"
 msgstr "Anchura de medición no válida ($1)"
 
-#: ../Generic/base.py:1372
+#: ../Generic/base.py:1483
 msgid "Invalid Measure Height ($1)"
 msgstr "Altura de medición no válida ($1)"
 
-#: ../Generic/base.py:1383
+#: ../Generic/base.py:1495
 msgid "Formula must be a string ($1)"
 msgstr "«Formula» debe ser una cadena de texto ($1)"
 
-#: ../Generic/base.py:1386
+#: ../Generic/base.py:1498
 msgid "There is invalid charactersin formula ($1)"
 msgstr "Hay caracteres no válidos en la fórmula ($1)"
 
-#: ../Generic/base.py:1451 ../Generic/base.py:2443
+#: ../Generic/base.py:1564 ../Generic/base.py:2618
 msgid "'a' value must be a float number"
 msgstr "El valor «a» debe ser un número de coma flotante"
 
-#: ../Generic/base.py:1455 ../Generic/base.py:2447
+#: ../Generic/base.py:1568 ../Generic/base.py:2622
 msgid "'b' value must be a float number"
 msgstr "El valor «b» debe ser un número de coma flotante"
 
-#: ../Generic/base.py:1459 ../Generic/base.py:2451
+#: ../Generic/base.py:1572 ../Generic/base.py:2626
 msgid "'c' value must be a float number"
 msgstr "El valor «c» debe ser un número de coma flotante"
 
-#: ../Generic/base.py:1463 ../Generic/base.py:2455
+#: ../Generic/base.py:1576 ../Generic/base.py:2630
 msgid "'d' value must be a float number"
 msgstr "El valor «d» debe ser un número de coma flotante"
 
-#: ../Generic/base.py:1491 ../Generic/base.py:2483
+#: ../Generic/base.py:1604 ../Generic/base.py:2658
 msgid "Invalid formula"
 msgstr "Fórmula no válida"
 
-#: ../Generic/base.py:1741
+#: ../Generic/base.py:1858
 msgid "sheet_dict must be a dictionay"
 msgstr "«sheet_dict» debe ser un diccionario."
 
-#: ../Generic/base.py:1758 ../Generic/base.py:1764
+#: ../Generic/base.py:1879 ../Generic/base.py:1886
 msgid "sheet field must be a string"
 msgstr "«sheet field» debe ser una cadena de texto"
 
-#: ../Generic/base.py:1760
+#: ../Generic/base.py:1881
 msgid "section_dict must be a dictionary"
 msgstr "«section_dict» debe ser un dicionario"
 
-#: ../Generic/base.py:1766
+#: ../Generic/base.py:1888
 msgid "sheet section must be a string"
 msgstr "La seccion del pliego debe ser una cadena de texto"
 
-#: ../Generic/base.py:1768
+#: ../Generic/base.py:1890
 msgid "sheet paragraph must be a string"
 msgstr "«sheet paragraph» debe ser una cadena de texto"
 
-#: ../Generic/base.py:2006
+#: ../Generic/base.py:2177
 msgid "Owner must be a string"
 msgstr "«Owner» debe ser una cadena de texto."
 
-#: ../Generic/base.py:2022
+#: ../Generic/base.py:2193
 msgid "Invalid Date: $1"
 msgstr "Fecha no válida: $1"
 
-#: ../Generic/base.py:2033
+#: ../Generic/base.py:2204
 msgid "Comment must be a string"
 msgstr "«Comment» debe ser una cadena"
 
-#: ../Generic/base.py:2049
+#: ../Generic/base.py:2220
 msgid "Budget type must be 1, 2, 3 or 4."
 msgstr "El tipo de presupuesto debe ser 1, 2, 3 o 4"
 
-#: ../Generic/base.py:2061
+#: ../Generic/base.py:2232
 msgid "Certificate order must be a integer."
 msgstr "«Certificate order» debe ser un número entero"
 
-#: ../Generic/base.py:2076
+#: ../Generic/base.py:2247
 msgid "Budget certificate Date must be a valid Date."
 msgstr "«Budget certificate Date» debe ser una fecha válida"
 
-#: ../Generic/base.py:2090
+#: ../Generic/base.py:2261
 msgid "Invalid title list format"
 msgstr "Formato de lista de rótulos no válida"
 
-#: ../Generic/base.py:2119
+#: ../Generic/base.py:2290
 msgid "Invalid Index Title"
 msgstr "Índice de rótulo no válido"
 
-#: ../Generic/base.py:2154
+#: ../Generic/base.py:2327
 msgid "Decimal Key error"
 msgstr "Clave de decimales errónea"
 
-#: ../Generic/base.py:2190
+#: ../Generic/base.py:2365
 msgid "Invalid Percentage key"
 msgstr "Clave de porcentajes no válida"
 
-#: ../Generic/base.py:2313
+#: ../Generic/base.py:2488
 msgid "Invalid parent code: $1"
 msgstr "Código del padre inválido: $1"
 
-#: ../Generic/base.py:2316
+#: ../Generic/base.py:2491
 msgid "Invalid child code: $1 $2"
 msgstr "Código de hijo inválido: $1 $2"
 
-#: ../Generic/base.py:2319
+#: ../Generic/base.py:2494
 msgid "Invalid position in measure $1, in code $2"
 msgstr "Posición no válida en medición $1, en código $2"
 
-#: ../Generic/base.py:2327
+#: ../Generic/base.py:2502
 msgid ""
 "Circular Decomposition, parent code: $1, child code: $2, repeated code: $3"
 msgstr ""
 "Descomposición circular, código padre: $1, código hijo: $2, código repetido: "
 "$3"
 
-#: ../Generic/base.py:2352
+#: ../Generic/base.py:2527
 msgid ""
 "No-estructured measure or empty position. Parent Code: $1, Child code: $2, "
 "Position: $3"
 msgstr ""
-"Mediciones no estructuradas o posicion vácia. Código padre: $1, Código hijo: $2, "
-"Posición: $3"
+"Mediciones no estructuradas o posicion vácia. Código padre: $1, Código hijo: "
+"$2, Posición: $3"
 
-#: ../Generic/base.py:2356
+#: ../Generic/base.py:2531
 msgid ""
 "No-estructured measure or empty position. Repeated child in unspecified "
 "position. It is impossible to determine the position. New child is added in "
 "the decomposition. Parent code: $1, Child code: $2, Position: $3"
 msgstr ""
 "Mediciones no estructuradas o posicion vácia. Hijo repetido sin especificar "
-"posición. Es imposible determinar la posición. Se añade un nuevo hijo en "
-"la descomposicón. Código padre: $1, Código hijo: $2, Posición: $3"
+"posición. Es imposible determinar la posición. Se añade un nuevo hijo en la "
+"descomposicón. Código padre: $1, Código hijo: $2, Posición: $3"
 
-#: ../Generic/base.py:2396 ../Generic/base.py:2408
+#: ../Generic/base.py:2571 ../Generic/base.py:2583
 msgid ""
 "Error: Invalid child position in decomposition. Parent code: $1 Child code: "
 "$2 Position: $3"
@@ -331,84 +358,84 @@
 "Error: Posición del hijo no válida en descomposición. Código padre: $1 "
 "Código hijo: $2 Posición: $3"
 
-#: ../Generic/base.py:2402
+#: ../Generic/base.py:2577
 msgid "Error: Empty child code. Parent code: $1 Position: $2"
 msgstr "Error: Código hijo vacío. Código padre: $1 Posición: $2"
 
-#: ../Generic/base.py:2494
+#: ../Generic/base.py:2669
 msgid "Invalid code"
 msgstr "Código no válido"
 
-#: ../Generic/base.py:2504
+#: ../Generic/base.py:2679
 msgid "Invalid record: $1"
 msgstr "Registro no válido: $1"
 
-#: ../Generic/base.py:2567
+#: ../Generic/base.py:2742
 msgid "Only can be one root record"
 msgstr "Sólo puede haber un registro raíz"
 
-#: ../Generic/base.py:2663 ../Generic/base.py:2669
+#: ../Generic/base.py:2851 ../Generic/base.py:2857
 msgid "This record does not exits"
 msgstr "Este registro no existe"
 
-#: ../Generic/base.py:2666
+#: ../Generic/base.py:2854
 msgid "Path item must be a integer"
 msgstr "El elemento de la ruta debe ser un número entero"
 
-#: ../Generic/base.py:2671
+#: ../Generic/base.py:2859
 msgid "Path must be a not empty tuple: $1"
 msgstr "«Path» debe ser una tupla no vacía: $1"
 
-#: ../Generic/base.py:2722
+#: ../Generic/base.py:2926
 msgid "The sheet code must be a string"
 msgstr "El código del pliego debe ser una cadena de texto"
 
-#: ../Generic/base.py:2724
+#: ../Generic/base.py:2928
 msgid "The sheet title must be a string"
 msgstr "El título del pliego debe ser una cadena de texto."
 
-#: ../Generic/base.py:2732
+#: ../Generic/base.py:2939
 msgid "The sheet sections must be a dictionary"
 msgstr "La sección del pliego debe ser un dicionario"
 
-#: ../Generic/base.py:2737
+#: ../Generic/base.py:2945
 msgid "The field code must be a string"
 msgstr "El código del ámbito debe ser una cadena de texto"
 
-#: ../Generic/base.py:2739
+#: ../Generic/base.py:2947
 msgid "The field title must be a string"
 msgstr "El título del ámbito debe ser una cadena de texto."
 
-#: ../Generic/base.py:2747
+#: ../Generic/base.py:2958
 msgid "The sheet field must be a dictionary"
 msgstr "El ámbito del pliego debe ser un dicionario."
 
-#: ../Generic/base.py:2752
+#: ../Generic/base.py:2964
 msgid "The paragraph code must be a string"
 msgstr "El código del parrafo debe ser una cadena de texto."
 
-#: ../Generic/base.py:2754
+#: ../Generic/base.py:2966
 msgid "The paragraph text must be a string"
 msgstr "El texto del parrafo debe ser una cadena de texto"
 
-#: ../Generic/base.py:2762
+#: ../Generic/base.py:2977
 msgid "The paragraph dict must be a dictionary"
 msgstr "El dicionario del parrafo debe ser un diccionario"
 
-#: ../Generic/base.py:2767 ../Generic/base.py:2791 ../Generic/base.py:2921
-#: ../Generic/base.py:2945 ../Generic/base.py:2967
+#: ../Generic/base.py:2983 ../Generic/base.py:3008 ../Generic/base.py:3147
+#: ../Generic/base.py:3171 ../Generic/base.py:3193
 msgid "The record_code code must be a string"
 msgstr "«record_code» debe ser una cadena de texto"
 
-#: ../Generic/base.py:2769
+#: ../Generic/base.py:2985
 msgid "The field must be a string"
 msgstr "El ámbito debe ser una cadena de texto."
 
-#: ../Generic/base.py:2771
+#: ../Generic/base.py:2987
 msgid "The section dict must be a dictionary"
 msgstr "El dicionario de la seccion debe ser un dicionario."
 
-#: ../Generic/base.py:2775
+#: ../Generic/base.py:2991
 msgid ""
 "Error: The budget do not have this record code and can not be added the "
 "sheet text in the field $1. Record Code: $2"
@@ -416,11 +443,11 @@
 "Error: El presupuesto no tiene ese código de registro y no puede añadirse el "
 "texto del pliego en el ámbito $1. Código del registro: $2"
 
-#: ../Generic/base.py:2793
+#: ../Generic/base.py:3011
 msgid "The filename must be a string"
 msgstr "El nombre del fichero debe ser una cadena de texto."
 
-#: ../Generic/base.py:2797
+#: ../Generic/base.py:3015
 msgid ""
 "Error: The budget do not have the record code $1 and can not be added the "
 "file: $2"
@@ -428,67 +455,67 @@
 "Error: El presupuesto no tiene el código de registro $1 y no puede añadirse "
 "el fichero: $2"
 
-#: ../Generic/base.py:2807
+#: ../Generic/base.py:3026
 msgid "The company code must be a string"
 msgstr "El código de la entidad debe ser una cadena de texto."
 
-#: ../Generic/base.py:2809
+#: ../Generic/base.py:3028
 msgid "The summary must be a string"
 msgstr "El resumen debe ser una cadena de texto"
 
-#: ../Generic/base.py:2811 ../Generic/base.py:2839
+#: ../Generic/base.py:3030 ../Generic/base.py:3058
 msgid "The name must be a string"
 msgstr "El nombre debe ser una cadena de texto."
 
-#: ../Generic/base.py:2813
+#: ../Generic/base.py:3032
 msgid "The name must be a list"
 msgstr "El nombre debe ser una lista"
 
-#: ../Generic/base.py:2817
+#: ../Generic/base.py:3036
 msgid "The office must be a list"
 msgstr "«The office» debe ser una lista"
 
-#: ../Generic/base.py:2819
+#: ../Generic/base.py:3038
 msgid "The office must be a 10 items list"
 msgstr "«The office» debe ser una lista de 10 elementos"
 
-#: ../Generic/base.py:2822
+#: ../Generic/base.py:3041
 msgid "This office item must be a string"
 msgstr "El elemento de la oficina debe ser una cadena de texto."
 
-#: ../Generic/base.py:2826
+#: ../Generic/base.py:3045
 msgid "This office item must be a list"
 msgstr "Este elemento de la oficina debe ser una lista"
 
-#: ../Generic/base.py:2841
+#: ../Generic/base.py:3060
 msgid "The web must be a string"
 msgstr "La web debe ser una cadena de texto."
 
-#: ../Generic/base.py:2843
+#: ../Generic/base.py:3062
 msgid "The email must be a string"
 msgstr "El email debe ser una cadena de texto."
 
-#: ../Generic/base.py:2853
+#: ../Generic/base.py:3074
 msgid "The tecnical info code must be a string"
 msgstr "La información técnica debe ser una cadena de texto."
 
-#: ../Generic/base.py:2855
+#: ../Generic/base.py:3076
 msgid "The tecnical info description must be a string"
 msgstr "La descripción de la información técnica debe ser una cadena de texto"
 
-#: ../Generic/base.py:2858
+#: ../Generic/base.py:3079
 msgid "The tecnical info unit must be a string"
 msgstr "La unidad de la información técnica debe ser una cadena de texto."
 
-#: ../Generic/base.py:2905
+#: ../Generic/base.py:3130
 msgid "The label must be a string"
 msgstr "La etiqueta debe ser una cadena de texto."
 
-#: ../Generic/base.py:2923
+#: ../Generic/base.py:3149
 msgid "The parametric select comment must be a string"
 msgstr "El comentario de selección paramétrico debe ser una cadena de texto"
 
-#: ../Generic/base.py:2926
+#: ../Generic/base.py:3152
 msgid ""
 "Error: The budget do not have the record code $1 and can not be added the "
 "Parametric select comment: $2"
@@ -496,7 +523,7 @@
 "Error: El presupuesto no tiene el código de registro $1 y no puede añadirse "
 "el comentario de selección paramétrico: $2"
 
-#: ../Generic/base.py:2933
+#: ../Generic/base.py:3159
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "comment"
@@ -504,11 +531,11 @@
 "Error: El registro $1 no es un registro paramétrico y no puede tener "
 "comentario paramétrico."
 
-#: ../Generic/base.py:2947
+#: ../Generic/base.py:3173
 msgid "The summary record must be a string"
 msgstr "El resumen del registro debe ser una cadena de texto"
 
-#: ../Generic/base.py:2949
+#: ../Generic/base.py:3175
 msgid ""
 "Error: The budget do not have the record code $1 and can not be seted the "
 "summary: $2"
@@ -516,7 +543,7 @@
 "Error: El presupuesto no tiene el codigo de registro $1 y no puede fijarse "
 "el resumen: $2"
 
-#: ../Generic/base.py:2955
+#: ../Generic/base.py:3181
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "summary"
@@ -524,11 +551,11 @@
 "Error: El registro $1 no es un registro paramétrico y no puede tener resumen "
 "paramétrico."
 
-#: ../Generic/base.py:2969
+#: ../Generic/base.py:3195
 msgid "The text record must be a string"
 msgstr "El texto del registro debe ser una cadena de texto"
 
-#: ../Generic/base.py:2971
+#: ../Generic/base.py:3197
 msgid ""
 "Error: The budget do not have the record code $1 and can not be seted the "
 "text: $2"
@@ -536,7 +563,7 @@
 "Error: El presupuesto no tiene el codigo de registro $1 y no puede fijarse "
 "el texto: $2"
 
-#: ../Generic/base.py:2977
+#: ../Generic/base.py:3203
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "text"
@@ -544,15 +571,15 @@
 "Error: El registro $1 no es un registro paramétrico y no puede tener texto "
 "paramétrico."
 
-#: ../Generic/base.py:3435
+#: ../Generic/base.py:3726
 msgid "Invalid Hierarchy ($1) The hierarchy must be -1, 0, 1, 2"
 msgstr "Categoría no válida ($1) La categoria debe ser -1, 0, 1 or 2"
 
-#: ../Generic/base.py:3445
+#: ../Generic/base.py:3738
 msgid "Invalid type ($1),the type must be (empty string,0,1,2,3)"
 msgstr "Tipo no válido ($1), el tipo debe ser (cadena vacía, 0, 1, 2, 3)"
 
-#: ../Generic/base.py:3454
+#: ../Generic/base.py:3749
 msgid ""
 "Invalid subtype ($1), The subtype must one in (empty string, EA, EU, EC, EF, "
 "OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
@@ -560,35 +587,28 @@
 "Subtipo no válido ($1), el subtipo debe ser uno de (cadena vacía, EA, EU, "
 "EC, EF, OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
 
-#: ../Generic/durusdatabase.py:48
-msgid "Incorrent Base version"
-msgstr "Versión de la Base incorrecta"
-
-#: ../Generic/durusdatabase.py:77
-msgid "Loading file: $1:"
-msgstr "Cargando archivo: $1"
-
-#: ../Generic/durusdatabase.py:82
-msgid "Loadig time: $1 seconds"
-msgstr "Tiempo de carga: $1 segundos"
-
-#: ../Generic/fiebdc.py:152
+#: ../Generic/fiebdc.py:150
 msgid "Invalid code, it must be a unicode string"
 msgstr "Código no válido, debe ser una cadena unicode"
 
-#: ../Generic/fiebdc.py:159
-msgid "The code '$1' have invalid characters."
-msgstr "El código «$1» tiene caracteres inválidos."
+#: ../Generic/fiebdc.py:157
+msgid "The code '$1' have invalid characters, replaced by '$2'."
+msgstr "El código «$1» tiene caracteres inválidos, reemplazado por «$2»."
 
-#: ../Generic/fiebdc.py:162
+#: ../Generic/fiebdc.py:160
 msgid "The code '$1' have invalid characters and can not be encoded in utf8."
-msgstr "El código «$1» tiene caracteres inválidos y no puede ser codificado en utf8."
+msgstr ""
+"El código «$1» tiene caracteres inválidos y no puede ser codificado en utf8."
 
-#: ../Generic/fiebdc.py:184
+#: ../Generic/fiebdc.py:187
 msgid "The code '$1' contains special characters repeated."
 msgstr "El código «$1» contiene caractectes especiales repetidos."
 
-#: ../Generic/fiebdc.py:405
+#: ../Generic/fiebdc.py:391
+msgid "FIEBDC. Unknow record: $1"
+msgstr "FIEBDC. Registro desconocido: $1"
+
+#: ../Generic/fiebdc.py:410
 msgid ""
 "The 'V' record (Property and Version) must be the first record in the file "
 "but it is the number: $1"
@@ -596,27 +616,27 @@
 "El registro «V» (Propiedad y  versión) debe ser el primer registro en el "
 "archivo pero es el número: $1"
 
-#: ../Generic/fiebdc.py:408
+#: ../Generic/fiebdc.py:413
 msgid "The default values were taken and this V record is ignored"
 msgstr "El valor por amisión ha sido tomado y el registro V es ignorado"
 
-#: ../Generic/fiebdc.py:442
+#: ../Generic/fiebdc.py:447
 msgid "FIEBDC format: $1"
-msgstr "Formato FIEBDC: $1"
+msgstr "FIEBDC formato: $1"
 
-#: ../Generic/fiebdc.py:452
+#: ../Generic/fiebdc.py:457
 msgid "FIEBDC file generated by $1"
-msgstr "Fichero FIEBDC generado por $1"
+msgstr "FIEBDC fichero generado por $1"
 
-#: ../Generic/fiebdc.py:793
+#: ../Generic/fiebdc.py:798
 msgid "Record C without a valid code"
 msgstr "Registro C sin un código válido"
 
-#: ../Generic/fiebdc.py:869 ../Generic/fiebdc.py:881 ../Generic/fiebdc.py:909
+#: ../Generic/fiebdc.py:876 ../Generic/fiebdc.py:888 ../Generic/fiebdc.py:916
 msgid "Incorrect type ($1) in the code $2"
 msgstr "Tipo incorrecto ($1) en el código $2"
 
-#: ../Generic/fiebdc.py:961
+#: ../Generic/fiebdc.py:970
 msgid ""
 "ValueError loadig the descomposition of the record $1, the factor of the "
 "child $2 must be a float number and can not be $3, seted default value 1.0"
@@ -625,7 +645,7 @@
 "hijo $2 debe ser un número de coma flotante y no puede ser $3, fijado el "
 "valor por omisión 1.0"
 
-#: ../Generic/fiebdc.py:972
+#: ../Generic/fiebdc.py:981
 msgid ""
 "ValueError loading the descomposition of the record $1, the yield of the "
 "child $2, must be a float number and cannot be $3,  seted default value 1.0"
@@ -634,23 +654,25 @@
 "del hijo $2, debe ser un número de coma flotante y no puede ser $3, fijado "
 "el valor por omisión 1.0"
 
-#: ../Generic/fiebdc.py:1060
+#: ../Generic/fiebdc.py:1070
 msgid "Invalid codes in $1 record, codes $2"
 msgstr "Códigos no válidos en registro $1, códigos $2"
 
-#: ../Generic/fiebdc.py:1064
+#: ../Generic/fiebdc.py:1074
 msgid "Empty child code in $1 record, codes: $2"
 msgstr "Código de hijo vacío en el registro $1, códigos: $2"
 
-#: ../Generic/fiebdc.py:1084
+#: ../Generic/fiebdc.py:1094
 msgid "Invalid path in $1 record, codes $2"
 msgstr "Camino no válido en el registro $1, códigos $2"
 
-#: ../Generic/fiebdc.py:1095
+#: ../Generic/fiebdc.py:1105
 msgid "Invalid Total Measure value in $1 record, codes $2. Total fixed to 0."
-msgstr "El Total de la medición no es válido en el registro $1, códigos $2. Total fijado a 0."
+msgstr ""
+"El Total de la medición no es válido en el registro $1, códigos $2. Total "
+"fijado a 0."
 
-#: ../Generic/fiebdc.py:1116
+#: ../Generic/fiebdc.py:1126
 msgid ""
 "The comment is not a formula or its have invalid characters, in the $1 "
 "record, codes $2"
@@ -658,270 +680,294 @@
 "El comentario no es una fórmula o tiene caracteres inválidos, en el registro "
 "$1, códigos $2"
 
-#: ../Generic/fiebdc.py:1142
+#: ../Generic/fiebdc.py:1152
 msgid "The measure values are not float numbers, code $1"
 msgstr "«Measure» debe ser un número de coma flotante. Tipo: $1"
 
-#: ../Generic/fiebdc.py:1438 ../Generic/fiebdc.py:1697
+#: ../Generic/fiebdc.py:1452 ../Generic/fiebdc.py:1717
 msgid "The file $1 do not exist"
 msgstr "El archivo $1 no existe"
 
-#: ../Generic/fiebdc.py:1803 ../Generic/fiebdc.py:1810
+#: ../Generic/fiebdc.py:1823 ../Generic/fiebdc.py:1830
 msgid "PyArq hates parametric DLLs"
 msgstr "PyArq odia las DLLs paramétricas"
 
-#: ../Generic/fiebdc.py:2019
+#: ../Generic/fiebdc.py:2028
 msgid "Loading file $1"
 msgstr "Cargando archivo $1"
 
-#: ../Generic/fiebdc.py:2038
+#: ../Generic/fiebdc.py:2049
 msgid "FIEBDC character encoding: $1"
 msgstr "FIEBDC codificación de caracteres: $1"
 
-#: ../Generic/fiebdc.py:2040
+#: ../Generic/fiebdc.py:2053
 msgid ""
 "This Character encoding do not exist in FIEBDC3! Default Character encoding: "
 "$1"
 msgstr "¡Esta codificación no existe en FIEBDC3! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2044
+#: ../Generic/fiebdc.py:2058
 msgid ""
 "This V record dot have a character encoding! Default character encoding: $1"
 msgstr "¡Este registro V no define codificación! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2048
+#: ../Generic/fiebdc.py:2063
 msgid "Not 'V' record in File! Default character encoding: $1"
 msgstr "¡No hay registro «V» en el archivo! Codificación por omisión: $1"
 
-#: ../Generic/fiebdc.py:2085
-msgid "Process terminated"
-msgstr "Proceso cancelado"
-
-#: ../Generic/fiebdc.py:2088
-msgid "Time to load: $1 seconds"
-msgstr "Tiempo de carga: $1 segundos"
-
-#: ../Generic/fiebdc.py:2090
-msgid "Records/Valid Records: $1/$2"
-msgstr "Registro/Registros válidos: $1/$2"
-
-#: ../Generic/fiebdc.py:2093
+#: ../Generic/fiebdc.py:2111
 msgid "$1 unsuported record type O: Comercial Relationship"
 msgstr "$1 tipo de registro no soportado O: Releción comercial"
 
-#: ../Generic/fiebdc.py:2096
+#: ../Generic/fiebdc.py:2114
 msgid "This file is not a valid FIBDC3 file"
 msgstr "El archivo no es un archivo FIEBDC3 válido"
 
-#: ../Generic/fiebdc.py:2133
+#: ../Generic/fiebdc.py:2127
 msgid "Testing budget ..."
 msgstr "Comprobando presupuesto ..."
 
-#: ../Generic/fiebdc.py:2151
+#: ../Generic/fiebdc.py:2146
 msgid "End Test"
 msgstr "Comprobación finalizada"
 
-#: ../Gtk/gui.py:68
+#: ../Generic/fiebdc.py:2230 ../Gtk/gui.py:1038
+msgid "Process terminated"
+msgstr "Proceso cancelado"
+
+#: ../Generic/fiebdc.py:2312
+msgid "Time to load: $1 seconds"
+msgstr "Tiempo de carga: $1 segundos"
+
+#: ../Generic/fiebdc.py:2314
+msgid "Records/Valid Records: $1/$2"
+msgstr "Registro/Registros válidos: $1/$2"
+
+#: ../Gtk/gui.py:83 ../Gtk/gui.py:89
 msgid "The icon file does not exist. '$1'"
 msgstr "El archivo de icono no existe. «$1»"
 
-#: ../Gtk/gui.py:74
+#: ../Gtk/gui.py:95
 msgid "pyArq-Presupuestos running on $1"
 msgstr "pyArq-Presupuestos ejecutandose en $1"
 
-#: ../Gtk/gui.py:169
-msgid "_File"
-msgstr "_Archivo"
+#: ../Gtk/gui.py:176
+msgid "_New window"
+msgstr "Ventana _Nueva"
+
+#: ../Gtk/gui.py:177
+msgid "_Close window"
+msgstr "_Cerrar ventana"
 
-#: ../Gtk/gui.py:170
+#: ../Gtk/gui.py:182
+msgid "About"
+msgstr "Acerca de"
+
+#: ../Gtk/gui.py:185
+msgid "_Quit application"
+msgstr "_Cerrar aplicación"
+
+#: ../Gtk/gui.py:195
 msgid "_Import Fiebdc"
 msgstr "_Importar Fiebdc"
 
-#: ../Gtk/gui.py:171
-msgid "Import FIEBDC"
-msgstr "Importar FIEBDC"
-
-#: ../Gtk/gui.py:172
-msgid "_Close"
-msgstr "_Cerrar"
-
-#: ../Gtk/gui.py:172
-msgid "Close"
-msgstr "Cerrar"
+#: ../Gtk/gui.py:199 ../Gtk/gui.py:400 ../Gtk/gui.py:955
+msgid "_Close tab"
+msgstr "_Cerrar pestaña"
 
-#: ../Gtk/gui.py:174
-msgid "_View"
-msgstr "_Ver"
+#: ../Gtk/gui.py:203
+msgid "_File"
+msgstr "_Archivo"
 
-#: ../Gtk/gui.py:175 ../Gtk/gui.py:185
-msgid "_Go"
-msgstr "_Ir"
-
-#: ../Gtk/gui.py:176
-msgid "_Test"
-msgstr "_Pruebas"
-
-#: ../Gtk/gui.py:186
+#: ../Gtk/gui.py:205
 msgid "_Back"
 msgstr "A_tras"
 
-#: ../Gtk/gui.py:187 ../Gtk/gui.py:198
-msgid "Go to the previous visited item"
-msgstr "Ir al concepto anterior"
-
-#: ../Gtk/gui.py:189
+#: ../Gtk/gui.py:208
 msgid "_Forward"
 msgstr "A_delante"
 
-#: ../Gtk/gui.py:190 ../Gtk/gui.py:202
-msgid "Go to the next visited item"
-msgstr "Ir al concepto siguiente"
-
-#: ../Gtk/gui.py:191
+#: ../Gtk/gui.py:211
 msgid "_Up Item"
 msgstr "Concepto _Superior"
 
-#: ../Gtk/gui.py:192
-msgid "Go up item"
-msgstr "Ir al concepto superior"
-
-#: ../Gtk/gui.py:193
+#: ../Gtk/gui.py:214
 msgid "_Root"
 msgstr "_Raiz"
 
-#: ../Gtk/gui.py:194
-msgid "Go to root"
-msgstr "Ir a la raiz"
+#: ../Gtk/gui.py:217
+msgid "_Go"
+msgstr "_Ir"
+
+#: ../Gtk/gui.py:391 ../Gtk/gui.py:392
+msgid "Import Fiebdc"
+msgstr "Importar Fiebdc"
+
+#: ../Gtk/gui.py:401 ../Gtk/gui.py:956
+msgid "Close tab"
+msgstr "Cerrar pestaña"
 
-#: ../Gtk/gui.py:221
-msgid "Back history"
-msgstr "Retroceder histórico"
+#: ../Gtk/gui.py:413 ../Gtk/gui.py:414
+msgid "Back"
+msgstr "Atras"
+
+#: ../Gtk/gui.py:422 ../Gtk/gui.py:423
+msgid "Forward"
+msgstr "Adelante"
 
-#: ../Gtk/gui.py:226
-msgid "Forward history"
-msgstr "Adelantar histórico"
+#: ../Gtk/gui.py:431 ../Gtk/gui.py:432
+msgid "Up Item"
+msgstr "Concepto Superior"
 
-#: ../Gtk/gui.py:444
+#: ../Gtk/gui.py:440 ../Gtk/gui.py:441
+msgid "Root"
+msgstr "Raiz"
+
+#: ../Gtk/gui.py:655
 msgid "The page is not in the page list"
 msgstr "La pestaña no está en la lista de pestañas"
 
-#: ../Gtk/gui.py:673 ../Gtk/importFiebdc.py:220
+#: ../Gtk/gui.py:792 ../Gtk/gui.py:793
+msgid "Open File"
+msgstr "Abrir archivo"
+
+#: ../Gtk/gui.py:794
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: ../Gtk/gui.py:833
+msgid "The file must have 'bc3' extension"
+msgstr "El archivo debe tener extensión «bc3»"
+
+#: ../Gtk/gui.py:991
 msgid "Time: 0s"
 msgstr "Tiempo: 0s"
 
-#: ../Gtk/gui.py:750 ../Gtk/importFiebdc.py:299
+#: ../Gtk/gui.py:1104
 msgid "Time: $1"
 msgstr "Tiempo: $1"
 
-#: ../Gtk/gui.py:1076
+#: ../Gtk/gui.py:1455
 msgid "The value must be a list"
 msgstr "El valor debe ser una lista"
 
-#: ../Gtk/gui.py:1079
+#: ../Gtk/gui.py:1458
 msgid "Incorrect len"
 msgstr "Longuitud incorrecta"
 
-#: ../Gtk/gui.py:1107
+#: ../Gtk/gui.py:1486
 msgid "Incorrect item $1"
 msgstr "Elemento incorrecto $1"
 
-#: ../Gtk/gui.py:1123
+#: ../Gtk/gui.py:1502
 msgid "The budget does not have the path record: $1"
 msgstr "El presupuesto no tiene el registro con camino: $1"
 
-#: ../Gtk/gui.py:1479
+#: ../Gtk/gui.py:1865
 msgid "Decomposition"
 msgstr "Descomposición"
 
-#: ../Gtk/gui.py:1480 ../Gtk/gui.py:2486
+#: ../Gtk/gui.py:1866 ../Gtk/gui.py:2895
 msgid "Description"
 msgstr "Descripción"
 
-#: ../Gtk/gui.py:1481 ../Gtk/gui.py:2488
+#: ../Gtk/gui.py:1867 ../Gtk/gui.py:2897
 msgid "Measure"
 msgstr "Medición"
 
-#: ../Gtk/gui.py:1482
+#: ../Gtk/gui.py:1868
 msgid "Sheet of Conditions"
 msgstr "Pliego de condicones"
 
-#: ../Gtk/gui.py:1483
+#: ../Gtk/gui.py:1869
 msgid "Files"
 msgstr "Archivos"
 
-#: ../Gtk/gui.py:1484
+#: ../Gtk/gui.py:1870
 msgid "Companies"
 msgstr "Entidades"
 
-#: ../Gtk/gui.py:1661
+#: ../Gtk/gui.py:1950
 msgid "Split View Left/Right"
 msgstr "Partir vista Izquierda/Derecha"
 
-#: ../Gtk/gui.py:1665
+#: ../Gtk/gui.py:1960
 msgid "Split View Top/Bottom"
 msgstr "Partir vista Arriba/Abajo"
 
-#: ../Gtk/gui.py:1669
+#: ../Gtk/gui.py:1968
+msgid "Disconnect view"
+msgstr "Desconectar vista"
+
+#: ../Gtk/gui.py:1971
+msgid "Connect view"
+msgstr "Concectar vista"
+
+#: ../Gtk/gui.py:1984 ../Gtk/gui.py:2081
 msgid "Close view"
 msgstr "Cerrar vista"
 
-#: ../Gtk/gui.py:1837
+#: ../Gtk/gui.py:2073
+msgid "Split view Left/Right"
+msgstr "Partir vista Izquierda/Derecha"
+
+#: ../Gtk/gui.py:2077
+msgid "Split view Top/Bottom"
+msgstr "Partir vista Arriba/Abajo"
+
+#: ../Gtk/gui.py:2112
+msgid "Connect View"
+msgstr "Conectar vista"
+
+#: ../Gtk/gui.py:2118
+msgid "Disconnect View"
+msgstr "Desconectar vista"
+
+#: ../Gtk/gui.py:2248
 msgid "The item must be a widget object."
 msgstr "El elemento debe ser un objeto «widget»."
 
-#: ../Gtk/gui.py:1843
+#: ../Gtk/gui.py:2256
 msgid "Invalid orientation."
 msgstr "Orientación no válida"
 
-#: ../Gtk/gui.py:2215 ../Gtk/gui.py:2842 ../Gtk/gui.py:4172
+#: ../Gtk/gui.py:2628 ../Gtk/gui.py:3256 ../Gtk/gui.py:4674
 msgid "Argument must be a Budget object"
 msgstr "El argumento debe ser un objeto «Budget»"
 
-#: ../Gtk/gui.py:2224
-msgid "Record path can not be None"
-msgstr "La ruta del registrio no puede ser None"
-
-#: ../Gtk/gui.py:2255
-msgid "a"
-msgstr "a"
-
-#: ../Gtk/gui.py:2483 ../Gtk/gui.py:4235
+#: ../Gtk/gui.py:2892 ../Gtk/gui.py:4739
 msgid "Code"
 msgstr "Código"
 
-#: ../Gtk/gui.py:2484
+#: ../Gtk/gui.py:2893
 msgid "Unit"
 msgstr "Unidad"
 
-#: ../Gtk/gui.py:2490
+#: ../Gtk/gui.py:2899
 msgid "Price"
 msgstr "Precio"
 
-#: ../Gtk/gui.py:2492
+#: ../Gtk/gui.py:2901
 msgid "Amount"
 msgstr "Importe"
 
-#: ../Gtk/gui.py:2503 ../Gtk/gui.py:2982
+#: ../Gtk/gui.py:2912 ../Gtk/gui.py:3528
 msgid "Invalid path"
 msgstr "Ruta no válida"
 
-#: ../Gtk/gui.py:2847
+#: ../Gtk/gui.py:3261
 msgid "Record path must be a tuple"
 msgstr "La posición del registro debe ser una tupla"
 
-#: ../Gtk/gui.py:2991
-msgid "measure must be a Measure object. Type: $1"
-msgstr "«measure» debe ser un objeto «Measure». Tipo: $1"
-
-#: ../Gtk/gui.py:3003 ../Gtk/gui.py:4250 ../Gtk/gui.py:4563
+#: ../Gtk/gui.py:3509 ../Gtk/gui.py:4754 ../Gtk/gui.py:5066
 msgid "Type"
 msgstr "Tipo"
 
-#: ../Gtk/gui.py:3004
+#: ../Gtk/gui.py:3510
 msgid "Comment"
 msgstr "Comentario"
 
-#: ../Gtk/gui.py:3005
+#: ../Gtk/gui.py:3511
 msgid ""
 "N\n"
 "(a)"
@@ -929,7 +975,7 @@
 "N\n"
 "(a)"
 
-#: ../Gtk/gui.py:3006
+#: ../Gtk/gui.py:3512
 msgid ""
 "Length\n"
 "(b)"
@@ -937,7 +983,7 @@
 "Longitud\n"
 "(b)"
 
-#: ../Gtk/gui.py:3007
+#: ../Gtk/gui.py:3513
 msgid ""
 "Width\n"
 "(c)"
@@ -945,7 +991,7 @@
 "Anchura\n"
 "(c)"
 
-#: ../Gtk/gui.py:3008
+#: ../Gtk/gui.py:3514
 msgid ""
 "Height\n"
 "(d)"
@@ -953,11 +999,11 @@
 "Altura\n"
 "(d)"
 
-#: ../Gtk/gui.py:3009
+#: ../Gtk/gui.py:3515
 msgid "Formula"
 msgstr "Fórmula"
 
-#: ../Gtk/gui.py:3010
+#: ../Gtk/gui.py:3516
 #, python-format
 msgid ""
 "Parcial\n"
@@ -966,227 +1012,256 @@
 "Parcial\n"
 "[%s]"
 
-#: ../Gtk/gui.py:3011
+#: ../Gtk/gui.py:3517
 msgid "Subtotal"
 msgstr "Subtotal"
 
-#: ../Gtk/gui.py:3419 ../Gtk/gui.py:3441
+#: ../Gtk/gui.py:3537
+msgid "measure must be a Measure object. Type: $1"
+msgstr "«measure» debe ser un objeto «Measure». Tipo: $1"
+
+#: ../Gtk/gui.py:3835 ../Gtk/gui.py:3856
 msgid "Description text of the record $1"
 msgstr "Texto descriptivo del registro $1"
 
-#: ../Gtk/gui.py:3592
+#: ../Gtk/gui.py:4010
 msgid "Sheet of Conditions of the record $1"
 msgstr "Pliego de condiciones del registro $1"
 
-#: ../Gtk/gui.py:3610
+#: ../Gtk/gui.py:4031
 msgid "Field"
 msgstr "Ámbito"
 
-#: ../Gtk/gui.py:3631
+#: ../Gtk/gui.py:4054
 msgid "Section"
 msgstr "Sección"
 
-#: ../Gtk/gui.py:3779
+#: ../Gtk/gui.py:4214
 msgid "Sheet2 of Conditions of the record $1"
 msgstr "Pliego2 de condiciones del registro $1"
 
-#: ../Gtk/gui.py:4236
+#: ../Gtk/gui.py:4740
 msgid "Code that define the company"
 msgstr "Código que define la entidad"
 
-#: ../Gtk/gui.py:4237
+#: ../Gtk/gui.py:4741
 msgid "Summary"
 msgstr "Resumen"
 
-#: ../Gtk/gui.py:4238
+#: ../Gtk/gui.py:4742
 msgid "Summary of the company name"
 msgstr "Resumen del nombre de la entidad"
 
-#: ../Gtk/gui.py:4239 ../Gtk/gui.py:4255
+#: ../Gtk/gui.py:4743 ../Gtk/gui.py:4759
 msgid "Name"
 msgstr "Nombre"
 
-#: ../Gtk/gui.py:4240
+#: ../Gtk/gui.py:4744
 msgid "Complete name"
 msgstr "Nombre completo"
 
-#: ../Gtk/gui.py:4241
+#: ../Gtk/gui.py:4745
 msgid "CIF"
 msgstr "CIF"
 
-#: ../Gtk/gui.py:4242
+#: ../Gtk/gui.py:4746
 msgid "Fiscal identifier number"
 msgstr "Número de identificación fiscal"
 
-#: ../Gtk/gui.py:4243
+#: ../Gtk/gui.py:4747
 msgid "Web"
 msgstr "Web"
 
-#: ../Gtk/gui.py:4244
+#: ../Gtk/gui.py:4748
 msgid "Company web page"
 msgstr "Página web de la entidad"
 
-#: ../Gtk/gui.py:4245
+#: ../Gtk/gui.py:4749
 msgid "Email"
 msgstr "Email"
 
-#: ../Gtk/gui.py:4246
+#: ../Gtk/gui.py:4750
 msgid "Company email"
 msgstr "Correo electrónico de la entidad"
 
-#: ../Gtk/gui.py:4251
+#: ../Gtk/gui.py:4755
 msgid ""
 "Type of Office:\n"
 "                           C: Central office\n"
 "                           D: Local office\n"
 "                           R: Performer"
 msgstr ""
-"Type of Office:\n"
+"Tipo de oficina:\n"
 "                           C: Oficina central\n"
 "                           D: Delegación\n"
 "                           R: Representante"
 
-#: ../Gtk/gui.py:4256
+#: ../Gtk/gui.py:4760
 msgid "Office name"
 msgstr "Nombre de la oficina"
 
-#: ../Gtk/gui.py:4257
+#: ../Gtk/gui.py:4761
 msgid "Address"
 msgstr "Dirección"
 
-#: ../Gtk/gui.py:4258
+#: ../Gtk/gui.py:4762
 msgid "Postal code"
 msgstr "Código postal"
 
-#: ../Gtk/gui.py:4259
+#: ../Gtk/gui.py:4763
 msgid "Town"
 msgstr "Ciudad"
 
-#: ../Gtk/gui.py:4260
+#: ../Gtk/gui.py:4764
 msgid "Province"
 msgstr "Provincia"
 
-#: ../Gtk/gui.py:4261
+#: ../Gtk/gui.py:4765
 msgid "Country"
 msgstr "Ciudad"
 
-#: ../Gtk/gui.py:4262
+#: ../Gtk/gui.py:4766
 msgid "Phone"
 msgstr "Teléfono"
 
-#: ../Gtk/gui.py:4263
+#: ../Gtk/gui.py:4767
 msgid "Phone numbers of the office"
 msgstr "Teléfono de la officina"
 
-#: ../Gtk/gui.py:4264
+#: ../Gtk/gui.py:4768
 msgid "Fax"
 msgstr "Fax"
 
-#: ../Gtk/gui.py:4265
+#: ../Gtk/gui.py:4769
 msgid "Fax numbers of the office"
 msgstr "Fax de la oficina"
 
-#: ../Gtk/gui.py:4266
+#: ../Gtk/gui.py:4770
 msgid "Contact person"
 msgstr "Persona de contacto"
 
-#: ../Gtk/gui.py:4267
+#: ../Gtk/gui.py:4771
 msgid "Contact persons in the office"
 msgstr "Persona de contacto en la oficina"
 
-#: ../Gtk/gui.py:4271
+#: ../Gtk/gui.py:4775
 msgid "Unknow Option Type"
 msgstr "Tipo de opcion desconocida"
 
-#: ../Gtk/gui.py:4501
+#: ../Gtk/gui.py:5002
 msgid "Boolean"
 msgstr "Booleano"
 
-#: ../Gtk/gui.py:4502
+#: ../Gtk/gui.py:5003
 msgid "Integer"
 msgstr "Entero"
 
-#: ../Gtk/gui.py:4503
+#: ../Gtk/gui.py:5004
 msgid "Text"
 msgstr "Texto"
 
-#: ../Gtk/gui.py:4504
+#: ../Gtk/gui.py:5005
 msgid "Color"
 msgstr "Color"
 
-#: ../Gtk/gui.py:4505
+#: ../Gtk/gui.py:5006
 msgid "List"
 msgstr "Lista"
 
-#: ../Gtk/gui.py:4537
+#: ../Gtk/gui.py:5040
 msgid "Option name"
 msgstr "Nombre de Opción"
 
-#: ../Gtk/gui.py:4550
+#: ../Gtk/gui.py:5053
 msgid "Value"
 msgstr "Valor"
 
-#: ../Gtk/gui.py:4589
+#: ../Gtk/gui.py:5094
 msgid "Description:"
 msgstr "Descripción:"
 
-#: ../Gtk/gui.py:4750
+#: ../Gtk/gui.py:5258
 msgid "Option values must be strings"
 msgstr "Los valores de la opción deben ser cadenas"
 
-#: ../Gtk/gui.py:4752
+#: ../Gtk/gui.py:5260
 msgid "Option must be a tuple with 4 items"
 msgstr "La opcion debe ser una tupla de 4 elementos"
 
-#: ../Gtk/gui.py:4754
+#: ../Gtk/gui.py:5262
 msgid "Option list must be a list"
 msgstr "La lista de opciones debe ser una lista lista"
 
-#: ../Gtk/gui.py:4774
+#: ../Gtk/gui.py:5282
 msgid "Icorrect type, must be boolean"
 msgstr "Tipo erroneo, debe ser booleano"
 
-#: ../Gtk/gui.py:4779
+#: ../Gtk/gui.py:5287
 msgid "Icorrect type, must be integer"
 msgstr "Tipo erroneo, debe ser un número entero"
 
-#: ../Gtk/gui.py:4792
+#: ../Gtk/gui.py:5300
 msgid "Icorrect type, must be string"
 msgstr "Tipo erroneo, debe ser una cadena de texto"
 
-#: ../Gtk/gui.py:4805
+#: ../Gtk/gui.py:5313
 msgid "Icorrect type, must be list"
 msgstr "Tipo erroneo, debe ser una lista"
 
-#: ../Gtk/gui.py:4811
+#: ../Gtk/gui.py:5317
 msgid "Icorrect type, must be a parseable color"
 msgstr "Tipo erroneo, debe ser un color parseable"
 
-#: ../Gtk/gui.py:4819
+#: ../Gtk/gui.py:5325
 msgid "Type must be boolean, integer, string or color"
 msgstr "El tipo debe ser booleano, entero, cadena de texto o color"
 
-#: ../Gtk/gui.py:4822
+#: ../Gtk/gui.py:5328
 msgid "Value must be in the option dict"
 msgstr "El valor debe estar en el diccionario de opciones"
 
-#: ../Gtk/gui.py:4824
+#: ../Gtk/gui.py:5331
 msgid "Values must be a dict"
 msgstr "El valor debe ser un dicionario"
 
-#: ../Gtk/importFiebdc.py:91
-msgid "Open File"
-msgstr "Abrir archivo"
+#~ msgid "Incorrent Base version"
+#~ msgstr "Versión de la Base incorrecta"
+
+#~ msgid "Loadig time: $1 seconds"
+#~ msgstr "Tiempo de carga: $1 segundos"
+
+#~ msgid "Import FIEBDC"
+#~ msgstr "Importar FIEBDC"
 
-#: ../Gtk/importFiebdc.py:135
-msgid "The file must have 'bc3' extension"
-msgstr "El archivo debe tener extensión «bc3»"
+#~ msgid "_View"
+#~ msgstr "_Ver"
+
+#~ msgid "_Test"
+#~ msgstr "_Pruebas"
+
+#~ msgid "Go to the previous visited item"
+#~ msgstr "Ir al concepto anterior"
+
+#~ msgid "Go to the next visited item"
+#~ msgstr "Ir al concepto siguiente"
 
-#: ../Gtk/importFiebdc.py:208
-msgid "Loading file ..."
-msgstr "Cargando archivo ..."
+#~ msgid "Go up item"
+#~ msgstr "Ir al concepto superior"
+
+#~ msgid "Go to root"
+#~ msgstr "Ir a la raiz"
+
+#~ msgid "Back history"
+#~ msgstr "Retroceder histórico"
 
-#: ../Gtk/importFiebdc.py:232
-msgid "Cancel"
-msgstr "Cancelar"
+#~ msgid "Forward history"
+#~ msgstr "Adelantar histórico"
+
+#~ msgid "Record path can not be None"
+#~ msgstr "La ruta del registrio no puede ser None"
 
+#~ msgid "a"
+#~ msgstr "a"
+
+#~ msgid "Loading file ..."
+#~ msgstr "Cargando archivo ..."
--- a/mo/pyArq-Presupuestos.pot	Tue Sep 30 17:16:50 2014 +0200
+++ b/mo/pyArq-Presupuestos.pot	Thu May 02 16:31:17 2019 +0200
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-11-02 18:58+0100\n"
+"POT-Creation-Date: 2019-04-27 10:53+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,973 +17,1010 @@
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../Generic/base.py:359
+#: ../Generic/base.py:283
+msgid ""
+"\n"
+"A free program of measurements, budgets and control of construction sites.\n"
+"In beta development, still there is not a fully functional version.\n"
+msgstr ""
+
+#: ../Generic/base.py:288
+msgid ""
+"\n"
+"Usage:\n"
+"    pyarqPresupuestos [file]...\n"
+"\n"
+"Help Options:\n"
+"    -h, --help     Show this help\n"
+msgstr ""
+
+#: ../Generic/base.py:421
 msgid "Invalid code: $1"
 msgstr ""
 
-#: ../Generic/base.py:374
+#: ../Generic/base.py:436
 msgid "Synonyms ($1) must be a list, code: $2"
 msgstr ""
 
-#: ../Generic/base.py:378
+#: ../Generic/base.py:440
 msgid "Invalid Code in synomyms list ($1) code: $2"
 msgstr ""
 
-#: ../Generic/base.py:409
+#: ../Generic/base.py:471
 msgid "Unit ($1) must be a string: $2"
 msgstr ""
 
-#: ../Generic/base.py:423
+#: ../Generic/base.py:485
 msgid "Summary ($1) must be a string: $1"
 msgstr ""
 
-#: ../Generic/base.py:440
+#: ../Generic/base.py:502
 msgid "Prices ($1) must be a list: $2"
 msgstr ""
 
-#: ../Generic/base.py:461
+#: ../Generic/base.py:523
 msgid "Price ($1) must be a list with two items: $2"
 msgstr ""
 
-#: ../Generic/base.py:466
+#: ../Generic/base.py:528
 msgid "Price must be a float number: $1"
 msgstr ""
 
-#: ../Generic/base.py:476
+#: ../Generic/base.py:538
 #, python-format
 msgid "The record do not have this Price. Code: %s"
 msgstr ""
 
-#: ../Generic/base.py:482
+#: ../Generic/base.py:544
 msgid "The record do not have this Price"
 msgstr ""
 
-#: ../Generic/base.py:497
+#: ../Generic/base.py:559
 msgid "Parents ($1) must be a list: $2"
 msgstr ""
 
-#: ../Generic/base.py:501 ../Generic/base.py:513
+#: ../Generic/base.py:563 ../Generic/base.py:575
 msgid "Invalid parent code ($1) in the record: $2"
 msgstr ""
 
-#: ../Generic/base.py:529
+#: ../Generic/base.py:591
 msgid "children ($1) must be a list, record: $2"
 msgstr ""
 
-#: ../Generic/base.py:533
+#: ../Generic/base.py:595
 msgid "child ($1) must be a Decomposition object, record: $2"
 msgstr ""
 
-#: ../Generic/base.py:581
+#: ../Generic/base.py:649
 msgid "Text ($1) must be a string, record: $2"
 msgstr ""
 
-#: ../Generic/base.py:594
+#: ../Generic/base.py:662
 msgid "sheet must be a Sheet instance"
 msgstr ""
 
-#: ../Generic/base.py:607
+#: ../Generic/base.py:674
 msgid "files must be a list: $1"
 msgstr ""
 
-#: ../Generic/base.py:618 ../Generic/base.py:633
+#: ../Generic/base.py:685 ../Generic/base.py:699
 msgid "Incorrect path"
 msgstr ""
 
-#: ../Generic/base.py:623
+#: ../Generic/base.py:690
 msgid "file must be a list or a File object: $1"
 msgstr ""
 
-#: ../Generic/base.py:652
+#: ../Generic/base.py:718
 msgid "labels must be a list"
 msgstr ""
 
-#: ../Generic/base.py:658
+#: ../Generic/base.py:724
 msgid "label must be a string"
 msgstr ""
 
-#: ../Generic/base.py:667
+#: ../Generic/base.py:733
 msgid "Label must be a string"
 msgstr ""
 
-#: ../Generic/base.py:907
+#: ../Generic/base.py:981
 msgid "Position must be a integer"
 msgstr ""
 
-#: ../Generic/base.py:917
+#: ../Generic/base.py:995
 msgid "BudgetMeasures atribute must be a list"
 msgstr ""
 
-#: ../Generic/base.py:920
+#: ../Generic/base.py:998
 msgid "BudgetMeasures item must be a Measure "
 msgstr ""
 
-#: ../Generic/base.py:927
+#: ../Generic/base.py:1007
 msgid "Certification atribute must be a list or None"
 msgstr ""
 
-#: ../Generic/base.py:933
+#: ../Generic/base.py:1015
 msgid "Real cost atribute must be a list or None"
 msgstr ""
 
-#: ../Generic/base.py:939
+#: ../Generic/base.py:1023
 msgid "Cost goals atribute must be a list or None"
 msgstr ""
 
-#: ../Generic/base.py:945
+#: ../Generic/base.py:1031
 msgid "Cost Planned atribute must be a list or None"
 msgstr ""
 
-#: ../Generic/base.py:1036
+#: ../Generic/base.py:1124
 msgid "Measure must be a float number. Type: $1"
 msgstr ""
 
-#: ../Generic/base.py:1047
+#: ../Generic/base.py:1136
 msgid "Lines must be a list"
 msgstr ""
 
-#: ../Generic/base.py:1050
+#: ../Generic/base.py:1139
 msgid "Line must be a MeasureLine objetc"
 msgstr ""
 
-#: ../Generic/base.py:1058
+#: ../Generic/base.py:1150
 msgid "Factor must be a float number |$1|"
 msgstr ""
 
-#: ../Generic/base.py:1070
+#: ../Generic/base.py:1162
 msgid "Yield must be a float number"
 msgstr ""
 
-#: ../Generic/base.py:1081
+#: ../Generic/base.py:1173
 msgid "Fixed must be boolean object"
 msgstr ""
 
-#: ../Generic/base.py:1151
+#: ../Generic/base.py:1243
 msgid "Type must be M or A. Type: $1"
 msgstr ""
 
-#: ../Generic/base.py:1283
+#: ../Generic/base.py:1387
 msgid " Parcial Subtotal must be a float number. Parcial: $1"
 msgstr ""
 
-#: ../Generic/base.py:1290
+#: ../Generic/base.py:1395
 msgid " Acumulated Subtotal must be a float number. Parcial: $1"
 msgstr ""
 
-#: ../Generic/base.py:1325
+#: ../Generic/base.py:1431
 msgid "Invalid measure line type ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1330
+#: ../Generic/base.py:1437
 msgid "Measure Comment must be a string ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1336
+#: ../Generic/base.py:1444
 msgid "Invalid Measure Units ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1348
+#: ../Generic/base.py:1457
 msgid "Invalid Measure length ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1360
+#: ../Generic/base.py:1470
 msgid "Invalid Measure Width ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1372
+#: ../Generic/base.py:1483
 msgid "Invalid Measure Height ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1383
+#: ../Generic/base.py:1495
 msgid "Formula must be a string ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1386
+#: ../Generic/base.py:1498
 msgid "There is invalid charactersin formula ($1)"
 msgstr ""
 
-#: ../Generic/base.py:1451 ../Generic/base.py:2443
+#: ../Generic/base.py:1564 ../Generic/base.py:2618
 msgid "'a' value must be a float number"
 msgstr ""
 
-#: ../Generic/base.py:1455 ../Generic/base.py:2447
+#: ../Generic/base.py:1568 ../Generic/base.py:2622
 msgid "'b' value must be a float number"
 msgstr ""
 
-#: ../Generic/base.py:1459 ../Generic/base.py:2451
+#: ../Generic/base.py:1572 ../Generic/base.py:2626
 msgid "'c' value must be a float number"
 msgstr ""
 
-#: ../Generic/base.py:1463 ../Generic/base.py:2455
+#: ../Generic/base.py:1576 ../Generic/base.py:2630
 msgid "'d' value must be a float number"
 msgstr ""
 
-#: ../Generic/base.py:1491 ../Generic/base.py:2483
+#: ../Generic/base.py:1604 ../Generic/base.py:2658
 msgid "Invalid formula"
 msgstr ""
 
-#: ../Generic/base.py:1741
+#: ../Generic/base.py:1858
 msgid "sheet_dict must be a dictionay"
 msgstr ""
 
-#: ../Generic/base.py:1758 ../Generic/base.py:1764
+#: ../Generic/base.py:1879 ../Generic/base.py:1886
 msgid "sheet field must be a string"
 msgstr ""
 
-#: ../Generic/base.py:1760
+#: ../Generic/base.py:1881
 msgid "section_dict must be a dictionary"
 msgstr ""
 
-#: ../Generic/base.py:1766
+#: ../Generic/base.py:1888
 msgid "sheet section must be a string"
 msgstr ""
 
-#: ../Generic/base.py:1768
+#: ../Generic/base.py:1890
 msgid "sheet paragraph must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2006
+#: ../Generic/base.py:2177
 msgid "Owner must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2022
+#: ../Generic/base.py:2193
 msgid "Invalid Date: $1"
 msgstr ""
 
-#: ../Generic/base.py:2033
+#: ../Generic/base.py:2204
 msgid "Comment must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2049
+#: ../Generic/base.py:2220
 msgid "Budget type must be 1, 2, 3 or 4."
 msgstr ""
 
-#: ../Generic/base.py:2061
+#: ../Generic/base.py:2232
 msgid "Certificate order must be a integer."
 msgstr ""
 
-#: ../Generic/base.py:2076
+#: ../Generic/base.py:2247
 msgid "Budget certificate Date must be a valid Date."
 msgstr ""
 
-#: ../Generic/base.py:2090
+#: ../Generic/base.py:2261
 msgid "Invalid title list format"
 msgstr ""
 
-#: ../Generic/base.py:2119
+#: ../Generic/base.py:2290
 msgid "Invalid Index Title"
 msgstr ""
 
-#: ../Generic/base.py:2154
+#: ../Generic/base.py:2327
 msgid "Decimal Key error"
 msgstr ""
 
-#: ../Generic/base.py:2190
+#: ../Generic/base.py:2365
 msgid "Invalid Percentage key"
 msgstr ""
 
-#: ../Generic/base.py:2313
+#: ../Generic/base.py:2488
 msgid "Invalid parent code: $1"
 msgstr ""
 
-#: ../Generic/base.py:2316
+#: ../Generic/base.py:2491
 msgid "Invalid child code: $1 $2"
 msgstr ""
 
-#: ../Generic/base.py:2319
+#: ../Generic/base.py:2494
 msgid "Invalid position in measure $1, in code $2"
 msgstr ""
 
-#: ../Generic/base.py:2327
+#: ../Generic/base.py:2502
 msgid ""
 "Circular Decomposition, parent code: $1, child code: $2, repeated code: $3"
 msgstr ""
 
-#: ../Generic/base.py:2352
+#: ../Generic/base.py:2527
 msgid ""
 "No-estructured measure or empty position. Parent Code: $1, Child code: $2, "
 "Position: $3"
 msgstr ""
 
-#: ../Generic/base.py:2356
+#: ../Generic/base.py:2531
 msgid ""
 "No-estructured measure or empty position. Repeated child in unspecified "
 "position. It is impossible to determine the position. New child is added in "
 "the decomposition. Parent code: $1, Child code: $2, Position: $3"
 msgstr ""
 
-#: ../Generic/base.py:2396 ../Generic/base.py:2408
+#: ../Generic/base.py:2571 ../Generic/base.py:2583
 msgid ""
 "Error: Invalid child position in decomposition. Parent code: $1 Child code: "
 "$2 Position: $3"
 msgstr ""
 
-#: ../Generic/base.py:2402
+#: ../Generic/base.py:2577
 msgid "Error: Empty child code. Parent code: $1 Position: $2"
 msgstr ""
 
-#: ../Generic/base.py:2494
+#: ../Generic/base.py:2669
 msgid "Invalid code"
 msgstr ""
 
-#: ../Generic/base.py:2504
+#: ../Generic/base.py:2679
 msgid "Invalid record: $1"
 msgstr ""
 
-#: ../Generic/base.py:2567
+#: ../Generic/base.py:2742
 msgid "Only can be one root record"
 msgstr ""
 
-#: ../Generic/base.py:2663 ../Generic/base.py:2669
+#: ../Generic/base.py:2851 ../Generic/base.py:2857
 msgid "This record does not exits"
 msgstr ""
 
-#: ../Generic/base.py:2666
+#: ../Generic/base.py:2854
 msgid "Path item must be a integer"
 msgstr ""
 
-#: ../Generic/base.py:2671
+#: ../Generic/base.py:2859
 msgid "Path must be a not empty tuple: $1"
 msgstr ""
 
-#: ../Generic/base.py:2722
+#: ../Generic/base.py:2926
 msgid "The sheet code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2724
+#: ../Generic/base.py:2928
 msgid "The sheet title must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2732
+#: ../Generic/base.py:2939
 msgid "The sheet sections must be a dictionary"
 msgstr ""
 
-#: ../Generic/base.py:2737
+#: ../Generic/base.py:2945
 msgid "The field code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2739
+#: ../Generic/base.py:2947
 msgid "The field title must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2747
+#: ../Generic/base.py:2958
 msgid "The sheet field must be a dictionary"
 msgstr ""
 
-#: ../Generic/base.py:2752
+#: ../Generic/base.py:2964
 msgid "The paragraph code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2754
+#: ../Generic/base.py:2966
 msgid "The paragraph text must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2762
+#: ../Generic/base.py:2977
 msgid "The paragraph dict must be a dictionary"
 msgstr ""
 
-#: ../Generic/base.py:2767 ../Generic/base.py:2791 ../Generic/base.py:2921
-#: ../Generic/base.py:2945 ../Generic/base.py:2967
+#: ../Generic/base.py:2983 ../Generic/base.py:3008 ../Generic/base.py:3147
+#: ../Generic/base.py:3171 ../Generic/base.py:3193
 msgid "The record_code code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2769
+#: ../Generic/base.py:2985
 msgid "The field must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2771
+#: ../Generic/base.py:2987
 msgid "The section dict must be a dictionary"
 msgstr ""
 
-#: ../Generic/base.py:2775
+#: ../Generic/base.py:2991
 msgid ""
 "Error: The budget do not have this record code and can not be added the "
 "sheet text in the field $1. Record Code: $2"
 msgstr ""
 
-#: ../Generic/base.py:2793
+#: ../Generic/base.py:3011
 msgid "The filename must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2797
+#: ../Generic/base.py:3015
 msgid ""
 "Error: The budget do not have the record code $1 and can not be added the "
 "file: $2"
 msgstr ""
 
-#: ../Generic/base.py:2807
+#: ../Generic/base.py:3026
 msgid "The company code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2809
+#: ../Generic/base.py:3028
 msgid "The summary must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2811 ../Generic/base.py:2839
+#: ../Generic/base.py:3030 ../Generic/base.py:3058
 msgid "The name must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2813
+#: ../Generic/base.py:3032
 msgid "The name must be a list"
 msgstr ""
 
-#: ../Generic/base.py:2817
+#: ../Generic/base.py:3036
 msgid "The office must be a list"
 msgstr ""
 
-#: ../Generic/base.py:2819
+#: ../Generic/base.py:3038
 msgid "The office must be a 10 items list"
 msgstr ""
 
-#: ../Generic/base.py:2822
+#: ../Generic/base.py:3041
 msgid "This office item must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2826
+#: ../Generic/base.py:3045
 msgid "This office item must be a list"
 msgstr ""
 
-#: ../Generic/base.py:2841
+#: ../Generic/base.py:3060
 msgid "The web must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2843
+#: ../Generic/base.py:3062
 msgid "The email must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2853
+#: ../Generic/base.py:3074
 msgid "The tecnical info code must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2855
+#: ../Generic/base.py:3076
 msgid "The tecnical info description must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2858
+#: ../Generic/base.py:3079
 msgid "The tecnical info unit must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2905
+#: ../Generic/base.py:3130
 msgid "The label must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2923
+#: ../Generic/base.py:3149
 msgid "The parametric select comment must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2926
+#: ../Generic/base.py:3152
 msgid ""
 "Error: The budget do not have the record code $1 and can not be added the "
 "Parametric select comment: $2"
 msgstr ""
 
-#: ../Generic/base.py:2933
+#: ../Generic/base.py:3159
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "comment"
 msgstr ""
 
-#: ../Generic/base.py:2947
+#: ../Generic/base.py:3173
 msgid "The summary record must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2949
+#: ../Generic/base.py:3175
 msgid ""
 "Error: The budget do not have the record code $1 and can not be seted the "
 "summary: $2"
 msgstr ""
 
-#: ../Generic/base.py:2955
+#: ../Generic/base.py:3181
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "summary"
 msgstr ""
 
-#: ../Generic/base.py:2969
+#: ../Generic/base.py:3195
 msgid "The text record must be a string"
 msgstr ""
 
-#: ../Generic/base.py:2971
+#: ../Generic/base.py:3197
 msgid ""
 "Error: The budget do not have the record code $1 and can not be seted the "
 "text: $2"
 msgstr ""
 
-#: ../Generic/base.py:2977
+#: ../Generic/base.py:3203
 msgid ""
 "Error: The Record $1 is not a Parametric Record and can not have Parametric "
 "text"
 msgstr ""
 
-#: ../Generic/base.py:3435
+#: ../Generic/base.py:3726
 msgid "Invalid Hierarchy ($1) The hierarchy must be -1, 0, 1, 2"
 msgstr ""
 
-#: ../Generic/base.py:3445
+#: ../Generic/base.py:3738
 msgid "Invalid type ($1),the type must be (empty string,0,1,2,3)"
 msgstr ""
 
-#: ../Generic/base.py:3454
+#: ../Generic/base.py:3749
 msgid ""
 "Invalid subtype ($1), The subtype must one in (empty string, EA, EU, EC, EF, "
 "OB, PA, PU, H, Q, %, MC, MCr, MM, MS, ME, MCu, MAl, ML, M)"
 msgstr ""
 
-#: ../Generic/durusdatabase.py:48
-msgid "Incorrent Base version"
-msgstr ""
-
-#: ../Generic/durusdatabase.py:77
-msgid "Loading file: $1:"
-msgstr ""
-
-#: ../Generic/durusdatabase.py:82
-msgid "Loadig time: $1 seconds"
-msgstr ""
-
-#: ../Generic/fiebdc.py:152
+#: ../Generic/fiebdc.py:150
 msgid "Invalid code, it must be a unicode string"
 msgstr ""
 
-#: ../Generic/fiebdc.py:159
-msgid "The code '$1' have invalid characters."
+#: ../Generic/fiebdc.py:157
+msgid "The code '$1' have invalid characters, replaced by '$2'."
 msgstr ""
 
-#: ../Generic/fiebdc.py:162
+#: ../Generic/fiebdc.py:160
 msgid "The code '$1' have invalid characters and can not be encoded in utf8."
 msgstr ""
 
-#: ../Generic/fiebdc.py:184
+#: ../Generic/fiebdc.py:187
 msgid "The code '$1' contains special characters repeated."
 msgstr ""
 
-#: ../Generic/fiebdc.py:405
+#: ../Generic/fiebdc.py:391
+msgid "FIEBDC. Unknow record: $1"
+msgstr ""
+
+#: ../Generic/fiebdc.py:410
 msgid ""
 "The 'V' record (Property and Version) must be the first record in the file "
 "but it is the number: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:408
+#: ../Generic/fiebdc.py:413
 msgid "The default values were taken and this V record is ignored"
 msgstr ""
 
-#: ../Generic/fiebdc.py:442
+#: ../Generic/fiebdc.py:447
 msgid "FIEBDC format: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:452
+#: ../Generic/fiebdc.py:457
 msgid "FIEBDC file generated by $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:793
+#: ../Generic/fiebdc.py:798
 msgid "Record C without a valid code"
 msgstr ""
 
-#: ../Generic/fiebdc.py:869 ../Generic/fiebdc.py:881 ../Generic/fiebdc.py:909
+#: ../Generic/fiebdc.py:876 ../Generic/fiebdc.py:888 ../Generic/fiebdc.py:916
 msgid "Incorrect type ($1) in the code $2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:961
+#: ../Generic/fiebdc.py:970
 msgid ""
 "ValueError loadig the descomposition of the record $1, the factor of the "
 "child $2 must be a float number and can not be $3, seted default value 1.0"
 msgstr ""
 
-#: ../Generic/fiebdc.py:972
+#: ../Generic/fiebdc.py:981
 msgid ""
 "ValueError loading the descomposition of the record $1, the yield of the "
 "child $2, must be a float number and cannot be $3,  seted default value 1.0"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1060
+#: ../Generic/fiebdc.py:1070
 msgid "Invalid codes in $1 record, codes $2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1064
+#: ../Generic/fiebdc.py:1074
 msgid "Empty child code in $1 record, codes: $2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1084
+#: ../Generic/fiebdc.py:1094
 msgid "Invalid path in $1 record, codes $2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1095
+#: ../Generic/fiebdc.py:1105
 msgid "Invalid Total Measure value in $1 record, codes $2. Total fixed to 0."
 msgstr ""
 
-#: ../Generic/fiebdc.py:1116
+#: ../Generic/fiebdc.py:1126
 msgid ""
 "The comment is not a formula or its have invalid characters, in the $1 "
 "record, codes $2"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1142
+#: ../Generic/fiebdc.py:1152
 msgid "The measure values are not float numbers, code $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1438 ../Generic/fiebdc.py:1697
+#: ../Generic/fiebdc.py:1452 ../Generic/fiebdc.py:1717
 msgid "The file $1 do not exist"
 msgstr ""
 
-#: ../Generic/fiebdc.py:1803 ../Generic/fiebdc.py:1810
+#: ../Generic/fiebdc.py:1823 ../Generic/fiebdc.py:1830
 msgid "PyArq hates parametric DLLs"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2019
+#: ../Generic/fiebdc.py:2028
 msgid "Loading file $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2038
+#: ../Generic/fiebdc.py:2049
 msgid "FIEBDC character encoding: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2040
+#: ../Generic/fiebdc.py:2053
 msgid ""
 "This Character encoding do not exist in FIEBDC3! Default Character encoding: "
 "$1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2044
+#: ../Generic/fiebdc.py:2058
 msgid ""
 "This V record dot have a character encoding! Default character encoding: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2048
+#: ../Generic/fiebdc.py:2063
 msgid "Not 'V' record in File! Default character encoding: $1"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2085
-msgid "Process terminated"
-msgstr ""
-
-#: ../Generic/fiebdc.py:2088
-msgid "Time to load: $1 seconds"
-msgstr ""
-
-#: ../Generic/fiebdc.py:2090
-msgid "Records/Valid Records: $1/$2"
-msgstr ""
-
-#: ../Generic/fiebdc.py:2093
+#: ../Generic/fiebdc.py:2111
 msgid "$1 unsuported record type O: Comercial Relationship"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2096
+#: ../Generic/fiebdc.py:2114
 msgid "This file is not a valid FIBDC3 file"
 msgstr ""
 
-#: ../Generic/fiebdc.py:2133
+#: ../Generic/fiebdc.py:2127
 msgid "Testing budget ..."
 msgstr ""
 
-#: ../Generic/fiebdc.py:2151
+#: ../Generic/fiebdc.py:2146
 msgid "End Test"
 msgstr ""
 
-#: ../Gtk/gui.py:68
+#: ../Generic/fiebdc.py:2230 ../Gtk/gui.py:1038
+msgid "Process terminated"
+msgstr ""
+
+#: ../Generic/fiebdc.py:2312
+msgid "Time to load: $1 seconds"
+msgstr ""
+
+#: ../Generic/fiebdc.py:2314
+msgid "Records/Valid Records: $1/$2"
+msgstr ""
+
+#: ../Gtk/gui.py:83 ../Gtk/gui.py:89
 msgid "The icon file does not exist. '$1'"
 msgstr ""
 
-#: ../Gtk/gui.py:74
+#: ../Gtk/gui.py:95
 msgid "pyArq-Presupuestos running on $1"
 msgstr ""
 
-#: ../Gtk/gui.py:169
-msgid "_File"
+#: ../Gtk/gui.py:176
+msgid "_New window"
+msgstr ""
+
+#: ../Gtk/gui.py:177
+msgid "_Close window"
 msgstr ""
 
-#: ../Gtk/gui.py:170
+#: ../Gtk/gui.py:182
+msgid "About"
+msgstr ""
+
+#: ../Gtk/gui.py:185
+msgid "_Quit application"
+msgstr ""
+
+#: ../Gtk/gui.py:195
 msgid "_Import Fiebdc"
 msgstr ""
 
-#: ../Gtk/gui.py:171
-msgid "Import FIEBDC"
-msgstr ""
-
-#: ../Gtk/gui.py:172
-msgid "_Close"
-msgstr ""
-
-#: ../Gtk/gui.py:172
-msgid "Close"
+#: ../Gtk/gui.py:199 ../Gtk/gui.py:400 ../Gtk/gui.py:955
+msgid "_Close tab"
 msgstr ""
 
-#: ../Gtk/gui.py:174
-msgid "_View"
+#: ../Gtk/gui.py:203
+msgid "_File"
 msgstr ""
 
-#: ../Gtk/gui.py:175 ../Gtk/gui.py:185
-msgid "_Go"
-msgstr ""
-
-#: ../Gtk/gui.py:176
-msgid "_Test"
-msgstr ""
-
-#: ../Gtk/gui.py:186
+#: ../Gtk/gui.py:205
 msgid "_Back"
 msgstr ""
 
-#: ../Gtk/gui.py:187 ../Gtk/gui.py:198
-msgid "Go to the previous visited item"
-msgstr ""
-
-#: ../Gtk/gui.py:189
+#: ../Gtk/gui.py:208
 msgid "_Forward"
 msgstr ""
 
-#: ../Gtk/gui.py:190 ../Gtk/gui.py:202
-msgid "Go to the next visited item"
-msgstr ""
-
-#: ../Gtk/gui.py:191
+#: ../Gtk/gui.py:211
 msgid "_Up Item"
 msgstr ""
 
-#: ../Gtk/gui.py:192
-msgid "Go up item"
-msgstr ""
-
-#: ../Gtk/gui.py:193
+#: ../Gtk/gui.py:214
 msgid "_Root"
 msgstr ""
 
-#: ../Gtk/gui.py:194
-msgid "Go to root"
+#: ../Gtk/gui.py:217
+msgid "_Go"
+msgstr ""
+
+#: ../Gtk/gui.py:391 ../Gtk/gui.py:392
+msgid "Import Fiebdc"
+msgstr ""
+
+#: ../Gtk/gui.py:401 ../Gtk/gui.py:956
+msgid "Close tab"
 msgstr ""
 
-#: ../Gtk/gui.py:221
-msgid "Back history"
+#: ../Gtk/gui.py:413 ../Gtk/gui.py:414
+msgid "Back"
+msgstr ""
+
+#: ../Gtk/gui.py:422 ../Gtk/gui.py:423
+msgid "Forward"
 msgstr ""
 
-#: ../Gtk/gui.py:226
-msgid "Forward history"
+#: ../Gtk/gui.py:431 ../Gtk/gui.py:432
+msgid "Up Item"
 msgstr ""
 
-#: ../Gtk/gui.py:444
+#: ../Gtk/gui.py:440 ../Gtk/gui.py:441
+msgid "Root"
+msgstr ""
+
+#: ../Gtk/gui.py:655
 msgid "The page is not in the page list"
 msgstr ""
 
-#: ../Gtk/gui.py:673 ../Gtk/importFiebdc.py:220
+#: ../Gtk/gui.py:792 ../Gtk/gui.py:793
+msgid "Open File"
+msgstr ""
+
+#: ../Gtk/gui.py:794
+msgid "Cancel"
+msgstr ""
+
+#: ../Gtk/gui.py:833
+msgid "The file must have 'bc3' extension"
+msgstr ""
+
+#: ../Gtk/gui.py:991
 msgid "Time: 0s"
 msgstr ""
 
-#: ../Gtk/gui.py:750 ../Gtk/importFiebdc.py:299
+#: ../Gtk/gui.py:1104
 msgid "Time: $1"
 msgstr ""
 
-#: ../Gtk/gui.py:1076
+#: ../Gtk/gui.py:1455
 msgid "The value must be a list"
 msgstr ""
 
-#: ../Gtk/gui.py:1079
+#: ../Gtk/gui.py:1458
 msgid "Incorrect len"
 msgstr ""
 
-#: ../Gtk/gui.py:1107
+#: ../Gtk/gui.py:1486
 msgid "Incorrect item $1"
 msgstr ""
 
-#: ../Gtk/gui.py:1123
+#: ../Gtk/gui.py:1502
 msgid "The budget does not have the path record: $1"
 msgstr ""
 
-#: ../Gtk/gui.py:1479
+#: ../Gtk/gui.py:1865
 msgid "Decomposition"
 msgstr ""
 
-#: ../Gtk/gui.py:1480 ../Gtk/gui.py:2486
+#: ../Gtk/gui.py:1866 ../Gtk/gui.py:2895
 msgid "Description"
 msgstr ""
 
-#: ../Gtk/gui.py:1481 ../Gtk/gui.py:2488
+#: ../Gtk/gui.py:1867 ../Gtk/gui.py:2897
 msgid "Measure"
 msgstr ""
 
-#: ../Gtk/gui.py:1482
+#: ../Gtk/gui.py:1868
 msgid "Sheet of Conditions"
 msgstr ""
 
-#: ../Gtk/gui.py:1483
+#: ../Gtk/gui.py:1869
 msgid "Files"
 msgstr ""
 
-#: ../Gtk/gui.py:1484
+#: ../Gtk/gui.py:1870
 msgid "Companies"
 msgstr ""
 
-#: ../Gtk/gui.py:1661
+#: ../Gtk/gui.py:1950
 msgid "Split View Left/Right"
 msgstr ""
 
-#: ../Gtk/gui.py:1665
+#: ../Gtk/gui.py:1960
 msgid "Split View Top/Bottom"
 msgstr ""
 
-#: ../Gtk/gui.py:1669
+#: ../Gtk/gui.py:1968
+msgid "Disconnect view"
+msgstr ""
+
+#: ../Gtk/gui.py:1971
+msgid "Connect view"
+msgstr ""
+
+#: ../Gtk/gui.py:1984 ../Gtk/gui.py:2081
 msgid "Close view"
 msgstr ""
 
-#: ../Gtk/gui.py:1837
+#: ../Gtk/gui.py:2073
+msgid "Split view Left/Right"
+msgstr ""
+
+#: ../Gtk/gui.py:2077
+msgid "Split view Top/Bottom"
+msgstr ""
+
+#: ../Gtk/gui.py:2112
+msgid "Connect View"
+msgstr ""
+
+#: ../Gtk/gui.py:2118
+msgid "Disconnect View"
+msgstr ""
+
+#: ../Gtk/gui.py:2248
 msgid "The item must be a widget object."
 msgstr ""
 
-#: ../Gtk/gui.py:1843
+#: ../Gtk/gui.py:2256
 msgid "Invalid orientation."
 msgstr ""
 
-#: ../Gtk/gui.py:2215 ../Gtk/gui.py:2842 ../Gtk/gui.py:4172
+#: ../Gtk/gui.py:2628 ../Gtk/gui.py:3256 ../Gtk/gui.py:4674
 msgid "Argument must be a Budget object"
 msgstr ""
 
-#: ../Gtk/gui.py:2224
-msgid "Record path can not be None"
-msgstr ""
-
-#: ../Gtk/gui.py:2255
-msgid "a"
-msgstr ""
-
-#: ../Gtk/gui.py:2483 ../Gtk/gui.py:4235
+#: ../Gtk/gui.py:2892 ../Gtk/gui.py:4739
 msgid "Code"
 msgstr ""
 
-#: ../Gtk/gui.py:2484
+#: ../Gtk/gui.py:2893
 msgid "Unit"
 msgstr ""
 
-#: ../Gtk/gui.py:2490
+#: ../Gtk/gui.py:2899
 msgid "Price"
 msgstr ""
 
-#: ../Gtk/gui.py:2492
+#: ../Gtk/gui.py:2901
 msgid "Amount"
 msgstr ""
 
-#: ../Gtk/gui.py:2503 ../Gtk/gui.py:2982
+#: ../Gtk/gui.py:2912 ../Gtk/gui.py:3528
 msgid "Invalid path"
 msgstr ""
 
-#: ../Gtk/gui.py:2847
+#: ../Gtk/gui.py:3261
 msgid "Record path must be a tuple"
 msgstr ""
 
-#: ../Gtk/gui.py:2991
-msgid "measure must be a Measure object. Type: $1"
-msgstr ""
-
-#: ../Gtk/gui.py:3003 ../Gtk/gui.py:4250 ../Gtk/gui.py:4563
+#: ../Gtk/gui.py:3509 ../Gtk/gui.py:4754 ../Gtk/gui.py:5066
 msgid "Type"
 msgstr ""
 
-#: ../Gtk/gui.py:3004
+#: ../Gtk/gui.py:3510
 msgid "Comment"
 msgstr ""
 
-#: ../Gtk/gui.py:3005
+#: ../Gtk/gui.py:3511
 msgid ""
 "N\n"
 "(a)"
 msgstr ""
 
-#: ../Gtk/gui.py:3006
+#: ../Gtk/gui.py:3512
 msgid ""
 "Length\n"
 "(b)"
 msgstr ""
 
-#: ../Gtk/gui.py:3007
+#: ../Gtk/gui.py:3513
 msgid ""
 "Width\n"
 "(c)"
 msgstr ""
 
-#: ../Gtk/gui.py:3008
+#: ../Gtk/gui.py:3514
 msgid ""
 "Height\n"
 "(d)"
 msgstr ""
 
-#: ../Gtk/gui.py:3009
+#: ../Gtk/gui.py:3515
 msgid "Formula"
 msgstr ""
 
-#: ../Gtk/gui.py:3010
+#: ../Gtk/gui.py:3516
 #, python-format
 msgid ""
 "Parcial\n"
 "[%s]"
 msgstr ""
 
-#: ../Gtk/gui.py:3011
+#: ../Gtk/gui.py:3517
 msgid "Subtotal"
 msgstr ""
 
-#: ../Gtk/gui.py:3419 ../Gtk/gui.py:3441
+#: ../Gtk/gui.py:3537
+msgid "measure must be a Measure object. Type: $1"
+msgstr ""
+
+#: ../Gtk/gui.py:3835 ../Gtk/gui.py:3856
 msgid "Description text of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:3592
+#: ../Gtk/gui.py:4010
 msgid "Sheet of Conditions of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:3610
+#: ../Gtk/gui.py:4031
 msgid "Field"
 msgstr ""
 
-#: ../Gtk/gui.py:3631
+#: ../Gtk/gui.py:4054
 msgid "Section"
 msgstr ""
 
-#: ../Gtk/gui.py:3779
+#: ../Gtk/gui.py:4214
 msgid "Sheet2 of Conditions of the record $1"
 msgstr ""
 
-#: ../Gtk/gui.py:4236
+#: ../Gtk/gui.py:4740
 msgid "Code that define the company"
 msgstr ""
 
-#: ../Gtk/gui.py:4237
+#: ../Gtk/gui.py:4741
 msgid "Summary"
 msgstr ""
 
-#: ../Gtk/gui.py:4238
+#: ../Gtk/gui.py:4742
 msgid "Summary of the company name"
 msgstr ""
 
-#: ../Gtk/gui.py:4239 ../Gtk/gui.py:4255
+#: ../Gtk/gui.py:4743 ../Gtk/gui.py:4759
 msgid "Name"
 msgstr ""
 
-#: ../Gtk/gui.py:4240
+#: ../Gtk/gui.py:4744
 msgid "Complete name"
 msgstr ""
 
-#: ../Gtk/gui.py:4241
+#: ../Gtk/gui.py:4745
 msgid "CIF"
 msgstr ""
 
-#: ../Gtk/gui.py:4242
+#: ../Gtk/gui.py:4746
 msgid "Fiscal identifier number"
 msgstr ""
 
-#: ../Gtk/gui.py:4243
+#: ../Gtk/gui.py:4747
 msgid "Web"
 msgstr ""
 
-#: ../Gtk/gui.py:4244
+#: ../Gtk/gui.py:4748
 msgid "Company web page"
 msgstr ""
 
-#: ../Gtk/gui.py:4245
+#: ../Gtk/gui.py:4749
 msgid "Email"
 msgstr ""
 
-#: ../Gtk/gui.py:4246
+#: ../Gtk/gui.py:4750
 msgid "Company email"
 msgstr ""
 
-#: ../Gtk/gui.py:4251
+#: ../Gtk/gui.py:4755
 msgid ""
 "Type of Office:\n"
 "                           C: Central office\n"
@@ -991,146 +1028,130 @@
 "                           R: Performer"
 msgstr ""
 
-#: ../Gtk/gui.py:4256
+#: ../Gtk/gui.py:4760
 msgid "Office name"
 msgstr ""
 
-#: ../Gtk/gui.py:4257
+#: ../Gtk/gui.py:4761
 msgid "Address"
 msgstr ""
 
-#: ../Gtk/gui.py:4258
+#: ../Gtk/gui.py:4762
 msgid "Postal code"
 msgstr ""
 
-#: ../Gtk/gui.py:4259
+#: ../Gtk/gui.py:4763
 msgid "Town"
 msgstr ""
 
-#: ../Gtk/gui.py:4260
+#: ../Gtk/gui.py:4764
 msgid "Province"
 msgstr ""
 
-#: ../Gtk/gui.py:4261
+#: ../Gtk/gui.py:4765
 msgid "Country"
 msgstr ""
 
-#: ../Gtk/gui.py:4262
+#: ../Gtk/gui.py:4766
 msgid "Phone"
 msgstr ""
 
-#: ../Gtk/gui.py:4263
+#: ../Gtk/gui.py:4767
 msgid "Phone numbers of the office"
 msgstr ""
 
-#: ../Gtk/gui.py:4264
+#: ../Gtk/gui.py:4768
 msgid "Fax"
 msgstr ""
 
-#: ../Gtk/gui.py:4265
+#: ../Gtk/gui.py:4769
 msgid "Fax numbers of the office"
 msgstr ""
 
-#: ../Gtk/gui.py:4266
+#: ../Gtk/gui.py:4770
 msgid "Contact person"
 msgstr ""
 
-#: ../Gtk/gui.py:4267
+#: ../Gtk/gui.py:4771
 msgid "Contact persons in the office"
 msgstr ""
 
-#: ../Gtk/gui.py:4271
+#: ../Gtk/gui.py:4775
 msgid "Unknow Option Type"
 msgstr ""
 
-#: ../Gtk/gui.py:4501
+#: ../Gtk/gui.py:5002
 msgid "Boolean"
 msgstr ""
 
-#: ../Gtk/gui.py:4502
+#: ../Gtk/gui.py:5003
 msgid "Integer"
 msgstr ""
 
-#: ../Gtk/gui.py:4503
+#: ../Gtk/gui.py:5004
 msgid "Text"
 msgstr ""
 
-#: ../Gtk/gui.py:4504
+#: ../Gtk/gui.py:5005
 msgid "Color"
 msgstr ""
 
-#: ../Gtk/gui.py:4505
+#: ../Gtk/gui.py:5006
 msgid "List"
 msgstr ""
 
-#: ../Gtk/gui.py:4537
+#: ../Gtk/gui.py:5040
 msgid "Option name"
 msgstr ""
 
-#: ../Gtk/gui.py:4550
+#: ../Gtk/gui.py:5053
 msgid "Value"
 msgstr ""
 
-#: ../Gtk/gui.py:4589
+#: ../Gtk/gui.py:5094
 msgid "Description:"
 msgstr ""
 
-#: ../Gtk/gui.py:4750
+#: ../Gtk/gui.py:5258
 msgid "Option values must be strings"
 msgstr ""
 
-#: ../Gtk/gui.py:4752
+#: ../Gtk/gui.py:5260
 msgid "Option must be a tuple with 4 items"
 msgstr ""
 
-#: ../Gtk/gui.py:4754
+#: ../Gtk/gui.py:5262
 msgid "Option list must be a list"
 msgstr ""
 
-#: ../Gtk/gui.py:4774
+#: ../Gtk/gui.py:5282
 msgid "Icorrect type, must be boolean"
 msgstr ""
 
-#: ../Gtk/gui.py:4779
+#: ../Gtk/gui.py:5287
 msgid "Icorrect type, must be integer"
 msgstr ""
 
-#: ../Gtk/gui.py:4792
+#: ../Gtk/gui.py:5300
 msgid "Icorrect type, must be string"
 msgstr ""
 
-#: ../Gtk/gui.py:4805
+#: ../Gtk/gui.py:5313
 msgid "Icorrect type, must be list"
 msgstr ""
 
-#: ../Gtk/gui.py:4811
+#: ../Gtk/gui.py:5317
 msgid "Icorrect type, must be a parseable color"
 msgstr ""
 
-#: ../Gtk/gui.py:4819
+#: ../Gtk/gui.py:5325
 msgid "Type must be boolean, integer, string or color"
 msgstr ""
 
-#: ../Gtk/gui.py:4822
+#: ../Gtk/gui.py:5328
 msgid "Value must be in the option dict"
 msgstr ""
 
-#: ../Gtk/gui.py:4824
+#: ../Gtk/gui.py:5331
 msgid "Values must be a dict"
 msgstr ""
-
-#: ../Gtk/importFiebdc.py:91
-msgid "Open File"
-msgstr ""
-
-#: ../Gtk/importFiebdc.py:135
-msgid "The file must have 'bc3' extension"
-msgstr ""
-
-#: ../Gtk/importFiebdc.py:208
-msgid "Loading file ..."
-msgstr ""
-
-#: ../Gtk/importFiebdc.py:232
-msgid "Cancel"
-msgstr ""
--- a/pyArq-Presupuestos.py	Tue Sep 30 17:16:50 2014 +0200
+++ b/pyArq-Presupuestos.py	Thu May 02 16:31:17 2019 +0200
@@ -3,7 +3,7 @@
 ## File presupuestos.py
 ## This file is part of pyArq-Presupuestos.
 ##
-## Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez
+## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
 ##                         <miguelangel@obraencurso.es>
 ##
 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify
@@ -21,10 +21,11 @@
 
 # Modules
 import sys
+import getopt
 import gettext
 # pyArq-Presupuestos modules
+from Generic import win32Locale
 from Generic import globalVars
-from Generic import win32Locale
 
 def _take_APPDATA_path():
     # take path to find mo file
@@ -40,18 +41,45 @@
     _dir = globalVars.path["APPDATA"] + "/mo/"
     if sys.platform == 'win32':
         win32Locale.check_win32_locale()
-    gettext.install(_app, _dir, unicode=1)
+    kwargs = {}
+    if sys.version_info < (3,):
+        kwargs['unicode'] = True
+    gettext.install(_app, _dir, **kwargs)
 
-def _run_gui():
+def _run_gtk():
+    print("Iniciando interfaz Gtk3.")
+    from Gtk import gui
+    _app = gui.App()
+    _app.run(sys.argv)
+    
+def _run_gui(argumentList):
     """def _run_gui
     
     Shows main window and starts the GTK+ event processing loop.
     """
-    from Gtk import gui
-    _window = gui.MainWindow()
+    unixOptions = "h"
+    gnuOptions = ["help"]
+    # import before transtale
+    from Generic import base
+    
+    help = base.help
+    try:  
+        arguments, values = getopt.getopt(argumentList, unixOptions, gnuOptions)
+        if len(arguments) > 0:
+            for currentArgument, currentValue in arguments:  
+                if currentArgument in ("-h", "--help"):
+                    print(help)
+                    break
+                else:
+                    _run_gtk()
+        else:
+            _run_gtk()
+    except getopt.error as err:  
+        # output error
+        print (str(err))
 
 # Run pyArq-Presupuestos
 if __name__ == "__main__":
     _take_APPDATA_path()
     _translate()
-    _run_gui()
+    _run_gui(sys.argv[1:])