[Goodies-commits] r6300 - in sion: . trunk trunk/po trunk/src

Enrico Troeger enrico at xfce.org
Sat Dec 13 17:33:35 CET 2008


Author: enrico
Date: 2008-12-13 16:33:35 +0000 (Sat, 13 Dec 2008)
New Revision: 6300

Added:
   sion/branches/
   sion/tags/
   sion/trunk/
   sion/trunk/AUTHORS
   sion/trunk/COPYING
   sion/trunk/ChangeLog
   sion/trunk/INSTALL
   sion/trunk/Makefile
   sion/trunk/NEWS
   sion/trunk/README
   sion/trunk/README.I18N
   sion/trunk/TODO
   sion/trunk/autogen.sh
   sion/trunk/configure
   sion/trunk/po/
   sion/trunk/po/ChangeLog
   sion/trunk/po/LINGUAS
   sion/trunk/po/POTFILES.in
   sion/trunk/po/POTFILES.skip
   sion/trunk/po/de.po
   sion/trunk/po/sion.pot
   sion/trunk/sion.1.in
   sion/trunk/sion.desktop.in
   sion/trunk/src/
   sion/trunk/src/Makefile
   sion/trunk/src/backendgvfs.c
   sion/trunk/src/backendgvfs.h
   sion/trunk/src/bookmark.c
   sion/trunk/src/bookmark.h
   sion/trunk/src/bookmarkdialog.c
   sion/trunk/src/bookmarkdialog.h
   sion/trunk/src/bookmarkeditdialog.c
   sion/trunk/src/bookmarkeditdialog.h
   sion/trunk/src/common.c
   sion/trunk/src/common.h
   sion/trunk/src/compat.c
   sion/trunk/src/compat.h
   sion/trunk/src/main.c
   sion/trunk/src/main.h
   sion/trunk/src/menubuttonaction.c
   sion/trunk/src/menubuttonaction.h
   sion/trunk/src/passworddialog.c
   sion/trunk/src/passworddialog.h
   sion/trunk/src/preferencesdialog.c
   sion/trunk/src/preferencesdialog.h
   sion/trunk/src/settings.c
   sion/trunk/src/settings.h
   sion/trunk/src/window.c
   sion/trunk/src/window.h
   sion/trunk/waf
   sion/trunk/wscript
Log:
Add layout and code for Sion.

Added: sion/trunk/AUTHORS
===================================================================
--- sion/trunk/AUTHORS	                        (rev 0)
+++ sion/trunk/AUTHORS	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1 @@
+Enrico Tröger <enrico at xfce.org>

Added: sion/trunk/COPYING
===================================================================
--- sion/trunk/COPYING	                        (rev 0)
+++ sion/trunk/COPYING	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,340 @@
+		    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.

Added: sion/trunk/INSTALL
===================================================================
--- sion/trunk/INSTALL	                        (rev 0)
+++ sion/trunk/INSTALL	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1 @@
+For basic installation instructions please see the file README.

Added: sion/trunk/Makefile
===================================================================
--- sion/trunk/Makefile	                        (rev 0)
+++ sion/trunk/Makefile	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,46 @@
+#!/usr/bin/make -f
+# Waf Makefile wrapper
+WAF_HOME=/home/enrico/projects/sion
+
+all:
+	@/home/enrico/projects/sion/waf build
+
+all-debug:
+	@/home/enrico/projects/sion/waf -v build
+
+all-progress:
+	@/home/enrico/projects/sion/waf -p build
+
+install:
+	if test -n "$(DESTDIR)"; then \
+		/home/enrico/projects/sion/waf install --yes --destdir="$(DESTDIR)" --prefix="/usr/local"; \
+	else \
+		/home/enrico/projects/sion/waf install --yes --prefix="/usr/local"; \
+	fi;
+
+uninstall:
+	@if test -n "$(DESTDIR)"; then \
+		/home/enrico/projects/sion/waf uninstall --destdir="$(DESTDIR)" --prefix="/usr/local"; \
+	else \
+		/home/enrico/projects/sion/waf uninstall --prefix="/usr/local"; \
+	fi;
+
+clean:
+	@/home/enrico/projects/sion/waf clean
+
+distclean:
+	@/home/enrico/projects/sion/waf distclean
+	@-rm -rf _build_
+	@-rm -f Makefile
+
+distcheck:
+	@/home/enrico/projects/sion/waf distcheck
+
+dist:
+	@/home/enrico/projects/sion/waf dist
+
+sign:
+	@/home/enrico/projects/sion/waf --sign
+
+.PHONY: clean dist distclean check uninstall install all
+


Property changes on: sion/trunk/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: sion/trunk/README
===================================================================
--- sion/trunk/README	                        (rev 0)
+++ sion/trunk/README	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,71 @@
+Sion
+^^^^
+
+
+About
+=====
+Sion is a frontend to easily manage connections to remote filesystems using
+GIO/GVFS. It allows you to quickly connect/mount a remote filesystem and manage
+bookmarks of such.
+
+
+Requirements
+============
+For compiling Sion, you will need the GTK (>= 2.12.0) libraries
+and header files. You will also need its dependency libraries and header
+files, such as Pango, Cairo, Glib and ATK. All these files are available at
+http://www.gtk.org.
+You also need Python for the included Waf build system.
+
+Furthermore you need, of course, a C compiler as well as the intltool package.
+
+
+Installation
+============
+If you have all the above listed requirements on your system installed,
+building the code is easy:
+
+Run the following commands::
+
+    $ ./waf configure
+    $ ./waf build
+    (maybe as root)
+    % ./waf install
+
+To get a list of available options to customize your build, enable debugging
+or to use a different installation prefix, run::
+
+    $ ./waf help
+
+
+Usage
+=====
+You can start Sion in the following ways:
+
+* From the Desktop Environment menu:
+
+  Choose in your application menu of your used Desktop Environment:
+  System --> Sion.
+
+* From the command line:
+
+  To start Sion from a command line, type the following and press Return::
+
+      % sion
+
+* To get a list of available command line options, run::
+
+      % sion --help
+
+
+License
+=======
+Sion is distributed under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2 of the license.
+A copy of this license can be found in the file COPYING included with
+the source code of this program.
+
+
+Ideas, questions, patches and bug reports
+=========================================
+Send them to me at enrico(at)xfce(dot)org.

Added: sion/trunk/README.I18N
===================================================================
--- sion/trunk/README.I18N	                        (rev 0)
+++ sion/trunk/README.I18N	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,33 @@
+Quick Guide for new translations
+--------------------------------
+
+If you want to translate Sion into another language, please check
+whether a translation for your language already exists (check the
+po/ subdirectory.
+Get the SVN version of Sion, change to the po directory and
+start the new translation with:
+
+$ msginit -l ll_CC -o ll.po -i sion.pot
+
+Fill in ll with the language code and CC with the country code.
+For example, to translate Sion into Italian you would type:
+
+$ msginit -l it_IT -o it.po -i sion.pot
+
+This will create a file it.po. This file can be opened with a
+text editor or you can also use a graphical interface.
+I can suggest PoEdit (http://www.poedit.net/), but there are
+several other GUIs.
+
+Make sure you add your language to the file po/LINGUAS.
+Just open the file with a text editor and add your code.
+
+When you have finished editing the file, check the file with:
+
+$ msgfmt -c --check-accelerators=_ it.po
+
+Please take care of menu accelerators(strings containing a "_").
+The "_" character should also be in your translation. Additionally,
+it would be nice if these accelerators are not twice for two strings
+inside a dialog or sub menu.
+

Added: sion/trunk/TODO
===================================================================
--- sion/trunk/TODO	                        (rev 0)
+++ sion/trunk/TODO	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,6 @@
+- better program icon
+- libnotify - to notify about new mounts or disappeared mounts (ftp timeout, etc.)
+- progressdialog when mounting
+- display pseudo names instead of URI schemes
+- change default file manager command to gvfs-open
+- allow usernames which include a '@' char

Added: sion/trunk/autogen.sh
===================================================================
--- sion/trunk/autogen.sh	                        (rev 0)
+++ sion/trunk/autogen.sh	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+
+./configure "$@"


Property changes on: sion/trunk/autogen.sh
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/configure
===================================================================
--- sion/trunk/configure	                        (rev 0)
+++ sion/trunk/configure	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,177 @@
+#!/bin/sh
+
+# waf configure wrapper
+
+# Fancy colors used to beautify the output a bit.
+#
+if [ "$NOCOLOR" ] ; then
+    NORMAL=""
+    BOLD=""
+    RED=""
+    YELLOW=""
+    GREEN=""
+else
+    NORMAL="\\x1b[0m"
+    BOLD="\\x1b[01;1m"
+    RED="\\x1b[01;91m"
+    YELLOW="\\x1b[33m"
+    GREEN="\\x1b[32m"
+fi
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_ERROR=2
+EXIT_BUG=10
+
+CUR_DIR=$PWD
+
+#possible relative path
+WORKINGDIR=`dirname $0`
+cd $WORKINGDIR
+#abs path
+WORKINGDIR=`pwd`
+cd $CUR_DIR
+
+
+# Checks for Python interpreter. Honours $PYTHON if set. Stores path to
+# interpreter in $PYTHON.
+#
+checkPython()
+{
+	if [ -z "$PYTHON" ] ; then
+		PYTHON=`which python 2>/dev/null`
+	fi
+	printf "Checking for Python\t\t\t:  "
+	if [ ! -x "$PYTHON" ] ; then
+		printf $RED"not found!"$NORMAL"\n"
+		echo "Please make sure that the Python interpreter is available in your PATH"
+		echo "or invoke configure using the PYTHON flag, e.g."
+		echo "$ PYTHON=/usr/local/bin/python configure"
+		exit $EXIT_FAILURE
+	fi
+	printf $GREEN"$PYTHON"$NORMAL"\n"
+}
+
+# Checks for WAF. Honours $WAF if set. Stores path to 'waf' in $WAF.
+# Requires that $PYTHON is set.
+#
+checkWAF()
+{
+	printf "Checking for WAF\t\t\t:  "
+	#installed miniwaf in sourcedir
+	if [ -z "$WAF" ] ; then
+		if [ -f "${WORKINGDIR}/waf" ] ; then
+			WAF="${WORKINGDIR}/waf"
+			if [ ! -x "$WAF" ] ; then
+				chmod +x $WAF
+			fi
+		fi
+	fi
+	if [ -z "$WAF" ] ; then
+		if [ -f "${WORKINGDIR}/waf-light" ] ; then
+			${WORKINGDIR}/waf-light --make-waf
+			WAF="${WORKINGDIR}/waf"
+		fi
+	fi
+	#global installed waf with waf->waf.py link
+	if [ -z "$WAF" ] ; then
+		WAF=`which waf 2>/dev/null`
+	fi
+	# neither waf nor miniwaf could be found
+	if [ ! -x "$WAF" ] ; then
+		printf $RED"not found"$NORMAL"\n"
+		echo "Go to http://code.google.com/p/waf/"
+		echo "and download a waf version"
+		exit $EXIT_FAILURE
+	else
+		printf $GREEN"$WAF"$NORMAL"\n"
+	fi
+}
+
+# Generates a Makefile. Requires that $WAF is set.
+#
+generateMakefile()
+{
+	cat > Makefile << EOF
+#!/usr/bin/make -f
+# Waf Makefile wrapper
+WAF_HOME=$CUR_DIR
+
+all:
+	@$WAF build
+
+all-debug:
+	@$WAF -v build
+
+all-progress:
+	@$WAF -p build
+
+install:
+	if test -n "\$(DESTDIR)"; then \\
+		$WAF install --yes --destdir="\$(DESTDIR)" --prefix="$PREFIX"; \\
+	else \\
+		$WAF install --yes --prefix="$PREFIX"; \\
+	fi;
+
+uninstall:
+	@if test -n "\$(DESTDIR)"; then \\
+		$WAF uninstall --destdir="\$(DESTDIR)" --prefix="$PREFIX"; \\
+	else \\
+		$WAF uninstall --prefix="$PREFIX"; \\
+	fi;
+
+clean:
+	@$WAF clean
+
+distclean:
+	@$WAF distclean
+	@-rm -rf _build_
+	@-rm -f Makefile
+
+distcheck:
+	@$WAF distcheck
+
+dist:
+	@$WAF dist
+
+sign:
+	@$WAF --sign
+
+.PHONY: clean dist distclean check uninstall install all
+
+EOF
+
+	cat > src/Makefile << EOF
+#!/usr/bin/make -f
+# Waf Makefile wrapper
+WAF_HOME=$CUR_DIR
+
+all:
+	cd .. && $WAF build
+
+all-debug:
+	cd .. && $WAF -v build
+
+clean:
+	cd .. && $WAF clean
+
+EOF
+}
+
+checkPython
+checkWAF
+
+PREFIX=/usr/local
+case $1 in
+    --prefix)
+        PREFIX=$2
+        ;;
+esac
+
+export PREFIX
+generateMakefile
+
+
+"${WAF}" configure --prefix "${PREFIX}"
+
+exit $?


Property changes on: sion/trunk/configure
___________________________________________________________________
Added: svn:executable
   + *

Added: sion/trunk/po/ChangeLog
===================================================================
--- sion/trunk/po/ChangeLog	                        (rev 0)
+++ sion/trunk/po/ChangeLog	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1 @@
+

Added: sion/trunk/po/LINGUAS
===================================================================
--- sion/trunk/po/LINGUAS	                        (rev 0)
+++ sion/trunk/po/LINGUAS	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,2 @@
+# set of available languages (in alphabetic order)
+de

Added: sion/trunk/po/POTFILES.in
===================================================================
--- sion/trunk/po/POTFILES.in	                        (rev 0)
+++ sion/trunk/po/POTFILES.in	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,15 @@
+# List of source files containing translatable strings.
+
+src/main.c
+src/compat.c
+src/common.c
+src/window.c
+src/bookmark.c
+src/settings.c
+src/menubuttonaction.c
+src/passworddialog.c
+src/bookmarkdialog.c
+src/bookmarkeditdialog.c
+src/preferencesdialog.c
+src/backendgvfs.c
+sion.desktop.in

Added: sion/trunk/po/POTFILES.skip
===================================================================
--- sion/trunk/po/POTFILES.skip	                        (rev 0)
+++ sion/trunk/po/POTFILES.skip	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,4 @@
+# List of source files containing translatable strings but should be ignored.
+
+# sion.desktop.in will be translated
+sion.desktop.in

Added: sion/trunk/po/de.po
===================================================================
--- sion/trunk/po/de.po	                        (rev 0)
+++ sion/trunk/po/de.po	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,330 @@
+# German translations for Sion.
+# Copyright (C) 2008 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Enrico Tröger <enrico at xfce.org>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sion 0.0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-12-12 18:57+0100\n"
+"PO-Revision-Date: 2008-11-30 19:17+0100\n"
+"Last-Translator: Enrico Tröger <enrico at xfce.org>\n"
+"Language-Team: German <xfce-i18n at xfce.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/main.c:41
+msgid "Print a list of supported URI schemes"
+msgstr ""
+
+#: ../src/main.c:42
+msgid "Be verbose"
+msgstr "ausführliche Meldungen"
+
+#: ../src/main.c:43
+msgid "Show version information"
+msgstr "Zeige Versionsinformationen"
+
+#: ../src/main.c:97
+msgid "- a simple frontend to easily connect to remote filesystems"
+msgstr ""
+
+#: ../src/window.c:171
+msgid "Error"
+msgstr ""
+
+#: ../src/window.c:439
+msgid "Non-local mountpoints can't be opened."
+msgstr ""
+
+#: ../src/window.c:440
+msgid "(not yet implemented)"
+msgstr "Noch nicht implementiert."
+
+#: ../src/window.c:884
+msgid "_File"
+msgstr "_Datei"
+
+#: ../src/window.c:885
+msgid "_Edit"
+msgstr "_Bearbeiten"
+
+#: ../src/window.c:886
+msgid "_Actions"
+msgstr "_Aktionen"
+
+#: ../src/window.c:887
+msgid "_Help"
+msgstr "_Hilfe"
+
+#: ../src/window.c:891
+msgid "Create _Bookmark"
+msgstr "Lesezeichen _erstellen"
+
+#: ../src/window.c:893
+msgid "_Edit Bookmarks"
+msgstr "Lesezeichen _bearbeiten"
+
+#: ../src/window.c:904
+msgid "_Bookmarks"
+msgstr "_Lesezeichen"
+
+#: ../src/window.c:904
+msgid "Choose a bookmark to connect to"
+msgstr ""
+
+#: ../src/window.c:953
+msgid "Mounted"
+msgstr ""
+
+#: ../src/window.c:961 ../src/bookmarkdialog.c:306
+msgid "URI Scheme"
+msgstr ""
+
+#: ../src/window.c:969 ../src/bookmarkdialog.c:298
+msgid "Name"
+msgstr "Name"
+
+#: ../src/window.c:1031 ../src/window.c:1105 ../sion.desktop.in.h:2
+msgid "Sion"
+msgstr "Sion"
+
+#: ../src/menubuttonaction.c:183
+#, fuzzy
+msgid "Connect"
+msgstr "_Verbinden"
+
+#: ../src/passworddialog.c:105
+msgid "Authentication information needed"
+msgstr ""
+
+#: ../src/passworddialog.c:127
+msgid "_Domain:"
+msgstr "_Domäne:"
+
+#: ../src/passworddialog.c:138
+msgid "_Username:"
+msgstr "_Benutzername:"
+
+#: ../src/passworddialog.c:150
+msgid "_Password:"
+msgstr "_Passwort:"
+
+#: ../src/bookmarkdialog.c:314
+msgid "Host"
+msgstr "Host"
+
+#: ../src/bookmarkdialog.c:322
+msgid "Port"
+msgstr "Port"
+
+#: ../src/bookmarkdialog.c:330
+msgid "Username"
+msgstr "Benutzername"
+
+#: ../src/bookmarkdialog.c:387
+msgid "Edit Bookmarks"
+msgstr "Lesezeichen bearbeiten"
+
+#: ../src/bookmarkeditdialog.c:104
+msgid "FTP"
+msgstr "FTP"
+
+#: ../src/bookmarkeditdialog.c:105
+msgid "SSH"
+msgstr "SSH"
+
+#: ../src/bookmarkeditdialog.c:106
+msgid "Windows share"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:107
+msgid "Secure WebDAV (HTTPS)"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:108
+msgid "WebDAV (HTTP)"
+msgstr ""
+
+#. must always be the last item
+#: ../src/bookmarkeditdialog.c:110
+msgid "Custom Location"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:513
+msgid "Create Bookmark"
+msgstr "Lesezeichen erstellen"
+
+#: ../src/bookmarkeditdialog.c:520
+msgid "Edit Bookmark"
+msgstr "Lesezeichen bearbeiten"
+
+#: ../src/bookmarkeditdialog.c:528
+msgid "Connect to Server"
+msgstr "Verbinde zum Server"
+
+#: ../src/bookmarkeditdialog.c:581
+msgid "_Bookmark name:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:589
+msgid "Service _type:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:612
+msgid "Set the port to 0 to use the default port."
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:615
+msgid "_Location (URI):"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:616
+msgid "_Server:"
+msgstr "_Server:"
+
+#: ../src/bookmarkeditdialog.c:617
+msgid "_User Name:"
+msgstr "_Benutzername:"
+
+#: ../src/bookmarkeditdialog.c:618
+msgid "Optional information:"
+msgstr "Optionale Informationen:"
+
+#: ../src/bookmarkeditdialog.c:619
+msgid "_Port:"
+msgstr "_Port:"
+
+#: ../src/preferencesdialog.c:182
+msgid "Icons"
+msgstr "Symbole"
+
+#: ../src/preferencesdialog.c:183
+msgid "Text"
+msgstr "Text"
+
+#: ../src/preferencesdialog.c:184
+msgid "Both"
+msgstr "Beides"
+
+#: ../src/preferencesdialog.c:185
+msgid "Both horizontal"
+msgstr "Beides horizontal"
+
+#: ../src/preferencesdialog.c:204
+msgid "Horizontal"
+msgstr "Horizontal"
+
+#: ../src/preferencesdialog.c:205
+msgid "Vertical"
+msgstr "Vertikal"
+
+#: ../src/preferencesdialog.c:224
+msgid "Symbols"
+msgstr ""
+
+#: ../src/preferencesdialog.c:225
+msgid "Detailed"
+msgstr ""
+
+#: ../src/preferencesdialog.c:332
+msgid "General"
+msgstr "Allgemeines"
+
+#: ../src/preferencesdialog.c:342
+msgid "Use _HAL based volume manager"
+msgstr ""
+
+#. / TODO fix this string to be more descriptive and clear
+#: ../src/preferencesdialog.c:344 ../src/preferencesdialog.c:352
+msgid ""
+"This option sets the implementation of the volume manager. In general, this "
+"should be left to HAL. Please note, this option requires a restart of Sion."
+msgstr ""
+
+#: ../src/preferencesdialog.c:351
+msgid "Use _Unix based volume manager"
+msgstr ""
+
+#: ../src/preferencesdialog.c:365
+msgid "_File Manager"
+msgstr "_Dateimanager"
+
+#: ../src/preferencesdialog.c:373
+msgid "Enter the name of a program to use to open or view mount points"
+msgstr ""
+
+#: ../src/preferencesdialog.c:379
+msgid "Interface"
+msgstr "Oberfläche"
+
+#: ../src/preferencesdialog.c:389
+msgid "_Save window position and geometry"
+msgstr "_Fensterposition und -größe speichern"
+
+#: ../src/preferencesdialog.c:390
+msgid "Saves the window position and geometry and restores it at the start"
+msgstr ""
+
+#: ../src/preferencesdialog.c:393
+msgid "Show tray _icon"
+msgstr "_Symbol in der Systemleiste anzeigen"
+
+#: ../src/preferencesdialog.c:396
+msgid "Show _toolbar"
+msgstr "_Werkzeugleiste anzeigen"
+
+#: ../src/preferencesdialog.c:402
+msgid "Toolbar St_yle"
+msgstr "Werk_zeugleistenstil"
+
+#: ../src/preferencesdialog.c:413
+msgid "Toolbar _Orientation"
+msgstr "_Ausrichtung der Werkzeugleiste"
+
+#: ../src/preferencesdialog.c:424
+msgid "_View Mode"
+msgstr ""
+
+#: ../src/preferencesdialog.c:484
+msgid "Preferences"
+msgstr "Einstellungen"
+
+#: ../src/backendgvfs.c:191
+#, c-format
+msgid ""
+"<b>%s</b>\n"
+"\n"
+"URI: %s\n"
+"Mounted: Yes\n"
+"Type: %s"
+msgstr ""
+
+#: ../src/backendgvfs.c:204
+#, c-format
+msgid "<b>Unix device: %s</b>"
+msgstr ""
+
+#: ../src/backendgvfs.c:381 ../src/backendgvfs.c:412
+msgid "unknown"
+msgstr "unbekannt"
+
+#: ../src/backendgvfs.c:385 ../src/backendgvfs.c:464
+#, c-format
+msgid "Mounting of \"%s\" failed."
+msgstr ""
+
+#: ../src/backendgvfs.c:416
+#, c-format
+msgid "Unmounting of \"%s\" failed."
+msgstr ""
+
+#: ../sion.desktop.in.h:1
+msgid "A simple frontend to easily connect to remote filesystems"
+msgstr ""
+
+#~ msgid "<b>Bookmarks</b>"
+#~ msgstr "<b>Lesezeichen</b>"

Added: sion/trunk/po/sion.pot
===================================================================
--- sion/trunk/po/sion.pot	                        (rev 0)
+++ sion/trunk/po/sion.pot	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,326 @@
+# 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: 2008-12-12 18:57+0100\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"
+
+#: ../src/main.c:41
+msgid "Print a list of supported URI schemes"
+msgstr ""
+
+#: ../src/main.c:42
+msgid "Be verbose"
+msgstr ""
+
+#: ../src/main.c:43
+msgid "Show version information"
+msgstr ""
+
+#: ../src/main.c:97
+msgid "- a simple frontend to easily connect to remote filesystems"
+msgstr ""
+
+#: ../src/window.c:171
+msgid "Error"
+msgstr ""
+
+#: ../src/window.c:439
+msgid "Non-local mountpoints can't be opened."
+msgstr ""
+
+#: ../src/window.c:440
+msgid "(not yet implemented)"
+msgstr ""
+
+#: ../src/window.c:884
+msgid "_File"
+msgstr ""
+
+#: ../src/window.c:885
+msgid "_Edit"
+msgstr ""
+
+#: ../src/window.c:886
+msgid "_Actions"
+msgstr ""
+
+#: ../src/window.c:887
+msgid "_Help"
+msgstr ""
+
+#: ../src/window.c:891
+msgid "Create _Bookmark"
+msgstr ""
+
+#: ../src/window.c:893
+msgid "_Edit Bookmarks"
+msgstr ""
+
+#: ../src/window.c:904
+msgid "_Bookmarks"
+msgstr ""
+
+#: ../src/window.c:904
+msgid "Choose a bookmark to connect to"
+msgstr ""
+
+#: ../src/window.c:953
+msgid "Mounted"
+msgstr ""
+
+#: ../src/window.c:961 ../src/bookmarkdialog.c:306
+msgid "URI Scheme"
+msgstr ""
+
+#: ../src/window.c:969 ../src/bookmarkdialog.c:298
+msgid "Name"
+msgstr ""
+
+#: ../src/window.c:1031 ../src/window.c:1105 ../sion.desktop.in.h:2
+msgid "Sion"
+msgstr ""
+
+#: ../src/menubuttonaction.c:183
+msgid "Connect"
+msgstr ""
+
+#: ../src/passworddialog.c:105
+msgid "Authentication information needed"
+msgstr ""
+
+#: ../src/passworddialog.c:127
+msgid "_Domain:"
+msgstr ""
+
+#: ../src/passworddialog.c:138
+msgid "_Username:"
+msgstr ""
+
+#: ../src/passworddialog.c:150
+msgid "_Password:"
+msgstr ""
+
+#: ../src/bookmarkdialog.c:314
+msgid "Host"
+msgstr ""
+
+#: ../src/bookmarkdialog.c:322
+msgid "Port"
+msgstr ""
+
+#: ../src/bookmarkdialog.c:330
+msgid "Username"
+msgstr ""
+
+#: ../src/bookmarkdialog.c:387
+msgid "Edit Bookmarks"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:104
+msgid "FTP"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:105
+msgid "SSH"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:106
+msgid "Windows share"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:107
+msgid "Secure WebDAV (HTTPS)"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:108
+msgid "WebDAV (HTTP)"
+msgstr ""
+
+#. must always be the last item
+#: ../src/bookmarkeditdialog.c:110
+msgid "Custom Location"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:513
+msgid "Create Bookmark"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:520
+msgid "Edit Bookmark"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:528
+msgid "Connect to Server"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:581
+msgid "_Bookmark name:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:589
+msgid "Service _type:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:612
+msgid "Set the port to 0 to use the default port."
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:615
+msgid "_Location (URI):"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:616
+msgid "_Server:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:617
+msgid "_User Name:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:618
+msgid "Optional information:"
+msgstr ""
+
+#: ../src/bookmarkeditdialog.c:619
+msgid "_Port:"
+msgstr ""
+
+#: ../src/preferencesdialog.c:182
+msgid "Icons"
+msgstr ""
+
+#: ../src/preferencesdialog.c:183
+msgid "Text"
+msgstr ""
+
+#: ../src/preferencesdialog.c:184
+msgid "Both"
+msgstr ""
+
+#: ../src/preferencesdialog.c:185
+msgid "Both horizontal"
+msgstr ""
+
+#: ../src/preferencesdialog.c:204
+msgid "Horizontal"
+msgstr ""
+
+#: ../src/preferencesdialog.c:205
+msgid "Vertical"
+msgstr ""
+
+#: ../src/preferencesdialog.c:224
+msgid "Symbols"
+msgstr ""
+
+#: ../src/preferencesdialog.c:225
+msgid "Detailed"
+msgstr ""
+
+#: ../src/preferencesdialog.c:332
+msgid "General"
+msgstr ""
+
+#: ../src/preferencesdialog.c:342
+msgid "Use _HAL based volume manager"
+msgstr ""
+
+#. / TODO fix this string to be more descriptive and clear
+#: ../src/preferencesdialog.c:344 ../src/preferencesdialog.c:352
+msgid ""
+"This option sets the implementation of the volume manager. In general, this "
+"should be left to HAL. Please note, this option requires a restart of Sion."
+msgstr ""
+
+#: ../src/preferencesdialog.c:351
+msgid "Use _Unix based volume manager"
+msgstr ""
+
+#: ../src/preferencesdialog.c:365
+msgid "_File Manager"
+msgstr ""
+
+#: ../src/preferencesdialog.c:373
+msgid "Enter the name of a program to use to open or view mount points"
+msgstr ""
+
+#: ../src/preferencesdialog.c:379
+msgid "Interface"
+msgstr ""
+
+#: ../src/preferencesdialog.c:389
+msgid "_Save window position and geometry"
+msgstr ""
+
+#: ../src/preferencesdialog.c:390
+msgid "Saves the window position and geometry and restores it at the start"
+msgstr ""
+
+#: ../src/preferencesdialog.c:393
+msgid "Show tray _icon"
+msgstr ""
+
+#: ../src/preferencesdialog.c:396
+msgid "Show _toolbar"
+msgstr ""
+
+#: ../src/preferencesdialog.c:402
+msgid "Toolbar St_yle"
+msgstr ""
+
+#: ../src/preferencesdialog.c:413
+msgid "Toolbar _Orientation"
+msgstr ""
+
+#: ../src/preferencesdialog.c:424
+msgid "_View Mode"
+msgstr ""
+
+#: ../src/preferencesdialog.c:484
+msgid "Preferences"
+msgstr ""
+
+#: ../src/backendgvfs.c:191
+#, c-format
+msgid ""
+"<b>%s</b>\n"
+"\n"
+"URI: %s\n"
+"Mounted: Yes\n"
+"Type: %s"
+msgstr ""
+
+#: ../src/backendgvfs.c:204
+#, c-format
+msgid "<b>Unix device: %s</b>"
+msgstr ""
+
+#: ../src/backendgvfs.c:381 ../src/backendgvfs.c:412
+msgid "unknown"
+msgstr ""
+
+#: ../src/backendgvfs.c:385 ../src/backendgvfs.c:464
+#, c-format
+msgid "Mounting of \"%s\" failed."
+msgstr ""
+
+#: ../src/backendgvfs.c:416
+#, c-format
+msgid "Unmounting of \"%s\" failed."
+msgstr ""
+
+#: ../sion.desktop.in.h:1
+msgid "A simple frontend to easily connect to remote filesystems"
+msgstr ""

Added: sion/trunk/sion.1.in
===================================================================
--- sion/trunk/sion.1.in	                        (rev 0)
+++ sion/trunk/sion.1.in	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,32 @@
+.TH "SION" "1" "" "sion @VERSION@" ""
+.SH "NAME"
+sion \(em a simple frontend to easily connect to remote filesystems with GIO/GVFS
+.SH "SYNOPSIS"
+.PP
+\fBsion\fR [\fBoption\fP]
+.SH "DESCRIPTION"
+.PP
+Sion is a frontend to easily manage connections to remote filesystems using
+GIO/GVFS. It allows you to quickly mount a remote filesystem and manage
+bookmarks to such.
+.PP
+Homepage: http://write me
+.SH "OPTIONS"
+If called without any arguments, the sion main window is shown.
+.IP "\fB-l\fP, \fB\-\-list-schemes\fP         " 10
+Print a list of supported URI schemes and exit.
+.IP "\fB-v\fP, \fB\-\-verbose\fP         " 10
+Be verbose and print some more information to stdout.
+.IP "\fB-V\fP, \fB\-\-version\fP         " 10
+Show version information.
+.IP "\fB-?\fP, \fB\-\-help\fP         " 10
+Show help information and exit.
+.PP
+Sion supports all generic GTK options, a list is available on the help screen.
+.SH "AUTHOR"
+.PP
+This manual page was written by Enrico Troeger. Permission is granted to copy,
+distribute and/or modify this document under the terms of the GNU General
+Public License, Version 2.
+A copy of this license can be found in the file COPYING included with the
+source code of this program.

Added: sion/trunk/sion.desktop.in
===================================================================
--- sion/trunk/sion.desktop.in	                        (rev 0)
+++ sion/trunk/sion.desktop.in	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Type=Application
+Version=1.0
+_Name=Sion
+_GenericName=Sion
+_Comment=A simple frontend to easily connect to remote filesystems
+Exec=sion
+Icon=gtk-network
+Terminal=false
+Categories=System;GTK;Filesystem;
+StartupNotify=true

Added: sion/trunk/src/Makefile
===================================================================
--- sion/trunk/src/Makefile	                        (rev 0)
+++ sion/trunk/src/Makefile	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,13 @@
+#!/usr/bin/make -f
+# Waf Makefile wrapper
+WAF_HOME=/home/enrico/projects/sion
+
+all:
+	cd .. && /home/enrico/projects/sion/waf build
+
+all-debug:
+	cd .. && /home/enrico/projects/sion/waf -v build
+
+clean:
+	cd .. && /home/enrico/projects/sion/waf clean
+


Property changes on: sion/trunk/src/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: sion/trunk/src/backendgvfs.c
===================================================================
--- sion/trunk/src/backendgvfs.c	                        (rev 0)
+++ sion/trunk/src/backendgvfs.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,540 @@
+/*
+ *      backendgvfs.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "backendgvfs.h"
+#include "passworddialog.h"
+#include "main.h"
+
+typedef struct _SionBackendGVFSPrivate			SionBackendGVFSPrivate;
+
+#define SION_BACKEND_GVFS_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_BACKEND_GVFS_TYPE, SionBackendGVFSPrivate))
+
+enum
+{
+    PROP_0,
+    PROP_STORE
+};
+
+enum
+{
+	MOUNTS_CHANGED,
+	OPERATION_FAILED,
+
+	LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL];
+
+
+struct _SionBackendGVFSPrivate
+{
+	GtkListStore *store;
+};
+
+static void sion_backend_gvfs_class_init			(SionBackendGVFSClass *klass);
+static void sion_backend_gvfs_init      			(SionBackendGVFS *self);
+static void sion_backend_gvfs_finalize  			(GObject *object);
+static void sion_backend_gvfs_set_property			(GObject *object, guint prop_id,
+													 const GValue *value, GParamSpec *pspec);
+
+
+static GObjectClass *parent_class = NULL;
+
+GType sion_backend_gvfs_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionBackendGVFSClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_backend_gvfs_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionBackendGVFS),
+			0,
+			(GInstanceInitFunc)sion_backend_gvfs_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(G_TYPE_OBJECT, "SionBackendGVFS", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void sion_backend_gvfs_cclosure_marshal_VOID__STRING_STRING(
+											GClosure		*closure,
+											GValue			*return_value,
+											guint			 n_param_values,
+											const GValue	*param_values,
+											gpointer		 invocation_hint,
+											gpointer		 marshal_data)
+{
+	typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer		 data1,
+													  const gchar	*arg_1,
+													  const gchar	*arg_2,
+													  gpointer		 data2);
+	register GMarshalFunc_VOID__STRING_STRING callback;
+	register GCClosure* cc = (GCClosure*) closure;
+	register gpointer data1, data2;
+
+	g_return_if_fail(n_param_values == 3);
+
+	if (G_CCLOSURE_SWAP_DATA(closure))
+	{
+		data1 = closure->data;
+		data2 = g_value_peek_pointer(param_values + 0);
+	}
+	else
+	{
+		data1 = g_value_peek_pointer(param_values + 0);
+		data2 = closure->data;
+	}
+	callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
+	callback(
+		data1,
+		g_value_get_string(param_values + 1),
+		g_value_get_string(param_values + 2),
+		data2);
+}
+
+
+static void sion_backend_gvfs_class_init(SionBackendGVFSClass *klass)
+{
+	GObjectClass *g_object_class;
+
+	g_object_class = G_OBJECT_CLASS(klass);
+
+	g_object_class->finalize = sion_backend_gvfs_finalize;
+	g_object_class->set_property = sion_backend_gvfs_set_property;
+
+	parent_class = (GObjectClass*)g_type_class_peek(G_TYPE_OBJECT);
+	g_type_class_add_private((gpointer)klass, sizeof(SionBackendGVFSPrivate));
+
+	g_object_class_install_property(g_object_class,
+										PROP_STORE,
+										g_param_spec_object(
+										"store",
+										"Liststore",
+										"The list store",
+										GTK_TYPE_LIST_STORE,
+										G_PARAM_WRITABLE));
+
+	signals[MOUNTS_CHANGED] = g_signal_new("mounts-changed",
+										G_TYPE_FROM_CLASS(klass),
+										(GSignalFlags) 0,
+										0,
+										0,
+										NULL,
+										g_cclosure_marshal_VOID__VOID,
+										G_TYPE_NONE, 0);
+	signals[OPERATION_FAILED] = g_signal_new("operation-failed",
+										G_TYPE_FROM_CLASS(klass),
+										(GSignalFlags) 0,
+										0,
+										0,
+										NULL,
+										sion_backend_gvfs_cclosure_marshal_VOID__STRING_STRING,
+										G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+}
+
+
+static void sion_backend_gvfs_finalize(GObject *object)
+{
+	SionBackendGVFS *self;
+
+	self = SION_BACKEND_GVFS(object);
+
+	if (G_OBJECT_CLASS(parent_class)->finalize)
+		(* G_OBJECT_CLASS(parent_class)->finalize)(object);
+}
+
+
+static gchar *get_tooltip_text(gpointer ref, gint ref_type, const gchar *type)
+{
+	gchar *result = NULL;
+	switch (ref_type)
+	{
+		case SION_WINDOW_REF_TYPE_MOUNT:
+		{
+			gchar *uri, *name;
+
+			sion_backend_gvfs_get_name_and_uri_from_mount(ref, &name, &uri);
+			result = g_strdup_printf(
+				_("<b>%s</b>\n\nURI: %s\nMounted: Yes\nType: %s"), name, uri, type);
+
+			g_free(uri);
+			g_free(name);
+			return result;
+		}
+		case SION_WINDOW_REF_TYPE_VOLUME:
+		default:
+		{
+			gchar *label = sion_backend_gvfs_get_volume_identifier(ref);
+
+			if (NZV(label))
+			{
+				result = g_strdup_printf(_("<b>Unix device: %s</b>"), label);
+			}
+			g_free(label);
+			return result;
+		}
+	}
+}
+
+
+static void mount_volume_changed_cb(GVolumeMonitor *vm, GMount *mnt, gpointer backend)
+{
+	GList *mounts, *volumes, *item;
+	GFile *file;
+	GMount *mount;
+	GVolume *volume;
+	GIcon *icon;
+	GtkTreeIter iter;
+	gchar *vol_name, *scheme, *uri, *scheme_upper, *tooltip_text;
+	SionBackendGVFSPrivate *priv = SION_BACKEND_GVFS_GET_PRIVATE(backend);
+
+	gtk_list_store_clear(priv->store);
+
+	// list mounts
+	mounts = g_volume_monitor_get_mounts(vm);
+	for (item = mounts; item != NULL; item = g_list_next(item))
+	{
+		mount = G_MOUNT(item->data);
+		vol_name = g_mount_get_name(mount);
+		file = g_mount_get_root(mount);
+		scheme = g_file_get_uri_scheme(file);
+		scheme_upper = sion_beautify_scheme(scheme);
+		uri = g_file_get_uri(file);
+		icon = g_mount_get_icon(mount);
+		tooltip_text = get_tooltip_text(mount, SION_WINDOW_REF_TYPE_MOUNT, scheme_upper);
+
+		gtk_list_store_append(priv->store, &iter);
+		gtk_list_store_set(priv->store, &iter,
+				SION_WINDOW_COL_IS_MOUNTED, TRUE,
+				SION_WINDOW_COL_NAME, vol_name,
+				SION_WINDOW_COL_SCHEME, scheme_upper,
+				SION_WINDOW_COL_REF, mount,
+				SION_WINDOW_COL_REF_TYPE, SION_WINDOW_REF_TYPE_MOUNT,
+				SION_WINDOW_COL_PIXBUF, icon,
+				SION_WINDOW_COL_ICON_NAME, "folder-remote",
+				SION_WINDOW_COL_TOOLTIP, tooltip_text,
+				-1);
+		g_free(vol_name);
+		g_free(scheme);
+		g_free(scheme_upper);
+		g_free(uri);
+		g_free(tooltip_text);
+		g_object_unref(file);
+		g_object_unref(icon);
+	}
+	g_list_foreach(mounts, (GFunc) g_object_unref, NULL);
+	g_list_free(mounts);
+
+	// list volumes
+	volumes = g_volume_monitor_get_volumes(vm);
+	for (item = volumes; item != NULL; item = g_list_next(item))
+	{
+		volume = G_VOLUME(item->data);
+		mount = g_volume_get_mount(volume);
+		// display this volume only if it is not mounted, otherwise it will be listed as mounted
+		if (mount == NULL)
+		{
+			icon = g_volume_get_icon(volume);
+			vol_name = g_volume_get_name(volume);
+			tooltip_text = get_tooltip_text(volume, SION_WINDOW_REF_TYPE_VOLUME, NULL);
+
+			gtk_list_store_append(priv->store, &iter);
+			gtk_list_store_set(priv->store, &iter,
+					SION_WINDOW_COL_IS_MOUNTED, FALSE,
+					SION_WINDOW_COL_NAME, vol_name,
+					SION_WINDOW_COL_SCHEME, "",
+					SION_WINDOW_COL_REF, volume,
+					SION_WINDOW_COL_REF_TYPE, SION_WINDOW_REF_TYPE_VOLUME,
+					SION_WINDOW_COL_PIXBUF, icon,
+					SION_WINDOW_COL_ICON_NAME, "folder-remote",
+					SION_WINDOW_COL_TOOLTIP, tooltip_text,
+					-1);
+			g_free(vol_name);
+			g_free(tooltip_text);
+			g_object_unref(icon);
+		}
+		else
+			g_object_unref(mount);
+	}
+	g_list_foreach(volumes, (GFunc) g_object_unref, NULL);
+	g_list_free(volumes);
+
+	g_signal_emit(backend, signals[MOUNTS_CHANGED], 0);
+}
+
+
+static void sion_backend_gvfs_set_property(GObject *object, guint prop_id,
+										   const GValue *value, GParamSpec *pspec)
+{
+	switch (prop_id)
+	{
+	case PROP_STORE:
+	{
+		GVolumeMonitor *gvm;
+		SionBackendGVFSPrivate *priv = SION_BACKEND_GVFS_GET_PRIVATE(object);
+
+		priv->store = g_value_get_object(value);
+
+		gvm = g_volume_monitor_get();
+		g_signal_connect(gvm, "mount-added", G_CALLBACK(mount_volume_changed_cb), object);
+		g_signal_connect(gvm, "mount-changed", G_CALLBACK(mount_volume_changed_cb), object);
+		g_signal_connect(gvm, "mount-removed", G_CALLBACK(mount_volume_changed_cb), object);
+		g_signal_connect(gvm, "volume-added", G_CALLBACK(mount_volume_changed_cb), object);
+		g_signal_connect(gvm, "volume-changed", G_CALLBACK(mount_volume_changed_cb), object);
+		g_signal_connect(gvm, "volume-removed", G_CALLBACK(mount_volume_changed_cb), object);
+
+		// fill the list store once
+		mount_volume_changed_cb(gvm, NULL, object);
+		break;
+	}
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void sion_backend_gvfs_init(SionBackendGVFS *self)
+{
+}
+
+
+SionBackendGVFS *sion_backend_gvfs_new(GtkListStore *store)
+{
+	SionBackendGVFS *backend = g_object_new(SION_BACKEND_GVFS_TYPE, "store", store, NULL);
+
+	return backend;
+}
+
+
+gboolean sion_backend_gvfs_is_mount(gpointer mnt)
+{
+	g_return_val_if_fail(mnt != NULL, FALSE);
+
+	return G_IS_MOUNT(mnt);
+}
+
+
+void sion_backend_gvfs_get_name_and_uri_from_mount(GMount *mount, gchar **name, gchar **uri)
+{
+	GFile *file;
+
+	g_return_if_fail(mount != NULL);
+
+	file = g_mount_get_root(mount);
+	if (name != NULL)
+		*name = g_mount_get_name(mount);
+	if (uri != NULL)
+		*uri = g_file_get_uri(file);
+
+	g_object_unref(file);
+}
+
+
+static void volume_mount_finished_cb(GObject *src, GAsyncResult *res, gpointer backend)
+{
+	GError *error = NULL;
+
+	if (! g_volume_mount_finish(G_VOLUME(src), res, &error))
+	{
+		gchar *name, *msg;
+
+		if (G_IS_VOLUME(src))
+			name = g_volume_get_name(G_VOLUME(src));
+		else
+		{
+			sion_backend_gvfs_get_name_and_uri_from_mount(G_MOUNT(src), &name, NULL);
+			if (name == NULL)
+				name = g_strdup(_("unknown"));
+		}
+
+		g_warning("Mounting of \"%s\" failed (%s)", name, error->message);
+		msg = g_strdup_printf(_("Mounting of \"%s\" failed."), name);
+
+		g_signal_emit(backend, signals[OPERATION_FAILED], 0, msg, error->message);
+
+		g_error_free(error);
+		g_free(name);
+		g_free(msg);
+	}
+	else
+		verbose("Mount finished sucessfully");
+}
+
+
+static void unmount_finished_cb(GObject *src, GAsyncResult *res, gpointer backend)
+{
+	GError *error = NULL;
+
+	if (! g_mount_unmount_finish(G_MOUNT(src), res, &error))
+	{
+		gchar *name, *msg;
+
+		if (G_IS_VOLUME(src))
+			name = g_volume_get_name(G_VOLUME(src));
+		else
+		{
+			sion_backend_gvfs_get_name_and_uri_from_mount(G_MOUNT(src), &name, NULL);
+			if (name == NULL)
+				name = g_strdup(_("unknown"));
+		}
+
+		g_warning("Unmounting of \"%s\" failed: %s", name, error->message);
+		msg = g_strdup_printf(_("Unmounting of \"%s\" failed."), name);
+
+		g_signal_emit(backend, signals[OPERATION_FAILED], 0, msg, error->message);
+
+		g_error_free(error);
+		g_free(name);
+		g_free(msg);
+	}
+}
+
+
+gboolean sion_backend_gvfs_mount_volume(SionBackendGVFS *backend, GVolume *vol)
+{
+	g_return_val_if_fail(backend != NULL, FALSE);
+	g_return_val_if_fail(vol != NULL, FALSE);
+
+	if (! G_IS_MOUNT(vol) && G_IS_VOLUME(vol) && g_volume_can_mount(vol))
+	{
+		g_volume_mount(vol, G_MOUNT_MOUNT_NONE, NULL, NULL, volume_mount_finished_cb, backend);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+void sion_backend_gvfs_unmount_mount(SionBackendGVFS *backend, GMount *mount)
+{
+	g_return_if_fail(backend != NULL);
+	g_return_if_fail(mount != NULL);
+
+	g_mount_unmount(mount, G_MOUNT_UNMOUNT_NONE, NULL, unmount_finished_cb, backend);
+}
+
+
+static void mount_ready_cb(GFile *location, GAsyncResult *res, gpointer backend)
+{
+	gchar *uri;
+	gboolean success;
+	GError *error = NULL;
+
+	uri = g_file_get_uri(location);
+	success = g_file_mount_enclosing_volume_finish(location, res, &error);
+
+	if (success || g_error_matches(error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED))
+		verbose("Successfully mounted \"%s\"", uri);
+	else
+	{
+		gchar *msg = g_strdup_printf(_("Mounting of \"%s\" failed."), uri);
+		g_signal_emit(backend, signals[OPERATION_FAILED], 0, msg, error->message);
+		g_free(msg);
+	}
+
+	if (error != NULL)
+		g_error_free(error);
+
+	g_free(uri);
+}
+
+
+static void set_password_cb(GMountOperation *op, gchar *message, gchar *default_user,
+							gchar *default_domain, GAskPasswordFlags flags, gpointer data)
+{
+	GtkWidget *dialog = sion_password_dialog_new(flags);
+	GMountOperationResult result;
+
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
+	{
+		result = G_MOUNT_OPERATION_HANDLED;
+
+		if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+			g_mount_operation_set_domain(op,
+				sion_password_dialog_get_domain(SION_PASSWORD_DIALOG(dialog)));
+		if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+			g_mount_operation_set_username(op,
+				sion_password_dialog_get_username(SION_PASSWORD_DIALOG(dialog)));
+		if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+		{
+			g_mount_operation_set_password(op,
+				sion_password_dialog_get_password(SION_PASSWORD_DIALOG(dialog)));
+			/// TODO make this configurable?
+			//~ g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_FOR_SESSION);
+			//~ g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_NEVER);
+			g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_PERMANENTLY);
+		}
+	}
+	else
+	{
+		result = G_MOUNT_OPERATION_ABORTED;
+	}
+
+	gtk_widget_destroy(dialog);
+
+	g_mount_operation_reply(op, result);
+}
+
+
+void sion_backend_gvfs_mount_uri(SionBackendGVFS *backend, const gchar *uri)
+{
+	GMountOperation *op;
+	GFile *file;
+
+	g_return_if_fail(uri != NULL);
+	g_return_if_fail(backend != NULL);
+
+	op = g_mount_operation_new();
+	file = g_file_new_for_uri(uri);
+
+	g_signal_connect(op, "ask-password", G_CALLBACK(set_password_cb), NULL);
+
+	g_file_mount_enclosing_volume(file, G_MOUNT_MOUNT_NONE, op, NULL,
+		(GAsyncReadyCallback) mount_ready_cb, backend);
+
+	g_object_unref(file);
+}
+
+
+gchar *sion_backend_gvfs_get_volume_identifier(GVolume *volume)
+{
+	g_return_val_if_fail(volume != NULL, NULL);
+
+	return g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+}
+
+


Property changes on: sion/trunk/src/backendgvfs.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/backendgvfs.h
===================================================================
--- sion/trunk/src/backendgvfs.h	                        (rev 0)
+++ sion/trunk/src/backendgvfs.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,65 @@
+/*
+ *      backendgvfs.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BACKENDGVFS_H__
+#define __BACKENDGVFS_H__
+
+G_BEGIN_DECLS
+
+#define SION_BACKEND_GVFS_TYPE				(sion_backend_gvfs_get_type())
+#define SION_BACKEND_GVFS(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_BACKEND_GVFS_TYPE, SionBackendGVFS))
+#define SION_BACKEND_GVFS_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_BACKEND_GVFS_TYPE, SionBackendGVFSClass))
+#define IS_SION_BACKEND_GVFS(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_BACKEND_GVFS_TYPE))
+#define IS_SION_BACKEND_GVFS_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_BACKEND_GVFS_TYPE))
+
+
+typedef struct _SionBackendGVFS			SionBackendGVFS;
+typedef struct _SionBackendGVFSClass	SionBackendGVFSClass;
+
+struct _SionBackendGVFS
+{
+	GObject parent;
+};
+
+struct _SionBackendGVFSClass
+{
+	GObjectClass parent_class;
+};
+
+GType				sion_backend_gvfs_get_type						(void);
+SionBackendGVFS*	sion_backend_gvfs_new							(GtkListStore *store);
+
+gboolean			sion_backend_gvfs_is_mount						(gpointer mnt);
+void				sion_backend_gvfs_get_name_and_uri_from_mount	(GMount *mount, gchar **name, gchar **uri);
+
+gboolean			sion_backend_gvfs_mount_volume					(SionBackendGVFS *backend, GVolume *vol);
+void				sion_backend_gvfs_unmount_mount					(SionBackendGVFS *backend, GMount *mount);
+
+void				sion_backend_gvfs_mount_uri						(SionBackendGVFS *backend, const gchar *uri);
+
+gchar*				sion_backend_gvfs_get_volume_identifier			(GVolume *volume);
+
+G_END_DECLS
+
+#endif /* __BACKENDGVFS_H__ */


Property changes on: sion/trunk/src/backendgvfs.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmark.c
===================================================================
--- sion/trunk/src/bookmark.c	                        (rev 0)
+++ sion/trunk/src/bookmark.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,424 @@
+/*
+ *      bookmark.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib-object.h>
+
+#include "bookmark.h"
+#include "common.h"
+#include "main.h"
+
+
+typedef struct _SionBookmarkPrivate			SionBookmarkPrivate;
+
+#define SION_BOOKMARK_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_BOOKMARK_TYPE, SionBookmarkPrivate))
+
+struct _SionBookmarkPrivate
+{
+	gchar	*name;
+	gchar	*scheme;
+	gchar	*host;
+	guint	 port;
+	gchar	*user;
+
+	gboolean is_valid;
+};
+
+static void sion_bookmark_class_init		(SionBookmarkClass *klass);
+static void sion_bookmark_init      		(SionBookmark *self);
+static void sion_bookmark_finalize  		(GObject *object);
+
+/* Local data */
+static GObjectClass *parent_class = NULL;
+
+GType sion_bookmark_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionBookmarkClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_bookmark_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionBookmark),
+			0,
+			(GInstanceInitFunc)sion_bookmark_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(G_TYPE_OBJECT, "SionBookmark", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void bookmark_clear(SionBookmark *self)
+{
+	SionBookmarkPrivate *priv = SION_BOOKMARK_GET_PRIVATE(self);
+
+	g_free(priv->name);
+	g_free(priv->scheme);
+	g_free(priv->host);
+	g_free(priv->user);
+
+	priv->name = NULL;
+	priv->scheme = NULL;
+	priv->host = NULL;
+	priv->port = 0;
+	priv->user = NULL;
+
+	priv->is_valid = TRUE;
+}
+
+
+static void sion_bookmark_class_init(SionBookmarkClass *klass)
+{
+	GObjectClass *g_object_class;
+
+	g_object_class = G_OBJECT_CLASS(klass);
+
+	g_object_class->finalize = sion_bookmark_finalize;
+
+	parent_class = (GObjectClass*)g_type_class_peek(G_TYPE_OBJECT);
+	g_type_class_add_private((gpointer)klass, sizeof(SionBookmarkPrivate));
+}
+
+
+static void sion_bookmark_finalize(GObject *object)
+{
+	bookmark_clear(SION_BOOKMARK(object));
+
+	G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+
+static gboolean parse_uri(SionBookmark *bm, const gchar *uri)
+{
+	gchar *s, *t, *x, *end;
+	guint l;
+	SionBookmarkPrivate *priv = SION_BOOKMARK_GET_PRIVATE(bm);
+
+	priv->scheme = g_uri_parse_scheme(uri);
+
+	s = strstr(uri, "://");
+	s += 3;
+
+	/* find end of host/port, this is the first slash after the initial double slashes */
+	end = strchr(s, '/');
+	if (end == NULL)
+		end = s + strlen(s); // there is no trailing '/', so use the whole remaining string
+
+	/* find username */
+	t = strchr(s, '@');
+	if (t != NULL)
+	{
+		l = 0;
+		x = s;
+		while (*x != '\0' && x < t && *x != ':')
+		{
+			l++; // count the len of the username
+			x++;
+		}
+		if (l == 0)
+		{
+			verbose("Error parsing URI %s while reading username", uri);
+			bookmark_clear(bm);
+			return FALSE;
+		}
+		priv->user = g_strndup(s, l);
+	}
+
+	/* find hostname */
+	s = (t) ? t + 1 : s;
+	if (*s == '[') // obex://[00:12:D1:94:1B:28]/ or http://[1080:0:0:0:8:800:200C:417A]/index.html
+	{
+		gchar *hostend;
+
+		s++; // skip the found '['
+		hostend = strchr(s, ']');
+		if (! hostend || hostend > end)
+		{
+			verbose("Error parsing URI %s, missing ']'", uri);
+			bookmark_clear(bm);
+			return FALSE;
+		}
+		l = 0;
+		x = s;
+		while (*x != '\0' && x < end && *x != ']')
+		{
+			l++; // count the len of the username
+			x++;
+		}
+		priv->host = g_strndup(s, l);
+		s = hostend;
+	}
+	else
+	{
+		l = 0;
+		x = s;
+		while (*x != '\0' && x < end && *x != ':')
+		{
+			l++; // count the len of the username
+			x++;
+		}
+		priv->host = g_strndup(s, l);
+	}
+
+	/* find port */
+	t = strchr(s, ':');
+	if (t != NULL)
+	{
+		gchar *tmp;
+
+		t++; // skip the found ':'
+		l = 0;
+		x = t;
+		while (*x != '\0' && x < end)
+		{
+			l++; // count the len of the username
+			x++;
+		}
+		// atoi should be enough as it returns simply 0 if there are any errors and 0 marks an
+		// invalid port
+		tmp = g_strndup(t, l);
+		priv->port = (guint) atoi(tmp);
+		g_free(tmp);
+	}
+	return TRUE;
+}
+
+
+static void sion_bookmark_init(SionBookmark *self)
+{
+	bookmark_clear(self);
+}
+
+
+SionBookmark *sion_bookmark_new(void)
+{
+	return (SionBookmark*) g_object_new(SION_BOOKMARK_TYPE, NULL);
+}
+
+
+SionBookmark *sion_bookmark_new_from_uri(const gchar *name, const gchar *uri)
+{
+	SionBookmark *bm = g_object_new(SION_BOOKMARK_TYPE, NULL);
+	SionBookmarkPrivate *priv = SION_BOOKMARK_GET_PRIVATE(bm);
+
+	sion_bookmark_set_name(bm, name);
+	if (! parse_uri(bm, uri))
+		priv->is_valid = FALSE;
+
+	return bm;
+}
+
+
+/* Copy the contents of the bookmark 'src' into the existing bookmark 'dest' */
+void sion_bookmark_clone(SionBookmark *dst, const SionBookmark *src)
+{
+	SionBookmarkPrivate *priv_dst;
+	const SionBookmarkPrivate *priv_src;
+
+	g_return_if_fail(dst != NULL);
+	g_return_if_fail(src != NULL);
+
+	priv_dst = SION_BOOKMARK_GET_PRIVATE(dst);
+	priv_src = SION_BOOKMARK_GET_PRIVATE(src);
+
+	/* free existing strings and data */
+	bookmark_clear(dst);
+
+	/* copy from src to dst */
+	priv_dst->name = g_strdup(priv_src->name);
+	priv_dst->host = g_strdup(priv_src->host);
+	priv_dst->scheme = g_strdup(priv_src->scheme);
+	priv_dst->user = g_strdup(priv_src->user);
+	priv_dst->port = priv_src->port;
+}
+
+
+gchar *sion_bookmark_get_uri(SionBookmark *bookmark)
+{
+	SionBookmarkPrivate *priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+	gchar *result;
+	gchar *port = NULL;
+
+	g_return_val_if_fail(bookmark != NULL, NULL);
+
+	if (priv->port > 0)
+	{
+		port = g_strdup_printf(":%d", priv->port);
+	}
+
+	result = g_strdup_printf("%s://%s%s%s%s/",
+		priv->scheme,
+		(NZV(priv->user)) ? priv->user : "",
+		(NZV(priv->user)) ? "@" : "",
+		priv->host,
+		(port) ? port : "");
+
+	g_free(port);
+	return result;
+}
+
+
+void sion_bookmark_set_uri(SionBookmark *bookmark, const gchar *uri)
+{
+	SionBookmarkPrivate *priv;
+	SionBookmark *tmp;
+
+	g_return_if_fail(bookmark != NULL);
+	g_return_if_fail(NZV(uri));
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	tmp = sion_bookmark_new_from_uri(priv->name, uri);
+	if (sion_bookmark_is_valid(tmp))
+		sion_bookmark_clone(bookmark, tmp);
+}
+
+
+const gchar *sion_bookmark_get_name(SionBookmark *bookmark)
+{
+	g_return_val_if_fail(bookmark != NULL, NULL);
+
+	return SION_BOOKMARK_GET_PRIVATE(bookmark)->name;
+}
+
+
+void sion_bookmark_set_name(SionBookmark *bookmark, const gchar *name)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_if_fail(bookmark != NULL);
+	g_return_if_fail(NZV(name));
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	g_free(priv->name);
+	priv->name = g_strdup(name);
+}
+
+
+const gchar *sion_bookmark_get_scheme(SionBookmark *bookmark)
+{
+	g_return_val_if_fail(bookmark != NULL, NULL);
+
+	return SION_BOOKMARK_GET_PRIVATE(bookmark)->scheme;
+}
+
+
+void sion_bookmark_set_scheme(SionBookmark *bookmark, const gchar *scheme)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_if_fail(bookmark != NULL);
+	g_return_if_fail(NZV(scheme));
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	g_free(priv->scheme);
+	priv->scheme = g_strdup(scheme);
+}
+
+
+const gchar *sion_bookmark_get_host(SionBookmark *bookmark)
+{
+	g_return_val_if_fail(bookmark != NULL, NULL);
+
+	return SION_BOOKMARK_GET_PRIVATE(bookmark)->host;
+}
+
+
+void sion_bookmark_set_host(SionBookmark *bookmark, const gchar *host)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_if_fail(bookmark != NULL);
+	g_return_if_fail(NZV(host));
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	g_free(priv->host);
+	priv->host = g_strdup(host);
+}
+
+
+guint sion_bookmark_get_port(SionBookmark *bookmark)
+{
+	g_return_val_if_fail(bookmark != NULL, 0);
+
+	return SION_BOOKMARK_GET_PRIVATE(bookmark)->port;
+}
+
+
+void sion_bookmark_set_port(SionBookmark *bookmark, guint port)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_if_fail(bookmark != NULL);
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	priv->port = port;
+}
+
+
+const gchar *sion_bookmark_get_user(SionBookmark *bookmark)
+{
+	g_return_val_if_fail(bookmark != NULL, NULL);
+
+	return SION_BOOKMARK_GET_PRIVATE(bookmark)->user;
+}
+
+
+void sion_bookmark_set_user(SionBookmark *bookmark, const gchar *user)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_if_fail(bookmark != NULL);
+	g_return_if_fail(NZV(user));
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	g_free(priv->user);
+	priv->user = g_strdup(user);
+}
+
+
+gboolean sion_bookmark_is_valid(SionBookmark *bookmark)
+{
+	SionBookmarkPrivate *priv;
+
+	g_return_val_if_fail(bookmark != NULL, FALSE);
+
+	priv = SION_BOOKMARK_GET_PRIVATE(bookmark);
+
+	return priv->is_valid;
+}
+


Property changes on: sion/trunk/src/bookmark.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmark.h
===================================================================
--- sion/trunk/src/bookmark.h	                        (rev 0)
+++ sion/trunk/src/bookmark.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,75 @@
+/*
+ *      bookmark.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BOOKMARK_H__
+#define __BOOKMARK_H__
+
+G_BEGIN_DECLS
+
+#define SION_BOOKMARK_TYPE					(sion_bookmark_get_type())
+#define SION_BOOKMARK(obj)					(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_BOOKMARK_TYPE, SionBookmark))
+#define SION_BOOKMARK_CLASS(klass)			(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_BOOKMARK_TYPE, SionBookmarkClass))
+#define IS_SION_BOOKMARK(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj), SION_BOOKMARK_TYPE))
+#define IS_SION_BOOKMARK_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass), SION_BOOKMARK_TYPE))
+
+typedef struct _SionBookmark				SionBookmark;
+typedef struct _SionBookmarkClass			SionBookmarkClass;
+
+struct _SionBookmark
+{
+	GObject parent;
+};
+
+struct _SionBookmarkClass
+{
+	GObjectClass parent_class;
+};
+
+GType				sion_bookmark_get_type		(void);
+SionBookmark*		sion_bookmark_new			(void);
+SionBookmark*		sion_bookmark_new_from_uri	(const gchar *name, const gchar *uri);
+
+gboolean			sion_bookmark_is_valid		(SionBookmark *bookmark);
+
+void				sion_bookmark_clone			(SionBookmark *dst, const SionBookmark *src);
+
+gchar*				sion_bookmark_get_uri		(SionBookmark *bookmark);
+void				sion_bookmark_set_uri		(SionBookmark *bookmark, const gchar *uri);
+
+const gchar*		sion_bookmark_get_name		(SionBookmark *bookmark);
+void				sion_bookmark_set_name		(SionBookmark *bookmark, const gchar *name);
+
+const gchar*		sion_bookmark_get_scheme	(SionBookmark *bookmark);
+void				sion_bookmark_set_scheme	(SionBookmark *bookmark, const gchar *scheme);
+
+const gchar*		sion_bookmark_get_host		(SionBookmark *bookmark);
+void				sion_bookmark_set_host		(SionBookmark *bookmark, const gchar *host);
+
+guint				sion_bookmark_get_port		(SionBookmark *bookmark);
+void				sion_bookmark_set_port		(SionBookmark *bookmark, guint port);
+
+const gchar*		sion_bookmark_get_user		(SionBookmark *bookmark);
+void				sion_bookmark_set_user		(SionBookmark *bookmark, const gchar *user);
+
+G_END_DECLS
+
+#endif /* __BOOKMARK_H__ */


Property changes on: sion/trunk/src/bookmark.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmarkdialog.c
===================================================================
--- sion/trunk/src/bookmarkdialog.c	                        (rev 0)
+++ sion/trunk/src/bookmarkdialog.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,447 @@
+/*
+ *      bookmarkdialog.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "settings.h"
+#include "bookmark.h"
+#include "bookmarkdialog.h"
+#include "bookmarkeditdialog.h"
+#include "window.h"
+#include "common.h"
+#include "compat.h"
+
+typedef struct _SionBookmarkDialogPrivate			SionBookmarkDialogPrivate;
+
+#define SION_BOOKMARK_DIALOG_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_BOOKMARK_DIALOG_TYPE, SionBookmarkDialogPrivate))
+
+struct _SionBookmarkDialogPrivate
+{
+	SionSettings *settings;
+
+	GtkWidget *parent;
+
+	GtkWidget *tree;
+	GtkListStore *store;
+
+	GtkWidget *button_edit;
+	GtkWidget *button_delete;
+
+	GtkWidget *popup_menu;
+	GtkWidget *edit_item;
+	GtkWidget *delete_item;
+};
+
+enum
+{
+	COL_NAME,
+	COL_SCHEME,
+	COL_HOST,
+	COL_PORT,
+	COL_USERNAME,
+	COL_BMREF,
+	ACTION_ADD,
+	ACTION_EDIT,
+	ACTION_DELETE
+};
+
+static void sion_bookmark_dialog_class_init			(SionBookmarkDialogClass *klass);
+static void sion_bookmark_dialog_init      			(SionBookmarkDialog *dialog);
+
+static GtkDialogClass *parent_class = NULL;
+
+GType sion_bookmark_dialog_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionBookmarkDialogClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_bookmark_dialog_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionBookmarkDialog),
+			0,
+			(GInstanceInitFunc)sion_bookmark_dialog_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_DIALOG, "SionBookmarkDialog", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void sion_bookmark_dialog_class_init(SionBookmarkDialogClass *klass)
+{
+	parent_class = (GtkDialogClass*)g_type_class_peek(GTK_TYPE_DIALOG);
+	g_type_class_add_private((gpointer)klass, sizeof(SionBookmarkDialogPrivate));
+}
+
+
+static void update_row_in_model(SionBookmarkDialog *dialog, GtkTreeIter *iter, SionBookmark *bm)
+{
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+	gchar port[6];
+
+	if (sion_bookmark_get_port(bm) > 0)
+		g_snprintf(port, sizeof(port), "%d", sion_bookmark_get_port(bm));
+	else
+		port[0] = '\0';
+
+	gtk_list_store_set(priv->store, iter,
+			COL_NAME, sion_bookmark_get_name(bm),
+			COL_SCHEME, sion_bookmark_get_scheme(bm),
+			COL_HOST, sion_bookmark_get_host(bm),
+			COL_PORT, port,
+			COL_USERNAME, sion_bookmark_get_user(bm),
+			COL_BMREF, bm,
+			-1);
+
+}
+
+
+static void add_button_click_cb(GtkButton *button, GtkWidget *dialog)
+{
+	GtkWidget *edit_dialog = sion_bookmark_edit_dialog_new(dialog, SION_BE_MODE_CREATE);
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+	SionBookmark *bm = NULL;
+
+	if (gtk_dialog_run(GTK_DIALOG(edit_dialog)) == GTK_RESPONSE_OK)
+	{
+		GtkTreeIter iter;
+
+		bm = sion_bookmark_new();
+		/* this fills the values of the dialog into 'bm' */
+		g_object_set(edit_dialog, "bookmark-update", bm, NULL);
+
+		g_ptr_array_add(sion_settings_get_bookmarks(priv->settings), bm);
+		gtk_list_store_append(priv->store, &iter);
+
+		update_row_in_model(SION_BOOKMARK_DIALOG(dialog), &iter, bm);
+		sion_window_update_bookmarks(SION_WINDOW(priv->parent));
+	}
+	gtk_widget_destroy(edit_dialog);
+}
+
+
+static void edit_button_click_cb(GtkButton *button, GtkWidget *dialog)
+{
+	GtkTreeSelection *treesel;
+	GtkTreeIter iter;
+	GtkWidget *edit_dialog;
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+	SionBookmark *bm;
+
+	treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->tree));
+
+	if (gtk_tree_selection_count_selected_rows(treesel) != 1)
+		return;
+
+	gtk_tree_selection_get_selected(treesel, NULL, &iter);
+
+	gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter, COL_BMREF, &bm, -1);
+
+	edit_dialog = sion_bookmark_edit_dialog_new_with_bookmark(dialog, SION_BE_MODE_EDIT, bm);
+	if (gtk_dialog_run(GTK_DIALOG(edit_dialog)) == GTK_RESPONSE_OK)
+	{
+		/* this fills the values of the dialog into 'bm' */
+		g_object_set(edit_dialog, "bookmark-update", bm, NULL);
+
+		update_row_in_model(SION_BOOKMARK_DIALOG(dialog), &iter, bm);
+		sion_window_update_bookmarks(SION_WINDOW(priv->parent));
+	}
+	gtk_widget_destroy(edit_dialog);
+}
+
+
+static void delete_button_click_cb(GtkButton *button, gpointer user_data)
+{
+	GtkTreeSelection *treesel;
+	GtkTreeIter iter;
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(user_data);
+	SionBookmark *bm;
+	SionBookmarkList *bml = sion_settings_get_bookmarks(priv->settings);
+
+	treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->tree));
+
+	if (gtk_tree_selection_count_selected_rows(treesel) != 1)
+		return;
+
+	gtk_tree_selection_get_selected(treesel, NULL, &iter);
+
+	gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter, COL_BMREF, &bm, -1);
+	gtk_list_store_remove(priv->store, &iter);
+	g_ptr_array_remove(bml, bm);
+	sion_window_update_bookmarks(SION_WINDOW(priv->parent));
+	g_object_unref(bm);
+}
+
+
+static void tree_fill(SionBookmarkDialog *dialog)
+{
+	guint i;
+	SionBookmark *bm;
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+	SionBookmarkList *bml = sion_settings_get_bookmarks(priv->settings);
+	GtkTreeIter iter;
+
+	for (i = 0; i < bml->len; i++)
+	{
+		bm = g_ptr_array_index(bml, i);
+
+		gtk_list_store_append(priv->store, &iter);
+		update_row_in_model(dialog, &iter, bm);
+	}
+}
+
+
+static void tree_row_activated_cb(GtkTreeView *treeview, GtkTreePath *path,
+								  GtkTreeViewColumn *arg2, gpointer data)
+{
+	edit_button_click_cb(NULL, data);
+}
+
+
+static void tree_selection_changed_cb(GtkTreeSelection *selection, gpointer data)
+{
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(data);
+
+	gtk_widget_set_sensitive(priv->button_edit, (selection != NULL));
+	gtk_widget_set_sensitive(priv->button_delete, (selection != NULL));
+}
+
+
+static gboolean tree_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	if (event->button == 3)
+	{
+		SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(data);
+		GtkTreeSelection *treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->tree));
+		gboolean have_sel = (gtk_tree_selection_count_selected_rows(treesel) > 0);
+
+		gtk_widget_set_sensitive(priv->edit_item, have_sel);
+		gtk_widget_set_sensitive(priv->delete_item, have_sel);
+
+		gtk_menu_popup(GTK_MENU(priv->popup_menu), NULL, NULL, NULL, NULL,
+																event->button, event->time);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+static void tree_popup_activate_cb(GtkCheckMenuItem *item, gpointer user_data)
+{
+	GtkWidget *dialog = g_object_get_data(G_OBJECT(item), "dialog");
+
+	switch (GPOINTER_TO_INT(user_data))
+	{
+		case ACTION_ADD:
+		{
+			add_button_click_cb(NULL, dialog);
+			break;
+		}
+		case ACTION_EDIT:
+		{
+			edit_button_click_cb(NULL, dialog);
+			break;
+		}
+		case ACTION_DELETE:
+		{
+			delete_button_click_cb(NULL, dialog);
+			break;
+		}
+	}
+}
+
+
+static void tree_prepare(SionBookmarkDialog *dialog)
+{
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *sel;
+	GtkWidget *item;
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+
+	priv->tree = gtk_tree_view_new();
+	priv->store = gtk_list_store_new(6,
+		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Name"), renderer, "text", COL_NAME, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, COL_NAME);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("URI Scheme"), renderer, "text", COL_SCHEME, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, COL_SCHEME);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Host"), renderer, "text", COL_HOST, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, COL_HOST);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Port"), renderer, "text", COL_PORT, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, COL_PORT);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Username"), renderer, "text", COL_USERNAME, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, COL_USERNAME);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(priv->tree), TRUE);
+	gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(priv->tree), TRUE);
+
+	// sorting
+	gtk_tree_sortable_set_sort_column_id(
+		GTK_TREE_SORTABLE(priv->store), COL_NAME, GTK_SORT_ASCENDING);
+
+	// selection handling
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->tree));
+	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(priv->tree), GTK_TREE_MODEL(priv->store));
+	g_object_unref(G_OBJECT(priv->store));
+
+	priv->popup_menu = gtk_menu_new();
+
+	item = gtk_image_menu_item_new_from_stock("gtk-add", NULL);
+	g_object_set_data(G_OBJECT(item), "dialog", dialog);
+	gtk_widget_show(item);
+	gtk_container_add(GTK_CONTAINER(priv->popup_menu), item);
+	g_signal_connect(item, "activate", G_CALLBACK(tree_popup_activate_cb),
+		GINT_TO_POINTER(ACTION_ADD));
+
+	priv->edit_item = gtk_image_menu_item_new_from_stock("gtk-edit", NULL);
+	g_object_set_data(G_OBJECT(priv->edit_item), "dialog", dialog);
+	gtk_widget_show(priv->edit_item);
+	gtk_container_add(GTK_CONTAINER(priv->popup_menu), priv->edit_item);
+	g_signal_connect(priv->edit_item, "activate", G_CALLBACK(tree_popup_activate_cb),
+		GINT_TO_POINTER(ACTION_EDIT));
+
+	priv->delete_item = gtk_image_menu_item_new_from_stock("gtk-delete", NULL);
+	g_object_set_data(G_OBJECT(priv->delete_item), "dialog", dialog);
+	gtk_widget_show(priv->delete_item);
+	gtk_container_add(GTK_CONTAINER(priv->popup_menu), priv->delete_item);
+	g_signal_connect(priv->delete_item, "activate", G_CALLBACK(tree_popup_activate_cb),
+		GINT_TO_POINTER(ACTION_DELETE));
+
+	g_signal_connect(priv->tree, "row-activated", G_CALLBACK(tree_row_activated_cb), dialog);
+	g_signal_connect(sel, "changed", G_CALLBACK(tree_selection_changed_cb), dialog);
+	g_signal_connect(priv->tree, "button-release-event",
+		G_CALLBACK(tree_button_press_event_cb), dialog);
+}
+
+
+static void sion_bookmark_dialog_init(SionBookmarkDialog *dialog)
+{
+	GtkWidget *vbox, *vbox2, *hbox, *swin, *button_add;
+	SionBookmarkDialogPrivate *priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+
+	g_object_set(dialog,
+		"icon-name", sion_find_icon_name("bookmark-new", GTK_STOCK_EDIT),
+		"title", _("Edit Bookmarks"),
+		NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+	vbox = sion_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_box_set_spacing(GTK_BOX(vbox), 2);
+
+	gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);
+
+	gtk_window_set_default_size(GTK_WINDOW(dialog), 450, 350);
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+	button_add = gtk_button_new_from_stock("gtk-add");
+	g_signal_connect(button_add, "clicked", G_CALLBACK(add_button_click_cb), dialog);
+
+	priv->button_edit = gtk_button_new_from_stock("gtk-edit");
+	g_signal_connect(priv->button_edit, "clicked", G_CALLBACK(edit_button_click_cb), dialog);
+
+	priv->button_delete = gtk_button_new_from_stock("gtk-delete");
+	g_signal_connect(priv->button_delete, "clicked", G_CALLBACK(delete_button_click_cb), dialog);
+
+	hbox = gtk_hbox_new(FALSE, 10);
+	gtk_box_pack_start(GTK_BOX(hbox), button_add, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), priv->button_edit, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), priv->button_delete, FALSE, FALSE, 0);
+
+	tree_prepare(dialog);
+
+	swin = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN);
+	gtk_container_add(GTK_CONTAINER(swin), priv->tree);
+
+	vbox2 = gtk_vbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(vbox2), swin, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
+
+	gtk_container_add(GTK_CONTAINER(vbox), vbox2);
+	gtk_widget_show_all(vbox);
+}
+
+
+GtkWidget *sion_bookmark_dialog_new(GtkWidget *parent, SionSettings *settings)
+{
+	GtkWidget *dialog;
+	SionBookmarkDialogPrivate *priv;
+
+	dialog = g_object_new(SION_BOOKMARK_DIALOG_TYPE, "transient-for", parent, NULL);
+	priv = SION_BOOKMARK_DIALOG_GET_PRIVATE(dialog);
+
+	priv->settings = settings;
+	priv->parent = parent;
+
+	tree_fill(SION_BOOKMARK_DIALOG(dialog));
+
+	tree_selection_changed_cb(NULL, dialog);
+
+	return dialog;
+}
+
+


Property changes on: sion/trunk/src/bookmarkdialog.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmarkdialog.h
===================================================================
--- sion/trunk/src/bookmarkdialog.h	                        (rev 0)
+++ sion/trunk/src/bookmarkdialog.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,54 @@
+/*
+ *      bookmarkdialog.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BOOKMARKDIALOG_H__
+#define __BOOKMARKDIALOG_H__
+
+G_BEGIN_DECLS
+
+#define SION_BOOKMARK_DIALOG_TYPE				(sion_bookmark_dialog_get_type())
+#define SION_BOOKMARK_DIALOG(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_BOOKMARK_DIALOG_TYPE, SionBookmarkDialog))
+#define SION_BOOKMARK_DIALOG_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_BOOKMARK_DIALOG_TYPE, SionBookmarkDialogClass))
+#define IS_SION_BOOKMARK_DIALOG(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_BOOKMARK_DIALOG_TYPE))
+#define IS_SION_BOOKMARK_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_BOOKMARK_DIALOG_TYPE))
+
+typedef struct _SionBookmarkDialog				SionBookmarkDialog;
+typedef struct _SionBookmarkDialogClass			SionBookmarkDialogClass;
+
+struct _SionBookmarkDialog
+{
+	GtkDialog parent;
+};
+
+struct _SionBookmarkDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+GType		sion_bookmark_dialog_get_type		(void);
+GtkWidget*	sion_bookmark_dialog_new			(GtkWidget *parent, SionSettings *settings);
+
+G_END_DECLS
+
+#endif /* __BOOKMARKDIALOG_H__ */


Property changes on: sion/trunk/src/bookmarkdialog.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmarkeditdialog.c
===================================================================
--- sion/trunk/src/bookmarkeditdialog.c	                        (rev 0)
+++ sion/trunk/src/bookmarkeditdialog.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,666 @@
+/*
+ *      bookmarkeditdialog.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* The code is mainly based on Nautilus' 'Connect to server' dialog, thanks */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "compat.h"
+#include "bookmark.h"
+#include "bookmarkeditdialog.h"
+
+typedef struct _SionBookmarkEditDialogPrivate			SionBookmarkEditDialogPrivate;
+
+#define SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_BOOKMARK_EDIT_DIALOG_TYPE, SionBookmarkEditDialogPrivate))
+
+struct _SionBookmarkEditDialogPrivate
+{
+	GtkWidget *table;
+
+	GtkWidget *type_combo;
+	GtkWidget *information_label;
+
+	GtkWidget *name_label;
+	GtkWidget *name_entry;
+
+	GtkWidget *uri_label;
+	GtkWidget *uri_entry;
+
+	GtkWidget *server_label;
+	GtkWidget *server_entry;
+
+	GtkWidget *port_label;
+	GtkWidget *port_spin;
+
+	GtkWidget *user_label;
+	GtkWidget *user_entry;
+/*
+	GtkWidget *share_entry;
+	GtkWidget *domain_entry;
+	GtkWidget *folder_entry;
+*/
+	SionBookmark *bookmark_init;
+	SionBookmark *bookmark_update;
+};
+
+static void sion_bookmark_edit_dialog_class_init			(SionBookmarkEditDialogClass *klass);
+static void sion_bookmark_edit_dialog_set_property			(GObject *object, guint prop_id,
+															 const GValue *value, GParamSpec *pspec);
+static void sion_bookmark_edit_dialog_init      			(SionBookmarkEditDialog *dialog);
+
+
+struct MethodInfo {
+	const gchar *scheme;
+	guint port;
+	guint flags;
+	const gchar *desc;
+};
+
+enum
+{
+    PROP_0,
+    PROP_MODE,
+    PROP_BOOKMARK_INIT,
+    PROP_BOOKMARK_UPDATE
+};
+
+enum {
+	/* Widgets to display in setup_for_type */
+	SHOW_SHARE     = 0x00000010,
+	SHOW_PORT      = 0x00000020,
+	SHOW_USER      = 0x00000040,
+	SHOW_DOMAIN    = 0x00000080
+};
+
+enum {
+	COLUMN_INDEX,
+	COLUMN_VISIBLE,
+	COLUMN_DESC,
+};
+
+static struct MethodInfo methods[] = {
+	{ "ftp",  21,	SHOW_PORT | SHOW_USER,					N_("FTP") },
+	{ "sftp", 22,	SHOW_PORT | SHOW_USER,					N_("SSH") },
+	{ "smb",  0,	SHOW_SHARE | SHOW_USER | SHOW_DOMAIN,	N_("Windows share") },
+	{ "davs", 443,	SHOW_PORT | SHOW_USER,					N_("Secure WebDAV (HTTPS)") },
+	{ "dav",  80,	SHOW_PORT | SHOW_USER,					N_("WebDAV (HTTP)") },
+	/* must always be the last item */
+	{ NULL,   0,	0, 										N_("Custom Location") }
+};
+static guint methods_len = G_N_ELEMENTS(methods);
+
+
+static GtkDialogClass *parent_class = NULL;
+
+
+GType sion_bookmark_edit_dialog_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionBookmarkEditDialogClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_bookmark_edit_dialog_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionBookmarkEditDialog),
+			0,
+			(GInstanceInitFunc)sion_bookmark_edit_dialog_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_DIALOG, "SionBookmarkEditDialog", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void sion_bookmark_edit_dialog_destroy(GtkObject *object)
+{
+	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(object);
+
+	gtk_widget_destroy(priv->uri_entry);
+	gtk_widget_destroy(priv->uri_label);
+	gtk_widget_destroy(priv->server_entry);
+	gtk_widget_destroy(priv->server_label);
+	gtk_widget_destroy(priv->port_label);
+	gtk_widget_destroy(priv->port_spin);
+	gtk_widget_destroy(priv->user_entry);
+	gtk_widget_destroy(priv->user_label);
+	gtk_widget_destroy(priv->information_label);
+
+	GTK_OBJECT_CLASS(parent_class)->destroy(object);
+}
+
+
+static void sion_bookmark_edit_dialog_class_init(SionBookmarkEditDialogClass *klass)
+{
+	GtkObjectClass *gtk_object_class = (GtkObjectClass *)klass;
+	GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
+
+	gtk_object_class->destroy = sion_bookmark_edit_dialog_destroy;
+
+	g_object_class->set_property = sion_bookmark_edit_dialog_set_property;
+
+	parent_class = (GtkDialogClass*)g_type_class_peek(GTK_TYPE_DIALOG);
+	g_type_class_add_private((gpointer)klass, sizeof(SionBookmarkEditDialogPrivate));
+
+	g_object_class_install_property(g_object_class,
+									PROP_MODE,
+									g_param_spec_int(
+									"mode",
+									"Mode",
+									"Operation mode",
+									0, G_MAXINT, SION_BE_MODE_CREATE,
+									G_PARAM_WRITABLE));
+	g_object_class_install_property(g_object_class,
+									PROP_BOOKMARK_INIT,
+									g_param_spec_object(
+									"bookmark-init",
+									"Bookmark-init",
+									"Bookmark instance to provide default values",
+									SION_BOOKMARK_TYPE,
+									G_PARAM_WRITABLE));
+	g_object_class_install_property(g_object_class,
+									PROP_BOOKMARK_UPDATE,
+									g_param_spec_object(
+									"bookmark-update",
+									"Bookmark-update",
+									"Bookmark instance",
+									SION_BOOKMARK_TYPE,
+									G_PARAM_WRITABLE));
+}
+
+
+static guint scheme_to_index(const gchar *scheme)
+{
+	guint i;
+
+	for (i = 0; i < methods_len; i++)
+	{
+		if (sion_str_equal(scheme, methods[i].scheme))
+		{
+			return i;
+		}
+	}
+	/* if no matching scheme was found, fall back to the Custom method */
+	return methods_len - 1;
+}
+
+
+gboolean combo_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+	gint idx = GPOINTER_TO_INT(data);
+	gint i;
+
+	gtk_tree_model_get(model, iter, COLUMN_INDEX, &i, -1);
+
+	if (i == idx)
+	{
+		GObject *combo = g_object_get_data(G_OBJECT(model), "combobox");
+		gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), iter);
+
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+static void combo_set_active(GtkWidget *combo, gint idx)
+{
+	gtk_tree_model_foreach(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)),
+		combo_foreach, GINT_TO_POINTER(idx));
+}
+
+
+static void init_values(SionBookmarkEditDialog *dialog)
+{
+	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+	gchar *uri;
+	const gchar *tmp;
+	guint port;
+	guint idx;
+
+	tmp = sion_bookmark_get_name(priv->bookmark_init);
+	if (tmp != NULL)
+		gtk_entry_set_text(GTK_ENTRY(priv->name_entry), tmp);
+		tmp = sion_bookmark_get_name(priv->bookmark_init);
+	uri = sion_bookmark_get_uri(priv->bookmark_init);
+	if (uri != NULL)
+	{
+		gtk_entry_set_text(GTK_ENTRY(priv->uri_entry), uri);
+		tmp = sion_bookmark_get_uri(priv->bookmark_init);
+		g_free(uri);
+	}
+	tmp = sion_bookmark_get_host(priv->bookmark_init);
+	if (tmp != NULL)
+		gtk_entry_set_text(GTK_ENTRY(priv->server_entry), tmp);
+		tmp = sion_bookmark_get_name(priv->bookmark_init);
+	tmp = sion_bookmark_get_user(priv->bookmark_init);
+	if (tmp != NULL)
+		gtk_entry_set_text(GTK_ENTRY(priv->user_entry), tmp);
+	port = sion_bookmark_get_port(priv->bookmark_init);
+	idx = scheme_to_index(sion_bookmark_get_scheme(priv->bookmark_init));
+	if (port == 0)
+		port = methods[idx].port;
+
+	gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->port_spin), port);
+	combo_set_active(priv->type_combo, (gint) idx);
+}
+
+
+static void setup_for_type(SionBookmarkEditDialog *dialog)
+{
+	struct MethodInfo *meth;
+	guint i;
+	guint idx;
+	GtkWidget *table;
+	GtkTreeIter iter;
+	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+
+	if (! gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->type_combo), &iter))
+		return;
+
+	gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->type_combo)),
+			    &iter, COLUMN_INDEX, &idx, -1);
+	g_return_if_fail(idx < methods_len && idx >= 0);
+	meth = &(methods[idx]);
+
+	if (gtk_widget_get_parent(priv->uri_entry) != NULL)
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->uri_label);
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->uri_entry);
+	}
+	if (gtk_widget_get_parent(priv->server_entry) != NULL)
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->server_label);
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->server_entry);
+	}
+	if (gtk_widget_get_parent(priv->port_spin) != NULL)
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->port_label);
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->port_spin);
+	}
+	if (gtk_widget_get_parent(priv->user_entry) != NULL)
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->user_label);
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->user_entry);
+	}
+	if (gtk_widget_get_parent(priv->information_label) != NULL)
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->table), priv->information_label);
+	}
+
+	i = 3;
+	table = priv->table;
+
+	if (meth->scheme == NULL)
+	{
+		gtk_misc_set_alignment(GTK_MISC(priv->uri_label), 0.0, 0.5);
+		gtk_widget_show(priv->uri_label);
+		gtk_table_attach(GTK_TABLE(table), priv->uri_label,
+				  0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
+
+		gtk_label_set_mnemonic_widget(GTK_LABEL(priv->uri_label), priv->uri_entry);
+		gtk_widget_show(priv->uri_entry);
+		gtk_table_attach(GTK_TABLE(table), priv->uri_entry,
+				  1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+		i++;
+	}
+	else
+	{
+		gtk_misc_set_alignment(GTK_MISC(priv->server_label), 0.0, 0.5);
+		gtk_widget_show(priv->server_label);
+		gtk_table_attach(GTK_TABLE(table), priv->server_label,
+				  0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
+
+		gtk_label_set_mnemonic_widget(GTK_LABEL(priv->server_label), priv->server_entry);
+		gtk_widget_show(priv->server_entry);
+		gtk_table_attach(GTK_TABLE(table), priv->server_entry,
+				  1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+		i++;
+	}
+
+	if (meth->flags)
+	{
+		gtk_misc_set_alignment(GTK_MISC(priv->information_label), 0.0, 0.5);
+		gtk_widget_show(priv->information_label);
+		gtk_table_attach(GTK_TABLE(table), priv->information_label,
+			0, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
+
+		i++;
+
+		if (meth->flags & SHOW_PORT)
+		{
+			gtk_misc_set_alignment(GTK_MISC(priv->port_label), 0.0, 0.5);
+			gtk_widget_show(priv->port_label);
+			gtk_table_attach(GTK_TABLE(table), priv->port_label,
+					  0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
+
+			gtk_label_set_mnemonic_widget(GTK_LABEL(priv->port_label), priv->port_spin);
+			gtk_widget_show(priv->port_spin);
+			gtk_table_attach(GTK_TABLE(table), priv->port_spin,
+					  1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+			i++;
+		}
+
+		if (meth->flags & SHOW_USER)
+		{
+			gtk_misc_set_alignment(GTK_MISC(priv->user_label), 0.0, 0.5);
+			gtk_widget_show(priv->user_label);
+			gtk_table_attach(GTK_TABLE(table), priv->user_label,
+					  0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
+
+			gtk_label_set_mnemonic_widget(GTK_LABEL(priv->user_label), priv->user_entry);
+			gtk_widget_show(priv->user_entry);
+			gtk_table_attach(GTK_TABLE(table), priv->user_entry,
+					  1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+			i++;
+		}
+	}
+}
+
+
+static void combo_changed_callback(GtkComboBox *combo_box, SionBookmarkEditDialog *dialog)
+{
+	setup_for_type(dialog);
+}
+
+
+static void fill_method_combo_box(SionBookmarkEditDialog *dialog)
+{
+	guint i, j;
+	gboolean visible;
+	const gchar* const *supported;
+	GtkListStore *store;
+	GtkTreeModel *filter;
+	GtkTreeIter iter;
+	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+
+	/* 0 - method index, 1 - visible/supported flag, 2 - description */
+	store = gtk_list_store_new(3, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_STRING);
+
+	supported = g_vfs_get_supported_uri_schemes(g_vfs_get_default());
+
+	for (i = 0; i < methods_len; i++)
+	{
+		visible = FALSE;
+		for (j = 0; supported[j] != NULL; j++)
+		{
+			if (methods[i].scheme == NULL || sion_str_equal(methods[i].scheme, supported[j]))
+			{
+				visible = TRUE;
+				break;
+			}
+		}
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter,
+			COLUMN_INDEX, i,
+			COLUMN_VISIBLE, visible,
+			COLUMN_DESC, methods[i].desc, -1);
+	}
+
+	filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(store), NULL);
+	gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(filter), COLUMN_VISIBLE);
+	gtk_combo_box_set_model(GTK_COMBO_BOX(priv->type_combo), filter);
+	g_object_set_data(G_OBJECT(filter), "combobox", priv->type_combo);
+	g_object_unref(G_OBJECT(store));
+	g_object_unref(G_OBJECT(filter));
+}
+
+
+/* Update the contents of the bookmark with the values from the dialog. */
+void update_bookmark(SionBookmarkEditDialog *dialog)
+{
+	SionBookmarkEditDialogPrivate *priv;
+	const gchar *tmp;
+	gint idx;
+	GtkTreeIter iter;
+
+	g_return_if_fail(dialog != NULL);
+
+	/// TODO do error checking, at the very least, don't allow empty bookmark names
+
+	priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+	g_return_if_fail(priv->bookmark_update != NULL);
+
+	tmp = gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
+	if (*tmp)
+		sion_bookmark_set_name(priv->bookmark_update, tmp);
+
+	if (! gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->type_combo), &iter))
+		return;
+
+	gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->type_combo)),
+			    &iter, COLUMN_INDEX, &idx, -1);
+
+	if (idx == -1)
+		idx = 0;
+	if (methods[idx].scheme == NULL)
+		sion_bookmark_set_uri(priv->bookmark_update, gtk_entry_get_text(GTK_ENTRY(priv->uri_entry)));
+	else
+	{
+		sion_bookmark_set_scheme(priv->bookmark_update, methods[idx].scheme);
+
+		tmp = gtk_entry_get_text(GTK_ENTRY(priv->server_entry));
+		if (*tmp)
+			sion_bookmark_set_host(priv->bookmark_update, tmp);
+		tmp = gtk_entry_get_text(GTK_ENTRY(priv->user_entry));
+		if (*tmp)
+			sion_bookmark_set_user(priv->bookmark_update, tmp);
+		sion_bookmark_set_port(priv->bookmark_update,
+			gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->port_spin)));
+	}
+}
+
+
+static void sion_bookmark_edit_dialog_set_property(GObject *object, guint prop_id,
+												   const GValue *value, GParamSpec *pspec)
+{
+ 	SionBookmarkEditDialog *dialog = SION_BOOKMARK_EDIT_DIALOG(object);
+ 	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+
+	switch (prop_id)
+    {
+    case PROP_BOOKMARK_INIT:
+		priv->bookmark_init = g_value_get_object(value);
+		init_values(dialog);
+		break;
+    case PROP_BOOKMARK_UPDATE:
+		priv->bookmark_update = g_value_get_object(value);
+		update_bookmark(dialog);
+		break;
+    case PROP_MODE:
+    {
+		const gchar *title;
+		const gchar *stock_id;
+		const gchar *button_stock_id;
+
+		switch (g_value_get_int(value))
+		{
+			case SION_BE_MODE_CREATE:
+			{
+				title = _("Create Bookmark");
+				button_stock_id = stock_id = GTK_STOCK_ADD;
+				combo_set_active(priv->type_combo, 0);
+				break;
+			}
+			case SION_BE_MODE_EDIT:
+			{
+				title = _("Edit Bookmark");
+				stock_id = GTK_STOCK_EDIT;
+				button_stock_id = GTK_STOCK_OK;
+				break;
+			}
+			case SION_BE_MODE_CONNECT:
+			default:
+			{
+				title = _("Connect to Server");
+				button_stock_id = stock_id = GTK_STOCK_CONNECT;
+				combo_set_active(priv->type_combo, 0);
+				gtk_widget_hide(priv->name_label);
+				gtk_widget_hide(priv->name_entry);
+				break;
+			}
+		}
+		gtk_window_set_title(GTK_WINDOW(dialog), title);
+		gtk_window_set_icon_name(GTK_WINDOW(dialog), stock_id);
+		gtk_dialog_add_buttons(GTK_DIALOG(dialog), button_stock_id, GTK_RESPONSE_OK, NULL);
+
+		setup_for_type(dialog);
+        break;
+    }
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+
+static void sion_bookmark_edit_dialog_init(SionBookmarkEditDialog *dialog)
+{
+	GtkWidget *label;
+	GtkWidget *table;
+	GtkWidget *combo;
+	GtkWidget *entry;
+	GtkWidget *hbox;
+	GtkWidget *vbox;
+	GtkCellRenderer *renderer;
+	SionBookmarkEditDialogPrivate *priv = SION_BOOKMARK_EDIT_DIALOG_GET_PRIVATE(dialog);
+
+	gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+	gtk_box_set_spacing(GTK_BOX(sion_dialog_get_content_area(GTK_DIALOG(dialog))), 2);
+
+	gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_set_border_width(GTK_CONTAINER (vbox), 5);
+	gtk_box_pack_start(GTK_BOX(sion_dialog_get_content_area(GTK_DIALOG(dialog))),
+		vbox, FALSE, TRUE, 0);
+
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+	priv->table = table = gtk_table_new(8, 2, FALSE);
+	gtk_table_set_row_spacings(GTK_TABLE(table), 6);
+	gtk_table_set_col_spacings(GTK_TABLE(table), 12);
+	gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
+
+	priv->name_label = gtk_label_new_with_mnemonic(_("_Bookmark name:"));
+	gtk_misc_set_alignment(GTK_MISC(priv->name_label), 0.0, 0.5);
+	gtk_table_attach(GTK_TABLE(table), priv->name_label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+	priv->name_entry = entry = gtk_entry_new();
+	gtk_label_set_mnemonic_widget(GTK_LABEL(priv->name_label), entry);
+	gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+	label = gtk_label_new_with_mnemonic(_("Service _type:"));
+	gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+	gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+	priv->type_combo = combo = gtk_combo_box_new();
+	gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+	label = gtk_label_new(" ");
+	gtk_table_attach(GTK_TABLE(table), label, 0, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
+	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer, "text", COLUMN_DESC);
+
+	fill_method_combo_box(dialog);
+
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label), combo);
+	g_signal_connect(combo, "changed", G_CALLBACK(combo_changed_callback), dialog);
+
+	priv->uri_entry = gtk_entry_new();
+	priv->server_entry = gtk_entry_new();
+	priv->port_spin = gtk_spin_button_new_with_range(0, 65536, 1);
+	gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->port_spin), 0);
+	gtk_widget_set_tooltip_text(priv->port_spin, _("Set the port to 0 to use the default port."));
+	priv->user_entry = gtk_entry_new();
+
+	priv->uri_label = gtk_label_new_with_mnemonic(_("_Location (URI):"));
+	priv->server_label = gtk_label_new_with_mnemonic(_("_Server:"));
+	priv->user_label = gtk_label_new_with_mnemonic(_("_User Name:"));
+	priv->information_label = gtk_label_new(_("Optional information:"));
+	priv->port_label = gtk_label_new_with_mnemonic(_("_Port:"));
+
+
+	gtk_entry_set_activates_default(GTK_ENTRY(priv->uri_entry), TRUE);
+	gtk_entry_set_activates_default(GTK_ENTRY(priv->server_entry), TRUE);
+	gtk_entry_set_activates_default(GTK_ENTRY(priv->port_spin), TRUE);
+	gtk_entry_set_activates_default(GTK_ENTRY(priv->user_entry), TRUE);
+
+	/* We need an extra ref so we can remove them from the table */
+	g_object_ref(priv->uri_entry);
+	g_object_ref(priv->uri_label);
+	g_object_ref(priv->server_entry);
+	g_object_ref(priv->server_label);
+	g_object_ref(priv->port_label);
+	g_object_ref(priv->port_spin);
+	g_object_ref(priv->user_entry);
+	g_object_ref(priv->user_label);
+	g_object_ref(priv->information_label);
+
+	gtk_widget_show_all(vbox);
+}
+
+
+GtkWidget* sion_bookmark_edit_dialog_new(GtkWidget *parent, SionBookmarkEditDialogMode mode)
+{
+	SionBookmarkEditDialog *dialog = g_object_new(SION_BOOKMARK_EDIT_DIALOG_TYPE,
+		"transient-for", parent,
+		"mode", mode,
+		NULL);
+
+
+	return GTK_WIDGET(dialog);
+}
+
+
+GtkWidget* sion_bookmark_edit_dialog_new_with_bookmark(GtkWidget *parent, SionBookmarkEditDialogMode mode, SionBookmark *bookmark)
+{
+	SionBookmarkEditDialog *dialog = g_object_new(SION_BOOKMARK_EDIT_DIALOG_TYPE,
+		"transient-for", parent,
+		"bookmark-init", bookmark,
+		"mode", mode,
+		NULL);
+
+
+	return GTK_WIDGET(dialog);
+}
+
+


Property changes on: sion/trunk/src/bookmarkeditdialog.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/bookmarkeditdialog.h
===================================================================
--- sion/trunk/src/bookmarkeditdialog.h	                        (rev 0)
+++ sion/trunk/src/bookmarkeditdialog.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,63 @@
+/*
+ *      bookmarkeditdialog.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BOOKMARKEDITDIALOG_H__
+#define __BOOKMARKEDITDIALOG_H__
+
+G_BEGIN_DECLS
+
+#define SION_BOOKMARK_EDIT_DIALOG_TYPE				(sion_bookmark_edit_dialog_get_type())
+#define SION_BOOKMARK_EDIT_DIALOG(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_BOOKMARK_EDIT_DIALOG_TYPE, SionBookmarkEditDialog))
+#define SION_BOOKMARK_EDIT_DIALOG_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_BOOKMARK_EDIT_DIALOG_TYPE, SionBookmarkEditDialogClass))
+#define IS_SION_BOOKMARK_EDIT_DIALOG(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_BOOKMARK_EDIT_DIALOG_TYPE))
+#define IS_SION_BOOKMARK_EDIT_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_BOOKMARK_EDIT_DIALOG_TYPE))
+
+typedef struct _SionBookmarkEditDialog				SionBookmarkEditDialog;
+typedef struct _SionBookmarkEditDialogClass			SionBookmarkEditDialogClass;
+
+
+typedef enum
+{
+	SION_BE_MODE_CREATE,
+	SION_BE_MODE_EDIT,
+	SION_BE_MODE_CONNECT,
+} SionBookmarkEditDialogMode;
+
+struct _SionBookmarkEditDialog
+{
+	GtkDialog parent;
+};
+
+struct _SionBookmarkEditDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+GType		sion_bookmark_edit_dialog_get_type			(void);
+GtkWidget*	sion_bookmark_edit_dialog_new				(GtkWidget *parent, SionBookmarkEditDialogMode mode);
+GtkWidget*	sion_bookmark_edit_dialog_new_with_bookmark	(GtkWidget *parent, SionBookmarkEditDialogMode, SionBookmark *bookmark);
+
+G_END_DECLS
+
+#endif /* __BOOKMARKEDITDIALOG_H__ */


Property changes on: sion/trunk/src/bookmarkeditdialog.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/common.c
===================================================================
--- sion/trunk/src/common.c	                        (rev 0)
+++ sion/trunk/src/common.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,113 @@
+/*
+ *      common.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "main.h"
+
+
+const gchar *sion_find_icon_name(const gchar *request, const gchar *fallback)
+{
+	GtkIconTheme *theme = gtk_icon_theme_get_default();
+
+	if (gtk_icon_theme_has_icon(theme, request))
+		return request;
+	else
+	{
+		debug("icon %s not found, using fallback %s", request, fallback);
+		return fallback;
+	}
+}
+
+
+/* NULL-safe string comparison */
+gboolean sion_str_equal(const gchar *a, const gchar *b)
+{
+	if (a == NULL && b == NULL) return TRUE;
+	else if (a == NULL || b == NULL) return FALSE;
+
+	while (*a == *b++)
+		if (*a++ == '\0')
+			return TRUE;
+
+	return FALSE;
+}
+
+
+gchar *sion_beautify_scheme(const gchar *scheme)
+{
+	gchar *result;
+
+	if (sion_str_equal(scheme, "file"))
+	{
+		result = g_strdup(scheme);
+		/* Capitalise first character */
+		result[0] = g_unichar_toupper(scheme[0]);
+	}
+	else
+		result = g_utf8_strup(scheme, -1);
+
+	return result;
+}
+
+
+/* Are we running in Xfce? */
+gboolean sion_is_desktop_xfce(void)
+{
+	static gboolean check = TRUE;
+	static gboolean is_xfce = FALSE;
+
+	if (check)
+	{
+		gint result;
+		gchar *out = NULL;
+		gboolean success;
+
+		success = g_spawn_command_line_sync("xprop -root _DT_SAVE_MODE", &out, NULL, &result, NULL);
+		if (success && result == 0 && out != NULL && strstr(out, "xfce4") != NULL)
+		{
+			is_xfce = TRUE;
+		}
+		g_free(out);
+
+		check = FALSE;
+	}
+    return is_xfce;
+}
+
+
+/* Can open URLs and email addresses using xdg/exo/gnome-open */
+void sion_show_uri(const gchar *uri)
+{
+	gchar *cmd;
+	gchar *open_cmd = g_find_program_in_path("xdg-open");
+
+	if (open_cmd == NULL)
+		open_cmd = g_strdup((sion_is_desktop_xfce()) ? "exo-open" : "gnome-open");
+
+	cmd = g_strconcat(open_cmd, " ", uri, NULL);
+	g_spawn_command_line_async(cmd, NULL);
+	g_free(cmd);
+	g_free(open_cmd);
+}


Property changes on: sion/trunk/src/common.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/common.h
===================================================================
--- sion/trunk/src/common.h	                        (rev 0)
+++ sion/trunk/src/common.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,62 @@
+/*
+ *      common.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+
+/* Returns: TRUE if @a ptr points to a non-zero value. */
+#define NZV(ptr) \
+	((ptr) && (ptr)[0])
+
+
+enum
+{
+	SION_WINDOW_COL_IS_MOUNTED,
+	SION_WINDOW_COL_SCHEME,
+	SION_WINDOW_COL_NAME,
+	SION_WINDOW_COL_REF,
+	SION_WINDOW_COL_REF_TYPE, /* volume or mount, see enum below */
+	SION_WINDOW_COL_PIXBUF,
+	SION_WINDOW_COL_ICON_NAME,
+	SION_WINDOW_COL_TOOLTIP,
+	SION_WINDOW_N_COLUMNS
+};
+
+enum
+{
+	SION_WINDOW_REF_TYPE_VOLUME,
+	SION_WINDOW_REF_TYPE_MOUNT /* mounted volume */
+};
+
+
+gchar *sion_beautify_scheme(const gchar *scheme);
+
+gboolean sion_str_equal(const gchar *a, const gchar *b);
+
+const gchar *sion_find_icon_name(const gchar *request, const gchar *fallback);
+
+gboolean sion_is_desktop_xfce(void);
+
+void sion_show_uri(const gchar *uri);
+
+
+#endif /* __COMMON_H__ */


Property changes on: sion/trunk/src/common.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/compat.c
===================================================================
--- sion/trunk/src/compat.c	                        (rev 0)
+++ sion/trunk/src/compat.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,56 @@
+/*
+ *      compat.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "compat.h"
+
+
+GdkWindow *sion_widget_get_window(GtkWidget *widget)
+{
+#if GTK_CHECK_VERSION(2, 14, 0)
+	return gtk_widget_get_window(widget);
+#else
+	return widget->window;
+#endif
+}
+
+
+GtkWidget *sion_dialog_get_content_area(GtkDialog *dialog)
+{
+#if GTK_CHECK_VERSION(2, 14, 0)
+	return gtk_dialog_get_content_area(dialog);
+#else
+	return dialog->vbox;
+#endif
+}
+
+
+void sion_status_icon_set_tooltip_text(GtkStatusIcon *status_icon, const gchar *tooltip_text)
+{
+#if GTK_CHECK_VERSION(2, 16, 0)
+	gtk_status_icon_set_tooltip_text(status_icon, tooltip_text);
+#else
+	gtk_status_icon_set_tooltip(status_icon, tooltip_text);
+#endif
+}
+


Property changes on: sion/trunk/src/compat.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/compat.h
===================================================================
--- sion/trunk/src/compat.h	                        (rev 0)
+++ sion/trunk/src/compat.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,32 @@
+/*
+ *      compat.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __COMPAT_H__
+#define __COMPAT_H__
+
+
+GdkWindow *sion_widget_get_window(GtkWidget *widget);
+
+GtkWidget *sion_dialog_get_content_area(GtkDialog *dialog);
+
+void sion_status_icon_set_tooltip_text(GtkStatusIcon *status_icon, const gchar *tooltip_text);
+
+
+#endif /* __COMPAT_H__ */
+


Property changes on: sion/trunk/src/compat.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/main.c
===================================================================
--- sion/trunk/src/main.c	                        (rev 0)
+++ sion/trunk/src/main.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,140 @@
+/*
+ *      main.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "main.h"
+#include "settings.h"
+#include "window.h"
+
+
+static gboolean show_version = FALSE;
+static gboolean verbose_mode = FALSE;
+static gboolean list_schemes = FALSE;
+
+static GOptionEntry cli_options[] =
+{
+	{ "list-schemes", 'l', 0, G_OPTION_ARG_NONE, &list_schemes, N_("Print a list of supported URI schemes"), NULL },
+	{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_mode, N_("Be verbose"), NULL },
+	{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Show version information"), NULL },
+	{ NULL, 0, 0, 0, NULL, NULL, NULL }
+};
+
+
+#ifdef DEBUG
+void debug(gchar const *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
+	va_end(args);
+}
+#endif
+
+
+void verbose(gchar const *format, ...)
+{
+#ifndef DEBUG
+	if (verbose_mode)
+#endif
+	{
+		va_list args;
+		va_start(args, format);
+		g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
+		va_end(args);
+	}
+}
+
+
+void print_supported_schemes(void)
+{
+	const gchar* const *supported;
+	gint j;
+
+	supported = g_vfs_get_supported_uri_schemes(g_vfs_get_default());
+	for (j = 0; supported[j] != NULL; j++)
+	{
+		g_print("%s\n", supported[j]);
+	}
+}
+
+
+gint main(gint argc, gchar** argv)
+{
+	SionSettings *settings;
+	const gchar *vm_impl;
+	GOptionContext *context;
+	GtkWidget *window;
+
+    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+    textdomain(GETTEXT_PACKAGE);
+
+	context = g_option_context_new(_("- a simple frontend to easily connect to remote filesystems"));
+	g_option_context_add_main_entries(context, cli_options, GETTEXT_PACKAGE);
+	g_option_group_set_translation_domain(g_option_context_get_main_group(context), GETTEXT_PACKAGE);
+	g_option_context_add_group(context, gtk_get_option_group(FALSE));
+	g_option_context_parse(context, &argc, &argv, NULL);
+	g_option_context_free(context);
+
+	gtk_init(&argc, &argv);
+
+	if (show_version)
+	{
+		g_print("%s %s\n\n", PACKAGE, VERSION);
+		g_print("%s\n", "Copyright (c) 2008");
+		g_print("\tEnrico Tröger <enrico at xfce.org>\n\n");
+		g_print("\n");
+
+		return EXIT_SUCCESS;
+	}
+
+	if (list_schemes)
+	{
+		print_supported_schemes();
+
+		return EXIT_SUCCESS;
+	}
+
+	settings = sion_settings_new();
+
+	// GVFS currently depends on gnome-mount for HAL-based GVolumeMonitor implementation,
+	// when gnome-mount is not installed, we can use "unix" as GVolumeMonitor implementation.
+	if ((vm_impl = sion_settings_get_vm_impl(settings)) != NULL)
+		setenv("GIO_USE_VOLUME_MONITOR", vm_impl, 0);
+
+	window = sion_window_new(settings);
+    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
+
+	gtk_widget_show(window);
+
+	gtk_main();
+
+	g_object_unref(settings);
+
+	return 0;
+}


Property changes on: sion/trunk/src/main.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/main.h
===================================================================
--- sion/trunk/src/main.h	                        (rev 0)
+++ sion/trunk/src/main.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,32 @@
+/*
+ *      main.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#ifdef DEBUG
+void debug(gchar const *format, ...);
+#else
+# define debug(...)
+#endif
+
+void verbose(gchar const *format, ...);
+
+
+#endif /* __MAIN_H__ */


Property changes on: sion/trunk/src/main.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/menubuttonaction.c
===================================================================
--- sion/trunk/src/menubuttonaction.c	                        (rev 0)
+++ sion/trunk/src/menubuttonaction.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,262 @@
+/*
+ *      menubuttonaction.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "bookmark.h"
+#include "settings.h"
+#include "menubuttonaction.h"
+
+
+enum
+{
+	PROP_0,
+	PROP_SETTINGS
+};
+
+enum
+{
+	ITEM_CLICKED,
+	BUTTON_CLICKED,
+
+	LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL];
+
+
+static void sion_menu_button_action_class_init			(SionMenubuttonActionClass *klass);
+static void sion_menu_button_action_init      			(SionMenubuttonAction *action);
+
+static GtkActionClass *parent_class = NULL;
+
+GType sion_menu_button_action_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionMenubuttonActionClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_menu_button_action_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionMenubuttonAction),
+			0,
+			(GInstanceInitFunc)sion_menu_button_action_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_ACTION, "SionMenubuttonAction", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void delegate_item_activated(GtkMenuItem *item, SionMenubuttonAction *action)
+{
+	g_signal_emit(action, signals[ITEM_CLICKED], 0, item);
+}
+
+
+static void delegate_button_activated(GtkAction *action)
+{
+	g_signal_emit(action, signals[BUTTON_CLICKED], 0);
+}
+
+
+static GtkWidget *sion_menu_button_action_create_menu_item(GtkAction *action)
+{
+	GtkWidget *menuitem;
+
+	menuitem = g_object_new(GTK_TYPE_IMAGE_MENU_ITEM, NULL);
+
+	return menuitem;
+}
+
+
+static GtkWidget *sion_menu_button_action_create_tool_item(GtkAction *action)
+{
+	GtkWidget *toolitem;
+
+	toolitem = g_object_new(GTK_TYPE_MENU_TOOL_BUTTON, NULL);
+
+	return toolitem;
+}
+
+
+static void set_menu(GtkWidget *item, GtkWidget *menu)
+{
+	if (GTK_IS_MENU_ITEM(item))
+		gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
+	else
+		gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), menu);
+}
+
+
+static GtkWidget *get_menu(GtkWidget *item)
+{
+	if (GTK_IS_MENU_ITEM(item))
+		return gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
+	else
+		return gtk_menu_tool_button_get_menu(GTK_MENU_TOOL_BUTTON(item));
+}
+
+
+static void update_menus(SionMenubuttonAction *action, SionSettings *settings)
+{
+	GSList *l;
+	GtkWidget *menu;
+	guint i;
+	GtkWidget *item;
+	SionBookmark *bm;
+	SionBookmarkList *bml = sion_settings_get_bookmarks(settings);
+
+	for (l = gtk_action_get_proxies(GTK_ACTION(action)); l; l = l->next)
+	{
+		menu = get_menu(l->data);
+
+		if (GTK_IS_MENU_ITEM(l->data))
+			gtk_widget_set_sensitive(l->data, (bml->len > 0));
+
+		if (bml->len == 0)
+		{
+			if (menu != NULL)
+				set_menu(l->data, NULL);
+			continue;
+		}
+
+		if (menu != NULL)
+		{	// clear the old menu items
+			gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback) gtk_widget_destroy, NULL);
+		}
+		else
+		{	// create new menu
+			menu = gtk_menu_new();
+			set_menu(l->data, menu);
+		}
+
+		for (i = 0; i < bml->len; i++)
+		{
+			bm = g_ptr_array_index(bml, i);
+			item = gtk_menu_item_new_with_label(sion_bookmark_get_name(bm));
+			g_object_set_data(G_OBJECT(item), "bookmark", bm);
+			gtk_container_add(GTK_CONTAINER(menu), item);
+			gtk_widget_show(item);
+			g_signal_connect(item, "activate", G_CALLBACK(delegate_item_activated), action);
+		}
+	}
+}
+
+
+static void sion_menu_button_action_connect_proxy(GtkAction *action, GtkWidget *widget)
+{
+	GTK_ACTION_CLASS(parent_class)->connect_proxy(action, widget);
+
+	/* Overwrite the icon and label of the toolbar button */
+	if (GTK_IS_TOOL_BUTTON(widget))
+	{
+		gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(widget), GTK_STOCK_CONNECT);
+		gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Connect"));
+	}
+}
+
+
+static void sion_menu_button_action_set_property(GObject *object, guint prop_id,
+												 const GValue *value, GParamSpec *pspec)
+{
+	SionMenubuttonAction *action = SION_MENU_BUTTON_ACTION(object);
+
+	switch (prop_id)
+	{
+	case PROP_SETTINGS:
+		update_menus(action, g_value_get_object(value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void sion_menu_button_action_class_init(SionMenubuttonActionClass *klass)
+{
+	GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
+	GtkActionClass *action_class = GTK_ACTION_CLASS(klass);
+
+	g_object_class->set_property = sion_menu_button_action_set_property;
+
+	action_class->activate = delegate_button_activated;
+	action_class->connect_proxy = sion_menu_button_action_connect_proxy;
+	action_class->create_menu_item = sion_menu_button_action_create_menu_item;
+	action_class->create_tool_item = sion_menu_button_action_create_tool_item;
+	action_class->menu_item_type = GTK_TYPE_IMAGE_MENU_ITEM;
+	action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
+
+	parent_class = (GtkActionClass*)g_type_class_peek(GTK_TYPE_ACTION);
+
+	g_object_class_install_property(g_object_class,
+										PROP_SETTINGS,
+										g_param_spec_object (
+										"settings",
+										"Settings",
+										"The associated settings",
+										SION_SETTINGS_TYPE,
+										G_PARAM_WRITABLE));
+
+	signals[ITEM_CLICKED] = g_signal_new("item-clicked",
+										G_TYPE_FROM_CLASS(klass),
+										(GSignalFlags) 0,
+										0,
+										0,
+										NULL,
+										g_cclosure_marshal_VOID__OBJECT,
+										G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	signals[BUTTON_CLICKED] = g_signal_new("button-clicked",
+										G_TYPE_FROM_CLASS(klass),
+										(GSignalFlags) 0,
+										0,
+										0,
+										NULL,
+										g_cclosure_marshal_VOID__VOID,
+										G_TYPE_NONE, 0);
+}
+
+
+static void sion_menu_button_action_init(SionMenubuttonAction *action)
+{
+}
+
+
+GtkAction *sion_menu_button_action_new(const gchar *name, const gchar *label,
+									   const gchar *tooltip, const gchar *icon_name)
+{
+	GtkAction *action = g_object_new(SION_MENU_BUTTON_ACTION_TYPE,
+		"name", name, "label", label, "tooltip", tooltip, "icon-name", icon_name, NULL);
+
+	return action;
+}
+


Property changes on: sion/trunk/src/menubuttonaction.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/menubuttonaction.h
===================================================================
--- sion/trunk/src/menubuttonaction.h	                        (rev 0)
+++ sion/trunk/src/menubuttonaction.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,57 @@
+/*
+ *      menubuttonaction.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __MENU_BUTTON_ACTION_H__
+#define __MENU_BUTTON_ACTION_H__
+
+G_BEGIN_DECLS
+
+#define SION_MENU_BUTTON_ACTION_TYPE				(sion_menu_button_action_get_type())
+#define SION_MENU_BUTTON_ACTION(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_MENU_BUTTON_ACTION_TYPE, SionMenubuttonAction))
+#define SION_MENU_BUTTON_ACTION_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_MENU_BUTTON_ACTION_TYPE, SionMenubuttonActionClass))
+#define IS_SION_MENU_BUTTON_ACTION(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_MENU_BUTTON_ACTION_TYPE))
+#define IS_SION_MENU_BUTTON_ACTION_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_MENU_BUTTON_ACTION_TYPE))
+
+typedef struct _SionMenubuttonAction			SionMenubuttonAction;
+typedef struct _SionMenubuttonActionClass		SionMenubuttonActionClass;
+
+struct _SionMenubuttonAction
+{
+	GtkAction parent;
+};
+
+struct _SionMenubuttonActionClass
+{
+	GtkActionClass parent_class;
+};
+
+GType		sion_menu_button_action_get_type	(void);
+GtkAction*	sion_menu_button_action_new			(const gchar	*name,
+												 const gchar	*label,
+												 const gchar	*tooltip,
+												 const gchar	*icon_name);
+
+G_END_DECLS
+
+#endif /* __MENU_BUTTON_ACTION_H__ */


Property changes on: sion/trunk/src/menubuttonaction.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/passworddialog.c
===================================================================
--- sion/trunk/src/passworddialog.c	                        (rev 0)
+++ sion/trunk/src/passworddialog.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,219 @@
+/*
+ *      passworddialog.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include "main.h"
+#include "compat.h"
+#include "passworddialog.h"
+
+typedef struct _SionPasswordDialogPrivate			SionPasswordDialogPrivate;
+
+#define SION_PASSWORD_DIALOG_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_PASSWORD_DIALOG_TYPE, SionPasswordDialogPrivate))
+
+struct _SionPasswordDialogPrivate
+{
+	GtkWidget *box_domain;
+	GtkWidget *box_username;
+	GtkWidget *box_password;
+
+	GtkWidget *entry_domain;
+	GtkWidget *entry_username;
+	GtkWidget *entry_password;
+};
+
+static void sion_password_dialog_class_init			(SionPasswordDialogClass *klass);
+static void sion_password_dialog_init      			(SionPasswordDialog *dialog);
+
+/* Local data */
+static GtkDialogClass *parent_class = NULL;
+
+GType sion_password_dialog_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionPasswordDialogClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_password_dialog_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionPasswordDialog),
+			0,
+			(GInstanceInitFunc)sion_password_dialog_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_DIALOG, "SionPasswordDialog", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void sion_password_dialog_class_init(SionPasswordDialogClass *klass)
+{
+	parent_class = (GtkDialogClass*)g_type_class_peek(GTK_TYPE_DIALOG);
+	g_type_class_add_private((gpointer)klass, sizeof(SionPasswordDialogPrivate));
+}
+
+
+static void entry_activate_cb(GtkEntry *entry, gpointer user_data)
+{
+	gtk_dialog_response(GTK_DIALOG(user_data), GTK_RESPONSE_OK);
+}
+
+
+static void sion_password_dialog_init(SionPasswordDialog *dialog)
+{
+	GtkWidget *vbox;
+	GtkWidget *dialog_vbox;
+	GtkWidget *label;
+	GtkSizeGroup *size_group;
+	SionPasswordDialogPrivate *priv = SION_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+	dialog_vbox = sion_dialog_get_content_area(GTK_DIALOG(dialog));
+
+	gtk_window_set_title(GTK_WINDOW(dialog), _("Authentication information needed"));
+	//~ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+	gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+	gtk_box_set_spacing(GTK_BOX(dialog_vbox), 2);
+	//~ gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+
+	gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
+
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+	gtk_box_pack_start(GTK_BOX(dialog_vbox), vbox, FALSE, TRUE, 0);
+
+	gtk_widget_show_all(GTK_WIDGET(dialog));
+
+	size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+	/* Domain */
+	priv->entry_domain = gtk_entry_new();
+	g_signal_connect(priv->entry_domain, "activate", G_CALLBACK(entry_activate_cb), dialog);
+	label = gtk_label_new_with_mnemonic(_("_Domain:"));
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label), priv->entry_domain);
+	priv->box_domain = gtk_hbox_new(FALSE, 3);
+	gtk_box_pack_start(GTK_BOX(priv->box_domain), label, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(priv->box_domain), priv->entry_domain, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+	gtk_widget_show(priv->entry_domain);
+	gtk_size_group_add_widget(size_group, label);
+
+	/* Username */
+	priv->entry_username = gtk_entry_new();
+	g_signal_connect(priv->entry_username, "activate", G_CALLBACK(entry_activate_cb), dialog);
+	label = gtk_label_new_with_mnemonic(_("_Username:"));
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label), priv->entry_username);
+	priv->box_username = gtk_hbox_new(FALSE, 3);
+	gtk_box_pack_start(GTK_BOX(priv->box_username), label, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(priv->box_username), priv->entry_username, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+	gtk_widget_show(priv->entry_username);
+	gtk_size_group_add_widget(size_group, label);
+
+	/* Password */
+	priv->entry_password = gtk_entry_new();
+	gtk_entry_set_visibility(GTK_ENTRY(priv->entry_password), FALSE);
+	g_signal_connect(priv->entry_password, "activate", G_CALLBACK(entry_activate_cb), dialog);
+	label = gtk_label_new_with_mnemonic(_("_Password:"));
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label), priv->entry_password);
+	priv->box_password = gtk_hbox_new(FALSE, 3);
+	gtk_box_pack_start(GTK_BOX(priv->box_password), label, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(priv->box_password), priv->entry_password, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+	gtk_widget_show(priv->entry_password);
+	gtk_size_group_add_widget(size_group, label);
+
+	gtk_box_pack_start(GTK_BOX(vbox), priv->box_domain, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), priv->box_username, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), priv->box_password, FALSE, FALSE, 0);
+
+	g_object_unref(size_group);
+}
+
+
+GtkWidget *sion_password_dialog_new(GAskPasswordFlags flags)
+{
+	GtkWidget *dialog = g_object_new(SION_PASSWORD_DIALOG_TYPE, NULL);
+	SionPasswordDialogPrivate *priv = SION_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+	/** Implement G_ASK_PASSWORD_SAVING_SUPPORTED */
+	if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+	{
+		gtk_widget_show(priv->box_password);
+		gtk_widget_grab_focus(priv->entry_password);
+	}
+	if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+	{
+		gtk_widget_show(priv->box_username);
+		gtk_widget_grab_focus(priv->entry_username);
+	}
+	if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+	{
+		gtk_widget_show(priv->box_domain);
+		gtk_widget_grab_focus(priv->entry_domain);
+	}
+
+	return dialog;
+}
+
+
+const gchar *sion_password_dialog_get_domain(SionPasswordDialog *dialog)
+{
+	g_return_val_if_fail(dialog != NULL, NULL);
+
+	return gtk_entry_get_text(GTK_ENTRY(
+		SION_PASSWORD_DIALOG_GET_PRIVATE(dialog)->entry_domain));
+}
+
+
+const gchar *sion_password_dialog_get_username(SionPasswordDialog *dialog)
+{
+	g_return_val_if_fail(dialog != NULL, NULL);
+
+	return gtk_entry_get_text(GTK_ENTRY(
+		SION_PASSWORD_DIALOG_GET_PRIVATE(dialog)->entry_username));
+}
+
+
+const gchar *sion_password_dialog_get_password(SionPasswordDialog *dialog)
+{
+	g_return_val_if_fail(dialog != NULL, NULL);
+
+	return gtk_entry_get_text(GTK_ENTRY(
+		SION_PASSWORD_DIALOG_GET_PRIVATE(dialog)->entry_password));
+}
+


Property changes on: sion/trunk/src/passworddialog.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/passworddialog.h
===================================================================
--- sion/trunk/src/passworddialog.h	                        (rev 0)
+++ sion/trunk/src/passworddialog.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,58 @@
+/*
+ *      passworddialog.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __PASSWORDDIALOG_H__
+#define __PASSWORDDIALOG_H__
+
+G_BEGIN_DECLS
+
+#define SION_PASSWORD_DIALOG_TYPE				(sion_password_dialog_get_type())
+#define SION_PASSWORD_DIALOG(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_PASSWORD_DIALOG_TYPE, SionPasswordDialog))
+#define SION_PASSWORD_DIALOG_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_PASSWORD_DIALOG_TYPE, SionPasswordDialogClass))
+#define IS_SION_PASSWORD_DIALOG(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_PASSWORD_DIALOG_TYPE))
+#define IS_SION_PASSWORD_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_PASSWORD_DIALOG_TYPE))
+
+typedef struct _SionPasswordDialog			SionPasswordDialog;
+typedef struct _SionPasswordDialogClass		SionPasswordDialogClass;
+
+struct _SionPasswordDialog
+{
+	GtkDialog parent;
+};
+
+struct _SionPasswordDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+GType			sion_password_dialog_get_type		(void);
+GtkWidget*		sion_password_dialog_new			(GAskPasswordFlags flags);
+
+const gchar*	sion_password_dialog_get_domain		(SionPasswordDialog *dialog);
+const gchar*	sion_password_dialog_get_username	(SionPasswordDialog *dialog);
+const gchar*	sion_password_dialog_get_password	(SionPasswordDialog *dialog);
+
+G_END_DECLS
+
+#endif /* __PASSWORDDIALOG_H__ */


Property changes on: sion/trunk/src/passworddialog.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/preferencesdialog.c
===================================================================
--- sion/trunk/src/preferencesdialog.c	                        (rev 0)
+++ sion/trunk/src/preferencesdialog.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,505 @@
+/*
+ *      preferencesdialog.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "common.h"
+#include "compat.h"
+#include "settings.h"
+#include "window.h"
+#include "preferencesdialog.h"
+
+
+typedef struct _SionPreferencesDialogPrivate			SionPreferencesDialogPrivate;
+
+#define SION_PREFERENCES_DIALOG_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+			SION_PREFERENCES_DIALOG_TYPE, SionPreferencesDialogPrivate))
+
+struct _SionPreferencesDialogPrivate
+{
+	SionWindow	*window;
+};
+
+static void sion_preferences_dialog_class_init			(SionPreferencesDialogClass *klass);
+static void sion_preferences_dialog_init      			(SionPreferencesDialog *dialog);
+
+static GtkDialogClass *parent_class = NULL;
+
+enum
+{
+    PROP_0,
+    PROP_SETTINGS
+};
+
+GType sion_preferences_dialog_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionPreferencesDialogClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_preferences_dialog_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionPreferencesDialog),
+			0,
+			(GInstanceInitFunc)sion_preferences_dialog_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_DIALOG, "SionPreferencesDialog", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+/* Create an Xfce header with icon and title (only used on Xfce).
+ * (Code from Midori, thanks to Christian Dywan.) */
+static GtkWidget *xfce_header_new(const gchar *icon, const gchar *title)
+{
+	GtkWidget *entry;
+	gchar *markup;
+	GtkWidget *xfce_heading;
+	GtkWidget *hbox;
+	GtkWidget *image;
+	GtkWidget *label;
+	GdkColor *color;
+
+	xfce_heading = gtk_event_box_new();
+	entry = gtk_entry_new();
+	color = &(gtk_widget_get_style(entry)->base[GTK_STATE_NORMAL]);
+	gtk_widget_modify_bg(xfce_heading, GTK_STATE_NORMAL, color);
+	hbox = gtk_hbox_new(FALSE, 12);
+	gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
+	image = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_DIALOG);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	label = gtk_label_new(NULL);
+	color = &(gtk_widget_get_style(entry)->text[GTK_STATE_NORMAL]);
+	gtk_widget_modify_fg(label, GTK_STATE_NORMAL, color);
+	markup = g_strdup_printf("<span size='large' weight='bold'>%s</span>", title);
+	gtk_label_set_markup(GTK_LABEL(label), markup);
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(xfce_heading), hbox);
+	g_free(markup);
+
+	gtk_widget_destroy(entry);
+
+	return xfce_heading;
+}
+
+
+/* Create a frame with no actual frame but a bold label and indentation.
+ * (Code from Midori, thanks to Christian Dywan.) */
+static GtkWidget *hig_frame_new(const gchar* title)
+{
+	GtkWidget *frame = gtk_frame_new(NULL);
+	gchar *title_bold = g_strdup_printf("<b>%s</b>", title);
+	GtkWidget *label = gtk_label_new(NULL);
+
+	gtk_label_set_markup(GTK_LABEL(label), title_bold);
+	g_free(title_bold);
+	gtk_frame_set_label_widget(GTK_FRAME(frame), label);
+	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
+	gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
+
+	return frame;
+}
+
+
+static void vm_imple_toggle_cb(GtkToggleButton *button, SionSettings *settings)
+{
+	sion_settings_set_vm_impl(settings, g_object_get_data(G_OBJECT(button), "impl"));
+}
+
+
+static void check_button_toggle_cb(GtkToggleButton *button, SionSettings *settings)
+{
+    gboolean toggled = gtk_toggle_button_get_active(button);
+    const gchar* property = g_object_get_data(G_OBJECT(button), "property");
+
+	g_object_set(settings, property, toggled, NULL);
+}
+
+
+static GtkWidget *add_check_button(SionSettings *settings, const gchar *property, const gchar *text)
+{
+	gboolean toggled;
+	GtkWidget *widget;
+
+	g_object_get(settings, property, &toggled, NULL);
+	widget = gtk_check_button_new_with_mnemonic(text);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toggled);
+
+	g_object_set_data(G_OBJECT(widget), "property", (gpointer) property);
+	g_signal_connect(widget, "toggled", G_CALLBACK(check_button_toggle_cb), settings);
+
+	return widget;
+}
+
+
+static void combo_box_changed_cb(GtkComboBox* button, SionSettings *settings)
+{
+    gint value = gtk_combo_box_get_active(button);
+    const gchar *property = g_object_get_data(G_OBJECT(button), "property");
+
+	g_object_set(settings, property, value, NULL);
+}
+
+
+static GtkWidget *add_toolbar_style_combo(SionSettings *settings, const gchar *property)
+{
+	gint value;
+	GtkWidget *widget;
+
+	g_object_get(settings, property, &value, NULL);
+
+	widget = gtk_combo_box_new_text();
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Icons"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Text"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Both"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Both horizontal"));
+
+	gtk_combo_box_set_active(GTK_COMBO_BOX(widget), value);
+
+	g_object_set_data(G_OBJECT(widget), "property", (gpointer) property);
+	g_signal_connect(widget, "changed", G_CALLBACK(combo_box_changed_cb), settings);
+
+	return widget;
+}
+
+
+static GtkWidget *add_toolbar_orientation_combo(SionSettings *settings, const gchar *property)
+{
+	gint value;
+	GtkWidget *widget;
+
+	g_object_get(settings, property, &value, NULL);
+
+	widget = gtk_combo_box_new_text();
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Horizontal"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Vertical"));
+
+	gtk_combo_box_set_active(GTK_COMBO_BOX(widget), value);
+
+	g_object_set_data(G_OBJECT(widget), "property", (gpointer) property);
+	g_signal_connect(widget, "changed", G_CALLBACK(combo_box_changed_cb), settings);
+
+	return widget;
+}
+
+
+static GtkWidget *add_view_mode_combo(SionSettings *settings, const gchar *property)
+{
+	gint value;
+	GtkWidget *widget;
+
+	g_object_get(settings, property, &value, NULL);
+
+	widget = gtk_combo_box_new_text();
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Symbols"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(widget), _("Detailed"));
+
+	gtk_combo_box_set_active(GTK_COMBO_BOX(widget), value);
+
+	g_object_set_data(G_OBJECT(widget), "property", (gpointer) property);
+	g_signal_connect(widget, "changed", G_CALLBACK(combo_box_changed_cb), settings);
+
+	return widget;
+}
+
+
+static void entry_check_input(GtkEntry *entry)
+{
+	const gchar *command;
+	gchar *first_space;
+	gchar *first_part;
+	gchar *path;
+	GtkImage *icon = g_object_get_data(G_OBJECT(entry), "image");
+
+	command = gtk_entry_get_text(entry);
+	if ((first_space = strstr(command, " ")))
+		first_part = g_strndup(command, first_space - command);
+	else
+		first_part = g_strdup(command);
+
+	path = g_find_program_in_path(first_part);
+
+	if (path != NULL)
+	{
+		if (gtk_icon_theme_has_icon(gtk_icon_theme_get_for_screen(
+				gtk_widget_get_screen(GTK_WIDGET(entry))), first_part))
+		{
+			gtk_image_set_from_icon_name(icon, first_part, GTK_ICON_SIZE_MENU);
+		}
+		else
+			gtk_image_set_from_stock(icon, GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU);
+		g_free(path);
+	}
+	else
+		gtk_image_set_from_stock(icon, GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
+
+	g_free(first_part);
+
+}
+
+
+static void entry_activate_cb(GtkEntry *entry, SionSettings *settings)
+{
+	const gchar *text = gtk_entry_get_text(entry);
+	const gchar *property = g_object_get_data(G_OBJECT(entry), "property");
+
+	g_object_set(settings, property, text, NULL);
+	entry_check_input(entry);
+}
+
+
+static gboolean entry_focus_out_event_cb(GtkEntry *entry, GdkEventFocus *event,
+										 SionSettings *settings)
+{
+	const gchar *text = gtk_entry_get_text(entry);
+	const gchar *property = g_object_get_data(G_OBJECT(entry), "property");
+
+	g_object_set(settings, property, text, NULL);
+	entry_check_input(entry);
+
+	return FALSE;
+}
+
+
+static GtkWidget *add_program_entry(SionSettings *settings, const gchar *property)
+{
+	GtkWidget *widget;
+	gchar *string;
+
+	widget = gtk_entry_new();
+	g_object_get(settings, property, &string, NULL);
+
+	if (string != NULL)
+		gtk_entry_set_text(GTK_ENTRY(widget), string);
+
+	g_object_set_data(G_OBJECT(widget), "property", (gpointer) property);
+	g_signal_connect(widget, "activate", G_CALLBACK(entry_activate_cb), settings);
+	g_signal_connect(widget, "focus-out-event",  G_CALLBACK(entry_focus_out_event_cb), settings);
+
+	return widget;
+}
+
+
+static void set_settings(SionPreferencesDialog *dialog, SionSettings *settings)
+{
+	GtkWidget *frame, *frame_vbox, *align, *vbox, *hbox;
+	GtkWidget *radio1, *radio2, *checkbox, *combo, *entry;
+	GtkWidget *label1, *label2, *label3, *label4, *image;
+	GSList *rlist;
+	GtkSizeGroup *sg;
+
+    vbox = sion_dialog_get_content_area(GTK_DIALOG(dialog));
+
+	if (sion_is_desktop_xfce())
+    {
+		GtkWidget *heading;
+		heading = xfce_header_new(
+			sion_window_get_icon_name(),
+			gtk_window_get_title(GTK_WINDOW(dialog)));
+		gtk_box_pack_start(GTK_BOX(vbox), heading, FALSE, FALSE, 0);
+	}
+
+	frame = hig_frame_new(_("General"));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 6);
+
+	align = gtk_alignment_new(0, 0.5, 0, 0);
+	gtk_container_add(GTK_CONTAINER(frame), align);
+
+	frame_vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_set_border_width(GTK_CONTAINER(frame_vbox), 4); \
+	gtk_container_add(GTK_CONTAINER(align), frame_vbox);
+
+	radio1 = gtk_radio_button_new_with_mnemonic(NULL, _("Use _HAL based volume manager"));
+	/// TODO fix this string to be more descriptive and clear
+	gtk_widget_set_tooltip_text(radio1, _("This option sets the implementation of the volume manager. In general, this should be left to HAL. Please note, this option requires a restart of Sion."));
+	rlist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio1));
+	if (strcmp(sion_settings_get_vm_impl(settings), "hal") == 0)
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio1), TRUE);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), radio1, FALSE, FALSE, 0);
+	g_object_set_data(G_OBJECT(radio1), "impl", "hal");
+
+	radio2 = gtk_radio_button_new_with_mnemonic(rlist, _("Use _Unix based volume manager"));
+	gtk_widget_set_tooltip_text(radio2, _("This option sets the implementation of the volume manager. In general, this should be left to HAL. Please note, this option requires a restart of Sion."));
+	rlist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio2));
+	if (strcmp(sion_settings_get_vm_impl(settings), "unix") == 0)
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio2), TRUE);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), radio2, FALSE, FALSE, 0);
+	g_object_set_data(G_OBJECT(radio2), "impl", "unix");
+
+	g_signal_connect(radio1, "toggled", G_CALLBACK(vm_imple_toggle_cb), settings);
+	g_signal_connect(radio2, "toggled", G_CALLBACK(vm_imple_toggle_cb), settings);
+
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 0);
+
+	label1 = gtk_label_new_with_mnemonic(_("_File Manager"));
+	gtk_misc_set_alignment(GTK_MISC(label1), 0.0f, 0.5f);
+	gtk_box_pack_start(GTK_BOX(hbox), label1, FALSE, FALSE, 0);
+
+	image = gtk_image_new();
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 3);
+
+	entry = add_program_entry(settings, "file-manager");
+	gtk_widget_set_tooltip_text(entry, _("Enter the name of a program to use to open or view mount points"));
+	g_object_set_data(G_OBJECT(entry), "image", image);
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label1), entry);
+	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
+	entry_check_input(GTK_ENTRY(entry));
+
+	frame = hig_frame_new(_("Interface"));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 6);
+
+	align = gtk_alignment_new(0, 0.5, 0, 0);
+	gtk_container_add(GTK_CONTAINER(frame), align);
+
+	frame_vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_set_border_width(GTK_CONTAINER(frame_vbox), 4); \
+	gtk_container_add(GTK_CONTAINER(align), frame_vbox);
+
+	checkbox = add_check_button(settings, "save-geometry", _("_Save window position and geometry"));
+	gtk_widget_set_tooltip_text(checkbox, _("Saves the window position and geometry and restores it at the start"));
+	gtk_box_pack_start(GTK_BOX(frame_vbox), checkbox, FALSE, FALSE, 0);
+
+	checkbox = add_check_button(settings, "show-trayicon", _("Show tray _icon"));
+	gtk_box_pack_start(GTK_BOX(frame_vbox), checkbox, FALSE, FALSE, 0);
+
+	checkbox = add_check_button(settings, "show-toolbar", _("Show _toolbar"));
+	gtk_box_pack_start(GTK_BOX(frame_vbox), checkbox, FALSE, FALSE, 0);
+
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 0);
+
+	label2 = gtk_label_new_with_mnemonic(_("Toolbar St_yle"));
+	gtk_misc_set_alignment(GTK_MISC(label2), 0.0f, 0.5f);
+	gtk_box_pack_start(GTK_BOX(hbox), label2, FALSE, FALSE, 0);
+
+	combo = add_toolbar_style_combo(settings, "toolbar-style");
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label2), combo);
+	gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
+
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 0);
+
+	label3 = gtk_label_new_with_mnemonic(_("Toolbar _Orientation"));
+	gtk_misc_set_alignment(GTK_MISC(label3), 0.0f, 0.5f);
+	gtk_box_pack_start(GTK_BOX(hbox), label3, FALSE, FALSE, 0);
+
+	combo = add_toolbar_orientation_combo(settings, "toolbar-orientation");
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label3), combo);
+	gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
+
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 0);
+
+	label4 = gtk_label_new_with_mnemonic(_("_View Mode"));
+	gtk_misc_set_alignment(GTK_MISC(label4), 0.0f, 0.5f);
+	gtk_box_pack_start(GTK_BOX(hbox), label4, FALSE, FALSE, 0);
+
+	combo = add_view_mode_combo(settings, "view-mode");
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label4), combo);
+	gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
+
+	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+	gtk_size_group_add_widget(sg, label2);
+	gtk_size_group_add_widget(sg, label3);
+	gtk_size_group_add_widget(sg, label4);
+	g_object_unref(sg);
+
+	gtk_widget_show_all(vbox);
+}
+
+
+static void sion_preferences_dialog_set_property(GObject *object, guint prop_id,
+												 const GValue *value, GParamSpec *pspec)
+{
+	SionPreferencesDialog *preferences = SION_PREFERENCES_DIALOG(object);
+
+	switch (prop_id)
+	{
+	case PROP_SETTINGS:
+	{
+		set_settings(preferences, g_value_get_object(value));
+		break;
+	}
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void sion_preferences_dialog_class_init(SionPreferencesDialogClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+	gobject_class->set_property = sion_preferences_dialog_set_property;
+
+	g_object_class_install_property(gobject_class,
+									PROP_SETTINGS,
+									g_param_spec_object(
+									"settings",
+									"Settings",
+									"Settings instance to provide properties",
+									SION_SETTINGS_TYPE,
+									G_PARAM_WRITABLE));
+
+	parent_class = (GtkDialogClass*)g_type_class_peek(GTK_TYPE_DIALOG);
+	g_type_class_add_private((gpointer)klass, sizeof(SionPreferencesDialogPrivate));
+}
+
+
+static void sion_preferences_dialog_init(SionPreferencesDialog *dialog)
+{
+    g_object_set(dialog,
+		"icon-name", GTK_STOCK_PREFERENCES,
+		"title", _("Preferences"),
+		"has-separator", FALSE,
+		NULL);
+	gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+}
+
+
+GtkWidget *sion_preferences_dialog_new(GtkWindow *parent, SionSettings *settings)
+{
+	GtkWidget *dialog;
+
+	dialog = g_object_new(SION_PREFERENCES_DIALOG_TYPE,
+		"transient-for", parent,
+		"destroy-with-parent", TRUE,
+		"settings", settings,
+		NULL);
+
+
+	return dialog;
+}
+
+


Property changes on: sion/trunk/src/preferencesdialog.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/preferencesdialog.h
===================================================================
--- sion/trunk/src/preferencesdialog.h	                        (rev 0)
+++ sion/trunk/src/preferencesdialog.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,54 @@
+/*
+ *      preferencesdialog.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __PREFERENCESDIALOG_H__
+#define __PREFERENCESDIALOG_H__
+
+G_BEGIN_DECLS
+
+#define SION_PREFERENCES_DIALOG_TYPE				(sion_preferences_dialog_get_type())
+#define SION_PREFERENCES_DIALOG(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+			SION_PREFERENCES_DIALOG_TYPE, SionPreferencesDialog))
+#define SION_PREFERENCES_DIALOG_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+			SION_PREFERENCES_DIALOG_TYPE, SionPreferencesDialogClass))
+#define IS_SION_PREFERENCES_DIALOG(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+			SION_PREFERENCES_DIALOG_TYPE))
+#define IS_SION_PREFERENCES_DIALOG_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass),\
+			SION_PREFERENCES_DIALOG_TYPE))
+
+typedef struct _SionPreferencesDialog				SionPreferencesDialog;
+typedef struct _SionPreferencesDialogClass			SionPreferencesDialogClass;
+
+struct _SionPreferencesDialog
+{
+	GtkDialog parent;
+};
+
+struct _SionPreferencesDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+GType		sion_preferences_dialog_get_type		(void);
+GtkWidget*	sion_preferences_dialog_new				(GtkWindow *parent, SionSettings *settings);
+
+G_END_DECLS
+
+#endif /* __PREFERENCESDIALOG_H__ */


Property changes on: sion/trunk/src/preferencesdialog.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/settings.c
===================================================================
--- sion/trunk/src/settings.c	                        (rev 0)
+++ sion/trunk/src/settings.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,661 @@
+/*
+ *      settings.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <string.h>
+
+#include "settings.h"
+#include "common.h"
+#include "bookmark.h"
+#include "main.h"
+
+
+typedef struct _SionSettingsPrivate			SionSettingsPrivate;
+
+#define SION_SETTINGS_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+		SION_SETTINGS_TYPE, SionSettingsPrivate))
+
+struct _SionSettingsPrivate
+{
+	gchar		*config_path;
+	gchar		*config_filename;
+	gchar		*bookmarks_filename;
+
+	gboolean	save_geometry;
+	gboolean	show_trayicon;
+	gboolean	show_toolbar;
+	gint		toolbar_style;
+	gint		toolbar_orientation;
+	gint		view_mode;
+
+	gchar		*file_manager;
+	gchar		*vm_impl; // GVolumeMonitor implementation to use
+	gint		*geometry; // window size and position, field 4 is a flag for maximized state
+
+	SionBookmarkList *bookmarks; // array of known bookmarks
+};
+
+static void sion_settings_class_init		(SionSettingsClass *klass);
+static void sion_settings_init				(SionSettings *self);
+static void sion_settings_finalize			(GObject* object);
+
+static GObjectClass *parent_class = NULL;
+
+// keyfile section names
+#define SECTION_GENERAL	"general"
+#define SECTION_UI		"ui"
+
+enum
+{
+	PROP_0,
+
+	PROP_FILE_MANAGER,
+
+	PROP_SAVE_GEOMETRY,
+	PROP_SHOW_TRAYICON,
+	PROP_SHOW_TOOLBAR,
+	PROP_TOOLBAR_STYLE,
+	PROP_TOOLBAR_ORIENTATION,
+	PROP_VIEW_MODE
+};
+
+GType sion_settings_get_type(void)
+{
+	static GType self_type = 0;
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionSettingsClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_settings_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionSettings),
+			0,
+			(GInstanceInitFunc)sion_settings_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(G_TYPE_OBJECT, "SionSettings", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static void sion_settings_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(object);
+
+	switch (prop_id)
+	{
+	case PROP_SAVE_GEOMETRY:
+		priv->save_geometry = g_value_get_boolean(value);
+		break;
+	case PROP_SHOW_TRAYICON:
+		priv->show_trayicon = g_value_get_boolean(value);
+		break;
+	case PROP_SHOW_TOOLBAR:
+		priv->show_toolbar = g_value_get_boolean(value);
+		break;
+	case PROP_TOOLBAR_STYLE:
+		priv->toolbar_style = g_value_get_int(value);
+		break;
+	case PROP_TOOLBAR_ORIENTATION:
+		priv->toolbar_orientation = g_value_get_int(value);
+		break;
+	case PROP_VIEW_MODE:
+		priv->view_mode = g_value_get_int(value);
+		break;
+	case PROP_FILE_MANAGER:
+		g_free(priv->file_manager);
+		priv->file_manager = g_value_dup_string(value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void sion_settings_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(object);
+
+	switch (prop_id)
+	{
+	case PROP_SAVE_GEOMETRY:
+		g_value_set_boolean(value, priv->save_geometry);
+		break;
+	case PROP_SHOW_TRAYICON:
+		g_value_set_boolean(value, priv->show_trayicon);
+		break;
+	case PROP_SHOW_TOOLBAR:
+		g_value_set_boolean(value, priv->show_toolbar);
+		break;
+	case PROP_TOOLBAR_STYLE:
+		g_value_set_int(value, priv->toolbar_style);
+		break;
+	case PROP_TOOLBAR_ORIENTATION:
+		g_value_set_int(value, priv->toolbar_orientation);
+		break;
+	case PROP_VIEW_MODE:
+		g_value_set_int(value, priv->view_mode);
+		break;
+	case PROP_FILE_MANAGER:
+		g_value_set_string(value, priv->file_manager);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void sion_settings_class_init(SionSettingsClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+	gobject_class->finalize = sion_settings_finalize;
+	gobject_class->get_property = sion_settings_get_property;
+	gobject_class->set_property = sion_settings_set_property;
+
+	parent_class = (GObjectClass*)g_type_class_peek(G_TYPE_OBJECT);
+	g_type_class_add_private((gpointer)klass, sizeof(SionSettingsPrivate));
+
+	g_object_class_install_property(gobject_class,
+									PROP_SAVE_GEOMETRY,
+									g_param_spec_boolean(
+									"save-geometry",
+									"Save window position and geometry",
+									"Saves the window position and geometry and restores it at the start",
+									TRUE,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_SHOW_TRAYICON,
+									g_param_spec_boolean(
+									"show-trayicon",
+									"show-trayicon",
+									"Whether to show the trayicon",
+									TRUE,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_SHOW_TOOLBAR,
+									g_param_spec_boolean(
+									"show-toolbar",
+									"show-toolbar",
+									"Whether to show the toolbar",
+									TRUE,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_TOOLBAR_STYLE,
+									g_param_spec_int(
+									"toolbar-style",
+									"toolbar-style",
+									"The style of the toolbar",
+									-1, G_MAXINT, -1,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_TOOLBAR_ORIENTATION,
+									g_param_spec_int(
+									"toolbar-orientation",
+									"toolbar-orientation",
+									"The orientation of the toolbar",
+									-1, G_MAXINT, -1,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_VIEW_MODE,
+									g_param_spec_int(
+									"view-mode",
+									"view-mode",
+									"Whether to use an IconView or a TreeView",
+									0, G_MAXINT, 0,
+									G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class,
+									PROP_FILE_MANAGER,
+									g_param_spec_string(
+									"file-manager",
+									"file-manager",
+									"A program for use to open mount points",
+									NULL,
+									G_PARAM_READWRITE));
+}
+
+
+static gchar *get_setting_string(GKeyFile *config, const gchar *section, const gchar *key,
+								 const gchar *default_value)
+{
+	gchar *tmp;
+	GError *error = NULL;
+
+	if (config == NULL)
+		return g_strdup(default_value);
+
+	tmp = g_key_file_get_string(config, section, key, &error);
+	if (error != NULL)
+	{
+		g_error_free(error);
+		return (gchar*) g_strdup(default_value);
+	}
+	return tmp;
+}
+
+
+static gint get_setting_int(GKeyFile *config, const gchar *section, const gchar *key,
+							  gint default_value)
+{
+	gint tmp;
+	GError *error = NULL;
+
+	if (config == NULL)
+		return default_value;
+
+	tmp = g_key_file_get_integer(config, section, key, &error);
+	if (error != NULL)
+	{
+		g_error_free(error);
+		return default_value;
+	}
+	return tmp;
+}
+
+
+static gboolean get_setting_boolean(GKeyFile *config, const gchar *section, const gchar *key,
+									gboolean default_value)
+{
+	gboolean tmp;
+	GError *error = NULL;
+
+	if (config == NULL)
+		return default_value;
+
+	tmp = g_key_file_get_boolean(config, section, key, &error);
+	if (error != NULL)
+	{
+		g_error_free(error);
+		return default_value;
+	}
+	return tmp;
+}
+
+
+static void set_setting_string(GKeyFile *config, const gchar *section, const gchar *key,
+							   const gchar *value)
+{
+	if (config != NULL && value != NULL)
+		g_key_file_set_string(config, section, key, value);
+}
+
+
+static void set_setting_int(GKeyFile *config, const gchar *section, const gchar *key, gint value)
+{
+	if (config != NULL && value > 0)
+		g_key_file_set_integer(config, section, key, value);
+}
+
+
+static void write_data(GKeyFile *k, const gchar *filename)
+{
+	gsize len;
+	GError *error = NULL;
+	gchar *data;
+
+	data = g_key_file_to_data(k, &len, &error);
+	if (data == NULL || error != NULL)
+	{
+		g_warning("Saving configuration file failed (%s).", error->message);
+		g_error_free(error);
+		g_free(data);
+		return;
+	}
+
+	if (! g_file_set_contents(filename, data, len, &error))
+	{
+		g_warning("Writing configuration file to disk failed (%s).", error->message);
+		g_error_free(error);
+	}
+	g_free(data);
+}
+
+
+static void write_settings_config(SionSettings *settings)
+{
+	GKeyFile *k;
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(settings);
+
+	if (! g_file_test(priv->config_path, G_FILE_TEST_IS_DIR))
+		g_mkdir_with_parents(priv->config_path, 0700);
+
+	k = g_key_file_new();
+
+	if (priv->vm_impl != NULL)
+		g_key_file_set_string(k, SECTION_GENERAL, "vm_impl", priv->vm_impl);
+	if (priv->file_manager != NULL)
+		g_key_file_set_string(k, SECTION_GENERAL, "file_manager", priv->file_manager);
+
+	if (priv->geometry != NULL)
+		g_key_file_set_integer_list(k, SECTION_UI, "geometry", priv->geometry, 5);
+	g_key_file_set_boolean(k, SECTION_UI, "save_geometry", priv->save_geometry);
+	g_key_file_set_boolean(k, SECTION_UI, "show_trayicon", priv->show_trayicon);
+	g_key_file_set_boolean(k, SECTION_UI, "show_toolbar", priv->show_toolbar);
+	g_key_file_set_integer(k, SECTION_UI, "toolbar_style", priv->toolbar_style);
+	g_key_file_set_integer(k, SECTION_UI, "toolbar_orientation", priv->toolbar_orientation);
+	g_key_file_set_integer(k, SECTION_UI, "view_mode", priv->view_mode);
+
+	write_data(k, priv->config_filename);
+
+	g_key_file_free(k);
+}
+
+
+static void write_settings_bookmarks(SionSettings *settings)
+{
+	GKeyFile *k;
+	const gchar *name;
+	gsize i;
+	SionBookmark *bm;
+	SionBookmarkList *bml;
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(settings);
+
+	if (! g_file_test(priv->config_path, G_FILE_TEST_IS_DIR))
+		g_mkdir_with_parents(priv->config_path, 0700);
+
+	k = g_key_file_new();
+
+	bml = sion_settings_get_bookmarks(settings);
+	for (i = 0; i < bml->len; i++)
+	{
+		bm = g_ptr_array_index(bml, i);
+		if (IS_SION_BOOKMARK(bm))
+		{
+			name = sion_bookmark_get_name(bm);
+			set_setting_string(k, name, "host", sion_bookmark_get_host(bm));
+			set_setting_string(k, name, "user", sion_bookmark_get_user(bm));
+			set_setting_string(k, name, "scheme", sion_bookmark_get_scheme(bm));
+			set_setting_int(k, name, "port", sion_bookmark_get_port(bm));
+		}
+	}
+
+	write_data(k, priv->bookmarks_filename);
+
+	g_key_file_free(k);
+}
+
+
+void sion_settings_write(SionSettings *settings)
+{
+	g_return_if_fail(settings != NULL);
+
+	write_settings_config(settings);
+	write_settings_bookmarks(settings);
+}
+
+
+static void sion_settings_finalize(GObject* object)
+{
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(object);
+
+	sion_settings_write(SION_SETTINGS(object));
+
+	g_free(priv->vm_impl);
+	g_free(priv->geometry);
+
+	g_ptr_array_foreach(priv->bookmarks, (GFunc) g_object_unref, NULL);
+	g_ptr_array_free(priv->bookmarks, TRUE);
+
+	g_free(priv->config_filename);
+	g_free(priv->bookmarks_filename);
+	g_free(priv->config_path);
+
+	G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+
+static void load_settings_read_config(SionSettingsPrivate *priv)
+{
+	GKeyFile *k;
+	GError *error = NULL;
+	const gchar *default_vm_impl = "hal";
+	gsize i;
+
+	k = g_key_file_new();
+	if (! g_key_file_load_from_file(k, priv->config_filename, G_KEY_FILE_NONE, &error))
+	{
+		verbose("Loading configuration file failed (%s).", error->message);
+		g_error_free(error);
+		error = NULL;
+	}
+
+	priv->vm_impl = get_setting_string(k, SECTION_GENERAL, "vm_impl", default_vm_impl);
+	priv->file_manager = get_setting_string(k, SECTION_GENERAL, "file_manager",
+		(sion_is_desktop_xfce() ? "thunar" : "nautilus"));
+
+	priv->save_geometry = get_setting_boolean(k, SECTION_UI, "save_geometry", TRUE);
+	priv->show_trayicon = get_setting_boolean(k, SECTION_UI, "show_trayicon", TRUE);
+	priv->show_toolbar = get_setting_boolean(k, SECTION_UI, "show_toolbar", TRUE);
+	priv->toolbar_style = get_setting_int(k, SECTION_UI, "toolbar_style", -1);
+	priv->toolbar_orientation = get_setting_int(k, SECTION_UI, "toolbar_orientation", 0);
+	priv->view_mode = get_setting_int(k, SECTION_UI, "view_mode", 0);
+	priv->geometry = g_key_file_get_integer_list(k, SECTION_UI, "geometry", NULL, &error);
+	if (error)
+	{
+		g_error_free(error);
+		error = NULL;
+		priv->geometry = NULL;
+	}
+	else
+	{
+		/* don't use insane values: when main windows was maximized last time, pos might be
+		 * negative at least on Windows for some reason */
+		if (priv->geometry[4] != 1)
+		{
+			for (i = 0; i < 4; i++)
+			{
+				if (priv->geometry[i] < -1)
+					priv->geometry[i] = -1;
+			}
+		}
+	}
+
+	g_key_file_free(k);
+}
+
+
+static void load_settings_read_bookmarks(SionSettingsPrivate *priv)
+{
+	GKeyFile *k;
+	GError *error = NULL;
+	gsize len, i;
+	gchar **groups;
+	gchar *scheme, *host, *user;
+	gint port;
+	SionBookmark *bm;
+
+	k = g_key_file_new();
+	if (! g_key_file_load_from_file(k, priv->bookmarks_filename, G_KEY_FILE_NONE, &error))
+	{
+		verbose("Loading bookmarks file failed (%s).", error->message);
+		g_error_free(error);
+		error = NULL;
+	}
+
+	// read groups for bookmarks
+	groups = g_key_file_get_groups(k, &len);
+	for (i = 0; i < len; i++)
+	{
+		scheme = get_setting_string(k, groups[i], "scheme", "");
+		host = get_setting_string(k, groups[i], "host", "");
+		user = get_setting_string(k, groups[i], "user", "");
+		port = get_setting_int(k, groups[i], "port", 0);
+
+		bm = sion_bookmark_new();
+		sion_bookmark_set_name(bm, groups[i]);
+		sion_bookmark_set_scheme(bm, scheme);
+		if (NZV(host))
+			sion_bookmark_set_host(bm, host);
+		if (NZV(user))
+			sion_bookmark_set_user(bm, user);
+		sion_bookmark_set_port(bm, port);
+
+		g_ptr_array_add(priv->bookmarks, bm);
+
+		g_free(scheme);
+		g_free(host);
+		g_free(user);
+	}
+	g_strfreev(groups);
+
+	g_key_file_free(k);
+}
+
+
+static void sion_settings_init(SionSettings *self)
+{
+	SionSettingsPrivate *priv = SION_SETTINGS_GET_PRIVATE(self);
+
+	priv->config_path = g_build_filename(g_get_user_config_dir(), PACKAGE, NULL);
+	priv->config_filename = g_build_filename(priv->config_path, "config", NULL);
+	priv->bookmarks_filename = g_build_filename(priv->config_path, "bookmarks", NULL);
+
+	priv->bookmarks = g_ptr_array_new();
+
+	load_settings_read_config(priv);
+	load_settings_read_bookmarks(priv);
+}
+
+
+SionSettings *sion_settings_new(void)
+{
+	return (SionSettings*) g_object_new(SION_SETTINGS_TYPE, NULL);
+}
+
+
+const gchar *sion_settings_get_vm_impl(SionSettings *settings)
+{
+	g_return_val_if_fail(settings != NULL, NULL);
+
+	return SION_SETTINGS_GET_PRIVATE(settings)->vm_impl;
+}
+
+
+void sion_settings_set_vm_impl(SionSettings *settings, const gchar *impl)
+{
+	SionSettingsPrivate *priv;
+
+	g_return_if_fail(settings != NULL);
+
+	priv = SION_SETTINGS_GET_PRIVATE(settings);
+
+	if (impl == NULL)
+		impl = "hal";
+
+	g_free(priv->vm_impl);
+	priv->vm_impl = g_strdup(impl);
+}
+
+
+const gint *sion_settings_get_geometry(SionSettings *settings)
+{
+	g_return_val_if_fail(settings != NULL, NULL);
+
+	return SION_SETTINGS_GET_PRIVATE(settings)->geometry;
+}
+
+
+void sion_settings_set_geometry(SionSettings *settings, const gint *geometry, gsize len)
+{
+	SionSettingsPrivate *priv;
+	guint i;
+
+	g_return_if_fail(settings != NULL);
+	g_return_if_fail(geometry != NULL);
+	g_return_if_fail(len > 0);
+
+	priv = SION_SETTINGS_GET_PRIVATE(settings);
+
+	g_free(priv->geometry);
+	priv->geometry = g_new(gint, len);
+
+	for (i = 0; i < len; i++)
+	{
+		priv->geometry[i] = geometry[i];
+	}
+}
+
+
+SionBookmarkList *sion_settings_get_bookmarks(SionSettings *settings)
+{
+	g_return_val_if_fail(settings != NULL, NULL);
+
+	return SION_SETTINGS_GET_PRIVATE(settings)->bookmarks;
+}
+
+
+gboolean sion_settings_get_boolean(SionSettings *settings, const gchar *property)
+{
+	gboolean value;
+
+	g_return_val_if_fail(settings != NULL, FALSE);
+	g_return_val_if_fail(property != NULL, FALSE);
+
+	g_object_get(settings, property, &value, NULL);
+
+	return value;
+}
+
+
+gint sion_settings_get_integer(SionSettings *settings, const gchar *property)
+{
+	gint value;
+
+	g_return_val_if_fail(settings != NULL, FALSE);
+	g_return_val_if_fail(property != NULL, FALSE);
+
+	g_object_get(settings, property, &value, NULL);
+
+	return value;
+}
+
+
+gchar *sion_settings_get_string(SionSettings *settings, const gchar *property)
+{
+	gchar *value;
+
+	g_return_val_if_fail(settings != NULL, FALSE);
+	g_return_val_if_fail(property != NULL, FALSE);
+
+	g_object_get(settings, property, &value, NULL);
+
+	return value;
+}
+
+
+gboolean sion_settings_has_file_manager(SionSettings *settings)
+{
+	SionSettingsPrivate *priv;
+
+	g_return_val_if_fail(settings != NULL, FALSE);
+
+	priv = SION_SETTINGS_GET_PRIVATE(settings);
+
+	return NZV(priv->file_manager);
+}


Property changes on: sion/trunk/src/settings.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/settings.h
===================================================================
--- sion/trunk/src/settings.h	                        (rev 0)
+++ sion/trunk/src/settings.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,69 @@
+/*
+ *      settings.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __SETTINGS_H__
+#define __SETTINGS_H__
+
+G_BEGIN_DECLS
+
+#define SION_SETTINGS_TYPE				(sion_settings_get_type())
+#define SION_SETTINGS(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+		SION_SETTINGS_TYPE, SionSettings))
+#define SION_SETTINGS_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+		SION_SETTINGS_TYPE, SionSettingsClass))
+#define IS_SION_SETTINGS(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), SION_SETTINGS_TYPE))
+#define IS_SION_SETTINGS_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), SION_SETTINGS_TYPE))
+
+typedef struct _SionSettings			SionSettings;
+typedef struct _SionSettingsClass		SionSettingsClass;
+typedef 	   GPtrArray				SionBookmarkList;
+
+struct _SionSettings
+{
+	GObject parent;
+};
+
+struct _SionSettingsClass
+{
+	GObjectClass parent_class;
+};
+
+GType				sion_settings_get_type			(void);
+SionSettings*		sion_settings_new				(void);
+
+void				sion_settings_write				(SionSettings *settings);
+
+const gchar*		sion_settings_get_vm_impl		(SionSettings *settings);
+void				sion_settings_set_vm_impl		(SionSettings *settings, const gchar *impl);
+
+const gint*			sion_settings_get_geometry		(SionSettings *settings);
+void				sion_settings_set_geometry		(SionSettings *settings, const gint *geometry, gsize len);
+
+SionBookmarkList*	sion_settings_get_bookmarks		(SionSettings *settings);
+gboolean			sion_settings_has_file_manager	(SionSettings *settings);
+
+gboolean			sion_settings_get_boolean		(SionSettings *settings, const gchar *property);
+gint				sion_settings_get_integer		(SionSettings *settings, const gchar *property);
+gchar*				sion_settings_get_string		(SionSettings *settings, const gchar *property);
+
+
+G_END_DECLS
+
+#endif /* __SETTINGS_H__ */


Property changes on: sion/trunk/src/settings.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/window.c
===================================================================
--- sion/trunk/src/window.c	                        (rev 0)
+++ sion/trunk/src/window.c	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,1151 @@
+/*
+ *      window.c
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include "compat.h"
+#include "common.h"
+#include "bookmark.h"
+#include "settings.h"
+#include "window.h"
+#include "bookmarkdialog.h"
+#include "bookmarkeditdialog.h"
+#include "menubuttonaction.h"
+#include "preferencesdialog.h"
+#include "backendgvfs.h"
+#include "main.h"
+
+
+typedef struct _SionWindowPrivate			SionWindowPrivate;
+
+#define SION_WINDOW_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+		SION_WINDOW_TYPE, SionWindowPrivate))
+
+/* Returns: TRUE if @a ptr points to a non-zero value. */
+#define NZV(ptr) \
+	((ptr) && (ptr)[0])
+
+struct _SionWindowPrivate
+{
+	SionSettings	*settings;
+	SionBackendGVFS	*backend_gvfs;
+
+	GtkWidget		*vbox;
+	GtkWidget		*hbox;
+
+	GtkWidget		*treeview;
+	GtkWidget		*iconview;
+	GtkWidget		*swin_treeview;
+	GtkWidget		*swin_iconview;
+	GtkListStore	*store;
+	GtkWidget		*tree_popup_menu;
+	GtkAction		*action_connect;
+	GtkAction		*action_disconnect;
+	GtkAction		*action_bookmarks;
+	GtkAction		*action_bookmark_create;
+	GtkAction		*action_open;
+
+	GtkActionGroup	*action_group;
+
+	GtkWidget		*toolbar;
+	GtkStatusIcon	*trayicon;
+	GtkWidget		*trayicon_popup_menu;
+};
+
+enum
+{
+	ACTION_OPEN,
+	ACTION_ADD,
+	ACTION_CONNECT,
+	ACTION_DISCONNECT
+};
+
+enum
+{
+	VIEW_MODE_ICONVIEW,
+	VIEW_MODE_TREEVIEW
+};
+
+static void sion_window_class_init			(SionWindowClass *klass);
+static void sion_window_init				(SionWindow *window);
+
+static GtkWindowClass *parent_class = NULL;
+
+
+GType sion_window_get_type(void)
+{
+	static GType self_type = 0;
+
+	if (! self_type)
+	{
+		static const GTypeInfo self_info =
+		{
+			sizeof(SionWindowClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc)sion_window_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof(SionWindow),
+			0,
+			(GInstanceInitFunc)sion_window_init,
+			NULL /* value_table */
+		};
+
+		self_type = g_type_register_static(GTK_TYPE_WINDOW, "SionWindow", &self_info, 0);
+	}
+
+	return self_type;
+}
+
+
+static gboolean sion_window_delete_event(GtkWidget *widget, GdkEventAny *event)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(widget);
+	gint geo[5];
+
+	if (sion_settings_get_boolean(priv->settings, "save-geometry"))
+	{
+		gtk_window_get_position(GTK_WINDOW(widget), &geo[0], &geo[1]);
+		gtk_window_get_size(GTK_WINDOW(widget), &geo[2], &geo[3]);
+		if (gdk_window_get_state(sion_widget_get_window(widget)) & GDK_WINDOW_STATE_MAXIMIZED)
+			geo[4] = 1;
+		else
+			geo[4] = 0;
+
+		sion_settings_set_geometry(priv->settings, geo, 5);
+	}
+	gtk_widget_destroy(priv->tree_popup_menu);
+	g_object_unref(priv->action_group);
+	g_object_unref(priv->trayicon);
+	g_object_unref(priv->trayicon_popup_menu);
+	g_object_unref(priv->toolbar);
+	g_object_unref(priv->swin_treeview);
+	g_object_unref(priv->swin_iconview);
+	g_object_unref(priv->backend_gvfs);
+
+	return FALSE;
+}
+
+
+static void sion_window_class_init(SionWindowClass *klass)
+{
+	GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
+	gtkwidget_class->delete_event = sion_window_delete_event;
+
+	parent_class =(GtkWindowClass*)g_type_class_peek(GTK_TYPE_WINDOW);
+	g_type_class_add_private((gpointer)klass, sizeof(SionWindowPrivate));
+}
+
+
+void sion_window_error_dialog(GtkWindow *parent, const gchar *text, const gchar *secondary)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new(parent, GTK_DIALOG_DESTROY_WITH_PARENT,
+                                  GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", text);
+	gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", secondary);
+	gtk_window_set_title(GTK_WINDOW(dialog), _("Error"));
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+}
+
+
+const gchar *sion_window_get_icon_name(void)
+{
+	static const gchar *icon_name = NULL;
+
+	if (icon_name == NULL)
+		icon_name = sion_find_icon_name("gtk-network", "gtk-connect");
+
+	return icon_name;
+}
+
+
+static void trayicon_activate_cb(GtkStatusIcon *status_icon, GtkWindow *window)
+{
+	if (gtk_window_is_active(window))
+		gtk_widget_hide(GTK_WIDGET(window));
+	else
+		gtk_window_present(window);
+}
+
+
+static void trayicon_popup_menu_cb(GtkStatusIcon *status_icon, guint button,
+								   guint activate_time, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	if (button == 3)
+		gtk_menu_popup(GTK_MENU(priv->trayicon_popup_menu), NULL, NULL, NULL, NULL,
+			button, activate_time);
+}
+
+
+/* Convenience function to get the selected GtkTreeIter from the icon view or the treeview
+ * whichever is currently used for display. */
+static void get_selected_iter(SionWindow *window, GtkTreeIter *iter)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	g_return_if_fail(window != NULL);
+	g_return_if_fail(iter != NULL);
+
+	if (sion_settings_get_integer(priv->settings, "view-mode") == VIEW_MODE_TREEVIEW)
+	{
+		GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
+		gtk_tree_selection_get_selected(selection, NULL, iter);
+	}
+	else
+	{
+		GList *l, *items = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(priv->iconview));
+		GtkTreeModel *model = gtk_icon_view_get_model(GTK_ICON_VIEW(priv->iconview));
+
+		for (l = items; l != NULL; l = l->next)
+		{
+			gtk_tree_model_get_iter(model, iter, l->data);
+			// the selection mode is SINGLE, so the list should never have more than one entry
+			break;
+		}
+
+		g_list_foreach(items, (GFunc) gtk_tree_path_free, NULL);
+		g_list_free(items);
+	}
+}
+
+
+static void mount_from_bookmark(SionWindow *window, SionBookmark *bookmark)
+{
+	gchar *uri;
+	SionWindowPrivate *priv;
+
+	g_return_if_fail(window != NULL);
+	g_return_if_fail(bookmark != NULL);
+
+	priv = SION_WINDOW_GET_PRIVATE(window);
+	uri = sion_bookmark_get_uri(bookmark);
+	sion_backend_gvfs_mount_uri(priv->backend_gvfs, uri);
+
+	g_free(uri);
+}
+
+
+static void action_mount_cb(GtkAction *button, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(priv->store);
+	gpointer vol;
+	gint ref_type;
+	gboolean handled = FALSE;
+
+	get_selected_iter(window, &iter);
+	if (gtk_list_store_iter_is_valid(priv->store, &iter))
+	{
+		gtk_tree_model_get(model, &iter,
+			SION_WINDOW_COL_REF_TYPE, &ref_type,
+			SION_WINDOW_COL_REF, &vol, -1);
+
+		if (ref_type == SION_WINDOW_REF_TYPE_VOLUME)
+			handled = sion_backend_gvfs_mount_volume(priv->backend_gvfs, vol);
+	}
+
+	if (! handled)
+	{
+		SionBookmark *bm = NULL;
+		GtkWidget *edit_dialog;
+
+		edit_dialog = sion_bookmark_edit_dialog_new(GTK_WIDGET(window), SION_BE_MODE_CONNECT);
+		if (gtk_dialog_run(GTK_DIALOG(edit_dialog)) == GTK_RESPONSE_OK)
+		{
+			bm = sion_bookmark_new();
+			/* this fills the values of the dialog into 'bm' */
+			g_object_set(edit_dialog, "bookmark-update", bm, NULL);
+
+			mount_from_bookmark(window, bm);
+
+			g_object_unref(bm);
+		}
+		gtk_widget_destroy(edit_dialog);
+	}
+}
+
+
+static void action_preferences_cb(GtkAction *button, SionWindow *window)
+{
+	GtkWidget *dialog;
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	dialog = sion_preferences_dialog_new(GTK_WINDOW(window), priv->settings);
+
+	gtk_dialog_run(GTK_DIALOG(dialog));
+
+	gtk_widget_destroy(dialog);
+}
+
+
+static void action_unmount_cb(GtkAction *button, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkTreeIter iter;
+
+	get_selected_iter(window, &iter);
+	if (gtk_list_store_iter_is_valid(priv->store, &iter))
+	{
+		gpointer mnt;
+		GtkTreeModel *model = GTK_TREE_MODEL(priv->store);
+
+		gtk_tree_model_get(model, &iter, SION_WINDOW_COL_REF, &mnt, -1);
+		if (sion_backend_gvfs_is_mount(mnt))
+		{
+			sion_backend_gvfs_unmount_mount(priv->backend_gvfs, mnt);
+		}
+	}
+	else
+		debug("Invalid iter");
+}
+
+
+static void action_quit_cb(GtkAction *button, SionWindow *window)
+{
+    sion_window_delete_event(GTK_WIDGET(window), NULL);
+    gtk_widget_destroy(GTK_WIDGET(window));
+}
+
+
+static void action_bookmark_edit_cb(GtkAction *button, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkWidget *dialog;
+
+	dialog = sion_bookmark_dialog_new(GTK_WIDGET(window), priv->settings);
+
+	g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
+	gtk_widget_show(dialog);
+}
+
+
+static void about_activate_link(GtkAboutDialog *about, const gchar *uri, gpointer data)
+{
+	sion_show_uri(uri);
+}
+
+
+static void action_about_cb(GtkAction *button, SionWindow *window)
+{
+    const gchar *authors[]= { "Enrico Tröger <enrico at xfce.org>", NULL };
+
+	gtk_about_dialog_set_email_hook(about_activate_link, NULL, NULL);
+	gtk_about_dialog_set_url_hook(about_activate_link, NULL, NULL);
+	gtk_show_about_dialog(GTK_WINDOW(window),
+		"authors", authors,
+		"comments", "A simple frontend to easily connect to remote filesystems",
+		"copyright", "Copyright 2008 Enrico Tröger",
+		"website", "http://www.uvena.de/sion/",
+		"version", VERSION,
+		"license",  "Copyright 2008 Enrico Tröger <enrico at xfce.org>\n\n"
+					"This program is free software; you can redistribute it and/or modify\n"
+					"it under the terms of the GNU General Public License as published by\n"
+					"the Free Software Foundation; either version 2 of the License, or\n"
+					"(at your option) any later version.\n"
+					"\n"
+					"This program is distributed in the hope that it will be useful,\n"
+					"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+					"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+					"GNU General Public License for more details.\n"
+					"\n"
+					"You should have received a copy of the GNU General Public License\n"
+					"along with this program; if not, write to the Free Software\n"
+					"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.",
+		  NULL);
+}
+
+
+static void action_open_cb(GtkAction *button, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(priv->store);
+
+	if (! sion_settings_has_file_manager(priv->settings))
+		return;
+
+	get_selected_iter(window, &iter);
+	if (gtk_list_store_iter_is_valid(priv->store, &iter))
+	{
+		gpointer mnt;
+		gtk_tree_model_get(model, &iter, SION_WINDOW_COL_REF, &mnt, -1);
+		if (sion_backend_gvfs_is_mount(mnt))
+		{
+#if 1
+			GError *error = NULL;
+			gchar *uri;
+			gchar *file_manager;
+			gchar *cmd;
+
+			file_manager = sion_settings_get_string(priv->settings, "file-manager");
+			sion_backend_gvfs_get_name_and_uri_from_mount(mnt, NULL, &uri);
+			cmd = g_strconcat(file_manager, " ", uri, NULL);
+
+			if (! g_spawn_command_line_async(cmd, &error))
+			{
+				verbose(error->message);
+				g_error_free(error);
+			}
+
+			g_free(cmd);
+			g_free(file_manager);
+			g_free(uri);
+#else
+			GFile *file = g_mount_get_root(mnt);
+			gchar *path = g_file_get_path(file);
+
+			if (path != NULL)
+			{
+				gchar *cmd = g_strconcat("xdg-open ", path, NULL);
+				g_spawn_command_line_async(cmd, NULL);
+				g_free(cmd);
+				g_free(path);
+			}
+			else
+			{
+				/// FIXME make the open command configurable or find a better solution
+				///       maybe gtk_show_uri() ?
+				GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
+							GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+							_("Non-local mountpoints can't be opened."));
+				gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), _("(not yet implemented)"));
+				gtk_dialog_run(GTK_DIALOG (dialog));
+				gtk_widget_destroy(dialog);
+				verbose("Non-local mountpoints can't be opened.");
+			}
+			g_object_unref(file);
+#endif
+		}
+	}
+}
+
+
+static void tree_realize_cb(GtkWidget *widget)
+{
+	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(widget));
+}
+
+
+static gboolean iter_is_bookmark(SionWindow *window, GtkTreeModel *model, GtkTreeIter *iter)
+{
+	gint ref_type;
+	gpointer ref;
+
+	gtk_tree_model_get(model, iter, SION_WINDOW_COL_REF_TYPE, &ref_type,
+									SION_WINDOW_COL_REF, &ref, -1);
+
+	if (ref_type == SION_WINDOW_REF_TYPE_MOUNT)
+	{
+		gchar *uri;
+		gchar *tmp_uri;
+		guint i;
+		SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+		SionBookmarkList *bml = sion_settings_get_bookmarks(priv->settings);
+		SionBookmark *bm;
+		gboolean found = FALSE;
+
+		sion_backend_gvfs_get_name_and_uri_from_mount(ref, NULL, &uri);
+
+		for (i = 0; i < bml->len; i++)
+		{
+			bm = g_ptr_array_index(bml, i);
+			tmp_uri = sion_bookmark_get_uri(bm);
+			if (uri != NULL && tmp_uri != NULL && strcmp(uri, tmp_uri) == 0)
+			{
+				found = TRUE;
+			}
+			g_free(tmp_uri);
+		}
+		g_free(uri);
+		return found;
+	}
+
+	return TRUE;
+}
+
+
+static void update_sensitive_buttons(SionWindow *window, GtkTreeModel *model, GtkTreeIter *iter)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	gint ref_type;
+	gboolean is_bookmark = FALSE;
+
+	if (iter != NULL && gtk_list_store_iter_is_valid(priv->store, iter))
+	{
+		gtk_tree_model_get(model, iter, SION_WINDOW_COL_REF_TYPE, &ref_type, -1);
+		is_bookmark = iter_is_bookmark(window, model, iter);
+
+		//~ gtk_action_set_sensitive(priv->action_connect, (ref_type != SION_WINDOW_REF_TYPE_MOUNT));
+		//~ gtk_action_set_sensitive(priv->action_bookmarks_toolbar, (ref_type != SION_WINDOW_REF_TYPE_MOUNT));
+		gtk_action_set_sensitive(priv->action_disconnect, (ref_type == SION_WINDOW_REF_TYPE_MOUNT));
+		gtk_action_set_sensitive(priv->action_bookmark_create, (ref_type == SION_WINDOW_REF_TYPE_MOUNT));
+		gtk_action_set_sensitive(priv->action_open, sion_settings_has_file_manager(priv->settings));
+	}
+	else
+	{
+		//~ gtk_action_set_sensitive(priv->action_connect, FALSE);
+		//~ gtk_action_set_sensitive(priv->action_bookmarks_toolbar, FALSE);
+		gtk_action_set_sensitive(priv->action_disconnect, FALSE);
+		gtk_action_set_sensitive(priv->action_bookmark_create, FALSE);
+		gtk_action_set_sensitive(priv->action_open, FALSE);
+	}
+}
+
+
+static void tree_selection_changed_cb(GtkTreeSelection *selection, SionWindow *window)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	if (selection == NULL)
+		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
+
+	gtk_tree_selection_get_selected(selection, &model, &iter);
+
+	update_sensitive_buttons(window, model, &iter);
+}
+
+
+static void iconview_selection_changed_cb(GtkIconView *view, SionWindow *window)
+{
+	GList *l, *items = gtk_icon_view_get_selected_items(view);
+	GtkTreeIter iter;
+	GtkTreeModel *model = gtk_icon_view_get_model(view);
+
+	for (l = items; l != NULL; l = l->next)
+	{
+		gtk_tree_model_get_iter(model, &iter, l->data);
+		update_sensitive_buttons(window, model, &iter);
+	}
+	if (items == NULL)
+		update_sensitive_buttons(window, model, NULL);
+
+	g_list_foreach(items, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free(items);
+}
+
+
+static void mounts_changed_cb(SionBackendGVFS *backend, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	gint view_mode = sion_settings_get_integer(priv->settings, "view-mode");
+
+	if (view_mode == VIEW_MODE_ICONVIEW)
+	{
+		iconview_selection_changed_cb(GTK_ICON_VIEW(priv->iconview), window);
+	}
+	else if (view_mode == VIEW_MODE_TREEVIEW)
+	{
+		tree_selection_changed_cb(NULL, window);
+	}
+}
+
+
+static void mount_operation_failed(SionBackendGVFS *backend, const gchar *message,
+								   const gchar *error_message, SionWindow *window)
+{
+	sion_window_error_dialog(GTK_WINDOW(window), message, error_message);
+}
+
+
+static void tree_row_activated_cb(GtkTreeView *treeview, GtkTreePath *path,
+								  GtkTreeViewColumn *arg2, SionWindow *window)
+{
+	GtkTreeIter iter;
+	gint ref_type;
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	if (gtk_tree_model_get_iter(GTK_TREE_MODEL(priv->store), &iter, path))
+	{
+		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+			SION_WINDOW_COL_REF_TYPE, &ref_type, -1);
+		if (ref_type == SION_WINDOW_REF_TYPE_MOUNT)
+		{
+			//~ action_unmount_cb(NULL, data);
+			action_open_cb(NULL, window);
+		}
+		else
+		{
+			action_mount_cb(NULL, window);
+		}
+	}
+}
+
+
+static void iconview_item_activated_cb(GtkIconView *iconview, GtkTreePath *path, SionWindow *window)
+{
+	tree_row_activated_cb(NULL, path, NULL, window);
+}
+
+
+static gboolean tree_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, SionWindow *window)
+{
+	if (event->button == 3)
+	{
+		SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+		GtkTreeSelection *treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
+		gboolean have_sel = (gtk_tree_selection_count_selected_rows(treesel) > 0);
+
+		if (have_sel)
+			gtk_menu_popup(GTK_MENU(priv->tree_popup_menu), NULL, NULL, NULL, NULL,
+																event->button, event->time);
+	}
+	return FALSE;
+}
+
+
+/* tries to select the item/path specified by wx and wy, GtkIconView doesn't do this by default
+ * when right-clicking on an item */
+static void iconview_select_item(GtkIconView *view, gdouble wx, gdouble wy)
+{
+	gint bx, by;
+	GtkTreePath *path;
+
+	gtk_icon_view_convert_widget_to_bin_window_coords(view, wx, wy, &bx, &by);
+	path = gtk_icon_view_get_path_at_pos(view, bx, by);
+
+	if (path != NULL)
+	{
+		gtk_icon_view_select_path(view, path);
+		gtk_tree_path_free(path);
+	}
+}
+
+
+static gboolean iconview_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, SionWindow *window)
+{
+	if (event->button == 3)
+	{
+		SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+		GList *items;
+		gboolean have_sel;
+
+		iconview_select_item(GTK_ICON_VIEW(widget), event->x, event->y);
+
+		items = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(widget));
+		have_sel = (items != NULL) && (g_list_length(items) > 0);
+		g_list_foreach(items, (GFunc) gtk_tree_path_free, NULL);
+		g_list_free(items);
+
+		if (have_sel)
+			gtk_menu_popup(GTK_MENU(priv->tree_popup_menu), NULL, NULL, NULL, NULL,
+																event->button, event->time);
+	}
+	return FALSE;
+}
+
+
+static void action_bookmark_activate_cb(SionMenubuttonAction *action, GtkWidget *item, SionWindow *window)
+{
+	SionBookmark *bm = g_object_get_data(G_OBJECT(item), "bookmark");
+
+	mount_from_bookmark(window, bm);
+}
+
+
+void sion_window_update_bookmarks(SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	/* writing to the 'settings' property will update the menus */
+	g_object_set(priv->action_bookmarks, "settings", priv->settings, NULL);
+}
+
+
+static void action_create_bookmark_cb(GtkAction *button, SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(priv->store);
+debug(__func__);
+	get_selected_iter(window, &iter);
+	if (gtk_list_store_iter_is_valid(priv->store, &iter))
+	{
+		gpointer mnt;
+
+		gtk_tree_model_get(model, &iter, SION_WINDOW_COL_REF, &mnt, -1);
+		if (sion_backend_gvfs_is_mount(mnt))
+		{
+			gchar *uri;
+			gchar *name;
+			SionBookmark *bm;
+
+			sion_backend_gvfs_get_name_and_uri_from_mount(mnt, &name, &uri);
+			bm = sion_bookmark_new_from_uri(name, uri);
+			if (sion_bookmark_is_valid(bm))
+			{
+				g_ptr_array_add(sion_settings_get_bookmarks(priv->settings), bm);
+				sion_window_update_bookmarks(window);
+
+				/** TODO show message dialog */
+			}
+			else
+				g_object_unref(bm);
+
+			g_free(uri);
+			g_free(name);
+		}
+		else
+			debug("%s: no mount", __func__);
+	}
+	else
+		debug("%s: invalid iter", __func__);
+}
+
+
+static void sion_window_show_trayicon(SionWindow *window, gboolean show)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	gtk_status_icon_set_visible(priv->trayicon, show);
+}
+
+
+static void sion_window_show_toolbar(SionWindow *window, gboolean show)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	if (show)
+		gtk_widget_show(priv->toolbar);
+	else
+		gtk_widget_hide(priv->toolbar);
+}
+
+
+static void sion_window_set_toolbar_style(SionWindow *window, gint style)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	if (style == -1)
+	{
+		g_object_get(gtk_widget_get_settings(GTK_WIDGET(window)), "gtk-toolbar-style", &style, NULL);
+		g_object_set(priv->settings, "toolbar-style", style, NULL);
+	}
+	else
+	{
+		gtk_toolbar_set_style(GTK_TOOLBAR(priv->toolbar), style);
+	}
+}
+
+
+static void sion_window_set_toolbar_orientation(SionWindow *window, gint orientation)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	gtk_toolbar_set_orientation(GTK_TOOLBAR(priv->toolbar), orientation);
+	if (orientation == GTK_ORIENTATION_HORIZONTAL && priv->vbox != gtk_widget_get_parent(priv->toolbar))
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->hbox), priv->toolbar);
+		gtk_container_add(GTK_CONTAINER(priv->vbox), priv->toolbar);
+		gtk_box_set_child_packing(GTK_BOX(priv->vbox), priv->toolbar, FALSE, FALSE, 0, GTK_PACK_START);
+		gtk_box_reorder_child(GTK_BOX(priv->vbox), priv->toolbar, 1);
+	}
+	else if (orientation == GTK_ORIENTATION_VERTICAL && priv->hbox != gtk_widget_get_parent(priv->toolbar))
+	{
+		gtk_container_remove(GTK_CONTAINER(priv->vbox), priv->toolbar);
+		gtk_container_add(GTK_CONTAINER(priv->hbox), priv->toolbar);
+		gtk_box_set_child_packing(GTK_BOX(priv->hbox), priv->toolbar, FALSE, FALSE, 0, GTK_PACK_START);
+	}
+}
+
+
+static void sion_window_set_view_mode(SionWindow *window, gint mode)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	if (mode == VIEW_MODE_ICONVIEW && priv->hbox != gtk_widget_get_parent(priv->swin_iconview))
+	{
+		gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview)));
+		gtk_container_remove(GTK_CONTAINER(priv->hbox), priv->swin_treeview);
+		gtk_container_add(GTK_CONTAINER(priv->hbox), priv->swin_iconview);
+	}
+	else if (mode == VIEW_MODE_TREEVIEW &&  priv->hbox != gtk_widget_get_parent(priv->swin_treeview))
+	{
+		gtk_icon_view_unselect_all(GTK_ICON_VIEW(priv->iconview));
+		gtk_container_remove(GTK_CONTAINER(priv->hbox), priv->swin_iconview);
+		gtk_container_add(GTK_CONTAINER(priv->hbox), priv->swin_treeview);
+	}
+}
+
+
+static void sion_window_settings_notify_cb(SionSettings *settings, GParamSpec *pspec, SionWindow *window)
+{
+	const gchar *name;
+	GValue *value;
+
+	name = g_intern_string(pspec->name);
+	value = g_new0(GValue, 1);
+	g_value_init(value, pspec->value_type);
+	g_object_get_property(G_OBJECT(settings), name, value);
+
+	if (name == g_intern_string("show-toolbar"))
+		sion_window_show_toolbar(window, g_value_get_boolean(value));
+	else if (name == g_intern_string("show-trayicon"))
+		sion_window_show_trayicon(window, g_value_get_boolean(value));
+	else if (name == g_intern_string("toolbar-style"))
+		sion_window_set_toolbar_style(window, g_value_get_int(value));
+	else if (name == g_intern_string("toolbar-orientation"))
+		sion_window_set_toolbar_orientation(window, g_value_get_int(value));
+	else if (name == g_intern_string("view-mode"))
+		sion_window_set_view_mode(window, g_value_get_int(value));
+	else if (! g_object_class_find_property(G_OBJECT_GET_CLASS(settings), name))
+		 verbose("Unexpected setting '%s'", name);
+	g_value_unset(value);
+	g_free(value);
+}
+
+
+static void create_ui_elements(SionWindow *window, GtkUIManager *ui_manager)
+{
+	GError *error = NULL;
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	const gchar *ui_markup =
+	"<ui>"
+		"<menubar>"
+			"<menu action='File'>"
+				"<menuitem action='Quit'/>"
+			"</menu>"
+			"<menu action='Edit'>"
+				"<menuitem action='EditBookmarks'/>"
+				"<separator/>"
+				"<menuitem action='Preferences'/>"
+			"</menu>"
+			"<menu action='Actions'>"
+				"<menuitem action='Connect'/>"
+				"<menuitem action='Disconnect'/>"
+				"<menuitem action='Bookmarks'/>"
+				"<separator/>"
+				"<menuitem action='Open'/>"
+			"</menu>"
+			"<menu action='Help'>"
+				"<menuitem action='About'/>"
+			"</menu>"
+		"</menubar>"
+
+		"<popup name='traymenu'>"
+			"<menuitem action='Connect'/>"
+			"<menuitem action='Bookmarks'/>"
+			"<separator/>"
+			"<menuitem action='EditBookmarks'/>"
+			"<menuitem action='Preferences'/>"
+			"<separator/>"
+			"<menuitem action='Quit'/>"
+		"</popup>"
+
+		"<popup name='treemenu'>"
+			"<menuitem action='Open'/>"
+			"<menuitem action='CreateBookmark'/>"
+			"<separator/>"
+			"<menuitem action='Connect'/>"
+			"<menuitem action='Disconnect'/>"
+		"</popup>"
+
+		"<toolbar>"
+			"<toolitem action='Bookmarks'/>"
+			"<toolitem action='Disconnect'/>"
+			"<separator/>"
+			"<toolitem action='EditBookmarks'/>"
+			"<separator/>"
+			"<toolitem action='Open'/>"
+			"<separator/>"
+			"<toolitem action='Quit'/>"
+		"</toolbar>"
+	"</ui>";
+	const GtkActionEntry entries[] = {
+		{ "File", NULL, _("_File"), NULL, NULL, NULL },
+		{ "Edit", NULL, _("_Edit"), NULL, NULL, NULL },
+		{ "Actions", NULL, _("_Actions"), NULL, NULL, NULL },
+		{ "Help", NULL, _("_Help"), NULL, NULL, NULL },
+		{ "Preferences", GTK_STOCK_PREFERENCES,
+			NULL, "<Ctrl>p", NULL, G_CALLBACK(action_preferences_cb) },
+		{ "CreateBookmark", GTK_STOCK_ADD,
+			_("Create _Bookmark"), "<Ctrl>n", NULL, G_CALLBACK(action_create_bookmark_cb) },
+		{ "EditBookmarks", GTK_STOCK_EDIT,
+			_("_Edit Bookmarks"), "<Ctrl>b", NULL, G_CALLBACK(action_bookmark_edit_cb) },
+		{ "Connect", GTK_STOCK_CONNECT, NULL, NULL, NULL, G_CALLBACK(action_mount_cb) },
+		{ "Disconnect", GTK_STOCK_DISCONNECT, NULL, NULL, NULL, G_CALLBACK(action_unmount_cb) },
+		{ "Open", GTK_STOCK_OPEN, NULL, "<Ctrl>o", NULL, G_CALLBACK(action_open_cb) },
+		{ "Quit", GTK_STOCK_QUIT, NULL, "<Ctrl>q", NULL, G_CALLBACK(action_quit_cb) },
+		{ "About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(action_about_cb) }
+	};
+	const guint entries_n = G_N_ELEMENTS(entries);
+
+
+	priv->action_bookmarks = sion_menu_button_action_new(
+		"Bookmarks", _("_Bookmarks"), _("Choose a bookmark to connect to"),
+		sion_find_icon_name("bookmark-new", GTK_STOCK_EDIT));
+	g_signal_connect(priv->action_bookmarks, "item-clicked", G_CALLBACK(action_bookmark_activate_cb), window);
+
+	priv->action_group = gtk_action_group_new("UI");
+	gtk_action_group_set_translation_domain(priv->action_group, GETTEXT_PACKAGE);
+	gtk_action_group_add_actions(priv->action_group, entries, entries_n, window);
+	gtk_action_group_add_action(priv->action_group, priv->action_bookmarks);
+	gtk_ui_manager_insert_action_group(ui_manager, priv->action_group, 0);
+	gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager));
+
+	if (! gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
+	{
+		verbose("User interface couldn't be created: %s", error->message);
+		g_error_free(error);
+	}
+}
+
+
+static void create_tree_view(SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *sel;
+
+	priv->treeview = gtk_tree_view_new();
+	gtk_widget_set_has_tooltip(priv->treeview, TRUE);
+	gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(priv->treeview), SION_WINDOW_COL_TOOLTIP);
+	gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(priv->treeview), TRUE);
+	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(priv->treeview), FALSE);
+	gtk_tree_sortable_set_sort_column_id(
+		GTK_TREE_SORTABLE(priv->store), SION_WINDOW_COL_NAME, GTK_SORT_ASCENDING);
+
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
+	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
+	if (gtk_check_version(2, 14, 0) == NULL)
+	{
+		renderer = gtk_cell_renderer_pixbuf_new();
+		column = gtk_tree_view_column_new_with_attributes(NULL, renderer,
+			"gicon", SION_WINDOW_COL_PIXBUF, NULL);
+		gtk_tree_view_column_set_sort_indicator(column, FALSE);
+		gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+		gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview), column);
+	}
+
+	renderer = gtk_cell_renderer_toggle_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Mounted"), renderer, "active", SION_WINDOW_COL_IS_MOUNTED, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, SION_WINDOW_COL_IS_MOUNTED);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("URI Scheme"), renderer, "text", SION_WINDOW_COL_SCHEME, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, SION_WINDOW_COL_SCHEME);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview), column);
+
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(
+		_("Name"), renderer, "text", SION_WINDOW_COL_NAME, NULL);
+	gtk_tree_view_column_set_sort_indicator(column, TRUE);
+	gtk_tree_view_column_set_sort_column_id(column, SION_WINDOW_COL_NAME);
+	gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview), column);
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview), GTK_TREE_MODEL(priv->store));
+
+	g_signal_connect(sel, "changed", G_CALLBACK(tree_selection_changed_cb), window);
+	g_signal_connect(priv->treeview, "realize", G_CALLBACK(tree_realize_cb), window);
+	g_signal_connect(priv->treeview, "button-press-event", G_CALLBACK(tree_button_press_event_cb), window);
+	g_signal_connect(priv->treeview, "row-activated", G_CALLBACK(tree_row_activated_cb), window);
+}
+
+
+static void create_icon_view(SionWindow *window)
+{
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+	GtkCellRenderer *renderer;
+
+	priv->iconview = gtk_icon_view_new();
+	gtk_widget_set_has_tooltip(priv->iconview, TRUE);
+	gtk_icon_view_set_tooltip_column(GTK_ICON_VIEW(priv->iconview), SION_WINDOW_COL_TOOLTIP);
+	gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(priv->iconview), GTK_SELECTION_SINGLE);
+	gtk_icon_view_set_spacing(GTK_ICON_VIEW(priv->iconview), 3);
+	gtk_icon_view_set_column_spacing(GTK_ICON_VIEW(priv->iconview), 30);
+	gtk_icon_view_set_row_spacing(GTK_ICON_VIEW(priv->iconview), 30);
+
+	renderer = gtk_cell_renderer_pixbuf_new();
+    g_object_set(renderer,
+		"stock-size", GTK_ICON_SIZE_DND,
+		"follow-state", TRUE,
+		"xalign", 0.5,
+		"yalign", 1.0, NULL);
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(priv->iconview), renderer, FALSE);
+	if (gtk_check_version(2, 14, 0) == NULL)
+		gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(priv->iconview), renderer,
+			"gicon", SION_WINDOW_COL_PIXBUF);
+	else
+		gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(priv->iconview), renderer,
+			"icon-name", SION_WINDOW_COL_ICON_NAME);
+
+	renderer = gtk_cell_renderer_text_new();
+	g_object_set(renderer, "xalign", 0.5, "yalign", 1.0, NULL);
+	gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(priv->iconview), renderer, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(priv->iconview), renderer,
+		"text", SION_WINDOW_COL_NAME, NULL);
+
+	gtk_icon_view_set_model(GTK_ICON_VIEW(priv->iconview), GTK_TREE_MODEL(priv->store));
+
+	g_signal_connect(priv->iconview, "selection-changed", G_CALLBACK(iconview_selection_changed_cb), window);
+	g_signal_connect(priv->iconview, "button-press-event", G_CALLBACK(iconview_button_press_event_cb), window);
+	g_signal_connect(priv->iconview, "item-activated", G_CALLBACK(iconview_item_activated_cb), window);
+}
+
+
+static void sion_window_init(SionWindow *window)
+{
+	GtkWidget *menubar;
+	GtkUIManager *ui_manager;
+	SionWindowPrivate *priv = SION_WINDOW_GET_PRIVATE(window);
+
+	gtk_window_set_title(GTK_WINDOW(window), _("Sion"));
+	gtk_window_set_icon_name(GTK_WINDOW(window), sion_window_get_icon_name());
+	gtk_window_set_default_size(GTK_WINDOW(window), 550, 350);
+
+	/* Init liststore */
+	priv->store = gtk_list_store_new(SION_WINDOW_N_COLUMNS,
+		G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER,
+		G_TYPE_INT, G_TYPE_ICON, G_TYPE_STRING, G_TYPE_STRING);
+
+	create_tree_view(window);
+	create_icon_view(window);
+
+	priv->swin_treeview = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(priv->swin_treeview),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(priv->swin_treeview), GTK_SHADOW_IN);
+	gtk_container_add(GTK_CONTAINER(priv->swin_treeview), priv->treeview);
+
+	priv->swin_iconview = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(priv->swin_iconview),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(priv->swin_iconview), GTK_SHADOW_IN);
+	gtk_container_add(GTK_CONTAINER(priv->swin_iconview), priv->iconview);
+
+	/* Init the GVFS backend */
+	priv->backend_gvfs = sion_backend_gvfs_new(priv->store);
+	g_signal_connect(priv->backend_gvfs, "mounts-changed", G_CALLBACK(mounts_changed_cb), window);
+	g_signal_connect(priv->backend_gvfs, "operation-failed", G_CALLBACK(mount_operation_failed), window);
+
+	/* UI Manager */
+	ui_manager = gtk_ui_manager_new();
+	create_ui_elements(window, ui_manager);
+	menubar = gtk_ui_manager_get_widget(ui_manager, "/menubar");
+	priv->toolbar = gtk_ui_manager_get_widget(ui_manager, "/toolbar");
+	priv->trayicon_popup_menu = gtk_ui_manager_get_widget(ui_manager, "/traymenu");
+	priv->tree_popup_menu = gtk_ui_manager_get_widget(ui_manager, "/treemenu");
+	// increase refcount to keep the widgets after the ui manager is destroyed
+	g_object_ref(priv->trayicon_popup_menu);
+	g_object_ref(priv->tree_popup_menu);
+	g_object_ref(priv->toolbar);
+	g_object_ref(priv->swin_treeview);
+	g_object_ref(priv->swin_iconview);
+
+	/* Buttons */
+	priv->action_connect = gtk_action_group_get_action(priv->action_group, "Connect");
+	priv->action_disconnect = gtk_action_group_get_action(priv->action_group, "Disconnect");
+	priv->action_bookmark_create = gtk_action_group_get_action(priv->action_group, "CreateBookmark");
+	priv->action_open = gtk_action_group_get_action(priv->action_group, "Open");
+
+	/* Set the is-important property for some toolbar actions */
+/*
+	g_object_set(gtk_action_group_get_action(priv->action_group, "EditBookmarks"), "is-important", TRUE, NULL);
+	g_object_set(priv->action_connect, "is-important", TRUE, NULL);
+	g_object_set(priv->action_disconnect, "is-important", TRUE, NULL);
+	g_object_set(priv->action_bookmarks, "is-important", TRUE, NULL);
+*/
+	/* Pack the widgets altogether */
+	priv->vbox = gtk_vbox_new(FALSE, 0);
+	priv->hbox = gtk_hbox_new(FALSE, 0);
+
+	gtk_box_pack_start(GTK_BOX(priv->vbox), menubar, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(priv->vbox), priv->toolbar, FALSE, FALSE, 0);
+
+	gtk_box_pack_start(GTK_BOX(priv->hbox), priv->swin_iconview, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(priv->vbox), priv->hbox, TRUE, TRUE, 0);
+
+	gtk_container_add(GTK_CONTAINER(window), priv->vbox);
+
+	/* Show everything */
+	gtk_widget_show_all(priv->vbox);
+	gtk_widget_show_all(priv->swin_treeview);
+
+	/* Status icon */
+	priv->trayicon = gtk_status_icon_new_from_icon_name(sion_window_get_icon_name());
+	sion_status_icon_set_tooltip_text(priv->trayicon, _("Sion"));
+	g_signal_connect(priv->trayicon, "activate", G_CALLBACK(trayicon_activate_cb), window);
+	g_signal_connect(priv->trayicon, "popup-menu", G_CALLBACK(trayicon_popup_menu_cb), window);
+
+	g_object_unref(ui_manager);
+}
+
+
+
+GtkWidget *sion_window_new(SionSettings *settings)
+{
+	GtkWidget *window;
+	SionWindowPrivate *priv;
+	const gint *geo;
+
+	window = g_object_new(SION_WINDOW_TYPE, NULL);
+	priv = SION_WINDOW_GET_PRIVATE(window);
+	priv->settings = settings;
+	g_signal_connect(settings, "notify", G_CALLBACK(sion_window_settings_notify_cb), window);
+
+	g_object_set(priv->action_bookmarks, "settings", settings, NULL);
+
+	sion_window_show_toolbar(SION_WINDOW(window), sion_settings_get_boolean(settings, "show-toolbar"));
+	sion_window_set_toolbar_style(SION_WINDOW(window), sion_settings_get_integer(settings, "toolbar-style"));
+	sion_window_set_toolbar_orientation(SION_WINDOW(window),
+		sion_settings_get_integer(settings, "toolbar-orientation"));
+	sion_window_set_view_mode(SION_WINDOW(window), sion_settings_get_integer(settings, "view-mode"));
+
+	if (sion_settings_get_boolean(settings, "save-geometry"))
+	{
+		geo = sion_settings_get_geometry(settings);
+		if (geo != NULL && *geo != -1)
+		{
+			gtk_window_move(GTK_WINDOW(window), geo[0], geo[1]);
+			gtk_window_set_default_size(GTK_WINDOW(window), geo[2], geo[3]);
+			if (geo[4] == 1)
+				gtk_window_maximize(GTK_WINDOW(window));
+		}
+	}
+
+	mounts_changed_cb(NULL, SION_WINDOW(window));
+	sion_window_update_bookmarks(SION_WINDOW(window));
+
+	return window;
+}
+
+


Property changes on: sion/trunk/src/window.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/src/window.h
===================================================================
--- sion/trunk/src/window.h	                        (rev 0)
+++ sion/trunk/src/window.h	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,59 @@
+/*
+ *      window.h
+ *
+ *      Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+ *
+ *      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; version 2 of the License.
+ *
+ *      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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __WINDOW_H__
+#define __WINDOW_H__
+
+G_BEGIN_DECLS
+
+#define SION_WINDOW_TYPE				(sion_window_get_type())
+#define SION_WINDOW(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
+		SION_WINDOW_TYPE, SionWindow))
+#define SION_WINDOW_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
+		SION_WINDOW_TYPE, SionWindowClass))
+#define IS_SION_WINDOW(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj), SION_WINDOW_TYPE))
+#define IS_SION_WINDOW_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass), SION_WINDOW_TYPE))
+
+
+typedef struct _SionWindow				SionWindow;
+typedef struct _SionWindowClass			SionWindowClass;
+
+struct _SionWindow
+{
+	GtkWindow parent;
+};
+
+struct _SionWindowClass
+{
+	GtkWindowClass parent_class;
+};
+
+GType		sion_window_get_type			(void);
+GtkWidget*	sion_window_new					(SionSettings *settings);
+
+void		sion_window_error_dialog		(GtkWindow *parent, const gchar *text, const gchar *secondary);
+void		sion_window_update_bookmarks	(SionWindow *window);
+
+
+const gchar* sion_window_get_icon_name		(void);
+
+G_END_DECLS
+
+#endif /* __WINDOW_H__ */


Property changes on: sion/trunk/src/window.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: sion/trunk/waf
===================================================================
--- sion/trunk/waf	                        (rev 0)
+++ sion/trunk/waf	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2005-2008
+
+"""
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import os, sys
+if sys.hexversion<0x203000f: raise "Waf requires Python >= 2.3"
+
+if 'PSYCOWAF' in os.environ:
+	try:import psyco;psyco.full()
+	except:pass
+
+VERSION="1.5.1"
+REVISION="d3500eb66edebf96ed49db8a561a9bfe"
+INSTALL=sys.platform=='win32' and 'c:/temp' or '/usr/local'
+C1='#%'
+C2='#$'
+cwd = os.getcwd()
+join = os.path.join
+
+def err(m):
+	print ('\033[91mError: %s\033[0m' % m)
+	sys.exit(1)
+
+def unpack_wafdir(dir):
+	f = open(sys.argv[0],'rb')
+	c = "corrupted waf (%d)"
+	while 1:
+		line = f.readline()
+		if not line: err("run waf-light from a folder containing wafadmin")
+		if line == '#==>\n':
+			txt = f.readline()
+			if not txt: err(c % 1)
+			if f.readline()!='#<==\n': err(c % 2)
+			break
+	if not txt: err(c % 3)
+	txt = txt[1:-1].replace(C1, '\n').replace(C2, '\r')
+
+	import shutil, tarfile
+	try: shutil.rmtree(dir)
+	except OSError: pass
+	try: os.makedirs(join(dir, 'wafadmin', 'Tools'))
+	except OSError: err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir)
+
+	os.chdir(dir)
+	tmp = 't.tbz2'
+	t = open(tmp,'wb')
+	t.write(txt)
+	t.close()
+
+	t = tarfile.open(tmp)
+	for x in t: t.extract(x)
+	t.close()
+
+	os.chmod(join('wafadmin','Tools'), 493)
+
+	os.unlink(tmp)
+	os.chdir(cwd)
+
+def test(dir):
+	try: os.stat(join(dir, 'wafadmin')); return os.path.abspath(dir)
+	except OSError: pass
+
+def find_lib():
+	name = sys.argv[0]
+	base = os.path.dirname(os.path.abspath(name))
+
+	#devs use $WAFDIR
+	w=test(os.environ.get('WAFDIR', ''))
+	if w: return w
+
+	#waf-light
+	if name.endswith('waf-light'):
+		w = test(base)
+		if w: return w
+		err("waf-light requires wafadmin -> export WAFDIR=/folder")
+
+	dir = "/lib/waf-%s-%s/" % (VERSION, REVISION)
+	for i in [INSTALL,'/usr','/usr/local','/opt']:
+		w = test(i+dir)
+		if w: return w
+
+	#waf-local
+	s = '.waf-%s-%s'
+	if sys.platform == 'win32': s = s[1:]
+	dir = join(base, s % (VERSION, REVISION))
+	w = test(dir)
+	if w: return w
+
+	#unpack
+	unpack_wafdir(dir)
+	return dir
+
+wafdir = find_lib()
+w = join(wafdir, 'wafadmin')
+t = join(w, 'Tools')
+sys.path = [w, t] + sys.path
+
+import Scripting
+Scripting.prepare(t, cwd, VERSION, wafdir)
+
+#==>
+#BZh91AY&SY+¢UÒsÿûþp Bÿÿÿÿÿÿÿÿÿÿÿ@   `ý4x         íöè	i¦I÷×r¹Y«·:çu¹–³fë§u3®óӏZ(gÞÇžAòÝn’¶"/v¹WVìëp«¶Ï]êBã®û®7Ë<7Úã  ¬ ïkÏRu´+{MhµÛµpèhŠ*[j€$(ª hEÛ½‡§;4uâGa …¥ô÷½öòÞÛZ¥»®ÚßmÞî³}î‡Ýñ÷¯®{+fîkz¨H¥SÐÔ†½yäY#%Ö[`	"W{$‚'Y€tTíîîkºîØÀ³e¶·ÞãÛzû±®ˆ®³é_{ïº÷W è;{„½Ÿs)%rÂ>×jEÝ­Üí™v`÷wG“×®štÚ×mï¾{ÛÜn¹Ûš"çV»ÍÛuÂEµÙŒ+éìË}Ãïz at s­*ªîÑq]A„ûœríï0Ù)Ðmáa^õž òÉt;=lî»­¯µ=¾ØŸw3]vé»zhïPµØ‹lÍõÎïzãî|BæÒÚΏYáæ;UÜíݼËm½=[yì=›³y«Ûº6ƒ^º¡×ùóÖBëFï•ÞF$16çcq`¹¾ïçfîÅ^ð;íßgÏ·Á{·ÛßzîŠ>ŽG‘ìO;µs<ÂÁèçvêêò^•¯ =Rõ½MéíöÀ(¡çFÛÄóg<5LÞì×:×»«o{#$Q(¤—µ“uç-ªšï:Ýw‘¼j)Ê»`®²;müǽiN†wQÞ½ëGÐ4Ё4 € &&“Èh˜ž¦0&ÄÉ#!ú¦€ ¦‚@@™4ѦšžŠ`Sõ2ö©ê?T“A ˆ   $"4ÓF‰èC*ÍIêŸêzJ=OF¦ž Ñ£!ê é  „ž©I54É‚›)êyLMÔôšA £@   Ó@’ @h	 	¦šh™4Ôɱ44jzž“M$ÚdÒ ÓÐI¨ˆ @i M4Òe4Ú¨Óy'¤Íª=OÊž¡êÒ€?T h@ù?Ú#%ÍIð‡­Š!LÅeF I˜ª¢ß×èõúêþÛûl^{mW++½áà4ìëùt Þ+MÜ+°¶ÂBMÛ©-%©È~"¡Xä´Sw¢Ñz›ÍèrÓÁp°ÌÁ*+ë ]¤I`(H¢’" ı{¶6V(>x@¬ °Sè…"€' DUŒ IB¤#TÌÃ1"ЕD¥…)¶2T&˜¶3!
 &"Lje‰+FÈc&‚jI¢XMHFY3i´ iªÍ[!©)¶ŒÆÙ‹©’É(*)4²„dRjHSYI’X¨É³"‚#RXˆÉ&T„I’Š5KFJZI&Ä¢›-E¢†„¢d’‚iClÁLSf&S)m3X¡1(„¢Èl”¤ÒÔk’#BXK&FÍ(PL’4šk#$bB”Æ‹Œ5Ͳ2XPȈKFH¡–$ØCIlÃ1RÍ4XʼnÃ*BÁ”$ˆLƒe4…$˜ŠÌ±¤‘šDؤ4(’	™D”YS%¦Ú$4À²Pfe£M(„ˆƒ0f˜±“R#$3I“#$‹´†Ôj-%‚S&…2)bK4Ò$*X™‘dÒZH™FÙ(ª ÔmŒiÖ$±)´Â4’)F¢¡™™1ª6-)*,QÑX@)£Ad‰‰¤P¢Š#%d“$b!i0L¥TÖ¡ÌÄ”j1‚HÈ@’›4V42п/·S-5™D’L™¡“f›IhÓAŠLÌ©’2m*a¥6H(²¨¤Ö2¦21“"#2I‘¬LÆ£%´EÆ¢¢ÍU*)µE¨ÖØ¢±FJѶ¢FŠm4ȦhÅcBÔ¨Û2­FÒÉ–µ›Y’QZš›6jTi+MdR›Y2M3L””²1AP‘±%“YI¤`“dR’#%‘À‹…£E-™$ƒ&$Å¥$’™Pj$M©(Òˆ"%£¢Åb¢“,–J£X¶b[b$ÅFÙ*QªDÖBÄERm@ÚFÌÚ“#$2lÙ*I4™¨†&j&Q#%Q¨B”¢É•££Z›2Tj2m%56j1“TH” L&2%ÄdÔ[Am¤MLÈ6i–Šˆ’YŒZM„Ѥԅ£"3hÓÛM ”É5©ÈÄPˆÙ”l6¦2¤“BYII-¬V™Œ˜±Š-C)4lVJ¥š6¢-!¶I†›&jJÔM1TF’MŠJŠ*BRÈfj¨¬šØYŒ–ŠÅHS›mˆ±ªŒdKb­“VRɨԙ6ÄdÚųDÊKa1fÍMŒ’XÄ–Õ5²‘”b£b1±T…J£lT[Y¨µ!¥çnmšXÖ’¯Í¸A€3ñQ?«ß®…±±)ÿŽ±ÿòÉ…Œ@XþÝj䤢£²Yÿ|Bˆž¿á™®ÒkŸÝª‹^¤þ/ðÃ¥Ýi‡yœÄô4cWÉÅdŒ\1mâm¡$#%âê*Å,‹>[”ðçd''ön|¾/	a-26¤ÑlozJA+µrÅ‚"3›¶)M#%&­lÏú«ùYòbÿ‚çFA³
 ü©HoýßËøà2ÄçE1*‚„ª¡t{Y-‡].M“ñeU~$2Qݵ©ÌWû¨(m¥#$HwÐW®)IµB˜®ôZZ	­@ð(¨‹!„YÒ‚…ŠDdöäåÃ"Ã#$Q RV”PÚÕ^½1y6#ÚUõ—<Ë…Š{÷—’0[ç[Ò<–ñ]"/‹¦ñ¥120dϝßÒ‰Þu ÌŒÚÒ°ôC³=5üEðÿ0kÏZÌ1ƍ÷WÏÒcmø#$—ý¬Óþœg phVvŒ#$¢¨°¶[_â©IŠ]óC  ÜåÛˆ`Ec8»§1ø·˜mŒû'4'1scm†DDÞÚ„džÈì“LTȈӰ„Æ›{5Èx¹Œ‰•Q·²G"‘ZUB/¿Ûò>ÏM­¯>ŸY[„ú°Ö¥RÁ±âÈ›ll<ByÈ–ßö?GÕ™›´DcŒ`V×L±ŒX7«V•[sY麙m&?ºé¤û®‘ÚªDú4ý˜½\TVoP®ê¨‘cÁ’¡¾hmªS•Ï—ŽŠ,Y2×#%èû&´@ÛR´KåÜ#ÉG#$8à=°8È“y“Ó›RÉÅTŽ²]X1¶&ĵhS±)UЭrÔ±f‹TÆHVŒ-ôå›Â(ÄPX"å§[çŒkŽmkˆu¶äþ©ÙëM®\MœÏ…‰!¤Ã½’Çݨ2AÀâ‘Gw0“õÂ/«ül‰Ø®ELHÇþ<Ÿ£U€8Vl/´äÉ‘$¡D3nËÂGBévˆ<PYVÃôMhEZsÁ Æ¥óT¼¦ë„2{uËùÚ¶¼!ƒ9^må*Uèè2Ê‘A'Ú™m'.­µ'PðeHà¢7e<ÉÙßt]¿r~γ¡×m—=Ò³ÅÆ/ìzjùËóqo#_û!š ×‡Ú‘Aw«²jŽÍ|®Ÿ7&ÔQŠö%òí¿́æãñ¶Ofÿ³'¶×VÃÍž¶mËƒ¬8oþv™øPR4‹”¤Qe<¶——m—…ïe-•ó€!!•b0„´AP7;(_úéÔ¹#%ê+c’”•8ÏL¥MÈÚ`“æáI$yðûÍ×]ýÒæŠI-Ì(Š †„S»¬»÷æí)£Ü•¾Þua…‡}·	^G{8_|¹HÛÁ·Ÿm؉¢TúœWvŸFSµµ‘³Òv[x+Û]îyM¾2K=X°éîÍÃI½R¨‚߁jZא¥YÍý—nýmÈ7ù0%æÈÿŒ‡ü?7cb®ÒW¨®§(ïשà#%l"Ó.öbÈ›ØJIêM
 â^ΗŽT5N§Âô]X°¯_e–Ä=ðªee:wtŠ}/¢ÕL8‘tBÚI‹½0’Oµ×j—¨*×ûl=ñ’ÂdSŸfÑ\êß#¹#û×{Þ³ŽóMS.›ï©SE::?Ôc3ûCì ^NµP8ò@£=g]—#ÿ<(Ëbâ\N”àÚeäåœXÈÅb¯•’c¤ØÄW%–¯Âí’»TÖÁaµd7.ÉÖ—Gwž˜Å3,Ó‘B•r˜ª§ª¨cQ…/„ƒëå/¯RÖÚíiŒoÙ	›µö„6Qít¿;¼á±iàøoàèxmDø3^ ðñ¨`Õ\€\[rï’–Ûö;<ÅšµBa‡÷¨yò$±TîÝÏ—•m/¯l:æ ôL—‰#$5.%ã#î¦Èù/1&íÃÞAÈ9óûWZÇf‘QPYÛMâcžhk{Â}S;kw¤è6ís`°IQòÒºžJòýMº:]]îÁyv¼Ù(ò^ÅœòÔ—ç›æowŽ‘©+‰É¬$N,S¤©*æÆ¢2Øz¬PN>¾.4ä¥òTR×wŸ.“B<;íìyXåÂêQ欍Óz¥Ùš=‰»‡+½jÃV;\¼¸^ê>Õˆ¦(Y†×AÃÍÕ0ÇJíº›&ÿmRlP,eðiÜ°GVZก»#%ƒy†Dš‘#„fh¬ÌPâÞšMx)„©ô¡rŸ>&;ÊGµIyÌŒ'añÛ;Ì¢½Pêï)_¦­',ó¸)(Ӯ͈a¥wl¼´ÏšaV4V6˜Ï!„‹&S¥™«j=7Aö³@te?òUABÜÖÅ…qý–P9WU]#$¬¤PŠf¢Gn>]|nª§€"è®û$7ë3a8V­½L,O΍_?fOY†ª7ñû,ðg±æ{<¸i:èÓD¥T®TnÎÆjÓ¦MF.ôJ6NïÊhI’µúN,8„—stûïoœžðSÚrͺ߶~¶¦µ¦bÞeêþ¿ó"+óz¼×!dˆÙz¦£i54v¼]Ïbð!"»øì—í„3ÑM`ë'óAFÚ6ÿì„#$Èy!ÿkï™[üš‹Ò(i¤QÏׁæx‰ä[’Ì0)0ýj F1	\š^ê(±<^m½ÿ*ù¯áüMÜ£(€¹SøôÜÁÂ"mó’ÞŸ—gVI‘à¾ã/OæÂ*–CAÎU³ÛM[â¤g÷´tå…°²å'…¹YêÐ,•Ä1Oø\ßQ\gÕFDM#% õô®|å9[Ã\BÚ0¡²«
 óQ{4¡ßU¶NËý¸å®ë¬ÔTœõŽt¡áHJ&#$dâÐnÒ¨žÍÓaªÞÀlªÐ…ÙäÀ@‘ROÙû9ñïÚ¬oÃWÛehêü3¶§k7³W,%Êürÿ’¤éeð/]AqÅ䀄•¿+{:gSƒ#$Þ`÷ù¹ñr?|éû7Àé/÷MYpö )"ÀÏ°N1v6}=¼ÃǸæV”[ŒÖè=ïeÜwðwªXå-‘éé%ü²ë=\¶.‚'¨ùÿbâ…¯GÒžˆN:IºûÈ#·{t^L	%:90î@º¢{V]h5s—F1ÛT—b,1 5ûïÝJ±3	„$Æƃ볞Ý+㝟ÆÕÀ‹a?½"~h Ã1ýI@±ÝÑ™à.ãÔíê(jÄý6úo»—’¸¿èƒè!í‚ö««ªd蜧S€†t‹–#	¨Û'oÏW;"ÖxVAîX¸fHß~^x1æ¦nËgw4Ž¨hÿ‚!-¤ÏUV`E…:ßØRD—™ËÉl$‚zŸ(¸¼¦¹Æz×*fK(´À*‹,‰U°{H¡Îyu`]…[ -ÞcL¦òÁnß„…¨cƒAÕó‰, Ÿ·ÁŒýaé°â·b–Ÿows#$8Tläd¬“øû¼7žÊË¿R#$zB€G+šõ]¸=±Iþ2¡“òqów¶£ûcôcç[ŽOïlíÛžgþ’ñíû|ݘDO^Ÿ "' dRD#$žô@ ÜGn‹IµP,Ê’Áêýš<>o§þμùÿ#%‰òìôæàçF &ÚÀX5Ø:æÿ½:X7¨$‘È*0¯e¨Êö¨½·Cìþ߯ý¸™ž4‡-[¬$å@…ü=à¬x„ˆoþ]]Zür¾ã!m#%\àX†”L¥ m¥CÖ…Ó"ÒP£E¢„CùõýŸMuÆÀ³Õ¨ö~¢`\ØqÑ+¯Qcê镏vœôœ-öÃjÜÛ~öÒéxa# 2ÖV&ÆÕuºÅGÖ[+^Ø/ôKþžíþO#$ZÿÅÿÛqup’`ìîÃ$z®Ëµ-ÀógÛ©?ÐZ˜2‡‘QRL©16cô¦nSÓûV"}˜üaµS³®’<dÈÛÕ6ÿ’§è€¶®6RÐÅ(GÞgt‡ººx½ÂË$ª%þ× #Ó/Å…FÛmQ¼„ãÚ	}kŽ†![”`*+ÒK°D´$÷üw«UD¾<õc8i.àü;^³|˜rĘû}ÓúÖÿ×Àü+lñÉ1¹ÀòPñðæê®…CÙ
 ¥þ÷ÍQEŠ‚ðþ*бŽGÄ)¢‹;ˆÛ·_–+_”æ;ß>?…ɺºé+¾Óµ¶‡:,¢Ž¨Êb:Ú¡ÐòC |MêzJµŠtž“7¢¾NunN…\*´BÝ3Ì|üÚ7΁] 5–	¢ƒC]¡v#^.oM±²yÉ|D<ÇJék;C%[Žkú¯h¬ÄFGXCÊbÍI at Hu[ôVµc¨øèúÙÂÕp¶-ïG=F:ò«h¯Í›wPVŸŽî¤½ƒ	UPÖ£VpHhÖ‚šÅhÑ•Ë„Æ)MÒIØù?›M¸˜üIíËŽŽ´ÐÏC’ƒ×ÒŽÓ2WJŠÆÚßùN¿Kφ†ïE"6·b\¥w d̳צþËäÐþ³Ýc€²®SzÓUø»}VEbŸ'É¢’—õ¢ñ¡Ä3±z´dxÌäç:y ÞóÚ5Á”$•Ü÷òÔ뵿o4žè´3HgHEÕ&8}ºšÛUÕ|5-rå˜çËÉkn8é2¦ó©]³“×DcWÈ¡ø)V¹9»÷T’¡"8Ïû7Á"b”g}µzïK¦Í.‹í4Q8Œ¥õ½BlŸì+á÷2_+sb qz»nZß©5?º¦}Ý	Ÿq/ÝÚ£òZYÑØéÔŠ§;.ôpXœÌÂ8EôžÏHÇÝÞ!שŒ©³\¢¨l §½ÞíW#$›òƦwí²‰‹º…ªîÊ…Ø­1Xæ1kA쮐K|fÅ ʧlòÐü_¶9hÛ$õd!³`ˆ#$¾*!=Å£Š¨7IÈ›‰'ÍÛG9í¾>ý©DÀJvØGÒï½Ü³Ð#%ø+ñpu=ã-¬`%VÓð't üÔ˜ÌïÝ&*­NaU‘ó{Zt^þ®åî?UÛè}–:I&7ÌZ€Ÿú<®…U/kZËUíîêÞ:#%	”f—.$X¤ß}wӓ݃aƒ»È-VASèŠ7Ýé:”R—A„Ž`ºAHàr Cë„Çr™€¥þÓ„ÝOƒDVÈ·K6냯3ûãäbë&¹!Ø*ók„ÆëêÈ#%„é¿wÊ—è ÔÜI¼<(òßq¢ÉÇþ–?ÑsJÖÚlò¤¾'Ç5 ï´I0êƒ)õB¦fA+:ºlùΚTÞ¸Ô?\µZùx.œE½:ÌX¡¬;wÞ‰)•@¬ÜéÆ\L¬Cœ²ðÌŒaÁ	!„à’ã.ia³	ù&Ú,¤#%ëÓÄÛ;—	ÓJ#$ ’"1(0ÄZa
 E±KB)+– ¡-’™pez¯.=9½jZQáúŸy¸[4ÂRl'ÌÛuÓ¹#Bé߈ó8õg¬0í)z:±Ð{Û~Ϥ{qø¨+„%}mã^¡}U˜CÈÀÊÅ•F*Ø[ßdåt‡JÔ­QŒ´#%dÙF"g×’µ­«"ŸM \UrÚ†þ}Z:¹ËZľJ«Xö„Y5†è”q(78˜s1÷&#žxsQ™ºïŒDVVÉ(tkÝ'YzÇ|Ùž%$‡D¿5ú«„á«C¾ðÛÏÞCF5e#Àºª„„S™žaæz§dYË“ÜçNÆ=·ÄÔšº¡°šÌ=Ibð,”4è1´6+ÄÄÖ8ÆÁ™#%S3WBɶ<5ê+¦‘88¢#$ëeÓZŒPºZ(ÒmŒ„Q(‰Š4춃J4Æ4{§˜‡EÙ5ÐÞL¢Øxo¢„ož<¯ë¾°dTó¼Æž»²23†ˆhÃEh<ä+Ù³¼8pMÍ؁äáDzŒ³t2ÓÕƒ”¬xZÔ €âÉ7‰Í"Ç5šéˆU˜JmÕ|œ.'jOÄé»®‹ô˜ëôž÷0Òðâ¤$Q›é߻ڽԣ_„Æ°šþš*-³žjÕás{'Û¥®Fo£Èsf^%¯Õ““#$³}eѯSm™e›àlÃi‚šv\jZ`•b„+ÕSmÍú`ì!dâ+™¤KÀ‹ª©B„U¶y,mDXÉÌJÂ¥]+vbaiFìJO"w±˜j]ø?ÂgŸxOiNbÌöFKêm¼ž)v¢Û¨³}a"‘(‰X£i 28œ°U•Ü f$Uƒ]Λøâ*}¨{B"_f=žñMïû²Øy¹ðMÝMßD *ªƒn'Â`Q	O…X[Klì<öëoðûGüz·öáöE}‡=×âçÕ†îVGØŸ¥“ŽAPÕæ顱à!š~þ?%òùì´0ø¸‘1ïgŒp> ‹úÕ01B¦LÇ2† z”{‹}läØGõ¿ÆlVËáÛf†ZU”BugÝ1çôk6%Ñõ|G/ÕÄwÕ·í(!‘s}œÑø”¨@#9+Œ‹›,´¤€$7ÉýÔMÈG¨äùùôþµX‚1×7)¡È2ê·Ã„åíB+dfþ2ó)dS*Í¢âh¬¤Úëíä]'äzþogýÇ—ýcwfpö|^ÿ“´nÊ} ‘Då¼o•íæñF³Ïß~šaÒ0¯î=U¿²GÙsÀ@& D¼mi3_~ËËì[¯V0£ÑžD9?
 _ÖYÐ탹³GìêÞŸO÷q6zt+)ÕÒî’˜iŠ…·JÍ@¦Z#%”ã‚ôž~=žþ½ýÆÜ—^òí~惚T¢…)‚]…å¹rÝÓ+ÇLY’Fø~zÞ¸ÓN5ĸ@ƒÄàë#%à”;6DÕ#%Q-¬C·8?¯$ûütÿH‘?÷‰É°OŽ®Ä‚E}œXq°%5·~^ttá+¶5¥¥úY$¤Öþæù>¯¹ŽtÅ._9ý£‡Ê~V=ók²#$Œ'Ý›w»rôߏÎ(|¿%¯•#TP£¦‹¢úc—ørw¾Ò’¶OPₐüšŒ‚ì“OeÿCYÏ`ï¹Qòoa!S*¾ìÕÒ}÷F”Éâ’1Š1YÌXÒX7ƒ ÉÑ<-‘,獁îŽÜÆ”´"îrµ´¯ö8%ïüåiÛ¨¯è(¢èFCÆaª!¹Ž3î`òè€bGþ2æSódcO¯m{¿B5òP÷Òä±éÇ~?°N›Ròl_,œaJy²‡Ì‰@¤CRU+€d¥9”WÏï’Ýd©ØXŸ€/½ûpŽì;DûLSæâß+½êÍNé[—i‘üJzHî"òVõgõAÇ̷侨­\_7WãÎ";ÉâѐP"$ÁGñéŒbT( ‹FcA¶(> ñÝËÝoîúû¾Éîûx¬/ú·€UÈeN#¦Ê5ŒCÎÞ#$»EˆëQ_]?܆fý=	¬4²OlüpÃ\Í/Å¢4J,íúùퟭÂ鄁]ýÛݽyðíñå÷Cp›»Û±·ì–òàœ™˜e‰”D·|“2%PQ™“w×°«S|“MøÕ|úUºtH8y¥ö4¥ªÁN‡Ž>¥×]œùVO.'»’©„B<uªJ¢0¤ªJ‚•?Ñû?¦™‘V.;uf¹KÞ-Î#$0ÁSE!h–„*T_Të(nîÏÃÜ>;°À|_›„!ø´›¸ßÖ9嬻.ªåeú=t㌩ùÂTJÿËà–„r„òê·(ücýƒKÂ:-•[¶q\úøWQ²ô·hØ/ù²]-Æ"à¡­ø!|)?ÁðýôÇm¶ÿöŒFÓl>>ñYoÁíÌN£¦œ{}ÿKð±wùt^xXuøBƒÊgéû«×Ѷ(%NñCööáÕùÓmÜ9~î¸jܱó"6žèªœf3‹ˆ’~~íæÚeŒÚ3ìq)‰+5)*Y)˜½„š;º•„Ö'€øot·M$Ëñ¥<]
 ‚¿Ý¶#$«ÛŒ}›çìÒœ{¯ú»¤þE6ô½çwFüߎùñÞ*>B’¹Bû¸ßI®ÑÜ.¸OM]õ@#%(é»êé„~³&¿×Ò*=ЦD#$ÀÖ(ÞÙºŠ S¥}fØz¿¯ŸåìÙû<Ùeôyö‡îçêz9æ#$—ÛßñÝîÿ=™~]ÿoÁâ¿Ã¼{FÛÓŸÅ+«Ô>=’·Èô_ˆÿRAB́½À@8Ø}ƒ8ØýuÝö~ÌöTD̨ú\N©µ¡ðZ ìó:Eùܽv|“õÔ@V¸½È÷í;™mnÄƍ‡9z>#$ÖüRVz_áÛÑózp°n¸ù¤³fpû—£…±Œ-`mÂPü¾¹>Tæã8û„?ˆêEz}!nD¼¢{,»Ùp!@vÓõf¼/ˆqaÕq'©†Á÷ûŠ#Ÿ+ß\Õ/´Ёz‡/ßó¹Ç+vÁ›õÐþ?Øñç›!öu?ÌDRcä¿u›ä$0(ÝÃì"Ü7tù?š£¨{…œ[,þ>µú“åô†#%°…üá‡÷ZÂB¸Â#$6B’ØRÖÔc £Ãë©Òçõ6HoVlˆ·¸cÂÇ$•~/?—~ï‘Éö)SÊ|Ó12B´6f -|8z²ã¸-ߪ‰Q[`ÁYP—µƒèª!/“0žÿÂü#$±ñ_$wõ+J|x7Ûîûøú;±íðeEuêoCs×Çòqds¸G»]ƒþNäõw(*v|§_‹Ûú–šú-ðßip3ãJ|pèÏg#$au!ÉAѹcñ{þWëü~¯¿õûfyˆgðü#ÔN:åôÓºR–Ó1Ÿë×èßُä1ù,إΌÍaRŽý(A¢8ˆ’>ð–˜Óq=#m‰Re#$S#%ÈeQ¤¥…m¹5B6f0UŽ2þyUÔ1F0´¬pŒ 5םa¡²–”m&V&R!B¨šmw¥M‡”dh%Yh¬éHŠ¡´·T±LÌQˆÊãˆþz^¯“iƒ‘õÔ;¶ÿoå(;+GZÆðƒô_`ÏÛÇÝ댟iÈ}kíûñn¿]ÄCÕ Ù{ ÆQŠÇ#$U>>ÙŠê£òUÏölúÇœ~¶OÁׯ‘ê>vWJ·/Åpœ1°ˆ#%$ÀQí Yó([3ìúj•?«`êž © TŒÕœ7y» KÜÿã‘QµåÌv#%rQÒFãv1Œà<Æ"$ýÌY«4ϐÆ׆—’ÖúÎܹ¯‡˜ß㛤æ(#Ü1ñê–—Ö˜QìʹK
 ÓæÂÛðÉm#$›¯eÁú7Ùn¯A=Æ}!o¾ WvGöb6pž¿–ŽEÈÌ_òY¸Ïöž;§v&Í;þ­§Ùæµ%‹}?{‘hÀ.Ø¢Œ­<??¿=ÉýÛG”0DE(nËýi÷dXÞeÔK!g*?Õo|Ù} ~Ù1¶r6šbËB¬9†b2\OEˆ`BÙzfaÃ0’š%•heøÛÙô»iµXβ^aÝ•õ4h=6m5‘©ŒvTÛm";nÕ¨ Û3ùµ¤f÷3¹Öb]•¨ˆ–4W,̹\1L2ÒfQ1’†#XªJJß×ú?ç"	j ô)½‰K»"Ö²cÜ9Ó˯¢ï”†ñóZ.ùnnþÿ¬åñåÑòõûeÑQ=²zVçt¹uDÐÒA¬kB˜XB at Wâƒ%Ȇšf—X¬Ï®’„EÑP¢‡§Ïø}{;Æë{zÀ’ïb'‘‡tÈÌ¡´8žEKlˆD$a'«Ì4h1C %önm™£Ñ¥(Œ#%)§GÃÄi‰Çl9š*T ±3Íi¦•)ëp¸š£86í^¥âJ­çB2ÿ"¤3Ãßû ü#$:i*Q#%‹ìgèMÛkßûf#¡ÌàoÊÐ[aPÔjfæK:Ð0ñN®Ò¡¢o_¬ŸÅÂyoû™ÐÜ]`íÙÉ!£ðÃÃu¢Ø¼vû¶w)—壃§‚o@ñ¨ozwÄ-‰š	¬Å·²E:˜\-â´|hº»±í76Qxsè½IrS5ÅÃ$&c3ýûÎñ›˜mK{aôdCïŠÔ ¦u3™%UüïeTD` Ž™6™›œ> Õìàfȯç•(véqÿ/ gH»µìè£R®ªú7+°k|u¥^:揄á’ÒAwŽ#%‹üæ0Të­ª.ìlì×hY¼Þ(É/ÒÙ$hjæÁ6%Œ´¯Á1’âk+*^¢ì‘KbܽÊd°›´÷~Óu”cþ‚̺U	Óa9¢*ª:{ÛünºNS:ý•¾Õ›~ø˜æÏ4™ñÖ7Ç««¿*Æu¥µc.ZÂ{¾!Ó¾4ñ°æÍ$×MOWÓµ‹éÙñ³Äßk¼-m…±up$ʧr…,*Ì={!„ Cè<í~1½ô,0©j³‰BCV¾B@ƒ‰‹T©Ñxjá÷(™‰¼’ÇKG·S·w¼&ê{DÙÎñzgÝÎoû¥¥XÖm$ìÂôÙ§;H\o\6­#%ÚaäÜB NŒ§HðvpÚ¹Æ6ð{ö»²¬2n{9àff¥f
 ¸ËŠWÆqû+îãaä°ièÏÜÕu„cŸ<^¹»Y/N¼û~ÉþŸà$ýÀÃêñÝ·³4QQ€ã,Pñé_ƒ—;¥B‘Aê`ŽŒ#DÆœñ9¼õÖÏKá'$¬ÏrIçf¥æ	â]úýã PŠ÷Ç*püù³~ÌÅSL‚B\¦ñÝ a¡ì¼¾­u´Qb ²(ª ,5ÕòÎtì&—‚÷|å¯O¿¾ís¾Èæ+÷ª¤å2*8$ú«‚ÅÄ©xc¦U«–s–j©ÝÏÄÚ«°øiÄäÀlµœa9áqéŽ9†w0|¿•r 0›»ù±3ÇX“ŒSDËïÝLßK{•‹à±ÚŒ½~©½,^w˜žµÖ½î÷ÉÁ'h«/^&_Ó”Є“RiFP[º«e‹g åx8Pƒ«†1ÏX°§;É ´¯	ãq9Ýî}òÛ#%QìÕàe³Šã­v!^¯)›5üÚr…þI—!ë›øÐ-Øö÷®dŠý“tÝ÷lf{ÂI«Ç[«ôüoU‰°ðåã딑EŠci³ŽnI´$³¦>¼¤ßaÃXw¿¿v£ÎÑq{OlÈ[Ó˜žÆOõ‡#pœZYJœ·¸âö¥bÞm\-bW„ÌÐà­Eà]—±kÓ‰³ Ó#${qBB³…½A9„xüµê"¶çÑD$þ:RŽW˜¥U(‚ðuxü«¿GnÝìƽ"Ѳ’©¥2?kÁ¼Zü[8’ß—™L—M$,&v!£<‹ÖÅÎ1ƒËÛˆ”'9Ü%^Êß¹Ä+—¬Ts¦ UF±Éî|ëFe.&Ó ±,É–­/xT©Yª/lG»o¢sI‘èÕ«7Ä@ëþzëÇ1cÜþ½:ÕŠn¡2ì¾ZZ`"¼ãÛoà=u>N¤”A’„Ox#$Y¸Còåtœô¨»n_ëã¶f\}_¯;R½“K2U>Ä{“Ώ_Ö÷ønÕcmôPzLZj«4é=îä‘ûob°E_i+.=93Us6ו|(vjð|êŠU…m«E]m8Á«4l%¹ÈìzÕíì¶L‡YVk<ñ»¾yÆ¢æû?Ž­cvF»¿EÙF*¢šŠ†¶õfW½	+8yA}³|®vÆûœßÒ:++,£ëÁ˜:×]lïöùq3¾"˺¦½ž9˜l»J#%͵X>U¦0IìœÅ«VíÏ=eR•ÚXó¡úÔtv]8µ5[ÌÜø#%Íê%ð8êj(G‚d1v0X®#d€\îáX|Á¨aÝŸË0káX¬ÊNI0øi’®oc‹Œ
 ”HÉ‚†!HRÌíN‹šCQcG	­Ï#$tŽÝ×ÒÎÜEöš§j5'Æ-sP	¢vYY¸ânjb:ñ”,þïÔ¿@6G‚*¦ÝÂüdN,#z»bb:Jm(ôQÑN–´ˆ%;!©I­šª³$c:äŒÂ7ã?¼ŠÃ8(WY”^Öx—µv›7w÷§Ÿ‡	ÉàÇCn<.êå¶Ó û5ÕšMe‚ª˜(î®+PÈš[däJ¡7‚;Z·ÅaÝe	UÈdØ½9s%™K‹zO²6Óâßg×Çñ¿×ÞQŸv“ÃÝTJd	—¢Áu5žå•µÒ¤¯ÙÝՏùBA«ÔÒH(þŽý8&Æ9í´â½º»tÞ­œáÆ"û[ih>›Úì•ðUÆ¥Ø_™öãüÿÚmú†ÊtÖÉ.ýŠ?äíð®+é4ê͎ݹV+º–¾±þ8NÃðuÄ<&ÑõŽ»^Føàv–bΪ#^¹Ž©©6ãÚŒ#ܘøeJá(b¸ì‹›¯…{gˆ“8Qv#2¨Ÿ63½&»ò3)é¶/ZQ„	ñf7ðRDÙp_¡›3#æØùEwª¡5k[˜R5èÛ:#%JڭݵµÂ]6–Kæ"Üãs>¥õWk»›X‹¥.ni¾-¸ÄÌ×_q鯙¶%	Wo„OÎÙ×}EËv±œ{|æBöqÅ~”תó}¢æ¯ŠWSÝb«ÊõSGÚî©ô­9w†]3߬ã=Š%—=ºBàN/”6tú¤/ÓuVfè›d/lm”å·Zü[õ¸‹˜2^‹Tß…]1ßf¢a¡²=üç#§ÄWŽÖ­ÆiÑWJ–á甤¶ß_ƒÁ*¦KÎÕº×A£Êƒ90#š¨'#%L3‚ç‹´o\c–æœm‰¬ (µƒÅ2Ü©s¬ïÆØ5±„”N#%•2›­Ÿ¾SJõJMŽt­¸¸Úé*«pÀ±Òóq[—”µuãÛlÝ8Icªás]5U‘îò¾š¶|‘Å6ôEõyÜx{ÏG½™DWÖ¢Î:ŸfV>ËÛÓ±tFoÊ 5ŠÞ$`RHõñ„áläӏ~š¾ê§u­âú&ê5e§ŸÎÁólè´í{p…´+‹^˜­3·8ˆAT…¼µÜ§¶PŸ3o ÏsÂÍ÷E؍ïúá`"Æ4L@QÛ©csÛ±il{,‹\¦È78^Â7DøŶ½eê³²{öØ{éÙjOüS¹BܱÐMÇ—O>3 #µoÔðîüh½èÍ5(ú²&ÍÊ3–XµÜn—¼	])¼ˆ™
 ¿zôn‹][(!ey/‰¼xÇ´èðÉÆP³Âû°…\Xhåºá¼Ý!kK!‹u4mÓ©cÂ8²æ VÒ=6f ù´Ê7C¢tÙÁOú}Ì6>/hS…õyïP•—ð‡M€Ü )µk`é#t Ó]U4~ÄÛm<N#²ú¢Ê[Šýþ{füéÍꂶHô­Cø"廿>Â^Ö04¦tˆv^"8È‘1½Ûœ±Ìå'¿¾:äÂS¶«>3•Ý»69#$Nªb;óØ*°)@½*3\[¸ÖV¤åMœD…Û& ¥–k*ùäÃXå#e‚P±ï[ø=Sb첍ˆŠï[xWÂêN²¯2\ƒ«î»Ÿûkæ³pù}æE¬-d»…0pÛÔl…ìƒH¿'¾µÄˆïñëŠ‰šIRåVÁnìÓxpÜáÁyø@Š´ÚpÂ$Ò†ÍÏ[®jã!*ÙeHˆ4]ц|î| »4bôhöÍ'ã1b—w—<:Xê4mozÎF“滥´‹öx_eƒ)avÉG„cU ±õ5ƒ§¾9ókd%xìjWqÇ>¦u]¶NÛhÖ«g-»Ãg×ÒLžWŽ¨8ÛIô±æ,±/#$3Y®+÷¸ßá	»	JëÖ¶éÌ5Šœ³]—\´÷™ötÙùŒ§¹uœ%³ê#$°Ä&ȱ‡£säf%Ϫ+Ø.Ìe‡°\‰ùžca#$Q at 1ý´B{w¯ä…!ãåëªê{?B†%ߎçN§U“)••KFã²¢‡âqaaað|£ Õ#$-@ÇÄËŸ-ÏÉâ#Im‚Ç;,2Ê¥¯øêŽm;øÑ+y×Óh¬­öÔ=’ÅEÒï[I2Þ)ì•%`46HXÍór›Ï®,’ºÏ›ÇÛˆžTÖ·ø0VXAVšÙ×¿dÆÙ_矢V©Ct…‘ëg—~3åŸKŒV¤0Wëdêg¦#%÷"±/W>ŽÍ`>¦Nßbz¡žÛ›n’LŸ!KàϦ1™ŠÕ¹tn¤VƳ‰ZA@@|.+¶MQuTV µïÁÊ_ôë%ÁÁBjXTÍqoWTepsC ‘¯2<Ÿ`»§Óëå¤j1Û–vˆã€szLyžîЄkãŸÂÔe×ÑPŽ³ä¤K²¨Ù`Ù„)ý3˜ˆÑë`Ö,Œì‚¼ú:'¶•ÂíÊÉ~,Ó#%THD.ïÜWE{§H½½È…k	1gYé†-)¬Aq“V0­lCnÍ §VImó…¶27"±‚ûÛBë´zšâ„CQæQa€>LY`r#	
 .‘ÎõC(0Gg¾P‰›ÊðÁ<ÑÕS¿¥½ÛN1Ó	’Ò=Å>ׯ‡ÀµÑé6ÕúKFt‘®Ë¶ðñ¤|ø}Åvñ¹¶CÝjž«RÒÊбFߎbaÅ¢*WŠ±‰Sš‘-mrŽ/“·zˆí°{ü4vàó¸Ð¯BÂ0ÀþŽó–Úƒ¯KV›2€{)SÔ¦ôóyâûNtü$˜Ù6&ûG¶Ã‰ÔG–ÛV­2kÁÞ‡*%ÿ“I(ê×n„Àé#$y[AdÚbwW>ÙÙ¶¢—‚…üô÷?O{¦ùêð»	ìšJj2nµÌ°þJh{W…Ý=Þ]øÓw_A"¢⛘+etpøÔ)ï9¯¯`ÓÃöÆÙ…"}³€ºŸüÝòéèVfÕömÀ0ËÙ}:p¤~ÉQ!Š—“»ÑO“Â-†‡šÕZ	,;’±s±ÑÐ<7_y	™˜yïA†ÆÁiI2¬t}°#$‘½½+2·¾©ý>ÿófÔ	 Gü	1=ßqÈ‚´y}s„®Y%»Gð~‰Mƒf¿©Õð-ª¿Ž³Î!„wéþÑÝÄâ/éDµŒb"€s#% ¨ƒYò’€÷»Jøˆ÷aááIîA<NÝ”2*üð²^'¶7Ö0[3äý+‘@ìÅ–f)ù§œYš¦'¼…q{gp‰%[ÜC‹îÖÉXaÌ‚˜–VáçTÀ\ø#%ìð^·+¡V¸ø¢_vú,su	²Ã{½	­po©¶Ãr뵚HøŸ:ú“Ÿ:råí‡#$»,¬œî–M銶*Œ3ˆksX¸Ï?Ï(w"%ÕPõ*¤z+›‡3Þ~ûЫÚÅü¬ÍÐwÍ]uÛ„s"|ð×­¿ºÀ1ýD\O-D¼Iê!öõÓ¯±Ùkc@Ýí½Z‹Xñ\Bm8JM™²ÜæÓ·ɍÑ%!„¬ÁÀ}ßìòA¯pæ»=8‹Ã¨•1eßL}ëw#$<0ß(%õ¢©/Š•.zXž8$}²&2.â§èéÃ-ýØØé~ÿ]ƒª²	ªøÀ„n+«†ù؉ÄçÈ#z¨[ç«Âø?L””V]˜9æ¾®êÆø#$ŸuB&˜0c°î8P¿Ý” é€üòKwF^õAñ#ž@iQ çeúE†1P7^ºˆö¤s›:‡£LõûÚä±0Á±É£Gw·»ºû°‡ìÖððD–báF}Ã{	_åù(µÏc¶ølVSEsÖäSŽþNõŠ™»«|L˜7
 ã››5Íyo3.Zï*5¶ðh¹ä6i7i ãfÇ­Ú¯}¹éãïƒé€EÙ‹KC ÆeÄðA¹÷½’?N˜`‚°€®pŠ*F5Œä¤RÔQûHÎÁ ¶Ñ•×(9vãzøJt/˜¡½ÔD°‚M¿,Gì±ßjSH¦ÃtÓÓ§}<oÓZòÌ{M†ˆj›áœµï§?J I¶r†ñãw at e·ZF鎊qËØ币ö*ÇoᾝÚяPFKÜ‚QL½ºls·V.¨Í!¤1ϯ{¶8â1‘xPfyÖÝfÔ¡©E9Ši3<‘r=ä#$|7±Ç6•°É\‘’Bç½"3d·u’´ožzÒúÉjÎà€0Ø*îAÁºÛn3ll*‚S–bìñQ퐨¨·p㺣gvh–è	d[ž„‚JZtŠyRéÌHD»MîQÕÏTè‚ÅÔ1×k˜'\1ã¯#ßÕ»Þá>w»}ò¹JÜ—,Ø)ŽœgÎ[&‰¨) „ PFm’¼¢ËŸïÛdÅ÷¨¦M7‘ôY6l®b"žŸ!1‰gÕ’1{ßÆZsJ„ôW® ‚BÍeEðS˜­<F€Ž‘èÄ0¦69-^Ò/æ£C™&”Ð#$Úù¥~éY}­e^aŒJë¿ÚÊAŽKŽ;Íá󜘹p»)™ã=ó}VÞþZ…únžQÍ;&ÎÇfûµ×Úl7¾ŽQºźÎslµÞº×ÇW+§FÝ4ãÆñdYN¹?ðé¢ÒÔ¾äУív°nâu¨šé’Ÿê8kô+@?>]þ„œ-Æ7EwR$”‘¶Á¬¹¬<&‘b¦åµ'`Ä‚ð÷÷¶ò™Fr;õößvLu£s؇®¸{@½’ÄèíIܵŠûv³N©;“Ûg# - h#$Ã|ìß×Æ`YÐ:’T¤¢ÌÐ\‡?ɘÙýVœ»¸åךp‰Ùûï¯|?Øcº1#Õ)¨STT§QJåvýÖúßFî_¥|“ú³,(D’ªªXWù<çi§,:ªlÜÿTOÏÜ7ÈOóDþè8võYãùÿ;Ïhv?N[-#%×#$CñÂÞ¿¿•O5µ±wëIIݬWÞ~û1ë#žß<³Hì-Ä@‹µ}›ã˜f“åÍðÒäoï˜Úˆ-/ù±¼ y-‘Að*¡uYÛª#$Œ*Òa¿JåëÅFÞf®swB~/É€Yôÿƒ½cóÁ’#ÞN£#$ôýðž#>áΞ;&<õ"@øH‹
 CbŠ€žq妡ä)h=›NUý^`3"òåJ¹¹>‹j7Rrˆ¯äÔ»·°éá{u‡0ÀgB²îFT3¶1pÂ;“	˜û"´Ÿa0äüÊ™q;‘kòD$Òsz—	!‡õÇÜ„o©ºgçÍ&4|_WO¸§¡a0þÒ¤^/ïa×ùHs´pÊÆw±C݃Q„>APyëhÓ^’5ç­ÝkÒé®bš³¿;¡#”>[P`H$óó¦°gá>µ\'IÑLm@Ój¡±Xàʬ"‘:†ÓrFM”š°(„*™W¿í)â#%3ÕÛºi›6Mª¶#% U`.u48Œ5!™$…rÑS)I#"ÄølWÑ4úwâ›fˆÓ´x°¼à·`Ü’¡¬ª&عº¨˜<…È€`Xl‘Ù¶'d‰ðG„T5gP2vQÈX‚¤Ä³²±ÔPPV@‘ʉhÎà1æ¼âb<¸–}l#$ŽA¡í×Ý߸_ qDX#%EŠ ,!ц­ˆ{Ɛ9Œ¤f¥pòÉIVu¬,¦œJ:ë†`T9,tÞ<Ö{ml·6¥ÄDå¦1ãÄqÈêõ[3µN6Æí=ËÓ™¢É‹0Ê<õ H%;ámrÉ’ÑÂÈR!ß ÷è™–“[Iï(NNº3(÷8Â\šrQÖƼÞΓ2¬45ðÄöžrƒ‹ÙÔ@Ù*#¨MzõçÈîl7Ä8t.uðs(•¸xÙ¶„9v`Ó†Ü/¹¤ÈÇ,N-L¿D9Г‰-‹>r2;Jæå vè•?Õ­³‚±b 1há¾Ûz´Ûh2T%iÛ–9#eÐë:¬ÈÜíuAc‰¸ ÷îa	_.b·››ÚW”oNLÛ'i9:%'«¾úõìØ,Ö9æ,E=bF°	#$º«)¹À6·¾«­D„G³¦Zº5eGgÈÆ]›ÈQH*Ga§víä4õ{›‹}È™ëã†?\KÒ©W2¥ÙØ"èkCu	7i&Ê…#Cs[’nFs:BÁB0*$T¦®þõ‰Ž”äË8èN«»š¾.œàV†6ˆÈÇåÆÂ'"G{V*Ò¦ ˆð‰{- @“Ò¥ã¿ËoÎyi~ȱÉuå´Û|bTD*žÎuÀka¤ë<;#%µUN8ц"å£ÍÕë;h3Ú¢m•ÖLbwɈàÒ>%ƒ>Áé	{,-2®åþÂì¶óÁ_ ‰xG±«vy!ñ=ÈÄcJ…†< ¸‡¸å„`,
 Þ5FÉ„†-sÃ}S›Á”íà@Å‘ÄàÞÞÝh¯F\áýÞ<Ô[—GŸ«Gd²ùÁçåˆ,À› wk¡Ð&Öâ½=n,yèé^†¨¬ˆ÷ªó~ì{JµòZ-Æñ®[±•Ë{+ï^öȍöãEt®ÆÂ,ÎœÁÐÞE¤)%øèÉÖªÏ?l!S‚¢á]/±É$:ºÀæuC	‚’#ÉL•c4gwà¸Ð`VžzZSIƨ+×éÐ8ø.Èû:Tˆœ	]gv8T$'N§™v&Ã'vÞª‰—.8â1^DL¼Ö¤L”Í÷~¯áÉü-ŸoðpS9—Ýð“‹Ý0<Ôê‡(¡³åý;LpžÏáí÷ñÁ?B—•6ñŒÊ~ž!¾ â'Äè$¹ÿ’	/­ùãù~õ[Þ6ýŸ¼c`UûœÈ$ÈIxTúþ²¡l7ib§ïå­˜¾Ôê)?Ã=¨,`e%1YMMl¢þ=™Æ"æ•*§íþ¼«Ì(DDJȈ‹õÿ§áúÛö¿ý?Þ.”¢cüÿ»ïh’Ãð[_Ëiü¨§þ¢±4|¹¾’XW¨LýZïežJE3S¦xæ…'íüF°úôÃ<Ô¢Ù+[ ’qZövä¾vU*‚Ëè20¾ ~¿Ïß“š®1AÈ…Z!æþ8òåZ°²&HÏñ<)ünZXµDR”^궚¤íÏoÝF¨<ãÏ#*/Ô`@ÜdÒe‰÷}'ìh>ΗýH¥”©i˜{B	_?XØ»$ƒxÜY®]œ@å°b#$#%½QSW¤*AHƒñÓO<Çf&yaŽ5–¼ÿ®!¦¼B ÍN­O‡/äÍîS…Ú‚K¾Ÿ··Ø{Yþµs«ÃŠO—ØõA#%,¬Î3åò=Þùö|¦=:+òuùüŽ‘:ª‡‡]“Ž)(R,ãAQ_:?»ú'§¿Ÿ›Æ÷¿.ïm¥,HîÛ:#$“(^uþ:P™fõùÐ%\»+÷{÷bŸw¥{7­:w$Û]ÖÉDP:ÙÄn³"³ …DCrôy‰ Ïu|;87†@¾@wæD¼ÄVBŽñÎ#$b¯˜ˆœm…™xØ	Þ€6àäèèÝOI ܉­Žâ|¡5”Uj¶£BjD~4îT ÷wøÂýÖÿznîØ<øA.Fmƒ¤€ATSNæq§Šô #$ý@`û~'ŒîDüt9/¾Ø ÍþºÎ³lYêþÿJofÝèÄR-„–1\±És8Dueg{XÛÂxf^„k:ÿ
 ‡ËÅ{té^3Š¤fgCBÐ<¹±‚ÁØ9¶”ß±ðÇ£[¾ôé¿ Ía6#%È°Å$ò‚·uÓ¿¡{á836P91õ⬂U´çý§¡r(d+³^eÜ~Š_Uü=ºIܲs85]q÷p²x}ÔDLȨ¾mÀÌßÒÍÎÔ4™Â*C–,-þ[Æ5kæ2«Z•£‡’A™ &Ûƒ±‰²SÒy Ay@"u´ážÛ<)º>Ö1¨»ü Lÿv?/Ê|ÿÅèø¾å †ï”¿È@D’'ø•(m*…­AòX$ÿ)“dþTm·úöü®üß™åR*³7?Lfb±‘ÅcûrGë|¥Å¢‘nƒiƒTä«“ò{i¶8üà¥9K²HŸJò$t•©Æä‘$üª$o-û”h{Í?‘ºÛyHm2Á”E̐æxÙ•ñ]᪲*ó—Ù=ðx[ﺛŸ¯>kq%¸”Zzé)€VtŠM;¼u¨l	ÿwø¯åWýýŒ†kmë#%MÓ“†%¶jºK…’x~Æò•ƒ‘낝Öía #Þpn‰íY6D,sínþ³•Éílp§‚rñR‡©ú_LadòH¨¤(ù\z Y­9í¢†6àF©ç÷Î&°ûç×Rê7&|TþJ;CÜÔH¨öT%^ºÆ±	#´OÙøÃïl_XŸå¯¦q#$s$ÜÀîÉérÇ>Œ{óÊd[ÇžÍ{8Ës¯'j’ý!óQÜUòÔ_ZuñYÄsièaéïãÓ2Å’Ä<wëÚLR~ød™VzT>Çn‘#fÉEõ¸gWðÞ,vIXÊu¡-÷©¥2.æ×-™-q¥@¨WBÞlJkTHHµË3Éi˜q)à-ÝÝ‹ö^™Có;œ(¾«Ðt+Í´ò…Û«Ç)ÊÖmÛ×80§‡ô¡[ÖÊt¬ìеfwl“J®U~ÇqQ]hüéU„·ÙkÛSä42•­î`¯z !¦Ëkçä¯KEùR $DPdáÒA ÿnzWiu—æ8¹na­e`Bgrûh†…?kYÖÙ·,£ûUæ^ïªYÄšiø«C‚;Þ¾9ö7XÝtA¶Ã‡–ºL°•!2ÃJü8êEëÇ)?”_N=366™:&kO»Û¥`Úûnz÷‡Bͳ–¹„¥4çœËÚ‹.Bwr¡Ù'WKBӏ,ìÜ!›UIòLmD›d RppÉ®ôIžò¦Ñ08dÖ‡îXI6Ë.át¤Áq*’M;f‡lã•Q{WÂ!ç€êŠš¸R—
 ß$¾!”øE¼Zq\`šã´ˆºM"3£ [¬Sú_¦ª7¨Þòþ&0ø¼HÒÖ)IôÍ®„gíq]„¿ßU°ô œg8†Uö¶¸ZùR|)6¹°Qƒrëû37÷{|¾zÕüìOZtOV¼*ð¾˜üØ\uÛ(?£»—Vaë~¹EM	æû(îÇÕ,ÈB9L¡PñÙµï6Ñ{;£Õ|#%’zC¸-öËf$E”ÕæÃÍÝlN—y± —ƒ_Èx¥¯…f\¢Äš&säA8„îwç}´´ÛܪÆ~£¼ïK_Ž5$œvîC5‚ËCÿÕ• N;jgqdËáGôü8˼{UŸŒ’âj.yC<²è*ÁµkyZ qóO®È¡VŵÚàãœľõó[½¹_`iØ‹áb#%K‰1£¿§¦,æ6ã Ã%N¡1݉©2Æ(G¤*ԍÐF‹†”^Õ‡deÂ1ã%!T(ÅúìÕ-®!G%#$skÝsy=LÜXàÄ}Øý'ø4R/N{Ïù{5yÕtëù0aoúx?¦>÷Ÿk_?w›gF at tìpÇ,AúN,!Yœ¥›åº±Îœ ڝŸ%ó£~)^‰Ç–¿·j'ê$-G*Çýj˜zƒÃýÑŸÕ`-Ú9§Ö#ÑvûlûhVuüpû#CæóâIaÿoñËË·o}²ãXýqn¢þ/;ÖIôqiÒ.,;V3¬¥Äíüø.gÇè`ç—nTch{½Pë1Éë’°ÇHj-$ì/`˜I}r<g´éÉ|ÿE#$QR¬¤ÿ_²¿›ã—»Ç°$$Að€â<ß±äìuþåå¹]¥‰5ñrݺÖtAÀ‚€sLCt>~REeâ}Œ°Ã%MS.ˆt{e‡ða˜ƒˆcöxo	šA/aóÃI¤|تA=)‚Jf(Œª Ò=Îñ¼2H;ݝ´{KÏ”yÍ^é3 ªAâb16y@ÊØùü×X>;1n}ùX¡õÐp5ûsà¸UúuòÃ/´Œ7Ê‚[#~ž‘‡Óßgîv½ëf/êðhTNCÉ#$²‹cúqA÷Pr:·#Öôm.v’……¬ÍÚ¬£œ¼:ÜD¦škl ¢?S.¾võݽ½Î~¯{)çÏÑÓØ?W4Hà|È»³Á¿[Ê#%š’>T*X0øËl¾µ&O•RҐ³tJ²xþ²Ôqùš:‡Çº… Mîsnbú2¢vüì~^/{Ãˇ;AI‡jHéh	Kì
 Á±‚b#%-µ«Åãtáè!þk¤ƒz¡uG·±=„fCæcWHÊ(uO Tr"#®MQóמA@1$°Ó}āÿZêe«u)ÜÄ2G£Ÿ·fÞ¼(&e£ÍâgR:¯ÿ_{Ê-XÌx¾‹Z£Åȼաâ¾ç¥±­ ²Únƒi€wÚ‰udT+*[h×	+#%!S&#ôOI ‚ ÔJÏba…~²È•Í´Æøñ(—_^¢š"Z#$ùbU‹¿/VFfØ©´ñ‡v§Óº%ølWÒ$sh1¾"#%+»/;÷!ÀJ/Ÿì…H¤t–¨{`# vÁœ'ýr®÷ïÙ«áU'g¢jŠe†è¼›ÇÉ…,5‹ÇHa­¡JþÇÀÀÃø8E’Aàê$D5¸†y£0ë„Ì)dú¼xûþºÊqÖ  p÷°[tÖË!)yû>ZÉ-¶ÁQáÊ;ÞœÔ^	ß(;È`.Kxdp¡TPyüäBí²Í­Lãlw^A#¯«Xž™f똪b6Òi@±T†£­@uˬíÆÛP‚sZEÅó]œ1Ž4‹fvÍ_(lªÓ;i4+	™‡ËDóªß³ü.VÛë‰[T7áËkl۝·¿_~Ëžpo†íø»`êÒÙ7~5æX`í?¦úÖ±]_o;#$*$Ûìa`»hdŽãvùÄYŒ“Ó $é.WÁk,v¼êEÇ8t59Â9ŽL¯ÆÙ]05dèDQànmìú[|uß­ «w¿|O­7ŽõÚ…ˆÉ¡Xw/VEö>$W&3<ü=žÚmxoÚï“ ½vˆÐÆ÷ʘÅÈà@UT#$!¥:àø.Þ–}p0²8#%2É Î”ÒBtÊ®-6”zF±FV‹.ll$ñ#% Lu&Èøû6$·	5-WÜ"ÆK{%pXÎõÀ=³N%×Ö A–[ˆu´ðõJ|U:#$¤¾‹4ÆcnTÁph°Åî•úÂ|‡#%a½ïo>Õ\ãd,Ã=àƒ%œ—u¾ˆ³:—£-…­¬ÅM‹ˆÑÍwð¿é®éûyõÉëìð¾#%GF/œ»ÔŠž^ÍàšÚ¦Ó5þ‡Øx˜ê²/–/`•³u{‹l°®ò?ƒÁdJpPÓQÐ@ȁ”•™3Ø9HãŒÂ„Î1©ãVkl·{†"ÛPv‚ãŠ.Åöw`ðöhsxªZLÙØ3ÑéŸOo¦7FY@- ´5†ZëI¡®Ã^VÀHðYðÝ<Ë9àó
 }ütñ¨Ó˜Zo˜|ƒÙ&#$÷Æ~R¤ñ¼ü‘qo ô½oÚu||¯p~Ç0l¾–™fÝ#ÎÆp|µª‡ç¶3„ksg Ò²U]Š¦%(`Q´ÛrÀ‰´µãý~í3þ>€}}#ÍíÜ7‘Áÿ_”M)‘0ö×ÖW——NÿŠŽMÚîH Hµpµ*;œ)æJYçۍjÔ9#$€	ùû™˜˜mxCçéÛãL° Ùé¸pý¯Ï¶?/jðlJ~C®13ü‚ Š~ÿä8Ö~ÏÌvvþX@åû_èOäQü"ñŸÁý¨ÿˆ#%ÑüfˆjÐË–Áƒ¡üGëBÉüúÍ<»yœéÏõ±+ÿC¯þ!ÈN®h`y·¬šž/Õ¿aúñînhqDv¢j¡#$¿­íwÅ|¹üß\;6 ÷ C3DæÐÿ½¹†#óôØâš¼DÜu%†gAÔà{åLmÖ‹˜§æSé8@Э…4HCP“ÖS?‡X`Îàý!¯~ÒÔ·2ò²–aì”E*._ºµçWèî«ö»Í¥,í:  {Š#%ׁ#%à“ç@QB'Ê€¤Q³¬'xXT90VQ=âÁa~¸Ü¡@jÅ{0;™p<ÚÁÖ¦ò(\¼ìâ®Îý]f÷‡–xëMÁ6Ð(u	ŸfÁÚsJ–¢£â?Ê~šOUºû{*ÄÞˆˆøT>-°™¿‘¶áò‡ö…Z9hÍü;Þ/A;ב(š²ÍT	M*¨UUrî=ِö>™ò®ÃÕ·WÅ|ähVþ’U¨§0ä­~É>Rgðö\¾}ÜŒ£¬ìùSõæ	%r«ÞU­ÚìU–u¦Ãû9oaóæÞ¸nì˵y¿õzNÒe¯g?#cTÔ`|aôøËÕaøkÐñ[F#g¸Û¥kFCX‚cáÛ0™¢¾Cr{ógüåW%qô¤DˆÈf •þg²t=ì~m`6‚Î?X§ïÔŸOqèÖ’.κJEÕý"CŒÏQµSÎmÈJœiÒÄׂ¹_.FcÛëg?Oåä×*¾°äwNEβÓ¹òž®ž]L).¬gˏ§ò~¿«ð8üô²$©z³R¨¨ÕSï(,<jFAå„`9#%˜«Y¸ÿq±q5®ŸRÊÊÛÐÀÞåVD?öî:{(ä”JƬN@þíÓ¸ØÂWMe¤¯#$~굃h™-Þ˱¦†	¯³Ìaù&xð›ù~¯ Ãêü/ÐûÔ‡—ÙÏësxìD>1õJ#^8ÆÛÙøæú
 !.ƒòLòõê"r²9I!IHAª%¿£—ãfXŒDØûìÛZªæª´5Æ˨`0l›‡‡uÈžÀR^Œ;|EžçÄX€Uï÷C÷ü—“íŸÄ>A€ûœæs=2¹úIj-_Õî:»µêm³«¬q 4ïØz7ñ)³Ç}x–ï½Y½[ÚrÚ$ƒî„‰:‘.¿i¿†)w¯­»w~›·ÚštRpÊÍ…yyÙ;„®¿V~Îß#ê’[´žAîzo(çÝat;ΐ#$ÿiÀí:~”ô«u^6§Šý&Ìý[ϼrNS­`p8p†&&#$(>sÕ¦¯Ë$’rzö¼8RîÔIlé;•ØãÛöŸ}ê;OyÑ[ŸËíÐO"|{›{ËÜQ¯Öcßéà™Ã¤ž®Ò¦¥ê=ê'ˆÓ@Så½@òžÎ>ãT‡‘yþÝŸf¸¯Þ£³j=™'»SæÕ1;òø ÌØo™°ÇFa%ze-!$RF:MÌ#$(Í1:¸Ù…U´ëI;Z0!F#%‰XCã⪈¸ÍŠ+DXšuœgXo¡	¹>`‚¬nèmlá2J÷Ôäûþ^@x;p4Âõ/О??¨û¾ _`„Ièõ–£è/sýP)çÀç=–Ø–OI©!yà÷É#%ÖŽgè‡çc^¹âÌ$™rÿ#œ.̺Ÿ¨ñ3èôJaèÊæÁáb©Ew°Æ'äñâw‚⸎”±lŽPG¡‰AeÀfÐ4±].~o±ÁßÆHðÄtäÜFÁvØ°§eŒŸ¢4šmÍÓ’Ò}ãqÃW 8zçc%W²šé«2jZTˆHª.Ë6ѲXÑFøõg•||êÛÔ#(ÂŒ€(Ô(œLâP$ˆ¸Ï¾üçÂ|tüO½¹äêÖGªLÌ÷1äw×ÇÐpû(±|<t°\¬ü!ðâ{o>ˆÉ©O”!#  Ð瀹É|"sÇ{¯)ÃÚ1Ø“úOÆN@†Àu=‘ ¡¾Ö÷ß_-˜+J®Å$>4@[ì°(Ö†M<f1Y^›céøŸ^^#óN囟 R_ï=¸“Ð~’Z­Ý‹1^¨YQŠ¥¥…YíùzhqOÈøÓç#$§JÑõðMYA—Ûè<ÙçîNÉš‡"–É4C«ÕóPDÍ_šòXÂ3$¤ ÄˆTKd¿.~ŸƒopàvcP	‹ò.È{=½xû¤€^|#ø¬öžî\^Ø•ªFŽä‡“ 
 Ö.ÅTÃM´\ûÉÂy·/R/‘cQÓLÙ#òÌ?½ÓˆDÖ®¶„ŽèŒP­/¹Ú88Ý¥JÅ#¢pÙ±r;DÂðO¶Ü҇&KêJSv䤇ØTD¸op"#$eKƒ~ø~Mr4™HH@ƒ>­¸^Ô3Û™ykÎӁÙ>JôíØñ`åÄ@°RFeØüÞ]¦;<7=8‚Hã†%VÇà;L!ó7x‡¿WÞ3Ô'!àÀ²¤M{øê©*·v›D²iºbùà	9î#%ÐÕƒ`-&¼€qš æ Ý  ˜ýÿNH~Sßìmú€@îøšR˜ëØ¿¿ÕGÇ×éùZkD>¨†Þv;l0(L^&)õzMw«Ó¯ÝêóÜ4ð<S/Xù	ÅSðzÁ)Aàó9´”^iKEïQ7õtZ5@¸Ru…ÜÍxe_´íöuØör& 'ãöå±Ï¥CÌcκké˜dÖΠj6ÊÙÜଲƒåÀ¶š¢*±TØãDûžYùþ_Ûõ«±(-4^$³ÕÙõ(ñ|èܧâ‰ñ|ïÅïß’¾“‹»Ûâk\Ö9è+Éû‰ñ0ûCø–h¼ç¿²W¼ŒQ"‘€FÉX)üÞ̨ˆÊ1+E1¢ª»ûHÄñÁReŸ%k[[¹çã±Ú{'á÷zbv ]î53¬ƒ#¦à^¢}ªlÀÀœöìá*J÷‡Òúëpç†9gv÷	|u¹Ì»¶V$Š¤‡HvKj‡ÖDüuz×"ßkñ}Æ"$ϯe§›¶®¹h#BŠ§ùnŽœ{æ$#$àAÑÉhRÕ·"'ù¿Qûz¹’~â|~¯#%ÙÝ›{ä~š¡ŠI|±^RµÓUÊ®l˜¢Û\ýš©[D[ûKVw63ÌèƆ¢öÍÉLCbZ ?Áj†¸¾¬Êeî‚úýK ÂeÍ€š[`i1d‹H ºk–vÿ^ÖUúÕr#$µýd}Ù„HÜ»¿$Z#%n 'kð-ú`¡¸È2Ž[×lÿcÉ_¡Ží“>BCqÛÛÂÍ÷™ýý”p‹`7p&l«qÑ÷µ›‹lvÖû$Ò,tµç]ìœú±[WæÑÀø¾ã˜Œ›yžfƒ¦4qÔy¿Éû0Tì‚H"c"ª5T´‹èàõô|Næ^ØHv:P†Í…ßÆjï]¡¼¸dz1™¥YØØçcÙ…3]=ç«fFgyFn;ïP#%¤U#%> ˆ2öS½Ã¡I]Ë–!I #$mšv“ÜyÞŽg„Ïw)¶NÃGݨ,Aâ¼¥¹ƒÇÐ~‘
 ·{˜VLC¶EbeÇ;‰™Ú;U‰q	¥ 7ûžjê?MH{‹Øý£œ|?äuŠðTNü»Ä{»™‡”_¾?óh¦XNÿWü¢!ñTKîš8!àAdÀÀVÃû•UKâœ8M#%8çù¶×X¨µ,\£¸÷²B#%wÍâÓŠ¯¢»HÞ[:È+}í“×¾~<o@¼ú;E»úaa›ËøÌ[ý7¾Z_ò=,|C‚;V­SþwتáD½²¼Oæ¶4$ŒU(ngºã+¥	x=q¾;i¬˜ÆªšIDß,\~õZÇʳËÕ+t®dPØS3GgöBÜ\+¯ ö	fÿç!ùÙXXCtîýøKÏú¼ö3×P˜$D&aÕ”Þ-½<•Mõs®Ÿ$]÷(è²ë”[•zÛŒ’C¥B\[>›X'¹îdŽ *ÆF¾ËÇÆÉ”ˆîX#$ c8žÞçé à(ð;R›` ýçÞdgëYK·ŒÌNŠäÛéÂÎÁ=ï>WÒ]~¥ÔCUi—>k—«‚–­Ö9£Ì/\yJªàGµÒ¢å#%gŠ•#% ±Uƒ;èQØvÑ;'o‡†ë…EùÁ¨²÷­#%0ÃÍ<- |ÿ¥7{GÇÛþ±ý5#$ŠæQÎ2¢'³€²;‘# ¨²‘F	":È^ŽøÈD§#!Öe7±G~œT dº¹Pwm€ø7`÷éGä%	¡R›c̬^šítÏ•?ž-³)Î+Õ	2ŠÃ?gõ]#$Ðá:¹õXáí®Üú²º¨i¼ÛnM§—-N‘üðÎ ß~²ý˜§}8T›¬Ó¾úZt%j+F<ã™	®µïï?ɹí¶CB7L”­¬ìÞíÇàë¿`ì9~DÛz›”d¹	øéÂÓˆÈ \m°8^Lz÷²äÀXˆZu|=.§ôÔ¤AnØûïžeu³ù¼Rt;a¸ýßu­oÛUß6:ž0xÿ5MgÛŠBH0ù_À¢û%ZOŸ‰þOÆê˜þ£æù%-\Ç÷¬?i™–QfF·çMæ†£$‰6~Ò`à8¼6Lo ì33]N<DØMÏš#$ÏÌodèR#%ÿ#Úkë;í:ʇ³¿Ë¨nŽ¨›sÞÐÔ(Jz`L°íÞsNÍCi¡UDZœ“#!™nÑ'uµžŒN¤¬ÇÁ䱞Ôý|oç£t„J+c'ñ€D	Ø‘Œ° ÀÃõÕÀo4ˆÅda‰EÅÜì¬ýß/ÚBE`ȤŒUˆ0EKF0m
 ?Vj¿‘çÂüëÖµä´HBˆ®Ô„×í#¬?˜Ç?óí·ñ'ï“¢õ=ßJµ$ƒlT}2ÇÈì!$?g8G´M5ó8˜!ß‘ßÌnnn04<1ë1'&\³¯r›®*4Q{O4¹Ç}Zg	‰SÔ%»àÚCX‹ÛÒÅÌ-½±ëMÒYÜK5ÔÔ›LA¢ ÊϯcÙ);Î&U#${êš©ÌIÀŽÀÐÐ(ÈUd°œ‰$çD¢ºžPÔ½œ»Ò]LÖi$Qƒ¼w£~°¢L–ZÕVN)€œ­hqjD‘ñm†D(i‰0#%“Øæ>-'9˜$¡y%ŽÓCˆAæcV%Z;ž®ãñµ“ÈÉÈXøD¡£k¨0±)AG܏Bè¥]1ì¶ñ€A:(tØàÞ2#$™ìNz¶°¾^ë·¹VK˜®xh¼>¤rECÔ<#%ðxÇ^v\ÀGTÁ6àHwLP‰~dk4Ö&“À¡ˆ®ãB©ð*ɐâíÞèBÕP¦mþ.Ôßjl†#i—óøe†£ÙÒJ6‰½iäÑϤ”h˜(X;)âCY¤’h½67¬‚Ô]Þh…6˜#$yà=ZÃc©â`4­ržÀÔÌ†¥ëF¥ÄK'®Åá|Áà(ö£CB#p	äÛêNH),e oŠ<)‹L›‡ƒnÇò£u,&7JˆÖ”%ÆæÜXì!ÉìÉÅ5S̲ñ ¹›apØn¼‚G½Üeà,À¸=:õxÀ•¼Lˆcu–»7‚Ù?«w¡šž™[àeÔÍfñãu[/#%ebE¸Ñ¦×F#$䦠Á¦âÀ _/#Iñ¦IsL|ó¢1À33MHhHG“s‰pÚQÐ̆Jc"W\(*¶8)©ql…—FÃÄ lç$n$ Mƒg‘PS„@"åFÔ«‘®Âôi{øÁŠ1TÑm±£2yDbiŽÚ¨†H,§ž…ÝjvèèÆ#$h.ê‚¥t텐à„;ó„Ä;q,ðK‡X¥bmÌU@ÛÈXU#%+åß;CPÔš¾‘.:ô¨&;Q6,ÁÔB[½É–q@’ÅÍF‰T™¯TIÎ!Ã@ˆ\[Êõdϸó!ð:lÝ}ÔîÜ”&J#$Ub'käY#$V^i¤™@Ë-Ý4ف8ñÍÙ‰$		wâBzb¼ÇDáâ:!Ë r2GXLAÖC`X¡ÞÎy«`fÛs²HÃѳEH[DM‚¨}}BL;K4{Ï2’>¯è
 \zµªÄM%*ëU––‹n袆dˆs<În”åês‘MSXt5œ&çYàž¥-)°ãH%$4êôªñlBÉçƒç‚žbÝ-y½‚L°ËÎw0*qÖŸí`–½	Ÿí-#Kç6"¿œýè	:ɹýX-…3Ž%ߝ5.òI<A<çC¸–lx'uÞWŠ‰ybÅY&…ÂQ1&Ý‚ó!× Ô“u©ØŸÆA.¿7¯î©ýßãØdr ö 'Sä‚!í¨Ø¡)$IEe@ý®…A5‡ÌàtNÔpKº˜—à{Ò‡VÐÓOŒ½‚‚*(@‰Àd at tõˆÒÍ J7L77@¤R"©&¿T×rû5†F´B €ƒîUµ~7è?4„‚,2tàày…-È9c QõOX§Ÿâ„	ŒMV½…õ\ÀÉEäÆ+ã×SÕàÏ´a˜€Hõ±¡çϬ‡`¦É¢&³`ë-6¤5yÌÏñÊ1#«<sÓ?crX¬(Øc…fʳ’Ó–£O!­r\2Èau¨MrTï †ÇQäÏ]ýáfÂñ2$5B†gÝPæ˜d8>lÂM;ªà‘=ú4…ÅˆŠF¢FAÜÁzÆžäÑ؈±€;wò_õ @]ˆ/dC? Öˆ‚á‚€H€¬…0@„SÓÁö— ñê5H^’ Z½3‘	¨ÆÔf6ò"š•çÚwßHÃŒŸ-‚”ŠE–¬:Ø[(IûÓ,¬4e“	xáv8¨#%(*Œ2ÍCu)x~øpIœŸ£d.#$'byã&ίª«–*z•d=ÔQ"%MâÅ„‘7Í)1ã=|¶šþ²(B‰)7vÏšp¬µº#%¡„Dç`mÒÿ]›21»k½wyÝÆêîºÝÑ»Wvm6¢’I! ٍÂBtÊ`ÎåÎÅ=¤“áòœç2Íy%{±‹¢eÈÀ¤ž±#$£4üW¼Œ€Ë”BŠÃé]æ….®[5?TBD5 oŽ®_é™Ûô|ïyÅå¹ ‘$… wÓ­Ù¶†Å’¶ÓÒäxü À0Ê[}ÜoCG—Û?ÁÚ¦ ”ÃÄŸZBv”YË3ïþZhüº«êa¸Ú«­@q«²_UÉqÚuª‡³©xXõ@S¡	n‹æŒ„€1îS7œ	~pÕDä'€Ù¸¼¼þGè(öUI à5~u3é©#PV*Š,Ѥԍ¶Æ²ÒÊjÍm–ªÞlðGÐ@D‚½Û(Mh#%#3%Š	¯ÒØ°õ y²7¹,sëÕ˜Í{>
 |A‰½¸š­-(H&œ!	#cEŒFÂÜl].¡Mཐ#$I!Œ™WD¨ ªÒÊ„°6Ä?Ð<Ò§Ìeœ‘ؓϸsÈŸl…wM®T†×ºÚó%ðº¼ÛïØÀàðˆ$H`/5Pâ»óÕ'»÷µ½á° rN ¦§×æŸÙÙó|ÞßËðþŸ×ý:×Â+¼ùäôXG²§DXÉa–Iòû(”žŸ}c^[]½vÅÎ#ÁšEkŠÂòŠ‰„M+üÁ„ÜA$EÕëwÄ~½êõ4঍ÛX^!ñgǾ^*¤ü¾ÚÞžRL°Ö’L»kßG±[j0#ü&aæå·Î dé¬æ#%ê ²"w>¸²!Öc½P塁c³(vÞ`“f£hˆP¾TµñukTn„›÷ÝMüd9kó¼Ô1ÀÜuÞ†ÈiÉ­ª•Ö€ÒÝNG†‡'DJÊQ£!yI¬ ¤óŠ?Þ+ûEn‡ƒûü!ýu%w=²­)§Ë´ÖCبŠ¨*¥QSK$TŒ©·Õ^ÿ‘>_/m£%ØŒhís˜åNpÎs+e&SÎ øæƒ_g†mŽj#$„£cÉLh¬ŸÌ!’×㨠Pš®ºÝ?3ؼrÏþ§ß;I@‰ŸonFÊÚ´°hd	$Š+"2‚L¹Á@Ó%ÕÙ­·b;Ãt×Eý'jŸ–(™Q{1üßÀˆ’è~¿É³æÄ|8Ìé¢äÂÄoµß¨…ï¸ÉûpÎË–Eùä¡`sp[ÍÎüdrÍu2·} è‰Çœ…CØOo´|ó)E Ðdc¡ðôïײ< ”ãÙövƶƒvYui`Åd:æ5A‹žb0Ã6#$ƒ.å’j Ú'ѨtÓ×ÊÆ/PÁÅñÝ|É•œî`ðG4¦Êùw® ø`Ò‡n9[2äAsŽ/ºt,ÛÏ߇TÙ±Éí	‰—·Mï1|;!vëuöüe{…÷yQ|WV€Ý¶m*V«k4!¶Ã쇏/"É僔¿ë—V-j–vqÁ³ÀÓ-ó¦ ÔÕ¡ÇâiѦ "š~•í›Ûí»pða½ÁÞâIt¹³[ÄèFBsÒI&æªÌK|û€˜ÑtÙ5›ö˜áÈÑN®µy³dj-À)I”„	¤ŒlQ¤8"0CÂÀÅ¤H…º˜A‘##5'XÎÍ`sÙäeQÊ&„QRq#%œzɃ¥¢75ýP at 4ȁ”Ç¢UçW¯;LªÜ¦EJU¨Q±k>Yðò˜
 ûênÀlã‚„{صM#$Gk—|SÆޓ¸N> u–Ä# ¢•H[<j¡ˆ—dlr*ÊÃZ;â†Èµ@«BàªAs“†$]Ç·‘7#%·£*Ð6ˆûÝæŠsÀèܝ•QÍ,r ôl¼íí@ôEX ±A]q¿o>_sãe5›L A‰T;L9—™/f%Ù©ÏÜiΊ¼ØGcGó{@ì\?¦ŠjaýË€ ,mÕž"1ÔŠ÷Ê‹}Íw2Ÿ©¤—EÐlÓ#S·n=¶úÌ`p#%)$„vÊT°×8ã9ð#ke¦\¨‘õg:î†jçW͉àþy—3‚{ñâ\i"Õ×3¹p¾ê2;SasLPU&5ÕáF7‹lQ$þØŒ¾›)Ó¿—o›çÔåë8)D%†Í@hÁb//UkMVN±`Ý	#Ðvîì8ˆrìæsf¦Š)}´N§ˆ!°gÝÕ×a…Br“´á|âšVìë$î#%æMc(bÁåéN0SLx‚ŠxpÓ˜noB`ï¸aJn•0Û@_‹ŒÙm¶ÍÏ­ÖcLÛ£[;Y²Ì´v­ø¡Å\&‚I8Loš“b¡üo¥OjÎ%i¸H±‘`òXmAõHȈhÃÍ°¶eQ>©dXŸFGá]—ÂÈÒÓ¬lE( (Gn‹`„ƒܽ“Jا‡Ë¼Yà÷žÏT:æÚf1‹40¶XÏ+Ԛϩää‡åxµ9ÛpérOIJÛz{rÀÞÄÅø[$oöM­6‹)•éžfA­}	#%èi‘EtûºJ¤~oFLãåpщvúkZO‡ª>¯Ó÷r<C1‡Öj-Bð±èËI#$H¶`ÇŽ i¶™U{†8&•þ¶*«5a*¥[F£q)Ò¨èÇÜٴ؁£&t¢€Ë@Æ%“ßd¤PŸ*FizY€B"áø\¡åD¦g羈5ÎC‘ðqGï9±â2„ãpƁFW᮱Ço†³„Ÿ†A{6„F˜Œ3']lÞ†í®n£iéR$¡ÆºKŸ¤wa-evZEàìÌ^wxÒ°êZ/’š¡î^žÌqcÏë¬V77í?¬DOÔ]¹#$6qÎb€QáÙƒj-D –cb¥¯T1/:ː ³;q|„’‚Šâ@ÍŽs(]"8‘(ˆë(ž‘DŠÒZÑÄA#^‡))ÐÐÏm«¹m)pYÂ䏒éÉÞ…aÂAÊå·ve9!DZiÌ°¥¡óò±Š‘îëk]­¶#
 ^4h¤DYöš3#–¼Å‚ö†k+C–¾‰	cñ9@‘¹#–k6]´aÁ„œ2‘`i•Ûƒ¢ È1&#$%$£¤˜"DbSIÑŽA!/d,à¦d­Òe"Üj2.#$ ˜®#$`Ü aI€`ü‚Ô§á¡üäÞŠeÛìMä+F¶1‹[ÌîÀnîZö¢§FöµWîÞö„tS%&b–ÌË;µg]Esm¶¹€¨	"PPy½|õ8m}RIõäÆ¥¢S æX®}u{Ô¶S!Ø÷;Kí^ûïÊÚý»Tj6M¤ÓF¨›åÛ²,¦RPÅ2”i˜P (P“M–ÆÔšI,Ò#$ˆ*e&b‰~Wna4¦ÐT’bH™RK`5°&íâÌÎ?¨ôzuÞd	›oe3=é8`Ãÿ™8dmÒáÓÊue¸ì¼kÞ°ƺc–©2ìý)K©qHØÂ#‹Öå#$ùãwrE(-s3å¬áÓa¤S­Lî$.g:1¶äÎõÅJŸÕ…ly\¬.ë{]1ýñ3&˜ùL|«(:Ããó=9Í#li¿Gp ÖEfJ©kÜiž¡¤²G˜ŒH‘$!HÈF'ß8¼¢o²=]}½{{<mA™“Z÷—–”+a¤PX—Ò<Yº÷ríž®í暑ëZ"·WüÿM§ÇCãÈ<-¨‹>¾åG»#%)‹•aÖ}>r·}í#$¦þß¡¿»¦‡ß‰e7Ó®Cür×£40*ö°,ê~nþxr³´†Ó8`õø'•Ž˜Â.3.E`xÎp>*mb­YIDɝðgk”\NÛg‹‰ýIßR–&Øï©ØEŒF÷ÅTQd‘T‹J»œ«O»ŽL¾0õ£&ýꆁ!;1È‹ûY£¬ÏRÙ9Ò)r Dãd/óKäòléY}ö˜ZŠŠ¡ÃÎwŒ ;§ˆ—FüüË»»»Öû\U{5ç0“U&ÏNŽ<¦'rWATĐN¢‹Ð*{úõ…ðýå"āžRÂÊÁ&HLLëŒ'V¡»rØŽÿöÔˆ¡™›žG¶:\ãé˜æ*bê`´¿¾a¨æ=ÛaÎ=R ïɘ`Ò%'Ó„c[ݨÙ#%ôÖ¦‚˜á¿ƒ+4qMqñ«>×	œN™¬zÙ]œZñœ\g~&÷#%ÖØ·¨´q#@Þ²[Yb5lm]RWu¶´²hw®õt'4ðwŽ3œÞíá&–f\¬Ôü5•äÔ.Þ=9ŽÆ¶·1Öñä!tmÅÒ¦@ƃøfîûö¼çV÷
 ÖþfFÍíd_V[~Üxùq!A¶#%À·ÌkRfäÚê‹<¶´SûG1‡{c4ÒÐÇKLعiH¼¾y,6Û:¼‘3AÔÛ„)”Šeª¦-Õˆ)dÅõT­mžôá”ļ¦FåáóxlnçGcÝç×xÉb}ð熭›ãgd<Sm#Ž°áq:\£ÞYµ’NÅÃ…µìÜv¶99ˆüR‹ïa¹§XÓÛ"ΗlmSXy‹9YâšÉ!jÛ©yv´Û4N&Á™Â°¥Û3–)jx‚"M¡–Ö»-kE†¨EeÔ#$#Íb·B#$¢äJqÛp›”ÓÜ̆a,È‡Ñ³Bc[hPëØ)Zy§Á‡<àû®ÝvW­Tua’kC‘ƒ®=ï±q܇{8¨ø´v#$‚ìcƒg±¸^Yٍ÷ðŽÍø6ÇÖÁôš²Ã™åÙ¶(„ÚÕ©®›L µª$ºwËíªMœì´Ó¢‹œVXe;ßV7'}M¦²<¦°¡*N)× #doÖaïÎËjŠÝAx¦…³>¯j}>';¹ËV²–­‚óšwEž!Ló+lÀ„!jh™W•#á¤.\¸ØäÔÆï,à!ౚK#%Îq%Ö2÷¾x¢/!³Á2ñ±8‘YìAà Lé¬GLjoö;ß®ÉÍmyWzÞÅÕ×3PL܍±ªÜ×GÕãZNõ…XÖ×&ö6ΪabdWtNÐX!åÝìëî›ÍÖ·­,€Þ\vDÆe‡_dÖ¦özeÕt~7w–:Ä’íYˆéʨ&̱’JæÖ‡¥KjŠšWrY²øsL+4³dÙpåšu­2´ì-³C&¦œ)5#‘Ìšæo2è„.¦;Ä6ðÚ›Î2Yšêäˆ'MÕ£gÖò`ÆÛo§Ï7‹Uê£Ã1ó¤ªl6–,28k4X»Ð)“BÕ]ø ÙÆmV‘Œ·­8K€œr69ESY·¦Ój#Z§g˜œŒ5‹*ÞâØòBk›Xe*(ËM¢Ï!%5Ê1Jå3$²æö/]²A qÑB at uñ2«ÕÄyg–×òde«1ª¥Â	 ]È#rSÇÓ]a¡Žî†Ë6HÖªpN{¼³KŽq/‰aÎVX/ÁኻhÚ.ƒ€”î•¢ŽB‚¤&Á‘87Õ;rT^ú§W*çqe‰–J*†êÄŒæ˜Ù)Æø­±LYÝ+hÔPQkz´RhÖ‡¨6̆‘I‰Åîĺg‘ÉP vdclhÌ„	Ä7¨LÍ\奄œµ·4Û§â˜ä$ÈpÍ´önÆÚÓìêzÜOØÈÙÐd×eJt:ºú
 ƒï¹Z7¥ë+é!Ý¥ÁÄîbv0A„µi”ó‚bgDxãS¾¬æt4;¦L“èÖ)¬‰ÍîÑ9‡7O³”‰”Ž7HŽú­>­Õ^v½ìÝzXò›88å@îÕÈá"-DUñW¦pŠƒ{sã&4ÕVM	”3bo58–jfïaV‚eÂá­`^€jã8Øm9Ä삳4xˆnê(#$QPnʁy#%0Ò4u%	m(yHv„:±¶Ýüp} t†ï–Ö¨«ÐÏC¸-• lÀòè;øUb©ª²i"Ðr¡O èr‘¾א¸#$#E]ÄJ³#$¼t˜Ðp[ §Xd12!Dˆ ÃMŠQ\a¡`uîAv!ƒFx1Ö0#À±aÓ$êºRÅÊ”‰eÈÖh]0W6%Á Ñ ‚4ÉH¡J‡¬5€` 퐉œ$•#ßv戉J:›à?Ðêù	h˜%©–ÉR€ðM$´}D–É cóÝÌ94¶¶?Xznqâo	ÒڏÝÐóò鯦{²4ÆcpQzô™–Nu`26oZîÇÍÉdJ>üá½`Í4Ímcm„€BɈS];HnÆÉ¢k	«¨‰¶ê\2_è 6ŠŠþÈ°` \±J‹1)W`ÆÁº;PÚÛrc‰#%ŒÈ±õ‡—“ïš&xŠ"ÃhÝ@úI‡ÈˆÆ‚Ÿ(…Gë	yhH¿IûÚ”æ	Àb.´9äd€æŽ‹ªÀ‰­‹x Úùˆå dGÒЮϪ>‡Ï^ÿyßGyïx?ÆGÈrS«dN•	T2¥QSuÎÕÝÝ\X×uÚw4]v»t2¨H€3dÚ«FŒ€pΰڠͧh$1G‰¡˜k`œ4kJš¥ILM¿Pw}.Ðk\) 2O~fAÅVº¡­‚1ˆ²H ÈkÖtۘỔä›Dõ„)#$hämœzțʢKº;h¦$@HE#$êJd„¡À‡xmøÇÏñälÁc‘䟥U)Š?uÊPΓ4ûâ½;SV2{uHI	Pª w.¼]®íÊŠŠ4Mæ×móyæ%â®î­-¹a¹Ã*ˆ1ÅŠ²„˜„È·o?K{3XkkïqÊ#$HáícMó¹å¤¶Ñ§„yà¤2/C4ÛC“"„Ó…<>­cƒ˜ÈÖªÓƒž]OçÐ`i…<È´>,#l¦jW‘&ÂèÂÄ4*ûõo¾6xØFÁ#%u.áѤJ)¦J—^ŲS½ ü ƒ`èPS7&èeßæÕl)
 ™•,’ϼøÁ·—ŸS¦Y|1_‘»ÞÉÍS‹N3¶DÌ™—öÓÈï›Üz½ÐUB§ˆ²_œ3NaK«ÛâŠR=Kµ”×9#%^!¥ã)Ê$Ø-r‚¨¨1`PØ—Ÿâ‡¥taaÉ/d%›·"¹ד#%ïÖ6Ó™_G­½ª”‰ß5#$#%“X°Ò”l8#$°Ù6Ákvi»ÀÚ¥d҇͑æ‚B#%P´îž›ÖS€h¾"ã”<ŒKR½¿¼„辤îå[«"cÇúìUü¿3%®Ñtæ"¶‡­(½¨ÚÚOVÆ0{‡˜y·oibÌPþxH¢w€zá~8ø-ÉÞF;pŸäè1gÕ¿’£Ÿ#G·¡	·üC/ì3åùk7¦=Êƾü­Ùb]àÓ"ƒK-(HŠ#UËjÄm¤¢¦§1ÑÖ¦¦²<ÛÓÜæážxçU«-Òj"Κͭé[Èí$Ýá›ÆúnS+—|4Þ752uͦY¥a¶S+ss\ZssLÞFM,vrÍæX=§Ìåé6Í0Š‰·ÐµË[	I¶qp]¹0_AÑ#ÕíÆ’?^.IhÈ¡HŠ0ɼ¡¢²`dÉA/„K$™Qarœþ>¯<“éõç›YRÔÝ×it›‰»ÙMÓ®»¶ëºŒIW,–.üüÌ<ê¼»^DÛd6¦¢mdÕ›Kf¥Jl“êõ~S‘Ç:AIXÂDQ"‘ˆ'³`³Ïp&*ܳÌV¬„%"ô£ãᪧžaþ´¿åíÔ… eÇìŠ2;†ÅÐÖšz}¾»—ûþEŸaî¼Ù]¤P‘Í •¾YKÀd[¤- ‘`Ä–o«<(Ï#%鬚®Ò±¯•—>pú@µ°t#$–غšqµr)»,°ˆÔäsÆë›\lˆ^=ÔÅ°õh`Æ¿i§è!‡4‡C-+Û£§f›tð™ü1ðOÌÝ*ύï*íq¯¸dg±Ñ·uaÚ7í}ì‰6I)µµÑ®tØŠ~{<Ü<ŽÕžøVG‡à'š®ŠË4DI‹TLÖÏ9ݦó¸ÖbJÓ%6]ºÜÍ2¬FeŒ˜‘´¦ÃdÓJh–ÑNk•çkWT’–W:îïyuJš¬m¼]LÙZfѪM%VÔQ¶ÜݤÔÒ–†‰d²X‰^—[i©•jU&Œ*JÔ‹-SMy7SY#%M¹­ºF5´šË—kË‚¡ðhcòî¢(¹ïÀ_Ž )Þ¥#$pÓÏÁ~žê¶èà…2ï,ßÔPx¯Ž‘­%%n]¬¾Æš
 ¹µ‚1‘A´U¢#$Œ…s½ÀC?*,1W6 %	ƒðÞÒÚ•l´AKk3Ze™d“mJ#LÚ‹6ÊæÖ¾&Y´¸ Ô„QW¬Š# …¤ƒ„ø†'™Ù&¶ÅsÏŒªâírÕ3œ` ^rÓKZ¯×€‹­§Vi9R`kƒáÖÃÀ@Þ	Èóyò<”pšÕB¨íʝfÄؘ¦ˆ`뢲$¥Z›šâ¼ÃwXMQ…2Äöx!ÀräÓ)î>[ÀÞüê|ú0Q#$§ØžJÆ!lè=\÷höðÂÖy©‰ìáwÈ,u½”ŽÞ¿YïrBÈHGH+ºäíI#%÷h»t^¤1ÌUÓËÂC	_véÈå_¤Iúsâ•?Q›Ú>²-¯!Í’G÷d¤n2Ì8é WC‚N£ÇA5ïÚu(|šÈaÚ PQJI²Å¤Ã)#$¢áöODÄAkØ>xçVgÖŸhI@Œ\ÃBL’Iªæˆ¨6‘ºjíõ0#$j‹e²@¤óBIG¬û»=™ g ÏçìžøŘbÀåÞûyx¼Ý—èka@=ˆpôh"SŠ3ªáÖ0Xª"ÐUFß#%d´USº %¡Cn1JC˜PUï&Ràhƒ˜“xÚƒd#!YøYF4©c"ŠN‰i–"›Tœ!1æsãÜ O@	0!rª°xØ[XA4=Ú/~h’ö§¢ ûšM®ip«.$QhDÞ±ÙnªTÄ‹äà(v€½@>õ™)ÃJ;ïOKÓ¿]GÔ%–ÕµˆÔ6±T`î”"‘‚kkyªipÕÙÚlÉ–-¥H¹æˆ-I¤˜´Dü…hk[VTXõ#$€’™©ê,Û€!`Üü,@©ï#M‚£zÛ…À%“èE at -#%š€»µíhM‹Ã4yÝÓ¯OÁfTF–ÏOhI›ËDŠ®$îTÑ#%1¡ŒÃæé¡W©¢H^ˆµ¼8·Ji?¼~ó 5²#$˜2·- 9HSŒyR¦fÆpÊ’TzmF‹ÛsÀÑ•uië¶á[cA½‚RGêS·_ª7$t9r~T¸×}V«][[cXk,™ÐcÄ o5o9ë|ýï²}>êÒPù¿©«$’BI'ÎŽþƒb^ 2¶Vêóâ+LÔ¤Û4­o{æú•7çÎ{"<ÀÔ*Œ ™Â#R¡ä]J\Š0õm:>êÈ¥ m¶àhE¬dJF(#$D:²Ñú½ú0†”#$²”Œ¨Â+£¤88MN@¦Y¹©{NÞ‘ÊïàçfC%Ïw7û¶Vnˆ†FŠ
 ðÏV­Vñ]ʏ-SGcA²FMÙ*è¥cˆÁeîáy§Mè­|Ò¾\ómÝJô7-ÚleaLöLi¡´™¦šj$3$ XKŒ¬cZÈÁÀcmA€XUˆ>@Ž®AÉКl ÷Ž‰±6x$¦™Í–—ô(Dø¤¤EJeuÖ¢ÐÍîˆa~b­ðo-Ñ×am­Û+9$#$Y P)$0À÷ dfj’D9‘ƱŠ!„ô@Q€î1¹•R[QQiK#%²gÜ„S*µón™¤läØU'lZI\€´ ìƒÁ×$Gà0˜Ò‡<‹XxMä¬Úö@ç[)>§ÓuSè*îäÕÉ¢ˆÐ `dŒÖ&E6.‚ÎÕ¨‘#$@a`IÏâ:€;‚±ú4Gòšm-Í¥½Ä@)5;¡#%Ä À ì6ƒß‰,Üý‡Ý}7†‡h¨¢!'š(8Nu±CyŸ3_‡ÃYd¬‰s ¯•_Å<O§ê¢×ÀÏ/ëÆ#%³œ|e™nÁ³»¡¦—Äù°z¤Tk°(GðÄ@. ]>Ò#[@Áë°ó»`ÑÙòú0µÇGê5¸ÝüÁHëÓªHª(¡:Ð*HêQ6²Œ¾³ÝòÆ©6ÆQ_TÞ;}ÅhÛŽz5$dfé®QÖåNÅ,?‡›Ì`o§ÚÛ跏ͬäIj“Èð3‚ÐáK½ÉõAáŠÔ Òý­#ÃúŒ•hj5,Z¬RH»¼5K§¦®=q¯NhMXb`bNÈ!ÇŸé´Ò).m{.oIÚ½M´k^šñi5‹O]¹b_ÐíÍkݶï]Qµr³»c{¶¬óÛͽf,cO.Ï\díçK•ÛÆñÌyž=–¹c4óºmÒ×-»"«›œ£r¨CHk®Ý5×=õy³<n{5|)콨ŒÎ»Wm„œÝE¬ãú÷½Ç¶nÁ Æ‰d`ä’#%µYüÁΰÇH‚1ý½¢,±VbÅ‹.ÉË•SÛ?3cÓ€‡™@Éùœñöﴗήibì.’£B“›QE`ƒ,Kýp\0OÉ/‡Ëéz¡ËPw™øB+Pzn²$mS+	²–‘U{[ÉúÒ¤fóKγ®•4lÍsµÚÍ©·;EU3^5nj®›´°"\1H”‚™h‚¡jõúnh¦UO˜pÕ‡^™ÛN¹Èx½ð'}¼,<Eë)=½µ‘#%¤(€üwxב­Ë›s­®òwNº‡DÊ8ÌK•„M÷óõOaå5žLÕ!ðEð†Ò2SÛ
 ‘W†4Šj	L`’UÙ·É«zj¼Ùj¹k3\&–¶M¿Œë5WÔk)AˆÖž{Ö´Êa /Ô˜¦HXÂ2(\HCx`ÉQH8»)ÎjIû¢¡tÈ°‰;3]P‘:F©§åéN”!¢m<l$;A]=J¤C#$ËHy‘R*y_¾ËFDË^ôM4¡^Њ¡0ô¦ï6x÷³ðëÌi±öú×_ ;RÙM¤e²Ò–ÔÔ’“6’K`¬Db0d^³™¿CŒìÇgÖ‰qÀJ¼‡§¥nîýÌDuŠÂ2,_é$¾nù‡²@h$¾ö˜-õ[Ö]Æ‚	ÝLi·™¥bJËʳš|îÐuðê=Ü1ÕxOïÍêÑLŸ$!"Ü"M„'a$--}oK#$Ë«}¯?ŸMw¬VÁ÷:«êkæY/g[Ú¹c\ìuòÖâR¡ˆT+2c`e2j—€ê”S±&º1P©2àù,P´$$Ðð³óãlV)KrðhtõïT1Ã~³V=Ýʽñ#%3âÕš–åi›Î?ì³÷ðY–ºg7-†7¯š¸Ã'ˆúß8	ÞaÛ'Êøþ×W½õ×܈“TÒ[0L¤µÍ#%¾ßJî²2ˆfÄŒi2Âk#%‘©•cI‚0Š¨\ý;dDŸw#öÄLÅ{Ðû¢	ö}âÖd—K {ы쨇¾?Y¬£J“ŸUFtö5d}¶‡•6–Øà‡l2ŠÕ=@â¨p\ď‰S_†ÉVMV/ÏksPê›PD„ü&$,+Õ¦ù8P¦¤"Äbš¤QC2FK#%ŸÃH6“0¢);ÃåCª"œßiéÈCŽ	Áµ“µ£Ö(}¡; ÐÛG–"rt5ã7fD“Xž.˜gbE,m˜`¥êîÚp†éïŠo"• ¹a¥Ÿ À,	‡ËyïÎå"P	d*/"ÑìK­%%uÑJ=ŒÅ¬—Ý}YÀe1J§E]=b¬bÎ`øàåŒ<­FÖÙ d!%3ÊÙŽXÌ õ*ÆýÑÊOà±’æ^ïæÀd `le¡äfQ`	‚S!/™Bš÷â–AÏ|TÓlIcµ¶§n"\üw¥èœ8›_+#%Ù–˜ç‹‹lµ\Z4¤V¶~=TiXlß–¤ŠÝ@( ”‰Á°PÙh@¡ M­)Ðæ¥A;®¾„¸*èSÄ:ÏÊN€F%I'>ô§æN v©‰ÐÄ4j¡ÒøÕV@ÚBõ#%W‚=âBØ	 Â4–·jï7Ýù#
 |‡wyמk«Òá(¤HKÖxËN¶ÁÆBåFǵFµ¢’á³F́	wm_,ãOá©z7ìveå8HQÁðíAg7âá÷OCKO~©jqÆÐÆÏ©®©­RJä‹ë˜SãÀ¹TÆä¡úfÇþvUÙäÀ6#%¦“iv®N­FcÞÉ›ÁºnæÉ„±è“t†1ýîi815œgAï^j7g•ÃiéÏ–9ÕR"ý V\ÁtÅ¢£kéùɉ6“àmrÉeNª#%[*ƒ…TE‚Åš8apê`l›DË]%Ýà-?—ôG·ËF€wœ“¥):š¡i ‚F(J(™d»ç/Ý#$P­›½½@(ÕÍÖ!¸öŠ±ÍÓ]?¶}ZÎÑ<üpÖê¢Óh>˜± )7º5É1>˜íȾÃÁ䮨õÓÁ‚De¢Qx·I©´s]f²©,jŠÅ±¶ËCk¹Ü±S»¶!”DŒh!@NtÀl“ 2Ba*Êšü”¨Œ”$6`XÃ	"¸#% °¤Qü1e¶g&$XØw¦)\¬#$¶ĈÉ#j	Ñ8Ý<E½w—•ÝÝÝs\õ(RD4Û*¢a6 AÖ¶àèÀÉâ¹®{ÎhJçžs»î®Ï;TÚ™ƒÃìPº405†LX¬Q"¦#"‚ÈP]LÐ?‚nþÁJMùŒ‘APw¤©T*õž~?v„æi>‘õ”ÖÍ?6к›«ûødÀqIÚ#%)(µ“këý]ZvíÞ]”osÆ¢2C^p}'QÈQ{AžÛ¸¿qâ¿òȺ-±…䣀5®\܉䌉±³gb-Ú¢‹RÒMÍ#%#$R?S¾Y1Ü}Ü!ÂHĈà=Öï– ùÏÕ«Ÿ)±#$:¸„´âë#$kF¥© ö¼Žã6YÙn"ÍðÄ"†HjÏõs)~îeÜwqóI㬘DgÉX¼ç°õH}=`’@7Ûw•¨-zbã°>ê)–«E&¦­g8Ï°3K×ôІà¨1Jå¯60âHt(h³]WÌø‘cÿËÖX¨Rûþ}WrÕò{­²h˜‹Àži8‚Zi¹™Ù;«–tÛ×W*\Õ$T`(¬ŸÏá¡SÄ’Ì~˹øˆ7ÛŒÂZq|…ÍŒ³ {™1§·Ät/ÖåêðLPÊØš¢w‘´Dø$¸õn#%ܸˆË3Z·´¯P	I.±?·‘°ÞØ[­­5†Äã‡N.Gm$*@Õz_¥éìž%cŒ€w{’œ& tŽBw#®$v+¶»ëÒM³yB}.›çœ¸‡ )’},
 d=&KÕˆ¡’ö9äwPB#%H#*ai`Ѐd€#%¶óM©-RójTÒ¼­{Ù"*’z·vϏ ‘¨„#%à”‡v‰óÇq÷&šlâ^øåÚEv&õʧ™Pà .‡RC“l2<Ù_¹çÌ®ʍÃkŠ!Ý9JȈJŠB¿ä4Þü-~J#˜%ËËOr˜mê" ˜zO:ÞŽÁ/î-¡}.´–#%H#%F, ÀŠî5ó¢ªESc6C¶µÛÑiT|(qB?>Eûgùÿáúkù2㜠@Ò;¡Ù¾+ x.é¶gžqcy2[sêwD7Yµ ‰bí†=ƒâ|;8“»Ç×Ûaf´ÚÄÅ—É6ò=Xß*¥äwfL·C3R›cª·¢2Æ’è`š#$Ê#%‘ó‡>dŒ"lÝÏuNY3pöØwã»@4>€î\‡\ÀP"«Ì¨ÝC3UÄÚ¹(#$Õ`ŸÂü´ÍìÍ&­øïmŒýÙ¹¬šÌD/äþÇ’ï£Ìì	AíEºí€ú(sƒî3 !$;¡¶¹mJ*V*R¶Ñ¶¬Tk)l¤©«RhÛi5­kòÏÌl÷ø°RXÝàk)ï3Ôv]Ø ñî[Îʤ°«š¡…º&J}QY‘J­Šì7jm%j´™`}]™šŽ.ãï}õâ¢7¿#$„ݸ”»uZòªÜ… L³´ˆØ™áÆ÷¸ÃmG]ç¨;žà4ÙyZNÜE}œºé·?=® #$i­Ëi‘"­¤:0ˆ¨¢A¢ [“ˆ¢R2¾)¬÷†X#$•ïrب‘‡f·ùùŽCDC’AU)Uó­ï;è)¾%÷nüŸ#‹XŽÎt£—´äå³h@¯¨ÀôÔî`e®ÜΘ•±ê÷ÌCgÎÖÙ#%eV–è’ÖlzŠHcÃM˯öN— àaþåU l´˜Èã"ü]¼ØáœR³Zjҏol£Zpno"ʼnÆA¤Ó„km¼’¡ qB´afT86A°´Ti#$°u¸¨ò°:…ƒWSQ:]—غ¶¯TÏ:å¬Ón¹uÓ% -srñ‚±CT–Ôª#%néÖ»FCFË6ÆRÒƒhF°°³Rk®êdš®›°ÆFWö½uzoS%ìÁI…d°£/$ˆ`ÊÛ‚hfnîD1ZmÎk Ã1…"A¼Â*æòõzy²­FظfÆêµ?}èšO…C7Œ†ãÈVÛº•ê[\ÓM(T©XV›Yu ÛI˜#$J
 ;cCbÈDf¤¡ Á¶b 0fëÑŠ¨BÙuí¼é¼\!èôÑÞǝ½%m¬ZQk&8ÖkHÖ5lË‹áª„ –|CÚV<Z OUy#%7eFrªÅÆ«ê©Ñ¡æ^”§ÌÀ7\«X–4K#%•\ío0ÄdûÄ…ºþ½(„ÒIyŸÜG­»ÃQ¹'ÈyÉŒ#A‹F‡4 Ñ'^(ðI³l+Q’¡)#%Œ+%®pú3Fµ¶Œ.ÆiØAÞN0úYÇ'#e$Õ[Ó$˜‚4Ç `E0ŠµC¨¬$™¡U¤Ž€ê&šT#%¨c(E@‡á#$	4Ë4(BŸƒ§ôP[/Â~¶Ü•=êu{J²xU‡}朧²¬C"¦¿c¡UúxP[$^ʦ† 4S½¢àëÁ†?Gõ¿+1[]7¨FYÉ©ø3Wk›»ĈjªP‚ ª%úP¢è5ŠmP&EHºÕz4ó7U:ú^d¡¤Wç˜9‘p&z9h{#¨íÚ’>jëjÂ5z|Yü‘ÎήŸRÝÌ·@[9»òG¾›ÉÑ´daÄßÐc¿¹î|òe.÷¦®ˆèŠ/éé±5¤þZ‰Eb¼îðý‹øyϐXFgÙ809280£ÖCŠ—r*Õ¼ëHYÔÛße9J#$'èÒ‡¿‡¶O°I‘1c‡¥PŃu±pú‹´K*ÕÂ+(µ¤“W-Ó5uÛk%®Ø‹#$¼¯l5%[¥k•{«x¯tÎZ„ˆýsXôÊÆ	ž	Önž­-i¨¸bï±»sÍJkE©©F“i-kA4¥½dº·¨†Â)u€Sq¥`ÆPöÆÀÅBã6%›hª¢¥HÉe‰d­…H­–d²ZÒHFÖ-–IF͍´mQdŠm©©~m}=¸K&·™,Và´ãFFD‘V"±	Ž¤ê5í¾«0c«Ý>Á	—³,nØ8#«Z „„Uâ@'¼¶¯Èm®Të«š­»Zd‰@Úju_„ÆŠqWÛ¥H YDu4'²RaHl3öêóï-ÓrÚŽ=ND9 átB¡¤6AëÔ=oµâ-ÎÀÍg/-Tüko‰Àtð²:âät¡0~«œîmf»ÚÞ¿È*Ì„zæ"&8m¢­rf5¦3¯ÛÎ#%ÄÁPÏGe¬ä»©Çà(¡}±öðá)÷v•!5çœ!Î]ȹonžË¦oÓ¡ã Ï#$wq¡G²õ³‡·§…™›cwÝPƒºÊÛdœ­Ø@nÜ
 òàÄ°þüðÑjè÷Ý®iï¾C©³MúªUUP¬q;#%ù]Kç«ÄÅð 	ë€2B bA‘āx*íµ-¢0"’XH|²üƒèa>óåGÍ URDRÇ­(a颠z!fí #%Ê°Š$¤3#$jHh1  „, at 40T½Õ·+Ì«ÓuzíÒ+®»6^FÛ¼óv×–îÔ%۴ζ\®¨d$Ç”XòZ,ŽFàã­Y’%‰iŠ"-Í°#!e¢X#%	’«D‚X#$0qdF%˜¥%4@_½ê"aÞ÷‡ ð}zFH²*#%Öø­(þé!#Æ#%c_¤ôxr#$O£Ý…¾±„½™6œ>¯ô“ø``ÿÃL»üúþóà|¯yQ¬0¦ÄpŸh£`îE<7îÝ_tF1Q}ö£À…KµcfŸæª÷ƒXäÒ+DG­@ùãéõLà/Q#úoôô2>“Þ@»+Þ`/Kë‘Á¥?rÌ¨Or²	H[›Ôš}Ú?qL2I„‚R¦›ü=¯3Ey<îmì×1 7*Në¬\·nº‹u©«bÚ‹¥RšbQ„$H@Ÿ‰¥¸%•u‰ˆÝUþ¦ w†ÔÞ;9÷Ø6ãÍ’ H È?ª P€R«òˆ#¯É0Tè>¡*¢‘ƒH½qd VÞ<#%û<<|ØãöaŸ¬RüC‰·Š`1$‚„=ÂQ+Š ʄ†-Bô¾Qmb6¶f+W_‚忶X¬WÓMÒ”Ò[מ^i,XL›J7ÔÕ}öMkšÞï[5"ûÝRªa œ[bÕ·S@°“ d”¢B0 "jÈ£3óê}ƒ®,bM¿ys(Fð/ ŠTGyø̝¸¨rI	€ÅÜAç¶gñ]¥uC Q3@¥„ÄH1tí:²À£ð ‰Fˆ­—ñcß•†|ýxZ¾¬¿AvHùã̏œƒJ0Œ†C8⃋G˜hïò怏m+ï¾¾ˆ?LZ* 0û†#À°â'Ò*Z¢¿ATK N?S|.w‡¬€|†uÃØCÇPþòOár˜Öƒ6Pe¨È,ÑÛ«hñÓj+wwØkÆÒòiŠgW m°lfìQ¬çEZÇ(#$ŽÈÐ؇¨¡Z[Ý0ß÷3=Îj5°Ú›@8ˆn)Zý²]l)@Š°Ä!– @â’¤À0Ñj±Q¯Ôé’”Ù³¸C0À,˜”¯6
 ·_c5Þ2S@Ò²B¡^ø¶{¥Ø…-9b²ß?ÔÅ€&l„ŒM[¸ŠÃÌ ‡\ÂH|úø’ ¡~T_ÛñíŸTž…–?«XÝP†Û3ÁZ‘’’¬¢sOØÌ"í¸‡¹ÝÉžCªí‚‘.n”mêòÞ.[¥â»/ƒ¼íÔЕiø]0P¶»r8R[“CRR3\šØÊ-<qÙßy&ÃJž+öD#%D)„´O4|@Ö`¿M½íE$ETE6%#%nq#$¸6|||ž#ùt×ã»mí[>FÔë=ƒ÷u¾¤úB2ƒØŠw]š(fG·ùàƒÙç“•È%sdYzác®Õ`XK}ƒzoR¼’Žª$0˜²€*«#%bäƒÀæ*hü“ãà©!\HÓC}0Í¢=›:q™q!‘Ç÷q1Â4‘ĉC{!:Á~YiǃÄÞCÀS°}`®<“é™#$×ä+æÑFb2R­{ß Ózm,YU<ð›Tºž®A5¹“ÖYÎØ©³JæÑ‚&LC¢ßÉXE•“ýÄW5Çê~Ñ›ŽBŒ¼z¿{»xuxM`haÛÄL-è9–²¡Mæ¾ÝXý;™˜ÝШ¦¿„«8iId<ÌóâBñ¨J-U1¸ºh9ž;GÛ¿Á«£ô×ÐíkOæÖÐÆ—^˜Nêæí[èFµ=”®£]Ø]}åfO„îL‚£‚\ðTh 12˜.†°¶íß 9eéñÿ#%”‡MfﻩÌïî8"õlNHã•2>ƒ–¾ìwµ	”c2ÝV›Èãg“iüHN†ÍÌç/'?Fú“ª)g²…L^¨E	ÇgK{d¹ÔÖà!	>!«–ˆ¨ÁaL˜ñû8q{”éE1äS&që|´*<>úùö-?®ä‚Ž&ˆRƒHvÐ’‰ºÜ=ÞßšFŒ®W”sɲžÓ1·S'“U3	ˆó¢vÍ6K‹H,"„AZÛKXTqèÖ¶êë:¼Ñ¦Ï%3	ƒM”i#$)}ð6ãÅ£‰Gq^ßcÑ®«»QVê–b÷ ¸]”Æ/3‹¨žÿPÂxIˆÄô¢ —w Á`HÀ=°U("N u u/¬"€œ È„V³*Àh^¶ì‘ƒ?Xþî/†®'cwÏèÂÆQÖ;ó17ðP¸?« îCÏ«Ûà„H)20ˆ]ò%¬%}Þˇy¹Ì!º»`I‡åÔ}™€‡¤ÍE|Ä1óiÈÒoì¿LÕEŽò€7Æ)ðu"B=Í.èˆîpŽýÏw#ÃvE$Ô€þûb
 =5nCî5ÐL«çÕø+­lˆˆDºr/¨§L“$$#%]þí¦}ˆ.:;m{ šJå<щºá»h,†Ê? –¹)ŃNÞ+Laé©Ÿâ, áϵ¯!±®Àß{e}áPœx&2éÒ2(Md#%½B&!h÷'Ùò+y&ª…ÆŒýï -5;>¨#*'EN3°|#$!¡±Ù|Én¦¯L&û·‡n'§\ø2ùUˆ¢™$m´†6 >Gšq™°ßÂÔáQ¼+?|ˆ¸!Ú˜&™Pq01mDƒ´ÔÍf¡TÓ%2”jÍšË2›3k6fÕï_o_½ˆ¯ªÓA4”(†ò—IÓ!²(†1IJ“HHŸ"Îÿ \‰…ª	ØÂ$„N'¡ûÞA=#ËÓܘEôÂ`ƒÌÖ=ô؝ýNtLÃéýGÝž–ÒÛGùZ;	!™†{ƒÆY6»ô3ÆÔc¥ãÝÚž³¼V¯Â:ÒNº PÇ#%»Ɉñ‰Ñ=n#%ÌÈL(Ð÷$¯Š.#·C”Š2FPþŒš³-&Mñ[†¶ö[–‡«±Ð_vÕ“2éPU.ÈKaLšh”¼ØÒX”*#”¨1”*«²ðÙ…˜ó]¿v˜›q1ݳ¼2^ÞQ]ÄrÊ6­N7Éx!t4n¢s≠û™¾N¹¯}S{1tÛ®Û•×wcÓsQŠ4†Ë]LIèi┃0ÔŽ¨IYT,FØÒi¦AŠ]AhLÆÓÁÄæ@aIdl–¶Îó®žU\žg]w‚òÕå14e¸Ô°‹MŦ`Ï“Z`×szÎC†qvÐkÛßï–éèÖŒyÄ\kyMêîkRþ9M™#$>¯Ï7ZëÖSˆÜ\õ§#$ÔåÈK$î¬ó"rÊïCoöM¨Ñ™/”ÆtåLÐb Í"³$L3–ŒÒÖ@›¶Ó5 kµ¸É½ÝèÅP‘Z‹]µDZN9®†=w†¸9㔀Ò9xŲH#ozÝ‹¥ÅÒ†™(±’¶«°YÅÑ–µ@䢄¦ÌÄe³›ñ‹ŒËš'Ðh¸PP—n¦Èòbt™‡–á†nFÖÉÖQî]MèšíÆ<0`¸%ý—Nφ‰¸1¬éHB1ª[‡2°Õ¯™GqÆ6\ äœ$Œ‰‹³ZhØÈ…,„ZR0ÔSˆ†	3)PÛBØTÒ#%$ËÀÐ@ÆÚc4‡ä/µ~ó4#%Û’Â…em·$¨m&HÆ¥ƒ¶¶ÊºÒgw$¸ÒÕ¾Z¯á›T
 “‚fŒ¥|ݧgÄ$_KkÖ®ô#±×òÆÝ Ža·Rduà£àÞ•ÊðdVAi ƒ×Eà1ìàÔµ%Ù«¯wžW7u¹TͦšÍlš®Ý÷;ÝvÝvh%z×ÍæºÉL@>Ûâs' fßv©J#%ŠÕu©@’³÷foɵîv¯ƒ»ˆª§é냲LÂ`›‚(kˤ7\Ž7EU67HM¦¢ÝçœÂúܪ.Á¯D…!Ú©ËûxþaÀ“#$ÔÙ¬èäç#%!Ò¦m.ì#$XÚQâ¾®§°³]…«#%£¹26l® ›¨¾à9Ú†zÂwµ9d¹Ñ!(>߶;ç¸ýîàǵß}›{}žÌÉ°Ó_WnÛ%¨Ò4¨”dÉ¥1J–Å~L¸I1Ò[f§ybdcQØõˆh…¦5ËAO:–Î=Z§‹ÊŒ.ò™AҲȐu*܁¡ÊŠ“(>F†4pèí0)«L_¡E!c#%cœÉúâÓCJV.~¸¯žN„^(áføöºÙ•çq[¥®m\·M}ÛÎeo1©1b±½M\1É;ñõ»3&Y#$ž8¹ÎE	U)diÐmF*n‡ è“©!€ê\39(à„	†êì:¡#%CÀ,'õeBB wŒD ¸	Þ²¸·(hß¿d݇ϊ#$¬E5ªAO!P~U‰%Ë™…Û‹[ꪂHÅ	U(r  â­“b‚á@ª#%ÒH‘Y5ÚÒÀë–D£#%m(Lì‘ÝG֐ÐAËÞ(•Žâ(âí<Ôí! ‰$#‹¦Å@OFó‹ý1@S`ùõú>­³¶ýµ±j:u¢‘D‘ˆ2$ˆm˜¢Ñ£S66c+S)¶‹bµ%­"°;ühstHÝB§–1pÄL%*ÄiF<j˜Àm"#$µ*P1•ÀÇQ9oNK½yWªZõi³S Ä`‚@.Θ ¸@Áq {D[dªŠuѝ±#µ¼Ñ,Ùö–#%,›ù”"ÈÀz€ßÈñëäcÒ«	?Cá©›)Dj8„ª‚žÿ^¹Èo®ß§GÅJUâÄã\l¥›Q)	M+g«±þÌPæèEÍÔ,\Õ2]e—‹9Kq‹Ú>¯ûo&1PÎâáZ"ëë(¶-:ÙÂrhF—Û\òcJ?ÏfR:ß»ïÌ¡Áuíu­ï±)/ICÈQ#$ueÐ(N¼Tnºl4Ø	‘Ñjãl««åjOš•©Þ`°®Êo0O.ÂUgz9 ì„œS¯HkÏž
 Ò#$à—tó].݈Å£yš…vç<à¹iڌԵ®ÜÈÌÞHU`ãL@3S1è²>N~[µþ’8*æNK‹F¯lÚHõïÎÌô÷vÑ®4ˆÄ‚^^›X|ùeÜ/ÅÛ]…,ÙfïÃR´œY!´ÔÑWS¡B“¼ª¹ƒ”ýœt¯Ÿn'‰¦£¼/e¥÷Å¢|vÞuË4wáH Õ”]ò’µx”ˆ¥.•gB.V÷‚ÔCtÌS“Gî“z [‚Q”y$‚\%í‹éáÉ,;íH¤^ï`ƒNPì‚“þÐw.Ï®¬×\èÁˆw-2õÌÝW•ï5Å·‘³©u¸¥2öÇ_#%í‘ØÉf“=Íe=ÇÁêHów…ŸZ;ClöÅ]½Øß¾í…ö+¨#$p±x*'Ãh’]ÎBy©%y5&lâ¹³Ù]Ó——l¶òÅè|­)už	Ž¶1qg:¡ÕpD—§Hãnoµð¯N¼S’ág槭ñÁ;v¦H×Ï#f˜†Ûô!<æHê8™‰¹…>¹gæXæ㉖êSlËc²Ñ;jˆ”‘|¶‰Ã¦• Ýüâêl’kàI‹¯nò6Ť)7” îP<^9š¨VÜõÖ¶§‹›PâLèuÚºÃKxè\g3’sGq»má&J9#$”k2ͬ	QL4˜ybŒˆyÍYÚX÷áî’ë°Äõß•r[‡…Ž†Ì6Ñ03èö>òͨq$)hNE‹¥Û Ók"È(`Û Qa×Âbf“£[²`#$Xƒñ-ƒí… N&F½xóÅ“½¬ÄM„*ü߬‚#%9º{±	¶ýöt5oâV–j7A I–ʼnr®¹¾æi°®¶˜‘Ú.«'‹ÍªzæÕnH‰ZYÚÍÉ(7‚—`ãÈ‹£jß8:½á±µ"ÖmæÝ‹û:Dtܳ¹•®b1ÌEŽŽèº|3>ÜDa8-Ÿk˾0‘DôrGAKG3åÖÖ6IŒ>¢¦&%õNi#§[:ñÍÓœ©¸o&@ÂñóÚøit%x=Hz{îî­^òq\g„œ•Ì®ž1×vÃs<ò>Ê͇0¾ܶ ¤;…s{ïK­,Œ¶ãž™ÁöÖWKÀIœØXÚ	Ôm""”›I™µæV–÷O²t¦S1IšÎUKǾԥ$x{-}U¶DÁ£Ì…ÔMj±chÆ,(gg;LZr‹êr…SF¹y3p)Ä;‡¿f#$÷r´Es¬ÄÁÂe#%‡ýq¬bÈ€
 ÜŒbõ	™–„'­*ˆJ,÷=³‘K´Ë 0Íw4¾…E!šLB…G$P}#$©#bä&Ñp=ÏLÛD°D-ñ½º³ï¯7py	ûU‚ìؽq$Œ©iP#$ï#%’ºÚ¶ŠÉ“RÄ2$TU`‰&AFÁ¶“Œ‰DV˜ÐX¬lmÑYtµízªíKÈ–uˬ۰ŒçßĆšîkaŒÌÊ„,¡ŽáH³gò8ÏÍšFÎ8+°Í¬J¥>É8ÂÉQ3™€Æ6×ëxŸ†‰#$¸=8éÒÓÏdåó©®y¼bf†XÜã"köȳU6› ãn¤Èš+CPâõ¢·¡IG:s(=BB É‚”yiŠÕlåííf¶”‹•½ªMêäs™ÄÊt#H¡ÂdpmŠÅ‡IðmM8ï “a¤«ÆбKM“&%9²@‡1ZnÒœÍf×ôÂ-mÆ#$!‡2R«ÑÁ#$â9Rk#$d‰-*t)ûñs#$|ŽäZ叼+‰h)zµœCC6³t!‘#$¸9[Ô3¬PÈôšmbÂV97ýù7ªrl.ƒž„TØpöºehàQ˜3•o¤Á痍¼Ã¡p9ÕW’AŽâÆ6ÇGB˜0¦À\ZÅ©œ<Z‰ÃP”Ìœ*Œ²Ìì&µE¥‚h⹇#$›À’˺” WºLÓÑ”Â3	å#èë0]¨gÝ4Žœo£Ç#$.1=¾p5ÀâjãµFšµZÖßWÕ­#& Â(¬U,*"cǝômœéDÞÎ{,2£!FNr•ÒisÁ¾7µ´µ±¢anJ¯.og7ß5Z”¨Š5êŸ_bkˆžuí÷#$¡ŽHoô|­\¤ºì¸{>òÈ(=°Ó³Sr+MGd(`ÈB´„	ÎœŒq¦!ÊÍyk<ì8¯Î(<Œÿz€ìX)ÃC0uó92Š·™{ŸªD4#r% Päû¼7wi–³(õ;#%d® Þm8iQª4´ÁŽ¶¡$’'ôýø¯¿~­ˆgÓ‚‡@î’À± `ˆQM Tõ;gˆ‚|`ŒY1¦a(M¬£fÒa’YlZl”‚[¤ŠfHµ“Q¢K![Vú/Ÿèójß*¶q!o§NîËu9í·_X—¹×Û/2#ÀÄI%QUzç²îZÐCÎÑÍæjPtH…ÈúŽé%áÀnqÏU£Fœq&NhŒÔDÍ!}&géj+–JR~lãMÝ&RÔ& <Þ~Ò¶¯³5¥5’Ô´
 Y¤š"±€„_ ÈòÛƒê<¶UîTsÒ÷:ƈôï±€BáUhôPª;ŒkBh"RÃd¨#%„E„n²’a1áña†™¡µ´5Ì(ŠˆuM“,3Wy ”@¡ú@!0]qØLþ߈•hÉm‘«(…Ú¥=4i‰='½ÃEµ‘O¯³œîTCÙˆââѶ^¬Lð¼ªZMDŲ‡¸Àô#%lZ‚Î4·Ô[êÖ¬‘Pñb¡>[ pÁ2b#>>ÿF½NŒ#“iOdâCú#$#$™½’‡Å~4–8?ç$=¡“É’^ªÙY™&=Ý ü}‡¯lg`}B4E”ž®Ø-Öp¯ƒ	(ø.fN,M‰®iJ3(; ÄÒœ-pàŠ‘O ©)i&ÙxÖÄSr„]¨T¢šDÍñk"ñN!n¦#%«2-{Þ²ßª~î)Ü:öï7´vCYxp	i áõê4µØm…»yò_&¾ß ¬™¬ÒQšÔn)š†gÁäÊϵîÁísÏ<tàf™ÐÕb)$Qó=ëÈ;ÃO4N|f»ð•»oÌž”­ž‚!ê‹+/-5ëñ³´ÓPSdo¼‘³@ïŒj:XN&8Ñ…4̇a³2Øk6Iˆï®RÜ=ˆéË´FA—í$Ò š°: þç©—XU˜‹GÏL0ž™!“ˬ†Y*ª*—’µw¼=	轫öÃíj°?¦åýÖë,Nk>•tÍyü¯Ý®)ì_»C2âmR¯OÅ“.2gK¬T=o»Xòü€sD‹¨ÀÕPV"UQB6Ài“IÂ6׆’ˆd,5MM	—7R¦¦GÍÞÍé·¡dXY rðËÆà%ŒÚb8T‡Jø^æÎZêÚás(XÒêR]‰¥ï!»òR¤l ·rÄ#$α9£ËOŒ¿c¸…Ýå‘6à®q̉#$(¢^šŽ11ɧÓZ}7·y™T"çdõñï)4Í=jYÎF–yoàí­vþ2¤´¯›º‹Úݤy,²=Ñ»Ûh‰Û}ø®&[0ÃX7×0Çãª	ªi£0šqæŽÌz[“5n£ö›xî-GM뇾8’·ÜwVÖ1‹p@†-‘„Aá€×<V¼àº%Œ{¥Ø4÷º`·:´Wƒ¶(}Y°Á¦õ¶#%­q­#$ŽZë‘A´dœ>³#’M>žÉÊ´È©5YàcEq#$‹dâõ³®¶¯j£Mc]1$…*sɐoØÚ(³âœ’P˜ ÀäÓ9m:ñœô'Ç™“‡Î
 [™ç'|ª°˜å#‹¼M—´Q©gÖó–pûjÞ=Ý0X=A·ÑÚ)»‡ŸÃÈ…ÞpBªå툁©äÏ^¦‘_kS#$ÊèüŽùÍ+L8m³‘Ó-ݱÕÀæÍò:S}æÍ5²}ï[+]¶L@ŒX4ð¾ÎH¡7]<‰ˆk¦Ñ{­Œ}dZi´fç£ìMj,×iû.h¨<“Ý`«›¿èıvk6aðÒÌòT7TZ¦'’"S!7Ž¼Å¯‡"?ñ|Y1†I^„ÏÆðr—3ï‚bv êoÅófÛºª´=Û=°Ë8Ó‹Eqˆ³„M<©+Ú*š‡ê¬´w¬F¨æYåžZqŒÐ¶Ó:.Ã]3âÓvN;»¦¡GN	kÄô‹¹,×i'Õ¨¡‘ãh+Ec±´9yé…F9‹•jѬËz翍c×`›cxÔè(lkÔ«UD8¦ã‚+aƒ†<)¾\ì]¶ð62¯ks#$îëp_w¡¶ÇÃÃéT^±‚`ES1Èš	)ßÀ«ãHÑ†.‘‚ÈZ^†¶ú>­eVs™‚ûh#%8¦“ŒŒD:§<vŠÅjm*2Q€Hh2(&4™‹\—Ћö…Qt6[#%èN˜®3TƒÑlÒf	"@ØâhdÁƒa Ü°PELR!träq¸KThr!˜´’ÒÃza§íè=šáÀ`ÈmJͤ´È„»°	‘ôû{4øj{f>V#)Mjí=t\x·—Œ÷t(æÔ"¨ÈfHæÀ“}×G›^¿YìÁð¹ªcJ+™ñW2»êòæb}fakÑðÝFðr‡ÛáK~S+B„7É*¨2£^!FýÆRŒÂ2s¢iiKë“2iòî–¯¶8Íhï÷Mø˜˜˜¶.’]ó?ÒlthÆ–ðìê7Üçñòß<¨ 0 ίD?eÝ«’|òNx&¹=ùM#$%u²ºí_‹Y9·ÙèóÐòîó®˜Înˆ{¹ãCíjÚûÕ­-½ëå\Ç&E´¬1æKôWð‰ PÓu-MP­)7ÀAóø†±õÒKUMD6VÞkyI!’™©l¡: £BmŒ$iý…+¨±•Y&B0`,pl]K‰Iv…²Å¤—Áp¹bØ?ÛXLk'E«weYx±Á­IÇ¨W=aãbBÄaíIyž;~„åÚ‡)b,¤n=¡³=†½·[ÔõE§hÁšêz÷·Äœö¦¢;äœ÷ŠÀ9Ô’‡@S
 iݾ‰\ÇÖç­ovß,´˜ÛMS6e$ d$¨Š£UB¸˜”ˆ… — Hˆâ‘à»ÌèJõR&Ö-oÒÏ]Ì.^ë¾C¸wöx׏Ù		#$#$m*™î-ԁö	 ˆŸ¬£p{@µÂÃrPøö\»ÛÙ÷¦xk˜S‘B$ÊJ.¡M@` •`½¨ª¥ e‚	 öŠÖÆ1›å–A#=áR5×ËËÔôžœÓê94–Æת|B݁ۈ$>hQ™1Ø!RDÚX…V{‘Û>#$w°#Ø^¢ìLõ~U•ôÌ(^¡†æ~XàÄ]† $-FÚ³]cA}‚âgJÜ>Ž%1çÑõ·$!ƒSÀ¶ÍA¢¿-7^¢ÙÛqU:œ}Ö ì§Á6øE&æ‡zŠÇÕ"FÚL¤ÛJ‰¤ÐYm¢š)MM˜£mùˆÚ+u6·†ÔìO~ï¤"Ô¼wÀòàVKÈ=¾¿Kpìœ5ËRl@¢‡Ù¹sò˜ŠÄv‘HE"AÌHà9ÇpjFEJzJuƒÚ--$^ú¬Ÿ|ìò|h¤ô¦—ê"‚~s-|0¦òÚôUˆØlj#$¦:¾›ôoFžâ+9pÔ#Ag<L%•¥¶iéÞuB´£|r]çˆE’…nXOQN®ˆø@Œ{lBÅÒôX·•îb™GŒmÒ`BYRÆ— öuKºÃÑû¥ˆQ~´·‚a‚b¡¬Ýب† °\šX:Ã×$]ÆéSJ+žÈw›Z–ç´Äéê!Ã[‚•ÅQDdÆk7`’2­f”q/§Q%ïÚݍ¥”\µ\hPÖ¤#$0Ëämöž5ói‚”mkobÔ'TÁ¯Ys:8y:}HûzÀ]Iü[ˆ˜ˆTd	*5'u;Š|/7d®rv–õæׯH‘I¤Í/Wv7™S4šF at R–2îÔ=êäÌ ‰~VöøUüшÛ5!ªEfÍ¥ßÖ	µ1Ií䧐kbB@Š‹  Å >ÜZ at c2?Ù;p[7­•¾?OK°2Y²™H°ˆHH"»â‰aÑ}gLýLȧú|:òðñž_¢ýÊwgaôƒ­#$mDõ*A¯U–Ĭ‰Ø'ú†3°¶²ñæ+äƒKÝöÒx@– ê¢@”wÙñ`ÚX­fø´ÈGóBÉ’.çÑD žqH	¾´Uí+òÛy«I‚)³Ê ¡iý1V1WÂùºöíózm/éõ‰qR?–›c08©·MÓ ÍÜGò¤$Xÿˆ¯ë¤‘
 „UQ‰R˜	e"4$¦„åÖ‰5£nd±;«˜’0Ha?%Í-Qi#%A§%á\G·~YI1O䀄’#  ]DR.ªó×B½ðC柽bï xŠÐ &S(—Å–ù:ŒÖ¼îª™¯Ñ[\Æ·yÅ%çv½Õ¹n›\‘~ª)¹õ1 sºP‘¹b¬Cd0Xio’¥ì˜–VÕkÔLîˆf z%Xæj­ZUé9:ƒDsì?·{ø¦Â±66<B6ŒÐ*ÑŠ¿ØÈ—#$U¢Î­ŒPhlΰë£Ì#%¨P‰¦Á´¤2Â1*n6ŒÂ)8(ŠØÚ6—ž»Ù^o:ñ¹z¬4–ɳiØg`Bfg©ƒ–%Üd7®85}騄„Ú0.¨ö }êÅ2×Öœt!ÚY3õܵ®wÈß^Ë$<ÑÀ×Õ7$ÎN0bâ"¤-"Œq¤C£ Ø³	‡wÝIŠFI=U#$N ¬`{ªZêÓ^è«,Š-#è‰f­„ü¼qڐÐÎdÝÓ¶S…•!jlØÀ|`ø5”#%›ëJ©}…u¤8´“ì`<åËTfÊJª3È®•¯–º¹UG¹ÃÓðw„G§ÖTÒÇ$o•â”f-J”CM“òx5E•Nÿßðñ¶[2±fˆG.ú>x…Käp_WÑõÉÌNhcéÔwØüˆmÙ€n"C¦Y±8Þˆ&rÌÄóë>eùûVû]áÒj:ʲ#ÊŒÜÍë(„t8˜hx?1aI³¿Ñós7ýl8’z!Íà=‰ˆƒøÒ9C¯‰Ù°GŸ?¢ìÛnkp¿œ–a¹0k~pñTmM#$XîÜ/Žý_þÿþÿ7ÿßôþÿ‡ýüÿüÛéÿgý¿ëÿúÿæÿÇÛÿùÿ‡þ?óÿŸÛéõ°I«×ó‹†0õý/à)/÷b§ÖèùÀ_Š|—VˆÈ’k¿å?9!\~”Ö-€þ$Õël6QºQà&ÔÉü—@± Ê®þ!ýñÂõÔ‘¸$pM*íRI#‘2	rÛS5îëúV{:ð!žžüð…×ìLð¨`ÁÖgöÝOÖWøççç_Óû?©*;I h”xçþÍ›v¯d (g`Žr<7ôÑY;l7 ôÐ$DY®²Æ‘»]’«J©l\™i#%gÒv•aYt﬽H v@çgõ¶ö5v¼Á¿©†\0¨{³`XßƻۭÁùp¹Q†éÔ9'¼Vòœû{ÃÃ&g_뀊A"# #$‹#$*Ø#H—ÿ¯KÖ¯z›WéV[
 |jj¯Ô³EBšF@„X_C„qYè©úeGøøȱ¿?ôsv×uŒoºjfæ=ç:ªdddižÅÃ<†¢#$¤á¡ûÙxÂRÍÖ–>]ÝÑãEx#$9`LYãD‹³Ÿ?¢øÞjÖe‹#$z’:à0‹ k#Pß#$Lr˜MU`¦E/Ž–]dŽ%û”Ð?Y¬¡0R SÞDNFI at 8uÄ̽Ó(¢|û)Sˆ×½†	¼öm?¶HH)Âj·¾«ëë5F­LÙņ¿½¸û‚u#%ò!$ AˆŠèÒàO=`Ÿ¯‡À¯«ÇÇ`߶Ÿ(ê,÷.sà}Ê_ÛkØ`ª©«þ¿Ó>Pÿ—¯ú¹ÈÏì­éjîãóõ×aŒû ÕfPˆa4xzÐÒx3ƒËo‡´	²»xÿ`¯|˲ÞW*B¯ú“èÿ£EOñßÚ|–tò3s€ÈÊ}ØóþÀhÇQZ9<1¿K^iÇñvÏ0ÃÕÓìÿÅÜ‘N$#%è•t€
+#<==


Property changes on: sion/trunk/waf
___________________________________________________________________
Added: svn:executable
   + *

Added: sion/trunk/wscript
===================================================================
--- sion/trunk/wscript	                        (rev 0)
+++ sion/trunk/wscript	2008-12-13 16:33:35 UTC (rev 6300)
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# WAF build script
+#
+# Copyright 2008 Enrico Tröger <enrico(at)xfce(dot)org>
+#
+# 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; version 2 of the License.
+#
+# 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# $Id$
+
+
+
+import Build, Configure, Options, Runner, Task, Utils
+import sys, os, subprocess, shutil
+
+
+APPNAME = 'sion'
+VERSION = '0.0.1'
+
+srcdir = '.'
+blddir = '_build_'
+
+
+sources = [ 'src/main.c', 'src/compat.c', 'src/window.c', 'src/bookmark.c', 'src/settings.c',
+			'src/menubuttonaction.c', 'src/passworddialog.c', 'src/bookmarkdialog.c',
+			'src/bookmarkeditdialog.c', 'src/preferencesdialog.c', 'src/backendgvfs.c',
+			'src/common.c' ]
+
+
+
+def configure(conf):
+	conf.check_tool('compiler_cc intltool misc')
+
+	conf.check_cfg(package='gtk+-2.0', atleast_version='2.12.0', uselib_store='GTK', mandatory=True)
+	conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='GTK')
+	conf.check_cfg(package='gio-2.0', atleast_version='2.16.0', uselib_store='GIO', mandatory=True)
+	conf.check_cfg(package='gio-2.0', args='--cflags --libs', uselib_store='GIO')
+
+	gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK')
+	gio_version = conf.check_cfg(modversion='gio-2.0', uselib_store='GIO')
+
+	conf.define('GETTEXT_PACKAGE', APPNAME, 1)
+	conf.define('PACKAGE', APPNAME, 1)
+	conf.define('VERSION', VERSION, 1)
+
+	if Options.options.mandir:
+		conf.define('MANDIR', opt_name, 1)
+	else:
+		conf.define('MANDIR', conf.env['DATADIR'] + '/man', 1)
+
+	conf.write_config_header('config.h')
+
+	# debug flags
+	if Options.options.debug:
+		conf.env.append_value('CCFLAGS', '-g -DDEBUG -O0 -Wdeclaration-after-statement -Wmissing-field-initializers -Wsign-compare -Wfloat-equal -Wshadow -Wpointer-arith -Wnested-externs -D_FORTIFY_SOURCE=2 -Wformat=2 -Wformat-security -fno-common -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE')
+
+	Utils.pprint('BLUE', 'Summary:')
+	print_message(conf, 'Install sion ' + VERSION + ' in', conf.env['PREFIX'])
+	print_message(conf, 'Using GTK version', gtk_version or 'Unknown')
+	print_message(conf, 'Using GIO version', gio_version or 'Unknown')
+	print_message(conf, 'Compiling with debugging support', Options.options.debug and 'yes' or 'no')
+
+
+def set_options(opt):
+	opt.tool_options('compiler_cc')
+	opt.tool_options('intltool')
+
+	# Features
+	opt.add_option('--enable-debug', action='store_true', default=False,
+		help='enable debug mode [default: No]', dest='debug')
+	opt.add_option('--update-po', action='store_true', default=False,
+		help='update the message catalogs for translation', dest='update_po')
+	# Paths
+	opt.add_option('--mandir', type='string', default='',
+		help='man documentation', dest='mandir')
+
+
+def build(bld):
+	obj = bld.new_task_gen('cc', 'program')
+	obj.name		 = 'sion'
+	obj.target	   = 'sion'
+	obj.source	   = sources
+	obj.uselib	   = 'GTK GIO'
+
+	# Translations
+	obj		 = bld.new_task_gen('intltool_po')
+	obj.podir   = 'po'
+	obj.appname = 'sion'
+
+	# sion.desktop
+	obj		 = bld.new_task_gen('intltool_in')
+	obj.source  = 'sion.desktop.in'
+	obj.install_path = '${DATADIR}/applications'
+	obj.flags   = '-d'
+
+	# sion.1
+	obj		 = bld.new_task_gen('subst')
+	obj.source  = 'sion.1.in'
+	obj.target  = 'sion.1'
+	obj.dict	= { 'VERSION' : VERSION }
+	obj.install_path = 0
+	bld.install_files('${MANDIR}/man1', 'sion.1')
+
+
+def dist():
+	import md5
+	from Scripting import dist, excludes
+	excludes.remove('Makefile')
+	excludes.append('sion-%s.tar.bz2.sig' % VERSION)
+	filename = dist(APPNAME, VERSION)
+	f = file(filename,'rb')
+	m = md5.md5()
+	readBytes = 100000
+	while (readBytes):
+		readString = f.read(readBytes)
+		m.update(readString)
+		readBytes = len(readString)
+	f.close()
+	launch('gpg --detach-sign --digest-algo SHA512 %s' % filename, 'Signing %s' % filename)
+	print 'MD5 sum:', filename, m.hexdigest()
+	sys.exit(0)
+
+
+def shutdown():
+	if Options.options.update_po:
+		os.chdir('%s/po' % srcdir)
+		try:
+			try:
+				size_old = os.stat('sion.pot').st_size
+			except:
+				size_old = 0
+			subprocess.call(['intltool-update', '--pot', '-g', APPNAME])
+			size_new = os.stat('sion.pot').st_size
+			if size_new != size_old:
+				Utils.pprint('CYAN', 'Updated POT file.')
+				launch('intltool-update -r -g %s' % APPNAME, 'Updating translations', 'CYAN')
+			else:
+				Utils.pprint('CYAN', 'POT file is up to date.')
+		except:
+			Utils.pprint('RED', 'Failed to generate pot file.')
+		os.chdir('..')
+
+
+# Simple function to execute a command and print its exit status
+def launch(command, status, success_color='GREEN'):
+	ret = 0
+	Utils.pprint(success_color, status)
+	try:
+		ret = subprocess.call(command.split())
+	except:
+		ret = 1
+
+	if ret != 0:
+		Utils.pprint('RED', status + ' failed')
+
+	return ret
+
+def print_message(conf, msg, result, color = 'GREEN'):
+	conf.check_message_1(msg)
+	conf.check_message_2(result, color)




More information about the Goodies-commits mailing list