[gnome-bluetooth] Initial push of a Moblin panel built on gnome-bluetooth



commit 4f72897a4f47157526dec4d67cb77995a6309960
Author: Joshua Lock <josh linux intel com>
Date:   Wed Sep 30 14:08:13 2009 +0100

    Initial push of a Moblin panel built on gnome-bluetooth
    
    This version doesn't do too much but list devices and allow you to remove
    them, plenty of work to be done but it compiles and can be run in
    standalone mode with bluetooth-panel -s.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=596871

 Makefile.am                                        |    8 +-
 configure.ac                                       |   28 +
 lib/bluetooth-chooser-private.h                    |    2 +-
 lib/bluetooth-chooser.c                            |    8 +-
 lib/gnome-bluetooth.symbols                        |    3 +-
 moblin/Makefile.am                                 |   28 +
 moblin/bluetooth-panel.desktop.in.in               |   12 +
 moblin/icons/bluetooth-not-paired-hover.png        |  Bin 0 -> 915 bytes
 moblin/icons/bluetooth-not-paired.png              |  Bin 0 -> 932 bytes
 moblin/icons/bluetooth-strong-hover.png            |  Bin 0 -> 881 bytes
 moblin/icons/bluetooth-strong.png                  |  Bin 0 -> 891 bytes
 moblin/icons/bluetooth-weak-hover.png              |  Bin 0 -> 832 bytes
 moblin/icons/bluetooth-weak.png                    |  Bin 0 -> 842 bytes
 moblin/main.c                                      |   81 +++
 moblin/moblin-copy-n-paste/Makefile.am             |    8 +
 .../koto-cell-renderer-pixbuf.c                    |   97 +++
 .../koto-cell-renderer-pixbuf.h                    |   53 ++
 .../moblin-copy-n-paste/mux-cell-renderer-text.c   |   72 +++
 .../moblin-copy-n-paste/mux-cell-renderer-text.h   |   41 ++
 moblin/moblin-panel.c                              |  614 ++++++++++++++++++++
 moblin/moblin-panel.h                              |   51 ++
 moblin/theme/Makefile.am                           |    9 +
 moblin/theme/bluetooth-panel.css.in                |   25 +
 23 files changed, 1133 insertions(+), 7 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 6f5b395..9391392 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,12 @@
+DEF_SUBDIRS = icons lib applet properties wizard sendto docs po help
 
-SUBDIRS = icons lib applet properties wizard sendto docs po help
+if WITH_MOBLIN
+MOBLIN_DIR = moblin
+endif
+
+SUBDIRS = icons lib applet properties wizard sendto $(MOBLIN_DIR) docs po help
 
+DIST_SUBDIRS = $(DEF_SUBDIRS) moblin
 EXTRA_DIST = intltool-extract.in intltool-update.in intltool-merge.in ChangeLog.pre-2.27 gtk-doc.make gnome-doc-utils.make
 
 # FIXME https://bugzilla.gnome.org/show_bug.cgi?id=595675
diff --git a/configure.ac b/configure.ac
index 966810a..9e89631 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,29 @@ dnl Requires for the plugins
 PKG_CHECK_MODULES(PLUGINS,
 		  gtk+-2.0)
 
+dnl Requires for the moblin interface
+AC_ARG_ENABLE(moblin,
+              AS_HELP_STRING([--enable-moblin=@<:@no/yes/auto@:>@],
+                             [build moblin interface]), ,
+                             enable_moblin=auto)
+
+if test "x$enable_moblin" != "xno"; then
+   PKG_CHECK_MODULES(MOBLIN,
+   [
+      dbus-glib-1,
+      gtk+-2.0,
+      nbtk-gtk-1.2
+      moblin-panel
+   ], have_moblin="yes", have_moblin="no")
+else
+   have_moblin=no
+fi
+
+if test "x$enable_moblin" = "xyes" -a "x$have_moblin" != "xyes"; then
+   AC_MSG_ERROR([Couldn't find Moblin dependencies.])
+fi
+AM_CONDITIONAL(WITH_MOBLIN, test "x$have_moblin" = "xyes")
+
 DBUS_BINDING_TOOL="dbus-binding-tool"
 AC_SUBST(DBUS_BINDING_TOOL)
 
@@ -172,6 +195,10 @@ AC_OUTPUT(Makefile
 	  properties/bluetooth-properties.desktop.in
 	  wizard/Makefile
 	  sendto/Makefile
+	  moblin/Makefile
+	  moblin/bluetooth-panel.desktop.in
+	  moblin/theme/Makefile
+	  moblin/moblin-copy-n-paste/Makefile
 	  docs/Makefile
 	  docs/reference/Makefile
 	  docs/reference/libgnome-bluetooth/Makefile
@@ -186,6 +213,7 @@ Configure summary:
 	Compiler....................:  ${CC}
 	Compiler Flags..............:  ${CFLAGS}
 	Prefix......................:  ${prefix}
+	Moblin interface............:  ${have_moblin}
 	nautilus-sendto plugin......:  ${have_nst}
 	Documentation...............:  ${enable_gtk_doc}
 	GObject-Introspection.......:  ${found_introspection}
diff --git a/lib/bluetooth-chooser-private.h b/lib/bluetooth-chooser-private.h
index 7a551cf..6b3d067 100644
--- a/lib/bluetooth-chooser-private.h
+++ b/lib/bluetooth-chooser-private.h
@@ -9,7 +9,7 @@
 G_BEGIN_DECLS
 
 GtkTreeModel *bluetooth_chooser_get_model (BluetoothChooser *self);
-GtkTreeViewColumn *bluetooth_chooser_get_device_column (BluetoothChooser *self);
+GtkTreeViewColumn *bluetooth_chooser_get_type_column (BluetoothChooser *self);
 GtkWidget *bluetooth_chooser_get_treeview (BluetoothChooser *self);
 gboolean bluetooth_chooser_remove_selected_device (BluetoothChooser *self);
 
diff --git a/lib/bluetooth-chooser.c b/lib/bluetooth-chooser.c
index c61e5b0..4b07497 100644
--- a/lib/bluetooth-chooser.c
+++ b/lib/bluetooth-chooser.c
@@ -426,17 +426,17 @@ bluetooth_chooser_get_model (BluetoothChooser *self)
 }
 
 /**
- * bluetooth_chooser_get_device_column:
+ * bluetooth_chooser_get_type_column:
  * @self: A BluetoothChooser widget.
  *
- * Return value: A GtkTreeViewColumn pointer to the device column of the BluetoothChooser.
+ * Return value: A GtkTreeViewColumn pointer to the type column of the BluetoothChooser.
  **/
 GtkTreeViewColumn *
-bluetooth_chooser_get_device_column (BluetoothChooser *self)
+bluetooth_chooser_get_type_column (BluetoothChooser *self)
 {
 	BluetoothChooserPrivate *priv = BLUETOOTH_CHOOSER_GET_PRIVATE(self);
 
-	return gtk_tree_view_get_column (GTK_TREE_VIEW (priv->treeview), 0);
+	return gtk_tree_view_get_column (GTK_TREE_VIEW (priv->treeview), 1);
 }
 
 /**
diff --git a/lib/gnome-bluetooth.symbols b/lib/gnome-bluetooth.symbols
index ccc97bf..c844024 100644
--- a/lib/gnome-bluetooth.symbols
+++ b/lib/gnome-bluetooth.symbols
@@ -8,7 +8,8 @@ bluetooth_chooser_get_selected_device_icon
 bluetooth_chooser_get_selected_device_type
 bluetooth_chooser_get_selected_device_is_connected
 bluetooth_chooser_get_model
-bluetooth_chooser_get_device_column
+bluetooth_chooser_get_type_column
+bluetooth_chooser_get_treeview
 bluetooth_chooser_start_discovery
 bluetooth_chooser_stop_discovery
 bluetooth_chooser_remove_selected_device
diff --git a/moblin/Makefile.am b/moblin/Makefile.am
new file mode 100644
index 0000000..a17ed40
--- /dev/null
+++ b/moblin/Makefile.am
@@ -0,0 +1,28 @@
+SUBDIRS = moblin-copy-n-paste theme
+
+bin_PROGRAMS = bluetooth-panel
+
+bluetooth_panel_SOURCES = main.c moblin-panel.c moblin-panel.h
+
+bluetooth_panel_LDADD = $(top_builddir)/lib/libcommon.la $(top_builddir)/lib/libgnome-bluetooth.la \
+			$(top_builddir)/moblin/moblin-copy-n-paste/libmoblin.la 
+			$(top_builddir)/wizard/libwizard.la $(MOBLIN_LIBS)
+
+AM_CFLAGS = $(MOBLIN_CFLAGS) $(WARN_CFLAGS) $(DISABLE_DEPRECATED) -DPKGDATADIR="\"$(pkgdatadir)\""
+
+INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/wizard -I$(top_srcdir)/moblin/moblin-copy-n-paste
+
+autostartdir = $(sysconfdir)/xdg/autostart
+
+autostart_in_in_files = bluetooth-panel.desktop.in.in
+autostart_in_files = bluetooth-panel.desktop.in
+
+autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
+
+ INTLTOOL_DESKTOP_RULE@
+
+CLEANFILES = $(autostart_DATA)
+
+EXTRA_DIST = $(autostart_in_in_files)
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/moblin/bluetooth-panel.desktop.in.in b/moblin/bluetooth-panel.desktop.in.in
new file mode 100644
index 0000000..22fdebb
--- /dev/null
+++ b/moblin/bluetooth-panel.desktop.in.in
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+_Name=Moblin Bluetooth Panel
+_Comment=Bluetooth Manager Panel
+Icon=bluetooth
+Exec=bluetooth-panel
+Terminal=false
+Type=Application
+Categories=
+OnlyShowIn=MOBLIN;
+X-GNOME-Autostart-enable=true
diff --git a/moblin/icons/bluetooth-not-paired-hover.png b/moblin/icons/bluetooth-not-paired-hover.png
new file mode 100644
index 0000000..cf356f0
Binary files /dev/null and b/moblin/icons/bluetooth-not-paired-hover.png differ
diff --git a/moblin/icons/bluetooth-not-paired.png b/moblin/icons/bluetooth-not-paired.png
new file mode 100644
index 0000000..3aef3cd
Binary files /dev/null and b/moblin/icons/bluetooth-not-paired.png differ
diff --git a/moblin/icons/bluetooth-strong-hover.png b/moblin/icons/bluetooth-strong-hover.png
new file mode 100644
index 0000000..7394376
Binary files /dev/null and b/moblin/icons/bluetooth-strong-hover.png differ
diff --git a/moblin/icons/bluetooth-strong.png b/moblin/icons/bluetooth-strong.png
new file mode 100644
index 0000000..852773f
Binary files /dev/null and b/moblin/icons/bluetooth-strong.png differ
diff --git a/moblin/icons/bluetooth-weak-hover.png b/moblin/icons/bluetooth-weak-hover.png
new file mode 100644
index 0000000..65954c9
Binary files /dev/null and b/moblin/icons/bluetooth-weak-hover.png differ
diff --git a/moblin/icons/bluetooth-weak.png b/moblin/icons/bluetooth-weak.png
new file mode 100644
index 0000000..15d77e1
Binary files /dev/null and b/moblin/icons/bluetooth-weak.png differ
diff --git a/moblin/main.c b/moblin/main.c
new file mode 100644
index 0000000..0d05906
--- /dev/null
+++ b/moblin/main.c
@@ -0,0 +1,81 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <glib/gi18n.h>
+#include <nbtk/nbtk-gtk.h>
+#include <moblin-panel/mpl-panel-common.h>
+#include <moblin-panel/mpl-panel-gtk.h>
+
+#include "moblin-panel.h"
+
+#define PKGTHEMEDIR PKGDATADIR"/theme"
+
+static void
+make_window_content (GtkWidget *panel)
+{
+	GtkWidget *content;
+
+	content = moblin_panel_new ();
+	gtk_widget_set_size_request (content, 800, -1);
+	gtk_widget_show (content);
+
+	gtk_container_add (GTK_CONTAINER (panel), content);
+	gtk_widget_show (panel);
+}
+
+int
+main (int argc, char *argv[])
+{
+	MplPanelClient *panel;
+	GtkWidget      *window;
+	gboolean        standalone = FALSE;
+	GtkSettings    *settings;
+	GError         *error = NULL;
+	GOptionEntry    entries[] = {
+		{ "standalone", 's', 0, G_OPTION_ARG_NONE, &standalone,
+		_("Run in standalone mode"), NULL },
+		{ NULL }
+	};
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	g_set_application_name (_("Moblin Bluetooth Panel"));
+	gtk_init_with_args (&argc, &argv, _("- Moblin Bluetooth Panel"),
+				entries, GETTEXT_PACKAGE, &error);
+
+	if (error) {
+		g_printerr ("%s\n", error->message);
+		g_error_free (error);
+		return 1;
+	}
+
+	/* Force to correct theme */
+	settings = gtk_settings_get_default ();
+	gtk_settings_set_string_property (settings, "gtk-theme-name",
+					"Moblin-Netbook", NULL);
+
+	if (standalone) {
+		window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+		g_signal_connect (window, "delete-event", (GCallback) gtk_main_quit,
+				NULL);
+		gtk_widget_set_size_request (window, 1000, -1);
+		make_window_content (window);
+	}  else {
+		panel = mpl_panel_gtk_new (MPL_PANEL_BLUETOOTH, _("bluetooth"),
+					PKGTHEMEDIR "/bluetooth-panel.css",
+					"state-dile", TRUE);
+		mpl_panel_client_set_height_request (panel, 450);
+		window  = mpl_panel_gtk_get_window (MPL_PANEL_GTK (panel));
+
+		make_window_content (GTK_WIDGET (panel));
+	}
+
+	gtk_main ();
+
+	return 0;
+}
diff --git a/moblin/moblin-copy-n-paste/Makefile.am b/moblin/moblin-copy-n-paste/Makefile.am
new file mode 100644
index 0000000..3c9d2f1
--- /dev/null
+++ b/moblin/moblin-copy-n-paste/Makefile.am
@@ -0,0 +1,8 @@
+noinst_LTLIBRARIES = libmoblin.la
+libmoblin_la_CFLAGS = $(MOBLIN_CFLAGS) \
+	              -DPKG_DATADIR=\"$(pkgdatadir)\" -Wall
+libmoblin_la_LIBADD = $(MOBLIN_LIBS)
+libmoblin_la_SOURCES = koto-cell-renderer-pixbuf.c \
+		       koto-cell-renderer-pixbuf.h \
+		       mux-cell-renderer-text.c \
+		       mux-cell-renderer-text.h
diff --git a/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.c b/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.c
new file mode 100644
index 0000000..b4ab170
--- /dev/null
+++ b/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 OpenedHand Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include "koto-cell-renderer-pixbuf.h"
+
+G_DEFINE_TYPE (KotoCellRendererPixbuf,
+               koto_cell_renderer_pixbuf,
+               GTK_TYPE_CELL_RENDERER_PIXBUF);
+
+enum {
+  ACTIVATED,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/*
+ * Utility function to determine if a point is inside a rectangle
+ */
+G_GNUC_CONST static gboolean
+contains (GdkRectangle *rect, int x, int y)
+{
+  return (rect->x + rect->width) > x && rect->x <= x &&
+    (rect->y + rect->height) > y && rect->y <= y;
+}
+
+static gboolean
+koto_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
+                                    GdkEvent *event, GtkWidget *widget,
+                                    const gchar *path,
+                                    GdkRectangle *background_area,
+                                    GdkRectangle *cell_area,
+                                    GtkCellRendererState flags)
+{
+  gdouble x, y;
+
+  if (event && gdk_event_get_coords (event, &x, &y)) {
+    if (contains (cell_area, (int)x, (int)y)) {
+      g_signal_emit (cell, signals[ACTIVATED], 0, path);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/*
+ * Object methods
+ */
+
+static void
+koto_cell_renderer_pixbuf_class_init (KotoCellRendererPixbufClass *class)
+{
+  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+
+  cell_class->activate = koto_cell_renderer_pixbuf_activate;
+
+  signals[ACTIVATED] =
+    g_signal_new ("activated",
+                  G_OBJECT_CLASS_TYPE (class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (KotoCellRendererPixbufClass, activated),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__STRING,
+                  G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+koto_cell_renderer_pixbuf_init (KotoCellRendererPixbuf *cellpixbuf)
+{
+  GTK_CELL_RENDERER (cellpixbuf)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+}
+
+/*
+ * Public methods
+ */
+
+GtkCellRenderer *
+koto_cell_renderer_pixbuf_new (void)
+{
+  return g_object_new (KOTO_TYPE_CELL_RENDERER_PIXBUF, NULL);
+}
diff --git a/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.h b/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.h
new file mode 100644
index 0000000..e8347f9
--- /dev/null
+++ b/moblin/moblin-copy-n-paste/koto-cell-renderer-pixbuf.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 OpenedHand Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __KOTO_CELL_RENDERER_PIXBUF_H__
+#define __KOTO_CELL_RENDERER_PIXBUF_H__
+
+#include <gtk/gtkcellrendererpixbuf.h>
+
+G_BEGIN_DECLS
+
+#define KOTO_TYPE_CELL_RENDERER_PIXBUF			(koto_cell_renderer_pixbuf_get_type ())
+#define KOTO_CELL_RENDERER_PIXBUF(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), KOTO_TYPE_CELL_RENDERER_PIXBUF, KotoCellRendererPixbuf))
+#define KOTO_CELL_RENDERER_PIXBUF_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), KOTO_TYPE_CELL_RENDERER_PIXBUF, KotoCellRendererPixbufClass))
+#define KOTO_IS_CELL_RENDERER_PIXBUF(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), KOTO_TYPE_CELL_RENDERER_PIXBUF))
+#define KOTO_IS_CELL_RENDERER_PIXBUF_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), KOTO_TYPE_CELL_RENDERER_PIXBUF))
+#define KOTO_CELL_RENDERER_PIXBUF_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), KOTO_TYPE_CELL_RENDERER_PIXBUF, KotoCellRendererPixbufClass))
+
+typedef struct _KotoCellRendererPixbuf KotoCellRendererPixbuf;
+typedef struct _KotoCellRendererPixbufClass KotoCellRendererPixbufClass;
+
+struct _KotoCellRendererPixbuf
+{
+  GtkCellRendererPixbuf parent;
+};
+
+struct _KotoCellRendererPixbufClass
+{
+  GtkCellRendererPixbufClass parent_class;
+
+  void (* activated) (KotoCellRendererPixbuf *cell, const char *path);
+};
+
+GType koto_cell_renderer_pixbuf_get_type (void) G_GNUC_CONST;
+GtkCellRenderer *koto_cell_renderer_pixbuf_new (void);
+
+G_END_DECLS
+
+#endif /* __KOTO_CELL_RENDERER_PIXBUF_H__ */
diff --git a/moblin/moblin-copy-n-paste/mux-cell-renderer-text.c b/moblin/moblin-copy-n-paste/mux-cell-renderer-text.c
new file mode 100644
index 0000000..ce07026
--- /dev/null
+++ b/moblin/moblin-copy-n-paste/mux-cell-renderer-text.c
@@ -0,0 +1,72 @@
+#include "mux-cell-renderer-text.h"
+
+G_DEFINE_TYPE (MuxCellRendererText,
+	       mux_cell_renderer_text,
+	       GTK_TYPE_CELL_RENDERER_TEXT)
+
+enum {
+  ACTIVATED,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static gboolean
+contains (GdkRectangle *rect, gint x, gint y)
+{
+  return (rect->x + rect->width) > x && rect->x <= x &&
+  	 (rect->y + rect->height) > y && rect->y <= y;
+}
+
+static gboolean
+mux_cell_renderer_text_activate (GtkCellRenderer     *cell,
+				 GdkEvent            *event,
+				 GtkWidget           *widget,
+				 const gchar         *path,
+				 GdkRectangle        *bg_area,
+				 GdkRectangle        *cell_area,
+				 GtkCellRendererState flags)
+{
+  gdouble x, y;
+
+  if (event) {
+    gdk_event_get_coords (event, &x, &y);
+    if (contains (cell_area, (gint) x, (gint) y)) {
+      g_signal_emit (cell, signals[ACTIVATED], 0, path);
+
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+static void
+mux_cell_renderer_text_class_init (MuxCellRendererTextClass *klass)
+{
+  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+  cell_class->activate = mux_cell_renderer_text_activate;
+
+  signals[ACTIVATED] =
+    g_signal_new ("activated",
+    		  G_OBJECT_CLASS_TYPE (klass),
+    		  G_SIGNAL_RUN_LAST,
+    		  G_STRUCT_OFFSET (MuxCellRendererTextClass, activated),
+    		  NULL,
+    		  NULL,
+    		  g_cclosure_marshal_VOID__STRING,
+    		  G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+mux_cell_renderer_text_init (MuxCellRendererText *self)
+{
+  GTK_CELL_RENDERER (self)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+}
+
+GtkCellRenderer*
+mux_cell_renderer_text_new (void)
+{
+  return g_object_new (MUX_TYPE_CELL_RENDERER_TEXT, NULL);
+}
diff --git a/moblin/moblin-copy-n-paste/mux-cell-renderer-text.h b/moblin/moblin-copy-n-paste/mux-cell-renderer-text.h
new file mode 100644
index 0000000..7635418
--- /dev/null
+++ b/moblin/moblin-copy-n-paste/mux-cell-renderer-text.h
@@ -0,0 +1,41 @@
+#ifndef _MUX_CELL_RENDERER_TEXT
+#define _MUX_CELL_RENDERER_TEXT
+
+#include <gtk/gtkcellrenderertext.h>
+
+G_BEGIN_DECLS
+
+#define MUX_TYPE_CELL_RENDERER_TEXT mux_cell_renderer_text_get_type()
+
+#define MUX_CELL_RENDERER_TEXT(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUX_TYPE_CELL_RENDERER_TEXT, MuxCellRendererText))
+
+#define MUX_CELL_RENDERER_TEXT_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), MUX_TYPE_CELL_RENDERER_TEXT, MuxCellRendererTextClass))
+
+#define MUX_IS_CELL_RENDERER_TEXT(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUX_TYPE_CELL_RENDERER_TEXT))
+
+#define MUX_IS_CELL_RENDERER_TEXT_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), MUX_TYPE_CELL_RENDERER_TEXT))
+
+#define MUX_CELL_RENDERER_TEXT_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), MUX_TYPE_CELL_RENDERER_TEXT, MuxCellRendererTextClass))
+
+typedef struct {
+  GtkCellRendererText parent;
+} MuxCellRendererText;
+
+typedef struct {
+  GtkCellRendererTextClass parent_class;
+  void (*activated) (MuxCellRendererText *cell, const gchar *path);
+} MuxCellRendererTextClass;
+
+GType mux_cell_renderer_text_get_type (void);
+
+GtkCellRenderer* mux_cell_renderer_text_new (void);
+
+G_END_DECLS
+
+#endif /* _MUX_CELL_RENDERER_TEXT */
+
diff --git a/moblin/moblin-panel.c b/moblin/moblin-panel.c
new file mode 100644
index 0000000..8a0ea2c
--- /dev/null
+++ b/moblin/moblin-panel.c
@@ -0,0 +1,614 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <nbtk/nbtk-gtk.h>
+
+#include "bluetooth-client.h"
+#include "bluetooth-chooser.h"
+#include "bluetooth-chooser-private.h"
+#include "bluetooth-killswitch.h"
+#include "bluetooth-plugin-manager.h"
+#include "bluetooth-agent.h"
+#include "bluetooth-filter-widget.h"
+
+#include "pin.h"
+
+#include "mux-cell-renderer-text.h"
+#include "koto-cell-renderer-pixbuf.h"
+
+#include "moblin-panel.h"
+
+G_DEFINE_TYPE (MoblinPanel, moblin_panel, GTK_TYPE_HBOX)
+
+#define MOBLIN_PANEL_GET_PRIVATE(o)                                         \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MOBLIN_TYPE_PANEL, MoblinPanelPrivate))
+
+struct _MoblinPanelPrivate
+{
+	BluetoothClient *client;
+	BluetoothKillswitch *killswitch;
+	BluetoothAgent *agent;
+
+	GtkWidget *device_list_frame;
+	GtkWidget *chooser;
+	GtkWidget *power_switch;
+	GtkWidget *power_label;
+	GtkWidget *filter;
+	GtkWidget *action_button;
+	GtkWidget *scan_label;
+	
+	GtkTreeModel *chooser_model;
+	
+	gboolean target_ssp;
+	gchar *pincode;
+	gboolean automatic_pincode;
+};
+
+static void set_scanning_view (GtkButton *button, gpointer   user_data);
+static void send_file_button_clicked_cb (GtkButton *button, gpointer   user_data);
+static void pin_options_button_clicked_cb (GtkButton *button, gpointer   user_data);
+
+static void
+power_switch_toggled_cb (NbtkGtkLightSwitch *light_switch,
+                         gpointer            user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE(user_data);
+
+	if (nbtk_gtk_light_switch_get_active (NBTK_GTK_LIGHT_SWITCH (light_switch))) {
+		bluetooth_killswitch_set_state (priv->killswitch, KILLSWITCH_STATE_UNBLOCKED);
+	} else {
+		bluetooth_killswitch_set_state (priv->killswitch, KILLSWITCH_STATE_SOFT_BLOCKED);
+	}
+}
+
+static void
+killswitch_state_changed_cb (BluetoothKillswitch *killswitch,
+                             KillswitchState      state,
+                             gpointer             user_data)
+{
+	MoblinPanel        *self = user_data;
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (self);
+
+	g_signal_handlers_disconnect_by_func (priv->power_switch, power_switch_toggled_cb,
+                                        NULL);
+
+	g_return_if_fail (self != NULL);
+
+	if (state == KILLSWITCH_STATE_SOFT_BLOCKED) {
+		nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->power_switch),
+	                                      FALSE);
+		gtk_widget_set_sensitive (priv->power_switch, TRUE);
+	} else if (state == KILLSWITCH_STATE_UNBLOCKED) {
+		nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->power_switch), TRUE);
+		gtk_widget_set_sensitive (priv->power_switch, TRUE);
+	} else if (state == KILLSWITCH_STATE_HARD_BLOCKED) {
+		gtk_widget_set_sensitive (priv->power_switch, FALSE);
+	} else {
+		g_assert_not_reached ();
+	}
+
+	g_signal_connect (priv->power_switch, "switch-flipped", 
+			G_CALLBACK (power_switch_toggled_cb), self);
+}
+
+static void
+selected_device_changed_cb (BluetoothChooser *chooser, const char *address, gpointer data)
+{
+	MoblinPanel *self = MOBLIN_PANEL (data);
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (self);
+	
+	if (!address) {
+		gtk_widget_set_sensitive (priv->action_button, FALSE);	
+	} else {
+		gtk_widget_set_sensitive (priv->action_button, TRUE);
+	}
+}
+
+static void
+set_frame_title (GtkFrame *frame, gchar *title)
+{
+	GtkWidget *frame_title;
+	gchar *label = NULL;
+
+	label = g_strdup_printf ("<span font_desc=\"Liberation Sans Bold 18px\""
+	                           "foreground=\"#3e3e3e\">%s</span>", title);
+	frame_title = gtk_frame_get_label_widget (frame);
+	gtk_label_set_markup (GTK_LABEL (frame_title), label);
+	g_free (label);
+	gtk_widget_show (frame_title);
+}
+
+static void
+set_default_view (GtkButton *button, gpointer user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (user_data);
+
+	set_frame_title (GTK_FRAME (priv->device_list_frame), _("Devices"));
+
+	bluetooth_chooser_stop_discovery (BLUETOOTH_CHOOSER (priv->chooser));
+	g_object_set (priv->chooser, "show-searching", FALSE, "device-category-filter",
+	                BLUETOOTH_CATEGORY_PAIRED_OR_TRUSTED, NULL);
+
+	g_signal_handlers_disconnect_by_func (button, set_default_view, user_data);
+	gtk_button_set_label (button, _("Add a new device"));
+	g_signal_connect (button, "clicked", G_CALLBACK (set_scanning_view), user_data);
+	gtk_widget_show (priv->power_switch);
+	gtk_widget_show (priv->power_label);
+
+	g_signal_handlers_disconnect_by_func (priv->action_button, pin_options_button_clicked_cb,
+                                        	NULL);
+	gtk_button_set_label (GTK_BUTTON (priv->action_button), _("Send file from your computer"));
+	gtk_widget_show (priv->action_button);
+	g_signal_connect (priv->action_button, "clicked", G_CALLBACK (send_file_button_clicked_cb),
+                    NULL);
+	gtk_widget_hide (priv->scan_label);
+	
+	g_signal_connect (priv->chooser, "selected-device-changed",
+			G_CALLBACK (selected_device_changed_cb), MOBLIN_PANEL (user_data));
+
+	gtk_widget_hide (priv->filter);
+}
+
+static void
+set_scanning_view (GtkButton *button, gpointer   user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (user_data);
+
+	set_frame_title (GTK_FRAME (priv->device_list_frame), _("Add a new Bluetooth device"));
+
+	g_object_set (priv->chooser, "show-searching", TRUE, "device-category-filter",
+                BLUETOOTH_CATEGORY_NOT_PAIRED_OR_TRUSTED, NULL);
+
+	g_signal_handlers_disconnect_by_func (button, set_scanning_view, user_data);
+        gtk_button_set_label (button, _("Back to devices"));
+	g_signal_connect (button, "clicked", G_CALLBACK (set_default_view),
+                    	user_data);
+
+	bluetooth_chooser_start_discovery (BLUETOOTH_CHOOSER (priv->chooser));
+	gtk_widget_hide (priv->power_switch);
+	gtk_widget_hide (priv->power_label);
+
+	g_signal_handlers_disconnect_by_func (priv->action_button,
+        	                                send_file_button_clicked_cb, NULL);
+        g_signal_handlers_disconnect_by_func (priv->chooser, selected_device_changed_cb,
+        					MOBLIN_PANEL (user_data));
+	gtk_button_set_label (GTK_BUTTON (priv->action_button), _("PIN options"));
+	gtk_widget_show (priv->action_button);
+	g_signal_connect (priv->action_button, "clicked",
+                    G_CALLBACK (pin_options_button_clicked_cb), NULL);
+	gtk_widget_show (priv->scan_label);
+
+	gtk_widget_show (priv->filter);
+}
+
+static void
+set_pairing_view (MoblinPanel *self)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (self);
+
+	set_frame_title (GTK_FRAME (priv->device_list_frame), _("Device setup"));
+
+	gtk_widget_hide (priv->chooser);
+
+	g_signal_handlers_disconnect_by_func (priv->action_button,
+        	                                send_file_button_clicked_cb, NULL);
+        g_signal_handlers_disconnect_by_func (priv->chooser, selected_device_changed_cb,
+        					self);
+	gtk_widget_hide (priv->action_button);
+
+	gtk_widget_hide (priv->scan_label);
+
+	gtk_widget_hide (priv->filter);
+}
+
+static void
+send_file_button_clicked_cb (GtkButton *button,
+                             gpointer   user_data)
+{
+	MoblinPanel *self = MOBLIN_PANEL (user_data);
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (self);
+	GPtrArray *a;
+	GError *err = NULL;
+	guint i;
+	const char *address, *name;
+
+	address = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (priv->chooser));
+	name = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (priv->chooser));
+
+	a = g_ptr_array_new ();
+	g_ptr_array_add (a, "bluetooth-sendto");
+	if (address != NULL) {
+		char *s;
+
+		s = g_strdup_printf ("--device=\"%s\"", address);
+		g_ptr_array_add (a, s);
+	}
+	if (address != NULL && name != NULL) {
+		char *s;
+
+		s = g_strdup_printf ("--name=\"%s\"", name);
+		g_ptr_array_add (a, s);
+	}
+	g_ptr_array_add (a, NULL);
+
+	if (g_spawn_async(NULL, (char **) a->pdata, NULL,
+			  G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &err) == FALSE) {
+		g_printerr("Couldn't execute command: %s\n", err->message);
+		g_error_free (err);
+	}
+
+	for (i = 1; a->pdata[i] != NULL; i++)
+		g_free (a->pdata[i]);
+
+	g_ptr_array_free (a, TRUE);
+}
+
+static void
+pin_options_button_clicked_cb (GtkButton *button,
+                             gpointer   user_data)
+{
+	g_debug ("PIN options clicked.");
+}
+
+static void
+remove_clicked_cb (GtkCellRenderer *cell, gchar *path, gpointer user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (user_data);
+	GtkTreeView *view = bluetooth_chooser_get_treeview (BLUETOOTH_CHOOSER (priv->chooser));
+	gchar *address = NULL;
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	GtkTreePath *tree_path;
+
+	/* Set selection */
+	tree_path = gtk_tree_path_new_from_string (path);
+	gtk_tree_view_set_cursor (view, tree_path, NULL, FALSE);
+	gtk_tree_path_free (tree_path);
+	/* Get address */
+	selection = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter) == FALSE)
+		return;
+
+	bluetooth_chooser_remove_selected_device (BLUETOOTH_CHOOSER (priv->chooser));
+	//bluetooth_plugin_manager_device_deleted (address);
+}
+
+static void
+set_pin_view (MoblinPanel *self)
+{
+	g_debug ("Show PIN");
+}
+
+static gboolean
+pincode_callback (DBusGMethodInvocation *context,
+		  DBusGProxy *device,
+		  gpointer user_data)
+{
+	MoblinPanel *self = MOBLIN_PANEL (user_data);
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (self);
+	
+	priv->target_ssp = FALSE;
+	if (priv->automatic_pincode == FALSE)
+		set_pin_view (self);
+	dbus_g_method_return (context, priv->pincode);
+	
+	return TRUE;
+}
+
+static void
+activity_clicked (GtkCellRenderer *renderer, const gchar *path, gpointer user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (user_data);
+	GtkTreeIter iter;
+	DBusGProxy *proxy = NULL;
+	char *address = NULL;
+	char *name = NULL;
+	GtkTreePath *tree_path;
+	
+	tree_path = gtk_tree_path_new_from_string (path);
+	gtk_tree_model_get_iter (priv->chooser_model, &iter, tree_path);
+	gtk_tree_model_get (priv->chooser_model, &iter, BLUETOOTH_COLUMN_PROXY, &proxy,
+			   BLUETOOTH_COLUMN_ADDRESS, &address,
+			   BLUETOOTH_COLUMN_NAME, &name, -1);
+			   
+	if (address == NULL || name == NULL || proxy == NULL) {
+		g_object_unref (proxy);
+		g_free (address);
+		g_free (name);
+		return;
+	}
+	
+	g_debug ("Activity clicked on %s", address);
+	
+	g_free (address);
+	g_free (name);
+	g_object_unref (proxy);
+}
+
+static void
+connect_clicked (GtkCellRenderer *renderer, const gchar *path, gpointer user_data)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (user_data);
+	GtkTreeIter iter;
+	DBusGProxy *proxy = NULL;
+	char *address = NULL;
+	char *name = NULL;
+	GtkTreePath *tree_path;
+	
+	tree_path = gtk_tree_path_new_from_string (path);
+	gtk_tree_model_get_iter (priv->chooser_model, &iter, tree_path);
+	gtk_tree_model_get (priv->chooser_model, &iter, BLUETOOTH_COLUMN_PROXY, &proxy,
+			   BLUETOOTH_COLUMN_ADDRESS, &address,
+			   BLUETOOTH_COLUMN_NAME, &name, -1);
+			   
+	if (address == NULL || name == NULL || proxy == NULL) {
+		g_object_unref (proxy);
+		g_free (address);
+		g_free (name);
+		return;
+	}
+	
+	g_debug ("Connect clicked on %s", address);
+
+	/*bluetooth_agent_set_pincode_func (priv->agent, pincode_callback, self);
+	bluetooth_agent_set_display_func (priv->agent, display_callback, self);
+	bluetooth_agent_set_cancel_func (priv->agent, cancel_callback, self);
+	bluetooth_agent_set_confirm_func (priv->agent, confirm_callback, self);
+	bluetooth_agent_setup (priv->agent, bluetooth_path);
+	
+	set_pairing_view (self);*/
+	
+	g_free (address);
+	g_free (name);
+	g_object_unref (proxy);
+}
+
+static void
+remove_to_icon (GtkTreeViewColumn *column, GtkCellRenderer *cell,
+		GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	gboolean paired, trusted;
+	
+	gtk_tree_model_get (model, iter, BLUETOOTH_COLUMN_PAIRED, &paired,
+			BLUETOOTH_COLUMN_TRUSTED, &trusted, -1);
+	
+	if (paired || trusted) {
+		g_object_set (cell, "icon-name", GTK_STOCK_CLEAR, NULL);
+	} else {
+		g_object_set (cell, "icon-name", NULL, NULL);
+	}
+}
+
+static void
+activity_to_text (GtkTreeViewColumn *column, GtkCellRenderer *cell,
+		GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	gboolean paired, trusted;
+	
+	gtk_tree_model_get (model, iter, BLUETOOTH_COLUMN_PAIRED, &paired,
+			BLUETOOTH_COLUMN_TRUSTED, &trusted, -1);
+
+	if (paired || trusted) {
+		g_object_set (cell, "markup", _("Activity"), NULL);
+	}
+}
+
+static void
+connect_to_text (GtkTreeViewColumn *column, GtkCellRenderer *cell,
+		GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	gboolean paired, trusted;
+	
+	gtk_tree_model_get (model, iter, BLUETOOTH_COLUMN_PAIRED, &paired,
+			BLUETOOTH_COLUMN_TRUSTED, &trusted, -1);
+
+	if (paired || trusted) {
+		g_object_set (cell, "markup", _("Connect"), NULL);
+	}
+}
+
+static void
+moblin_panel_dispose (GObject *object)
+{
+	MoblinPanelPrivate *priv = MOBLIN_PANEL_GET_PRIVATE (object);
+	
+	bluetooth_plugin_manager_cleanup ();
+	
+	//g_object_unref (priv->agent);
+	//g_object_unref (priv->client);
+	
+	G_OBJECT_CLASS (moblin_panel_parent_class)->dispose (object);
+}
+
+static void
+moblin_panel_class_init (MoblinPanelClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS (klass);
+	
+	g_type_class_add_private (klass, sizeof (MoblinPanelPrivate));
+	
+	obj_class->dispose = moblin_panel_dispose;
+}
+
+static void
+moblin_panel_init (MoblinPanel *self)
+{
+	MoblinPanelPrivate *priv;
+	GtkWidget *add_new_button;
+	GtkWidget *frame_title;
+	GtkWidget *vbox, *hbox;
+	gchar *scan_text = NULL;
+	KillswitchState switch_state;
+	GtkSizeGroup *group;
+	GtkTreeViewColumn *type_column;
+	GtkCellRenderer *cell;
+
+	priv = MOBLIN_PANEL_GET_PRIVATE (self);
+	
+	priv->target_ssp = FALSE;
+	priv->pincode = FALSE;
+	priv->automatic_pincode = FALSE;
+
+	priv->client = bluetooth_client_new ();
+	priv->killswitch = bluetooth_killswitch_new ();
+	if (bluetooth_killswitch_has_killswitches (priv->killswitch) == FALSE) {
+		g_object_unref (priv->killswitch);
+		priv->killswitch = NULL;
+	} else {
+		g_signal_connect  (priv->killswitch, "state-changed",
+                       G_CALLBACK (killswitch_state_changed_cb), self);
+	}
+	
+	priv->agent = bluetooth_agent_new ();
+	bluetooth_plugin_manager_init ();
+
+	/* set up the box */
+	gtk_box_set_homogeneous (GTK_BOX (self), FALSE);
+	gtk_box_set_spacing (GTK_BOX (self), 4);
+
+	/* Add child widgetry */
+	vbox = gtk_vbox_new (FALSE, 4);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (self), vbox, TRUE, TRUE, 4);
+
+	priv->device_list_frame = nbtk_gtk_frame_new ();
+	frame_title = gtk_label_new ("");
+	gtk_frame_set_label_widget (GTK_FRAME (priv->device_list_frame), frame_title);
+	set_frame_title (GTK_FRAME (priv->device_list_frame), _("Devices"));
+
+	/* Device list */
+	priv->chooser = g_object_new (BLUETOOTH_TYPE_CHOOSER,
+				      "has-internal-device-filter", FALSE,
+		      		      "show-device-category", FALSE,
+				      NULL);
+	
+	priv->chooser_model = bluetooth_chooser_get_model (BLUETOOTH_CHOOSER (priv->chooser));
+	type_column = bluetooth_chooser_get_type_column (BLUETOOTH_CHOOSER (priv->chooser));
+	
+	/* Add the activity button */
+	cell = mux_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (type_column, cell, FALSE);
+
+	gtk_tree_view_column_set_cell_data_func (type_column, cell,
+						 activity_to_text, self, NULL);
+	g_signal_connect (cell, "activated", G_CALLBACK (activity_clicked), self);
+
+	/* Add the connect button */
+	cell = mux_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (type_column, cell, FALSE);
+
+	gtk_tree_view_column_set_cell_data_func (type_column, cell,
+						 connect_to_text, self, NULL);
+	g_signal_connect (cell, "activated", G_CALLBACK (connect_clicked), self);
+	
+	/* Add the remove button */
+	cell = koto_cell_renderer_pixbuf_new ();
+	gtk_tree_view_column_pack_end (type_column, cell, FALSE);
+	
+	gtk_tree_view_column_set_cell_data_func (type_column, cell,
+						remove_to_icon, self, NULL);
+	g_signal_connect (cell, "activated", G_CALLBACK (remove_clicked_cb), self);
+	
+	g_signal_connect (priv->chooser, "selected-device-changed",
+			G_CALLBACK (selected_device_changed_cb), self);
+
+	gtk_widget_show (priv->chooser);
+	gtk_container_add (GTK_CONTAINER (priv->device_list_frame), priv->chooser);
+	gtk_widget_show (priv->device_list_frame);
+	gtk_box_pack_start (GTK_BOX (vbox), priv->device_list_frame,
+                      FALSE, FALSE, 4);
+
+	/* Add new button */
+	add_new_button = gtk_button_new_with_label (_("Add a new device"));
+	gtk_widget_show (add_new_button);
+	g_signal_connect (add_new_button, "clicked",
+			G_CALLBACK (set_scanning_view), self);
+	gtk_box_pack_start (GTK_BOX (vbox), add_new_button, FALSE, FALSE, 4);
+
+	/* Right column */
+	//group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+	vbox = gtk_vbox_new (FALSE, 4);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (self), vbox, FALSE, FALSE, 4);
+
+	hbox = gtk_hbox_new (FALSE, 4);
+	gtk_widget_show (hbox);
+	//gtk_size_group_add_widget (group, hbox);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
+
+	/* Power switch */
+	priv->power_label = gtk_label_new (_("Turn Bluetooth"));
+	gtk_widget_show (priv->power_label);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->power_label, FALSE, FALSE, 4);
+
+	priv->power_switch = nbtk_gtk_light_switch_new ();
+	if (priv->killswitch != NULL) {
+		switch_state = bluetooth_killswitch_get_state (priv->killswitch);
+
+		switch (switch_state) {
+			case KILLSWITCH_STATE_UNBLOCKED:
+				nbtk_gtk_light_switch_set_active
+					(NBTK_GTK_LIGHT_SWITCH (priv->power_switch),
+         					TRUE);
+			break;
+			case KILLSWITCH_STATE_SOFT_BLOCKED:
+				nbtk_gtk_light_switch_set_active
+					(NBTK_GTK_LIGHT_SWITCH (priv->power_switch),
+						FALSE);
+			break;
+			case KILLSWITCH_STATE_HARD_BLOCKED:
+			default:
+				gtk_widget_set_sensitive (priv->power_switch, FALSE);
+			break;
+		}
+	} else {
+		gtk_widget_set_sensitive (priv->power_switch, FALSE);
+	}
+	gtk_widget_show (priv->power_switch);
+	g_signal_connect (priv->power_switch, "switch-flipped",
+                    G_CALLBACK (power_switch_toggled_cb), self);
+	gtk_box_pack_start (GTK_BOX (hbox), priv->power_switch, FALSE, FALSE, 4);
+
+	/* Filter combo */
+	priv->filter = bluetooth_filter_widget_new ();
+	bluetooth_filter_widget_set_title (BLUETOOTH_FILTER_WIDGET (priv->filter), _("Only show:"));
+	bluetooth_filter_widget_bind_filter (BLUETOOTH_FILTER_WIDGET (priv->filter),
+					     BLUETOOTH_CHOOSER (priv->chooser));
+	gtk_box_pack_start (GTK_BOX (vbox), priv->filter, FALSE, FALSE, 4);
+
+	/* Button for Send file/PIN options */
+	priv->action_button = gtk_button_new_with_label (_("Send file from your computer"));
+	gtk_widget_show (priv->action_button);
+	//gtk_size_group_add_widget (group, priv->action_button);
+	g_signal_connect (priv->action_button, "clicked",
+                    G_CALLBACK (send_file_button_clicked_cb), self);
+	gtk_box_pack_start (GTK_BOX (vbox), priv->action_button, FALSE, FALSE, 4);
+
+	/* Scanning "help" label */
+	scan_text = g_strdup (_("Searching for devices.\n\n"
+                          	"Please make sure they're nearby and in 'discoverable' or "
+	                        "'visible' mode. Check your devices manual if you have "
+	                        "problems."));
+	priv->scan_label = gtk_label_new (scan_text);
+	//gtk_size_group_add_widget (group, priv->scan_label);
+	gtk_label_set_line_wrap (GTK_LABEL (priv->scan_label), TRUE);
+	g_free (scan_text);
+	gtk_box_pack_start (GTK_BOX (vbox), priv->scan_label, FALSE, FALSE, 4);
+
+	//g_object_unref (group);
+}
+
+/**
+ * moblin_panel_new:
+ *
+ * Return value: A #MoblinPanel widget
+ **/
+GtkWidget *
+moblin_panel_new (void)
+{
+	return g_object_new (MOBLIN_TYPE_PANEL, NULL);
+}
diff --git a/moblin/moblin-panel.h b/moblin/moblin-panel.h
new file mode 100644
index 0000000..927a8cf
--- /dev/null
+++ b/moblin/moblin-panel.h
@@ -0,0 +1,51 @@
+#ifndef _MOBLIN_PANEL_H
+#define _MOBLIN_PANEL_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define MOBLIN_TYPE_PANEL moblin_panel_get_type()
+
+#define MOBLIN_PANEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  MOBLIN_TYPE_PANEL, MoblinPanel))
+
+#define MOBLIN_PANEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  MOBLIN_TYPE_PANEL, MoblinPanelClass))
+
+#define MOBLIN_IS_PANEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  MOBLIN_TYPE_PANEL))
+
+#define MOBLIN_IS_PANEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  MOBLIN_TYPE_PANEL))
+
+#define MOBLIN_PANEL_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  MOBLIN_TYPE_PANEL, MoblinPanelClass))
+
+typedef struct _MoblinPanel MoblinPanel;
+typedef struct _MoblinPanelClass MoblinPanelClass;
+typedef struct _MoblinPanelPrivate MoblinPanelPrivate;
+
+struct _MoblinPanel
+{
+  GtkHBox parent;
+};
+
+struct _MoblinPanelClass
+{
+  GtkHBoxClass parent_class;
+  MoblinPanelPrivate *priv;
+};
+
+GType moblin_panel_get_type (void);
+
+GtkWidget *moblin_panel_new (void);
+
+G_END_DECLS
+
+#endif /* _MOBLIN_PANEL_H */
diff --git a/moblin/theme/Makefile.am b/moblin/theme/Makefile.am
new file mode 100644
index 0000000..730330e
--- /dev/null
+++ b/moblin/theme/Makefile.am
@@ -0,0 +1,9 @@
+themedir = $(pkgdatadir)/theme
+
+theme_DATA = bluetooth-panel.css
+
+%.css: %.css.in $(top_builddir)/config.log
+	$(QUIET_GEN)sed -e "s|\ pkgdatadir\@|$(pkgdatadir)|" $< > $@
+
+EXTRA_DIST = bluetooth-panel.css.in
+DISTCLEANFILES = bluetooth-panel.css
diff --git a/moblin/theme/bluetooth-panel.css.in b/moblin/theme/bluetooth-panel.css.in
new file mode 100644
index 0000000..2c25934
--- /dev/null
+++ b/moblin/theme/bluetooth-panel.css.in
@@ -0,0 +1,25 @@
+MnbToolbarButton {
+  background-color: #fff0;
+}
+
+MnbToolbarButton:checked {
+  border-image: url("file://@pkgdatadir@/icons/toolbar-button-active.png") 0 stretch;
+}
+
+MnbToolbarButton:hover, MnbToolbarButton:active {
+  border-image: url("file://@pkgdatadir@/icons/toolbar-button-hover.png") 0 stretch;
+}
+
+MnbToolbarButton#state-idle {
+  background-image: url("file://@pkgdatadir@/icons/bluetooth-idle.png");
+}
+
+MnbToolbarButton#state-idle:hover, MnbToolbarButton#state-idle:active, MnbToolbarButton#state-idle:checked  {
+  background-image: url("file://@pkgdatadir@/icons/bluetooth-idle-active.png");
+
+MnbToolbarButton#state-paired {
+  background-image: url("file://@pkgdatadir@/icons/bluetooth-idle.png");
+}
+
+MnbToolbarButton#state-paired:hover, MnbToolbarButton#state-paired:active, MnbToolbarButton#state-paired:checked  {
+  background-image: url("file://@pkgdatadir@/icons/bluetooth-idle-active.png");



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]