[SCM] earcandy/master: Revert "Imported Upstream version 0.9"

alessio at users.alioth.debian.org alessio at users.alioth.debian.org
Mon Oct 25 17:09:29 UTC 2010


The following commit has been merged in the master branch:
commit c5108ed0bc1b954d1bf6a470306026d8f6ed815c
Author: Alessio Treglia <alessio at debian.org>
Date:   Mon Oct 25 19:05:38 2010 +0200

    Revert "Imported Upstream version 0.9"
    
    This reverts commit cf83b2bab9463f502994222e902fb5a4145a0046.

diff --git a/.quickly b/.quickly
deleted file mode 100644
index e14aa10..0000000
--- a/.quickly
+++ /dev/null
@@ -1,3 +0,0 @@
-project = earcandy
-template = ubuntu-project
-format = 0.2.5
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..1bb399f
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,341 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/Copyright b/Copyright
deleted file mode 100644
index 659103a..0000000
--- a/Copyright
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) YYYY <Your Name> <Your E-mail>
-### BEGIN AUTOMATIC LICENSE GENERATION
-### END AUTOMATIC LICENSE GENERATION
diff --git a/README b/README
new file mode 100644
index 0000000..ba3eda7
--- /dev/null
+++ b/README
@@ -0,0 +1,4 @@
+Ear Candy is a sound manager that controls pulseaudio to create a seamless sound experience
+
+Please note that much of the functionality should eventually make its way into pulseaudio its self
+
diff --git a/bin/earcandy b/bin/earcandy
deleted file mode 100755
index a978b40..0000000
--- a/bin/earcandy
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-### BEGIN LICENSE
-# This file is in the public domain
-### END LICENSE
-
-import sys
-import os
-import gtk
-import logging
-
-# Check if we are working in the source tree or from the installed 
-# package and mangle the python path accordingly
-if os.path.dirname(sys.argv[0]) != ".":
-    if sys.argv[0][0] == "/":
-        fullPath = os.path.dirname(sys.argv[0])
-    else:
-        fullPath = os.getcwd() + "/" + os.path.dirname(sys.argv[0])
-else:
-    fullPath = os.getcwd()
-sys.path.insert(0, os.path.dirname(fullPath))
-
-from earcandy.earcandyconfig import getdatapath
-from earcandy.EarCandy import EarCandy
-
-if __name__ == "__main__":
-
-    #run the application
-    logging.basicConfig(level=logging.INFO)
-    
-    gtk.window_set_default_icon_from_file(os.path.join(getdatapath(), 'media', 'icon.png'))
-
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-
-    ec = EarCandy()
-    ec.run()
-
-    gtk.main()
diff --git a/data/media/earcandy.png b/data/media/earcandy.png
deleted file mode 100644
index 9b18fb7..0000000
Binary files a/data/media/earcandy.png and /dev/null differ
diff --git a/data/media/icon.png b/data/media/icon.png
deleted file mode 100644
index 9b18fb7..0000000
Binary files a/data/media/icon.png and /dev/null differ
diff --git a/data/ui/AboutEarcandyDialog.ui b/data/ui/AboutEarcandyDialog.ui
deleted file mode 100644
index 939e039..0000000
--- a/data/ui/AboutEarcandyDialog.ui
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-requires about_earcandy_dialog 1.0 -->
-  <!-- interface-naming-policy project-wide -->
-  <object class="AboutEarcandyDialog" id="about_earcandy_dialog">
-    <property name="border_width">5</property>
-    <property name="icon">../media/icon.png</property>
-    <property name="type_hint">normal</property>
-    <property name="has_separator">False</property>
-    <property name="program_name">Earcandy</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child>
-          <placeholder/>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
diff --git a/data/ui/EarcandyWindow.ui b/data/ui/EarcandyWindow.ui
deleted file mode 100644
index 5176da1..0000000
--- a/data/ui/EarcandyWindow.ui
+++ /dev/null
@@ -1,226 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-requires earcandy_window 1.0 -->
-  <!-- interface-naming-policy project-wide -->
-  <!-- interface-local-resource-path ../media -->
-  <object class="EarcandyWindow" id="earcandy_window">
-    <property name="width_request">600</property>
-    <property name="height_request">500</property>
-    <property name="title" translatable="yes">Earcandy</property>
-    <property name="icon">../media/icon.png</property>
-    <signal name="destroy" handler="on_destroy"/>
-    <child>
-      <object class="GtkVBox" id="vbox1">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">5</property>
-        <child>
-          <object class="GtkMenuBar" id="menubar1">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtkMenuItem" id="menuitem1">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_File</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu1">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem1">
-                        <property name="label">gtk-new</property>
-                        <property name="visible">True</property>
-                        <property name="use_action_appearance">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem2">
-                        <property name="label">gtk-open</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem3">
-                        <property name="label">gtk-save</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem4">
-                        <property name="label">gtk-save-as</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
-                        <property name="visible">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem5">
-                        <property name="label">gtk-quit</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="quit"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="menuitem2">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_Edit</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu2">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem6">
-                        <property name="label">gtk-cut</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem7">
-                        <property name="label">gtk-copy</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem8">
-                        <property name="label">gtk-paste</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem9">
-                        <property name="label">gtk-delete</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
-                        <property name="visible">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem11">
-                        <property name="label">gtk-preferences</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="preferences"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="menuitem3">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_View</property>
-                <property name="use_underline">True</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="menuitem4">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_Help</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu3">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem10">
-                        <property name="label">gtk-about</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="about"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="label1">
-            <property name="visible">True</property>
-            <property name="xpad">5</property>
-            <property name="ypad">5</property>
-            <property name="label" translatable="yes">Your application has been created!
-
-To start changing this user interface, run 'quickly glade', which will open Glade so you can edit the default windows and dialogs.
-
-To change the behavior and edit the python code, run 'quickly edit', which will bring up a text editor.</property>
-            <property name="wrap">True</property>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkImage" id="image1">
-            <property name="visible">True</property>
-            <property name="xpad">5</property>
-            <property name="ypad">5</property>
-            <property name="pixbuf">../media/background.png</property>
-          </object>
-          <packing>
-            <property name="padding">15</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkStatusbar" id="statusbar1">
-            <property name="visible">True</property>
-            <property name="spacing">2</property>
-            <child>
-              <object class="GtkLabel" id="label2">
-                <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="xpad">5</property>
-                <property name="ypad">5</property>
-                <property name="label" translatable="yes">Status Area</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
diff --git a/data/ui/about_earcandy_dialog.xml b/data/ui/about_earcandy_dialog.xml
deleted file mode 100644
index c6c1aa6..0000000
--- a/data/ui/about_earcandy_dialog.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<glade-catalog name="about_earcandy_dialog" domain="glade-3" 
-               depends="gtk+" version="1.0">
-  <glade-widget-classes>
-    <glade-widget-class title="About Earcandy Dialog" name="AboutEarcandyDialog" 
-                        generic-name="AboutEarcandyDialog" parent="GtkAboutDialog"
-                        icon-name="widget-gtk-about-dialog"/>
-  </glade-widget-classes>
-
-</glade-catalog>
diff --git a/data/ui/earcandy_window.xml b/data/ui/earcandy_window.xml
deleted file mode 100644
index b8977d8..0000000
--- a/data/ui/earcandy_window.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<glade-catalog name="earcandy_window" domain="glade-3" 
-               depends="gtk+" version="1.0">
-  <glade-widget-classes>
-    <glade-widget-class title="Earcandy Window" name="EarcandyWindow" 
-                        generic-name="EarcandyWindow" parent="GtkWindow"
-                        icon-name="widget-gtk-window"/>
-  </glade-widget-classes>
-</glade-catalog>
diff --git a/earcandy/Client.py b/ear_candy/Client.py
similarity index 62%
rename from earcandy/Client.py
rename to ear_candy/Client.py
index e08794a..1a3a581 100644
--- a/earcandy/Client.py
+++ b/ear_candy/Client.py
@@ -24,56 +24,41 @@ class Client():
         self.core = core
 
         self.name = name
-        self.description = self.clean_client_name(name)
-        self.pid = pid
-        self.role = "" # music | video | phone
-        self.icon = None
-
-        self.volume_max = 100
-        self.volume_min = 0
-        self.volume_target = 100
-        self.volume_step = 2   
-
+        self.description = self.core.clean_client_name(name)
+        self.volume_default = 100
+        self.volume_mute = -1
         self.rule_re_window_title = re.compile("")
         self.rule_re_command = re.compile("")
         self.rule_re_application = re.compile("")
-        
+        self.category = "" # music | video | phone
         self.apply_volume_meter_hack = True
         self.fade_volume = True
-        self.prefer_sink = ""
-
-
-        self.dbus_name = ""
-        self.__pause_status = 0       
-        self.application = None
-        self.sinks = {}
-        self.generate_rules()
+        self.output = ""
 
-        self.__status = False
+        self.pid = pid
+        self.volume_step = 2        
+        self.has_focus = False
+        self.fullscreen = False
+        self.icon = None
+        self.icon_name = ""
+        self.iter = None
+        self.balance = 0
 
-        self.icon_name = None
+        self.volume_target = self.volume_default
 
-        self.iter = None
-        self.gtk = None
+        self.sinks = {}
 
-    def clean_client_name(self, name):
-        name = name.strip()
-        alsa_plugin = "ALSA plug-in ["
-        if name.startswith(alsa_plugin):
-            self.apply_volume_meter_hack = True
-            name = name[len(alsa_plugin): -1]
-        return name
+        self.generate_rules()
 
-    def get_sink(self):
-        for sink_input in self.sinks.values():
-            return sink_input.sink
-        return -1
+        # TODO: remove these
+        self.window_position_fade = False
+        self.matched = False
 
     def get_volume(self):
         v = 0
         count = 0
         for sink in self.sinks.values():
-            v = v + sink.volume_meter_level
+            v = v + sink.volume[0]
             count = count + 1
         if count > 0: return v / count
         return v
@@ -88,19 +73,31 @@ class Client():
         return v
 
     def is_active(self):
-        for sink in self.sinks.values():
-            if sink.is_active():
-                return True
-        return False
 
+        # no sinks then not active
+        if len(self.sinks.values()) == 0: return False
 
+        timestamp = time.mktime(datetime.datetime.now().timetuple())
+
+        # check meter levels on others
+        if self.apply_volume_meter_hack:
+            for sink in self.sinks.values():
+            
+                if sink.volume_meter > 0: return True
+                
+                # HACK: Check how long its been inactive... and if more than a second count as expired
+                if timestamp - sink.volume_meter_last_non_zero < 1:
+                    return True
+            return False
+
+        return True
 
     def has_rule(self):
         return self.rule_re_command.pattern or self.rule_re_window_title.pattern or self.rule_re_application.pattern
 
     def generate_rules(self, app=None):
         if not app:
-            app = self.clean_client_name(self.name).lower()
+            app = self.core.clean_client_name(self.name).lower()
         else:
             app = app.lower()
 
@@ -113,6 +110,7 @@ class Client():
         # It will fail for things like gstreamer preview and nautilus that have no process link
         # until thats fixed at a lower level we have our trusty regular expressions
         if pid and self.pid and pid == self.pid:
+            #print "Match PID", pid, self.pid
             return True
 
         # Fall back rules if pid matching fails
@@ -135,90 +133,52 @@ class Client():
         return False
 
     def __fade_in(self):
-        self.volume_target = self.volume_max
+        self.volume_target = self.volume_default
 
     def __fade_out(self):
-        if self.volume_min == -1:
+        if self.volume_mute == -1:
             self.volume_target = self.core.mute_level
         else:
-            self.volume_target = self.volume_min
+            self.volume_target = self.volume_mute
 
     def __fade_mute(self):
-
-        if self.volume_min == -1:
-            self.volume_target = self.core.mute_level
-        else:
-            self.volume_target = self.volume_min
-
-        # if we goto 0 than our volume meter will never register a value
-        if self.volume_target < self.volume_step:
-            self.volume_target = self.volume_step
+        self.volume_target = self.volume_step # if we goto 0 than our volume meter will never register a value
     
-    def set_status(self, value):
-        if value or self.role == "default":
+    def set_primary(self, value):
+        if value or self.category == "default":
             self.__fade_in()
-            #if self.__pause_status > 0:
-            #    for plugin in self.plugins:
-            #        if plugin.enabled and not plugin.is_playing():
-            #            if plugin.set_pause(False): 
-            #                self.__pause_status = 0
         else:
             self.__fade_mute()
-            #if self.is_active() and self.__pause_status == 0:                 
-            #    self.__pause_status = 1
-        self.__status = value
-
-    def get_status(self):
-        for sink in self.sinks.values():
-            if sink.get_status():
-                return True
-        return False
-
-
-    # called by sink, check if all sinks are at correct volume
-    def check_volume(self):
-        result = True
-        for sink in self.sinks.values():
-            result = result and sink.volume_check
-
-        if result and self.__pause_status == 1:
-           #for plugin in self.plugins:
-           #     if plugin.enabled and plugin.is_playing():
-           #         plugin.set_pause(True)
-           self.__pause_status = 2
 
     def to_xml(self, el):
 
         # Set attributes to user element
         el.setAttribute("name", self.name)
         el.setAttribute("description", str(self.description))
-        el.setAttribute("volume_max", str(self.volume_max))
-        el.setAttribute("volume_min", str(self.volume_min))
+        el.setAttribute("volume_default", str(self.volume_default))
+        el.setAttribute("volume_mute", str(self.volume_mute))
         el.setAttribute("rule_re_window_title",self.rule_re_window_title.pattern)
         el.setAttribute("rule_re_command",self.rule_re_command.pattern)
         el.setAttribute("rule_re_application",self.rule_re_application.pattern)
-        el.setAttribute("role",self.role)
+        el.setAttribute("category",self.category)
+        el.setAttribute("window_position_fade", str(self.window_position_fade))
         el.setAttribute("icon_name", str(self.icon_name))
         el.setAttribute("apply_volume_meter_hack", str(self.apply_volume_meter_hack))
         el.setAttribute("fade_volume", str(self.fade_volume))
-        el.setAttribute("prefer_sink", self.prefer_sink)
 
-        if self.role == "default":
-            self.role = "event"
+        if self.category == "default":
+            self.category = "event"
 
     def from_xml(self, el):
         if(el.hasAttribute("name")) :                   self.name = el.getAttribute("name")
         if(el.hasAttribute("description")) :            self.description = el.getAttribute("description")
         if(el.hasAttribute("icon_name")) :              self.icon_name = el.getAttribute("icon_name")
-        if(el.hasAttribute("volume_max")) :         self.volume_max = int(el.getAttribute("volume_max"))
-        if(el.hasAttribute("volume_min")) :         self.volume_min = int(el.getAttribute("volume_min"))
+        if(el.hasAttribute("volume_default")) :         self.volume_default = int(el.getAttribute("volume_default"))
+        #self.volume_mute = int(el.getAttribute("volume_mute"))
         if(el.hasAttribute("rule_re_window_title")) :   self.rule_re_window_title = re.compile(el.getAttribute("rule_re_window_title"), re.IGNORECASE)
         if(el.hasAttribute("rule_re_command")) :        self.rule_re_command = re.compile(el.getAttribute("rule_re_command"), re.IGNORECASE)
         if(el.hasAttribute("rule_re_application")) :    self.rule_re_application = re.compile(el.getAttribute("rule_re_application"), re.IGNORECASE)
-        if(el.hasAttribute("role")) :               self.role = el.getAttribute("role")
+        if(el.hasAttribute("category")) :               self.category = el.getAttribute("category")
         if(el.hasAttribute("window_position_fade")) :   self.window_position_fade = el.getAttribute("window_position_fade") == "True"
         if(el.hasAttribute("apply_volume_meter_hack")): self.apply_volume_meter_hack = el.getAttribute("apply_volume_meter_hack") == "True"
         if(el.hasAttribute("fade_volume")):             self.fade_volume = el.getAttribute("fade_volume") == "True"
-        if(el.hasAttribute("prefer_sink")):                  self.prefer_sink = el.getAttribute("prefer_sink")
-
-
diff --git a/earcandy/util/DesktopFiles.py b/ear_candy/DesktopFiles.py
similarity index 100%
rename from earcandy/util/DesktopFiles.py
rename to ear_candy/DesktopFiles.py
diff --git a/earcandy/ui/EarCandyAppSelect.py b/ear_candy/EarCandyAppSelect.py
similarity index 95%
rename from earcandy/ui/EarCandyAppSelect.py
rename to ear_candy/EarCandyAppSelect.py
index 3dee445..4a0b4eb 100644
--- a/earcandy/ui/EarCandyAppSelect.py
+++ b/ear_candy/EarCandyAppSelect.py
@@ -15,13 +15,22 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys
-
-import gtk
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
 
 import re
 import copy
 
 from glade_window import GladeWindow
+from window.WindowWatcher import WindowWatcher
 from Client import Client
 
 class EarCandyAppSelect(GladeWindow):
diff --git a/earcandy/ui/EarCandyClientProperties.py b/ear_candy/EarCandyClientProperties.py
similarity index 56%
rename from earcandy/ui/EarCandyClientProperties.py
rename to ear_candy/EarCandyClientProperties.py
index 150daad..b7965ec 100644
--- a/earcandy/ui/EarCandyClientProperties.py
+++ b/ear_candy/EarCandyClientProperties.py
@@ -15,11 +15,23 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys
-import gobject
-import gtk
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
 import re
 import copy
+
 from glade_window import GladeWindow
+from window.WindowWatcher import WindowWatcher
+
 from Client import Client
 
 class EarCandyClientProperties(GladeWindow):
@@ -29,67 +41,60 @@ class EarCandyClientProperties(GladeWindow):
         
         GladeWindow.__init__(self, "pulseoptions.glade", "window_client_properties", parent)
         
-        self.entry_description = self.wtree.get_object("entry_description")
-        self.image_icon = self.wtree.get_object("image_icon")
-        self.hscale_max_volume = self.wtree.get_object("hscale_max_volume")
-        self.hscale_min_volume = self.wtree.get_object("hscale_min_volume")
-        self.entry_window_title = self.wtree.get_object("entry_window_title")
-        self.entry_command = self.wtree.get_object("entry_command")
-        self.entry_application = self.wtree.get_object("entry_application")
-        self.label_name = self.wtree.get_object("label_name")
-        self.entry_name = self.wtree.get_object("entry_name")
-        self.combobox_category = self.wtree.get_object("combobox_category")
-        self.checkbutton_fix = self.wtree.get_object("checkbutton_fix")
-        self.checkbutton_fade_volume = self.wtree.get_object("checkbutton_fade_volume")
-        self.combobox_output = self.wtree.get_object("combobox_output")
+        self.entry_description = self.wtree.get_widget("entry_description")
+        self.image_icon = self.wtree.get_widget("image_icon")
+        self.hscale_max_volume = self.wtree.get_widget("hscale_max_volume")
+        self.entry_window_title = self.wtree.get_widget("entry_window_title")
+        self.entry_command = self.wtree.get_widget("entry_command")
+        self.entry_application = self.wtree.get_widget("entry_application")
+        self.label_name = self.wtree.get_widget("label_name")
+        self.entry_name = self.wtree.get_widget("entry_name")
+        self.combobox_category = self.wtree.get_widget("combobox_category")
+        self.checkbutton_fix = self.wtree.get_widget("checkbutton_fix")
+        self.checkbutton_fade_volume = self.wtree.get_widget("checkbutton_fade_volume")
+        self.combobox_output = self.wtree.get_widget("combobox_output")
 
         signals = {
             "on_button_close_clicked" : self.on_button_close_clicked,
             "on_button_apply_clicked" : self.on_button_apply_clicked
         }
-        self.wtree.connect_signals(signals)
+        self.wtree.signal_autoconnect(signals)
 
         self.entry_description.set_text(client.description)
 
         self.window.set_title("Ear Candy : " + client.description)
-        self.image_icon.set_from_pixbuf(client.icon)      
-        self.hscale_max_volume.set_value( client.volume_max )
-        self.hscale_min_volume.set_value( client.volume_min )
+
+        self.image_icon.set_from_pixbuf(client.icon)
+        
+        self.hscale_max_volume.set_value( client.volume_default )
+
         self.entry_window_title.set_text( client.rule_re_window_title.pattern )
+        
         self.entry_command.set_text( client.rule_re_command.pattern )
+
         self.entry_application.set_text( client.rule_re_application.pattern )
+
         self.label_name.set_markup("<b><big>" + client.description + "</big></b>")
-        self.entry_name.set_text(client.name)
-        self.checkbutton_fix.set_active( client.apply_volume_meter_hack )
-        self.checkbutton_fade_volume.set_active( client.fade_volume )
 
+        self.entry_name.set_text(client.name)
 
-        #store = gtk.ListStore(gobject.TYPE_STRING)
-        #self.combobox_output.set_model(store)
-        #cell = gtk.CellRendererText()
-        #self.combobox_output.pack_start(cell, True)
-        #self.combobox_output.add_attribute(cell, 'text', 0)
+        self.checkbutton_fix.set_active( client.apply_volume_meter_hack )
 
-        store = gtk.ListStore(gobject.TYPE_STRING)
-        self.combobox_category.set_model(store)
-        cell = gtk.CellRendererText()
-        self.combobox_category.pack_start(cell, True)
-        self.combobox_category.add_attribute(cell, 'text', 0)
+        self.checkbutton_fade_volume.set_active( client.fade_volume )
 
-        
         count = 0
         for value in self.core.display.values():
             self.combobox_category.append_text(value)
-            if self.core.display[client.role] == value: self.combobox_category.set_active(count)
+            if self.core.display[client.category] == value: self.combobox_category.set_active(count)
             count = count + 1
         
         self.client = client
 
         count = 1
         self.combobox_output.set_active(0 )
-        for key in self.core.pa.sinks.keys():
-            self.combobox_output.append_text(self.core.pa.sinks[key].description)
-            if self.core.pa.sinks[key].name == client.prefer_sink: 
+        for key in self.core.pa_output_descriptions.keys():
+            self.combobox_output.append_text(self.core.pa_output_descriptions[key])
+            if self.core.pa_outputs[key] == client.output: 
                 self.combobox_output.set_active(count)
             count = count + 1
 
@@ -98,8 +103,7 @@ class EarCandyClientProperties(GladeWindow):
 
     def on_button_apply_clicked(self, widget):
         self.client.description = self.entry_description.get_text()
-        self.client.volume_max = int(self.hscale_max_volume.get_value())
-        self.client.volume_min = int(self.hscale_min_volume.get_value())
+        self.client.volume_default = int(self.hscale_max_volume.get_value())
         self.client.rule_re_window_title = re.compile( self.entry_window_title.get_text() )
         self.client.rule_re_command = re.compile( self.entry_command.get_text() )
         self.client.rule_re_application = re.compile( self.entry_application.get_text() )
@@ -107,16 +111,14 @@ class EarCandyClientProperties(GladeWindow):
         self.client.apply_volume_meter_hack = self.checkbutton_fix.get_active()
         self.client.fade_volume = self.checkbutton_fade_volume.get_active()
 
-        output = ""
-        self.client.prefer_sink = ""
-        for key in self.core.pa.sinks.keys():
-            if self.core.pa.sinks[key].description == self.combobox_output.get_active_text():
-                self.client.prefer_sink = self.core.pa.sinks[key].name
-        self.core.pa.move_client_to_sink(self.client)
+        self.client.output = ""
+        for key in self.core.pa_output_descriptions.keys():
+            if self.core.pa_output_descriptions[key] == self.combobox_output.get_active_text():
+                self.client.output = self.core.pa_outputs[key]
 
-        self.client.role = ""
+        self.client.category = ""
         for key in self.core.display.keys():
             if self.core.display[key] == self.combobox_category.get_active_text():
-                self.client.role = key
+                self.client.category = key
 
         self.stop()
diff --git a/earcandy/EarCandyDBus.py b/ear_candy/EarCandyDBus.py
similarity index 100%
rename from earcandy/EarCandyDBus.py
rename to ear_candy/EarCandyDBus.py
diff --git a/earcandy/ui/EarCandyPrefs.py b/ear_candy/EarCandyPrefs.py
similarity index 56%
rename from earcandy/ui/EarCandyPrefs.py
rename to ear_candy/EarCandyPrefs.py
index 9b89867..853f987 100644
--- a/earcandy/ui/EarCandyPrefs.py
+++ b/ear_candy/EarCandyPrefs.py
@@ -19,15 +19,24 @@ import sys
 import gobject
 import re
 import time
-import gtk
-
-from earcandy.util.Threads import threaded
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+
+from Threads import threaded
 from glade_window import GladeWindow
 from EarCandyAppSelect import EarCandyAppSelect
 from EarCandyClientProperties import EarCandyClientProperties
-from Client import Client
 
-class EarCandayPrefs(GladeWindow):
+class EarCandayPref(GladeWindow):
     def __init__(self, core):
         
         self.core = core
@@ -36,35 +45,29 @@ class EarCandayPrefs(GladeWindow):
 
         GladeWindow.__init__(self, "pulseoptions.glade", "dialog_options")
 
-        self.treeview_pulse_clients = self.wtree.get_object("treeview_pulse_clients")
-        self.label_pulse_client = self.wtree.get_object("label_pulse_client")
-        self.entry_pulse_client_description = self.wtree.get_object("entry_pulse_client_description")
-        self.comboboxentry_window_match = self.wtree.get_object("comboboxentry_window_match")
-        self.radiobutton_do_not_mute_others = self.wtree.get_object("radiobutton_do_not_mute_others")
-        self.radiobutton_mute_others_onfocus = self.wtree.get_object("radiobutton_mute_others_onfocus")
-        self.radiobutton_mute_others_focus = self.wtree.get_object("radiobutton_mute_others_focus")
-        self.checkbutton_mute_onblur = self.wtree.get_object("checkbutton_mute_onblur")
-        self.checkbutton_do_not_mute = self.wtree.get_object("checkbutton_do_not_mute")
-        self.vscale_volume = self.wtree.get_object("vscale_volume")
-        self.vscale_mute = self.wtree.get_object("vscale_mute")
-        self.combobox_profile = self.wtree.get_object("combobox_profile")
-        self.entry_application = self.wtree.get_object("entry_application")
-        self.entry_command = self.wtree.get_object("entry_command")
-        self.entry_window_title = self.wtree.get_object("entry_window_title")
-        self.checkbutton_channel_window = self.wtree.get_object("checkbutton_channel_window")
-        self.label_client = self.wtree.get_object("label_client")
-        self.hscale_fade = self.wtree.get_object("hscale_fade")
-        self.hscale_mute_level = self.wtree.get_object("hscale_mute_level")
-        self.checkbutton_tray = self.wtree.get_object("checkbutton_tray")
-        self.checkbutton_output = self.wtree.get_object("checkbutton_output")
-        self.combobox_view = self.wtree.get_object("combobox_view")
-        self.checkbutton_autostart = self.wtree.get_object("checkbutton_autostart")
-        self.treeview_plugins = self.wtree.get_object("treeview_plugins")
-        self.checkbutton_mute_phone = self.wtree.get_object("checkbutton_mute_phone")
-        self.combobox_sink = self.wtree.get_object("combobox_sink")
-        self.vbox_repeater = self.wtree.get_object("vbox_repeater")
-        self.table_clients = self.wtree.get_object("table_clients")
-        self.treeview_outputs = self.wtree.get_object("treeview_outputs")
+        self.treeview_pulse_clients = self.wtree.get_widget("treeview_pulse_clients")
+        self.label_pulse_client = self.wtree.get_widget("label_pulse_client")
+        self.entry_pulse_client_description = self.wtree.get_widget("entry_pulse_client_description")
+        self.comboboxentry_window_match = self.wtree.get_widget("comboboxentry_window_match")
+        self.radiobutton_do_not_mute_others = self.wtree.get_widget("radiobutton_do_not_mute_others")
+        self.radiobutton_mute_others_onfocus = self.wtree.get_widget("radiobutton_mute_others_onfocus")
+        self.radiobutton_mute_others_focus = self.wtree.get_widget("radiobutton_mute_others_focus")
+        self.checkbutton_mute_onblur = self.wtree.get_widget("checkbutton_mute_onblur")
+        self.checkbutton_do_not_mute = self.wtree.get_widget("checkbutton_do_not_mute")
+        self.vscale_volume = self.wtree.get_widget("vscale_volume")
+        self.vscale_mute = self.wtree.get_widget("vscale_mute")
+        self.combobox_profile = self.wtree.get_widget("combobox_profile")
+        self.entry_application = self.wtree.get_widget("entry_application")
+        self.entry_command = self.wtree.get_widget("entry_command")
+        self.entry_window_title = self.wtree.get_widget("entry_window_title")
+        self.checkbutton_channel_window = self.wtree.get_widget("checkbutton_channel_window")
+        self.label_client = self.wtree.get_widget("label_client")
+        self.hscale_fade = self.wtree.get_widget("hscale_fade")
+        self.hscale_mute_level = self.wtree.get_widget("hscale_mute_level")
+        self.checkbutton_tray = self.wtree.get_widget("checkbutton_tray")
+        self.checkbutton_output = self.wtree.get_widget("checkbutton_output")
+        self.combobox_view = self.wtree.get_widget("combobox_view")
+        self.checkbutton_autostart = self.wtree.get_widget("checkbutton_autostart")
 
         signals = {
             "on_entry_pulse_client_description_changed" : self.on_entry_pulse_client_description_changed,
@@ -72,8 +75,8 @@ class EarCandayPrefs(GladeWindow):
             "on_entry_application_changed" : self.on_entry_application_changed,
             "on_entry_command_changed" : self.on_entry_command_changed,
             "on_entry_window_title_changed" : self.on_entry_window_title_changed,
-            #"on_vscale_volume_change_value" : self.on_vscale_volume_change_value,
-            #"on_vscale_mute_change_value" : self.on_vscale_mute_change_value,
+            "on_vscale_volume_change_value" : self.on_vscale_volume_change_value,
+            "on_vscale_mute_change_value" : self.on_vscale_mute_change_value,
             "on_checkbutton_channel_window_toggled" : self.on_checkbutton_channel_window_toggled,
 
             "on_treeview_pulse_clients_cursor_changed" : self.on_treeview_pulse_clients_cursor_changed,
@@ -96,90 +99,81 @@ class EarCandayPrefs(GladeWindow):
 
             "on_button_reset_clicked" : self.on_button_reset_clicked,
 
-            "on_checkbutton_autostart_toggled" : self.on_checkbutton_autostart_toggled,
+            "on_checkbutton_autostart_toggled" : self.on_checkbutton_autostart_toggled
+        }
+        self.wtree.signal_autoconnect(signals)
+                
+        # Setup tree
 
-            "on_checkbutton_mute_phone_toggled" : self.on_checkbutton_mute_phone_toggled,
 
-            "on_combobox_sink_changed" : self.on_combobox_sink_changed,
+        column = gtk.TreeViewColumn((''))
+        column.set_spacing(4)
+        cell = gtk.CellRendererPixbuf()
+        column.pack_start(cell, False)
+        column.set_attributes(cell, pixbuf=0)
+        self.treeview_pulse_clients.append_column(column)
 
-            "on_treeview_outputs_drag_drop" : self.on_treeview_outputs_drag_drop
-        }
-        self.wtree.connect_signals(signals)
+        column_label = gtk.TreeViewColumn(('Application'))
+        cell = gtk.CellRendererText()
+        column_label.pack_start(cell, True)
+        column_label.set_attributes(cell, markup=1)
+        self.treeview_pulse_clients.append_column(column_label)
+        column_label.set_expand(True)
 
         #list store for cell renderer
         self.cb_model = gtk.ListStore(str)
         for key in self.core.display.keys():
             self.cb_model.append([self.core.display[key]])
 
+        cell = gtk.CellRendererCombo()
+        cell.connect('edited', self.on_client_category_changed)
+        column = gtk.TreeViewColumn('Category', cell)
+        cell.set_property("model",self.cb_model)
+        cell.set_property('text-column', 0)
+        cell.set_property('editable', True)
+        cell.connect('editing-started', self.cell_edit_start)
+        column.set_attributes(cell, text = 2)
+        column.set_expand(False)
+        self.treeview_pulse_clients.append_column(column)
+
+        """column = gtk.TreeViewColumn('Fix')
+        cell = gtk.CellRendererToggle()
+        cell.set_property('activatable', True)
+        cell.connect( 'toggled', self.on_client_fade_toggled)
+        column.pack_start(cell, False)
+        column.set_attributes(cell, active=3)
+        self.treeview_pulse_clients.append_column(column)"""
+
         self.last_popup = None
         self.last_path = None
         #self.update_treeview()
+        self.combobox_view.set_active(0)
 
         self.checkbutton_autostart.set_active( self.core.is_auto_start() )
-        self.checkbutton_mute_phone.set_active( self.core.mute_phone )
-
-
-        column_label = gtk.TreeViewColumn(('Source'))
-        cell = gtk.CellRendererText()
-        column_label.pack_start(cell, True)
-        column_label.set_attributes(cell, markup=1)
-        self.treeview_outputs.append_column(column_label)
-        column_label.set_expand(True)
-        self.store = gtk.ListStore(str, str, object)
-        self.treeview_outputs.set_model(self.store) 
-
-        self.clients = {}
-
-        # fix color : Fix this for dark themes....
-        style = gtk.Style()
-        viewport1 = self.wtree.get_object("viewport1")
-        viewport1.modify_bg(gtk.STATE_NORMAL, style.base[gtk.STATE_NORMAL])
-
-
-    def on_treeview_outputs_drag_drop(self, widget, b):
-        self.update_ouput_order()
-
-
-    def on_combobox_sink_changed(self, widget):
-        
-        return
-
-    def on_treeview_plugins_toggled(self, cell, path):
-        model =  self.treeview_plugins.get_model()
-        iter = model.get_iter((int(path),))
-        if not iter: return
-
-        model[path][0] = not model[path][0]
-        model[path][2].enabled = model[path][0]
-
-    def on_checkbutton_mute_phone_toggled(self, widget):
-        self.core.mute_phone = not self.core.mute_phone
 
     def on_checkbutton_autostart_toggled(self, widget):
         self.core.set_auto_start( widget.get_active() )
 
     def on_button_reset_clicked(self, widget):
 
-        md = gtk.MessageDialog(self.window, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_YES_NO, message_format="Are you sure you want to reset all your settings?") 
+        md = gtk.MessageDialog(self.window, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_YES_NO, message_format="Are you sure you want to reset all volume levels?") 
         result = md.run()
         md.destroy()
         if result == gtk.RESPONSE_YES:
-            self.window.destroy()
-            self.core.reset_all()
-            self.core.pref = None
-            self.core.open_preferances()
+            self.core.reset_all_volumes(False)
 
     def cell_edit_start(self,  editable, control, path):
         self.last_popup = control
         self.last_path = path
 
     def on_combobox_view_changed(self, widget):
-        return
-        #self.update_treeview()
+        self.update_treeview()
 
 
     def on_checkbutton_tray_toggled(self, widget):
-        self.core.status_icon.set_visible( widget.get_active() )
+        self.core.tray.set_visible( widget.get_active() )
+        if widget.get_active():
+            self.core.move_all_sinks()
 
     def on_checkbutton_output_toggled(self, widget):
         self.core.follow_new_outputs = widget.get_active()
@@ -201,14 +195,14 @@ class EarCandayPrefs(GladeWindow):
     def on_hscale_fade_value_changed(self, widget):
         self.core.fade_timer_speed = self.hscale_fade.get_value()
 
-    def on_client_role_changed(self, cell, row, newText):
+    def on_client_category_changed(self, cell, row, newText):
         model, iter =  self.treeview_pulse_clients.get_selection().get_selected()
         if not iter: return
         self.selected_client = model.get_value(iter, 5)
 
         for key in self.core.display.keys():
             if self.core.display[key] == newText:
-                self.selected_client.role = key
+                self.selected_client.category = key
                 self.store.set(iter,
                     2,  newText
                 )
@@ -222,7 +216,7 @@ class EarCandayPrefs(GladeWindow):
         result = md.run()
         md.destroy()
         if result == gtk.RESPONSE_YES:
-            self.selected_client.role = ""
+            self.selected_client.category = ""
             self.selected_client.iter = None
             self.store.remove(iter)
         self.core.save()
@@ -232,14 +226,11 @@ class EarCandayPrefs(GladeWindow):
         model, iter =  self.treeview_pulse_clients.get_selection().get_selected()
         if not iter: return
         self.selected_client = model.get_value(iter, 5)
+        print self.selected_client
         
-
-
-
-    def open_client_properties(self, client):
-        eccp = EarCandyClientProperties(self.core, client, self.window)
+        eccp = EarCandyClientProperties(self.core, self.selected_client, self.window)
         eccp.run()
-        self.update_client(client)
+        self.update_client(self.selected_client)
         self.core.save()
 
     def on_button_add_new_clicked(self, widget):
@@ -270,7 +261,7 @@ class EarCandayPrefs(GladeWindow):
     def on_combobox_profile_changed(self, widget):
         for key in self.vals.keys():
             if self.vals[key] == self.combobox_profile.get_active():
-                self.current_client.role = key
+                self.current_client.category = key
                 self.core.save()
 
     def on_vscale_volume_change_value(self, widget, a, b):
@@ -315,120 +306,68 @@ class EarCandayPrefs(GladeWindow):
 
     def __get_title(self, client):
         text = client.name
-        if client.is_active() and client.get_status():
-            text = "<b>" + client.description + "</b>"
-            for sink in client.sinks.values():
-                text += "\n<small><i>" + sink.name + "</i></small>"
-            return text
-
-        elif not client.is_active():
-            return "<i>" + client.description + "</i>"
-
-        return client.description
+        if client.description:
+            text = client.description
+        return text
 
     def update_treeview(self):
-        for client in self.core.pa.clients.values():
+        for client in self.core.pa_clients.values():
             client.iter = None
 
-        self.store = gtk.ListStore(gtk.gdk.Pixbuf, str, str, bool, int, object, str)
+        self.store = gtk.ListStore(gtk.gdk.Pixbuf, str, str, bool, int, object)
         self.treeview_pulse_clients.set_model(self.store) 
 
         icon_theme = gtk.icon_theme_get_default()
         icon = icon_theme.lookup_icon("audio-volume-medium", 32, 0).load_icon()
-        for client in self.core.pa.clients.values():
-            if not (client.name in self.core.ignore):
+        for client in self.core.pa_clients.values():
+            if client.category and not (client.name in self.core.ignore):
                 if client.is_active() or self.combobox_view.get_active() == 1:
-                    client.iter = self.store.append(([client.icon or icon, self.__get_title(client), self.core.display[client.role], client.apply_volume_meter_hack, 0, client, client.description])) 
+                    client.iter = self.store.append(([client.icon or icon, self.__get_title(client), self.core.display[client.category], client.apply_volume_meter_hack, 50, client])) 
 
-        self.store.set_sort_column_id(6, gtk.SORT_ASCENDING)  
+        self.store.set_sort_column_id(1, gtk.SORT_ASCENDING)  
 
     def update_client(self, client):
 
         # load saved icon
-        if not client.icon:
-            if client.icon_name:
-                print "load client icon", client.icon_name
-                icon_theme = gtk.icon_theme_get_default()
-                try:
-                    client.icon = icon_theme.load_icon(client.icon_name, 32, 0)
-                except:
-                    client.icon = icon_theme.load_icon("audio-volume-medium", 32, 0)
-            elif client.application and client.application.icon_name:
-                icon_theme = gtk.icon_theme_get_default()
-                try:
-                    client.icon = icon_theme.load_icon(client.application.icon_name, 32, 0)
-                except:
-                    client.icon = icon_theme.load_icon("audio-volume-medium", 32, 0)
-        
-        if not self.clients.has_key(client.name):
-
-            client_gtk = Client(client, self.core)
-            self.clients[client.name] = client_gtk
-            self.vbox_repeater.pack_start(client_gtk.gtk, expand=False, fill=False, padding=0)
-            client_gtk.gtk.show()
-
-            count = 0 
-            for key in self.core.display.keys():
-                if key == client.role: 
-                    client_gtk.gtk_role_combobox.set_active(count)
-                    break
-                count = count + 1
-        
-        else:
-            client_gtk = self.clients[client.name]
-
-        client_gtk.set_status(client.is_active())
-
-        client_gtk.gtk_progressbar_meter.set_fraction(client.get_volume() / 100)
-        client_gtk.gtk_label.set_markup(self.__get_title(client))
-        if client.icon: client_gtk.gtk_icon.set_from_pixbuf(client.icon)
-
-        for key in self.core.display.keys():
-            self.cb_model.append([self.core.display[key]])
-
-        client_gtk.gtk.show()
-
-    def update_output(self, output, priority):
-        itr = self.store.get_iter_first()
-        while itr:
-            o = self.store.get_value(itr, 2)
-            if o.name == output.name:
-                if not output.index:
-                    self.store.remove(itr)
-                    self.update_ouput_order()
-                return
-            itr = self.store.iter_next(itr)
-
-        self.store.insert(priority, ([output.name, output.description, output]))
-
-        self.update_ouput_order()
-
-    def update_ouput_order(self):
-
-        itr = self.store.get_iter_first()
-        count = 1
-        flagCurrent = False
-        while itr:
-            output = self.store.get_value(itr, 2)
-            output.priority = count
-            if count == 1:
-                self.store.set_value(itr, 1, "<b>" + output.description + "</b>")
+        if not client.icon and client.icon_name:
+            print "load client icon", client.icon_name
+            icon_theme = gtk.icon_theme_get_default()
+            try:
+                client.icon = icon_theme.load_icon(client.icon_name, 32, 0)
+            except:
+                client.icon = icon_theme.load_icon("audio-volume-medium", 32, 0)
+
+        if client.iter:
+            if client.is_active():
+                self.store.set(client.iter,
+                    0, client.icon,
+                    1,  self.__get_title(client),
+                    4, client.get_volume()
+                )
+                if client.category in self.core.display.keys():
+                    self.store.set(client.iter,
+                        2,  self.core.display[client.category]
+                    )
             else:
-                self.store.set_value(itr, 1, output.description)
-
-            itr = self.store.iter_next(itr)
-            
-            count = count + 1
+                pass
+                # This needs to be on a timer
+                #self.store.remove(client.iter)
+                #client.iter = None
+        else:
+            if client.has_rule() and not client.name in self.core.ignore:
+                icon_theme = gtk.icon_theme_get_default()
+                icon = icon_theme.lookup_icon("audio-volume-medium", 32, 0).load_icon()
+                client.iter = self.store.append(([client.icon or icon, self.__get_title(client), self.core.display[client.category], client.apply_volume_meter_hack, client.get_volume(), client])) 
 
-        self.core.pa.set_default_prefered_device()
+        self.store.set_sort_column_id(1,gtk.SORT_ASCENDING)
 
     def run(self):
         self.window.show()  
         self.hscale_mute_level.set_value(self.core.mute_level)
         self.hscale_fade.set_value(self.core.fade_timer_speed)
-        self.checkbutton_tray.set_active( self.core.status_icon.get_visible() )
+        self.checkbutton_tray.set_active( self.core.tray.get_visible() )
+        self.checkbutton_output.set_active( self.core.follow_new_outputs )
         self.window.present()
-        self.core.pa.pa_context_get_sink_info_list()
         return self.return_value
 
     def stop(self):
@@ -436,6 +375,18 @@ class EarCandayPrefs(GladeWindow):
         self.core.close_preferances()
         self.window.destroy()
     
+    @threaded
+    def remove_client_on_timer(self, client):
+        #time.sleep(60)
+        #gobject.idle_add(self.remove_client, client) 
+        return
+    
+    def remove_client(self, client):
+        if not client.is_active() and client.iter :
+            self.store.remove(client.iter)
+            client.iter = None
+
+
 
 
 
diff --git a/earcandy/util/Freedesktop.py b/ear_candy/Freedesktop.py
similarity index 100%
rename from earcandy/util/Freedesktop.py
rename to ear_candy/Freedesktop.py
diff --git a/ear_candy/Sink.py b/ear_candy/Sink.py
new file mode 100644
index 0000000..db474f9
--- /dev/null
+++ b/ear_candy/Sink.py
@@ -0,0 +1,64 @@
+# Ear Candy - Pulseaduio sound managment tool
+# Copyright (C) 2008 Jason Taylor
+# 
+# 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, see <http://www.gnu.org/licenses/>.
+
+import math  
+import time
+          
+class Sink():
+    def __init__(self, index, name, volume, client, channels=1):
+
+        self.index = index
+        self.name = name
+        self.client = client
+        self.volume = volume
+        self.channels = channels
+
+        self.volume_meter = 0
+        self.volume_meter_last_non_zero = 0
+
+        self.__previous_volume = 0
+ 
+    def set_volume(self):
+
+        current_volume = round(self.volume[1])
+        step_volume = current_volume
+        result = True
+
+        if current_volume < self.client.volume_target:      
+            step_volume = current_volume + self.client.volume_step
+            if not self.client.fade_volume: step_volume = self.client.volume_target
+        elif current_volume > self.client.volume_target: 
+            step_volume = current_volume - self.client.volume_step
+            if not self.client.fade_volume: step_volume = self.client.volume_target
+        
+        if step_volume > 100:
+            step_volume = 100
+        if step_volume < self.client.volume_step:
+            step_volume = self.client.volume_step
+
+        # we dont want to get stuck in a loop because volumes arn't exactly the same 
+        result = math.fabs(self.__previous_volume - current_volume) >= self.client.volume_step
+
+        if result:
+            for i in range(0, self.channels+1):
+                self.volume[i] = step_volume
+
+            #print "\nAdjust Volume", self.client.name, step_volume
+
+        self.__previous_volume = step_volume
+       
+        return result
+
diff --git a/earcandy/util/Threads.py b/ear_candy/Threads.py
similarity index 100%
rename from earcandy/util/Threads.py
rename to ear_candy/Threads.py
diff --git a/earcandy/ui/TrayIcon.py b/ear_candy/TrayIcon.py
similarity index 66%
rename from earcandy/ui/TrayIcon.py
rename to ear_candy/TrayIcon.py
index 5d89f36..44a8868 100644
--- a/earcandy/ui/TrayIcon.py
+++ b/ear_candy/TrayIcon.py
@@ -19,7 +19,16 @@ import os
 import sys
 import gtk
 
-from earcandy.earcandyconfig import getdatapath
+def find_program_file(path):
+    """Finds a program file, for example, a png included with the program.
+    First looks for it in files/ under the parent directory of the parent directory
+    of ear_candy.py
+    Then looks for it in /usr/share/earcandy
+    Returns the path of the file"""
+    if os.path.exists(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)):
+        return os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)
+    else:
+        return os.path.join(sys.prefix, "share/earcandy", path)
 
 class EarCandyStatusIcon(gtk.StatusIcon):
     def __init__(self, core):
@@ -30,7 +39,6 @@ class EarCandyStatusIcon(gtk.StatusIcon):
             <ui>
              <menubar name="Menubar">
               <menu action="Menu">
-               <separator/>
                <menuitem action="Preferences"/>
                <menuitem action="About"/>
                <separator/>
@@ -41,10 +49,7 @@ class EarCandyStatusIcon(gtk.StatusIcon):
         '''
         actions = [
             ('Menu',  None, 'Menu'),
-            ('Mute', "stock_volume-mute", '_Mute...', None, 'Mute sound', self.on_preferences),
-            ('Lock', "stock_lock", '_Lock...', None, 'Lock volume levels', self.on_preferences),
             ('Preferences', gtk.STOCK_PREFERENCES, '_Preferences...', None, 'Edit Preferences', self.on_preferences),
-
             ('About', gtk.STOCK_ABOUT, '_About...', None, 'About Ear Candy', self.on_about),
             ('Exit', gtk.STOCK_STOP, '_Exit...', None, 'Exit Ear Candy', self.stop)]
         ag = gtk.ActionGroup('Actions')
@@ -60,31 +65,38 @@ class EarCandyStatusIcon(gtk.StatusIcon):
         self.connect('activate', self.on_activate)
         self.connect('popup-menu', self.on_popup_menu)
 
-
     def on_activate(self, data):
 
-        self.core.open_preferances()
+        if not self.core.slider.active:
+            self.core.slider.window.set_position(gtk.WIN_POS_MOUSE)
+            screen, rect, orin = self.get_geometry()           
+            x, y = self.core.slider.window.get_position()
+            if rect.y - rect.height/2 > y - rect.height:
+                self.core.slider.window.move(x, y + rect.height)
+            self.core.slider.run()
             
     def on_preferences(self, widget):
         self.core.open_preferances()
 
-    def on_reset(self, widget):
-        self.core.reset()
-
-    def on_popup_menu(self, status, button=None, time=0):
+    def on_popup_menu(self, status, button, time):
         self.menu.popup(None, None, None, button, time)
 
     def on_about(self, data):
         dialog = gtk.AboutDialog()
         dialog.set_name('Ear Candy')
         dialog.set_version(str(self.core.version))
-        dialog.set_comments('An pulseaudio / X.org sound volume manager')
-        dialog.set_website('https://launchpad.net/earcandy')
+        dialog.set_comments('An pulseaudio / X.org sound manager')
+        dialog.set_website('http://edge.launchpad.net/eyecandy')
         dialog.run()
         dialog.destroy()
     
+
     def set_icon(self):
-        self.set_from_file( os.path.join(getdatapath(), 'media', 'icon.png') )
+        if self.core.active:
+            icon_path = find_program_file("earsLabel.png")
+        else:
+            icon_path = find_program_file("earsLabelOff.png")
+        self.set_from_file( icon_path )
 
     def stop(self, data=None):
         self.core.exit()
diff --git a/earcandy/ui/VolumeSlider.py b/ear_candy/VolumeSlider.py
similarity index 84%
rename from earcandy/ui/VolumeSlider.py
rename to ear_candy/VolumeSlider.py
index 8579a82..05df249 100644
--- a/earcandy/ui/VolumeSlider.py
+++ b/ear_candy/VolumeSlider.py
@@ -15,14 +15,23 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys, os
-
-import gtk
-import gtk.glade
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
 
 import re
 import copy
 
 from glade_window import GladeWindow
+from window.WindowWatcher import WindowWatcher
+from Client import Client
 
 class EarCandyVolumeSlider(GladeWindow):
     def __init__(self, core):
@@ -32,13 +41,12 @@ class EarCandyVolumeSlider(GladeWindow):
         
         self.vscale_volume = self.wtree.get_widget("vscale_volume")
         self.image_status = self.wtree.get_widget("image_status")
-        self.image_mute = self.wtree.get_widget("image_mute")
 
         signals = {
           "on_popup_volume_control_focus_out_event" : self.on_popup_volume_control_focus_out_event,
           "on_vscale_volume_change_value" : self.on_vscale_volume_change_value,
-          "on_button_suspend_clicked" : self.on_button_suspend_clicked,
-          "on_button_mute_clicked" : self.on_button_mute_clicked
+          "on_button_suspend_clicked" : self.on_button_suspend_clicked
+
         }
 
         self.wtree.signal_autoconnect(signals)
@@ -50,21 +58,11 @@ class EarCandyVolumeSlider(GladeWindow):
         #    self.combobox_client_category.append_text( val )
         self.active = False
 
-    def on_button_mute_clicked(self, widget):
-        self.core.set_mute( not self.core.is_mute )
-        self.stop()
-
     def on_button_suspend_clicked(self, widget):
 
         self.core.set_active( not self.core.active )
         self.stop()
 
-    def update_mute_status(self):
-        if self.core.is_mute:
-            self.image_mute.set_from_file( self.core.find_program_file("volume-magic.png") )
-        else:
-            self.image_mute.set_from_file( self.core.find_program_file("volume-muted.png") ) 
-
     def update_active_status(self):
         if self.core.active:
             self.image_status.set_from_stock("gtk-media-pause", 4)
@@ -87,7 +85,7 @@ class EarCandyVolumeSlider(GladeWindow):
 
     def run(self):
         self.active = True
-        #self.core.get_current_sink_volume()
+        self.core.get_current_sink_volume()
         self.window.present()
         gtk.gdk.keyboard_grab(self.window.window, True)
         gtk.gdk.pointer_grab(self.window.window, True,
diff --git a/ear_candy/__init__.py b/ear_candy/__init__.py
new file mode 100644
index 0000000..4265cc3
--- /dev/null
+++ b/ear_candy/__init__.py
@@ -0,0 +1 @@
+#!/usr/bin/env python
diff --git a/ear_candy/ear_candy.py b/ear_candy/ear_candy.py
new file mode 100755
index 0000000..2b4e74e
--- /dev/null
+++ b/ear_candy/ear_candy.py
@@ -0,0 +1,552 @@
+#!/usr/bin/env python
+
+# Ear Candy - Pulseaduio sound managment tool
+# Copyright (C) 2008 Jason Taylor
+# 
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import wnck
+import gobject
+import time
+import datetime
+import re
+import os
+import copy
+import sys
+import gconf
+import time
+import shutil
+import pynotify
+from xml.dom.minidom import *
+
+from window.WindowWatcher import WindowWatcher
+from pulseaudio.PulseAudio import PulseAudio 
+from Client import Client
+from Sink import Sink
+from Threads import threaded
+from TrayIcon import EarCandyStatusIcon
+from EarCandyPrefs import EarCandayPref 
+from VolumeSlider import EarCandyVolumeSlider 
+from EarCandyDBus import EarCandyDBusClient
+
+# Turn on gtk threading
+gtk.gdk.threads_init()
+
+def find_program_file(path):
+    """Finds a program file, for example, a png included with the program.
+    First looks for it in files/ under the parent directory of the parent directory
+    of ear_candy.py
+    Then looks for it in /usr/share/earcandy
+    Returns the path of the file"""
+    if os.path.exists(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)):
+        return os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)
+    else:
+        return os.path.join(sys.prefix, "share/earcandy", path)
+
+gtk.window_set_default_icon_from_file(find_program_file("earsLabel.png"))
+
+class EarCandy():
+    def save(self):
+        path = os.path.dirname(self.config_file)
+        if not os.path.exists( path ):
+            os.makedirs(path)
+
+        # New document
+        doc = Document()
+        ec = doc.createElement("earcandy")
+        doc.appendChild(ec)
+	
+        rules = doc.createElement("rules")
+        ec.appendChild(rules)
+        skip = copy.copy(self.ignore)
+        for client in self.pa_clients.values():
+            if not client.name in skip and client.category:
+                # Creates user element
+                el = doc.createElement("rule")
+                rules.appendChild(el)
+                client.to_xml(el)
+                skip.append(client.name)
+        
+
+        doc.documentElement.setAttribute("fade_timer_speed", str(self.fade_timer_speed))
+        doc.documentElement.setAttribute("mute_level", str(self.mute_level))
+        doc.documentElement.setAttribute("tray_visible", str(self.tray.get_visible()))
+        doc.documentElement.setAttribute("managed_output_name", str(self.managed_output_name))
+        doc.documentElement.setAttribute("follow_new_outputs", str(self.follow_new_outputs))
+        doc.documentElement.setAttribute("version", str(self.version))
+
+        # Record outputs
+        outputs = doc.createElement("outputs")
+        for output in self.pa_outputs.values():
+            # Creates user element
+            el = doc.createElement("output")
+            el.setAttribute("name", output)
+            outputs.appendChild(el)
+        ec.appendChild(outputs)
+
+
+        fp = open(self.config_file,"w")
+        doc.writexml(fp, "    ", "", "\n", "UTF-8")
+        fp.close()
+
+    def load(self):
+        settings_version = 0
+        xml = None
+        doc = None
+
+        # Load the defaults
+        f = open(self.default_config_file, "r")
+        xml = f.read()
+        f.close()
+        default_doc = parseString(xml)
+        default_version = float(default_doc.documentElement.getAttribute("version"))
+
+        # Check for user settings
+        if os.path.exists( self.config_file ):
+            # Load XML
+            try:
+                f = open(self.config_file, "r")
+                xml = f.read()
+                f.close()
+                doc = parseString(xml)
+                if doc.documentElement.hasAttribute("version"):
+                    settings_version = float(doc.documentElement.getAttribute("version"))
+            except:
+                pass
+
+        # Load defaults ?
+        if not doc or default_version > settings_version:
+            doc = default_doc
+            
+        # Load client rules
+        for el in doc.getElementsByTagName("rule"):
+            client = Client(self, "")
+            client.from_xml(el)
+            if client.category:
+                print "Loaded client rules :", client.description
+            self.pa_clients[client.name] = client
+
+        self.fade_timer_speed = float(doc.documentElement.getAttribute("fade_timer_speed"))
+        #self.mute_level = float(doc.documentElement.getAttribute("mute_level"))
+        if doc.documentElement.hasAttribute("tray_visible"):
+            self.tray.set_visible( doc.documentElement.getAttribute("tray_visible") == "True" )
+        if doc.documentElement.hasAttribute("managed_output_name"):
+            self.managed_output_name = doc.documentElement.getAttribute("managed_output_name")
+        if doc.documentElement.hasAttribute("follow_new_outputs"):
+            self.follow_new_outputs = doc.documentElement.getAttribute("follow_new_outputs") == "True"
+
+    def __init__(self):
+        self.version = 0.5
+        self.active = True
+        self.display = {"": "[ unknown ]", "phone" : "Phone (VoIP)", "video" : "Video Player", "music" : "Music Player", "event" : "Notification" }
+        self.ignore = ["EsounD client (UNIX socket client)", "ear-candy", "Native client (UNIX socket client)", "PulseAudio Volume Control"]
+        self.config_file = os.path.expanduser("~/.config/Ear Candy/settings.xml")     
+        self.default_config_file = find_program_file("settings.xml")
+
+        self.pa_clients = {}        # clients by name
+        self.pa_clients_by_id = {}  # clients by id
+        self.pa_sinks = {}
+        self.pa_outputs = {}
+        self.pa_output_descriptions = {}
+        self.client_with_focus = None # client that has a focused window
+        self.last_application = None
+        self.primary_client = None # Client that gets foreground sound regardless of window focus
+        self.managed_output_name = ""
+        self.current_source_name = ""
+        self.reset_all = False
+
+        self.pref = None
+
+        self.fade_timer_speed = 0.1 
+        self.mute_level = 20
+        self.follow_new_outputs = True
+
+        self.priority_stack = { "" : [], "phone" : [], "video" : [], "music" : [] }      
+
+        pass
+
+    def run(self):
+        self.ecb = EarCandyDBusClient(self)
+
+        if self.ecb.is_running():
+            print "Ear candy already running..."
+            self.ecb.show_window()
+            sys.exit(0)
+        else:
+
+            self.tray = EarCandyStatusIcon(self)
+            
+            self.slider = EarCandyVolumeSlider(self)
+
+            self.ecb.start_service()
+            self.load()
+            self.pa = PulseAudio( self.on_new_pa_client, self.on_remove_pa_client, self.on_new_pa_sink, self.on_remove_pa_sink, self.on_new_pa_output, self.on_remove_pa_output, self.on_volume_change, self.pa_volume_meter)
+            self.ww = WindowWatcher(self.on_active_window_change)
+
+            self.select_client_thread()
+            self.apply_volume_thread()
+            
+            gtk.main()
+            self.exit()
+
+    def show_notification(self, title, body, icon):
+        try:
+            pynotify.init( "Ear Candy" )
+            n = pynotify.Notification(title, body, icon)
+            n.show ()
+        except:
+            print "Unable to show notification"
+
+    def set_active(self, active):
+        self.active = active
+        if self.slider: self.slider.update_active_status()
+        self.tray.set_icon()
+
+
+    def open_preferances(self):
+        if not self.pref:
+            self.pref = EarCandayPref(self)
+        self.pref.run()
+
+    def close_preferances(self):
+        if self.pref:
+            self.pref = None
+
+    def get_current_sink_volume(self):
+        self.pa.get_sink_info_by_name(self.managed_output_name)
+
+    @threaded
+    def apply_volume_thread(self):
+        while True:
+            time.sleep(self.fade_timer_speed)
+            if self.active:
+                gobject.idle_add(self.__adjust_volumes)      
+
+    @threaded
+    def select_client_thread(self):
+        while True:
+            time.sleep(0.5)
+            if self.active:
+                gobject.idle_add(self.__set_primary_client)  
+
+    def __adjust_volumes(self):
+
+        # Always update based on active sinks
+        for sink in self.pa_sinks.values():
+            if sink.set_volume():
+                # set pa volume
+                self.pa.set_sink_volume(sink.index, sink.volume, sink.channels)  
+
+
+    def __set_window_stack(self):
+        for client in self.pa_clients.values():
+            # self.pref.update_client( client )
+
+            # Select the primary client and order previous clients
+            for key in self.priority_stack.keys():
+                if client.category == key:
+                    # Add client to category
+                    if not client in self.priority_stack[key]:
+                        if self.client_with_focus == client:
+                            self.priority_stack[key].insert(0, client)
+                        else:
+                            self.priority_stack[key].append(client)
+
+                    # reshuffle if active
+                    elif self.client_with_focus == client and not self.priority_stack[key][0] == client:
+                        self.priority_stack[key].remove(client)
+                        self.priority_stack[key].insert(0, client)
+
+                # If category has changed remove old entry
+                elif client in self.priority_stack[key]:
+                    self.priority_stack[key].remove(client)
+
+    def __set_primary_client(self):
+
+        # Toggle primary status
+        flagFound = False
+        for key in self.priority_stack.keys():
+            if key:
+                for client in self.priority_stack[key]:         
+
+                    if not flagFound and self.active and client.is_active():
+                        # Toggle old client to inactive
+                        if self.primary_client:
+                            self.primary_client.set_primary(False)
+                        self.primary_client = client
+                        client.set_primary(True)
+                        flagFound = True
+                    else:
+                        client.set_primary(False)
+            else:
+                # all clients with no category should be treated as active for volume
+                for client in self.priority_stack[key]:
+                    client.set_primary(True)
+                     
+
+    def on_volume_change(self, level):
+        self.slider.set_volume( level )
+        #print self.managed_output_name, level
+
+    def on_remove_pa_output(self, index):
+        # /desktop/gnome/sound/default_mixer_device
+
+        del( self.pa_outputs[index] )
+        del( self.pa_output_descriptions[index] )
+
+        # fall back to previous value...
+        for value in self.pa_outputs.values():
+            self.set_last_output(value)
+            return
+
+    def set_last_output(self, name):
+        self.managed_output_name = name
+        
+        # Update gconf key that governs multimedia key controls
+        gconf_key =  "/desktop/gnome/sound/default_mixer_device"
+        prefix = "pulsemixer:"
+        client = gconf.client_get_default()
+        value = client.get_string(gconf_key)
+        if not value == prefix + name:
+            print
+            print "== Change gnome default sound device =="
+            client.set_string(gconf_key, prefix + name)
+
+    def on_new_pa_output(self, index, output_name, output_description, startup):
+        self.pa_outputs[index] = output_name
+        self.pa_output_descriptions[index] = output_description
+        self.save()
+       
+        if self.follow_new_outputs and (self.managed_output_name == "" or output_name.lower().count("usb") > 0):
+            # Move all streams to the new output ;)
+            if not startup: 
+                self.show_notification("New sound device detected", "Moving all sound to new device...", "notification-audio-volume-high")
+            self.set_last_output(output_name)
+            self.move_all_sinks()
+
+    def move_all_sinks(self):
+        if self.managed_output_name:
+            for sink in self.pa_sinks.values():
+                if not sink.client.output:
+                    self.pa.move_sink(sink.index, self.managed_output_name)
+
+    def on_new_pa_sink(self, index, name, client_index, volume, sink_index, channels):
+
+        if not self.pa_sinks.has_key(index):
+            print 
+            print "== pa sink input =="
+            print "sink:", index, name
+            if self.pa_clients_by_id.has_key(client_index):
+                client = self.pa_clients_by_id[client_index]
+                print "client:", client.name
+                print "client index:", client_index
+                print "category:", client.category
+                sink = Sink(index, name, volume, client, channels)
+                client.sinks[index] = sink
+                self.pa_sinks[index] = sink
+
+                # insure the sink input is on the correct output..
+                output = None
+                if self.follow_new_outputs and self.managed_output_name: 
+                    output = self.managed_output_name
+                
+                if client.output:
+                    output = client.output
+
+                if output:               
+                    self.pa.move_sink(sink.index, output)
+
+            else:
+                return
+        else:
+            self.pa_sinks[index].volume = volume
+        
+        if self.pref:
+            self.pref.update_client( self.pa_clients_by_id[client_index] )
+        self.on_active_window_change( self.last_application, "pa")
+
+    def pa_volume_meter(self, index, level):
+        if self.pa_sinks.has_key(index):
+            sink = self.pa_sinks[index]
+            sink.volume_meter = level
+            if(level > sink.client.volume_step): sink.volume_meter_last_non_zero = time.mktime(datetime.datetime.now().timetuple())
+
+    def on_remove_pa_sink(self, index):
+        print 
+        print "== pa remove sink input =="
+        print index
+        if self.pa_sinks.has_key(index):
+            client = self.pa_sinks[index].client
+            # Delete entry in store so that volume dosnt stay low :)
+            self.pa.pa_ext_stream_restore_delete( self.pa_sinks[index].name )
+            del( client.sinks[index] )
+            del( self.pa_sinks[index] )
+            if self.pref:
+                self.pref.update_client( client )
+            self.on_active_window_change( self.last_application, "pa")
+        
+    def get_unregistered_clients(self):
+        clients = []
+        # client names to skip from adding to list
+        skip = copy.copy(self.ignore)
+        count = 0
+        for client in self.pa_clients.values():
+            if client.category == "" and not client.icon and not client.name in skip:
+                clients.append(client)
+                skip.append( client.name )
+        return clients
+
+    def on_new_pa_client(self, index, name, pid, proplist):
+        if not pid: pid = -1
+        print 
+        print "== pa sink client =="
+        print "index:", index
+        print "name:", name
+        print proplist
+        # Link all clients with same name into same object
+
+        if not self.pa_clients.has_key(name):
+            client = Client(self, name, int(pid))
+            self.pa_clients[name] = client
+        else:
+            client = self.pa_clients[name]
+            client.pid = int(pid)
+        self.pa_clients_by_id[index] = client
+
+        # Check windows for a match
+        for application in self.ww.applications.values():
+            if self.match_client_to_application(client, application, index): break
+
+    def on_remove_pa_client(self, index):
+        print "== pa remove client =="
+        if self.pa_clients_by_id.has_key(index):
+            print self.pa_clients_by_id[index].name
+            client = self.pa_clients_by_id[index]
+
+            # remove from by ID list
+            del self.pa_clients_by_id[index]
+
+            # Remove from priority array
+            if client in self.priority_stack[client.category]:
+                self.priority_stack[client.category].remove(client)
+
+            # If not category then totaly delete the entry
+            # if not client.category: del self.pa_clients[client.name]
+
+            if self.pref:
+                self.pref.update_client( client )
+                if not client.is_active():
+                    self.pref.remove_client_on_timer( client )
+
+    def on_active_window_change(self, application, state):  #, pid, window_name, x, y, icon, fullscreen
+        if application:
+            # Need to run this if a client is added or removed...
+            if state == "active":
+                """print
+                print "== active window changed =="
+                print "window title:", application.window_name
+                print "application:", application.name
+                print "pid:", application.pid
+                print "gid:", os.getpgid(application.pid)
+                print "command:", application.command
+                print "category:", application.category"""
+
+            # set active / fullscreen flags
+            if self.client_with_focus:
+                self.client_with_focus.has_focus = False
+
+            self.client_with_focus = None
+            for client in self.pa_clients.values():
+                if self.match_client_to_application(client, application, state): break
+
+            self.last_application = application
+
+        self.__set_window_stack()
+
+    def match_client_to_application(self, client, application, index=0):
+        if client.test_focus_window(application.pid, application.window_name, application.command, application.name): 
+
+            client.fullscreen = application.fullscreen  
+            if not client.icon : client.icon = application.icon
+            if not  client.icon_name : client.icon_name = application.icon_name
+            if not  client.description :client.description = application.description
+            client.matched = True
+            #if not state == "open": 
+            self.client_with_focus = client
+
+            if not client.category:
+                client.category = application.category
+            # Balance has no practical use I can think of....
+            # Im going to leave it here in case someone thinks of something
+            #if client.window_position_fade:
+            #    client.balance = ((100 - (application.y / (gtk.gdk.screen_width() /  100))) * 2)  - 100
+            #    print "BALANCE", client.balance
+            #else:
+            #    client.balance = 0
+            if self.pref:
+                self.pref.update_client( client )
+            return True
+        return False
+
+    def clean_client_name(self, name):
+        name = name.strip()
+        alsa_plugin = "ALSA plug-in ["
+        if name.startswith(alsa_plugin):
+            name = name[len(alsa_plugin): -1]
+        return name
+
+    def exit(self):
+        self.set_active(False)
+        # Reset all volumes
+        self.reset_all_volumes()
+        sys.exit(0)
+
+    def reset_all_volumes(self, deleteFile=True):
+        print ""
+        print "Resetting all volume levels..."
+        for sink in self.pa_sinks.values():
+            self.pa.set_sink_volume(sink.index, [100, 100, 100], sink.channels)  
+
+    def set_auto_start(self, flag):
+        filename = "earcandy.desktop"
+        path = os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config/autostart'))
+        dest = os.path.join(path, filename)
+        src = find_program_file(filename)
+
+        if flag:
+            # insure the autostart path exists
+            if not os.path.exists(path):
+                os.makedirs(path)
+
+            if not os.path.exists( dest ):
+                shutil.copyfile(src, dest)
+        else:
+            if os.path.exists( dest ):
+                os.remove( dest )
+
+    def is_auto_start(self):
+        filename = "earcandy.desktop"
+        dest = os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config/autostart/' + filename))
+        return os.path.exists(dest)
+
+if __name__ == '__main__':
+
+    os.chdir(os.path.dirname(sys.argv[0]))
+    
+    ec = EarCandy()
+    ec.set_auto_start( True )
+    ec.run()
+    ec.save()
+    
diff --git a/earcandy/ui/glade_window.py b/ear_candy/glade_window.py
similarity index 59%
rename from earcandy/ui/glade_window.py
rename to ear_candy/glade_window.py
index 691e9b2..374a283 100644
--- a/earcandy/ui/glade_window.py
+++ b/ear_candy/glade_window.py
@@ -15,25 +15,38 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys
-import gtk
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
 import os, sys
 
-from earcandy.earcandyconfig import getdatapath
 
+def find_program_file(path):
+    """Finds a program file, for example, a png included with the program.
+    First looks for it in files/ under the parent directory of the parent directory
+    of ear_candy.py
+    Then looks for it in /usr/share/earcandy
+    Returns the path of the file"""
+    if os.path.exists(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)):
+        return os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "files",path)
+    else:
+        return os.path.join(sys.prefix, "share/earcandy", path)
+    
 class GladeWindow():
 
     def __init__(self, glade_file, window_name, parent=None):
         self.return_value = None
         self.parent = parent
-
-        ui_filename = os.path.join(getdatapath(), 'ui', 'EarCandy.ui')
-        if not os.path.exists(ui_filename):
-            ui_filename = None
-
-        self.wtree = gtk.Builder()
-        self.wtree.add_from_file(ui_filename)
-
-        self.window = self.wtree.get_object(window_name)
+        self.wtree = gtk.glade.XML(find_program_file(glade_file))
+        self.window = self.wtree.get_widget(window_name)
         self.window.connect("destroy", self.on_destroy)
         if parent: self.window.set_transient_for(parent)
         
diff --git a/ear_candy/pulseaudio/PulseAudio.py b/ear_candy/pulseaudio/PulseAudio.py
new file mode 100644
index 0000000..2f7e565
--- /dev/null
+++ b/ear_candy/pulseaudio/PulseAudio.py
@@ -0,0 +1,337 @@
+# Ear Candy - Pulseaduio sound managment tool
+# Copyright (C) 2008 Jason Taylor
+# 
+# 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, see <http://www.gnu.org/licenses/>.
+
+from lib_pulseaudio import *
+import gobject
+import sys 
+import os
+import ctypes
+
+PA_VOLUME_CONVERSION_FACTOR = 655.36
+      
+# A null method that can be given to pulse methods
+def null_cb(a=None, b=None, c=None, d=None):
+    #print "NULL CB"
+    return
+
+class PulseAudio():
+    def __init__(self, new_client_cb, remove_client_cb, new_sink_cb, remove_sink_cb, new_output_cb, remove_pa_output, volume_change_cb, volume_meter_cb):
+        
+        self.sinks = {}
+        self.monitor_sinks = []
+        self.module_stream_restore_argument = ""
+
+        self.new_client_cb = new_client_cb
+        self.new_sink_cb = new_sink_cb
+        self.remove_sink_cb = remove_sink_cb
+        self.remove_client_cb = remove_client_cb
+        self.new_output_cb = new_output_cb
+        self.volume_change_cb = volume_change_cb
+        self.remove_pa_output = remove_pa_output
+        self.volume_meter_cb = volume_meter_cb
+
+        self.pa_mainloop = pa_threaded_mainloop_new();
+        self.pa_mainloop_api = pa_threaded_mainloop_get_api(self.pa_mainloop);
+        
+        self._context = pa_context_new(self.pa_mainloop_api, "ear-candy");
+        self._context_notify_cb = pa_context_notify_cb_t(self.context_notify_cb)
+        pa_context_set_state_callback(self._context, self._context_notify_cb, None);
+        pa_context_connect(self._context, None, 0, None);
+       
+        pa_threaded_mainloop_start(self.pa_mainloop);
+
+    # pulseaudio connection status    
+    def context_notify_cb(self, context, userdata):
+        
+        try:
+            ctc = pa_context_get_state(context)
+            if ctc == PA_CONTEXT_READY:
+                print
+                print "Pulseaudio connection ready..."
+
+                self._null_cb = pa_context_success_cb_t(null_cb)
+                self._pa_context_success_cb = pa_context_success_cb_t(self.pa_context_success_cb)
+                self._pa_stream_request_cb = pa_stream_request_cb_t(self.pa_stream_request_cb)
+                self._pa_stream_notify_cb = pa_stream_notify_cb_t(self.pa_stream_request_cb)
+                self._pa_sink_info_cb = pa_sink_info_cb_t(self.pa_sink_info_cb)
+                self._pa_context_subscribe_cb = pa_context_subscribe_cb_t(self.pa_context_subscribe_cb)
+                self._pa_source_info_cb = pa_source_info_cb_t(self.pa_source_info_cb)
+                self._pa_source_output_info_cb = pa_source_output_info_cb_t(self.pa_source_output_info_cb)
+                self._pa_sink_input_info_list_cb = pa_sink_input_info_cb_t(self.pa_sink_input_info_cb)
+                self._pa_client_info_list_cb = pa_client_info_cb_t(self.pa_client_info_cb)
+                self._pa_module_info_cb = pa_module_info_cb_t(self.pa_module_info_cb)
+                self._pa_context_index_cb = pa_context_index_cb_t(self.pa_context_index_cb) 
+
+                o = pa_context_get_module_info_list(self._context, self._pa_module_info_cb, True)
+                pa_operation_unref(o)
+
+                o = pa_context_get_source_info_list(self._context, self._pa_source_info_cb, True)
+                pa_operation_unref(o)
+
+                o = pa_context_get_client_info_list(self._context, self._pa_client_info_list_cb, None)
+                pa_operation_unref(o)
+                
+                o = pa_context_get_source_output_info_list(self._context, self._pa_source_output_info_cb, None)
+                pa_operation_unref(o)
+
+                o = pa_context_get_sink_info_list(self._context, self._pa_sink_info_cb, None)
+                pa_operation_unref(o)
+
+                o = pa_context_get_sink_input_info_list(self._context, self._pa_sink_input_info_list_cb, True)
+                pa_operation_unref(o)
+
+                pa_context_set_subscribe_callback(self._context, self._pa_context_subscribe_cb, None);
+                o = pa_context_subscribe(self._context, (pa_subscription_mask_t)
+                                               (PA_SUBSCRIPTION_MASK_SINK|
+                                                PA_SUBSCRIPTION_MASK_SOURCE|
+                                                PA_SUBSCRIPTION_MASK_SINK_INPUT|
+                                                PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT|
+                                                PA_SUBSCRIPTION_MASK_CLIENT|
+                                                PA_SUBSCRIPTION_MASK_SERVER), self._null_cb, None)  
+
+                pa_operation_unref(o)             
+
+            if ctc == PA_CONTEXT_FAILED :
+                self.__print("Connection failed")
+                pa_threaded_mainloop_signal(self.pa_mainloop, 0)
+                sys.exit(1)
+                
+            if ctc == PA_CONTEXT_TERMINATED:
+                self.__print("Connection terminated")
+                pa_threaded_mainloop_signal(self.pa_mainloop, 0)
+                sys.exit(1)
+
+        except Exception, text:
+            self.__print("ERROR context_notify_cb %s" % text)
+
+
+    def pa_context_index_cb(self, context, index, user_data):
+        # Do nothing....
+        return
+
+    def load_module_stream_restore(self):
+        print "Reloading module-stream-restore " 
+        pa_context_load_module(self._context, "module-stream-restore", self.module_stream_restore_argument, self._pa_context_index_cb, None)
+
+ 
+    def pa_module_info_cb(self, context, pa_module_info, eol, user_data):
+        if user_data and pa_module_info:
+                      
+            """if pa_module_info.contents.name == "module-stream-restore":
+                print
+                print "Found 'module-stream-restore'... unloading.."  
+                self.module_stream_restore_argument = pa_module_info.contents.argument
+                pa_context_unload_module(context, pa_module_info.contents.index, self._null_cb, None)"""
+        return
+
+    def pa_source_info_cb(self, context, struct, eol, user_data):
+        if eol: return
+
+        if struct:
+            
+            if  struct.contents.monitor_of_sink_name:
+                print 
+                print "== new output device found =="
+                print struct.contents.name
+                print struct.contents.description
+                """print struct.contents.monitor_of_sink_name
+                print struct.contents.driver
+                print struct.contents.sample_spec
+                print struct.contents.channel_map
+                print struct.contents.owner_module
+                print struct.contents.volume
+                print struct.contents.mute
+                print struct.contents.monitor_of_sink
+                print struct.contents.monitor_of_sink_name
+                print struct.contents.flags
+                print struct.contents.index"""
+                
+                gobject.idle_add(self.new_output_cb, struct.contents.index, struct.contents.monitor_of_sink_name, struct.contents.description, user_data)
+                volume = int(pa_cvolume_avg(struct.contents.volume) / PA_VOLUME_CONVERSION_FACTOR)
+                gobject.idle_add(self.volume_change_cb, volume)
+
+    def pa_stream_request_cb(self, stream, length, index):
+
+        # This isnt quite right... maybe not a float.. ?
+        
+        #null_ptr = ctypes.c_void_p()
+        data = POINTER(c_float)()
+        pa_stream_peek(stream, data, ctypes.c_ulong(length)) 
+        v = data[length / 4 -1] * 100
+        if (v < 0):
+            v = 0
+        if (v > 100):
+            v = 100
+        pa_stream_drop(stream)
+
+        self.volume_meter_cb(index, v)
+    
+    def pa_create_monitor_stream_for_sink_input(self, index, monitor_index, name):
+        
+        if not index in self.monitor_sinks:
+            self.monitor_sinks.append(index)
+            # Create new stream
+            ss = pa_sample_spec()
+            ss.channels = 1
+            ss.format = 5
+            ss.rate = 25
+            pa_stream = pa_stream_new(self._context, "Peak detect - " + name, ss, None)
+            
+            pa_stream_set_monitor_stream(pa_stream, index);
+            pa_stream_set_read_callback(pa_stream, self._pa_stream_request_cb, index);
+            pa_stream_set_suspended_callback(pa_stream, self._pa_stream_notify_cb, None);
+
+            attr = pa_buffer_attr()
+            attr.fragsize = 4
+            attr.maxlength = 10
+            attr.tlength = 0
+            attr.prebuf = 0
+            attr.minreq = 0
+
+            pa_stream_connect_record(pa_stream, str(monitor_index), attr, 10752) 
+                    
+    def pa_context_success_cb(self, context, c_int,  user_data):
+        return
+
+    def pa_source_output_info_cb(self, context, struct, c_int, user_data):
+        return
+        
+    def pa_context_subscribe_cb(self, context, event_type, index, user_data):
+
+        try:
+            et = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK
+
+            if et == PA_SUBSCRIPTION_EVENT_CLIENT:
+            
+                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
+                    gobject.idle_add(self.remove_client_cb, int(index))
+                else:
+                    o = pa_context_get_client_info(self._context, index, self._pa_client_info_list_cb, None)
+                    pa_operation_unref(o)
+
+            if et == PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
+                     gobject.idle_add(self.remove_sink_cb, int(index))
+                     self.monitor_sinks.remove(index)
+                else:
+                    o = pa_context_get_sink_input_info(self._context, int(index), self._pa_sink_input_info_list_cb, True)
+                    pa_operation_unref(o)
+                    
+            if et == PA_SUBSCRIPTION_EVENT_SOURCE:
+                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
+                    # Remove output source
+                    self.remove_pa_output( int(index) )
+                else:
+                    o = pa_context_get_source_info_by_index(self._context, int(index), self._pa_source_info_cb, False)
+                    pa_operation_unref(o)
+
+        except Exception, text:
+            self.__print("pa :: ERROR pa_context_subscribe_cb %s" % text)
+    
+    def pa_client_info_cb(self, context, struct, c_int, user_data):
+        try:
+            if struct :
+
+                self.__print("CLIENT")
+                self.__print( pa_proplist_to_string(struct.contents.proplist))
+
+                # Get the client pid so we can match to the x11 window application pid
+                pid = pa_proplist_gets(struct.contents.proplist, "application.process.id")
+                #binary = pa_proplist_gets(struct.contents.proplist, "application.process.binary")
+
+                gobject.idle_add(self.new_client_cb, struct.contents.index, struct.contents.name, pid, pa_proplist_to_string(struct.contents.proplist))
+                
+        except Exception, text:
+            self.__print( "pa :: ERROR pa_client_info_cb %s" % text)    
+
+    def pa_sink_input_info_cb(self, context, struct, index, user_data):
+        if struct and user_data:
+            
+            # TODO: Only do this if app dosnt release pulse streams correctly
+            if float(struct.contents.sink) in self.sinks:
+                self.pa_create_monitor_stream_for_sink_input(int(struct.contents.index), self.sinks[float(struct.contents.sink)], struct.contents.name)
+
+            # here we go...
+            self.__print( "SINK INPUT INFO")
+            self.__print( pa_proplist_to_string(struct.contents.proplist))
+            
+            # Get volume level
+            volume = []
+            volume.append( int(pa_cvolume_avg(struct.contents.volume) / PA_VOLUME_CONVERSION_FACTOR) )
+            for i in range(0, struct.contents.volume.channels):
+                volume.append(int(struct.contents.volume.values[i]) / PA_VOLUME_CONVERSION_FACTOR)
+            
+            gobject.idle_add( self.new_sink_cb, int(struct.contents.index), struct.contents.name, int(struct.contents.client), volume, struct.contents.sink, struct.contents.channel_map.channels)
+
+    # Move a playing stream to a differnt output sink
+    def move_sink(self, sink_index, output_name):
+        self.__print("move_sink")
+        pa_context_move_sink_input_by_name(self._context, sink_index, output_name, self._pa_context_success_cb, None)
+
+    def set_sink_volume_by_name(self, sink_name, volume):
+        self.__print("set_sink_volume_by_name")
+        if volume < 0: volume = 0
+        vol = pa_cvolume()
+        vol.channels = 2 #len(cvolume) - 1
+        v = pa_volume_t * 32
+        vol.values = v (int(volume * PA_VOLUME_CONVERSION_FACTOR), int(volume * PA_VOLUME_CONVERSION_FACTOR))
+
+        o = pa_context_set_sink_volume_by_name(self._context, sink_name, vol, self._null_cb, None)
+        pa_operation_unref(o)
+
+    def set_sink_volume(self, index, cvolume, number_of_channels):
+        self.__print("set_sink_volume")
+        vol = pa_cvolume()
+        vol.channels = number_of_channels #len(cvolume) - 1
+        v = pa_volume_t * 32
+
+        vol.values = v()
+        for i in range(0, number_of_channels):
+            if len(cvolume) > i:
+                vol.values[i] = int(cvolume[i+1] * PA_VOLUME_CONVERSION_FACTOR)
+            else:
+                vol.values[i] = int(cvolume[1] * PA_VOLUME_CONVERSION_FACTOR)
+
+        # Note setting volume causes a trigger of sink_input_info which will gives us back new volume!
+        o = pa_context_set_sink_input_volume(self._context, index, vol, self._null_cb, None) # NOTE: dont pass in any thing here causes a seg fault
+        pa_operation_unref(o)
+
+    def get_sink_info_by_name(self, sink_name):
+        self.__print("get_sink_info_by_name")
+        o = pa_context_get_sink_info_by_name(self._context, sink_name, self._pa_sink_info_cb, False)
+        pa_operation_unref(o)
+
+    def pa_sink_info_cb(self, context, struct, index, data):
+        if struct:
+            # Get volume level
+
+            # Update sink to monitor links
+            self.sinks[ float(struct.contents.index) ] = struct.contents.monitor_source
+            self.__print("pa_sink_info_cb")
+            gobject.idle_add(self.volume_change_cb, int(pa_cvolume_avg(struct.contents.volume) / PA_VOLUME_CONVERSION_FACTOR))
+
+    def pa_ext_stream_restore_delete( self, stream ):
+        pa_ext_stream_restore_delete(self._context, stream, self._pa_context_success_cb, None)
+
+
+
+    def __print(self, text):
+        #print text
+        return
+
+if __name__ == '__main__':
+    c = PulseAudio()
+    
diff --git a/earcandy/__init__.py b/ear_candy/pulseaudio/__init__.py
similarity index 100%
rename from earcandy/__init__.py
rename to ear_candy/pulseaudio/__init__.py
diff --git a/earcandy/pulseaudio/lib.py b/ear_candy/pulseaudio/lib.py
similarity index 95%
rename from earcandy/pulseaudio/lib.py
rename to ear_candy/pulseaudio/lib.py
index 35b020d..37eb3f8 100644
--- a/earcandy/pulseaudio/lib.py
+++ b/ear_candy/pulseaudio/lib.py
@@ -32,15 +32,13 @@
 import os
 import re
 import sys
-import logging
+
 import ctypes
 import ctypes.util
 
 _debug_lib = False
 _debug_trace = False
 
-logging.basicConfig(level=logging.DEBUG)
-
 class LibraryLoader(object):
     def load_library(self, *names, **kwargs):
         '''Find and load a library.  
@@ -66,7 +64,10 @@ class LibraryLoader(object):
         for name in platform_names:
             try:
                 lib = ctypes.cdll.LoadLibrary(name)
-                logging.debug("lib :: Loaded library : %s" % name)
+                #if _debug_lib:
+                print "Loaded library :", name
+                #if _debug_trace:
+                #    lib = _TraceLibrary(lib)
                 return lib
             except OSError:
                 path = self.find_library(name)
diff --git a/earcandy/pulseaudio/lib_pulseaudio.py b/ear_candy/pulseaudio/lib_pulseaudio.py
similarity index 99%
rename from earcandy/pulseaudio/lib_pulseaudio.py
rename to ear_candy/pulseaudio/lib_pulseaudio.py
index bdf9e9d..6824457 100644
--- a/earcandy/pulseaudio/lib_pulseaudio.py
+++ b/ear_candy/pulseaudio/lib_pulseaudio.py
@@ -1928,7 +1928,7 @@ pa_proplist_to_string.argtypes = [
 
 pa_ext_stream_restore_delete = _lib.pa_ext_stream_restore_delete
 pa_ext_stream_restore_delete.restype = pa_operation
-pa_ext_stream_restore_delete.argtypes = [POINTER(pa_context), POINTER(c_char_p), pa_context_success_cb_t, POINTER(None)]
+pa_ext_stream_restore_delete.argtypes = [POINTER(pa_context), c_char_p, pa_context_success_cb_t, POINTER(None)]
 
 
 
diff --git a/ear_candy/window/WindowWatcher.py b/ear_candy/window/WindowWatcher.py
new file mode 100644
index 0000000..51c1a78
--- /dev/null
+++ b/ear_candy/window/WindowWatcher.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+# Ear Candy - Pulseaduio sound managment tool
+# Copyright (C) 2008 Jason Taylor
+# 
+# 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, see <http://www.gnu.org/licenses/>.
+
+# based on original code by by RYX (aka Rico Pfaus)
+# http://thegraveyard.org/files/kapager-0.0.3.py
+
+import wnck
+import gobject
+import os
+import gtk
+from DesktopFiles import DesktopFiles
+
+class Application():
+    def __init__(self, pid, command, name, desktop_files, icon):
+        self.command = os.path.basename(command.lower().strip())
+        self.name = name.lower().strip()
+        self.category = ""
+        self.icon = icon
+        self.icon_name = ""
+        self.description = name
+
+        # current application window info
+        self.pid = pid
+        self.window_name = ""
+        self.x = 0
+        self.y = 0
+        self.fullscreen = False
+        
+        self.__match_desktop(desktop_files)
+        return
+
+    def __match_desktop(self,  desktop_files):
+
+        #print "checking desktop files for match....", self.name
+        # Try looking up the application list
+        for a in desktop_files:
+            ex = a.get_exec_array()[0].lower()
+
+            # Check for pulse audio settings first...
+            if a.get("X-PulseAudio-Properties"):
+                self.category = a.get("X-PulseAudio-Properties")
+                break
+
+            if a.get("X-GNOME-Bugzilla-Product") == self.name or ex == self.name or ex == self.command or a.get("Name").lower() == self.name or a.get("Name").lower() == self.command or ex + ".real" == self.command :
+                self.icon_name = a.get("Icon")
+                self.description = a.get("Name")
+                self.category = self.__desktop_categories_to_category( a.get("Categories") )
+                #print "category : " + (self.category or "<unknown>")
+                break
+
+        if self.command == "skype.real":
+            self.category = "phone"
+            #print "category : " + self.category
+            
+
+    def __desktop_categories_to_category(self, categories):
+        if categories:
+            for category in categories:
+                if "Telephony" in categories or "InstantMessaging" in categories:
+                    return "phone"
+                if "Music" in categories:
+                    return "music"
+                if "Video" in categories:
+                    return "video"
+                if "AudioVideo" in categories:
+                    return "music"             
+    
+        return ""
+
+class WindowWatcher():
+    
+    def __init__(self, callback = None, existing=False):
+        self.screen = wnck.screen_get_default()
+        self.screen.connect("active_window_changed", self.active_window_changed)
+        self.screen.connect("window_opened", self.window_opened)
+        self.callback = callback
+        self.current_window = None
+        self.applications = {}
+        self.desktop_files = DesktopFiles().read_all()   
+
+        for win in self.screen.get_windows():
+            self.update("exists", win)
+
+    def send_window_key_press_from_pid(self, pid, key):
+        for win in self.screen.get_windows():
+            app = win.get_application()
+            app_name = app.get_name()
+            if pid == win.get_pid():       
+                
+                break;
+
+
+    def get_command(self, pid):
+        command = str(pid)
+        try:
+            # Try and get command from PID
+            f = open("/proc/%s/cmdline" % pid, "r")
+            command = f.readline()[:-1]
+            f.close()
+        except:
+            pass
+        return command
+
+    def window_opened(self, screen, win):
+        if win and win.get_window_type() != wnck.WINDOW_DOCK: # ignore docks
+            #print            
+            #print "window opened"
+            app = win.get_application ()
+            app_name = app.get_name()
+            pid = win.get_pid()
+            command = self.get_command(pid)
+            category = ""
+
+            if not self.applications.has_key(command):
+                a = Application(pid, command, app_name, self.desktop_files, win.get_icon ())
+                self.applications[command] = a
+            
+            self.update("open", win)
+            win.connect("geometry-changed", self.geometry_changed)
+
+    def active_window_changed(self, screen, old_window):
+        win = screen.get_active_window ()
+        self.update("active", win)        
+
+    def update(self, state, win):
+        if win and win.get_window_type() != wnck.WINDOW_DOCK: # ignore docks
+                
+            #try:
+                app = win.get_application ()
+                app_name = app.get_name()
+                pid = win.get_pid()
+
+                command = self.get_command(pid)
+
+                application = None
+                application = self.applications[command]
+                application.pid = pid
+
+                geom = win.get_geometry()
+                x = float(geom[1])
+                y = float(geom[0])
+                w = float(geom[2])
+                h = float(geom[3])
+
+                if win.get_name():
+                    application.window_name =  win.get_name()
+
+                application.x = x+h/2
+                application.y = y+w/2
+                application.fullscreen = win.is_fullscreen () or win.is_maximized ()
+                application.icon = win.get_icon ()
+
+                
+                if self.callback:
+                    gobject.idle_add(self.callback, application, state)
+            #except:
+            #    print "error reading window", win
+
+    def geometry_changed(self, win):
+        self.update("geo", win)
+
+
+if __name__ == '__main__':
+    ww = WindowWatcher()
+
diff --git a/earcandy/plugins/banshee/__init__.py b/ear_candy/window/__init__.py
similarity index 100%
rename from earcandy/plugins/banshee/__init__.py
rename to ear_candy/window/__init__.py
diff --git a/earcandy.desktop.in b/earcandy.desktop.in
deleted file mode 100644
index 1aa0283..0000000
--- a/earcandy.desktop.in
+++ /dev/null
@@ -1,8 +0,0 @@
-[Desktop Entry]
-Name=Earcandy
-Comment=Earcandy application
-Categories=GNOME;AudioVideo;
-Exec=earcandy
-Icon=/usr/share/earcandy/media/icon.png
-Terminal=false
-Type=Application
diff --git a/earcandy/AboutEarcandyDialog.py b/earcandy/AboutEarcandyDialog.py
deleted file mode 100644
index 0607548..0000000
--- a/earcandy/AboutEarcandyDialog.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# -*- coding: utf-8 -*-
-### BEGIN LICENSE
-# This file is in the public domain
-### END LICENSE
-
-import sys
-import os
-import gtk
-
-from earcandy.earcandyconfig import getdatapath
-
-class AboutEarcandyDialog(gtk.AboutDialog):
-    __gtype_name__ = "AboutEarcandyDialog"
-
-    def __init__(self):
-        """__init__ - This function is typically not called directly.
-        Creation of a AboutEarcandyDialog requires redeading the associated ui
-        file and parsing the ui definition extrenally, 
-        and then calling AboutEarcandyDialog.finish_initializing().
-    
-        Use the convenience function NewAboutEarcandyDialog to create 
-        NewAboutEarcandyDialog objects.
-    
-        """
-        pass
-
-    def finish_initializing(self, builder):
-        """finish_initalizing should be called after parsing the ui definition
-        and creating a AboutEarcandyDialog object with it in order to finish
-        initializing the start of the new AboutEarcandyDialog instance.
-    
-        """
-        #get a reference to the builder and set up the signals
-        self.builder = builder
-        self.builder.connect_signals(self)
-
-        #code for other initialization actions should be added here
-
-def NewAboutEarcandyDialog():
-    """NewAboutEarcandyDialog - returns a fully instantiated
-    AboutEarcandyDialog object. Use this function rather than
-    creating a AboutEarcandyDialog instance directly.
-    
-    """
-
-    #look for the ui file that describes the ui
-    ui_filename = os.path.join(getdatapath(), 'ui', 'AboutEarcandyDialog.ui')
-    if not os.path.exists(ui_filename):
-        ui_filename = None
-
-    builder = gtk.Builder()
-    builder.add_from_file(ui_filename)    
-    dialog = builder.get_object("about_earcandy_dialog")
-    dialog.finish_initializing(builder)
-    return dialog
-
-if __name__ == "__main__":
-    dialog = NewAboutEarcandyDialog()
-    dialog.show()
-    gtk.main()
-
diff --git a/earcandy/Application.py b/earcandy/Application.py
deleted file mode 100644
index c1990f8..0000000
--- a/earcandy/Application.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import gtk
-from util.DesktopFiles import DesktopFiles
-
-class Application():
-    def __init__(self, pid, command, name, icon):
-        self.command = os.path.basename(command.lower().strip())
-        self.name = name.lower().strip()
-        self.category = ""
-        self.icon = icon
-        self.icon_name = ""
-        self.description = name
-
-        # current application window info
-        self.pid = pid
-        self.window_name = ""
-        self.x = 0
-        self.y = 0
-        self.fullscreen = False
-
-        self.clients = {}
-        return
-
-    def __match_desktop(self,  desktop_files):
-
-        #print "checking desktop files for match....", self.name
-        # Try looking up the application list
-        for a in desktop_files:
-            ex = a.get_exec_array()[0].lower()
-
-            # Check for pulse audio settings first...
-            if a.get("X-PulseAudio-Properties"):
-                self.category = a.get("X-PulseAudio-Properties")
-                break
-
-            if a.get("X-GNOME-Bugzilla-Product") == self.name or ex == self.name or ex == self.command or a.get("Name").lower() == self.name or a.get("Name").lower() == self.command or ex + ".real" == self.command :
-                self.icon_name = a.get("Icon")
-                self.description = a.get("Name")
-                self.category = self.__desktop_categories_to_category( a.get("Categories") )
-                #print "category : " + (self.category or "<unknown>")
-                break
-
-        if self.command == "skype.real":
-            self.category = "phone"
-            #print "category : " + self.category
-            
-
-    def __desktop_categories_to_category(self, categories):
-        if categories:
-            for category in categories:
-                if "Telephony" in categories or "InstantMessaging" in categories:
-                    return "phone"
-                if "Music" in categories:
-                    return "music"
-                if "Video" in categories:
-                    return "video"
-                if "AudioVideo" in categories:
-                    return "music"             
-    
-        return ""
diff --git a/earcandy/EarCandy.py b/earcandy/EarCandy.py
deleted file mode 100644
index 58c9144..0000000
--- a/earcandy/EarCandy.py
+++ /dev/null
@@ -1,433 +0,0 @@
-
-import os
-import copy
-import sys
-import time
-import logging
-import shutil
-from xml.dom.minidom import *
-
-import gconf
-import pynotify
-import gtk
-import gobject
-import pynotify
-
-from util.DesktopFiles import DesktopFiles
-from util.Threads import threaded
-
-from Client import Client
-from Sink import Sink
-from windows.Watcher import Watcher
-from PulseAudio import PulseAudio
-
-from ui.TrayIcon import EarCandyStatusIcon
-from ui.EarCandyPrefs import EarCandayPrefs
-
-from EarCandyDBus import EarCandyDBusClient
-
-from earcandyconfig import getdatapath
-
-log = logging.getLogger('EarCandy')
-log.setLevel(logging.DEBUG)
-
-
-class EarCandy():
-
-    def __init__(self):
-
-        self.version = 0.7
-        self.active = True
-        
-        self.display = {
-                        "": "[ unknown ]", 
-                        "phone" : "Phone (VoIP)", 
-                        "video" : "Video Player", 
-                        "music" : "Music Player", 
-                        "event" : "Notification", 
-                        "game" : "Game" }
-
-        self.ignore = ["EsounD client (UNIX socket client)", 
-                        "ear-candy", 
-                        "Native client (UNIX socket client)", 
-                        "PulseAudio Volume Control"]
-
-        self.config_file = os.path.expanduser("~/.config/Ear Candy/settings.xml")     
-        self.default_config_file = os.path.join(getdatapath(), 'defaults', 'settings.xml')
-
-        self.pa = PulseAudio(self)
-        self.window_watcher = Watcher()
-        self.window_watcher.callback = self.on_active_window_change
-
-        self.prefer_sink = None
-
-        self.pref = None
-
-        pynotify.init('earcandy')
-
-    def notify(self, name, text):
-        return        
-        #n = pynotify.Notification(name, text, None)
-        #n.show()
-
-    def init(self):
-        self.is_mute = False
-        self.mute_phone = False
-
-        self.fade_timer_speed = 0.01 
-        self.mute_level = 20
-        self.follow_new_outputs = True
-
-        self.priority_stack = { "" : [], "phone" : [], "video" : [], "music" : [] , "game" : [] }   
-
-        self.apply_volume_thread_running = False 
-        self.select_client_thread_running = False
-
-    def run(self):
-
-        ecb = EarCandyDBusClient(self)
-        if ecb.is_running():
-            print "Ear candy already running..."
-            ecb.show_window()
-            sys.exit(0)
-
-        ecb.start_service()
-
-        self.init() 
-        self.load()
-        self.pa.connect()
-
-        self.apply_volume_thread()
-        self.select_client_thread()
-
-        self.status_icon = EarCandyStatusIcon(self)
-        self.start()
-
-        self.window_watcher.check_all()
-        
-        
-        #self.open_preferances()
-
-    def exit(self):
-        self.stop()
-        self.pa.disconnect()
-        gtk.main_quit()
-
-
-    def stop(self):
-        self.active = False
-        while self.apply_volume_thread_running or self.select_client_thread_running:
-            time.sleep(0.1)
-
-    def start(self):
-        self.active = True
-        while not self.apply_volume_thread_running or not self.select_client_thread_running:
-            time.sleep(0.1)
-
-    def reset_all(self):
-        # tricky we want to delete all client settings and reload our default xml file
-        self.stop()
-        self.pa.disconnect()
-        self.init()
-        self.load(False)
-        self.pa.connect()
-        self.start()
-        return
-
-    def reset(self):
-        self.stop()
-        self.pa.disconnect()
-        self.init()
-        self.load()
-        self.pa.connect()
-        self.start()
-        return
-
-    def save(self):
-        path = os.path.dirname(self.config_file)
-        if not os.path.exists( path ):
-            os.makedirs(path)
-
-        # New document
-        doc = Document()
-        ec = doc.createElement("earcandy")
-        doc.appendChild(ec)
-	
-        rules = doc.createElement("rules")
-        ec.appendChild(rules)
-        skip = copy.copy(self.ignore)
-        for client in self.pa.clients.values():
-            if not client.name in skip and client.role:
-                # Creates user element
-                el = doc.createElement("rule")
-                rules.appendChild(el)
-                client.to_xml(el)
-                skip.append(client.name)
-        
-        doc.documentElement.setAttribute("fade_timer_speed", str(self.fade_timer_speed))
-        doc.documentElement.setAttribute("mute_level", str(self.mute_level))
-        doc.documentElement.setAttribute("tray_visible", str(self.status_icon.get_visible()))
-        doc.documentElement.setAttribute("prefer_sink", str(self.prefer_sink))
-        doc.documentElement.setAttribute("follow_new_outputs", str(self.follow_new_outputs))
-        doc.documentElement.setAttribute("version", str(self.version))
-        doc.documentElement.setAttribute("mute_phone", str(self.mute_phone))
-
-        # Record outputs
-        outputs = doc.createElement("outputs")
-        for sink in self.pa.sinks.values():
-            # Creates user element
-            el = doc.createElement("output")
-            el.setAttribute("name", sink.name)
-            el.setAttribute("priority", str(sink.priority))
-            outputs.appendChild(el)
-        ec.appendChild(outputs)
-
-        # Plugin status
-        """
-        plugins = doc.createElement("plugins")
-        for plugin in self.plugin_manager.plugins:
-            # Creates user element
-            el = doc.createElement("plugin")
-            el.setAttribute("name", plugin.get_plugin_name())
-            el.setAttribute("enabled", str(plugin.enabled))
-            plugins.appendChild(el)
-        ec.appendChild(plugins)"""
-
-        fp = open(self.config_file,"w")
-        doc.writexml(fp, "    ", "", "\n", "UTF-8")
-        fp.close()
-
-    def load(self, user_settings=True):
-
-        settings_version = 0
-        xml = None
-        doc = None
-
-        # Load the defaults
-        f = open(self.default_config_file, "r")
-        xml = f.read()
-        f.close()
-        default_doc = parseString(xml)
-        default_version = float(default_doc.documentElement.getAttribute("version"))
-
-        # Check for user settings
-        if user_settings and os.path.exists( self.config_file ):
-            # Load XML
-            try:
-                f = open(self.config_file, "r")
-                xml = f.read()
-                f.close()
-                doc = parseString(xml)
-                if doc.documentElement.hasAttribute("version"):
-                    settings_version = float(doc.documentElement.getAttribute("version"))
-            except:
-                pass
-
-        # Load defaults ?
-        if not doc or default_version > settings_version:
-            doc = default_doc
-            
-        # Load client rules
-        for el in doc.getElementsByTagName("rule"):
-            client = Client(self, "")
-            client.from_xml(el)
-            if client.role:
-                log.info("load rule : %s " % client.description)
-            self.pa.clients[client.name] = client
-            #self.plugin_manager.check_client( client )
-
-
-        # Load sink rules
-        for el in doc.getElementsByTagName("output"):
-            sink = Sink(el.getAttribute("name"), int(el.getAttribute("priority")) )
-            self.pa.sinks[sink.name] = sink
-            #self.plugin_manager.check_client( client )
-
-
-        self.fade_timer_speed = float(doc.documentElement.getAttribute("fade_timer_speed"))
-        #self.mute_level = float(doc.documentElement.getAttribute("mute_level"))
-        #if doc.documentElement.hasAttribute("tray_visible"):
-        #    self.status_icon.set_visible( doc.documentElement.getAttribute("tray_visible") == "True" )
-        #if doc.documentElement.hasAttribute("prefer_sink"):
-        #    self.prefer_sink = doc.documentElement.getAttribute("prefer_sink")
-        #if doc.documentElement.hasAttribute("follow_new_outputs"):
-        #    self.follow_new_outputs = doc.documentElement.getAttribute("follow_new_outputs") == "True"
-        #if doc.documentElement.hasAttribute("mute_phone"):
-        #    self.mute_phone = doc.documentElement.getAttribute("mute_phone") == "True"
-
-
-    @threaded
-    def apply_volume_thread(self):
-        while True:
-            #logging.debug(": apply_volume_thread " )
-            if self.active:
-                self.apply_volume_thread_running = True
-                gobject.idle_add(self.__adjust_volumes)      
-            else:
-                self.apply_volume_thread_running = False
-            time.sleep(self.fade_timer_speed)
-
-    @threaded
-    def select_client_thread(self):
-        while True:
-            if self.active:
-                self.select_client_thread_running = True
-                gobject.idle_add(self.set_active_clients)  
-            else:
-                self.select_client_thread_running = False
-            time.sleep(0.5)
-
-    def __adjust_volumes(self):
-        # Always update based on active sinks
-        for sink in self.pa.sink_inputs.values():
-            if sink.set_volume():
-                # set pa volume
-                self.pa.pa_context_set_sink_input_volume(sink.index, sink.volume)  
-
-    def __set_window_stack(self, active_client):
-        for client in self.pa.clients.values():
-
-            # Select the primary client and order previous clients
-            for key in self.priority_stack.keys():
-                if client.role == key:
-                    # Add client to role
-                    if not client in self.priority_stack[key]:
-                        if active_client == client:
-                            self.priority_stack[key].insert(0, client)
-                        else:
-                            self.priority_stack[key].append(client)
-
-                    # reshuffle if active
-                    elif active_client == client and not self.priority_stack[key][0] == client:
-                        self.priority_stack[key].remove(client)
-                        self.priority_stack[key].insert(0, client)
-
-                # If role has changed remove old entry
-                elif client in self.priority_stack[key]:
-                    self.priority_stack[key].remove(client)
-
-    def print_stacks(self):
-        for key in self.priority_stack.keys():
-            if key:
-                text =""
-                for client in self.priority_stack[key]:
-                    text += client.description
-                    text += " (" 
-                    if client.is_active():
-                        text += "*"
-                    else:
-                        text += str(len(client.sinks.values())) 
-                    text += "), "
-                if text: log.debug("stack " + key + " " + text)
-
-    def set_active_clients(self):
-
-        # Based on per sink stacks
-        for sink in self.pa.sinks.values():
-
-            # find the top ranking sink_input for this sink
-            highest_sink_input = None
-            highest_stack_media_role_index = -1   
-            highest_stack_media_role_window_index = -1
-
-            for sink_input in self.pa.sink_inputs.values():
-                status = False
-
-                if sink_input.is_active():
-
-                    # check against media role   
-                    if sink_input.role and sink_input.role in self.priority_stack.keys():
-                    
-                        index = self.priority_stack.keys().index(sink_input.role)
-                        if index <= highest_stack_media_role_index or highest_stack_media_role_index == -1:
-
-                            # check window stack for client
-                            if sink_input.client in self.priority_stack[sink_input.role]:
-                                window_index = self.priority_stack[sink_input.role].index(sink_input.client)
-                                if window_index <= highest_stack_media_role_window_index or highest_stack_media_role_window_index == -1:
-                                    
-                                    # Set previous highest to inactive
-                                    if highest_sink_input:
-                                        highest_sink_input.set_status(False)
-
-                                    # Set new sink to active
-                                    highest_sink_input = sink_input
-                                    highest_stack_media_role_index = index
-                                    highest_stack_media_role_window_index = window_index
-                                    status = True
-                                    
-                    else:
-                        # unknown media role so leave it always on
-                        status = True
-
-                sink_input.set_status(status)
-        #self.print_stacks()
-
-    def on_active_window_change(self, application, state):  #, pid, window_name, x, y, icon, fullscreen
-        if application:
-            if state in ("active","open"):
-                for client in self.pa.clients.values():
-                    if self.match_client_to_application(client, application, state): 
-                        log.info(": window to client match %s => %s" % (application.name, client.description) )
-                        self.__set_window_stack(client)
-                        break
-                
-
-    def match_client_to_application(self, client, application, index=0):
-        if client.test_focus_window(application.pid, application.window_name, application.command, application.name): 
-            client.fullscreen = application.fullscreen  
-            if not client.icon : client.icon = application.icon
-            if not client.icon_name : client.icon_name = application.icon_name
-            if not client.description :client.description = application.description
-            if not client.role: client.role = application.role
-            client.application = application
-
-            return True
-        return False
-
-    def set_auto_start(self, flag):
-        filename = "earcandy.desktop"
-        path = os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config/autostart'))
-        dest = os.path.join(path, filename)
-        src = "/usr/share/applications/earcandy.desktop"
-
-        if flag:
-            # insure the autostart path exists
-            if not os.path.exists(path):
-                os.makedirs(path)
-
-            if not os.path.exists( dest ):
-                shutil.copyfile(src, dest)
-        else:
-            if os.path.exists( dest ):
-                os.remove( dest )
-
-    def is_auto_start(self):
-        filename = "earcandy.desktop"
-        dest = os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config/autostart/' + filename))
-        return os.path.exists(dest)
-
-    def open_preferances(self):
-        self.print_stacks()
-        if not self.pref:
-            self.pref = EarCandayPrefs(self)
-        self.pref.run()
-
-    def close_preferances(self):
-        if self.pref:
-            self.pref = None
-
-    def get_current_sink_volume(self):
-        self.pa.get_sink_info_by_name(self.pa.prefer_sink_index)
-
-
-if __name__ == '__main__':
-    logging.basicConfig(level=logging.INFO)
-    import gtk
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-
-    ec = EarCandy()
-    ec.run()
-
-    gtk.main()
diff --git a/earcandy/PulseAudio.py b/earcandy/PulseAudio.py
deleted file mode 100644
index 44d1b24..0000000
--- a/earcandy/PulseAudio.py
+++ /dev/null
@@ -1,254 +0,0 @@
-# Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2008 Jason Taylor
-# 
-# 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, see <http://www.gnu.org/licenses/>.
-import logging
-import ctypes
-from pulseaudio.PulseAudioConnection import PulseAudioConnection
-from Client import Client
-from SinkInput import SinkInput
-from Sink import Sink
-
-log = logging.getLogger('EarCandyPulseAudio')
-log.setLevel(logging.INFO)
-
-class PulseAudio(PulseAudioConnection):
-    def __init__(self, Core):
-
-        self.core = Core 
-        self.prefer_sink_index = 0       
-        self.prefer_source_index = 0 
-
-        self.sink = {}          # sinks by name
-        self.sinks_by_id = {}   # sinks by id
-        self.clients = {}       # clients by name
-        self.clients_by_id = {} # clients by id
-        self.sink_inputs = {}   # sink inputs by id
-        self.source_outputs = {}   # source outputs by id
-
-        PulseAudioConnection.__init__(self, "EarCandy")
-
-    # CONNECTION
-    def pa_status_ready(self):
-        # list sinks again now that sink_inputs have been loaded
-        # this will trigger auto usb selection
-        self.pa_context_get_sink_info_list()
-        self.pa_context_get_source_info_list()
-        self.pa_context_get_source_output_info_list()
-
-
-    ### DEAL WITH SINKS #################################
-    def pa_sink_info_cb(self, sink, user_data):
-        s = None
-        if not sink.name in self.sinks.keys():
-            s = Sink(sink.name, 0, sink.index)
-            log.info("new sink : %s %s" % (sink.description, sink.index))
-            self.sinks[sink.name] = s
-                      
-        else:
-            s = self.sinks[sink.name]
-
-        self.sinks_by_id[sink.index] = s  
-        s.description = sink.description
-        s.monitor_source = sink.monitor_source
-        s.monitor_source_name = sink.monitor_source_name
-        s.index = sink.index
-        s.volume = sink.volume
-
-        if s.name.lower().count("usb") > 0 or s.name.lower().count("bluetooth") > 0:
-            self.core.notify("New sound device", "Moving sound to new device")
-            log.info("new device detected moving sink inputs : %s " % sink.description)
-
-            self.prefer_sink_index = sink.index
-            self.pa_context_set_default_sink(sink.name)
-            self.move_all_sinks_inputs(sink.index)
-
-        if self.core.pref:
-            self.core.pref.update_output(s, s.priority)
-
-    def pa_sink_remove_cb(self, index):
-        sink = self.sinks_by_id[index]
-        sink.index = 0
-        if self.core.pref:
-            self.core.pref.update_output(sink, False)
-        return
-
-    def move_all_sinks_inputs(self, sink_index):
-        for sink_input in self.sink_inputs.values():
-            self.pa_context_move_sink_input_by_index(sink_input.index, sink_index)
-
-    def move_client_to_sink(self, client):
-        sink_index = self.prefer_sink_index
-        if client.prefer_sink:
-            for sink in self.sinks_by_id.values():
-                if sink.name == client.prefer_sink:
-                    sink_index = sink.index
-                    break
-        for sink_input in client.sinks.values():
-            self.pa_context_move_sink_input_by_index(sink_input.index, sink_index)
-
-    ### DEAL WITH SINKS #################################
-
-
-    ### DEAL WITH SOURCES ###############################
-    def pa_source_info_cb(self, source, user_data, s):
-        if source.name.lower().count("usb") > 0 or source.name.lower().count("bluetooth") > 0:
-            self.core.notify("New microphone", "Moving input to new device")
-            self.prefer_source_index = source.index
-            self.pa_context_set_default_source(source.name)
-            self.move_all_source_outputs(source.index)
-
-    def pa_source_output_info_cb(self, source_output, user_data):
-
-        if self.prefer_source_index > 0 and source_output.source != self.prefer_source_index:
-            self.pa_context_move_source_output_by_index(source_output.index, self.prefer_source_index)
-
-        self.source_outputs[source_output.index] = source_output
-
-        print "SOURCE OUTPUT" ,  source_output.name, source_output.source 
-
-    def move_all_source_outputs(self, source_index):
-        for source_output in self.source_outputs.values():
-            self.pa_context_move_source_output_by_index(source_output.index,  source_index)
-
-    ### DEAL WITH SOURCES ###############################
-
-
-    # CLIENTS    
-    def pa_client_info_cb(self, client, user_data):
-
-        if not self.clients.has_key(client.name):
-            c = Client(self.core, client.name, client.pid)
-            log.info("new client : %s" % c.description)
-            
-            self.clients[client.name] = c
-        else:
-            log.debug("update client : %s" % client.name)
-            c = self.clients[client.name]
-            c.pid = client.pid
-        self.clients_by_id[client.index] = c
-
-    def pa_client_remove_cb(self, index):
-        
-        if self.clients_by_id.has_key(index):
-            client = self.clients_by_id[index]
-            log.debug("remove client : %s" % client.name)
-            del self.clients_by_id[index]
-
-    # SINK INPUTS
-    def pa_sink_input_info_cb(self, sink_input, user_data):
-        target_sink = self.prefer_sink_index
-
-        if not self.sink_inputs.has_key(sink_input.index):
-            s = SinkInput(sink_input.index, sink_input.name, sink_input.volume, sink_input.sink, sink_input.media_role)
-            self.sink_inputs[s.index] = s
-
-            if self.clients_by_id.has_key(sink_input.client):
-                client = self.clients_by_id[sink_input.client]
-                client.sinks[s.index] = s
-                s.client = client
-
-                # Skim client role from 1st stream
-                if not client.role and sink_input.media_role:
-                    client.role = sink_input.media_role
-                    log.info("new client media role : %s %s " % (client.name, sink_input.media_role))
-
-            self.pa_create_monitor_stream_for_sink_input(sink_input.index, self.sinks_by_id[sink_input.sink].monitor_source, sink_input.name, s.client.description)
-
-            log.info("new sink input : %s %s " % (s.client.description, s.name))
-
-        else:
-            log.debug("update sink input : %s %s" % (sink_input.name, sink_input.sink))
-            s = self.sink_inputs[sink_input.index]
-            s.volume = sink_input.volume
-            s.name = sink_input.name
-
-            # Check we have the correct sink
-            if s.client.prefer_sink:
-                for sink in self.sinks_by_id.values():
-                    if sink.name == s.client.prefer_sink:
-                        target_sink = sink.index
-
-            if not s.sink == sink_input.sink:
-                self.pa_create_monitor_stream_for_sink_input(sink_input.index, self.sinks_by_id[sink_input.sink].monitor_source, sink_input.name, s.client.description)   
-                s.sink = sink_input.sink
-
-        if target_sink > 0 and self.sink_inputs[sink_input.index].sink != target_sink:
-            self.pa_context_move_sink_input_by_index(sink_input.index, target_sink)
-
-        # recheck clients to windows
-        self.core.window_watcher.check_all()
-
-    def pa_sink_input_remove_cb(self, index):
-
-        if self.sink_inputs.has_key(index):
-            sink = self.sink_inputs[index]
-            log.debug("remove sink input : %s" % sink.name)
-            
-            del( sink.client.sinks[index] )
-            del( self.sink_inputs[index] )
-
-            # reset volume in pa
-            v = []
-            for i in range(0, len(sink.volume)):
-                v.append(100)
-            self.pa_context_set_sink_input_volume(index, v)
-
-            if self.core.pref:
-                self.core.pref.update_client( sink.client )
-
-
-    # VOLUME METER FOR SINK INPUT
-    def pa_stream_request_cb(self, meter_level, user_data):
-        if user_data in self.sink_inputs.keys():
-            self.sink_inputs[user_data].set_meter( meter_level )
-            log.debug("pa_stream_request_cb : %s %s" % (meter_level, user_data))
-            if self.core.pref:
-                self.core.pref.update_client( self.sink_inputs[user_data].client )
-
-    def pa_create_monitor_stream_for_sink_input(self, index, monitor_index, name, description):
-        
-        log.debug("pa_create_monitor_stream_for_sink_input : %s" % index)
-
-        # Create new stream
-        ss = self.pa_sample_spec()
-        ss.channels = 1
-        ss.format = 5
-        ss.rate = 25
-        pa_stream = self.pa_stream_new(description, ss)
-        
-        self.pa_stream_set_monitor_stream(pa_stream, index);
-        self.pa_stream_set_read_callback(pa_stream, index);
-        self.pa_stream_set_suspended_callback(pa_stream);
-
-        attr = self.pa_buffer_attr()
-        attr.fragsize = 4
-        attr.maxlength = 10
-        attr.tlength = 0
-        attr.prebuf = 0
-        attr.minreq = 0
-
-        self.pa_stream_connect_record(pa_stream, str(monitor_index), attr, 10752) 
-
-
-if __name__ == '__main__':
-
-    import gtk
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-
-    pa = PulseAudio("Test")
-    pa.connect()
-
-    gtk.main()
diff --git a/earcandy/SinkInput.py b/earcandy/SinkInput.py
deleted file mode 100644
index 78d7a2a..0000000
--- a/earcandy/SinkInput.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2008 Jason Taylor
-# 
-# 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, see <http://www.gnu.org/licenses/>.
-
-import math  
-import time
-import datetime 
-         
-class SinkInput():
-    def __init__(self, index, name, volume, sink, role):
-
-        self.index = index
-        self.name = name
-        self.client = None
-        self.volume = volume
-        self.sink = sink
-        self.__role = role
-
-        self.volume_meter_level = 0
-        self.volume_meter_last_non_zero_timestamp = time.mktime(datetime.datetime.min.timetuple())
-
-        self.volume_target = 100
-
-        self.__previous_volume = 0
-
-        self.volume_check = True
-        self.__status = False
-
-
-    def get_media_role(self):
-        if not self.__role: return self.client.role
-        return self.__role
-
-    def set_media_role(self, role):
-        self.__role = role
-
-    role = property(get_media_role, set_media_role)
-
- 
-    def set_meter(self, meter_level):
-        timestamp = math.floor(time.mktime(datetime.datetime.now().timetuple()))
-        if(meter_level > 0):
-            self.volume_meter_last_non_zero_timestamp = timestamp
-        self.volume_meter_level = meter_level
-
-    def is_active(self):
-        timestamp = math.floor(time.mktime(datetime.datetime.now().timetuple()))
-        compare = timestamp - self.volume_meter_last_non_zero_timestamp
-        if compare <= 1:
-            return True
-        return False
-
-
-
-    ## new per sink settings ##
-    def set_volume(self):
-
-        current_volume = round(self.volume[0])
-        step_volume = current_volume
-        result = True
-
-        if current_volume < self.volume_target:      
-            step_volume = current_volume + self.client.volume_step
-            if not self.client.fade_volume: step_volume = self.volume_target
-        elif current_volume > self.volume_target: 
-            step_volume = current_volume - self.client.volume_step
-            if not self.client.fade_volume: step_volume = self.volume_target
-        
-        if step_volume > 100:
-            step_volume = 100
-        if step_volume < self.client.volume_step:
-            step_volume = self.client.volume_step
-
-        # we dont want to get stuck in a loop because volumes arn't exactly the same 
-        result = math.fabs(self.__previous_volume - current_volume) >= self.client.volume_step
-        volume_check = math.fabs(self.client.volume_target - current_volume) < self.client.volume_step
-
-        if result:
-            for i in range(0, len(self.volume)):
-                self.volume[i] = step_volume
-
-            #print "\nAdjust Volume", self.client.name, step_volume
-        
-        if volume_check and not self.volume_check:
-            self.volume_check = volume_check
-            self.client.check_volume()
-
-        self.volume_check = volume_check
-
-        self.__previous_volume = step_volume       
-        return result
-
-    def get_volume_meter(self):
-        return sink.volume_meter_level
-
-    def __fade_in(self):
-        self.volume_target = self.client.volume_max
-
-    def __fade_out(self):
-        if self.client.volume_min == -1:
-            self.volume_target = self.client.core.mute_level
-        else:
-            self.volume_target = self.client.volume_min
-
-    def __fade_mute(self):
-        if self.client.volume_min == -1:
-            self.volume_target = self.client.core.mute_level
-        else:
-            self.volume_target = self.client.volume_min
-
-        # if we goto 0 than our volume meter will never register a value
-        if self.volume_target < self.client.volume_step:
-            self.volume_target = self.client.volume_step
-    
-    def set_status(self, value):
-        
-        if value or self.role == "default":
-            self.__fade_in()
-        else:
-            self.__fade_mute()
-
-        self.__status = value
-
-    def get_status(self):
-        return self.__status
-
-
-
-
-
-
-
diff --git a/earcandy/earcandyconfig.py b/earcandy/earcandyconfig.py
deleted file mode 100644
index c1a4778..0000000
--- a/earcandy/earcandyconfig.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-### BEGIN LICENSE
-# This file is in the public domain
-### END LICENSE
-
-# THIS IS Earcandy CONFIGURATION FILE
-# YOU CAN PUT THERE SOME GLOBAL VALUE
-# Do not touch until you know what you're doing.
-# you're warned :)
-
-# where your project will head for your data (for instance, images and ui files)
-# by default, this is ../data, relative your trunk layout
-__earcandy_data_directory__ = '../data/'
-
-
-import os
-
-class project_path_not_found(Exception):
-    pass
-
-def getdatapath():
-    """Retrieve earcandy data path
-
-    This path is by default <earcandy_lib_path>/../data/ in trunk
-    and /usr/share/earcandy in an installed version but this path
-    is specified at installation time.
-    """
-
-    # get pathname absolute or relative
-    if __earcandy_data_directory__.startswith('/'):
-        pathname = __earcandy_data_directory__
-    else:
-        pathname = os.path.dirname(__file__) + '/' + __earcandy_data_directory__
-
-    abs_data_path = os.path.abspath(pathname)
-    if os.path.exists(abs_data_path):
-        return abs_data_path
-    else:
-        raise project_path_not_found
-
diff --git a/earcandy/plugins/banshee/plugin.py b/earcandy/plugins/banshee/plugin.py
deleted file mode 100644
index ff3f02f..0000000
--- a/earcandy/plugins/banshee/plugin.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2009  Jason Taylor
-# 
-# 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, see <http://www.gnu.org/licenses/>.
-
-from PluginBase import PluginBaseObject
-
-import dbus
-
-class BansheeControlPlugin(PluginBaseObject):
-
-    def __init__(self, core, path):
-        PluginBaseObject(core, path) 
-        self.bus = dbus.SessionBus()
-        return
-
-    def get_client_name(self):
-        return "Banshee"
-
-    def get_plugin_name(self):
-        return "Banshee pause control (DBUS)"
-
-    # Is application playing
-    def is_playing(self):
-        banshee = self.__get_application()
-        if banshee:        
-            return not banshee.GetCurrentState() == "paused"
-        return False
-
-    # Set application paused status
-    def set_pause(self, status):
-        banshee = self.__get_application()
-        if banshee:
-            if status:
-                banshee.Pause()
-            else:
-                banshee.Play()
-            return True
-        return False
-
-    def __get_application(self):
-        return self.bus.get_object("org.bansheeproject.Banshee", "/org/bansheeproject/Banshee/PlayerEngine")
-
-
-def register_plugin( core, path ):
-    return BansheeControlPlugin( core, path )
diff --git a/earcandy/plugins/rhythmbox/__init__.py b/earcandy/plugins/rhythmbox/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/earcandy/plugins/rhythmbox/plugin.py b/earcandy/plugins/rhythmbox/plugin.py
deleted file mode 100644
index 97d4526..0000000
--- a/earcandy/plugins/rhythmbox/plugin.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2009  Jason Taylor
-# 
-# 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, see <http://www.gnu.org/licenses/>.
-
-from PluginBase import PluginBaseObject
-
-import dbus
-
-class RhythmboxControlPlugin(PluginBaseObject):
-
-    def __init__(self, core, path):
-        PluginBaseObject(core, path) 
-        self.bus = dbus.SessionBus()
-        return
-
-    # Client this plugin applies to
-    def get_client_name(self):
-        return "Rhythmbox"
-
-    def get_plugin_name(self):
-        return "Rhythmbox pause control (DBUS)"
-
-    def __get_application(self):
-        return self.bus.get_object("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
-
-    # Is application paused
-    def is_playing(self):
-        rb = self.__get_application()
-        if rb:  
-            return rb.getPlaying()
-        return False
-
-    # Set application paused status
-    def set_pause(self, status):
-        rb = self.__get_application()
-        if rb:
-            rb.playPause(status)
-            return True
-        return False
-
-def register_plugin( core, path ):
-    return RhythmboxControlPlugin( core, path )
diff --git a/earcandy/pulseaudio/Client.py b/earcandy/pulseaudio/Client.py
deleted file mode 100644
index f623988..0000000
--- a/earcandy/pulseaudio/Client.py
+++ /dev/null
@@ -1,12 +0,0 @@
-
-class Client():
-    def __init__(self, pa, contents):
-        
-        self.name = str(contents.name)
-        self.index = int(contents.index)
-        self.pid = float(pa.pa_proplist_gets(contents.proplist, "application.process.id") or -1)
-
-        # Almost no applications use these yet :(
-        self.binary = pa.pa_proplist_gets(contents.proplist, "application.process.binary") or None
-        self.xid = pa.pa_proplist_gets(contents.proplist, "window.x11.xid") or -1
-        self.window_id = pa.pa_proplist_gets(contents.proplist, "window.id") or -1
diff --git a/earcandy/pulseaudio/Crash.py b/earcandy/pulseaudio/Crash.py
deleted file mode 100644
index 98239eb..0000000
--- a/earcandy/pulseaudio/Crash.py
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-from PulseAudioConnection import PulseAudioConnection
-
-
-class PulseAudio(PulseAudioConnection):
-    def __init__(self, Name):
-
-        PulseAudioConnection.__init__(self, Name)
-
-    def pa_sink_input_info_cb(self, sink_input, user_data):
-        #print self.convert_simple_volume_to_pa_volume(sink_input.volume).values[0]
-        self.pa_context_set_sink_input_volume(sink_input.index, sink_input.volume  )
-        return
-
-if __name__ == '__main__':
-    import gtk
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-
-    pa = PulseAudio("Test")
-    pa.connect()
-
-    gtk.main()
diff --git a/earcandy/pulseaudio/PulseAudioConnection.py b/earcandy/pulseaudio/PulseAudioConnection.py
deleted file mode 100644
index d05e512..0000000
--- a/earcandy/pulseaudio/PulseAudioConnection.py
+++ /dev/null
@@ -1,363 +0,0 @@
-# Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2008 Jason Taylor
-# 
-# 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, see <http://www.gnu.org/licenses/>.
-
-from lib_pulseaudio import *
-import gobject
-import ctypes
-import logging
-from Client import Client
-from SinkInput import SinkInput
-from Sink import Sink
-from SourceOutput import SourceOutput
-from Source import Source
-PA_VOLUME_CONVERSION_FACTOR = 655.36
-
-log = logging.getLogger('PulseAudioConnection')
-log.setLevel(logging.DEBUG)
-
-# A null method that can be given to pulse methods
-def null_cb(a=None, b=None, c=None, d=None):
-    #print "NULL CB"
-    return
-
-class PulseAudioConnection():
-
-    def __init__(self, Name="Simple Pulse Audio Connection"):
-        
-        self.Name = Name
-
-        self.sinks = {}
-        self.monitor_sinks = []
-        self.module_stream_restore_argument = ""
-
-    def connect(self):
-
-        self.__mainloop = pa_threaded_mainloop_new()
-        self.__mainloop_api = pa_threaded_mainloop_get_api(self.__mainloop)
-
-        self._context = pa_context_new(self.__mainloop_api, self.Name )   
-
-        self._context_notify_cb = pa_context_notify_cb_t(self.context_notify_cb) 
-        pa_context_set_state_callback(self._context, self._context_notify_cb, None)   
-
-        pa_context_connect(self._context, None, 0, None);
-        pa_threaded_mainloop_start(self.__mainloop)
-
-    def disconnect(self):
-        pa_context_disconnect(self._context)
-
-    # pulseaudio connection status    
-    def context_notify_cb(self, context, userdata):
-        
-        try:
-            ctc = pa_context_get_state(context)
-            if ctc == PA_CONTEXT_READY:
-                log.debug("connection ready")
-
-                self._null_cb = pa_context_success_cb_t(null_cb)
-                self._pa_context_success_cb = pa_context_success_cb_t(self.__pa_context_success_cb)
-                self._pa_stream_request_cb = pa_stream_request_cb_t(self.__pa_stream_request_cb)
-                self._pa_stream_notify_cb = pa_stream_notify_cb_t(self.__pa_stream_request_cb)
-                self._pa_sink_info_cb = pa_sink_info_cb_t(self.__pa_sink_info_cb)
-                self._pa_context_subscribe_cb = pa_context_subscribe_cb_t(self.__pa_context_subscribe_cb)
-                self._pa_source_info_cb = pa_source_info_cb_t(self.__pa_source_info_cb)
-                self._pa_source_output_info_cb = pa_source_output_info_cb_t(self.__pa_source_output_info_cb)
-                self._pa_sink_input_info_list_cb = pa_sink_input_info_cb_t(self.__pa_sink_input_info_cb)
-                self._pa_client_info_list_cb = pa_client_info_cb_t(self.__pa_client_info_cb)
-                self._pa_module_info_cb = pa_module_info_cb_t(self.__pa_module_info_cb)
-                self._pa_context_index_cb = pa_context_index_cb_t(self.__pa_context_index_cb) 
-
-                o = pa_context_get_module_info_list(self._context, self._pa_module_info_cb, True)
-                pa_operation_unref(o)
-
-                o = pa_context_get_source_info_list(self._context, self._pa_source_info_cb, True)
-                pa_operation_unref(o)
-
-                o = pa_context_get_sink_info_list(self._context, self._pa_sink_info_cb, True)
-                pa_operation_unref(o)
-
-                o = pa_context_get_client_info_list(self._context, self._pa_client_info_list_cb, None)
-                pa_operation_unref(o)
-                
-                o = pa_context_get_source_output_info_list(self._context, self._pa_source_output_info_cb, None)
-                pa_operation_unref(o)
-
-                o = pa_context_get_sink_input_info_list(self._context, self._pa_sink_input_info_list_cb, True)
-                pa_operation_unref(o)
-
-                pa_context_set_subscribe_callback(self._context, self._pa_context_subscribe_cb, None);
-                o = pa_context_subscribe(self._context, (pa_subscription_mask_t)
-                                               (PA_SUBSCRIPTION_MASK_SINK |
-                                                PA_SUBSCRIPTION_MASK_SOURCE |
-                                                PA_SUBSCRIPTION_MASK_SINK_INPUT |
-                                                PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT |
-                                                PA_SUBSCRIPTION_MASK_CLIENT |
-                                                PA_SUBSCRIPTION_MASK_SERVER), self._null_cb, None)  
-
-                pa_operation_unref(o)     
-                gobject.idle_add(self.pa_status_ready)        
-
-            if ctc == PA_CONTEXT_FAILED :
-                log.debug("connection failed")
-                pa_threaded_mainloop_signal(self.__mainloop, 0)
-                
-            if ctc == PA_CONTEXT_TERMINATED:
-                log.debug("connection terminated")
-                pa_threaded_mainloop_signal(self.__mainloop, 0)
-
-        except Exception, text:
-            log.exception("context_notify_cb %s" % text)
-
-    def __pa_context_index_cb(self, context, index, user_data):
-        log.debug("__pa_context_index_cb")
-        gobject.idle_add(self.pa_context_index_cb,  index, user_data)
-        return
-
-    def __pa_module_info_cb(self, context, struct, eol, user_data):
-        
-        if struct:
-            log.debug("__pa_module_info_cb : %s" % struct.contents.name)
-            gobject.idle_add(self.pa_module_info_cb, struct.contents, eol, user_data)
-
-    def __pa_source_info_cb(self, context, struct, eol, user_data):
-        if struct:
-            source = Source(self, struct.contents)
-            log.debug("__pa_source_info_cb : %s" % struct.contents.name)
-            gobject.idle_add(self.pa_source_info_cb, source, eol, user_data)
-
-    def __pa_source_output_info_cb(self, context, struct, c_int, user_data):
-            if struct:
-                source_output = SourceOutput(self, struct.contents)
-                log.debug("__pa_source_output_info_cb : %s" % struct.contents.name)
-                gobject.idle_add(self.pa_source_output_info_cb, source_output, user_data)
-
-    def __pa_context_success_cb(self, context, c_int, user_data):
-        log.debug("__pa_source_output_info_cb")
-        gobject.idle_add(self.pa_context_success_cb, c_int, user_data)
-
-    def __pa_stream_request_cb(self, stream, length, user_data):
-        data = self.pa_stream_peek(stream, length)
-        v = data[length / 4 -1] * 100
-        if (v < 0):
-            v = 0
-        if (v > 100):
-            v = 100
-        self.pa_stream_drop(stream)
-
-        #log.debug("__pa_stream_request_cb")
-        gobject.idle_add(self.pa_stream_request_cb, v, user_data)
-
-    def __pa_context_subscribe_cb(self, context, event_type, index, user_data):
-
-        try:
-            et = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK
-
-            if et == PA_SUBSCRIPTION_EVENT_CLIENT:
-                
-                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
-                    log.debug("PA_SUBSCRIPTION_EVENT_CLIENT | PA_SUBSCRIPTION_EVENT_REMOVE : %d" % index)
-                    gobject.idle_add(self.pa_client_remove_cb, int(index))
-                else:
-                    o = pa_context_get_client_info(self._context, index, self._pa_client_info_list_cb, None)
-                    pa_operation_unref(o)
-
-            if et == PA_SUBSCRIPTION_EVENT_SINK_INPUT:
-                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
-                    log.debug("PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_REMOVE : %d" % index)
-                    gobject.idle_add(self.pa_sink_input_remove_cb, int(index))
-                else:
-                    o = pa_context_get_sink_input_info(self._context, int(index), self._pa_sink_input_info_list_cb, True)
-                    pa_operation_unref(o)
-                    
-            if et == PA_SUBSCRIPTION_EVENT_SINK:
-                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
-                    log.debug("PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE : %d" % index)
-                    gobject.idle_add(self.pa_sink_remove_cb, int(index))
-                else:
-                    o = pa_context_get_sink_info_by_index(self._context, int(index), self._pa_sink_info_cb, False)
-                    pa_operation_unref(o)
-
-            if et == PA_SUBSCRIPTION_EVENT_SOURCE:
-                if event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK == PA_SUBSCRIPTION_EVENT_REMOVE:
-                    log.debug("PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE : %d" % index)
-                    gobject.idle_add(self.pa_source_remove_cb, int(index))
-                else:
-                    o = pa_context_get_source_info_by_index(self._context, int(index), self._pa_source_info_cb, False)
-                    pa_operation_unref(o)
-
-
-        except Exception, text:
-            log.exception("PA ERROR pa_context_subscribe_cb %s" % text)
-    
-    def __pa_client_info_cb(self, context, struct, c_int, user_data):
-        if struct:
-            client = Client(self, struct.contents)
-            log.debug("__pa_client_info_cb : %s" % struct.contents.name)
-            gobject.idle_add(self.pa_client_info_cb, client, user_data)
-   
-    def __pa_sink_input_info_cb(self, context, struct, index, user_data):
-        if struct:
-            sink_input = SinkInput(self, struct.contents)
-            log.debug("__pa_sink_input_info_cb : %s" % struct.contents.name)
-            gobject.idle_add( self.pa_sink_input_info_cb, sink_input, user_data)
-
-    def __pa_sink_info_cb(self, context, struct, index, user_data):
-        if struct:
-            sink = Sink(self, struct.contents)
-            log.debug("__pa_sink_info_cb : %s" % struct.contents.name)
-            gobject.idle_add( self.pa_sink_info_cb, sink, user_data)
-
-    # EVENTS
-    def pa_client_info_cb(self, client, user_data):
-        return
-    def pa_client_remove_cb(self, index):
-        return
-
-    def pa_sink_input_info_cb(self, sink_input, user_data):
-        return
-    def pa_sink_input_remove_cb(self, index):
-        return
-
-    def pa_sink_info_cb(self, sink, user_data):
-        return
-    def pa_sink_remove_cb(self, index):
-        return
-
-    def pa_source_info_cb(self, contents, eol, user_data):
-        return
-    def pa_source_remove_cb(self, index):
-        return
-
-    def pa_module_info_cb(self, contents, eol, user_data):
-        return
-    def pa_source_output_info_cb(self, contents, index, user_data):
-        return
-    def pa_stream_request_cb(self, meter, index):
-        return
-    def pa_context_success_cb(self, c_int, user_data):
-        return
-    def pa_context_index_cb(self, index, user_data):
-        return
-
-    def pa_status_ready(self):
-        return
-
-
-    def pa_buffer_attr(self):
-        return pa_buffer_attr()
-    def pa_sample_spec(self):
-        return pa_sample_spec()
-    def pa_stream_new(self, name, sample_spec):
-        return pa_stream_new(self._context, name, sample_spec, None)
-    def pa_stream_set_monitor_stream(self, pa_stream, index):
-        return pa_stream_set_monitor_stream(pa_stream, index)
-    def pa_stream_set_read_callback(self, pa_stream, index):
-        return pa_stream_set_read_callback(pa_stream, self._pa_stream_request_cb, index)
-    def pa_stream_set_suspended_callback(self, pa_stream):
-        return pa_stream_set_suspended_callback(pa_stream, self._pa_stream_notify_cb, "DOOM")
-    def pa_stream_connect_record(self, pa_stream, monitor_index, attr, size):
-        return pa_stream_connect_record(pa_stream, monitor_index, attr, size) 
-    def pa_stream_peek(self, stream, length):
-        data = POINTER(c_float)()
-        pa_stream_peek(stream, data, ctypes.c_ulong(length))
-        return data
-    def pa_stream_drop(self, stream):
-        pa_stream_drop(stream)
-
-
-    # METHODS
-    def pa_context_get_sink_info_list(self):
-        o = pa_context_get_sink_info_list(self._context, self._pa_sink_info_cb, True)
-        pa_operation_unref(o)
-
-    def pa_context_get_source_output_info_list(self):
-        o = pa_context_get_source_output_info_list(self._context, self._pa_source_output_info_cb, True)
-        pa_operation_unref(o)
-
-    def pa_context_get_source_info_list(self):
-        o = pa_context_get_source_info_list(self._context, self._pa_source_info_cb, True)
-        pa_operation_unref(o)
-
-    def pa_proplist_gets(self, proplist, name):
-        return pa_proplist_gets(proplist, name)
-
-    def convert_simple_volume_to_pa_volume(self, volume):
-        vol = pa_cvolume()
-        vol.channels = len(volume)
-        v = pa_volume_t * 32
-        vol.values = v()
-        for i in range(0, len(volume)):
-            if i == 32: return vol
-            channel_volume = volume[i]
-            if channel_volume < 0: channel_volume = 0
-            if channel_volume > 100: channel_volume = 100
-            vol.values[i] = int(channel_volume * PA_VOLUME_CONVERSION_FACTOR)
-        return vol
-
-    def convert_pa_volume_to_simple_volume(self, volume):
-        vol = []
-        for i in range(0, volume.channels):
-            vol.append( int(volume.values[i] / PA_VOLUME_CONVERSION_FACTOR) )
-        return vol
-
-    def pa_context_move_sink_input_by_index(self, sink_input_index, sink_index):
-        pa_context_move_sink_input_by_index(self._context, sink_input_index, sink_index, self._pa_context_success_cb, None)
-
-    def pa_context_move_sink_input_by_name(self, sink_index, output_name):
-        pa_context_move_sink_input_by_name(self._context, sink_index, output_name, self._pa_context_success_cb, None)
-
-    def pa_context_set_sink_volume_by_name(self, sink_name, volume):       
-        vol = self.convert_simple_volume_to_pa_volume(volume)
-        o = pa_context_set_sink_volume_by_name(self._context, sink_name, vol, self._null_cb, None)
-        pa_operation_unref(o)
-
-    def pa_context_set_sink_input_volume(self, index, volume):
-        log.debug("pa_context_set_sink_input_volume : %s" % index)
-        vol = self.convert_simple_volume_to_pa_volume(volume)
-        o = pa_context_set_sink_input_volume(self._context, index, vol, self._null_cb, None) # NOTE: dont pass in any thing here causes a seg fault
-        pa_operation_unref(o)
-
-    def pa_context_get_sink_info_by_name(self, sink_name):
-        o = pa_context_get_sink_info_by_name(self._context, sink_name, self._pa_sink_info_cb, False)
-        pa_operation_unref(o)
-
-    def pa_context_get_source_info_by_name(self, source_name):
-        o = pa_context_get_source_info_by_name(self._context, source_name, self._pa_source_info_cb, False)
-        pa_operation_unref(o)
-
-    def pa_context_set_default_sink(self, sink_name):
-        o = pa_context_set_default_sink(self._context, sink_name, self._pa_context_success_cb, False)
-        pa_operation_unref(o)
-
-    def pa_context_move_source_output_by_index(self, source_output_index, source_index):
-        pa_context_move_source_output_by_index(self._context, source_output_index, source_index, self._pa_context_success_cb, None)
-
-    def pa_context_set_default_source(self, source_name):
-        o = pa_context_set_default_source(self._context, source_name, self._pa_context_success_cb, False)
-        pa_operation_unref(o)
-
-if __name__ == '__main__':
-
-    log.basicConfig(level=log.CRITICAL)
-    import gtk
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-
-    pac = PulseAudioConnection("Test")
-    pac.connect()
-
-    gtk.main()
-    
diff --git a/earcandy/pulseaudio/Sink.py b/earcandy/pulseaudio/Sink.py
deleted file mode 100644
index 61969e1..0000000
--- a/earcandy/pulseaudio/Sink.py
+++ /dev/null
@@ -1,11 +0,0 @@
-
-class Sink():
-    def __init__(self, pa, contents):
-        
-        self.name = str(contents.name)
-        self.index = int(contents.index)
-        self.volume = pa.convert_pa_volume_to_simple_volume(contents.volume)
-        self.description = pa.pa_proplist_gets(contents.proplist, "device.description")
-
-        self.monitor_source = int(contents.monitor_source)
-        self.monitor_source_name = str(contents.monitor_source_name)
diff --git a/earcandy/pulseaudio/SinkInput.py b/earcandy/pulseaudio/SinkInput.py
deleted file mode 100644
index 2198781..0000000
--- a/earcandy/pulseaudio/SinkInput.py
+++ /dev/null
@@ -1,16 +0,0 @@
-
-class SinkInput():
-    def __init__(self, pa, contents):
-        
-        self.name = str(contents.name)
-        self.index = int(contents.index)
-        self.volume = pa.convert_pa_volume_to_simple_volume(contents.volume)
-
-        self.client = int(contents.client)
-        self.sink = int(contents.sink)
-
-        self.media_role = pa.pa_proplist_gets(contents.proplist, "media.role") or None
-        self.media_name = pa.pa_proplist_gets(contents.proplist, "media.name") or None
-        self.media_title = pa.pa_proplist_gets(contents.proplist, "media.title") or None
-        self.media_artist = pa.pa_proplist_gets(contents.proplist, "media.artist") or None
-        self.media_icon_name = pa.pa_proplist_gets(contents.proplist, "media.icon_name") or None
diff --git a/earcandy/pulseaudio/Source.py b/earcandy/pulseaudio/Source.py
deleted file mode 100644
index 4bbb1f2..0000000
--- a/earcandy/pulseaudio/Source.py
+++ /dev/null
@@ -1,9 +0,0 @@
-
-class Source():
-    def __init__(self, pa, contents):
-        
-        self.name = str(contents.name)
-        self.index = int(contents.index)
-        #self.volume = pa.convert_pa_volume_to_simple_volume(contents.volume)
-        #self.description = pa.pa_proplist_gets(contents.proplist, "device.description")
-
diff --git a/earcandy/pulseaudio/SourceOutput.py b/earcandy/pulseaudio/SourceOutput.py
deleted file mode 100644
index 47126fe..0000000
--- a/earcandy/pulseaudio/SourceOutput.py
+++ /dev/null
@@ -1,12 +0,0 @@
-
-class SourceOutput():
-    def __init__(self, pa, contents):
-        
-        self.name = str(contents.name)
-        self.index = int(contents.index)
-        #self.volume = pa.convert_pa_volume_to_simple_volume(contents.volume)
-
-        self.client = int(contents.client)
-        self.source = int(contents.source)
-
-
diff --git a/earcandy/pulseaudio/__init__.py b/earcandy/pulseaudio/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/earcandy/ui/Client.py b/earcandy/ui/Client.py
deleted file mode 100644
index 5f72dba..0000000
--- a/earcandy/ui/Client.py
+++ /dev/null
@@ -1,85 +0,0 @@
-
-import sys
-import gtk
-import time
-import gobject
-import os
-from earcandy.earcandyconfig import getdatapath
-from earcandy.util.Threads import threaded
-
-class Client:
-        def __init__(self, client, core):
-            self.core = core
-            self.client = client
-
-            glade = os.path.join(getdatapath(), 'ui', 'EarCandy.ui')
-
-            # Get glade file XML
-            f = open( glade ,"r")
-            xml =  f.read()
-            f.close()
-        
-            # Remember you will need to recreate tree everytime the window loads
-            #wtree = gtk.glade.xml_new_from_buffer(xml, len(xml), "table_clients")
-
-            wtree = gtk.Builder()
-            wtree.add_from_string(xml)
-
-            self.gtk = wtree.get_object("table_clients") 
-            self.gtk_progressbar_meter = wtree.get_object("progressbar_meter")   
-            self.gtk_label = wtree.get_object("label_client_name")  
-            self.gtk_icon = wtree.get_object("image_client_icon") 
-            self.gtk_role_combobox = wtree.get_object("combobox_role") 
-            self.button_client = wtree.get_object("button_client") 
-
-            store = gtk.ListStore(gobject.TYPE_STRING)
-            self.gtk_role_combobox.set_model(store)
-            cell = gtk.CellRendererText()
-            self.gtk_role_combobox.pack_start(cell, True)
-            self.gtk_role_combobox.add_attribute(cell, 'text', 0)
-
-            for key in self.core.display.keys():
-                self.gtk_role_combobox.append_text(self.core.display[key])
-            self.gtk_role_combobox.set_active(0)
-
-            #client.gtk_role_combobox.set_model(self.cb_model)
-            self.gtk_role_combobox.connect("changed", self.on_role_changed)
-            self.button_client.connect("clicked", self.on_clicked)
-
-            style = gtk.Style()
-            self.gtk_label.modify_fg(gtk.STATE_NORMAL, style.fg[gtk.STATE_NORMAL])
-
-            self.__hide_timer = False
-
-            self.gtk.unparent()
-
-        def on_clicked(self, widget):
-            self.core.pref.open_client_properties(self.client)
-
-
-        def on_role_changed(self, widget):
-            #self.client.role = ""
-            for key in self.core.display.keys():
-                if self.core.display[key] == widget.get_active_text():
-                    self.client.role = key
-            self.core.save()
-            return
-
-        def set_status(self, status):
-            if not status:
-                if not self.__hide_timer:
-                    self.__hide_timer = True
-                    self.remove()
-            else:
-                self.__hide_timer = False
-
-        @threaded
-        def remove(self):
-            count = 1
-            while count < 60:
-                if not self.__hide_timer: return
-                time.sleep(1)
-                count = count + 1
-            if not self.client.is_active():
-                self.gtk.hide()
-
diff --git a/earcandy/ui/__init__.py b/earcandy/ui/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/earcandy/util/__init__.py b/earcandy/util/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/earcandy/windows/Application.py b/earcandy/windows/Application.py
deleted file mode 100644
index 49b8db4..0000000
--- a/earcandy/windows/Application.py
+++ /dev/null
@@ -1,69 +0,0 @@
-
-import os
-import gtk
-from earcandy.util.DesktopFiles import DesktopFiles
-import logging
-
-log = logging.getLogger('WindowApplication')
-log.setLevel(logging.WARNING)
-
-class Application():
-    def __init__(self, pid, command, name, desktop_files, icon):
-        self.command = os.path.basename(command.lower().strip())
-        self.name = name.lower().strip()
-        self.role = ""
-        self.icon = icon
-        self.icon_name = ""
-        self.description = name
-
-        # current application window info
-        self.pid = pid
-        self.window_name = ""
-        self.x = 0
-        self.y = 0
-        self.fullscreen = False
-        
-        self.__match_desktop(desktop_files)
-        return
-
-    def __match_desktop(self,  desktop_files):
-
-        #print "checking desktop files for match....", self.name
-        # Try looking up the application list
-        for a in desktop_files:
-            ex = a.get_exec_array()[0].lower()
-
-            # Check for pulse audio settings first...
-            if a.get("X-PulseAudio-Properties"):
-                self.role = a.get("X-PulseAudio-Properties")
-                break
-
-            if a.get("Categories") and len(a.get("Categories")) == 1 and a.get("Categories")[0] == "Core":
-                # skip entries that are core only
-                pass
-            else:
-                if a.get("X-GNOME-Bugzilla-Product") == self.name or ex == self.name or ex == self.command or a.get("Name").lower() == self.name or a.get("Name").lower() == self.command or ex + ".real" == self.command :
-                    self.icon_name = a.get("Icon")
-                    self.description = a.get("Name")
-                    self.role = self.__desktop_categories_to_role( a.get("Categories") )
-                    log.debug("WW :: desktop file : %s" % a.filename)
-                    break
-
-        if self.command == "skype.real":
-            self.role = "phone"
-        
-        log.debug("WW :: role : %s" % self.role)
-
-    def __desktop_categories_to_role(self, categories):
-        if categories:
-            for role in categories:
-                if "Telephony" in categories or "InstantMessaging" in categories:
-                    return "phone"
-                if "Music" in categories:
-                    return "music"
-                if "Video" in categories:
-                    return "video"
-                if "AudioVideo" in categories:
-                    return "music"             
-    
-        return ""
diff --git a/earcandy/windows/Watcher.py b/earcandy/windows/Watcher.py
deleted file mode 100644
index 49b563e..0000000
--- a/earcandy/windows/Watcher.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import wnck
-import gobject
-import logging
-from earcandy.util.DesktopFiles import DesktopFiles
-from Application import Application
-
-log = logging.getLogger('WindowWatcher')
-log.setLevel(logging.WARNING)
-
-class Watcher():
-    
-    def __init__(self):
-        self.screen = wnck.screen_get_default()
-        self.screen.connect("active_window_changed", self.active_window_changed)
-        self.screen.connect("window_opened", self.window_opened)
-
-        self.desktop_files = DesktopFiles().read_all()
-        self.current_window = None
-        self.applications = {}
-
-        self.callback = None
-
-
-
-
-    def check_all(self):
-        for win in self.screen.get_windows():
-            self.update("exists", win) 
-
-    def get_command(self, pid):
-        command = str(pid)
-        try:
-            # Try and get command from PID
-            f = open("/proc/%s/cmdline" % pid, "r")
-            command = f.readline()[:-1]
-            f.close()
-        except:
-            pass
-        return command
-
-    def window_opened(self, screen, win):
-        if win and win.get_window_type() != wnck.WINDOW_DOCK: # ignore docks
-           
-            app = win.get_application ()
-            app_name = app.get_name()
-            
-            pid = win.get_pid()
-            command = self.get_command(pid)
-            category = ""
-
-            if not self.applications.has_key(command):
-                a = Application(pid, command, app_name, self.desktop_files, win.get_icon ())
-                self.applications[command] = a
-            
-            log.debug("WW :: window opened : %s" % app_name)
-            self.update("open", win)
-            #win.connect("geometry-changed", self.geometry_changed)
-           
-    def active_window_changed(self, screen, old_window):
-        #print screen
-        win = screen.get_active_window ()
-        if win:
-            log.debug("WW :: active window changed : %s" % win.get_name())
-            self.update("active", win)    
-    
-
-    def update(self, state, win):
-        if win and win.get_window_type() != wnck.WINDOW_DOCK: # ignore docks
-                
-            #try:
-                app = win.get_application ()
-                app_name = app.get_name()
-                pid = win.get_pid()
-
-                command = self.get_command(pid)
-
-                application = None
-                application = self.applications[command]
-                application.pid = pid
-
-                geom = win.get_geometry()
-                x = float(geom[1])
-                y = float(geom[0])
-                w = float(geom[2])
-                h = float(geom[3])
-
-                if win.get_name():
-                    application.window_name =  win.get_name()
-
-                #application.x = x+h/2
-                #application.y = y+w/2
-                #application.fullscreen = win.is_fullscreen () or win.is_maximized ()
-                #application.icon = win.get_icon ()
-                log.debug("WW :: application : %s" % application.description)
-                
-                if self.callback:
-                    gobject.idle_add(self.callback, application, state)
-            #except:
-            #    print "error reading window", win
-
-    def geometry_changed(self, win):
-        self.update("geo", win)
-
-
-if __name__ == '__main__':
-    logging.basicConfig(level=log.debug)
-    import gtk
-    # Turn on gtk threading
-    gtk.gdk.threads_init()
-    ww = Watcher()
-    gtk.main()
-
diff --git a/earcandy/windows/__init__.py b/earcandy/windows/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/files/earcandy.desktop b/files/earcandy.desktop
new file mode 100644
index 0000000..89c8497
--- /dev/null
+++ b/files/earcandy.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Ear Candy
+Comment=Gracefully fade applications volume in and out
+Terminal=false
+Icon=earsLabel
+Type=Application
+Exec=earcandy
+Categories=Utility;
+StartupNotify=true
diff --git a/files/earsLabel.png b/files/earsLabel.png
new file mode 100644
index 0000000..b8ecce8
Binary files /dev/null and b/files/earsLabel.png differ
diff --git a/files/earsLabelOff.png b/files/earsLabelOff.png
new file mode 100644
index 0000000..2395f7b
Binary files /dev/null and b/files/earsLabelOff.png differ
diff --git a/data/ui/EarCandy.ui b/files/pulseoptions.glade
similarity index 54%
rename from data/ui/EarCandy.ui
rename to files/pulseoptions.glade
index ab9cd1b..72dcda3 100644
--- a/data/ui/EarCandy.ui
+++ b/files/pulseoptions.glade
@@ -1,363 +1,372 @@
 <?xml version="1.0"?>
-<interface>
-  <requires lib="gtk+" version="2.16"/>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.16 -->
   <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkAdjustment" id="adjustment1">
-    <property name="value">0.01</property>
-    <property name="lower">0.01</property>
-    <property name="upper">0.20000000000000001</property>
-    <property name="step_increment">0.01</property>
-    <property name="page_increment">0.01</property>
-    <property name="page_size">0.01</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment2">
-    <property name="value">20</property>
-    <property name="upper">110</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">1</property>
-    <property name="page_size">1</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment3">
-    <property name="value">50</property>
-    <property name="upper">110</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-    <property name="page_size">10</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment4">
-    <property name="value">50</property>
-    <property name="upper">110</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-    <property name="page_size">10</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment5">
-    <property name="value">50</property>
-    <property name="upper">110</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-    <property name="page_size">10</property>
-  </object>
-  <object class="GtkListStore" id="model1">
-    <columns>
-      <!-- column-name gchararray -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">[ automatic ]</col>
-      </row>
-    </data>
-  </object>
-  <object class="GtkDialog" id="dialog_options">
+  <widget class="GtkDialog" id="dialog_options">
     <property name="width_request">500</property>
     <property name="height_request">400</property>
     <property name="border_width">5</property>
-    <property name="title" translatable="yes">Ear Candy - Audio Clients</property>
+    <property name="title" translatable="yes">Ear Candy</property>
     <property name="window_position">center-on-parent</property>
     <property name="type_hint">dialog</property>
     <property name="has_separator">False</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+      <widget class="GtkVBox" id="dialog-vbox1">
         <property name="visible">True</property>
         <property name="spacing">2</property>
         <child>
-          <object class="GtkNotebook" id="notebook1">
+          <widget class="GtkNotebook" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <child>
-              <object class="GtkVBox" id="vbox1">
+              <widget class="GtkVBox" id="vbox1">
                 <property name="visible">True</property>
                 <child>
-                  <placeholder/>
+                  <widget class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkToolbar" id="toolbar1">
+                        <property name="visible">True</property>
+                        <property name="toolbar_style">both</property>
+                        <child>
+                          <widget class="GtkToolButton" id="toolbutton_add">
+                            <property name="visible">True</property>
+                            <property name="stock_id">gtk-add</property>
+                            <signal name="clicked" handler="on_button_add_new_clicked"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkToolButton" id="toolbutton_edit">
+                            <property name="visible">True</property>
+                            <property name="use_underline">True</property>
+                            <property name="stock_id">gtk-edit</property>
+                            <signal name="clicked" handler="on_toolbutton_edit_clicked" after="yes"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkToolButton" id="toolbutton_delete">
+                            <property name="visible">True</property>
+                            <property name="stock_id">gtk-delete</property>
+                            <signal name="clicked" handler="on_toolbutton_delete_clicked"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
                 </child>
                 <child>
-                  <object class="GtkHBox" id="hbox3">
+                  <widget class="GtkHBox" id="hbox3">
                     <property name="visible">True</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="scrolledwindow1">
+                      <widget class="GtkScrolledWindow" id="scrolledwindow1">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="hscrollbar_policy">automatic</property>
+                        <property name="vscrollbar_policy">automatic</property>
                         <property name="shadow_type">etched-in</property>
                         <child>
-                          <object class="GtkViewport" id="viewport1">
+                          <widget class="GtkTreeView" id="treeview_pulse_clients">
                             <property name="visible">True</property>
-                            <property name="resize_mode">queue</property>
-                            <property name="shadow_type">none</property>
-                            <child>
-                              <object class="GtkVBox" id="vbox_repeater">
-                                <property name="visible">True</property>
-                                <property name="orientation">vertical</property>
-                                <child>
-                                  <placeholder/>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
+                            <property name="can_focus">True</property>
+                            <property name="headers_clickable">False</property>
+                            <signal name="cursor_changed" handler="on_treeview_pulse_clients_cursor_changed"/>
+                            <signal name="row_activated" handler="on_treeview_pulse_clients_row_activated"/>
+                          </widget>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
                         <property name="padding">4</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
-                  </object>
+                  </widget>
                   <packing>
                     <property name="padding">4</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
-              </object>
+                <child>
+                  <widget class="GtkHBox" id="hbox5">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment1">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="xscale">0</property>
+                        <child>
+                          <widget class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Display :</property>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="padding">4</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkComboBox" id="combobox_view">
+                        <property name="visible">True</property>
+                        <property name="active">0</property>
+                        <property name="items" translatable="yes">Only active rules
+All rules</property>
+                        <signal name="changed" handler="on_combobox_view_changed"/>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="padding">4</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">4</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label2">
+            <child>
+              <widget class="GtkLabel" id="label2">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes">Applications</property>
-              </object>
+                <property name="label" translatable="yes">Application Rules</property>
+              </widget>
               <packing>
-                <property name="position">1</property>
                 <property name="tab_fill">False</property>
+                <property name="type">tab</property>
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox2">
+              <widget class="GtkHBox" id="hbox2">
                 <property name="visible">True</property>
                 <child>
-                  <object class="GtkTable" id="table3">
+                  <widget class="GtkTable" id="table3">
                     <property name="visible">True</property>
-                    <property name="n_rows">11</property>
+                    <property name="n_rows">7</property>
                     <property name="n_columns">2</property>
                     <child>
-                      <object class="GtkAlignment" id="alignment6">
+                      <widget class="GtkAlignment" id="alignment6">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
                         <property name="xscale">0</property>
                         <child>
-                          <object class="GtkCheckButton" id="checkbutton_tray">
+                          <widget class="GtkCheckButton" id="checkbutton_tray">
                             <property name="label" translatable="yes">Show Icon</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="draw_indicator">True</property>
                             <signal name="toggled" handler="on_checkbutton_tray_toggled"/>
-                          </object>
+                          </widget>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHScale" id="hscale_fade">
+                      <widget class="GtkLabel" id="label10">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="adjustment">adjustment1</property>
-                        <property name="inverted">True</property>
-                        <property name="digits">2</property>
-                        <property name="draw_value">False</property>
-                        <property name="value_pos">right</property>
-                        <signal name="value_changed" handler="on_hscale_fade_value_changed"/>
-                      </object>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Notification Tray</property>
+                      </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
                         <property name="top_attach">2</property>
                         <property name="bottom_attach">3</property>
+                        <property name="x_options"></property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHScale" id="hscale_mute_level">
-                        <property name="can_focus">True</property>
-                        <property name="adjustment">adjustment2</property>
-                        <property name="digits">0</property>
-                        <property name="value_pos">right</property>
-                        <signal name="value_changed" handler="on_hscale_mute_level_value_changed"/>
-                        <signal name="change_value" handler="on_hscale_mute_level_change_value"/>
-                      </object>
+                      <widget class="GtkLabel" id="label6">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Volume Fade Speed</property>
+                      </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
+                        <property name="x_options"></property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="checkbutton_autostart">
-                        <property name="label" translatable="yes">Start on login</property>
+                      <widget class="GtkHScale" id="hscale_fade">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="on_checkbutton_autostart_toggled"/>
-                      </object>
+                        <property name="adjustment">0.01 0.01 0.20000000000000001 0.01 0.01 0.01</property>
+                        <property name="inverted">True</property>
+                        <property name="digits">2</property>
+                        <property name="draw_value">False</property>
+                        <property name="value_pos">right</property>
+                        <signal name="value_changed" handler="on_hscale_fade_value_changed"/>
+                      </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">6</property>
-                        <property name="bottom_attach">7</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="checkbutton_mute_phone">
-                        <property name="label" translatable="yes">Include 'phone' category when muting</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="on_checkbutton_mute_phone_toggled"/>
-                      </object>
+                      <widget class="GtkLabel" id="label9">
+                        <property name="label" translatable="yes">Partial Mute Level</property>
+                      </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options"></property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkExpander" id="expander1">
+                      <widget class="GtkHScale" id="hscale_mute_level">
                         <property name="can_focus">True</property>
-                        <child>
-                          <object class="GtkScrolledWindow" id="scrolledwindow2">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="border_width">4</property>
-                            <property name="hscrollbar_policy">automatic</property>
-                            <property name="vscrollbar_policy">automatic</property>
-                            <property name="shadow_type">etched-in</property>
-                            <child>
-                              <object class="GtkTreeView" id="treeview_plugins">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel" id="label13">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Application control plugins</property>
-                          </object>
-                        </child>
-                      </object>
+                        <property name="adjustment">20 0 110 1 1 1</property>
+                        <property name="digits">0</property>
+                        <property name="value_pos">right</property>
+                        <signal name="value_changed" handler="on_hscale_mute_level_value_changed"/>
+                        <signal name="change_value" handler="on_hscale_mute_level_change_value"/>
+                      </widget>
                       <packing>
+                        <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">9</property>
-                        <property name="bottom_attach">10</property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkAlignment" id="alignment5">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xscale">0</property>
-                        <child>
-                          <object class="GtkLabel" id="label6">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Cross Fade Speed</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment7">
+                      <widget class="GtkLabel" id="label11">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xscale">0</property>
-                        <child>
-                          <object class="GtkLabel" id="label9">
-                            <property name="label" translatable="yes">Partial Mute Level</property>
-                          </object>
-                        </child>
-                      </object>
+                        <property name="label" translatable="yes">Output Device</property>
+                      </widget>
                       <packing>
                         <property name="top_attach">3</property>
                         <property name="bottom_attach">4</property>
+                        <property name="x_options"></property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment8">
+                      <widget class="GtkAlignment" id="alignment7">
+                        <property name="visible">True</property>
                         <property name="xalign">0</property>
                         <property name="xscale">0</property>
                         <child>
-                          <object class="GtkLabel" id="label5">
+                          <widget class="GtkCheckButton" id="checkbutton_output">
+                            <property name="label" translatable="yes">Move streams to new output (USB Headsets)</property>
                             <property name="visible">True</property>
-                            <property name="xalign">0.49000000953674316</property>
-                            <property name="label" translatable="yes">Mute</property>
-                          </object>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="on_checkbutton_output_toggled"/>
+                          </widget>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment9">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xscale">0</property>
-                        <child>
-                          <object class="GtkLabel" id="label10">
-                            <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">Notification Tray</property>
-                          </object>
-                        </child>
-                      </object>
+                      <widget class="GtkLabel" id="label15">
+                        <property name="label" translatable="yes">Reset volume</property>
+                      </widget>
                       <packing>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
+                        <property name="top_attach">6</property>
+                        <property name="bottom_attach">7</property>
+                        <property name="x_options"></property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment10">
-                        <property name="visible">True</property>
+                      <widget class="GtkAlignment" id="alignment3">
                         <property name="xalign">0</property>
                         <property name="xscale">0</property>
                         <child>
-                          <object class="GtkLabel" id="label4">
+                          <widget class="GtkButton" id="button_reset">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">Autostart</property>
-                          </object>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <signal name="clicked" handler="on_button_reset_clicked"/>
+                            <child>
+                              <widget class="GtkHBox" id="hbox4">
+                                <property name="visible">True</property>
+                                <child>
+                                  <widget class="GtkImage" id="image1">
+                                    <property name="visible">True</property>
+                                    <property name="stock">gtk-refresh</property>
+                                    <property name="icon-size">2</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="padding">4</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label17">
+                                    <property name="visible">True</property>
+                                    <property name="label" translatable="yes">Reset all volume levels</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="padding">4</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
                         <property name="top_attach">6</property>
                         <property name="bottom_attach">7</property>
                         <property name="y_options"></property>
@@ -366,173 +375,121 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkFrame" id="frame1">
-                        <property name="label_xalign">0</property>
-                        <child>
-                          <object class="GtkTable" id="table1">
-                            <property name="visible">True</property>
-                            <child>
-                              <object class="GtkScrolledWindow" id="scrolledwindow3">
-                                <property name="height_request">50</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="hscrollbar_policy">automatic</property>
-                                <property name="shadow_type">etched-in</property>
-                                <child>
-                                  <object class="GtkTreeView" id="treeview_outputs">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="headers_visible">False</property>
-                                    <property name="reorderable">True</property>
-                                    <signal name="drag_end" handler="on_treeview_outputs_drag_drop"/>
-                                  </object>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="x_padding">8</property>
-                                <property name="y_padding">8</property>
-                              </packing>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel" id="label3">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes"> Output Devices  </property>
-                            <property name="use_markup">True</property>
-                          </object>
-                        </child>
-                      </object>
+                      <widget class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Autostart</property>
+                      </widget>
                       <packing>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">10</property>
-                        <property name="bottom_attach">11</property>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
+                        <property name="x_options"></property>
+                        <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="button1">
-                        <property name="label">gtk-revert-to-saved</property>
+                      <widget class="GtkCheckButton" id="checkbutton_autostart">
+                        <property name="label" translatable="yes">Start on login</property>
+                        <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="clicked" handler="on_button_reset_clicked"/>
-                      </object>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="on_checkbutton_autostart_toggled"/>
+                      </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">7</property>
-                        <property name="bottom_attach">8</property>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment1">
-                        <property name="xalign">0</property>
-                        <property name="xscale">0</property>
+                      <widget class="GtkVBox" id="vbox2">
+                        <property name="visible">True</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="label7">
-                            <property name="label" translatable="yes">Restore defaults</property>
-                          </object>
+                          <widget class="GtkHSeparator" id="hseparator1"/>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="padding">4</property>
+                            <property name="position">0</property>
+                          </packing>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
-                        <property name="top_attach">7</property>
-                        <property name="bottom_attach">8</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">5</property>
+                        <property name="bottom_attach">6</property>
                         <property name="y_options"></property>
                         <property name="x_padding">4</property>
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
+                  </widget>
                   <packing>
                     <property name="padding">4</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="position">1</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label1">
+            <child>
+              <widget class="GtkLabel" id="label1">
                 <property name="visible">True</property>
                 <property name="label" translatable="yes">Advanced</property>
-              </object>
+              </widget>
               <packing>
                 <property name="position">1</property>
                 <property name="tab_fill">False</property>
+                <property name="type">tab</property>
               </packing>
             </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child type="tab">
-              <placeholder/>
-            </child>
-          </object>
+          </widget>
           <packing>
             <property name="position">1</property>
           </packing>
         </child>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
             <property name="visible">True</property>
             <property name="layout_style">end</property>
             <child>
               <placeholder/>
             </child>
             <child>
-              <object class="GtkButton" id="button_close">
-                <property name="label">gtk-close</property>
+              <widget class="GtkButton" id="button_close">
+                <property name="label" translatable="yes">gtk-close</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
                 <signal name="clicked" handler="on_close_button_clicked"/>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
-          </object>
+          </widget>
           <packing>
             <property name="expand">False</property>
             <property name="pack_type">end</property>
             <property name="position">0</property>
           </packing>
         </child>
-      </object>
+      </widget>
     </child>
-    <action-widgets>
-      <action-widget response="0">button_close</action-widget>
-    </action-widgets>
-  </object>
-  <object class="GtkDialog" id="dialog_select">
+  </widget>
+  <widget class="GtkDialog" id="dialog_select">
     <property name="border_width">5</property>
     <property name="title" translatable="yes">Select PulseAudio Stream</property>
     <property name="modal">True</property>
@@ -540,25 +497,25 @@
     <property name="type_hint">dialog</property>
     <property name="has_separator">False</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox2">
+      <widget class="GtkVBox" id="dialog-vbox2">
         <property name="visible">True</property>
         <property name="spacing">2</property>
         <child>
-          <object class="GtkVBox" id="vbox3">
+          <widget class="GtkVBox" id="vbox3">
             <property name="visible">True</property>
             <child>
-              <object class="GtkAlignment" id="alignment3">
+              <widget class="GtkAlignment" id="alignment3">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="xscale">0</property>
                 <child>
-                  <object class="GtkLabel" id="label16">
+                  <widget class="GtkLabel" id="label16">
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">&lt;b&gt;1) Select pulseaudio client&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
-                  </object>
+                  </widget>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -567,9 +524,10 @@
               </packing>
             </child>
             <child>
-              <object class="GtkComboBox" id="combobox_clients">
+              <widget class="GtkComboBox" id="combobox_clients">
                 <property name="visible">True</property>
-              </object>
+                <property name="items" translatable="yes"></property>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -577,11 +535,11 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="label14">
+              <widget class="GtkLabel" id="label14">
                 <property name="visible">True</property>
                 <property name="label" translatable="yes">&lt;i&gt;For a client to show here it must have played a sound at least once&lt;/i&gt;</property>
                 <property name="use_markup">True</property>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -590,18 +548,18 @@
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="alignment4">
+              <widget class="GtkAlignment" id="alignment4">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="xscale">0</property>
                 <child>
-                  <object class="GtkLabel" id="label400">
+                  <widget class="GtkLabel" id="label4">
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">&lt;b&gt;2) Select application&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
-                  </object>
+                  </widget>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -610,30 +568,30 @@
               </packing>
             </child>
             <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow200">
+              <widget class="GtkScrolledWindow" id="scrolledwindow2">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="hscrollbar_policy">automatic</property>
                 <property name="vscrollbar_policy">automatic</property>
                 <property name="shadow_type">etched-in</property>
                 <child>
-                  <object class="GtkTreeView" id="treeview_applications">
+                  <widget class="GtkTreeView" id="treeview_applications">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="headers_visible">False</property>
-                  </object>
+                  </widget>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="position">4</property>
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="label8">
+              <widget class="GtkLabel" id="label8">
                 <property name="visible">True</property>
                 <property name="label" translatable="yes">&lt;i&gt;For an application to show here it must be open&lt;/i&gt;</property>
                 <property name="use_markup">True</property>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -642,18 +600,18 @@
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="alignment500">
+              <widget class="GtkAlignment" id="alignment5">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="xscale">0</property>
                 <child>
-                  <object class="GtkLabel" id="label500">
+                  <widget class="GtkLabel" id="label5">
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">&lt;b&gt;3) Select category&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
-                  </object>
+                  </widget>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -662,34 +620,35 @@
               </packing>
             </child>
             <child>
-              <object class="GtkComboBox" id="combobox_category">
+              <widget class="GtkComboBox" id="combobox_category">
                 <property name="visible">True</property>
-              </object>
+                <property name="items" translatable="yes"></property>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
                 <property name="position">7</property>
               </packing>
             </child>
-          </object>
+          </widget>
           <packing>
             <property name="padding">4</property>
             <property name="position">1</property>
           </packing>
         </child>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area2">
+          <widget class="GtkHButtonBox" id="dialog-action_area2">
             <property name="visible">True</property>
             <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="button_cancel">
-                <property name="label">gtk-cancel</property>
+              <widget class="GtkButton" id="button_cancel">
+                <property name="label" translatable="yes">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
                 <signal name="clicked" handler="on_button_cancel_clicked"/>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -697,35 +656,31 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="button_add">
-                <property name="label">gtk-add</property>
+              <widget class="GtkButton" id="button_add">
+                <property name="label" translatable="yes">gtk-add</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
                 <signal name="clicked" handler="on_button_add_clicked"/>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
-          </object>
+          </widget>
           <packing>
             <property name="expand">False</property>
             <property name="pack_type">end</property>
             <property name="position">0</property>
           </packing>
         </child>
-      </object>
+      </widget>
     </child>
-    <action-widgets>
-      <action-widget response="0">button_cancel</action-widget>
-      <action-widget response="0">button_add</action-widget>
-    </action-widgets>
-  </object>
-  <object class="GtkWindow" id="popup_volume_control">
+  </widget>
+  <widget class="GtkWindow" id="popup_volume_control">
     <property name="height_request">150</property>
     <property name="can_focus">True</property>
     <property name="has_focus">True</property>
@@ -739,400 +694,345 @@
     <property name="window_position">center-on-parent</property>
     <property name="type_hint">popup-menu</property>
     <child>
-      <object class="GtkHBox" id="hbox4">
+      <widget class="GtkHBox" id="hbox4">
         <property name="visible">True</property>
         <child>
-          <object class="GtkVBox" id="vbox5">
+          <widget class="GtkVBox" id="vbox5">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
             <child>
-              <object class="GtkButton" id="button_mute">
+              <widget class="GtkButton" id="button_suspend">
                 <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="tooltip_text" translatable="yes">Mute sound</property>
-                <signal name="clicked" handler="on_button_mute_clicked"/>
-                <child>
-                  <object class="GtkImage" id="image_mute">
-                    <property name="visible">True</property>
-                    <property name="icon_name">audio-volume-muted</property>
-                    <property name="icon-size">2</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="padding">4</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button_suspend">
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="tooltip_text" translatable="yes">Lock volume levels</property>
+                <property name="tooltip" translatable="yes">Lock volume levels</property>
                 <signal name="clicked" handler="on_button_suspend_clicked"/>
                 <child>
-                  <object class="GtkImage" id="image_status">
+                  <widget class="GtkImage" id="image_status">
                     <property name="visible">True</property>
                     <property name="stock">gtk-media-pause</property>
                     <property name="icon-size">2</property>
-                  </object>
+                  </widget>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="padding">4</property>
-                <property name="position">1</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVScale" id="vscale_volume">
+              <widget class="GtkVScale" id="vscale_volume">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="orientation">vertical</property>
-                <property name="adjustment">adjustment3</property>
+                <property name="adjustment">50 0 110 1 10 10</property>
                 <property name="inverted">True</property>
                 <property name="digits">0</property>
                 <property name="draw_value">False</property>
                 <property name="value_pos">bottom</property>
                 <signal name="value_changed" handler="on_vscale_volume_value_changed"/>
                 <signal name="change_value" handler="on_vscale_volume_change_value"/>
-              </object>
+              </widget>
               <packing>
                 <property name="padding">4</property>
-                <property name="position">2</property>
+                <property name="position">1</property>
               </packing>
             </child>
-          </object>
+          </widget>
           <packing>
             <property name="expand">False</property>
             <property name="padding">4</property>
             <property name="position">0</property>
           </packing>
         </child>
-      </object>
+      </widget>
     </child>
-  </object>
-  <object class="GtkWindow" id="window_client_properties">
+  </widget>
+  <widget class="GtkWindow" id="window_client_properties">
     <property name="resizable">False</property>
     <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
     <property name="destroy_with_parent">True</property>
     <property name="type_hint">dialog</property>
     <child>
-      <object class="GtkHBox" id="hbox1">
+      <widget class="GtkHBox" id="hbox1">
         <property name="visible">True</property>
         <child>
-          <object class="GtkVBox" id="vbox100">
+          <widget class="GtkVBox" id="vbox1">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
             <child>
-              <object class="GtkVBox" id="vbox300">
+              <widget class="GtkHBox" id="hbox2">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkHBox" id="hbox200">
+                  <widget class="GtkImage" id="image_icon">
                     <property name="visible">True</property>
-                    <child>
-                      <object class="GtkImage" id="image_icon">
-                        <property name="visible">True</property>
-                        <property name="stock">gtk-directory</property>
-                        <property name="icon-size">6</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="padding">4</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">&lt;big&gt;Banshee&lt;/big&gt;</property>
-                        <property name="use_markup">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="padding">4</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
+                    <property name="stock">gtk-directory</property>
+                    <property name="icon-size">6</property>
+                  </widget>
                   <packing>
-                    <property name="fill">False</property>
+                    <property name="expand">False</property>
                     <property name="padding">4</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkTable" id="table100">
+                  <widget class="GtkLabel" id="label_name">
                     <property name="visible">True</property>
-                    <property name="n_rows">7</property>
-                    <property name="n_columns">2</property>
-                    <child>
-                      <object class="GtkLabel" id="label_description">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Description</property>
-                      </object>
-                      <packing>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name2">
-                        <property name="label" translatable="yes">Category</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">3</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="combobox_category0"/>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="entry_description">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="invisible_char">&#x25CF;</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkCheckButton" id="checkbutton_fix">
-                        <property name="label" translatable="yes">Use volume meter detection</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name3">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Activity</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">3</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name4">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Fade</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">3</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkCheckButton" id="checkbutton_fade_volume">
-                        <property name="label" translatable="yes">Fade volume</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="xalign">0.56999999284744263</property>
-                        <property name="draw_indicator">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label60">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Output Device</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="combobox_output">
-                        <property name="visible">True</property>
-                        <property name="model">model1</property>
-                        <property name="active">0</property>
-                        <child>
-                          <object class="GtkCellRendererText" id="renderer1"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name1">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Max</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHScale" id="hscale_max_volume">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="adjustment">adjustment4</property>
-                        <property name="digits">0</property>
-                        <property name="value_pos">left</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">5</property>
-                        <property name="bottom_attach">6</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_name5">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Min</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">6</property>
-                        <property name="bottom_attach">7</property>
-                        <property name="x_options"></property>
-                        <property name="y_options"></property>
-                        <property name="x_padding">4</property>
-                        <property name="y_padding">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHScale" id="hscale_min_volume">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="adjustment">adjustment5</property>
-                        <property name="digits">0</property>
-                        <property name="value_pos">left</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">6</property>
-                        <property name="bottom_attach">7</property>
-                      </packing>
-                    </child>
-                  </object>
+                    <property name="label" translatable="yes">&lt;big&gt;Banshee&lt;/big&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
+                    <property name="padding">4</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
-              </object>
+              </widget>
               <packing>
-                <property name="expand">False</property>
                 <property name="fill">False</property>
+                <property name="padding">4</property>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <placeholder/>
+              <widget class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">7</property>
+                <property name="n_columns">2</property>
+                <child>
+                  <widget class="GtkLabel" id="label_description">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Description</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label_name1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Max Volume</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHScale" id="hscale_max_volume">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="adjustment">100 0 110 1 10 10</property>
+                    <property name="digits">0</property>
+                    <property name="value_pos">left</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label_name2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Category</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">3</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkComboBox" id="combobox_category">
+                    <property name="visible">True</property>
+                    <property name="items" translatable="yes"></property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="entry_description">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="checkbutton_fix">
+                    <property name="label" translatable="yes">Use volume meter detection</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label_name3">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Fix</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">3</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label_name4">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Fade</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">6</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">3</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="checkbutton_fade_volume">
+                    <property name="label" translatable="yes">Fade volume</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="xalign">0.56999999284744263</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">6</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="label" translatable="yes">Output</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">6</property>
+                    <property name="bottom_attach">7</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkComboBox" id="combobox_output">
+                    <property name="active">0</property>
+                    <property name="items" translatable="yes">[ automatic ]</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">6</property>
+                    <property name="bottom_attach">7</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">4</property>
+                    <property name="y_padding">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
             </child>
             <child>
-              <object class="GtkExpander" id="expander10">
+              <widget class="GtkExpander" id="expander1">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <child>
-                  <object class="GtkVBox" id="vbox2">
+                  <widget class="GtkVBox" id="vbox2">
                     <property name="visible">True</property>
                     <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkLabel" id="label50">
+                      <widget class="GtkLabel" id="label5">
                         <property name="visible">True</property>
                         <property name="label" translatable="yes">&lt;b&gt;Do not edit these values
  unless you know what you are doing&lt;/b&gt;</property>
                         <property name="use_markup">True</property>
                         <property name="justify">center</property>
-                      </object>
+                      </widget>
                       <packing>
                         <property name="padding">4</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkTable" id="table2">
+                      <widget class="GtkTable" id="table2">
                         <property name="visible">True</property>
                         <property name="n_rows">4</property>
                         <property name="n_columns">2</property>
                         <child>
-                          <object class="GtkLabel" id="label20">
+                          <widget class="GtkLabel" id="label2">
                             <property name="visible">True</property>
                             <property name="label" translatable="yes">Window Title</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="x_options"></property>
                             <property name="y_options"></property>
@@ -1141,11 +1041,11 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="entry_window_title">
+                          <widget class="GtkEntry" id="entry_window_title">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="invisible_char">&#x25CF;</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
@@ -1155,10 +1055,10 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label30">
+                          <widget class="GtkLabel" id="label3">
                             <property name="visible">True</property>
                             <property name="label" translatable="yes">Command</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="top_attach">1</property>
                             <property name="bottom_attach">2</property>
@@ -1169,10 +1069,10 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label40">
+                          <widget class="GtkLabel" id="label4">
                             <property name="visible">True</property>
                             <property name="label" translatable="yes">Application</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="top_attach">2</property>
                             <property name="bottom_attach">3</property>
@@ -1183,11 +1083,11 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="entry_command">
+                          <widget class="GtkEntry" id="entry_command">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="invisible_char">&#x25CF;</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
@@ -1199,11 +1099,11 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="entry_application">
+                          <widget class="GtkEntry" id="entry_application">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="invisible_char">&#x25CF;</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
@@ -1215,10 +1115,10 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label_description1">
+                          <widget class="GtkLabel" id="label_description1">
                             <property name="visible">True</property>
                             <property name="label" translatable="yes">Client Name</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="top_attach">3</property>
                             <property name="bottom_attach">4</property>
@@ -1229,11 +1129,11 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="entry_name">
+                          <widget class="GtkEntry" id="entry_name">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="invisible_char">&#x25CF;</property>
-                          </object>
+                          </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
@@ -1244,20 +1144,23 @@
                             <property name="y_padding">4</property>
                           </packing>
                         </child>
-                      </object>
+                      </widget>
                       <packing>
                         <property name="position">2</property>
                       </packing>
                     </child>
-                  </object>
+                  </widget>
                 </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label101">
+                <child>
+                  <widget class="GtkLabel" id="label1">
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">Advanced client matching rules</property>
-                  </object>
+                  </widget>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="padding">4</property>
@@ -1265,46 +1168,46 @@
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox303">
+              <widget class="GtkHBox" id="hbox3">
                 <property name="visible">True</property>
                 <child>
-                  <object class="GtkAlignment" id="alignment2">
+                  <widget class="GtkAlignment" id="alignment2">
                     <property name="visible">True</property>
                     <property name="xalign">1</property>
                     <property name="yalign">1</property>
                     <property name="xscale">0</property>
                     <child>
-                      <object class="GtkButton" id="button_close01">
-                        <property name="label">gtk-close</property>
+                      <widget class="GtkButton" id="button_close">
+                        <property name="label" translatable="yes">gtk-close</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
                         <property name="use_stock">True</property>
                         <signal name="clicked" handler="on_button_close_clicked"/>
                         <signal name="activate" handler="on_button_close_activate"/>
-                      </object>
+                      </widget>
                     </child>
-                  </object>
+                  </widget>
                   <packing>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkAlignment" id="alignment101">
+                  <widget class="GtkAlignment" id="alignment1">
                     <property name="visible">True</property>
                     <property name="xalign">1</property>
                     <property name="xscale">0</property>
                     <child>
-                      <object class="GtkButton" id="button_apply">
-                        <property name="label">gtk-apply</property>
+                      <widget class="GtkButton" id="button_apply">
+                        <property name="label" translatable="yes">gtk-apply</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
                         <property name="use_stock">True</property>
                         <signal name="clicked" handler="on_button_apply_clicked"/>
-                      </object>
+                      </widget>
                     </child>
-                  </object>
+                  </widget>
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
@@ -1312,7 +1215,7 @@
                     <property name="position">2</property>
                   </packing>
                 </child>
-              </object>
+              </widget>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
@@ -1320,108 +1223,13 @@
                 <property name="position">3</property>
               </packing>
             </child>
-          </object>
+          </widget>
           <packing>
             <property name="padding">4</property>
             <property name="position">0</property>
           </packing>
         </child>
-      </object>
-    </child>
-  </object>
-  <object class="GtkWindow" id="window_client_holder">
-    <child>
-      <object class="GtkTable" id="table_clients">
-        <property name="visible">True</property>
-        <property name="n_rows">2</property>
-        <property name="n_columns">4</property>
-        <property name="column_spacing">2</property>
-        <property name="row_spacing">2</property>
-        <child>
-          <object class="GtkImage" id="image_client_icon">
-            <property name="width_request">32</property>
-            <property name="visible">True</property>
-            <property name="stock">gtk-media-play</property>
-            <property name="icon-size">3</property>
-          </object>
-          <packing>
-            <property name="bottom_attach">2</property>
-            <property name="x_options"></property>
-            <property name="x_padding">4</property>
-            <property name="y_padding">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkProgressBar" id="progressbar_meter">
-            <property name="height_request">4</property>
-            <property name="visible">True</property>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">4</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="y_options"></property>
-            <property name="x_padding">4</property>
-            <property name="y_padding">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkComboBox" id="combobox_role">
-            <property name="visible">True</property>
-          </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="right_attach">3</property>
-            <property name="x_options"></property>
-            <property name="y_options"></property>
-            <property name="x_padding">4</property>
-            <property name="y_padding">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="button_client">
-            <property name="label" translatable="yes">Edit</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="relief">half</property>
-            <signal name="clicked" handler="on_button_client_clicked"/>
-          </object>
-          <packing>
-            <property name="left_attach">3</property>
-            <property name="right_attach">4</property>
-            <property name="x_options"></property>
-            <property name="y_options"></property>
-            <property name="x_padding">4</property>
-            <property name="y_padding">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkAlignment" id="alignment303">
-            <property name="visible">True</property>
-            <property name="xalign">0</property>
-            <child>
-              <object class="GtkLabel" id="label_client_name">
-                <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="label" translatable="yes">label</property>
-                <property name="ellipsize">end</property>
-                <attributes>
-                  <attribute name="gravity" value="west"/>
-                </attributes>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="y_options"></property>
-            <property name="x_padding">4</property>
-            <property name="y_padding">4</property>
-          </packing>
-        </child>
-      </object>
+      </widget>
     </child>
-  </object>
-</interface>
+  </widget>
+</glade-interface>
diff --git a/data/defaults/settings.xml b/files/settings.xml
similarity index 96%
rename from data/defaults/settings.xml
rename to files/settings.xml
index a4ab937..1c449ce 100644
--- a/data/defaults/settings.xml
+++ b/files/settings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-    <earcandy fade_timer_speed="0.015" follow_new_outputs="True" tray_visible="True" version="0.6">
+    <earcandy fade_timer_speed="0.1" follow_new_outputs="True" tray_visible="True" version="0.5">
     <rules>
     <rule apply_volume_meter_hack="True" category="music" description="File Manager" fade_volume="True" icon_name="system-file-manager" name="totem-audio-preview" rule_re_application="nautilus" rule_re_command=".*\/nautilus" rule_re_window_title="" volume_default="100" volume_mute="-1" window_position_fade="True" />
     <rule apply_volume_meter_hack="True" category="video" description="Totem Movie Player" fade_volume="True" icon_name="totem" name="Totem Movie Player" rule_re_application="totem movie player" rule_re_command=".*\/totem movie player" rule_re_window_title="" volume_default="100" volume_mute="-1" window_position_fade="True"/>
diff --git a/po/earcandy.pot b/po/earcandy.pot
deleted file mode 100644
index 4434017..0000000
--- a/po/earcandy.pot
+++ /dev/null
@@ -1,219 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-04-15 22:38+1200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../data/ui/EarcandyWindow.ui.h:1
-msgid "Earcandy"
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:2
-msgid "Status Area"
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:3
-msgid ""
-"Your application has been created!\n"
-"\n"
-"To start changing this user interface, run 'quickly glade', which will open "
-"Glade so you can edit the default windows and dialogs.\n"
-"\n"
-"To change the behavior and edit the python code, run 'quickly edit', which "
-"will bring up a text editor."
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:8
-msgid "_Edit"
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:9
-msgid "_File"
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:10
-msgid "_Help"
-msgstr ""
-
-#: ../data/ui/EarcandyWindow.ui.h:11
-msgid "_View"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:1
-msgid " Output Devices  "
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:2
-msgid "<b>1) Select pulseaudio client</b>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:3
-msgid "<b>2) Select application</b>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:4
-msgid "<b>3) Select category</b>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:5
-msgid ""
-"<b>Do not edit these values\n"
-" unless you know what you are doing</b>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:7
-msgid "<big>Banshee</big>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:8
-msgid ""
-"<i>For a client to show here it must have played a sound at least once</i>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:9
-msgid "<i>For an application to show here it must be open</i>"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:10
-msgid "Activity"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:11
-msgid "Advanced"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:12
-msgid "Advanced client matching rules"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:13
-msgid "Application"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:14
-msgid "Application control plugins"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:15
-msgid "Applications"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:16
-msgid "Autostart"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:17
-msgid "Category"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:18
-msgid "Client Name"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:19
-msgid "Command"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:20
-msgid "Cross Fade Speed"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:21
-msgid "Description"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:22
-msgid "Ear Candy - Audio Clients"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:23
-msgid "Edit"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:24
-msgid "Fade"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:25
-msgid "Fade volume"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:26
-msgid "Include 'phone' category when muting"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:27
-msgid "Lock volume levels"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:28
-msgid "Max"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:29
-msgid "Min"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:30
-msgid "Mute"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:31
-msgid "Mute sound"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:32
-msgid "Notification Tray"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:33
-msgid "Output Device"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:34
-msgid "Partial Mute Level"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:35
-msgid "Restore defaults"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:36
-msgid "Select PulseAudio Stream"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:37
-msgid "Show Icon"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:38
-msgid "Start on login"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:39
-msgid "Use volume meter detection"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:40
-msgid "Window Title"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:41
-msgid "[ automatic ]"
-msgstr ""
-
-#: ../data/ui/EarCandy.ui.h:42
-msgid "label"
-msgstr ""
diff --git a/earcandy/Sink.py b/runner/ear_candy
old mode 100644
new mode 100755
similarity index 64%
rename from earcandy/Sink.py
rename to runner/ear_candy
index 340b392..7faf7a4
--- a/earcandy/Sink.py
+++ b/runner/ear_candy
@@ -1,5 +1,6 @@
+#!/usr/bin/env python
 # Ear Candy - Pulseaduio sound managment tool
-# Copyright (C) 2008 Jason Taylor
+# Copyright (C) 2008 Jason Taylor, Michael Budde
 # 
 # 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
@@ -13,20 +14,10 @@
 # 
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
+import ear_candy
+import subprocess
+import os, sys
 
-import math  
-import time
-import datetime 
-         
-class Sink():
-    def __init__(self, name, priority=0, index=0):
-
-        self.name = name
-        self.priority = priority
-
-        
-        self.index = index
-        self.monitor_source = 0
-        self.monitor_source_name = ""
-        self.description = name
-        self.volume = None
+if __name__ == "__main__":
+    path = os.path.join(os.path.dirname(ear_candy.__file__), "ear_candy.py")
+    subprocess.call([sys.executable, path] + sys.argv[1:])
diff --git a/setup.py b/setup.py
index 81fdc9b..f6a61a2 100644
--- a/setup.py
+++ b/setup.py
@@ -1,94 +1,47 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
-### BEGIN LICENSE
-# This file is in the public domain
-### END LICENSE
-
-###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ######################
-
-try:
-    import DistUtilsExtra.auto
-except ImportError:
-    import sys
-    print >> sys.stderr, 'To build earcandy you need https://launchpad.net/python-distutils-extra'
-    sys.exit(1)
-
-assert DistUtilsExtra.auto.__version__ >= '2.10', 'needs DistUtilsExtra.auto >= 2.10'
-import os
-
-
-def update_data_path(prefix, oldvalue=None):
-
-    try:
-        fin = file('earcandy/earcandyconfig.py', 'r')
-        fout = file(fin.name + '.new', 'w')
-
-        for line in fin:            
-            fields = line.split(' = ') # Separate variable from value
-            if fields[0] == '__earcandy_data_directory__':
-                # update to prefix, store oldvalue
-                if not oldvalue:
-                    oldvalue = fields[1]
-                    line = "%s = '%s'\n" % (fields[0], prefix)
-                else: # restore oldvalue
-                    line = "%s = %s" % (fields[0], oldvalue)
-            fout.write(line)
-
-        fout.flush()
-        fout.close()
-        fin.close()
-        os.rename(fout.name, fin.name)
-    except (OSError, IOError), e:
-        print ("ERROR: Can't find earcandy/earcandyconfig.py")
-        sys.exit(1)
-    return oldvalue
-
-
-def update_desktop_file(datadir):
-
-    try:
-        fin = file('earcandy.desktop.in', 'r')
-        fout = file(fin.name + '.new', 'w')
-
-        for line in fin:            
-            if 'Icon=' in line:
-                line = "Icon=%s\n" % (datadir + 'media/icon.png')
-            fout.write(line)
-        fout.flush()
-        fout.close()
-        fin.close()
-        os.rename(fout.name, fin.name)
-    except (OSError, IOError), e:
-        print ("ERROR: Can't find earcandy.desktop.in")
-        sys.exit(1)
-
-
-class InstallAndUpdateDataDirectory(DistUtilsExtra.auto.install_auto):
-    def run(self):
-        if self.root or self.home:
-            print "WARNING: You don't use a standard --prefix installation, take care that you eventually " \
-            "need to update quickly/quicklyconfig.py file to adjust __quickly_data_directory__. You can " \
-            "ignore this warning if you are packaging and uses --prefix."
-        previous_value = update_data_path(self.prefix + '/share/earcandy/')
-        update_desktop_file(self.prefix + '/share/earcandy/')
-        DistUtilsExtra.auto.install_auto.run(self)
-        update_data_path(self.prefix, previous_value)
-
-
-        
-##################################################################################
-###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ######################
-##################################################################################
-
-DistUtilsExtra.auto.setup(
-    name='earcandy',
-    version='0.9',
-    license='GPL v2',
-    author='Jason Taylor',
-    author_email='killerkiwi2005 at gmail.com',
-    description='Automatic pulseaudio volume control',
-    long_description='A sound level manager that nicely fades applications in and out based on their media role and window focus',
-    url='https://launchpad.net/earcandy',
-    cmdclass={'install': InstallAndUpdateDataDirectory}
-    )
-
+# author: David D Lowe
+# year: 2009
+# this file has been released into the public domain
+
+from distutils.core import setup
+import os, sys
+import glob
+
+
+def main():
+    
+    data_files = glob.glob("files/*")  # data_files a list of strings
+    # of the relative paths of all non-py files that should be included
+    # ex: data_files is ['files/pulseoptions.glade', 'settings.xml', ...]
+    
+    setup( name="earcandy", # this should start with a lowercase letter 
+        #so that it can be used as a debian package name later on
+    version="0.4", # string, version of your program, not python version
+    description="A sound level manager that nicely fades applications in and out based on their profile and window focus", # short
+    author="KillerKiwi",
+    author_email="killerkiwi2005 at gmail.com",
+    url="https://launchpad.net/earcandy", # home page for end-users
+    license="unknown",
+    packages=["ear_candy", "ear_candy.pulseaudio", "ear_candy.window"], # python packages, not debian packages
+    data_files=[('share/earcandy', data_files),
+      ('/usr/share/applications', ['files/earcandy.desktop']),
+      ('/usr/share/pixmaps', ['files/earsLabel.png'])], # data_files is a list of tuples
+            # each tuple contaning an installation path and a list of data files
+    scripts=["runner/ear_candy"], # the script that should be run and installed in /usr/bin
+    classifiers=["Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", "License :: unknown", "Operating System :: POSIX :: Linux"],
+        # a bunch of optional tags, a list of classifiers can be found at http://pypi.python.org/pypi?:action=list_classifiers
+    long_description="""A sound level manager that nicely fades applications in and out based on there profile and window focus
+
+What works now :
+ - All volume adjustments are fades
+ - Fade out music/video players on skype call
+ - Fade to music player with focus when more than one
+ - Fade out music player when video playing
+ - Push sound to USB headsets on plugin
+ - Categories to assign to clients
+ - Sniffs desktop files to guess application category ... music/video/VoIP
+ - Simplified pref UI for creating rules
+ - Volume sniffing to fix youtube video issue""")
+
+if __name__ == "__main__":
+    main()  

-- 
earcandy packaging



More information about the pkg-multimedia-commits mailing list