/usr/share/pyshared/gtkmvc/view.py is in python-gtkmvc 1.99.1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | # Author: Roberto Cavada <roboogle@gmail.com>
# Modified by: Guillaume Libersat <glibersat AT linux62.org>
#
# Copyright (c) 2005 by Roberto Cavada
# Copyright (c) 2007 by Guillaume Libersat
#
# pygtkmvc is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# pygtkmvc 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110, USA.
#
# For more information on pygtkmvc see <http://pygtkmvc.sourceforge.net>
# or email to the author Roberto Cavada <roboogle@gmail.com>.
# Please report bugs to <roboogle@gmail.com>.
from gtkmvc.controller import Controller
from gtkmvc.support.log import logger
from gtkmvc.support.exceptions import ViewError
import gtk
import sys
try:
from gtk import glade as gtkglade
__glade_is_available__ = True
except ImportError: __glade_is_available__ = False
try:
from gtk import Builder
__builder_is_available__ = True
except ImportError: __builder_is_available__ = False
# verbose message
if not __glade_is_available__ or not __builder_is_available__:
logger.warn({(False, False) : "both glade and gtk.Builder are not available: relying only on manual widgets in views",
(False, True) : "gtk.Builder is not available, relying on manual and glade based views only",
(True, False) : "glade is not available, relying on manual and gtk.Builder based views only",
}[(__builder_is_available__, __glade_is_available__)])
pass
import types
# ----------------------------------------------------------------------
class View (object):
glade = None
top=None
builder=None
def __init__(self, glade=None, top=None,
parent=None,
builder=None):
"""
Only the first three may be given as positional arguments. If an
argument is empty a class attribute of the same name is used. This
does not work for *parent*.
*glade* is a path to an XML file defining widgets in libglade format.
.. deprecated:: 1.99.1
*builder* is a path to an XML file defining widgets in GtkBuilder
format.
.. versionadded:: 1.99.1
*top* is a string or a list of strings containing the names of our top
level widgets. When using libglade only their children are loaded.
*parent* is used to call :meth:`set_parent_view`.
The last two only work if *glade* or *builder* are used, not if you
intend to create widgets later from code.
.. deprecated:: 1.99.1
In future versions the functionality will be split into the new class
:class:`ManualView` and its child :class:`BuilderView`.
"""
if isinstance(glade, Controller):
raise NotImplementedError("This version of GTKMVC does not"
" support the 1.2 API")
if isinstance(builder, Controller):
raise NotImplementedError("This version of GTKMVC does not"
" support the 1.99.0 API")
if parent and not isinstance(parent, View):
raise NotImplementedError("This version of GTKMVC does not"
" support the unreleased first GtkBuilder API")
self.manualWidgets = {}
self.autoWidgets = {}
self.__autoWidgets_calculated = False
self.glade_xmlWidgets = []
# Sets a callback for custom widgets
if __glade_is_available__:
gtkglade.set_custom_handler(self._custom_widget_create)
pass
if top: _top = top
else: _top = self.top
if type(_top) == types.StringType or _top is None:
wids = (_top,)
else: wids = _top # Already a list or tuple
# retrieves XML objects from glade
if glade: _glade = glade
else: _glade = self.glade
if _glade is not None:
if not __glade_is_available__:
raise ViewError("Module gtk.glade was required, but not available")
for wid in wids:
self.glade_xmlWidgets.append(gtkglade.XML(_glade, wid))
pass
pass
# retrieves objects from builder if available
if builder: _builder = builder
else: _builder = self.builder
if _builder is not None:
if not __builder_is_available__:
raise ViewError("gtk.Builder was used, but is not available")
# if the user passed a Builder, use it as it is, otherwise
# build one
if isinstance(_builder, gtk.Builder):
self._builder = _builder
else:
self._builder = gtk.Builder()
self._builder.add_from_file(_builder)
pass
pass
else: self._builder = None # no gtk builder
# top widget list or singleton:
if _top is not None:
if len(wids) > 1:
self.m_topWidget = []
for i in range(0, len(wids)):
self.m_topWidget.append(self[wids[i]])
pass
else: self.m_topWidget = self[wids[0]]
else: self.m_topWidget = None
if parent is not None: self.set_parent_view(parent)
return
def __getitem__(self, key):
"""
Return the widget named *key*, or ``None``.
.. note::
In future versions this will likely change to raise ``KeyError``.
"""
wid = None
# first try with manually-added widgets:
if self.manualWidgets.has_key(key):
wid = self.manualWidgets[key]
pass
if wid is None:
# then try with glade and builder, starting from memoized
if self.autoWidgets.has_key(key): wid = self.autoWidgets[key]
else:
# try with glade
for xml in self.glade_xmlWidgets:
wid = xml.get_widget(key)
if wid is not None:
self.autoWidgets[key] = wid
break
pass
# try with gtk.builder
if wid is None and self._builder is not None:
wid = self._builder.get_object(key)
if wid is not None:
self.autoWidgets[key] = wid
pass
pass
pass
pass
return wid
def __setitem__(self, key, wid):
"""
Add a widget. This overrides widgets of the same name that were loaded
fom XML. It does not affect GTK container/child relations.
If no top widget is known, this sets it.
"""
self.manualWidgets[key] = wid
if (self.m_topWidget is None): self.m_topWidget = wid
return
def show(self):
"""
Call `show()` on each top widget or `show_all()` if only one is known.
Otherwise does nothing.
"""
top = self.get_top_widget()
if type(top) in (types.ListType, types.TupleType):
for t in top:
if t is not None: t.show()
pass
elif (top is not None): top.show_all()
return
def hide(self):
"""
Call `hide_all()` on all known top widgets.
"""
top = self.get_top_widget()
if type(top) in (types.ListType, types.TupleType):
for t in top:
if t is not None: t.hide_all()
pass
elif top is not None: top.hide_all()
return
def get_top_widget(self):
"""
Return a widget or list of widgets.
"""
return self.m_topWidget
def set_parent_view(self, parent_view):
"""
Set ``self.``:meth:`get_top_widget` transient for
``parent_view.get_top_widget()``.
"""
top = self.get_top_widget()
if type(top) in (types.ListType, types.TupleType):
for t in top:
if t is not None:
t.set_transient_for(parent_view.get_top_widget())
pass
pass
elif (top is not None):
top.set_transient_for(parent_view.get_top_widget())
pass
return
def set_transient(self, transient_view):
"""
Set ``transient_view.get_top_widget()`` transient for
``self.``:meth:`get_top_widget`.
"""
top = self.get_top_widget()
if type(top) in (types.ListType, types.TupleType):
for t in top:
if t is not None:
transient_view.get_top_widget().set_transient_for(t)
pass
pass
elif (top is not None):
transient_view.get_top_widget().set_transient_for(top)
pass
return
# Finds the right callback for custom widget creation and calls it
# Returns None if an undefined or invalid handler is found
def _custom_widget_create(self, glade, function_name, widget_name,
str1, str2, int1, int2):
# This code was kindly provided by Allan Douglas <zalguod at
# users.sourceforge.net>
if function_name is not None:
handler = getattr(self, function_name, None)
if handler is not None: return handler(str1, str2, int1, int2)
pass
return None
def __iter__(self):
"""
Return an iterator over widgets added with :meth:`__setitem__` and
those loaded from XML.
.. note::
In case of name conflicts this yields widgets that are not
accessible via :meth:`__getitem__`.
"""
# precalculates if needed
self.__extract_autoWidgets()
import itertools
for i in itertools.chain(self.manualWidgets, self.autoWidgets): yield i
return
def __extract_autoWidgets(self):
"""Extract autoWidgets map if needed, out of the glade
specifications and gtk builder"""
if self.__autoWidgets_calculated: return
if __glade_is_available__:
for xml in self.glade_xmlWidgets:
for wid in xml.get_widget_prefix(""):
wname = gtkglade.get_widget_name(wid)
if wname not in self.autoWidgets:
self.autoWidgets[wname] = wid
pass
pass
pass
pass
if self._builder is not None:
for wid in self._builder.get_objects():
# General workaround for issue
# https://bugzilla.gnome.org/show_bug.cgi?id=607492
try: name = gtk.Buildable.get_name(wid)
except TypeError: continue
if name in self.autoWidgets and self.autoWidgets[name] != wid:
raise ViewError("Widget '%s' in builder also found in glade specification" % name)
self.autoWidgets[name] = wid
pass
pass
self.__autowidgets_calculated = True
return
pass # end of class View
|