[gnome-control-center] bluetooth: Move Bluetooth panel from gnome-bluetooth



commit 844dd9e3211e121ad1791aa2435c7412488a3b26
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Oct 18 18:44:29 2011 +0100

    bluetooth: Move Bluetooth panel from gnome-bluetooth

 configure.ac                                       |    7 +
 panels/Makefile.am                                 |    4 +
 panels/bluetooth/Makefile.am                       |   33 +
 .../bluetooth/bluetooth-properties.desktop.in.in   |   15 +
 panels/bluetooth/bluetooth.ui                      |  673 ++++++++++++++++
 panels/bluetooth/cc-bluetooth-panel.c              |  844 ++++++++++++++++++++
 panels/bluetooth/cc-bluetooth-panel.h              |   59 ++
 po/POTFILES.in                                     |    3 +
 8 files changed, 1638 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c109fc8..8976fe5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,6 +142,11 @@ if test "x$have_networkmanager" = xno ; then
 fi
 AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes])
 
+# Check for gnome-bluetooth
+PKG_CHECK_MODULES(BLUETOOTH, $COMMON_MODULES gnome-bluetooth-1.0 >= 3.3.0,
+		  [have_bluetooth=yes], have_bluetooth=no)
+AM_CONDITIONAL(BUILD_BLUETOOTH, [test x$have_bluetooth = xyes])
+
 # Check for CUPS 1.4 or newer
 AC_ARG_ENABLE([cups],
               AS_HELP_STRING([--disable-cups], [disable CUPS support (default: enabled)]),,
@@ -315,6 +320,8 @@ panels/Makefile
 panels/common/Makefile
 panels/background/Makefile
 panels/background/gnome-background-panel.desktop.in
+panels/bluetooth/Makefile
+panels/bluetooth/bluetooth-properties.desktop.in
 panels/datetime/Makefile
 panels/datetime/gnome-datetime-panel.desktop.in
 panels/datetime/po-timezones/Makefile
diff --git a/panels/Makefile.am b/panels/Makefile.am
index d2133f5..172dd06 100644
--- a/panels/Makefile.am
+++ b/panels/Makefile.am
@@ -24,4 +24,8 @@ if BUILD_NETWORK
 SUBDIRS += network
 endif
 
+if BUILD_BLUETOOTH
+SUBDIRS += bluetooth
+endif
+
 -include $(top_srcdir)/git.mk
diff --git a/panels/bluetooth/Makefile.am b/panels/bluetooth/Makefile.am
new file mode 100644
index 0000000..a0f33d6
--- /dev/null
+++ b/panels/bluetooth/Makefile.am
@@ -0,0 +1,33 @@
+# This is used in PANEL_CFLAGS
+cappletname = bluetooth
+
+ccpanelsdir = $(PANELS_DIR)
+ccpanels_LTLIBRARIES = libbluetooth.la
+
+INCLUDES = 						\
+	$(PANEL_CFLAGS)					\
+	$(BLUETOOTH_CFLAGS)				\
+	-DGNOMELOCALEDIR="\"$(datadir)/locale\""	\
+	-DPKGDATADIR="\"$(pkgdatadir)\""		\
+	$(NULL)
+
+libbluetooth_la_SOURCES =			\
+	cc-bluetooth-panel.c			\
+	cc-bluetooth-panel.h
+
+libbluetooth_la_LIBADD = $(PANEL_LIBS) $(BLUETOOTH_LIBS)
+libbluetooth_la_LDFLAGS = $(PANEL_LDFLAGS)
+
+desktopdir = $(datadir)/applications
+desktop_in_in_files = bluetooth-properties.desktop.in.in
+desktop_in_files = bluetooth-properties.desktop.in
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ INTLTOOL_DESKTOP_RULE@
+
+ui_DATA = bluetooth.ui
+uidir = $(pkgdatadir)
+
+CLEANFILES = $(desktop_DATA)
+EXTRA_DIST = $(man_MANS) $(desktop_in_in_files) $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/panels/bluetooth/bluetooth-properties.desktop.in.in b/panels/bluetooth/bluetooth-properties.desktop.in.in
new file mode 100644
index 0000000..552b6f4
--- /dev/null
+++ b/panels/bluetooth/bluetooth-properties.desktop.in.in
@@ -0,0 +1,15 @@
+[Desktop Entry]
+_Name=Bluetooth
+_Comment=Configure Bluetooth settings
+Icon=bluetooth
+Exec=gnome-control-center bluetooth
+Terminal=false
+Type=Application
+Categories=GTK;GNOME;Settings;X-GNOME-NetworkSettings;HardwareSettings;X-GNOME-Settings-Panel;
+OnlyShowIn=GNOME;XFCE;
+StartupNotify=true
+X-GNOME-Bugzilla-Bugzilla=GNOME
+X-GNOME-Bugzilla-Product=gnome-bluetooth
+X-GNOME-Bugzilla-Component=properties
+X-GNOME-Bugzilla-Version= VERSION@
+X-GNOME-Settings-Panel=bluetooth
diff --git a/panels/bluetooth/bluetooth.ui b/panels/bluetooth/bluetooth.ui
new file mode 100644
index 0000000..2e1e5fb
--- /dev/null
+++ b/panels/bluetooth/bluetooth.ui
@@ -0,0 +1,673 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkGrid" id="grid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkBox" id="vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkBox" id="box_devices">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkScrolledWindow" id="message_scrolledwindow">
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="no_show_all">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="shadow_type">in</property>
+                    <property name="min_content_width">200</property>
+                    <property name="min_content_height">250</property>
+                    <child>
+                      <object class="GtkViewport" id="viewport2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkLabel" id="message_label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="xpad">12</property>
+                            <property name="ypad">12</property>
+                            <property name="label">Bluetooth is disabled by hardware switch</property>
+                            <property name="wrap">True</property>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolbar" id="toolbar">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="toolbar_style">icons</property>
+                <property name="icon_size">1</property>
+                <style>
+                  <class name="inline-toolbar"/>
+                </style>
+                <child>
+                  <object class="GtkToolButton" id="button_setup">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">list-add-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToolButton" id="button_delete">
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">False</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">list-remove-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkNotebook" id="props_notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">6</property>
+            <property name="show_tabs">False</property>
+            <property name="show_border">False</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkViewport" id="viewport3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkLabel" id="label8">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label">empty</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="vscrollbar_policy">always</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkViewport" id="viewport1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkBox" id="properties_vbox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="margin_top">8</property>
+                        <property name="orientation">vertical</property>
+                        <child>
+                          <object class="GtkBox" id="box1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkBox" id="box2">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">18</property>
+                                <property name="homogeneous">True</property>
+                                <child>
+                                  <object class="GtkLabel" id="connection_label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Connection</property>
+                                    <style>
+                                      <class name="dim-label"/>
+                                    </style>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkBox" id="box6">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <child>
+                                      <object class="GtkSwitch" id="switch_connection">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="use_action_appearance">False</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">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">18</property>
+                                <property name="homogeneous">True</property>
+                                <child>
+                                  <object class="GtkLabel" id="label4">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Paired</property>
+                                    <style>
+                                      <class name="dim-label"/>
+                                    </style>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="paired_label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label">Yes</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">18</property>
+                                <property name="homogeneous">True</property>
+                                <child>
+                                  <object class="GtkLabel" id="label5">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Type</property>
+                                    <style>
+                                      <class name="dim-label"/>
+                                    </style>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="type_label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label">Keyboard</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box5">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">18</property>
+                                <property name="homogeneous">True</property>
+                                <child>
+                                  <object class="GtkLabel" id="label6">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Address</property>
+                                    <style>
+                                      <class name="dim-label"/>
+                                    </style>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="address_label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label">00:00:00:00:00</property>
+                                    <property name="selectable">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="additional_setup_box">
+                            <property name="can_focus">False</property>
+                            <property name="no_show_all">True</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">8</property>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="vbox3">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_right">6</property>
+                            <property name="margin_bottom">6</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkBox" id="mouse_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                 <object class="GtkLinkButton" id="mouse_link">
+                                   <property name="label" translatable="yes">Mouse and Touchpad Settings</property>
+                                   <property name="visible">True</property>
+                                   <property name="can_focus">True</property>
+                                   <property name="receives_default">True</property>
+                                   <property name="has_tooltip">True</property>
+                                   <property name="use_action_appearance">False</property>
+                                   <property name="relief">none</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="pack_type">end</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="sound_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                 <object class="GtkLinkButton" id="sound_link">
+                                   <property name="label" translatable="yes">Sound Settings</property>
+                                   <property name="visible">True</property>
+                                   <property name="can_focus">True</property>
+                                   <property name="receives_default">True</property>
+                                   <property name="has_tooltip">True</property>
+                                   <property name="use_action_appearance">False</property>
+                                   <property name="relief">none</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="pack_type">end</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="keyboard_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                 <object class="GtkLinkButton" id="keyboard_link">
+                                   <property name="label" translatable="yes">Keyboard Settings</property>
+                                   <property name="visible">True</property>
+                                   <property name="can_focus">True</property>
+                                   <property name="receives_default">True</property>
+                                   <property name="has_tooltip">True</property>
+                                   <property name="use_action_appearance">False</property>
+                                   <property name="relief">none</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="pack_type">end</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="send_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <object class="GtkButton" id="send_button">
+                                    <property name="label" translatable="yes">Send Files...</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_action_appearance">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="pack_type">end</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="browse_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <object class="GtkButton" id="browse_button">
+                                    <property name="label" translatable="yes">Browse Files...</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_action_appearance">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="pack_type">end</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label7">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label">properties</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box_power">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_bottom">12</property>
+            <child>
+              <object class="GtkLabel" id="label18">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes" context="Power" comments="Translator: This string appears next to a toggle switch which controls enabling/disabling Bluetooth radio's on the device.">Bluetooth</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="padding">6</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="switch_bluetooth">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="use_action_appearance">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box_vis">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_bottom">12</property>
+            <child>
+              <object class="GtkLabel" id="visible_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">1</property>
+                <property name="label">Visibility of âBastien's computerâ</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="padding">6</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="switch_discoverable">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="use_action_appearance">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/panels/bluetooth/cc-bluetooth-panel.c b/panels/bluetooth/cc-bluetooth-panel.c
new file mode 100644
index 0000000..ccb29ad
--- /dev/null
+++ b/panels/bluetooth/cc-bluetooth-panel.c
@@ -0,0 +1,844 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2006-2010  Bastien Nocera <hadess hadess net>
+ *
+ *
+ *  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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <libgnome-control-center/cc-shell.h>
+
+#include "cc-bluetooth-panel.h"
+
+#include <bluetooth-client.h>
+#include <bluetooth-utils.h>
+#include <bluetooth-killswitch.h>
+#include <bluetooth-chooser.h>
+#include <bluetooth-plugin-manager.h>
+
+G_DEFINE_DYNAMIC_TYPE (CcBluetoothPanel, cc_bluetooth_panel, CC_TYPE_PANEL)
+
+#define BLUETOOTH_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanelPrivate))
+
+#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))
+
+#define KEYBOARD_PREFS		"keyboard"
+#define MOUSE_PREFS		"mouse"
+#define SOUND_PREFS		"sound"
+#define WIZARD			"bluetooth-wizard"
+
+struct CcBluetoothPanelPrivate {
+	GtkBuilder          *builder;
+	GtkWidget           *chooser;
+	BluetoothClient     *client;
+	BluetoothKillswitch *killswitch;
+	gboolean             debug;
+};
+
+static void cc_bluetooth_panel_finalize (GObject *object);
+
+static void
+launch_command (const char *command)
+{
+	GError *error = NULL;
+
+	if (!g_spawn_command_line_async(command, &error)) {
+		g_warning ("Couldn't execute command '%s': %s\n", command, error->message);
+		g_error_free (error);
+	}
+}
+
+static void
+cc_bluetooth_panel_class_init (CcBluetoothPanelClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = cc_bluetooth_panel_finalize;
+
+	g_type_class_add_private (klass, sizeof (CcBluetoothPanelPrivate));
+}
+
+static void
+cc_bluetooth_panel_class_finalize (CcBluetoothPanelClass *klass)
+{
+}
+
+static void
+cc_bluetooth_panel_finalize (GObject *object)
+{
+	CcBluetoothPanel *self;
+
+	bluetooth_plugin_manager_cleanup ();
+
+	self = CC_BLUETOOTH_PANEL (object);
+	if (self->priv->builder) {
+		g_object_unref (self->priv->builder);
+		self->priv->builder = NULL;
+	}
+	if (self->priv->killswitch) {
+		g_object_unref (self->priv->killswitch);
+		self->priv->killswitch = NULL;
+	}
+	if (self->priv->client) {
+		g_object_unref (self->priv->client);
+		self->priv->client = NULL;
+	}
+
+	G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->finalize (object);
+}
+
+typedef struct {
+	char             *bdaddr;
+	CcBluetoothPanel *self;
+} ConnectData;
+
+static void
+connect_done (GObject      *source_object,
+	      GAsyncResult *res,
+	      gpointer      user_data)
+{
+	CcBluetoothPanel *self;
+	char *bdaddr;
+	gboolean success;
+	ConnectData *data = (ConnectData *) user_data;
+
+	success = bluetooth_client_connect_service_finish (BLUETOOTH_CLIENT (source_object),
+							   res, NULL);
+
+	self = data->self;
+
+	/* Check whether the same device is now selected */
+	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	if (g_strcmp0 (bdaddr, data->bdaddr) == 0) {
+		GtkSwitch *button;
+
+		button = GTK_SWITCH (WID ("switch_connection"));
+		/* Reset the switch if it failed */
+		if (success == FALSE)
+			gtk_switch_set_active (button, !gtk_switch_get_active (button));
+		gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
+	}
+
+	g_free (bdaddr);
+	g_object_unref (data->self);
+	g_free (data->bdaddr);
+	g_free (data);
+}
+
+static void
+switch_connected_active_changed (GtkSwitch        *button,
+				 GParamSpec       *spec,
+				 CcBluetoothPanel *self)
+{
+	char *proxy;
+	GValue value = { 0, };
+	ConnectData *data;
+
+	if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+							"proxy", &value) == FALSE) {
+		g_warning ("Could not get D-Bus proxy for selected device");
+		return;
+	}
+	proxy = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
+	g_value_unset (&value);
+
+	if (proxy == NULL)
+		return;
+
+	data = g_new0 (ConnectData, 1);
+	data->bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	data->self = g_object_ref (self);
+
+	bluetooth_client_connect_service (self->priv->client,
+					  proxy,
+					  gtk_switch_get_active (button),
+					  NULL,
+					  connect_done,
+					  data);
+
+	/* FIXME: make a note somewhere that the button for that
+	 * device should be disabled */
+	gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
+	g_free (proxy);
+}
+
+enum {
+	NOTEBOOK_PAGE_EMPTY = 0,
+	NOTEBOOK_PAGE_PROPS = 1
+};
+
+static void
+set_notebook_page (CcBluetoothPanel *self,
+		   int               page)
+{
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (WID ("props_notebook")), page);
+}
+
+static void
+add_extra_setup_widgets (CcBluetoothPanel *self,
+			 const char       *bdaddr)
+{
+	GValue value = { 0 };
+	char **uuids;
+	GList *list, *l;
+	GtkWidget *container;
+
+	if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+							"uuids", &value) == FALSE)
+		return;
+
+	uuids = (char **) g_value_get_boxed (&value);
+	list = bluetooth_plugin_manager_get_widgets (bdaddr, (const char **) uuids);
+	if (list == NULL) {
+		g_value_unset (&value);
+		return;
+	}
+
+	container = WID ("additional_setup_box");
+	for (l = list; l != NULL; l = l->next) {
+		GtkWidget *widget = l->data;
+		gtk_box_pack_start (GTK_BOX (container), widget,
+				    FALSE, FALSE, 0);
+		gtk_widget_show_all (widget);
+	}
+	gtk_widget_show (container);
+	g_value_unset (&value);
+}
+
+static void
+remove_extra_setup_widgets (CcBluetoothPanel *self)
+{
+	GtkWidget *box;
+
+	box = WID ("additional_setup_box");
+	gtk_container_forall (GTK_CONTAINER (box), (GtkCallback) gtk_widget_destroy, NULL);
+	gtk_widget_hide (WID ("additional_setup_box"));
+}
+
+static void
+cc_bluetooth_panel_update_properties (CcBluetoothPanel *self)
+{
+	char *bdaddr;
+	GtkSwitch *button;
+
+	button = GTK_SWITCH (WID ("switch_connection"));
+	g_signal_handlers_block_by_func (button, switch_connected_active_changed, self);
+
+	/* Hide all the buttons now, and show them again if we need to */
+	gtk_widget_hide (WID ("keyboard_box"));
+	gtk_widget_hide (WID ("sound_box"));
+	gtk_widget_hide (WID ("mouse_box"));
+	gtk_widget_hide (WID ("browse_box"));
+	gtk_widget_hide (WID ("send_box"));
+
+	/* Remove the extra setup widgets */
+	remove_extra_setup_widgets (self);
+
+	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	if (bdaddr == NULL) {
+		gtk_widget_set_sensitive (WID ("properties_vbox"), FALSE);
+		gtk_switch_set_active (button, FALSE);
+		gtk_widget_set_sensitive (WID ("button_delete"), FALSE);
+		set_notebook_page (self, NOTEBOOK_PAGE_EMPTY);
+	} else {
+		BluetoothType type;
+		gboolean connected;
+		GValue value = { 0 };
+		GHashTable *services;
+
+		if (self->priv->debug)
+			bluetooth_chooser_dump_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+
+		gtk_widget_set_sensitive (WID ("properties_vbox"), TRUE);
+
+		connected = bluetooth_chooser_get_selected_device_is_connected (BLUETOOTH_CHOOSER (self->priv->chooser));
+		gtk_switch_set_active (button, connected);
+
+		/* Paired */
+		bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+							    "paired", &value);
+		gtk_label_set_text (GTK_LABEL (WID ("paired_label")),
+				    g_value_get_boolean (&value) ? _("Yes") : _("No"));
+		g_value_unset (&value);
+
+		/* Connection */
+		bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+							    "services", &value);
+		services = g_value_get_boxed (&value);
+		gtk_widget_set_sensitive (GTK_WIDGET (button), (services != NULL));
+		g_value_unset (&value);
+
+		/* UUIDs */
+		if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+								"uuids", &value)) {
+			const char **uuids;
+			guint i;
+
+			uuids = (const char **) g_value_get_boxed (&value);
+			for (i = 0; uuids && uuids[i] != NULL; i++) {
+				if (g_str_equal (uuids[i], "OBEXObjectPush"))
+					gtk_widget_show (WID ("send_box"));
+				else if (g_str_equal (uuids[i], "OBEXFileTransfer"))
+					gtk_widget_show (WID ("browse_box"));
+			}
+			g_value_unset (&value);
+		}
+
+		/* Type */
+		type = bluetooth_chooser_get_selected_device_type (BLUETOOTH_CHOOSER (self->priv->chooser));
+		gtk_label_set_text (GTK_LABEL (WID ("type_label")), bluetooth_type_to_string (type));
+		switch (type) {
+		case BLUETOOTH_TYPE_KEYBOARD:
+			gtk_widget_show (WID ("keyboard_box"));
+			break;
+		case BLUETOOTH_TYPE_MOUSE:
+		case BLUETOOTH_TYPE_TABLET:
+			gtk_widget_show (WID ("mouse_box"));
+			break;
+		case BLUETOOTH_TYPE_HEADSET:
+		case BLUETOOTH_TYPE_HEADPHONES:
+		case BLUETOOTH_TYPE_OTHER_AUDIO:
+			gtk_widget_show (WID ("sound_box"));
+		default:
+			/* others? */
+			;
+		}
+
+		/* Extra widgets */
+		add_extra_setup_widgets (self, bdaddr);
+
+		gtk_label_set_text (GTK_LABEL (WID ("address_label")), bdaddr);
+		g_free (bdaddr);
+
+		gtk_widget_set_sensitive (WID ("button_delete"), TRUE);
+		set_notebook_page (self, NOTEBOOK_PAGE_PROPS);
+	}
+
+	g_signal_handlers_unblock_by_func (button, switch_connected_active_changed, self);
+}
+
+static void
+power_callback (GObject          *object,
+		GParamSpec       *spec,
+		CcBluetoothPanel *self)
+{
+	gboolean state;
+
+	state = gtk_switch_get_active (GTK_SWITCH (WID ("switch_bluetooth")));
+	g_debug ("Power switched to %s", state ? "off" : "on");
+	bluetooth_killswitch_set_state (self->priv->killswitch,
+					state ? KILLSWITCH_STATE_UNBLOCKED : KILLSWITCH_STATE_SOFT_BLOCKED);
+}
+
+static void
+cc_bluetooth_panel_update_treeview_message (CcBluetoothPanel *self,
+					    const char       *message)
+{
+	if (message != NULL) {
+		gtk_widget_hide (self->priv->chooser);
+		gtk_widget_show (WID ("message_scrolledwindow"));
+
+		gtk_label_set_text (GTK_LABEL (WID ("message_label")),
+				    message);
+	} else {
+		gtk_widget_hide (WID ("message_scrolledwindow"));
+		gtk_widget_show (self->priv->chooser);
+	}
+}
+
+static void
+cc_bluetooth_panel_update_power (CcBluetoothPanel *self)
+{
+	KillswitchState state;
+	char *path;
+	gboolean powered, sensitive;
+	GtkSwitch *button;
+
+	g_object_get (G_OBJECT (self->priv->client),
+		      "default-adapter", &path,
+		      "default-adapter-powered", &powered,
+		      NULL);
+	state = bluetooth_killswitch_get_state (self->priv->killswitch);
+
+	g_debug ("Updating power, default adapter: %s (powered: %s), killswitch: %s",
+		 path ? path : "(none)",
+		 powered ? "on" : "off",
+		 bluetooth_killswitch_state_to_string (state));
+
+	if (path == NULL &&
+	    bluetooth_killswitch_has_killswitches (self->priv->killswitch) &&
+	    state != KILLSWITCH_STATE_HARD_BLOCKED) {
+		g_debug ("Default adapter is unpowered, but should be available");
+		sensitive = TRUE;
+		cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled"));
+	} else if (path == NULL &&
+		   state == KILLSWITCH_STATE_HARD_BLOCKED) {
+		g_debug ("Bluetooth is Hard blocked");
+		sensitive = FALSE;
+		cc_bluetooth_panel_update_treeview_message (self, _("Bluetooth is disabled by hardware switch"));
+	} else if (path == NULL) {
+		sensitive = FALSE;
+		g_debug ("No Bluetooth available");
+		cc_bluetooth_panel_update_treeview_message (self, _("No Bluetooth adapters found"));
+	} else {
+		sensitive = TRUE;
+		g_debug ("Bluetooth is available and powered");
+		cc_bluetooth_panel_update_treeview_message (self, NULL);
+	}
+
+	g_free (path);
+	gtk_widget_set_sensitive (WID ("box_power") , sensitive);
+	gtk_widget_set_sensitive (WID ("box_vis") , sensitive);
+
+	button = GTK_SWITCH (WID ("switch_bluetooth"));
+
+	g_signal_handlers_block_by_func (button, power_callback, self);
+	gtk_switch_set_active (button, powered);
+	g_signal_handlers_unblock_by_func (button, power_callback, self);
+}
+
+static void
+switch_panel (CcBluetoothPanel *self,
+	      const char       *panel)
+{
+  CcShell *shell;
+  GError *error = NULL;
+
+  shell = cc_panel_get_shell (CC_PANEL (self));
+  if (cc_shell_set_active_panel_from_id (shell, panel, NULL, &error) == FALSE)
+    {
+      g_warning ("Failed to activate Region panel: %s", error->message);
+      g_error_free (error);
+    }
+}
+
+static gboolean
+keyboard_callback (GtkButton        *button,
+		   CcBluetoothPanel *self)
+{
+	switch_panel (self, KEYBOARD_PREFS);
+	return TRUE;
+}
+
+static gboolean
+mouse_callback (GtkButton        *button,
+		CcBluetoothPanel *self)
+{
+	switch_panel (self, MOUSE_PREFS);
+	return TRUE;
+}
+
+static gboolean
+sound_callback (GtkButton        *button,
+		CcBluetoothPanel *self)
+{
+	switch_panel (self, SOUND_PREFS);
+	return TRUE;
+}
+
+static void
+send_callback (GtkButton        *button,
+	       CcBluetoothPanel *self)
+{
+	char *bdaddr, *alias;
+
+	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	alias = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
+
+	bluetooth_send_to_address (bdaddr, alias);
+
+	g_free (bdaddr);
+	g_free (alias);
+}
+
+static void
+mount_finish_cb (GObject *source_object,
+		 GAsyncResult *res,
+		 gpointer user_data)
+{
+	GError *error = NULL;
+
+	if (bluetooth_browse_address_finish (source_object, res, &error) == FALSE) {
+		g_printerr ("Failed to mount OBEX volume: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+}
+
+static void
+browse_callback (GtkButton        *button,
+		 CcBluetoothPanel *self)
+{
+	char *bdaddr;
+
+	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+
+	bluetooth_browse_address (G_OBJECT (self), bdaddr,
+				  GDK_CURRENT_TIME, mount_finish_cb, NULL);
+
+	g_free (bdaddr);
+}
+
+/* Visibility/Discoverable */
+static void discoverable_changed (BluetoothClient  *client,
+				  GParamSpec       *spec,
+				  CcBluetoothPanel *self);
+
+static void
+switch_discoverable_active_changed (GtkSwitch        *button,
+				    GParamSpec       *spec,
+				    CcBluetoothPanel *self)
+{
+	g_signal_handlers_block_by_func (self->priv->client, discoverable_changed, self);
+	g_object_set (G_OBJECT (self->priv->client), "default-adapter-discoverable",
+		      gtk_switch_get_active (button), NULL);
+	g_signal_handlers_unblock_by_func (self->priv->client, discoverable_changed, self);
+}
+
+static void
+cc_bluetooth_panel_update_visibility (CcBluetoothPanel *self)
+{
+	gboolean discoverable;
+	GtkSwitch *button;
+	char *name;
+
+	button = GTK_SWITCH (WID ("switch_discoverable"));
+	g_object_get (G_OBJECT (self->priv->client), "default-adapter-discoverable", &discoverable, NULL);
+	g_signal_handlers_block_by_func (button, switch_discoverable_active_changed, self);
+	gtk_switch_set_active (button, discoverable);
+	g_signal_handlers_unblock_by_func (button, switch_discoverable_active_changed, self);
+
+	g_object_get (G_OBJECT (self->priv->client), "default-adapter-name", &name, NULL);
+	if (name == NULL) {
+		gtk_widget_set_sensitive (WID ("switch_discoverable"), FALSE);
+		gtk_widget_set_sensitive (WID ("visible_label"), FALSE);
+		gtk_label_set_text (GTK_LABEL (WID ("visible_label")), _("Visibility"));
+	} else {
+		char *label;
+
+		label = g_strdup_printf (_("Visibility of â%sâ"), name);
+		g_free (name);
+		gtk_label_set_text (GTK_LABEL (WID ("visible_label")), label);
+		g_free (label);
+
+		gtk_widget_set_sensitive (WID ("switch_discoverable"), TRUE);
+		gtk_widget_set_sensitive (WID ("visible_label"), TRUE);
+	}
+}
+
+static void
+discoverable_changed (BluetoothClient  *client,
+		      GParamSpec       *spec,
+		      CcBluetoothPanel *self)
+{
+	cc_bluetooth_panel_update_visibility (self);
+}
+
+static void
+name_changed (BluetoothClient  *client,
+	      GParamSpec       *spec,
+	      CcBluetoothPanel *self)
+{
+	cc_bluetooth_panel_update_visibility (self);
+}
+
+static void
+device_selected_changed (BluetoothChooser *chooser,
+			 GParamSpec       *spec,
+			 CcBluetoothPanel *self)
+{
+	cc_bluetooth_panel_update_properties (self);
+}
+
+static gboolean
+show_confirm_dialog (CcBluetoothPanel *self,
+		     const char *name)
+{
+	GtkWidget *dialog, *parent;
+	gint response;
+
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
+	dialog = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+					 _("Remove '%s' from the list of devices?"), name);
+	g_object_set (G_OBJECT (dialog), "secondary-text",
+		      _("If you remove the device, you will have to set it up again before next use."),
+		      NULL);
+
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT);
+
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+	gtk_widget_destroy (dialog);
+
+	if (response == GTK_RESPONSE_ACCEPT)
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+remove_selected_device (CcBluetoothPanel *self)
+{
+	GValue value = { 0, };
+	char *device, *adapter;
+	GDBusProxy *adapter_proxy;
+	GError *error = NULL;
+	GVariant *ret;
+
+	if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
+							"proxy", &value) == FALSE) {
+		return FALSE;
+	}
+	device = g_strdup (g_dbus_proxy_get_object_path (g_value_get_object (&value)));
+	g_value_unset (&value);
+
+	g_object_get (G_OBJECT (self->priv->client), "default-adapter", &adapter, NULL);
+	adapter_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+						       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+						       NULL,
+						       "org.bluez",
+						       adapter,
+						       "org.bluez.Adapter",
+						       NULL,
+						       &error);
+	g_free (adapter);
+	if (adapter_proxy == NULL) {
+		g_warning ("Failed to create a GDBusProxy for the default adapter: %s", error->message);
+		g_error_free (error);
+		g_free (device);
+		return FALSE;
+	}
+
+	ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (adapter_proxy),
+				      "RemoveDevice",
+				      g_variant_new ("(o)", device),
+				      G_DBUS_CALL_FLAGS_NONE,
+				      -1,
+				      NULL,
+				      &error);
+	if (ret == NULL) {
+		g_warning ("Failed to remove device '%s': %s", device, error->message);
+		g_error_free (error);
+	} else {
+		g_variant_unref (ret);
+	}
+
+	g_object_unref (adapter_proxy);
+	g_free (device);
+
+	return (ret != NULL);
+}
+
+/* Treeview buttons */
+static void
+delete_clicked (GtkToolButton    *button,
+		CcBluetoothPanel *self)
+{
+	char *address, *name;
+
+	address = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	g_assert (address);
+
+	name = bluetooth_chooser_get_selected_device_name (BLUETOOTH_CHOOSER (self->priv->chooser));
+
+	if (show_confirm_dialog (self, name) != FALSE) {
+		if (remove_selected_device (self))
+			bluetooth_plugin_manager_device_deleted (address);
+	}
+
+	g_free (address);
+	g_free (name);
+}
+
+static void
+setup_clicked (GtkToolButton    *button,
+	       CcBluetoothPanel *self)
+{
+	launch_command (WIZARD);
+}
+
+/* Overall device state */
+static void
+cc_bluetooth_panel_update_state (CcBluetoothPanel *self)
+{
+	char *bdaddr;
+	gboolean powered;
+
+	g_object_get (G_OBJECT (self->priv->client),
+		      "default-adapter", &bdaddr,
+		      "default-adapter-powered", &powered,
+		      NULL);
+	gtk_widget_set_sensitive (WID ("toolbar"), (bdaddr != NULL));
+	g_free (bdaddr);
+}
+
+static void
+default_adapter_changed (BluetoothClient  *client,
+			 GParamSpec       *spec,
+			 CcBluetoothPanel *self)
+{
+	cc_bluetooth_panel_update_state (self);
+	cc_bluetooth_panel_update_power (self);
+}
+
+static void
+killswitch_changed (BluetoothKillswitch *killswitch,
+		    KillswitchState      state,
+		    CcBluetoothPanel    *self)
+{
+	cc_bluetooth_panel_update_state (self);
+	cc_bluetooth_panel_update_power (self);
+}
+
+static void
+cc_bluetooth_panel_init (CcBluetoothPanel *self)
+{
+	GtkWidget *widget;
+	GError *error = NULL;
+	GtkStyleContext *context;
+
+	self->priv = BLUETOOTH_PANEL_PRIVATE (self);
+
+	bluetooth_plugin_manager_init ();
+	self->priv->killswitch = bluetooth_killswitch_new ();
+	self->priv->client = bluetooth_client_new ();
+	self->priv->debug = g_getenv ("BLUETOOTH_DEBUG") != NULL;
+
+	self->priv->builder = gtk_builder_new ();
+	gtk_builder_set_translation_domain (self->priv->builder, GETTEXT_PACKAGE);
+	gtk_builder_add_from_file (self->priv->builder,
+				   PKGDATADIR "/bluetooth.ui",
+				   &error);
+	if (error != NULL) {
+		g_warning ("Failed to load '%s': %s", PKGDATADIR "/bluetooth.ui", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	widget = WID ("grid");
+	gtk_widget_reparent (widget, GTK_WIDGET (self));
+
+	/* Overall device state */
+	cc_bluetooth_panel_update_state (self);
+	g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter",
+			  G_CALLBACK (default_adapter_changed), self);
+
+	/* The discoverable button */
+	cc_bluetooth_panel_update_visibility (self);
+	g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-discoverable",
+			  G_CALLBACK (discoverable_changed), self);
+	g_signal_connect (G_OBJECT (self->priv->client), "notify::default-adapter-name",
+			  G_CALLBACK (name_changed), self);
+	g_signal_connect (G_OBJECT (WID ("switch_discoverable")), "notify::active",
+			  G_CALLBACK (switch_discoverable_active_changed), self);
+
+	/* The known devices */
+	widget = WID ("devices_table");
+
+	context = gtk_widget_get_style_context (WID ("message_scrolledwindow"));
+	gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+
+	/* Note that this will only ever show the devices on the default
+	 * adapter, this is on purpose */
+	self->priv->chooser = bluetooth_chooser_new (NULL);
+	gtk_box_pack_start (GTK_BOX (WID ("box_devices")), self->priv->chooser, TRUE, TRUE, 0);
+	g_object_set (self->priv->chooser,
+		      "show-searching", FALSE,
+		      "show-device-type", FALSE,
+		      "show-device-type-column", FALSE,
+		      "show-device-category", FALSE,
+		      "show-pairing", FALSE,
+		      "show-connected", FALSE,
+		      "device-category-filter", BLUETOOTH_CATEGORY_PAIRED_OR_TRUSTED,
+		      "no-show-all", TRUE,
+		      NULL);
+
+	/* Join treeview and buttons */
+	widget = bluetooth_chooser_get_scrolled_window (BLUETOOTH_CHOOSER (self->priv->chooser));
+	gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget), 250);
+	gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (widget), 200);
+	context = gtk_widget_get_style_context (widget);
+	gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+	widget = WID ("toolbar");
+	context = gtk_widget_get_style_context (widget);
+	gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+
+	g_signal_connect (G_OBJECT (self->priv->chooser), "notify::device-selected",
+			  G_CALLBACK (device_selected_changed), self);
+	g_signal_connect (G_OBJECT (WID ("button_delete")), "clicked",
+			  G_CALLBACK (delete_clicked), self);
+	g_signal_connect (G_OBJECT (WID ("button_setup")), "clicked",
+			  G_CALLBACK (setup_clicked), self);
+
+	/* Set the initial state of the properties */
+	cc_bluetooth_panel_update_properties (self);
+	g_signal_connect (G_OBJECT (WID ("mouse_link")), "activate-link",
+			  G_CALLBACK (mouse_callback), self);
+	g_signal_connect (G_OBJECT (WID ("keyboard_link")), "activate-link",
+			  G_CALLBACK (keyboard_callback), self);
+	g_signal_connect (G_OBJECT (WID ("sound_link")), "activate-link",
+			  G_CALLBACK (sound_callback), self);
+	g_signal_connect (G_OBJECT (WID ("browse_button")), "clicked",
+			  G_CALLBACK (browse_callback), self);
+	g_signal_connect (G_OBJECT (WID ("send_button")), "clicked",
+			  G_CALLBACK (send_callback), self);
+	g_signal_connect (G_OBJECT (WID ("switch_connection")), "notify::active",
+			  G_CALLBACK (switch_connected_active_changed), self);
+
+	/* Set the initial state of power */
+	g_signal_connect (G_OBJECT (WID ("switch_bluetooth")), "notify::active",
+			  G_CALLBACK (power_callback), self);
+	g_signal_connect (G_OBJECT (self->priv->killswitch), "state-changed",
+			  G_CALLBACK (killswitch_changed), self);
+	cc_bluetooth_panel_update_power (self);
+
+	gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+void
+cc_bluetooth_panel_register (GIOModule *module)
+{
+	cc_bluetooth_panel_register_type (G_TYPE_MODULE (module));
+	g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
+					CC_TYPE_BLUETOOTH_PANEL,
+					"bluetooth", 0);
+}
+
+/* GIO extension stuff */
+void
+g_io_module_load (GIOModule *module)
+{
+	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+	/* register the panel */
+	cc_bluetooth_panel_register (module);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
+
diff --git a/panels/bluetooth/cc-bluetooth-panel.h b/panels/bluetooth/cc-bluetooth-panel.h
new file mode 100644
index 0000000..b7192e5
--- /dev/null
+++ b/panels/bluetooth/cc-bluetooth-panel.h
@@ -0,0 +1,59 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2005-2008  Marcel Holtmann <marcel holtmann org>
+ *  Copyright (C) 2006-2010  Bastien Nocera <hadess hadess net>
+ *
+ *
+ *  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 _CC_BLUETOOTH_PANEL_H
+#define _CC_BLUETOOTH_PANEL_H
+
+#include <libgnome-control-center/cc-shell.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_BLUETOOTH_PANEL cc_bluetooth_panel_get_type()
+#define CC_BLUETOOTH_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanel))
+#define CC_BLUETOOTH_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanelClass))
+#define CC_IS_BLUETOOTH_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CC_TYPE_BLUETOOTH_PANEL))
+#define CC_IS_BLUETOOTH_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CC_TYPE_BLUETOOTH_PANEL))
+#define CC_BLUETOOTH_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CC_TYPE_BLUETOOTH_PANEL, CcBluetoothPanelClass))
+
+typedef struct CcBluetoothPanel CcBluetoothPanel;
+typedef struct CcBluetoothPanelClass CcBluetoothPanelClass;
+typedef struct CcBluetoothPanelPrivate CcBluetoothPanelPrivate;
+
+struct CcBluetoothPanel {
+	CcPanel parent;
+	CcBluetoothPanelPrivate *priv;
+};
+
+struct CcBluetoothPanelClass {
+	CcPanelClass parent_class;
+};
+
+GType cc_bluetooth_panel_get_type (void) G_GNUC_CONST;
+
+void  cc_bluetooth_panel_register (GIOModule *module);
+
+G_END_DECLS
+
+#endif /* _CC_BLUETOOTH_PANEL_H */
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 773b542..4cf99ce 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,6 +7,9 @@ panels/background/gnome-background-panel.desktop.in.in
 panels/background/bg-colors-source.c
 panels/background/cc-background-panel.c
 panels/background/cc-background-item.c
+panels/bluetooth/cc-bluetooth-panel.c
+[type: gettext/glade] panels/bluetooth/bluetooth.ui
+panels/bluetooth/bluetooth-properties.desktop.in.in
 panels/common/cc-common-language.c
 panels/common/cc-language-chooser.c
 panels/common/gdm-languages.c



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