[conduit/gsoc09_alexandre] UI rewrite (Not 100% functional).



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">&lt;b&gt;Conduit&lt;/b&gt;</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">&lt;b&gt;Source&lt;/b&gt;</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">&lt;b&gt;Sinks&lt;/b&gt;</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]