summaryrefslogtreecommitdiff
path: root/virtManager/uiutil.py
blob: 364aaa7c9ca5f3429f5eb113a6be4fbe123e157e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#
# Copyright (C) 2009, 2013, 2014 Red Hat, Inc.
# Copyright (C) 2009 Cole Robinson <crobinso@redhat.com>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#

# pylint: disable=E0611
from gi.repository import GObject
from gi.repository import Gtk
# pylint: enable=E0611

try:
    import gi
    gi.check_version("3.7.4")
    can_set_row_none = True
except (ValueError, AttributeError):
    can_set_row_none = False


def set_combo_text_column(combo, col):
    """
    Set the text column of the passed combo to 'col'. Does the
    right thing whether it's a plain combo or a comboboxentry. Saves
    some typing.
    """
    if combo.get_has_entry():
        combo.set_entry_text_column(col)
    else:
        text = Gtk.CellRendererText()
        combo.pack_start(text, True)
        combo.add_attribute(text, 'text', col)


def spin_get_helper(widget):
    """
    Safely get spin button contents, converting to int if possible
    """
    adj = widget.get_adjustment()
    txt = widget.get_text()

    try:
        return int(txt)
    except:
        return adj.get_value()


def get_list_selection(widget, rowindex=None, check_visible=False):
    """
    Helper to simplify getting the selected row in a list/tree/combo
    """
    if check_visible and not widget.get_visible():
        return None

    if hasattr(widget, "get_selection"):
        selection = widget.get_selection()
        model, treeiter = selection.get_selected()
        if treeiter is None:
            return None

        row = model[treeiter]
    else:
        idx = widget.get_active()
        if idx == -1:
            return None

        row = widget.get_model()[idx]

    if rowindex is None:
        return row
    return row[rowindex]


def set_list_selection(widget, rownum):
    """
    Helper to set list selection from the passed row number
    """
    path = str(rownum)
    selection = widget.get_selection()

    selection.unselect_all()
    widget.set_cursor(path)
    selection.select_path(path)


def set_row_selection(listwidget, prevkey):
    """
    Set a list or tree selection given the passed key. The key is
    expected to be element 0 in the list rows.
    """
    model = listwidget.get_model()
    _iter = None
    if prevkey is not None:
        for row in model:
            if row[0] == prevkey:
                _iter = row.iter
                break
    if not _iter:
        _iter = model.get_iter_first()

    if hasattr(listwidget, "get_selection"):
        selection = listwidget.get_selection()
        cb = selection.select_iter
    else:
        selection = listwidget
        cb = selection.set_active_iter
    if _iter:
        cb(_iter)
    selection.emit("changed")


def set_combo_entry(combo, value, rowidx=0):
    """
    Search the passed combobox for value, comparing against
    rowidx. If found, select it. If not found, and
    the combobox has a text entry, stick the value in their and
    select it.
    """
    idx = -1
    model_list = [x[rowidx] for x in combo.get_model()]
    model_in_list = (value in model_list)
    if model_in_list:
        idx = model_list.index(value)

    combo.set_active(idx)
    if idx == -1 and combo.get_has_entry():
        combo.get_child().set_text(value or "")


def get_combo_entry(combo, rowidx=0):
    """
    Helper to get the value specified in a combo box, with or
    without and entry
    """
    row = get_list_selection(combo)
    if row:
        return row[rowidx]
    if not combo.get_has_entry():
        return None
    return combo.get_child().get_text().strip()


def child_get_property(parent, child, propname):
    """
    Wrapper for child_get_property, which pygobject doesn't properly
    introspect
    """
    value = GObject.Value()
    value.init(GObject.TYPE_INT)
    parent.child_get_property(child, propname, value)
    return value.get_int()


def set_grid_row_visible(child, visible):
    """
    For the passed widget, find its parent GtkGrid, and hide/show all
    elements that are in the same row as it. Simplifies having to name
    every element in a row when we want to dynamically hide things
    based on UI interraction
    """
    parent = child.get_parent()
    if not type(parent) is Gtk.Grid:
        raise RuntimeError("Programming error, parent must be grid, "
                           "not %s" % type(parent))

    row = child_get_property(parent, child, "top-attach")
    for child in parent.get_children():
        if child_get_property(parent, child, "top-attach") == row:
            child.set_visible(visible)