1#
2# Gramps - a GTK+/GNOME based genealogy program
3#
4# Copyright (C) 2000-2003  Donald N. Allingham
5# Copyright (C) 2010       Benny Malengier
6# Copyright (C) 2010       Nick Hall
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22# gui/columnorder.py
23
24"""
25Handle the column ordering
26"""
27
28#-------------------------------------------------------------------------
29#
30# python modules
31#
32#-------------------------------------------------------------------------
33from gramps.gen.const import GRAMPS_LOCALE as glocale
34_ = glocale.translation.gettext
35import logging
36
37#-------------------------------------------------------------------------
38#
39# GTK modules
40#
41#-------------------------------------------------------------------------
42from gi.repository import Gtk
43from gi.repository import GObject
44
45#-------------------------------------------------------------------------
46#
47# Gramps modules
48#
49#-------------------------------------------------------------------------
50from .managedwindow import ManagedWindow
51from .glade import Glade
52
53
54#-------------------------------------------------------------------------
55#
56# set up logging
57#
58#-------------------------------------------------------------------------
59__LOG = logging.getLogger(".ColumnOrder")
60
61class ColumnOrder(Gtk.Box):
62    """
63    Column ordering selection widget
64    """
65
66    def __init__(self, config, column_names, widths, on_apply, tree=False):
67        """
68        Create the Column Ordering widget based on config
69
70        config: a configuration file with column data
71        column_names: translated names for the possible columns
72        widths: the widths of the visible columns
73        on_apply: function to run when apply is clicked
74        tree: are the columns for a treeview, if so, the first columns is not
75            changable
76        """
77        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
78
79        self.treeview = tree
80        self.colnames = column_names
81        self.config = config
82        self.on_apply = on_apply
83
84        self.pack_start(Gtk.Label(label=' '), False, False, 0)
85
86        self.startrow = 0
87        if self.treeview:
88            label = Gtk.Label(label=
89                    _('Tree View: first column "%s" cannot be changed') %
90                      column_names[0])
91            self.startrow = 1
92            self.pack_start(label, False, False, 0)
93            self.pack_start(Gtk.Label(label=' '), False, False, 0)
94
95        self.pack_start(Gtk.Label(label=_('Drag and drop the columns to change'
96                                    ' the order')), False, False, 0)
97        self.pack_start(Gtk.Label(label=' '), False, False,0)
98        hbox = Gtk.Box()
99        hbox.set_spacing(10)
100        hbox.pack_start(Gtk.Label(label=' '), True, True, 0)
101        scroll = Gtk.ScrolledWindow()
102        scroll.set_size_request(300,300)
103        hbox.pack_start(scroll, True, True, 0)
104        self.tree = Gtk.TreeView()
105        self.tree.set_reorderable(True)
106        scroll.add(self.tree)
107        self.apply_button = Gtk.Button.new_with_mnemonic(_('_Apply'))
108        btns = Gtk.ButtonBox()
109        btns.set_layout(Gtk.ButtonBoxStyle.END)
110        btns.pack_start(self.apply_button, True, True, 0)
111        hbox.pack_start(btns, False, True, 0)
112        self.pack_start(hbox, True, True, 0)
113
114        #Model holds:
115        # bool: column visible or not
116        # str : name of the column
117        # int : order of the column
118        # int : size (width) of the column
119        self.model = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
120                                   GObject.TYPE_INT, GObject.TYPE_INT)
121
122        self.tree.set_model(self.model)
123
124        checkbox = Gtk.CellRendererToggle()
125        checkbox.connect('toggled', toggled, self.model)
126        renderer = Gtk.CellRendererText()
127
128        column_n = Gtk.TreeViewColumn(_('Display'), checkbox, active=0)
129        column_n.set_min_width(50)
130        self.tree.append_column(column_n)
131
132        column_n = Gtk.TreeViewColumn(_('Column Name'),  renderer, text=1)
133        column_n.set_min_width(225)
134        self.tree.append_column(column_n)
135
136        self.apply_button.connect('clicked', self.__on_apply)
137
138        #obtain the columns from config file
139        self.oldorder = self.config.get('columns.rank')
140        self.oldsize = self.config.get('columns.size')
141        self.oldvis = self.config.get('columns.visible')
142        colord = []
143        index = 0
144        for val, size in zip(self.oldorder, self.oldsize):
145            if val in self.oldvis:
146                if val != self.oldvis[-1]:
147                    # don't use last col width, its wrong
148                    size = widths[index]
149                    index += 1
150                colord.append((1, val, size))
151            else:
152                colord.append((0, val, size))
153        for item in colord[self.startrow:]:
154            node = self.model.append()
155            self.model.set(node,
156                           0, item[0],
157                           1, column_names[item[1]],
158                           2, item[1],
159                           3, item[2])
160
161    def __on_apply(self, obj):
162        """
163        called with the OK button is pressed
164        """
165        neworder = []
166        newsize = []
167        newvis = []
168        if self.treeview:
169            #first row is fixed
170            neworder.append(self.oldorder[0])
171            newvis.append(self.oldvis[0])
172            newsize.append(self.oldsize[0])
173        for i in range(0, len(self.colnames[self.startrow:])):
174            node = self.model.get_iter((int(i), ))
175            enable = self.model.get_value(node, 0)
176            index = self.model.get_value(node, 2)
177            size = self.model.get_value(node, 3)
178            if enable:
179                newvis.append(index)
180            neworder.append(index)
181            newsize.append(size)
182        if len(newvis) > 0 and self.on_apply:
183            self.config.set('columns.rank', neworder)
184            self.config.set('columns.size', newsize)
185            self.config.set('columns.visible', newvis)
186            self.config.save()
187            self.on_apply()
188
189def toggled(cell, path, model):
190    """
191    Called when the cell information is changed, updating the
192    data model so the that change occurs.
193    """
194    node = model.get_iter((int(path), ))
195    value = not model.get_value(node, 0)
196    model.set(node, 0, value)
197