Beispiel #1
0
 def __init__(self, set_projecttype_cb, parent):
     '''Creates new project window'''
     super(NewProjectWin, self).__init__(Gtk.WindowType.TOPLEVEL)
     self.modify_bg(Gtk.StateType.NORMAL, fstimer.gui.bgcolor)
     self.set_transient_for(parent)
     self.set_modal(True)
     self.set_title('fsTimer - New project')
     self.set_position(Gtk.WindowPosition.CENTER)
     self.set_border_width(20)
     self.connect('delete_event', lambda b, jnk_unused: self.hide())
     # Now create the vbox.
     vbox = Gtk.VBox(False, 10)
     self.add(vbox)
     # Now add the text.
     label_0 = Gtk.Label('Enter a name for the new project.\nOnly letters, numbers, and underscore.')
     # And an error, if needed..
     self.label_1 = Gtk.Label()
     self.label_1.set_line_wrap(True)
     # And the text entry
     self.entry = Gtk.Entry()
     self.entry.set_max_length(32)
     # Select a file to import, if desired
     label_2 = Gtk.Label('Select a project to import settings from (optional)')
     # A combobox to select the project
     combobox = Gtk.ComboBoxText()
     projectlist = ["-- No import --"]
     rootdir = normpath(join(dirname(abspath(__file__)),'../../'))
     projectlist.extend([i for i in os.listdir(rootdir) if os.path.isdir(join(rootdir,i)) and os.path.exists(join(rootdir,i+'/'+i+'.reg'))]) #List the folders in pwd that contain a .reg registration file
     projectlist.sort()
     for project in projectlist:
         combobox.append_text(project)
     combobox.set_active(0)
     # And an hbox with 2 buttons
     hbox_1 = Gtk.HBox(False, 0)
     btnCANCEL = GtkStockButton('close',"Close")
     btnCANCEL.connect('clicked', lambda btn: self.hide())
     alignCANCEL = Gtk.Alignment.new(0, 0, 0, 0)
     alignCANCEL.add(btnCANCEL)
     btnNEXT = GtkStockButton('forward',"Next")
     btnNEXT.connect('clicked', self.nextClicked, set_projecttype_cb, projectlist, combobox)
     alignNEXT = Gtk.Alignment.new(1, 0, 1, 0)
     alignNEXT.add(btnNEXT)
     btnNEXT.set_sensitive(False)
     # And populate
     self.entry.connect("changed", self.lock_btn_title, btnNEXT)
     hbox_1.pack_start(alignCANCEL, True, True, 0)
     hbox_1.pack_start(alignNEXT, False, False, 0)
     vbox.pack_start(label_0, False, False, 0)
     vbox.pack_start(self.entry, False, False, 0)
     vbox.pack_start(self.label_1, False, False, 0)
     vbox.pack_start(label_2, False, False, 0)
     vbox.pack_start(combobox, False, False, 0)
     vbox.pack_start(hbox_1, False, False, 0)
     self.show_all()
Beispiel #2
0
 def __init__(self, load_project_cb, create_project_cb):
     '''Builds and display the introduction window'''
     super(IntroWin, self).__init__(Gtk.WindowType.TOPLEVEL)
     self.modify_bg(Gtk.StateType.NORMAL, fstimer.gui.bgcolor)
     icon_fname = normpath(join(dirname(abspath(__file__)),'../data/icon.png'))
     self.set_icon_from_file(icon_fname)
     self.set_title('fsTimer')
     self.set_position(Gtk.WindowPosition.CENTER)
     self.set_border_width(20)
     self.connect('delete_event', Gtk.main_quit)
     # Create the vbox that will contain everything
     vbox = Gtk.VBox(False, 10)
     self.add(vbox)
     # Main logo
     logo = Gtk.Image()
     logo.set_from_file(normpath(join(dirname(abspath(__file__)),'../data/fstimer_logo.png')))
     # Welcome text
     label0 = Gtk.Label(label='')
     label = Gtk.Label('Select an existing project, or begin a new project.')
     # A combobox to select the project
     combobox = Gtk.ComboBoxText()
     projectlist = [' -- Select an existing project --']
     rootdir = normpath(join(dirname(abspath(__file__)),'../../'))
     projectlist.extend([i for i in os.listdir(rootdir) if os.path.isdir(join(rootdir,i)) and os.path.exists(join(rootdir,i+'/'+i+'.reg'))]) #List the folders in pwd that contain a .reg registration file
     projectlist.sort()
     for project in projectlist:
         combobox.append_text(project)
     combobox.set_active(0)
     #An hbox for the buttons.
     hbox = Gtk.HBox(False, 0)
     #And build the buttons
     btnNEW = GtkStockButton('new','New')
     btnNEW.connect('clicked', create_project_cb)
     btnOK = GtkStockButton('ok','OK')
     btnOK.connect('clicked', load_project_cb, combobox, projectlist)
     btnOK.set_sensitive(False)
     #Set combobox to lock btnOK, so we can't press OK until we have selected a project
     combobox.connect('changed', self.lock_btnOK, combobox, btnOK)
     btnCANCEL = GtkStockButton('close','Close')
     btnCANCEL.connect('clicked', Gtk.main_quit)
     #Now fill the hbox.
     hbox.pack_start(btnCANCEL, True, True, 0)
     hbox.pack_start(btnNEW, True, True, 50)
     hbox.pack_start(btnOK, True, True, 0)
     #Now build the vbox
     vbox.pack_start(logo, False, False, 0)
     vbox.pack_start(label0, False, False, 0)
     vbox.pack_start(label, False, False, 0)
     vbox.pack_start(combobox, False, False, 0)
     vbox.pack_start(hbox, False, False, 0)
     #And show everything.
     self.show_all()
Beispiel #3
0
class RegistrationWin(Gtk.Window):
    '''Handling of the window dedicated to registration'''

    def __init__(self, path, fields, fieldsdic, prereg, projecttype, save_registration_cb, parent_win=None,
                 autosave=True, save_label=''):
        '''Builds and display the registration window'''
        super(RegistrationWin, self).__init__(Gtk.WindowType.TOPLEVEL)
        if parent_win:
            self.set_transient_for(parent_win)
            self.set_modal(True)
        self.fields = fields
        self.fieldsdic = fieldsdic
        self.prereg = prereg
        self.ids = set()
        self.projecttype = projecttype
        self.save_registration_cb = save_registration_cb
        self.autosave = autosave
        self.editreg_win = None
        self.editregfields = None
        # First we define the registration model.
        # We will setup a liststore that is wrapped in a treemodelfilter
        # that is wrapped in a treemodelsort that is put in a treeview
        # that is put in a scrolled window. Eesh.
        self.regmodel = Gtk.ListStore(*[str for field in self.fields])
        self.modelfilter = self.regmodel.filter_new()
        self.modelfiltersorted = Gtk.TreeModelSort(self.modelfilter)
        self.treeview = Gtk.TreeView()
        # Now we define each column in the treeview
        for (colid, field) in enumerate(fields):
            column = Gtk.TreeViewColumn(field, Gtk.CellRendererText(), text=colid)
            column.set_sort_column_id(colid)
            self.treeview.append_column(column)
        # Now we populate the model with the pre-registration info, if any
        for reg in prereg:
            self.regmodel.append([reg[field] for field in fields])
            if reg['ID']:
                self.ids.add(reg['ID'])
        # This is the string that we filter based on.
        self.searchstr = ''
        self.modelfilter.set_visible_func(self.visible_filter)
        self.treeview.set_model(self.modelfiltersorted)
        self.treeview.set_enable_search(False)
        # Now let us actually build the window
        self.modify_bg(Gtk.StateType.NORMAL, fstimer.gui.bgcolor)
        fname = os.path.abspath(
            os.path.join(
                os.path.dirname(os.path.abspath(__file__)),
                '../data/icon.png'))
        self.set_icon_from_file(fname)
        self.set_title('fsTimer - ' + os.path.basename(path))
        self.set_position(Gtk.WindowPosition.CENTER)
        self.connect('delete_event', lambda b, jnk: self.close_clicked(jnk))
        self.set_border_width(10)
        self.set_size_request(850, 450)
        #Now the filter entrybox
        filterbox = Gtk.HBox(False, 8)
        filterbox.pack_start(Gtk.Label('Filter by ', True, True, 0), False, False, 0)
        self.filter_combo = Gtk.ComboBoxText()
        for field in self.fields:
            self.filter_combo.append_text(field)
        self.filter_combo.set_active(0)
        filterbox.pack_start(self.filter_combo, False, False, 0)
        filterbox.pack_start(Gtk.Label(':'), False, False, 0)
        self.filterentry = Gtk.Entry()
        self.filterentry.set_max_length(40)
        self.filterentry.connect('changed', self.filter_apply)
        self.filterbtnCLEAR = GtkStockButton('clear',"Clear")
        self.filterbtnCLEAR.connect('clicked', self.filter_clear)
        self.filterbtnCLEAR.set_sensitive(False)
        filterbox.pack_start(self.filterentry, False, False, 0)
        filterbox.pack_start(self.filterbtnCLEAR, False, False, 0)
        # Now the scrolled window that contains the treeview
        regsw = Gtk.ScrolledWindow()
        regsw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
        regsw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        regsw.add(self.treeview)
        # And a message that says if we have saved or not.
        self.regstatus = Gtk.Label(label=save_label)
        # Some boxes for all the stuff on the left
        regvbox1 = Gtk.VBox(False, 8)
        regvbox1.pack_start(filterbox, False, False, 0)
        regvbox1.pack_start(regsw, True, True, 0)
        regvbox1.pack_start(self.regstatus, False, False, 0)
        vbox1align = Gtk.Alignment.new(0, 0, 1, 1)
        vbox1align.add(regvbox1)
        # And boxes/table for the buttons on the right
        regtable = Gtk.Table(2, 1, False)
        regtable.set_row_spacings(5)
        regtable.set_col_spacings(5)
        regtable.set_border_width(5)
        btnEDIT = GtkStockButton('edit',"Edit")
        btnEDIT.connect('clicked', self.edit_clicked)
        btnREMOVE = GtkStockButton('remove',"Remove")
        btnREMOVE.connect('clicked', self.rm_clicked)
        btnNEW = GtkStockButton('new',"New")
        btnNEW.connect('clicked', self.new_clicked)
        btnSAVE = GtkStockButton('save',"Save")
        btnSAVE.connect('clicked', self.save_clicked)
        btnOK = GtkStockButton('close',"Close")
        btnOK.connect('clicked', self.close_clicked)
        vsubbox = Gtk.VBox(False, 8)
        vsubbox.pack_start(btnSAVE, False, False, 0)
        regvspacer = Gtk.Alignment.new(1, 1, 0, 0)
        regvspacer.add(vsubbox)
        regtable.attach(regvspacer, 0, 1, 1, 2)
        regvbox2 = Gtk.VBox(False, 8)
        regvbox2.pack_start(btnNEW, False, False, 0)
        regvbox2.pack_start(btnEDIT, False, False, 0)
        regvbox2.pack_start(btnREMOVE, False, False, 30)
        regvbalign = Gtk.Alignment.new(1, 0, 0, 0)
        regvbalign.add(regvbox2)
        regtable.attach(regvbalign, 0, 1, 0, 1)
        #Now we pack everything together
        reghbox = Gtk.HBox(False, 8)
        reghbox.pack_start(vbox1align, True, True, 0)
        reghbox.pack_start(regtable, False, False, 0)
        # Add in the close button on the bottom
        vbox_all = Gtk.VBox(False, 0)
        vbox_all.pack_start(reghbox, True, True, 0)
        donespacer = Gtk.Alignment.new(0, 0, 0, 0)
        donespacer.add(btnOK)
        vbox_all.pack_start(donespacer, False, False, 5)
        self.add(vbox_all)
        # And show.
        self.show_all()

    def visible_filter(self, model, titer, data):
        '''This is the filter function.
           It checks if self.searchstr is contained in column matching self.filter_combo
           case insensitive'''
        if self.searchstr:
            col_idx = self.filter_combo.get_active()
            if not model.get_value(titer, col_idx):
                return False
            else:
                return self.searchstr.lower() in model.get_value(titer, col_idx).lower()
        else:
            return True

    def filter_apply(self, jnk_unused):
        ''' handles modification of the content of the filter box
            sets self.searchstr to the current entrybox contents and refilter'''
        self.searchstr = self.filterentry.get_text()
        self.filterbtnCLEAR.set_sensitive(True)
        self.modelfilter.refilter()

    def filter_clear(self, jnk_unused):
        '''handles clearing of the filter box. Clears self.searchstr and refilter'''
        self.searchstr = ''
        self.filterentry.set_text('')
        self.filterbtnCLEAR.set_sensitive(False)
        self.modelfilter.refilter()

    def edit_clicked(self, jnk_unused):
        '''handles click on the 'edit' button on the registration window'''
        selection = self.treeview.get_selection()
        treeiter = selection.get_selected()[1]
        # if no selection, do nothing.
        if treeiter:
            # Grab the current information.
            current_info = {}
            for (colid, field) in enumerate(self.fields):
                current_info[field] = self.modelfiltersorted.get_value(treeiter, colid)
            # Find where this is in self.prereg
            preregiter = self.prereg.index(current_info)
            # Generate the window
            self.edit_registration(treeiter, preregiter, current_info)

    def rm_clicked(self, jnk_unused):
        '''Handling click on the 'remove' button of the registration window
           Throws up an 'are you sure' dialog box, and delete if yes'''
        selection = self.treeview.get_selection()
        treeiter = selection.get_selected()[1]
        # if nothing is selected, do nothing.
        if treeiter:
            rmreg_dialog = MsgDialog(self, 'warning', ['yes', 'no'], 'Really delete?', 'Are you sure you want to delete this entry?\nThis cannot be undone.')
            rmreg_dialog.set_default_response(Gtk.ResponseType.NO)
            response = rmreg_dialog.run()
            rmreg_dialog.destroy()
            if response == Gtk.ResponseType.YES:
                # Grab the current information.
                current_info = {}
                for (colid, field) in enumerate(self.fields):
                    current_info[field] = self.modelfiltersorted.get_value(treeiter, colid)
                # Find where this is in self.prereg
                preregiter = self.prereg.index(current_info)
                # converts the treeiter from sorted to filter to model, and remove
                self.regmodel.remove(self.modelfilter.convert_iter_to_child_iter(self.modelfiltersorted.convert_iter_to_child_iter(treeiter)))
                try:
                    self.ids.remove(current_info['ID'])
                except:
                    pass
                self.prereg.pop(preregiter)
                # The latest stuff has no longer been saved.
                self.regstatus.set_markup('')

    def new_clicked(self, jnk_unused):
        '''Handles click on the 'new' button on the registration window
           Creates the editreg window with a None treeiter and clear initial values.'''
        self.edit_registration(None, None, None)

    def save_clicked(self, jnk_unused):
        '''Handles click on the 'save' button on the registration window.
           We do a json dump of self.prereg'''
        filename, success = self.save_registration_cb()
        if success:
            self.regstatus.set_markup('<span color="blue">Registration saved to %s</span>' % filename)
            return True
        else:
            self.regstatus.set_markup('<span color="red">Registration NOT saved: %s</span>' % filename)
            return False

    def close_clicked(self, jnk_unused):
        '''Handles click on the 'close' button on the registration window.
           Throws up a 'do you want to save' dialog, and close the window'''
        okreg_dialog = MsgDialog(self, 'question', ['yes', 'no'], 'Save?', 'Do you want to save before finishing?\nUnsaved data will be lost.')
        okreg_dialog.set_default_response(Gtk.ResponseType.YES)
        response = okreg_dialog.run()
        okreg_dialog.destroy()
        if response == Gtk.ResponseType.YES:
            # this will save
            save_res = self.save_clicked(None)
            if not save_res:
                return
        self.hide()
        # Clear the file setting from pre-reg, in case pre-reg is
        # re-run without selecting a file
        del self.prereg[:]

    def edit_registration(self, treeiter, preregiter, current_info):
        '''handles creation/modification of a registration entry.
           Converts the treeiter from the treemodelsort to the liststore.'''
        if treeiter:
            treeiter = self.modelfilter.convert_iter_to_child_iter(self.modelfiltersorted.convert_iter_to_child_iter(treeiter))
        # Define the window
        self.editreg_win = Gtk.Window(Gtk.WindowType.TOPLEVEL)
        self.editreg_win.modify_bg(Gtk.StateType.NORMAL, fstimer.gui.bgcolor)
        self.editreg_win.set_title('Registration entry')
        self.editreg_win.set_transient_for(self)
        self.editreg_win.set_modal(True)
        self.editreg_win.set_position(Gtk.WindowPosition.CENTER)
        self.editreg_win.connect('delete_event', lambda b, jnk_unused: self.editreg_win.hide())
        self.editreg_win.set_border_width(10)
        #An hbox for the buttons
        editreghbox = Gtk.HBox(False, 8)
        editregbtnOK = GtkStockButton('ok',"OK")
        editregbtnCANCEL = GtkStockButton('close',"Cancel")
        editregbtnCANCEL.connect('clicked', lambda b: self.editreg_win.hide())
        editreghbox.pack_start(editregbtnOK, False, False, 5)
        editreghbox.pack_start(editregbtnCANCEL, False, False, 5)
        # fill in current_info if available.
        self.editregfields = {}
        for field in self.fields:
            # Determine which type of entry is appropriate, create it and fill it.
            # Entrybox
            if self.fieldsdic[field]['type'] in ['entrybox', 'entrybox_int']:
                self.editregfields[field] = Gtk.Entry()
                self.editregfields[field].set_max_length(self.fieldsdic[field]['max'])
                if current_info:
                    self.editregfields[field].set_text(current_info[field])
            # Combobox
            elif self.fieldsdic[field]['type'] == 'combobox':
                self.editregfields[field] = Gtk.ComboBoxText()
                self.editregfields[field].append_text('')
                for val in self.fieldsdic[field]['options']:
                    self.editregfields[field].append_text(val)
                if current_info:
                    try:
                        indx = self.fieldsdic[field]['options'].index(current_info[field])
                        self.editregfields[field].set_active(indx+1)
                    except ValueError:
                        self.editregfields[field].set_active(0) #this catches if current_inf[field] is not a valid value. It is probably blank. Otherwise this is an issue, but we will force it blank.
                else:
                    self.editregfields[field].set_active(0)
        # Set up the vbox
        editregvbox = Gtk.VBox(False, 8)
        # We will make a smaller hbox for each of the fields.
        hboxes = {}
        for field in self.fields:
            hboxes[field] = Gtk.HBox(False, 15)
            hboxes[field].pack_start(Gtk.Label(field+':', True, True, 0), False, False, 0) #Pack the label
            hboxes[field].pack_start(self.editregfields[field], False, False, 0) #Pack the button/entry/..
            if self.projecttype == 'handicap' and field == 'Handicap':
                label_hd = Gtk.Label(label='hh:mm:ss')
                hboxes[field].pack_start(label_hd, False, False, 0)
            if field == 'ID':
                label_id = Gtk.Label('Must be unique')
                hboxes[field].pack_start(label_id, False, False, 0)
            editregvbox.pack_start(hboxes[field], False, False, 0) #Pack this hbox into the big vbox.
        #Pack and show
        if self.projecttype == 'handicap':
            editregbtnOK.connect('clicked', self.validate_entry, treeiter, preregiter, label_hd, label_id)
        else:
            editregbtnOK.connect('clicked', self.validate_entry, treeiter, preregiter, None, label_id)
        editregvbox.pack_start(editreghbox, False, False, 5)
        self.editreg_win.add(editregvbox)
        self.editreg_win.show_all()

    def validate_entry(self, jnk_unused, treeiter, preregiter, label_hd, label_id):
        '''Handles a click on the 'ok' button of the entry edition window.
           Reads out the input information, and writes the changes to the treemodel'''
        #First check if we have entered a handicap, and if so, make sure it is valid
        if self.projecttype == 'handicap':
            sduration = self.editregfields['Handicap'].get_text()
            if sduration != '':
                try:
                    timePattern = r'((?P<days>-?\d+) day(s)?, )?((?P<hours>\d+):)?'r'(?P<minutes>\d+):(?P<seconds>\d+)'
                    re.match(timePattern, sduration).groupdict(0)
                except AttributeError:
                    label_hd.set_markup('<span color="red">hh:mm:ss</span>')
                    return
        # If that was OK, we go through each field and grab the new value.
        new_vals = {}
        for field in self.fields:
            #Entrybox
            if self.fieldsdic[field]['type'] in ['entrybox', 'entrybox_int']:
                new_vals[field] = self.editregfields[field].get_text()
            #Combobox
            elif self.fieldsdic[field]['type'] == 'combobox':
                indx = self.editregfields[field].get_active()
                if indx == 0:
                    new_vals[field] = ''
                else:
                    new_vals[field] = self.fieldsdic[field]['options'][indx-1]
        # Make sure we don't have a duplicate ID, unless we are editing and leave it the same.
        if treeiter and new_vals['ID'] == self.prereg[preregiter]['ID']:
            pass  # No need for an ID check, it was already done.
        elif new_vals['ID'] in self.ids:
            label_id.set_markup('<span color="red">{} has already been used</span>'.format(new_vals['ID']))
            return
        # Now we replace or append in the treemodel and in prereg
        if treeiter:
            # Remove the old ID from the id store, and add the new value
            if self.prereg[preregiter]['ID']:
                self.ids.remove(self.prereg[preregiter]['ID'])
            # Update the tree and prereg
            for (colid, field) in enumerate(self.fields):
                self.regmodel.set_value(treeiter, colid, new_vals[field])
            self.prereg[preregiter] = new_vals
        else:
            self.regmodel.append([new_vals[field] for field in self.fields])
            self.prereg.append(new_vals)
        # Add the new ID to the id store
        if new_vals['ID']:
            self.ids.add(new_vals['ID'])
        # The saved status is unsaved
        self.regstatus.set_markup('')
        # Filter results by the current filter field, for this value
        self.filterentry.set_text(new_vals[self.filter_combo.get_active_text()])
        # Save
        if self.autosave:
            self.save_clicked(None)
        # we're done
        self.editreg_win.hide()
Beispiel #4
0
 def __init__(self, fields, fieldsdic, divisions, back_clicked_cb,
              next_clicked_cb, parent, edit):
     '''Creates divisions window'''
     super(DivisionsWin, self).__init__(Gtk.WindowType.TOPLEVEL)
     self.divisions = divisions
     self.fields = fields
     self.fieldsdic = fieldsdic
     self.winnewdiv = None
     self.modify_bg(Gtk.StateType.NORMAL, fstimer.gui.bgcolor)
     self.set_transient_for(parent)
     self.set_modal(True)
     self.set_title('fsTimer - Divisions')
     self.set_position(Gtk.WindowPosition.CENTER)
     self.set_border_width(20)
     self.set_size_request(800, 500)
     self.connect('delete_event', lambda b, jnk_unused: self.hide())
     # Now create the vbox.
     vbox = Gtk.VBox(False, 10)
     self.add(vbox)
     # Now add the text.
     label2_0 = Gtk.Label(
         "Specify the divisions for reporting divisional places.\n"
         "Press 'Forward' to continue with the default settings, or make "
         "edits below.\n\nDivisions can be any combination of number entry"
         " and selection box fields.")
     # Make the liststore, with columns:
     # name | (... combobox and entrybox_int fields...)
     # To do this we first count the number of fields
     ndivfields = len([field for field in fields
                       if fieldsdic[field]['type']
                       in ['combobox', 'entrybox_int']])
     self.divmodel = Gtk.ListStore(*[str for i_unused
                                     in range(ndivfields + 1)])
     #We will put the liststore in a treeview
     self.divview = Gtk.TreeView()
     #Add each of the columns
     Columns = {}
     Columns[1] = Gtk.TreeViewColumn(
         'Division name', Gtk.CellRendererText(), text=0)
     self.divview.append_column(Columns[1])
     # The fields
     textcount = 1
     for field in fields:
         if fieldsdic[field]['type'] in ['combobox', 'entrybox_int']:
             Columns[field] = Gtk.TreeViewColumn(
                 field, Gtk.CellRendererText(), text=textcount)
             textcount += 1
             self.divview.append_column(Columns[field])
     #Now we populate the model with the default fields
     divmodelrows = {}
     for div in self.divisions:
         divmodelrow = self.get_divmodelrow(div)
         self.divmodel.append(divmodelrow)
     #Done there.
     self.divview.set_model(self.divmodel)
     selection = self.divview.get_selection()
     #And put it in a scrolled window, in an alignment
     divsw = Gtk.ScrolledWindow()
     divsw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
     divsw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
     divsw.add(self.divview)
     divalgn = Gtk.Alignment.new(0, 0, 1, 1)
     divalgn.add(divsw)
     #Now we put the buttons on the side.
     vbox2 = Gtk.VBox(False, 10)
     btnUP = GtkStockButton('up','Up')
     btnUP.connect('clicked', self.div_up, selection)
     vbox2.pack_start(btnUP, False, False, 0)
     btnDOWN = GtkStockButton('down','Down')
     btnDOWN.connect('clicked', self.div_down, selection)
     vbox2.pack_start(btnDOWN, False, False, 0)
     btnEDIT = GtkStockButton('edit','Edit')
     btnEDIT.connect('clicked', self.div_edit, selection)
     vbox2.pack_start(btnEDIT, False, False, 0)
     btnREMOVE = GtkStockButton('remove','Remove')
     btnREMOVE.connect('clicked', self.div_remove, selection)
     vbox2.pack_start(btnREMOVE, False, False, 0)
     btnNEW = GtkStockButton('new','New')
     btnNEW.connect('clicked', self.div_new, ('', {}), None)
     vbox2.pack_start(btnNEW, False, False, 0)
     btnCOPY = GtkStockButton('copy','Copy')
     btnCOPY.connect('clicked', self.div_copy, selection)
     vbox2.pack_start(btnCOPY, False, False, 0)
     #And an hbox for the fields and the buttons
     hbox4 = Gtk.HBox(False, 0)
     hbox4.pack_start(divalgn, True, True, 10)
     hbox4.pack_start(vbox2, False, False, 0)
     ##And an hbox with 3 buttons
     hbox3 = Gtk.HBox(False, 0)
     btnCANCEL = GtkStockButton('close', 'Close')
     btnCANCEL.connect('clicked', lambda btn: self.hide())
     alignCANCEL = Gtk.Alignment.new(0, 0, 0, 0)
     alignCANCEL.add(btnCANCEL)
     btnBACK = GtkStockButton('back', 'Back')
     if edit:
         btnBACK.set_sensitive(False)
     else:
         btnBACK.connect('clicked', back_clicked_cb)
     btnNEXT = GtkStockButton('forward', 'Next')
     btnNEXT.connect('clicked', next_clicked_cb, edit)
     ##And populate
     hbox3.pack_start(alignCANCEL, True, True, 0)
     hbox3.pack_start(btnBACK, False, False, 2)
     hbox3.pack_start(btnNEXT, False, False, 0)
     alignText = Gtk.Alignment.new(0, 0, 0, 0)
     alignText.add(label2_0)
     vbox.pack_start(alignText, False, False, 0)
     vbox.pack_start(hbox4, True, True, 0)
     vbox.pack_start(hbox3, False, False, 10)
     self.show_all()