[conduit/gsoc09_alexandre] UI rewrite (Not 100% functional).
- From: Alexandre Rosenfeld <arosenfeld src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [conduit/gsoc09_alexandre] UI rewrite (Not 100% functional).
- Date: Thu, 13 Aug 2009 04:30:48 +0000 (UTC)
commit e570e524e857f22bc71041f9659d4977d5727877
Author: Alexandre Rosenfeld <airmind gmail com>
Date: Thu Aug 13 01:29:17 2009 -0300
UI rewrite (Not 100% functional).
Move to gtk.Builder (Glade is deprecated).
Removed dependencies on GooCanvas (Canvas.py is not used anymore).
New UI layout.
New dataprovider chooser dialog.
conduit/Conduit.py | 13 ++
conduit/ModuleWrapper.py | 20 ++-
conduit/gtkui/DataproviderWizard.py | 114 ++++++++++++
conduit/gtkui/UI.py | 235 +++++++++++++++++++------
data/conduit_box_ui.glade | 330 +++++++++++++++++++++++++++++++++++
data/conduit_ui.glade | 300 +++++++++++++++++++++++++++++++
6 files changed, 957 insertions(+), 55 deletions(-)
---
diff --git a/conduit/Conduit.py b/conduit/Conduit.py
index 5490d77..1c40cb0 100644
--- a/conduit/Conduit.py
+++ b/conduit/Conduit.py
@@ -78,6 +78,7 @@ class Conduit(gobject.GObject):
self.uid = uid
#a conduit can hold one datasource and many datasinks (wrappers)
+ self.name = self.uid
self.datasource = None
self.datasinks = []
self.twoWaySyncEnabled = False
@@ -232,6 +233,18 @@ class Conduit(gobject.GObject):
else:
log.warn("Could not remove %s" % dataprovider)
return False
+
+ def get_name(self):
+ if self.datasource:
+ return self.datasource.get_descriptive_name()
+ else:
+ return self.name
+
+ def get_icon(self, size=16):
+ if self.datasource:
+ return self.datasource.get_icon(size)
+ else:
+ return None
def can_do_two_way_sync(self):
"""
diff --git a/conduit/ModuleWrapper.py b/conduit/ModuleWrapper.py
index 0fe696a..1360e92 100644
--- a/conduit/ModuleWrapper.py
+++ b/conduit/ModuleWrapper.py
@@ -108,8 +108,9 @@ class ModuleWrapper:
#
# 2. They are also serve a way to show the same class in multiple categories
def get_dnd_key(self):
- if self.cached_info:
- return self.classname
+ #TODO: Oops, I think this screws things up, not sure why it was needed
+ #if self.cached_info:
+ # return self.classname
if self.dndKey:
return self.dndKey
return self.get_key()
@@ -125,6 +126,8 @@ class ModuleWrapper:
pickle but requires less implementation detail on the part of the DP
"""
initargs = self.initargs
+ # The module cache inserts the module information on the first item
+ # of initargs, so we must remove it
if self.cached_info:
initargs = initargs[1:]
if len(initargs) > 0:
@@ -146,6 +149,16 @@ class ModuleWrapper:
Sets the dataproviders user readable name
"""
self.name = name
+
+ def get_descriptive_name(self):
+ names = {'file/photo': 'Pictures',
+ 'file/video': 'Videos',
+ 'file/audio': 'Music',
+ 'file': 'Files'}
+ out_name = self.out_type.capitalize()
+ if self.out_type in names:
+ out_name = names[self.out_type]
+ return "%s from %s" % (out_name, self.name)
def get_UID(self):
"""
@@ -206,7 +219,8 @@ class ModuleWrapper:
return None
self.icon[size] = info.load_icon()
self.icon_path = info.get_filename()
-
+ if self.icon[size] and (self.icon[size].get_width() != size or self.icon[size].get_height() != size):
+ self.icon[size] = self.icon[size].scale_simple(size, size, gtk.gdk.INTERP_BILINEAR)
return self.icon[size]
def get_descriptive_icon(self):
diff --git a/conduit/gtkui/DataproviderWizard.py b/conduit/gtkui/DataproviderWizard.py
new file mode 100644
index 0000000..1add3a0
--- /dev/null
+++ b/conduit/gtkui/DataproviderWizard.py
@@ -0,0 +1,114 @@
+"""
+Copyright: Alexandre Rosenfeld, 2009
+License: GPLv2
+"""
+import thread
+import gobject
+import gtk, gtk.glade
+import os.path
+import gettext
+import threading
+from gettext import gettext as _
+import logging
+log = logging.getLogger("gtkui.UI")
+
+import conduit
+import conduit.Web as Web
+import conduit.Conduit as Conduit
+import conduit.gtkui.Canvas as Canvas
+import conduit.gtkui.MsgArea as MsgArea
+import conduit.gtkui.Tree as Tree
+import conduit.gtkui.ConflictResolver as ConflictResolver
+import conduit.gtkui.Database as Database
+
+class DataproviderWizard(gobject.GObject):
+ def __init__(self, main_window, syncset, module_manager, kinds=("source", "twoway"), cond=None):
+ gobject.GObject.__init__(self)
+ self.main_window = main_window
+ self.syncset = syncset
+ self.module_manager = module_manager
+ self.kinds = kinds
+ self.conduit = cond
+
+ self._make_add_conduit_dialog()
+
+ def _assistant_apply(self, assistant):
+ self.assistant.hide()
+ mod = self.module_manager.get_module_wrapper_with_instance(self.selected_dataprovider.get_dnd_key())
+ if not self.conduit:
+ cond = Conduit.Conduit(self.syncset.syncManager)
+ cond.add_dataprovider(mod, True)
+ self.syncset.add_conduit(cond)
+ else:
+ self.conduit.add_dataprovider(mod, False)
+
+ def _assistant_close(self, assistant):
+ self.assistant.hide()
+
+ def _dataprovider_tree_selection(self, tree):
+ model, iter_ = tree.get_selection().get_selected()
+ obj = model.get_value(iter_, 0)
+ self.assistant.set_page_complete(self.dataproviders_page, obj is not None)
+ if obj:
+ self.selected_dataprovider = obj
+
+ def _make_add_conduit_dialog(self):
+ #dialog = gtk.Dialog("Add Conduit",
+ # self.mainWindow,
+ # gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ # (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+ # gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+ self.assistant = gtk.Assistant()
+ self.assistant.set_default_size(600, 600)
+ self.assistant.connect("apply", self._assistant_apply)
+ self.assistant.connect("close", self._assistant_close)
+ self.assistant.connect("cancel", self._assistant_close)
+
+ model = gtk.TreeStore(object, str, gtk.gdk.Pixbuf)
+ tree = gtk.TreeView()
+ tree.set_headers_visible(False)
+ tree.set_show_expanders(False)
+ tree.set_level_indentation(32)
+ tree.set_model(model)
+
+ sw = gtk.ScrolledWindow()
+ sw.add(tree)
+ self.dataproviders_page = sw
+
+ pixbufRenderer = gtk.CellRendererPixbuf()
+ textRenderer = gtk.CellRendererText()
+ tvcolumn0 = gtk.TreeViewColumn("name")
+ tvcolumn0.pack_start(pixbufRenderer, False)
+ tvcolumn0.add_attribute(pixbufRenderer, 'pixbuf', 2)
+ tvcolumn0.pack_start(textRenderer, True)
+ tvcolumn0.add_attribute(textRenderer, 'markup', 1)
+ tree.append_column(tvcolumn0)
+ #tree.insert_column_with_attributes(-1, "Name", gtk.CellRendererText(), text=1)
+ categories = {}
+
+ for mod in self.module_manager.get_modules_by_type(*self.kinds):
+ #print mod
+ if not mod.enabled:
+ continue
+ if mod.category.key in categories:
+ parent = categories[mod.category.key]
+ else:
+ cat_icon = gtk.icon_theme_get_default().load_icon(mod.category.icon, 16, 0)
+ parent = model.append(None, (None, mod.category.name, cat_icon))
+ categories[mod.category.key] = parent
+ model.append(parent, (mod, mod.name, mod.get_descriptive_icon()))
+
+ #dialog.vbox.pack_start(sw)
+ #dialog.vbox.show_all()
+ tree.connect("cursor-changed", self._dataprovider_tree_selection)
+ tree.expand_all()
+ sw.show_all()
+ tree_page = self.assistant.append_page(sw)
+ self.assistant.set_page_type(sw, gtk.ASSISTANT_PAGE_CONFIRM)
+ self.assistant.set_page_title(sw, "Choose a dataprovider")
+ #return dialog.run()
+ self.assistant.set_modal(True)
+ self.assistant.set_transient_for(self.main_window)
+
+ def show(self):
+ self.assistant.show()
diff --git a/conduit/gtkui/UI.py b/conduit/gtkui/UI.py
index af3539a..dad31af 100644
--- a/conduit/gtkui/UI.py
+++ b/conduit/gtkui/UI.py
@@ -4,6 +4,7 @@ Draws the applications main window
Also manages the callbacks from menu and GUI items
Copyright: John Stowers, 2006
+ Alexandre Rosenfeld, 2009
License: GPLv2
"""
import thread
@@ -19,7 +20,6 @@ log = logging.getLogger("gtkui.UI")
import conduit
import conduit.Web as Web
import conduit.Conduit as Conduit
-import conduit.gtkui.Canvas as Canvas
import conduit.gtkui.MsgArea as MsgArea
import conduit.gtkui.Tree as Tree
import conduit.gtkui.ConflictResolver as ConflictResolver
@@ -27,6 +27,9 @@ import conduit.gtkui.Database as Database
def N_(message): return message
+from conduit.gtkui.ConfigContainer import ConfigContainer
+from conduit.gtkui.DataproviderWizard import DataproviderWizard
+
DEFAULT_CONDUIT_BROWSER = "gtkmozembed"
DEVELOPER_WEB_LINKS = (
#name, #url
@@ -43,34 +46,11 @@ for module in gtk.glade, gettext:
if hasattr(module, 'bind_textdomain_codeset'):
module.bind_textdomain_codeset('conduit','UTF-8')
+class Error(Exception):
+ ''' Generic error for the UI'''
+ pass
-class _PreconfiguredConduitMenu(gtk.Menu):
- def __init__(self):
- gtk.Menu.__init__(self)
-# self._items = {}
-# conduit.GLOBALS.moduleManager.connect("dataprovider-available", self._dp_added)
-# conduit.GLOBALS.moduleManager.connect("dataprovider-unavailable", self._dp_removed)
-
- for sok,sik,desc,w in conduit.GLOBALS.moduleManager.list_preconfigured_conduits():
- item = gtk.MenuItem(desc)
- item.connect("activate", self._create, sok, sik, w)
- item.show()
- self.append(item)
-
- def set_sync_set(self, syncSet):
- self.syncSet = syncSet
-
- def _create(self, menu, sok, sik, w):
- self.syncSet.create_preconfigured_conduit(sok,sik,w)
-
- def _dp_added(self, manager, dpw):
- item = gtk.MenuItem(dpw.get_key())
- self._items[dpw] = item
- self.append(item)
- item.show()
-
- def _dp_removed(self, manager, dpw):
- self.remove(self._items[dpw])
+PIX_COLUMN, STR_COLUMN, CONDUIT_COLUMN = range(3)
class MainWindow:
"""
@@ -94,8 +74,10 @@ class MainWindow:
gtk.window_set_default_icon_name("conduit")
self.conduitApplication = conduitApplication
- self.gladeFile = os.path.join(conduit.SHARED_DATA_DIR, "conduit.glade")
- self.widgets = gtk.glade.XML(self.gladeFile, "MainWindow")
+ self.gladeFile = os.path.join(conduit.SHARED_DATA_DIR, "conduit_ui.glade")
+ self.widgets = gtk.Builder()
+ self.widgets.add_from_file(self.gladeFile)
+ self.widgets.connect_signals(self)
dic = { "on_mainwindow_delete" : self.on_window_closed,
"on_mainwindow_state_event" : self.on_window_state_event,
@@ -109,14 +91,15 @@ class MainWindow:
"on_save1_activate" : self.save_settings,
None : None
}
- self.widgets.signal_autoconnect(dic)
+ #self.widgets.signal_autoconnect(dic)
#type converter and sync manager
self.type_converter = typeConverter
self.sync_manager = syncManager
+ self.module_manager = moduleManager
#Initialize the mainWindow
- self.mainWindow = self.widgets.get_widget("MainWindow")
+ self.mainWindow = self.widgets.get_object("main_window")
#Enable RGBA colormap
if conduit.GLOBALS.settings.get("gui_use_rgba_colormap") == True:
screen = self.mainWindow.get_screen()
@@ -130,12 +113,41 @@ class MainWindow:
if not conduit.IS_INSTALLED:
title = title + _(" - Running Uninstalled")
self.mainWindow.set_title(title)
-
+
+ self.remove_conduit_action = self.widgets.get_object("remove_conduit_action")
+ self.sync_conduit_action = self.widgets.get_object("sync_conduit_action")
+ self.cancel_sync_action = self.widgets.get_object("cancel_sync_action")
+
+ self.conduits_treemodel = gtk.ListStore(gtk.gdk.Pixbuf, str, object)
+
+ self.conduits_tree = self.widgets.get_object("conduits_tree")
+ self.conduits_tree.set_model(self.conduits_treemodel)
+ #self.conduits_tree.insert_column_with_data_func(-1, "Conduit Name",
+ # gtk.CellRendererText(), self._tree_get_conduit_name)
+ self.conduits_tree.insert_column_with_attributes(-1, "Conduit Icon",
+ gtk.CellRendererPixbuf(), pixbuf=PIX_COLUMN)
+ self.conduits_tree.insert_column_with_attributes(-1, "Conduit Name",
+ gtk.CellRendererText(), text=STR_COLUMN)
+
+ self.conduits_pages = {}
+ self.conduits_notebook = self.widgets.get_object("conduits_notebook")
+
+ self.add_conduit_label = gtk.Label("Start by adding a new Conduit")
+ self.conduits_notebook.append_page(self.add_conduit_label)
+ self.select_conduit_label = gtk.Label("Select a Conduit to change it's configuration")
+ self.conduits_notebook.append_page(self.select_conduit_label)
+
+ self.conduits_notebook.set_current_page(self.conduits_notebook.page_num(self.add_conduit_label))
+ self.conduits_notebook.show_all()
+
#Configure canvas
- self.canvasSW = self.widgets.get_widget("canvasScrolledWindow")
- self.hpane = self.widgets.get_widget("hpaned1")
-
+ #self.canvasSW = self.widgets.get_widget("canvasScrolledWindow")
+ #self.hpane = self.widgets.get_widget("hpaned1")
+
+ self.selected_conduit = None
+
#start up the canvas
+ '''
msg = MsgArea.MsgAreaController()
self.widgets.get_widget("mainVbox").pack_start(msg, False, False)
self.canvas = Canvas.Canvas(
@@ -196,8 +208,95 @@ class MainWindow:
self.hpane.set_position(conduit.GLOBALS.settings.get("gui_hpane_postion"))
self.dataproviderTreeView.set_expand_rows()
self.window_state = 0
+
+ '''
+ #self.hpane.set_position(conduit.GLOBALS.settings.get("gui_hpane_postion"))
log.info("Main window constructed (thread: %s)" % thread.get_ident())
-
+
+ def _tree_get_conduit_name(self, column, cell, model, iter_):
+ cell.props.text = model.get_value(iter_, 0)
+
+ def _update_actions(self):
+ cond = self.selected_conduit
+ self.remove_conduit_action.set_sensitive(cond is not None)
+ self.sync_conduit_action.set_sensitive(cond is not None)
+
+ def on_conduits_tree_cursor_changed(self, tree):
+ #print "Cursor changed"
+ model, iter_ = tree.get_selection().get_selected()
+ cond = model.get_value(iter_, CONDUIT_COLUMN)
+ page_num = self.conduits_notebook.page_num(self.conduits_pages[cond]['root'])
+ self.conduits_notebook.set_current_page(page_num)
+ self.selected_conduit = cond
+ self._update_actions()
+
+ def on_remove_conduit_action_activate(self, action):
+ self.syncSet.remove_conduit(self.selected_conduit)
+
+ def on_add_sink_action_activate(self, action, cond):
+ wizard = DataproviderWizard(self.mainWindow, self.syncSet, self.module_manager,
+ ("sink","twoway"), cond)
+ wizard.show()
+
+ def _make_dataprovider_widget(self, dp, sizegroup):
+ widget = gtk.VBox()
+ hbox = gtk.HBox()
+ hbox.set_spacing(8)
+ icon = gtk.image_new_from_pixbuf(dp.get_icon(48))
+ icon.set_property("pixel-size", 48)
+ label = gtk.Label(dp.get_name())
+ label.props.xalign = 0
+ config_button = gtk.Button(stock="gtk-preferences")
+ refresh_button = gtk.Button(stock="gtk-refresh")
+ #button_box = gtk.HButtonBox()
+ #button_box.add(config_button)
+ #button_box.add(refresh_button)
+ hbox.pack_start(icon, expand=False, fill=False)
+ hbox.pack_start(label, expand=True, fill=True)
+ #hbox.pack_start(button_box, expand=False, fill=False)
+ widget.pack_start(hbox, False, False)
+ config_container = dp.module.get_config_container(ConfigContainer, dp.name, dp.get_icon(), self)
+ config_widget = config_container.get_config_widget()
+ if config_widget:
+ align = gtk.Alignment(xalign=0.5, yalign=0.5)
+ align.add(config_widget)
+ sizegroup.add_widget(config_widget)
+ widget.pack_start(align, False, False)
+ widget.show_all()
+ return widget
+
+ def set_busy(self, value):
+ pass
+
+ def _make_conduit_page(self, cond):
+ # We have to load the UI file every time because gtk.Builder cant create
+ # several instances from the same file
+ info = {}
+ glade_file = os.path.join(conduit.SHARED_DATA_DIR, "conduit_box_ui.glade")
+ builder = gtk.Builder()
+ builder.add_from_file(glade_file)
+ builder.connect_signals(self, cond)
+ #builder.connect_signals(self)
+ widget = builder.get_object("root")
+ builder.get_object("conduit_name_label").set_text(cond.name)
+ info['root'] = widget
+ info['sizegroup'] = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+ source_box = builder.get_object("source_vbox")
+ if cond.datasource:
+ source_box.add(self._make_dataprovider_widget(cond.datasource, info['sizegroup']))
+ info['source_box'] = source_box
+ sink_box = builder.get_object("sink_vbox")
+ for datasink in cond.datasinks:
+ sink_box.add(self._make_dataprovider_widget(datasink, info['sizegroup']))
+ info['sink_box'] = sink_box
+ return info
+
+ def on_main_window_destroy(self, window):
+ self.conduitApplication.Quit()
+
+ def on_add_conduit_action_activate(self, action):
+ self.dataprovider_wizard.show()
+
def on_developer_menu_item_clicked(self, menuitem, name, url):
threading.Thread(
target=Web.LoginMagic,
@@ -205,17 +304,47 @@ class MainWindow:
kwargs={"login_function":lambda: True}
).start()
+ def on_conduit_dataprovider_added(self, cond, dp):
+ info = self.conduits_pages[cond]
+ if cond.datasource == dp:
+ info['source_box'].add(self._make_dataprovider_widget(dp, info['sizegroup']))
+ else:
+ info['sink_box'].add(self._make_dataprovider_widget(dp, info['sizegroup']))
+
def on_conduit_added(self, syncset, cond):
cond.connect("sync-started", self.on_sync_started)
cond.connect("sync-completed", self.on_sync_completed)
- cond.connect("sync-conflict", self.conflictResolver.on_conflict)
+ cond.connect("dataprovider-added", self.on_conduit_dataprovider_added)
+ iter_ = self.conduits_treemodel.append((cond.get_icon(), cond.get_name(), cond))
+ self.conduits_pages[cond] = self._make_conduit_page(cond)
+ self.conduits_notebook.append_page(self.conduits_pages[cond]['root'])
+ path = self.conduits_treemodel.get_string_from_iter(iter_)
+ self.conduits_tree.set_cursor(path)
+ #cond.connect("sync-conflict", self.conflictResolver.on_conflict)
+
+ def on_conduit_removed(self, syncset, cond):
+ if cond == self.selected_conduit:
+ self.selected_conduit = None
+ self._update_actions()
+ iter_ = None
+ for row in iter(self.conduits_treemodel):
+ if row[CONDUIT_COLUMN] == cond:
+ iter_ = row.iter
+ break
+ if not iter_:
+ raise Error("Conduit not found")
+ self.conduits_treemodel.remove(iter_)
+ page_num = self.conduits_notebook.page_num(self.conduits_pages[cond]['root'])
+ self.conduits_notebook.remove_page(page_num)
def set_model(self, syncSet):
self.syncSet = syncSet
self.syncSet.connect("conduit-added", self.on_conduit_added)
- self.canvas.set_sync_set(syncSet)
- if self.preconfiguredConduitsMenu:
- self.preconfiguredConduitsMenu.set_sync_set(syncSet)
+ self.syncSet.connect("conduit-removed", self.on_conduit_removed)
+ self.dataprovider_wizard = DataproviderWizard(self.mainWindow, self.syncSet, self.module_manager)
+ #self.canvas.set_sync_set(syncSet)
+ #if self.preconfiguredConduitsMenu:
+ # self.preconfiguredConduitsMenu.set_sync_set(syncSet)
def present(self):
"""
@@ -241,13 +370,15 @@ class MainWindow:
return (not minimized) and self.mainWindow.get_property('visible')
def on_sync_started(self, thread):
- self.cancelSyncButton.set_property("sensitive", True)
+ #self.cancelSyncButton.set_property("sensitive", True)
+ pass
def on_sync_completed(self, thread, aborted, error, conflict):
- self.cancelSyncButton.set_property(
- "sensitive",
- conduit.GLOBALS.syncManager.is_busy()
- )
+ #self.cancelSyncButton.set_property(
+ # "sensitive",
+ # conduit.GLOBALS.syncManager.is_busy()
+ # )
+ pass
def on_synchronize_all_clicked(self, widget):
"""
@@ -573,15 +704,15 @@ class MainWindow:
self.syncSet.save()
#GUI settings
- conduit.GLOBALS.settings.set(
- "gui_hpane_postion",
- self.hpane.get_position())
+ #conduit.GLOBALS.settings.set(
+ # "gui_hpane_postion",
+ # self.hpane.get_position())
conduit.GLOBALS.settings.set(
"gui_window_size",
self.mainWindow.get_size())
- conduit.GLOBALS.settings.set(
- "gui_expanded_rows",
- self.dataproviderTreeView.get_expanded_rows())
+ #conduit.GLOBALS.settings.set(
+ # "gui_expanded_rows",
+ # self.dataproviderTreeView.get_expanded_rows())
class SplashScreen:
"""
diff --git a/data/conduit_box_ui.glade b/data/conduit_box_ui.glade
new file mode 100644
index 0000000..a101812
--- /dev/null
+++ b/data/conduit_box_ui.glade
@@ -0,0 +1,330 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkVBox" id="root">
+ <property name="visible">True</property>
+ <property name="border_width">8</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkImage" id="image16">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-error</property>
+ <property name="icon-size">3</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="conduit_name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Conduit</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox2">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label">gtk-properties</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button5">
+ <property name="label" translatable="yes">Sync</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image14</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <property name="border_width">8</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Not configured</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hadjustment">adjustment1</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="resize_mode">queue</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="source_frame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="border_width">8</property>
+ <property name="left_padding">16</property>
+ <child>
+ <object class="GtkVBox" id="source_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkImage" id="image7">
+ <property name="visible">True</property>
+ <property name="icon_name">stock_up</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Source</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="border_width">4</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="icon_name">stock_down</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Sinks</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">Add sink</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="related_action">add_sink_action</property>
+ <property name="image">image3</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="border_width">8</property>
+ <property name="left_padding">16</property>
+ <child>
+ <object class="GtkVBox" id="sink_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox3">
+ <property name="visible">True</property>
+ <property name="spacing">8</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button4">
+ <property name="label">gtk-revert-to-saved</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button3">
+ <property name="label">gtk-apply</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkImage" id="image14">
+ <property name="visible">True</property>
+ <property name="icon_name">stock_mail-send-receive</property>
+ </object>
+ <object class="GtkAction" id="add_sink_action">
+ <property name="label">Add sink</property>
+ <property name="stock_id">gtk-add</property>
+ <property name="icon_name">add</property>
+ <property name="is_important">True</property>
+ <signal name="activate" handler="on_add_sink_action_activate"/>
+ </object>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ <property name="page_size">10</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </object>
+</interface>
diff --git a/data/conduit_ui.glade b/data/conduit_ui.glade
new file mode 100644
index 0000000..556de5b
--- /dev/null
+++ b/data/conduit_ui.glade
@@ -0,0 +1,300 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="conduits_treemodel"/>
+ <object class="GtkWindow" id="main_window">
+ <property name="default_width">800</property>
+ <property name="default_height">600</property>
+ <signal name="destroy" handler="on_main_window_destroy"/>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem1">
+ <property name="label">gtk-new</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem3">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem4">
+ <property name="label">gtk-save-as</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="label">gtk-cut</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="label">gtk-copy</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="label">gtk-paste</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="toolbar1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkToolButton" id="toolbutton1">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">True</property>
+ <property name="related_action">add_conduit_action</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">toolbutton1</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton2">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">True</property>
+ <property name="related_action">remove_conduit_action</property>
+ <property name="label" translatable="yes">toolbutton2</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem" id="toolbutton3">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton5">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">True</property>
+ <property name="related_action">cancel_sync_action</property>
+ <property name="label" translatable="yes">toolbutton5</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton4">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">True</property>
+ <property name="related_action">sync_conduit_action</property>
+ <property name="label" translatable="yes">toolbutton4</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkTreeView" id="conduits_tree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">conduits_treemodel</property>
+ <property name="headers_visible">False</property>
+ <property name="enable_search">False</property>
+ <signal name="cursor_changed" handler="on_conduits_tree_cursor_changed"/>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="conduits_notebook">
+ <property name="visible">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAction" id="add_conduit_action">
+ <property name="label">Add Conduit</property>
+ <property name="stock_id">gtk-add</property>
+ <property name="is_important">True</property>
+ <signal name="activate" handler="on_add_conduit_action_activate"/>
+ </object>
+ <object class="GtkAction" id="remove_conduit_action">
+ <property name="label">Remove Conduit</property>
+ <property name="stock_id">gtk-delete</property>
+ <property name="sensitive">False</property>
+ <signal name="activate" handler="on_remove_conduit_action_activate"/>
+ </object>
+ <object class="GtkAction" id="sync_conduit_action">
+ <property name="label">Sync</property>
+ <property name="icon_name">mail-send-receive</property>
+ <property name="sensitive">False</property>
+ </object>
+ <object class="GtkAction" id="cancel_sync_action">
+ <property name="label">Cancel</property>
+ <property name="stock_id">gtk-cancel</property>
+ <property name="sensitive">False</property>
+ </object>
+ <object class="GtkActionGroup" id="actiongroup1"/>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]