150 lines
4.9 KiB
Python
150 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
UI Base Module for GtkBuilder
|
|
|
|
Based on SimpleGladeApp.py Copyright (C) 2004 Sandino Flores Moreno
|
|
"""
|
|
|
|
# This library 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.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
# USA
|
|
|
|
import os
|
|
import re
|
|
import tokenize
|
|
|
|
from gi.repository import Gtk
|
|
|
|
|
|
class GtkBuilderWidget(object):
|
|
def __init__(self, ui_folders, textdomain, parent, **kwargs):
|
|
"""
|
|
Loads the UI file from the specified folder (with translations
|
|
from the textdomain) and initializes attributes.
|
|
|
|
ui_folders:
|
|
List of folders with GtkBuilder .ui files in search order
|
|
|
|
textdomain:
|
|
The textdomain to be used for translating strings
|
|
|
|
**kwargs:
|
|
Keyword arguments will be set as attributes to this window
|
|
"""
|
|
for key, value in list(kwargs.items()):
|
|
setattr(self, key, value)
|
|
|
|
self.builder = Gtk.Builder()
|
|
if parent is not None:
|
|
self.builder.expose_object('parent_widget', parent)
|
|
self.builder.set_translation_domain(textdomain)
|
|
|
|
# print >>sys.stderr, 'Creating new from file', self.__class__.__name__
|
|
|
|
ui_file = '%s.ui' % self.__class__.__name__.lower()
|
|
|
|
# Search for the UI file in the UI folders, stop after first match
|
|
for ui_folder in ui_folders:
|
|
filename = os.path.join(ui_folder, ui_file)
|
|
if os.path.exists(filename):
|
|
self.builder.add_from_file(filename)
|
|
break
|
|
|
|
self.builder.connect_signals(self)
|
|
self.set_attributes()
|
|
if hasattr(self, '_gtk_properties'):
|
|
for ((gobj, prop), val) in self._gtk_properties.items():
|
|
getattr(self, gobj).set_property(prop, val)
|
|
|
|
self.new()
|
|
|
|
def set_attributes(self):
|
|
"""
|
|
Convert widget names to attributes of this object.
|
|
|
|
It means a widget named vbox-dialog in GtkBuilder
|
|
is referred using self.vbox_dialog in the code.
|
|
"""
|
|
for widget in self.builder.get_objects():
|
|
# Just to be safe - every widget from the builder is buildable
|
|
if not isinstance(widget, Gtk.Buildable):
|
|
continue
|
|
|
|
# The following call looks ugly, but see Gnome bug 591085
|
|
widget_name = Gtk.Buildable.get_name(widget)
|
|
|
|
widget_api_name = '_'.join(re.findall(tokenize.Name, widget_name))
|
|
if hasattr(self, widget_api_name):
|
|
raise AttributeError(
|
|
"instance %s already has an attribute %s" % (
|
|
self, widget_api_name))
|
|
else:
|
|
setattr(self, widget_api_name, widget)
|
|
|
|
@property
|
|
def main_window(self):
|
|
"""Returns the main window of this GtkBuilderWidget"""
|
|
return getattr(self, self.__class__.__name__)
|
|
|
|
def new(self):
|
|
"""
|
|
Method called when the user interface is loaded and ready to be used.
|
|
At this moment, the widgets are loaded and can be referred as self.widget_name
|
|
"""
|
|
|
|
def main(self):
|
|
"""
|
|
Starts the main loop of processing events.
|
|
The default implementation calls Gtk.main()
|
|
|
|
Useful for applications that needs a non gtk main loop.
|
|
For example, applications based on gstreamer needs to override
|
|
this method with Gst.main()
|
|
|
|
Do not directly call this method in your programs.
|
|
Use the method run() instead.
|
|
"""
|
|
Gtk.main()
|
|
|
|
def quit(self):
|
|
"""
|
|
Quit processing events.
|
|
The default implementation calls Gtk.main_quit()
|
|
|
|
Useful for applications that needs a non gtk main loop.
|
|
For example, applications based on gstreamer needs to override
|
|
this method with Gst.main_quit()
|
|
"""
|
|
Gtk.main_quit()
|
|
|
|
def run(self):
|
|
"""
|
|
Starts the main loop of processing events checking for Control-C.
|
|
|
|
The default implementation checks whether a Control-C is pressed,
|
|
then calls on_keyboard_interrupt().
|
|
|
|
Use this method for starting programs.
|
|
"""
|
|
try:
|
|
self.main()
|
|
except KeyboardInterrupt:
|
|
self.on_keyboard_interrupt()
|
|
|
|
def on_keyboard_interrupt(self):
|
|
"""
|
|
This method is called by the default implementation of run()
|
|
after a program is finished by pressing Control-C.
|
|
"""
|