[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îkz¨H¥SÐÔ½yäY#%Ö[` "W{$'YtTíîî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üǽiNwQÞ½ëGÐ4Ð4 &&Èh¦0&ÄÉ#!ú¦ ¦@@4Ѧ`Sõ2ö©ê?TA $"4ÓFèC*ÍIêêzJ=OF¦ Ñ£!ê é ©I54É)êyLMÔôA £@ Ó@ @h ¦h4Ôɱ44jzM$ÚdÒ ÓÐI¨ @i M4Òe4Ú¨Óy'¤Íª=OÊ¡êÒ?T h@ù?Ú#%ÍIð!LÅeF Iª¢ß×èõúêþÛûl^{mW++½áà4ìëùt Þ+MÜ+°¶ÂBMÛ©-%©È~"¡Xä´Sw¢ÑzÍèrÓÁp°ÌÁ*+ë ]¤I`(H¢" ı{¶6V(>x@¬ °Sè
"' DU IB¤#TÌÃ1"ÐD¥
)¶2T&¶3!
&"Lje+FÈc&jI¢XMHFY3i´ iªÍ[!©)¶ÆÙ©É(*)4²dRjHSYIX¨É³"#RXÉ&TI5KFJZI&Ä¢-E¢¢diClÁLSf&S)m3X¡1(¢Èl¤ÒÔk#BXK&FÍ(PL4k#$bBÆ5Ͳ2XPÈKFH¡$ØCIlÃ1RÍ4XÅÃ*BÁ$Le4
$̱¤Dؤ4( DYS%¦Ú$4À²Pfe£M(0f±R#$3I#$´Ôj-%S&
2)bK4Ò$*XdÒZHFÙ(ª ÔmiÖ$±)´Â4)F¢¡1ª6-)*,QÑX@)£Ad¤P¢#%d$b!i0L¥TÖ¡ÌÄj1HÈ@4V42п/·S-5DL¡fIhÓALÌ©2m*a¥6H(²¨¤Ö2¦21"#2I¬LÆ£%´EÆ¢¢ÍU*)µE¨ÖØ¢±FJѶ¢Fm4ȦhÅcBÔ¨Û2FÒɵYQZ6jTi+MdRY2M3L²1AP±%YI¤`dR#%À
£E-$&$Å¥$Pj$M©(Ò"%£¢Åb¢,J£X¶b[b$ÅFÙ*QªDÖBÄERm@ÚFÌÚ#$2lÙ*I4¨&j&Q#%Q¨B¢É££Z2Tj2m%56j1TH L&2%ÄdÔ[Am¤MLÈ6iYZMѤÔ
£"3hÓÛM É5©ÈÄPÙl6¦2¤BYII-¬V±-C)4lVJ¥6¢-!¶I&jJÔM1TFMJ*BRÈfj¨¬ØYÅHSm±ªdKbVRɨÔ6ÄdÚųDÊKa1fÍMXÄÕ5²b£b1±T
J£lT[Y¨µ!¥çnmX֯͸A3ñQ?«ß®
±±)ÿ±ÿòÉ
@XþÝj䤢£²Yÿ|B¿á®Òkݪ^¤þ/ðÃ¥ÝiyÄô4cWÉÅd\1mâm¡$#%âê*Å,>[ðçd''ön|¾/ a-26¤ÑlozJA+µrÅ"3¶)M#%&lÏú«ùYòbÿçFA³
ü©HoýßËøà2ÄçE1*ª¡t{Y-].MñeU~$2Qݵ©ÌWû¨(m¥#$HwÐW®)IµB®ôZZ @ð(¨!YÒ
DdöäåÃ"Ã#$Q RVPÚÕ^½1y6#ÚUõ<Ë
{÷0[ç[Ò<ñ]"/¦ñ¥120dÏßÒÞu ÌÚÒ°ôC³=5üEðÿ0kÏZÌ1Æ÷WÏÒcmø#$ý¬Óþg phVv#$¢¨°¶[_â©I]óC ÜåÛ`Ec8»§1ø·mû'4'1scmDDÞÚdÈìLTÈÓ°Æ{5Èx¹Q·²G"ZUB/¿Ûò>ÏM¯>Y[ú°Ö¥RÁ±âÈll<ByÈßö?GÕ´Dc`V×L±X7«V[sYéºm&?ºé¤û®ÚªDú4ý½\TVoP®ê¨cÁ¡¾hmªSÏ,Y2×#%èû&´@ÛR´KåÜ#ÉG#$8à=°8ÈyÓRÉÅT²]X1¶&ĵhS±)UÐrÔ±fTÆHV-ôåÂ(ÄPX"å§[çkmku¶äþ©ÙëM®\MÏ
!¤Ã½Çݨ2AÀâGw0õÂ/«ülØ®ELHÇþ<£U8Vl/´äÉ$¡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;(_úéÔ¹#%ê+c8ÏL¥MÈÚ`æáI$yðûÍ×]ýÒæI-Ì( S»¬»÷æí)£Ü¾Þua
}· ^G{8_|¹HÛÁ·mØ¢TúWvFSµµ³Òv[x+Û]îyM¾2K=X°éîÍÃI½R¨ßjZ×¥YÍýnýmÈ7ù0%æÈÿü?7cb®ÒW¨®§(ïשà#%l"Ó.öbÈØJIêM
â^ÎT5N§Âô]X°¯_eÄ=ðªee:wt}/¢ÕL8tBÚI½0Oµ×j¨*×ûl=ñÂdSfÑ\êß#¹#û×{Þ³óMS.ï©SE::?Ôc3ûCì ^NµP8ò@£=g]#ÿ<(Ëbâ\NàÚeäåXÈÅb¯c¤ØÄW%¯Âí»TÖÁaµd7.ÉÖGwÅ3,ÓBrª§ª¨cQ
/ëå/¯RÖÚíioÙ µö6Qít¿;¼á±iàøoàèxmDø3^ ðñ¨`Õ\\[rïÛö;<ŵBa÷¨yò$±TîÝÏm/¯l:æ ôL#$5.%ã#î¦Èù/1&íÃÞAÈ9óûWZÇfQPYÛMâchk{Â}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฻#%yD#fh¬ÌPâÞMx)©ô¡r>&;ÊGµIyÌ'añÛ;Ì¢½Pêï)_¦',ó¸)(Ó®Ía¥wl¼´ÏaV4V6Ï!&S¥«j=7Aö³@te?òUABÜÖÅ
qýP9WU]#$¬¤Pf¢Gn>]|nª§"è®û$7ë3a8V½L,OÎ_?fOYª7ñû,ðg±æ{<¸i:èÓD¥T®TnÎÆjÓ¦MF.ôJ6NïÊhIµúN,8stûï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]h5sF1ÛTb,1 5ûïÝJ±3 $ÆÆë³Ý+ãÆÕÀa?½"~h Ã1ýI@±ÝÑà.ãÔíê(jÄý6úo»¸¿èè!íö««ªdè§St# ¨Û'oÏW;"ÖxVAîX¸fHß~^x1æ¦nËgw4¨hÿ!-¤ÏUV`E
:ßØRDËÉl$z(¸¼¦¹Æz×*fK(´À*,U°{H¡Îyu`]
[ -ÞcL¦òÁnß
¨cAÕó, ·Áýaé°â·bows#$8Tläd¬øû¼7ÊË¿R#$zBG+õ]¸=±Iþ2¡òqów¶£ûcôcç[OïlíÛgþñíû|ÝDO^ "' dRD#$ô@ ÜGnIµP,ÊÁêý<>o§þμùÿ#%òìôæàçF &ÚÀX5Ø:æÿ½:X7¨$ÂÈ*0¯e¨Êö¨½·Cìþ߯ý¸4-[¬$å@
ü=à¬xoþ]]Zür¾ã!m#%\àXL¥ m¥CÖ
Ó"ÒP£E¢CùõýMuÆÀ³Õ¨ö~¢`\ØqÑ+¯Qcêévô-öÃjÜÛ~öÒéxa# 2ÖV&ÆÕuºÅGÖ[+^Ø/ôKþíþO#$ZÿÅÿÛqup`ìîÃ$z®Ëµ-ÀógÛ©?ÐZ2QRL©16cô¦nSÓûV"}üaµS³®<dÈÛÕ6ÿ§è¶®6RÐÅ(GÞgtººx½ÂË$ª%þ× #Ó/Å
FÛmQ¼ãÚ }k![`*+ÒK°D´$÷üw«UD¾<õc8i.àü;^³|rÄû}ÓúÖÿ×Àü+lñÉ1¹ÀòPñðæê®
CÙ
¥þ÷ÍQEðþ*бGÄ)¢;Û·_+_æ;ß>?
ɺºé+¾Óµ¶:,¢¨Êb:Ú¡ÐòC |MêzJµt7¢¾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Á"bg}µzïK¦Í.í4Q8¥õ½Blì+á÷2_+sb qz»nZß©5?º¦}Ý q/ÝÚ£òZYÑØéÔ§;.ôpXÌÂ8EôÏHÇÝÞ!ש©³\¢¨l §½ÞíW#$òƦwí²º
ªîÊ
Ø1Xæ1kAì®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Ýé:RA`ºAHàr CëÇr¥þÓÝODVÈ·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ã^¡}UCÈÀÊÅF*Ø[ßdåtJÔQ´#%dÙF"g×µ«"M \UrÚþ}Z:¹ËZľJ«XöY5èq(78s1÷&#xsQºïDVVÉ(tkÝ'YzÇ|Ù%$D¿5ú«á«C¾ðÛÏÞCF5e#ÀºªSaæz§dYËÜçNÆ=·ÄÔº¡°Ì=Ibð,4è1´6+ÄÄÖ8ÆÁ#%S3WBɶ<5ê+¦88¢#$ëeÓZPºZ(ÒmQ(4ì¶J4Æ4{§EÙ5ÐÞL¢Øxo¢o<¯ë¾°dTó¼Æ»²23hÃEh<ä+Ù³¼8pMÍØäáDz³t2ÓÕ¬xZÔ âÉ7Í"Ç5éUJmÕ|.'jOÄé»®ôëô÷0Òðâ¤$Qé߻ڽԣ_Æ°þ*-³jÕás{'Û¥®Fo£Èsf^%¯Õ#$³}eѯSmeàlÃiv\jZ`b+ÕSmÃú`ì!dâ+¤KÀª©BU¶y,mDXÉÌJÂ¥]+vbaiFìJO"w±j]ø?ÂgxOiNbÌö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ïgp> úÕ01B¦LÇ2 z{}läØGõ¿ÆlVËáÛfZUBugÝ1çôk6%Ñõ|G/ÕÄwÕ·í(!s}Ñø¨@#9+,´¤$7ÉýÔMÈG¨äùùôþµX1×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ÝÓ+ÇLYFø~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Éâ11YÌXÒX7 ÉÑ<-,çîÜÆ´"îrµ´¯ö8%ïüåiÛ¨¯è(¢èFCÆaª!¹3î`òèbGþ2æSódcO¯m{¿B5òP÷Òä±éÇ~?°NRòl_,aJy²Ì@¤CRU+d¥9WÃïÝd©ØX/½ûpì;DûLSæâß+½êÍNé[iüJzHî"òVõgõAÇ̷侨\_7WãÎ";ÉâÑP"$ÁGñébT( FcA¶(> ñÝËÝoîúû¾Éîûx¬/ú·UÈeN#¦Ê5CÎÞ#$»EëQ_]?Üfý= ¬4²OlüpÃ\Í/Å¢4J,íúùíÂé]ýÛݽyðíñå÷Cp»Û±·ìòàeD·|2%PQw×°«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ëü~¯¿õûfygðü#ÔN:åôÓºRÓ1ë×èßÙä1ù,Ø¥ÎÍaRý(A¢8>ðÓq=#mRe#$S#%ÈeQ¤¥
m¹5B6f0U2þyUÔ1F0´¬p 5×a¡²m&V&R!B¨mw¥Mdh%Yh¬éH¡´·T±LÌQÊãþz^¯iõÔ;¶ÿoå(;+GZÆðô_`ÏÛÇÝëiÈ}kíûñn¿]ÄCÕ Ù{ ÆQÇ#$U>>Ùê£òUÏölúÇ~¶OÁׯê>vWJ·/Åp1°#%$À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À.Ø¢<??¿=ÉýÛG0DE(nËýi÷dXÞeÔK!g*?Õo|Ù} ~Ù1¶r6bËB¬9b2\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¬kBXB at Wâ%ÈfX¬Ï®EÑP¢§Ïø}{;Æë{zÀïb'tÈÌ¡´8EKlD$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°´÷~Óucþ̺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àff¥f
¸ËWÆqû+îãaä°ièÏÜÕuc<^¹»Y/N¼û~ÉþÂà$ýÀÃêñÝ·³4QQã,Pñé_;¥BAê`#DÆñ9¼õÖÏKá'$¬ÏrIçf¥æ â]úýã P÷Ç*püù³~ÌÅSLÂB\¦ñÝ a¡ì¼¾u´Qb ²(ª ,5ÕòÎtì&÷|å¯O¿¾ís¾Èæ+÷ª¤å2*8$ú«ÅÄ©xc¦U«sj©ÝÏÄÚ«°øiÄäÀlµa9áqé9w0|¿r 0»ù±3ÇXSDËïÝLßK{à±Ú½~©½,^wµÖ½î÷ÉÁ'h«/^&_ÃÐRiFP[º«eg åx8P«1ÏX°§;É ´¯ ãq9Ýî}òÛ#%QìÕàe³ãv!^¯)5üÚr
þI!ëøÐ-Øö÷®dýtÝ÷lf{ÂI«Ç[«ôüoU°ðåãëEci³nI´$³¦>¼¤ßaÃXw¿¿v£ÎÑq{OlÈ[ÓÆOõ#pZYJ·¸âö¥bÞm\-bWÌÐàEà]±kÓ³ Ó#${qBB³
½A9xüµê"¶çÑD$þ:RW¥U(ðuxü«¿GnÝìƽ"ò©¥2?kÁ¼Zü[8ßLM$,&v!£<ÖÅÎ1ËÛ'9Ü%^Êß¹Ä+¬Ts¦ UF±Éî|ëFe.&Ó ±,É/xT©Yª/lG»o¢sIèÕ«7Ä@ëþzëÇ1cÜþ½:Õn¡2ì¾ZZ`"¼ãÛï¶oà=u>N¤AOx#$Y¸Còåtô¨»n_ëã¶f\}_¯;R½K2U>Ä{Î_Ö÷ønÕcmôPzLZj«4é=îäûob°E_i+.=93Us6×|(vjð|êU
m«E]m8Á«4l%¹ÈìzÕíì¶LYVk<ñ»¾yÆ¢æû?cvF»¿EÙF*¢¶õfW½ +8yA}³|®vÆûßÒ:++,£ëÁ:×]lïöùq3¾"˺¦½9l»J#%͵X>U¦0IìÅ«VíÏ=eRÚXó¡úÔtv]8µ5[ÌÜø#%Íê%ð8êj(Gdî¬1v0X®#d\îáX|Á¨aÝË0káX¬ÊNI0øi®oc
HÉ!HRÌíNCQcG Ï#$tÝ×ÒÎÜEö§j5'Æ-sP ¢vYY¸ânjb:ñ,þïÔ¿@6G*¦ÝÂüdN,#z»bb:Jm(ôQÑN´%;!©Iª³$c:äÂ7ã?¼Ã8(WY^Öxµv7w÷§ ÉàÇCn<.êå¶Ó û5ÕMeª(î®+PÈ[däJ¡7;Z·ÅaÝe UÈdؽ9s%KzO²6Óâßg×Çñ¿×ÞQvÃÝTJd ¢Áu5åµÒ¤¯ÙÝÕùBA«ÔÒH(þý8&Æ9í´â½º»tÞáÆ"û[ih>ÚìðUÆ¥Ø_öãüÿÚmúÊtÖÉ.ý?äíð®+é4êÍݹV+º¾±þ8NÃðuÄ<&Ñõ»^FøàvbΪ#^¹©©6ãÚ#ÜøeJá(b¸ì¯
{g8Qv#2¨63½&»ò3î³)é¶/ZQ ñf7ðRDÙp_¡3#æØùEwª¡5k[R5èÛ:#%JÚݵµÂ]6Kæ"Üãs>¥õWk»X¥.ni¾-¸ÄÌ×_q鯶% WoOÎÙ×}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õJMt¸¸Úé*«pÀ±Òóq[µuãÛlÝ8Icªás]5Uîò¾¶|Å6ôEõyÜx{ÏG½DWÖ¢Î:fV>ËÛÓ±tFoÊ 5Þ$`RHõñáläÓ~¾ê§uâú&ê5e§ÎÁólè´í{p
´+^Â3·8AT
¼µÜ§¶P3o ÏsÂÍ÷EØïúá`"Æ4L@QÛ©csÛ±il{,\¦È78^Â7DøŶ½eê³²{öØ{éÙjOüS¹BܱÐMÇO>3 #µoÔðîüh½èÍ5(ú²&ÍÊ3XµÜn¼ ])¼
¿zôn][(!ey/¼xÇ´èðÉÆP³Âû°
\Xhåºá¼Ý!kK!u4mÓ©cÂ8²æ VÒ=6f ù´Ê7C¢tÙÁOú}Ì6>/hS
õyïPðMÜ )µk`é#t Ó]U4~ÄÛm<N#²ú¢Ê[ýþ{füéÍê¶HôCø"廿>Â^Ö04¦tv^"8È1½Û±Ìå'¿¾:äÂS¶«>3Ý»69#$Nªb;óØ*°)@½*3\[¸ÖV¤åMD
Û& ¥k*ùäÃXå#eP±ï[ø=Sbì²ï[xWÂêN²¯2\«î»ûkæ³pù}æE¬-d»
0pÛÔl
ìH¿'¾µÄïñëIRåVÁnìÓxpÜáÁyø@´ÚpÂ$ÒÍÏ[®jã!*ÙeH4]Ñ|î| »4bôhöÍ'ã1bw<:Xê4mozÎF滥´öx_e)avÉGcU ±õ5§¾9ókd%xìjWqÇ>¦u]¶NÛhÖ«g-»Ãg×ÒLW¨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åKV¤0Wëdêg¦#%÷"±/W>Í`>¦Nßbz¡ÛnL!KàϦ1Õ¹tn¤VƳZA@@|.+¶MQuTV µïÁÊ_ôë%ÁÁBjXTÍqoWTepsC ¯2<`»§Óëå¤j1ÛvãszLyîÐkãÂÔe×ÑP³ä¤K²¨Ù`Ù)ý3Ñë`Ö,ì¼ú:'¶ÂíÊÉ~,Ó#%THD.ïÜWE{§H½½È
k 1gYé-)¬AqV0lCnÍ §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ÀþóÚ¯KV2{)SÔ¦ôóyâûNtü$Ù6&ûG¶ÃÔGÛV2kÁÞ*%ÿ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ð~Mf¿©Õð-ª¿³Î!wéþÑÝÄâ/éDµb"s#% ¨Yò÷»Jø÷aááIîA<NÝ2*üð²^'¶7Ö0[3äý+@ìÅf)ù§Y¦'¼
q{gp%[ÜCîÖÉXaÌVáçTÀ\ø#%ìð^·+¡V¸ø¢_vú,su ²Ã{½ po©¶ÃrëµHø:ú:råí#$»,¬îMé¶*3ksX¸Ï?Ï(w"%ÕPõ*¤z+3Þ~ûЫÚÅü¬ÍÐwÍ]uÛs"|ð׿ºÀ1ýD\O-D¼Iê!öõÓ¯±Ùkc@Ýí½ZXñ\Bm8JM²ÜæÓ·ÉÂÑ%!¬ÁÀ}ßìòA¯pæ»=8è1eßL}ëw#$<0ß(%õ¢©/.zX8$}²&2.â§èéÃ-ýØØé~ÿ]ª² ªøÀn+«ùØÄçÈ#z¨[ç«Âø?LV]9æ¾®êÆø#$uB&0c°î8P¿Ý éüòKwF^õAñ#@iQ çeúE1P7^ºö¤s:£LõûÚä±0Á±É£Gw·»ºû°ìÖððDbáF}Ã{ _åù(µÏc¶ølVSEsÖäSþNõ»«|L7
ã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òÌ{Mjáµï§?J I¶rñãw at e·ZFéqËØå¸ö*Çoá¾ÚÑPFKÜQL½ºls·V.¨Í!¤1ϯ{¶8â1xPfyÖÝfÔ¡©E9i3<r=ä#$|7±Ç6°É\Bç½"3d·u´ozÒúÉjÎà0Ø*îAÁºÛn3ll*SbìñQí¨¨·p㺣gvhè d[JZtyRéÌHD»MîQÕÏTèÅÔ1×k'\1ã¯#ßÕ»Þá>w»}ò¹JÜ,Ø)gÎ[&¨) PFm¼¢ËïÛdÅ÷¨¦M7ôY6l®b"!1gÕ1{ßÆZsJôW® BÍeEðS<FèÄ0¦69-^Ò/æ£C&Ð#$Úù¥~éY}e^aJë¿ÚÊAK;Íáó¹p»)ã=ó}VÞþZ
únQÍ;&ÎÇ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
Cbq妡ä)h=NUý^`3"òåJ¹¹>j7Rr¯äÔ»·°éá{u0À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ÕÛºi6Mª¶#% U`.u485!$
rÑS)I#"ÄølWÑ4úwâfÓ´x°¼à·`Ü¡¬ª&عº¨<
È`XlÙ¶'dðGT5gP2vQÈ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·ÚWoNLÛ'i9:%'«¾úõìØ,Ö9æ,E=bF° #$º«)¹À6·¾«DG³¦Zº5eGgÈÆ]ÈîQH*Ga§víä4õ{}Èëã?\KÒ©W2¥ÙØ"èkCu 7i&Ê
#Cs[nFs:BÁB0*$T¦®þõäË8èN«»¾.àV6ÈÇåÆÂ'"G{V*Ò¦ ð{- @Ò¥ã¿ËoÎyi~ȱÉuå´Û|bTD*Î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 #ÉLc4gwà¸Ð`VzZSIƨ+×éÐ8ø.Èû:T ]gv8T$'N§v&Ã'vÞª.8â1^DL¼Ö¤LÍ÷~¯áÉü-oðpS9ÝðÝ0<Ôê(¡³åý;LpÏáí÷ñÁ?B6ñÊ~!¾ â'Äè$¹ÿ /ùãù~õ[Þ6ý¼c`UûÈ$ÈIxTúþ²¡l7ib§ïå¾Ôê)?Ã=¨,`e%1YMMl¢þ=Æ"æ*§íþ¼«Ì(DDJÈõÿ§áúÛö¿ý?Þ.¢cüÿ»ïhÃð[_Ëiü¨§þ¢±4|¹¾XW¨LýZïeJE3S¦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&ya5¼ÿ®!¦¼B ÍNO/äÍîS
ÚK¾··Ø{Yþµs«ÃOØõA#%,¬Î3åò=Þùö|¦=:+òuùü:ª])(R,ãAQ_:?»ú'§¿Æ÷¿.ïm¥,HîÛ:#$(^uþ:PfõùÐ%\»+÷{÷bw¥{7:w$Û]ÖÉDP:ÙÄn³"³
DCrôy Ïu|;87@¾@wæD¼ÄVBñÎ#$b¯m
xØ Þ6àäèèÝOI Üâ|¡5Uj¶£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?Lfb±ÅcûrGë|¥Å¢niTä«ò{i¶8üà¥9K²HJò$t©Æä$üª$o-ûh{Í?ºÛyHm2ÁEÌæxÙñ]᪲*óÙ=ðx[ﺯ>kq%¸Zzé)VtM;¼u¨l ÿwø¯åWýýkmë#%MÓ%¶jºK
x~ÆòëÖía #ÞpníY6D,sínþ³Éílp§rñR©ú_LadòH¨¤(ù\z Y9í¢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~ødVzT>Çn#fÉEõ¸gWðÞ,vIXÊu¡-÷©¥2.æ×--q¥@¨WBÞlJkTHHµË3Éiq)à-ÝÝö^Có;(¾«Ðt+Í´ò
Û«Ç)ÊÖmÛ×80§ô¡[ÖÊt¬ìеfwlJ®U~ÇqQ]hüéU·ÙkÛSä42î`¯z !¦Ëkçä¯KEùR $DPdáÒA ÿnzWiuæ8¹nae`Bgrûh
?kYÖÙ·,£ûUæ^ïªYÄiø«C;Þ¾9ö7XÝtA¶ÃºL°!2ÃJü8êEëÇ)?_N=366:&kO»Û¥`Úûnz÷Bͳ¹¥4çËÚ.Bwr¡Ù'WKBÓ,ìÜ!UIòLmDd RppÉ®ôIò¦Ñ08dÖîXI6Ë.át¤Áq*M;flãQ{WÂ!çê¸R
ß$¾!øE¼Zq\`ã´ºM"3£ [¬Sú_¦ª7¨Þòþ&0ø¼HÒÖ)IôÍ®gíq]¿ßU°ô g8Uö¶¸ZùR|)6¹°Qrëû37÷{|¾zÕüìOZtOV¼*ð¾üØ\uÛ(?£»Vaë~¹EM æû(îÇÕ,ÈB9L¡PñÙµï6Ñ{;£Õ|#%zC¸-öËf$EÕæÃÍÝlNy± _Èx¥¯
f\¢Ä&säA8îwç}´´ÛܪÆ~£¼ïK_5$vîC5ËCÿÕ N;jgqdËáGôü8˼{Uâj.yC<²è*ÁµkyZ qóO®È¡VŵÚàãľõó[½¹_`iØáb#%K1£¿§¦,æ6ã Ã%N¡1Ý©2Æ(G¤*ÔÐF^ÕdeÂ1ã%!T(ÅúìÕ-®!G%#$skÝsy=LÜXàÄ}Øý'ø4R/N{Ïù{5yÕtëù0aoúx?¦>÷k_?wgF at tìpÇ,AúN,!Y¥åº±Î Ú%ó£~)^Ç¿·j'ê$-G*ÃýjzÃýÑÕ`-Ú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ðacö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¾µ&ORÒ³tJ²xþ²Ôqù:Ǻ
Mîsnbú2¢vüì~^/{ÃË;AIjHéh Kì
Á±b#%-µ«Åãtáè!þk¤z¡uG·±=fCæcWHÊ(uO Tr"#®MQó×A@1$°Ó}ÄÿZêe«u)ÜÄ2G£·fÞ¼(&e£ÍâgR:¯ÿ_{Ê-XÌx¾Z£Åȼաâ¾ç¥± ²ÚniwÚudT+*[h× +#%!S&#ôOI ÔJÏba
~²ÈÍ´Æøñ(_^¢"Z#$ùbU¿/VFfØ©´ñv§Óº%ølWÒ$sh1¾"#%+»/;÷!ÀJ/ì
H¤t¨{`# vÁ'ýr®÷ïÙ«áU'g¢jeè¼ÇÉ
,5ÇHa¡JþÇÀÀÃø8EAàê$D5¸y£0ëÌ)dú¼xûþºÊqÖ p÷°[tÖË!)yû>ZÉ-¶ÁQáÊ;ÞÔ^ ß(;È`.Kxdp¡TPyüäBí²ÍLãlw^A#¯«Xfëªb6Òi@±T£@uˬíÆÛPsZEÅó]14fvÍ_(lªÓ;i4+ ËDóªß³ü.VÛë[T7áËklÛ·¿_~Ëpoíø»`êÒÙ7~5æX`í?¦úÖ±]_o;#$*$Ûìa`»hdãvùÄYÓ $é.WÁk,v¼êEÇ8t59Â9L¯ÆÙ]05dèDQànmìú[|uß «w¿|O7õÚ
É¡Xw/VEö>$W&3<ü=ÚmxoÚï ½vÐÆ÷ÊÅÈà@UT#$!¥:àø.Þ}p0²8#%2É ÎÒBtÊ®-6zF±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¦7FY@- ´5ZëI¡®Ã^VÀHðYðÝ<Ë9àó
}ütñ¨ÓZo|Ù&#$÷Æ~R¤ñ¼üqo ô½oÚu||¯p~Ç0l¾fÝ#ÎÆp|µªç¶3ksg Ò²U]¦%(`Q´ÛrÀ´µãý~í3þ>}}#ÍíÜ7Áÿ_M)0ö×ÖWNÿMÚîH Hµpµ*;)æJYçÛjÔ9#$ ùûmxCçéÛãL° Ùé¸pý¯Ï¶?/jðlJ~C®13ü ~ÿä8Ö~ÏÌvvþX@åû_èOäQü"ñÁý¨ÿ#%ÑüfjÐËÁ¡ü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¢£â?Ê~OUºû{*ÄÞøT>-°¿¶áòö
Z9hÍü;Þ/A;×(²ÍT M*¨UUrî=Ùö>ò®ÃÕ·WÅ|ähVþU¨§0ä~É>Rgðö\¾}Ü£¬ìùSõæ %r«ÞUÚìUu¦Ãû9oaóæÞ¸nì˵y¿õzNÒe¯g?#cTÔ`|aôøËÕaøkÐñ[F#g¸Û¥kFCXcáÃ0¢¾Cr{ógüåW%qô¤DÈf þg²t=ì~m`6Î?X§ïÔOqèÖ.κJEÕý"CÏQµSÎmÈJiÒÄ×¹_.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ª%¿£ãfXDØûìÛZªæª´5Æ˨`0luÈÀR^;|EçÄXUï÷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å½@òÎ>ãTyþÝf¸¯Þ£³j='»SæÕ1;òø ÌØo°ÇFa%ze-!$RF:MÌ#$(Í1:¸Ù
U´ëI;Z0!F#%XCã⪸Í+DXugXo¡ ¹>`¬nèmlá2J÷Ôäûþ^@x;p4Âõ/Ð??¨û¾ _`Ièõ£è/sýP)çÀç=ØOI©!yà÷É#%Ögèçc^¹âÌ$rÿ#.̺¨ñ3èôJaèÊæÁáb©Ew°Æ'äñâw⸱lPG¡AeÀfÐ4±].~o±ÁßÆHðÄtäÜFÁvØ°§e¢4mÍÓÒ}ãqÃW 8zçc%W²é«2jZTHª.Ë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~ø~Mr4HH@>¸^Ô3ÛykÎÓÙ>JôíØñ`åÄ@°RFeØüÞ]¦;<7=8Hã%VÇà;L!ó7x¿WÞ3Ô'!àÀ²¤M{øê©*·vD²iºbùà 9î#%ÐÕ`-&¼q æ Ý ýÿNH~Sßìmú@îøRëØ¿¿ÕGÇ×éùZkD>¨Þv;l0(L^&)õzMw«Ó¯ÝêóÜ4ð<S/Xù ÅSðzÁ)Aàó9´^iKEïQ7õtZ5@¸Ru
ÜÍxe_´íö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Í[`i1dH ºkvÿ^ÖUúÕr#$µýd}ÙHÜ»¿$Z#%n 'kð-ú`¡¸È2[×lÿcÉ_¡í>BCqÛÛÂÍ÷ýýp`7p&l«qÑ÷µlvÖû$Ò,tµç]ìú±[WæÑÀø¾ãyf¦4qÔy¿Éû0TìH"c"ª5T´èàõô|Næ^ØHv:PÍ
ßÆjï]¡¼¸dz1¥YØØçcÙ
3]=ç«fFgyFn;ïP#%¤U#%> 2öS½Ã¡I]Ë!I #$mvÜyÞgÏw)¶NÃGݨ,Aâ¼¥¹ÇÐ~
·{VLC¶EbeÇ;Ú;Uq ¥ 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;VSþ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ä% ¡Rc̬^ítÏ?-³)Î+Õ 2Ã?gõ]#$Ðá:¹õXáí®Üú²º¨i¼ÛnM§-NüðÎ ß~²ý§}8T¬Ó¾úZt%j+F<ã ®µïï?ɹí¶CB7L¬ìÞíÇàë¿`ì9~DÛzd¹ øéÂÓÈ \m°8^Lz÷²äÀXZu|=.§ôÔ¤AnØûïeu³ù¼Rt;a¸ýßuoÛUß6:0xÿ5MgÛBH0ù_À¢û%ZOþOÆêþ£æù%-\Ç÷¬?iQfF·çMæ£$6~Ò`à8¼6Lo ì33]N<DØMÏ#$ÏÌodèR#%ÿ#Úkë;í:ʳ¿Ë¨n¨sÞÐÔ(Jz`L°íÞsNÍCi¡UDZ#!nÑ'uµN¤¬ÇÁä±Ôý|oç£tJ+c'ñD Ø° ÀÃõÕÀo4ÅdaEÅÜì¬ýß/ÚBE`ȤU0EKF0m
?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£~°¢LZÕVN)hqjDñmD(i0#%Øæ>-'9$¡y%ÓCAæcV%Z;®ãñµÈÉÈXøD¡£k¨0±)AGÜBè¥]1ì¶ñA:(tØàÞ2#$ìNz¶°¾^ë·¹VK®xh¼>¤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©â`4rÀÔÌ¥ëF¥ÄK'®Åá|Áà(ö£CB#p äÛêNH),e o<)LnÇò£u,&7JÖ%ÆæÜXì!ÉìÉÅ5S̲ñ ¹apØn¼G½Üeà,À¸=:õxÀ¼Lcu»7Ù?«w¡[àeÔÍfñãu[/#%ebE¸Ñ¦×F#$ä¦ Á¦âÀ _/#Iñ¦IsL|ó¢1À33MHhHGspÚQÐÌJc"W\(*¶8)©ql
FÃÄ lç$n$ MgPS@"åFÔ«®Âôi{øÁ1TÑm±£2yDbiÚ¨H,§
ÝjvèèÆ#$h.ê¥tí
à;óÄ;q,ðKX¥bmÌU@ÛÈXU#%+åß;CPÔ¾.:ô¨&;Q6,ÁÔB[½Éq@ÅÍFT¯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%*ëUnè¢ds<ÎnåêsMSXt5&çYà¥-)°ãH%$4êôªñlBÉççbÝ-y½L°ËÎw0*qÖí`½ í-#Kç6"¿ýè :ɹýX-
3%ß5.òI<A<çC¸lx'uÞWybÅY&
ÂQ1&Ýó!× Ôu©ØÆA.¿7¯î©ýßãØdr ö 'Sä!í¨Ø¡)$IEe@ý®
A5ÌàtNÔpKºà{ÒVÐÓO½*(@Àd at tõÒÍ J7L77@¤R"©&¿T×rû5F´B îUµ~7è?4,2tàày
-È9c QõOX§â MV½
õ\ÀÉEäÆ+ã×SÕàÏ´aHõ±¡çϬ`¦É¢&³`ë-6¤5yÌÃñÊ1#«<sÓ?crX¬(Øc
fʳӣO!r\2Èau¨MrTï ÇQäÏ]ýáfÂñ2$5BgÝ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ã&ίª«*zd=ÔQ"%MâÅ7Í)1ã=|¶þ²(B)7vÏp¬µº#%¡Dç`mÒÿ]21»k½wyÝÆêîºÝÑ»Wvm6¢I! ÙÂBtÊ`ÎåÎÅ=¤áòç2Ãy%{±¢eÈÀ¤±#$£4üW¼ËBÃé]æ
.®[5?TBD5 o®_éÛô|ïyÅå¹ $
wÓٶŶÓÒäxü À0Ê[}ÜoCGÛ?ÁÚ¦ ÃÄZBvYË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&! #cEFÂÜl].¡Mà½#$I!WD¨ ªÒÊ°6Ä?Ð<Ò§ÌeØϸsÈl
wM®T׺Úó%ðº¼ÛïØÀàð$H`/5Pâ»óÕ'»÷µ½á° rN ¦§×æÙÙó|ÞßËðþ×ý:×Â+¼ùäôXG²§DXÉaIòû(}c^[]½vÅÎ#ÁEkÂòÂM+üÁÜA$EÕëwÄ~½êõ4à¦ÛX^!ñgǾ^*¤ü¾ÚÞRL°ÖL»kßG±[j0#ü&aæå·Î dé¬æ#%ê ²"w>¸²!Öc½På¡c³(vÞ`f£hP¾TµñukTn÷ÝMüd9kó¼Ô1ÀÜuÞÈiɪÖÒÝNG'DJÊQ£!yI¬ ¤ó?Þ+ûEnûü!ýu%w=²)§Ë´ÖCب¨*¥QSK$T©·Õ^ÿ>_/m£%ØhísåNpÎs+e&SÎ øæ_gmj#$£cÉLh¬Ì!×㨠P®ºÝ?3ؼrÏþ§ß;I@onFÊÚ´°hd $+"2L¹Á@Ó%ÕÙ·b;Ãt×Eý'j(Q{1üßÀè~¿É³æÄ|8Ìé¢äÂÄoµß¨
ï¸ÉûpÎËEùä¡`sp[ÍÎüdrÍu2·} èÇ
CØOo´|ó)E Ðdc¡ðôïײ< ãÙövƶvYui`Åd:æ5Ab0Ã6#$.åj Ú'ѨtÓ×ÊÆ/PÁÅñÝ|Éî`ðG4¦Êùw® ø`Òn9[2äAs/ºt,ÛÏßTÙ±Éí ·Mï1|;!vëuöüe{
÷yQ|WVݶm*V«k4!¶Ãì/"Éå¿ëV-jvqÁ³ÀÓ-ó¦ ÔÕ¡Çâ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ãe5L AT;L9/f%Ù©ÏÜiμØGcGó{@ì\?¦jaýË ,mÕ"1Ô÷Ê}Íw2©¤EÐlÓ#S·n=¶úÌ`p#%)$vÊT°×8ã9ð#ke¦\¨õg:îjçWÍàþy3{ñâ\i"Õ×3¹p¾ê2;SasLPU&5ÕáF7lQ$þؾ)Ó¿oçÔåë8)D%Í@hÁb//UkMVN±`Ý #Ðvîì8rìæsf¦)}´N§!°gÝÕ×a
Br´á|âVìë$î#%æMc(bÁåéN0SLxxpÓnoB`ï¸aJn0Û@_Ùm¶ÍÏÖcLÛ£[;Y²Ì´vø¡Å\&I8Lob¡üo¥OjÎ%i¸H±`òXmAõHÈhÃÍ°¶eQ>©dXFÂGá]ÂÈÒÓ¬lE( (Gn`ܽJا˼Yà÷ÏT:æÚf140¶XÏ+ÔÏ©ääåxµ9ÛpérOIJÛz{rÀÞÄÅø[$oöM6)éfA} #%èiEtûºJ¤~oFLãåpÑvúkZOª>¯Ó÷r<C1Öj-Bð±èËI#$H¶`Ç i¶U{8&þ¶*«5a*¥[F£q)Ò¨èÇÜٴأ&t¢Ë@Æ%ßd¤P*FizYB"áø\¡åD¦gç¾5ÎCðqGï9±â2ãpÆFWá®±Ão³A{6F3']lÞí®n£iéR$¡ÆºK¤wa-evZEàìÌ^wxÒ°êZ/¡î^ÌqcÏë¬V77í?¬DOÔ]¹#$6qÎbQáÙ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Å2iP (PMÆÔI,Ò#$*e&b~Wna4¦ÐTbHRK`5°&íâÌÎ?¨ôzuÞd oe3=é8`Ãÿ8dmÒáÓÊue¸ì¼kްƺc©2ìý)K©qHØÂ#Öå#$ùãwrE(-s3å¬áÓa¤SLî$.g:1¶äÎõÅJÕ
ly\¬.ë{]1ýñ3&ùL|«(:Ããó=9Í#li¿Gp ÖEfJ©kÜi¡¤²GH$!HÈF'ß8¼¢o²=]}½{{<mAZ÷+a¤PXÒ<Yº÷rí®íï©ëZ"·WüÿM§ÇCãÈ<-¨>¾åG»#%)aÖ}>r·}í#$¦þß¡¿»¦ße7Ó®Cür×£40*ö°,ê~nþxr³´Ó8`õø'Â.3.E`xÎp>*mbYIDÉðgk\NÛgýIßR&Øï©ØEF÷ÅTQdTJ»«O»L¾0õ£&ýê!;1ÈûY£¬ÏRÙ9Ò)r Dãd/óKäòléY}öZ¡ÃÎw ;§FüüË»»»Öû\U{5ç0U&ÏN<¦'rWATÄN¢Ð*{úõ
ðýå"ÄRÂÊÁ&HLLë'V¡»rØÿöÔ¡G¶:\ãéæ*bê`´¿¾a¨æ=ÛaÎ=R ïÉ`Ò%'Óc[ݨÙ#%ôÖ¦á¿+4qMqñ«>× N¬zÙ]Zñ\g~&÷#%ÖØ·¨´q#@Þ²[Yb5lm]RWu¶´²hw®õt'4ðw3Þíá&f\¬Ôü5äÔ.Þ=9ƶ·1Öñä!tmÅÒ¦@Æøfîûö¼çV÷
ÖþfFÍíd_V[~Üxùq!A¶#%À·ÌkRfäÚê<¶´SûG1{c4ÒÐÇKLعiH¼¾y,6Û:¼3AÔÛ)eª¦-Õ)dÅõTmôáļ¦FåáóxlnçGcÝç×xÉb}ðçãgd<Sm#°áq:\£ÞYµNÅÃ
µìÜv¶99üRïa¹§XÓÛ"ÎlmSXy9YâÉ!jÛ©yv´Û4N&Á°¥Û3)jx"M¡Ö»-kE¨EeÔ#$#Íb·B#$¢äJqÛpÓÜÌa,ÈѳBc[hPëØ)Zy§Á<àû®ÝvWTuakC®=ï±qÜ{8¨ø´v#$ìcg±¸^YÙ÷ðÍø6ÇÖÁô²ÃåÙ¶(ÚÕ©®L µª$ºwËíªMì´Ó¢VXe;ßV7'}M¦²<¦°¡*N)× #doÖaïÎËjÝAx¦
³>¯j}>';¹ËV²ówE!Ló+lÀ!jhW#á¤.\¸ØäÔÆï,à!à±K#%Îq%Ö2÷¾x¢/!³Á2ñ±8YìAà Lé¬GLjoö;ß®ÉÍmyWzÞÅÕ×3PLܱªÜ×GÕãZNõ
XÖ×&ö6ΪabdWtNÐX!åÝìëîÍÖ·,Þ\vDÆe_dÖ¦özeÕt~7w:ÄíYéʨ&̱JæÖ¥KjWrY²øsL+4³dÙpåu2´ì-³C&¦)5#Ìæo2è.¦;Ä6ðÚÎ2Yêä'MÕ£gÖò`ÆÛo§Ï7Uê£Ã1ó¤ªl6,28k4X»Ð)BÕ]ø ÙÆmV·8Kr69ESY·¦Ój#Z§g5*ÞâØòBkXe*(ËM¢Ï!%5Ê1Jå3$²æö/]²A qÑB at uñ2«ÕÄyg×òde«1ª¥Â ]È#rSÇÓ]a¡îË6HÖªpN{¼³Kq/aÎVX/Áá»hÚ.î¢B¤&Á87Õ;rT^ú§W*çqeJ*êÄæÙ)Æø±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èÖ)¬ÍîÑ97O³7Hú>Õ^v½ìÝzXò88å@îÕÈá"-DUñW¦p{sã&4ÃVM 3bo58jfïaVeÂá`^jã8Øm9Äì³4xnê(#$QPnÊy#%0Ò4u% m(yHv:±¶Ýüp} tïÖ¨«ÐÏC¸- lÀòè;øUb©ª²i"Ðr¡O èr¾×¸#$#E]ÄJ³#$¼tÐp[ §Xd12!D ÃMQ\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ÍmcmBÉS];HnÆÉ¢k «¨¶ê\2_è 6þÈ°` \±J1)W`ÆÁº;PÚÛrc#%ȱõï&x"ÃhÝ@úIÈÆ(
Gë yhH¿IûÚæ Àb.´9ädæªÀx Úùå dGÒЮϪ>Ï^ÿyßGyïx?ÆGÈrS«dN T2¥QSuÎÕÝÝ\X×uÚw4]v»t2¨H3dÚ«FpÎ°Ú Í§h$1G¡k`4kJ¥ILM¿Pw}.Ðk\) 2O~fAÅVº¡1²H ÈkÖtÛá»äDõ)#$hämzÈÊ¢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_»ÞÉÍSN3¶DÌöÓÈïÜz½ÐUB§²_3NaK«ÛâR=Kµ×9#%^!¥ã)Ê$Ø-r¨¨1`PØâ¥taaÉ/d%·"¹×#%ïÖ6Ó_G½ªß5#$#%X°Òl8#$°Ù6Ákvi»ÀÚ¥dÒÍæB#%P´îÖSh¾"ã<KR½¿¼è¾¤îå[«"cÇúìUü¿3%®Ñtæ"¶(½¨ÚÚOVÆ0{y·oibÌPþxH¢wzá~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È¡H0ɼ¡¢²`dÉA/K$Qarþ>¯<éõçYRÔÝ×it»ÙMÓ®»¶ëºIW,.üüÌ<ê¼»^DÛd6¦¢mdÕKf¥Jlêõ~SÇ:AIXÂDQ"'³`³Ïp&*ܳÌV¬%"ô£ãᪧaþ´¿åíÔ
eÇì2;ÅÐÖz}¾»ûþEaî¼Ù]¤PÍ ¾YKÀd[¤- `Äo«<(Ï#%鬮ұ¯>pú@µ°t#$غqµr)»,°ÔäsÆë\l^=ÔÅ°õh`Æ¿i§è!4C-+Û£§ftðü1ðOÌÝ*Ïï*íq¯¸dg±Ñ·uaÚ7í}ì6I)µµÑ®tØ~{<Ü<ÕøVGà'®Ë4DITLÖÏ9ݦó¸ÖbJÓ%6]ºÜÍ2¬Fe´¦ÃdÓJhÑNkçkWTW:îïyuJ¬m¼]LÙZfѪM%VÔQ¶ÜݤÔÒd²X^[i©jU&*JÔ-SMy7SY#%M¹ºF5´ËkË¡ðhcòî¢(¹ïÀ_ )Þ¥#$pÓÏÁ~ê¶èà
2ï,ßÔPx¯%%n]¬¾Æ
¹µ1A´U¢#$
s½ÀC?*,1W6 % ðÞÒÚl´AKk3ZedmJ#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é WCN£ÇA5ïÚu(|ÈaÚ PQJI²Å¤Ã)#$¢áöODÄAkØ>xçVgÖhI@\ÃBLIªæ¨6ºjíõ0#$je²@¤óBIG¬û»= g ÏçìøÅbÀåÞûyx¼Ýèka@=pôh"S3ªáÖ0Xª"ÐUFß#%d´USº %¡Cn1JCPUï&RàhxÚd#!YøYF4©c"Ni"T!1æsãÜ O@ 0!rª°xØ[XA4=Ú/~hö§¢ ûM®ip«.$QhDÞ±ÙnªTÄäà(v½@>õ)ÃJ;ïOKÓ¿]GÔ%ÕµÔ6±T`î"kkyª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·- 9HSyR¦fÆpÊTzmFÛsÀÑuië¶á[cA½RGêS·_ª7$t9r~T¸×}V«][[cXk,ÐcÄ o5o9ë|ýï²}>êÒPù¿©«$BI'Îþb^ 2¶Vêóâ+LÔ¤Û4o{æú7çÎ{"<ÀÔ* Â#R¡ä]J\0õm:>êÈ¥ m¶àhE¬dJF(#$D:²Ñú½ú0#$²¨Â+£¤88MN@¦Y¹©{NÞÊïàçfC%Ïw7û¶VnF
ðÏVVñ]Ê-SGcA²FMÙ*è¥cÁeîáy§Mè|Ò¾\ómÝJô7-ÚleaLöLi¡´¦j$3$ XK¬cZÈÁÀcmAXU>@®AÉÐl ÷±6x$¦Íô(Dø¤¤EJeuÖ¢ÐÍîa~bðo-Ñ×amÛ+9$#$Y P)$0À÷ dfjD9Ʊ!ô@Qî1¹R[QQiK#%²gÜS*µón¤läØU'lZI\´ ìÁ×$Gà0Ò<XxMä¬Úö@ç[)>§ÓuSè*îäÕɢР`dÖ&E6.ÎÕ¨#$@a`IÏâ:;±ú4Gòm-Í¥½Ä@)5;¡#%Ä À ì6ß,ÜýÝ}7h¨¢!'(8Nu±Cy3_ÃYdï·¬s ¯_Å<O§ê¢×ÀÏ/ëÆ#%³|enÁ³»¡¦Äù°z¤Tk°(GðÄ@. ]>Ò#[@Áë°ó»`ÑÙòú0µÇGê5¸ÝüÁHëÓªHª(¡:Ð*HêQ6²¾³ÝòÆ©6ÆQ_TÞ;}ÅhÛz5$dfé®QÖåNÅ,?Ì`o§ÚÛè·Í¬äIjÈð3ÐáK½ÉõAáÔ Òý#Ãúhj5,Z¬RH»¼5K§¦®=q¯NhMXb`bNÈ!Çé´Ò).m{.oIÚ½M´k^ñi5O]¹b_ÐíÍkݶï]Qµr³»c{¶¬óÛͽf,cO.Ï\díçKÛÆñÌy=¹c4óºmÒ×-»"«£r¨CHk®Ý5×=õy³<n{5|)콨λWmÝE¬ãú÷½Ç¶nÁ Æd`ä#%µYüÁΰÇH1ý½¢,±VbÅ.ÉËSÛ?3cÓ@Éùñöï´Î®ibì.£BQE`,Kýp\0OÉ/Ëéz¡ËPwøB+Pzn²$mS+ ²U{[ÉúÒ¤fóKγ®4lÍsµÚÍ©·;EU3^5nj®´°"\1Hh¡jõúnh¦UOpÕ^ÛN¹Èx½ð'}¼,<Eë)=½µ#%¤(üwx×Ës®òwNºDÊ8ÌKM÷óõOaå5LÕ!ðEðÒ2SÛ
W4j 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#$ËHyR*y_¾ËFDË^ôM4¡^С0ô¦ï6x÷³ðëÌi±öú×_ ;RÙM¤e²ÒÔÔ6K`¬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î²2fÄi2Âk#%©cI0¨\ý;dDw#öÄLÅ{Ðû¢ ö}âÖdK {Ñ쨾?Y¬£JUFtö5d}¶6Øàl2Õ=@â¨p\ÄS_ÉVMV/ÏksPêPDü&$,+Õ¦ù8P¦¤"Äb¤QC2FK#%ÃH60¢);Ãå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Ä:ÏÊNF%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®NFcÞÉÁºnæɱèt1ýîi815gAï^j7gÃiéÏ9ÕR"ý V\ÁtÅ¢£kéùÉ6àmrÉeNª#%[*
TEÅ8apê`lDË]%Ýà-?ôG·ËFw¥):¡i F(J(d»ç/Ý#$P½½@(ÕÍÖ!¸ö±ÍÓ]?¶}ZÎÑ<üpÖê¢Óh>± )7º5É1>íȾÃÁ䮨õÓÁDe¢Qx·I©´s]f²©,jű¶ËCk¹Ü±S»¶!Dh!@NtÀl 2Ba*Êü¨$6`Xà "¸#% °¤Qü1e¶g&$XØw¦)\¬#$¶ÄÉ#j Ñ8Ý<E½wÝÝÝs\õ(RD4Û*¢a6 AÖ¶àèÀÉâ¹®{ÎhJçs»î®Ï;TÚÃìPº405LX¬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Ï°3K×ôÐà¨1Jå¯60âHt(h³]WÌøcÿËÖX¨Rûþ}WrÕò{²hÀi8Zi¹Ù;«tÛ×W*\Õ$T`(¬Ïá¡SÄÌ~˹ø7ÛÂZq|
ͳ {1§·Ät/ÖåêðLPÊØ¢w´Dø$¸õn#%ܸË3Z·´¯P I.±?·°ÞØ[Â5ÄãN.Gm$*@Õz_¥éì%cw{& tBw#®$v+¶»ëÒM³yB}.ç¸ )},
d=&KÕ¡ö9äwPB#%H#*ai`Ðd#%¶óM©-RójTÒ¼{Ù"*z·vÏ ¨#%àvÂóÇq÷&lâ^øåÚEv&õʧPà .RCl2<Ù_¹çÌ®ÊÃk!Ý9JÈJB¿ä4Þü-~J#%ËËOrmê" zO:ÞÁ/î-¡}.´#%H#%F, Àî5ó¢ªESc6C¶µÛÑiT|(qB?>Eûgùÿáúkù2ã @Ò;¡Ù¾+ x.é¶gqcy2[sêwD7Yµ bí=â|;8»Ç×Ûaf´ÚÄÅÉ6ò=Xß*¥äwfL·C3Rcª·¢2Æè`#$Ê#%ó>d"lÝÏuNY3pöØwã»@4>î\\ÀP"«Ì¨ÝC3UÄÚ¹(#$Õ`Âü´ÍìÍ&øïmýÙ¹¬ÌD/äþÇï£Ìì AíEºíú(sî3 !$;¡¶¹mJ*V*R¶Ñ¶¬Tk)l¤©«RhÛi5kòÏÌl÷ø°RXÝàk)ï3Ôv]Ø ñî[Îʤ°«¡
º&J}QYJì7jm%j´`}].ãï}õâ¢7¿#$ݸ»uZòªÜ
L³´ØáÆ÷¸ÃmG]ç¨;à4ÙyZNÜE}ºé·?=® #$iËi"¤:0¨¢A¢ [¢R2¾)¬÷X#$ÂïrبÂf·ùùCDCAU)Uóï;è)¾%÷nü#XÎt£´äå³h@¯¨ÀôÔî`e®Üαê÷ÌCgÎÖÙ#%eVèÖlzHcÃM˯öN àaþåU l´Èã"ü]¼ØáR³ZjÒol£Zpno"ÅÆA¤Ókm¼¡ qB´afT86A°´Ti#$°u¸¨ò°:
WSQ:]غ¶¯TÏ:å¬Ón¹uÓ% -srñ±CTÔª#%néÖ»FCFË6ÆRÒhF°°³Rk®êd®°ÆFWö½uzoS%ìÁI
d°£/$`ÊÛhfnîD1ZmÎk Ã1
"A¼Â*æòõzy²FظfÆêµ?}èO
C7ãÈVÛºê[\ÓM(T©XVYu ÛI#$J
;cCbÈDf¤¡ Á¶b 0fëѨBÙuí¼é¼\!èôÑÞǽ%m¬ZQk&8ÖkHÖ5lË᪠|CÚV<Z OUy#%7eFrªÅÆ«ê©Ñ¡æ^§ÌÀ7\«X4K#%\ío0ÄdûÄ
ºþ½(ÒIyÜG»ÃQ¹'ÈyÉ#AF4 Ñ'^(ð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ç9p&z9h{#¨íÚ>jëjÂ5z|YüÎήRÝÌ·@[9»òG¾ÉÑ´daÄßÐc¿¹î|òe.÷¦®è/éé±5¤þZEb¼îðýøyÏXFgÙ809280£ÖCr*Õ¼ëHYÔÛße9J#$'èÒ¿¶O°I1c¥PÅu±pú´K*ÕÂ+(µ¤W-Ó5uÛk%®Ø#$¼¯l5%[¥k{«x¯tÎZýsXôÊÆ Ön-i¨¸bï±»sÍJkE©©Fi-kA4¥½dº·¨Â)uSq¥`ÆPöÆÀÅBã6%hª¢¥HÉed
Hd²ZÒHFÖ-IFÍ´mQdm©©~m}=¸K&·,Và´ãFFDV"± ¤ê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#% «DX#$0qdF%¥%4@_½ê"aÞ÷ ð}zFH²*#%Öø(þé!#Æ#%c_¤ôxr#$O£Ý
¾±½6>¯ôø``ÿÃL»üúþóà|¯yQ¬0¦Äph£`îE<7îÝ_tF1Q}ö£À
Kµcfæª÷XäÒ+DG@ùãéõLà/Q#úoôô2>Þ@»+Þ`/KëÁ¥?r̨Or² H[Ô}Ú?qL2IR¦ü=¯3Ey<îmì×1 7*Në¬\·nºu©«bÚ¥RbQ$H@¥¸%uÝUþ¦ wÔÞ;9÷Ø6ãÍ H È?ª PR«ò#¯É0Tè>¡*¢H½qd VÞ<#%û<<|Øãöa¬RüC·`1$=ÂQ+ Ê-Bô¾Qmb6¶f+W_忶X¬WÓMÒÒ[×^i,XLJ7ÔÕ}öMkÞï[5"ûÝRªa [bÕ·S@° d¢B0 "jÈ£3óê}®,bM¿ys(Fð/ TGyø̸¨rI ÅÜAç¶gñ]¥uC Q3@¥ÄH1tí:²À£ð Fñcß|ýxZ¾¬¿AvHùãÌJ0C8âGhïòæm+ï¾¾?LZ* 0û#À°â'Ò*Z¢¿ATK N?S|.w¬|uÃØCÇPþòOárÖ6Pe¨È,ÑÛ«hñÓj+wwØkÆÒòigW m°lfìQ¬çEZÇ(#$ÈÐب¡Z[Ý0ß÷3=Îj5°Ú@8n)Zý²]l)@°Ä! @â¤À0Ñj±Q¯ÔéÙ³¸C0À,¯6
·_c5Þ2S@Ò²B¡^ø¶{¥Ø
-9b²ß?ÔÅ&lM[¸ÃÌ \ÂH|úø ¡~T_ÛñíT
?«XÝPÛ3ÁZ¬¢sOØÌ"í¸¹ÝÉCªí.nmêòÞ.[¥â»/¼íÔÐiø]0P¶»r8R[CRR3\ØÃ-<qÙßy&ÃJ+öD#%D)´O4|@Ö`¿M½íE$ETE6%#%nq#$¸6|||#ùt×ã»mí[>FÔë=÷u¾¤úB2Øw](fG·ùàÙçÈ%sdYzác®Õ`XK}zoR¼ª$0²*«#%bäÀæ*hüãà©!\HÓC}0Í¢=:qq!Ç÷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ÈãgiüHNÍÌç/'?Fúª)g²
L^¨E ÇgK{d¹ÔÖà! >!«¨ÁaLñû8q{éE1äS&që|´*<>úùö-?®ä&RHvкÜ=ÞßF®WsɲÓ1·S'U3 ó¢vÍ6KH,"AZÛKXTqèÖ¶êë:¼Ñ¦Ï%3 Mi#$)}ð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«çÕø+lDºr/¨§L$$#%]þí¦}.:;m{ Jå<Ѻá»h,Ê? ¹)ÅNÞ+Laé©â, áϵ¯!±®Àß{e}áPx&2éÒ2(Md#%½B&!h÷'Ùò+y&ª
Æýï -5;>¨#*'EN3°|#$!¡±Ù|Én¦¯L&û·n'§\ø2ùU¢$m´6ã>Gq°ßÂÔáQ¼+?|¸!Ú&Pq01mD´ÔÍf¡TÓ%2jÍË23k6fÕï_o_½¯ªÓA4(òIÓ!²(1IJHH"Îÿ \
ª ØÂ$N'¡ûÞA=#ËÓÜEôÂ`ÌÖ=ôØýNtLÃéýGÝÒÛGùZ; !{ÆY6»ô3ÆÔc¥ãÝÚ³¼V¯Â:ÒNº PÇ#%»ÉñÑ=n#%ÌÈL(Ð÷$¯.#·C2FPþ³-&Mñ[¶ö[«±Ð_vÕ2éPU.ÈKaLh¼ØÒXÂ*#¨1*«²ðÙ
ó]¿vq1ݳ¼2^ÞQ]ÄrÊ6N7Éx!t4n¢sâ û¾N¹¯}S{1tÛ®Û×wcÓsQ4Ë]LIèiâ0Ô¨IYT,FØÒi¦A]AhLÆÓÁÄæ@aIdl¶Îó®U\g]wòÕå14e¸Ô°MŦ`ÏZ`×szÎCqvÐkÛßïéèÖyÄ\kyMêîkRþ9M#$>¯Ï7ZëÖSÜ\õ§#$ÔåÈK$î¬ó"rÊïCoöM¨Ñ/ÆtåLÐb Í"³$L3ÒÃ@¶Ó5 kµ¸É½ÝèÅPZ]µDZN9®=w¸9ãÒ9xŲH#ozÝ¥ÅÒ(±¶«°YÅѵ@䢦ÌÄe³ñË'Ðh¸PPn¦ÈòbtánFÖÉÖQî]MèíÆ<0`¸%ýNϸ1¬éHB1ª[2°Õ¯GqÆ6\ ä$³ZhØÈ
,ZR0ÔS 3)PÛBØTÒ#%$ËÀÐ@ÆÚc4ä/µ~ó4#%ÛÂ
em·$¨m&HÆ¥¶¶ÊºÒgw$¸ÒÕ¾Z¯áT
f¥|ݧgÄ$_KkÖ®ô#±×òÆÝ a·Rduà£àÞÊðdVAi ×Eà1ìàÔµ%Ù«¯wW7u¹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*Ü¡Ê(>F4pèí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 wD ¸ Þ²¸·(hß¿dÝÏ#$¬E5ªAO!P~U%Ë
Û[êªHÅ U(r âbá@ª#%ÒHY5ÚÒÀëD£#%m(LìÝGÖÐAËÞ(â(âí<Ôí! $#¦Å@OFóý1@S`ùõú>³¶ýµ±j:u¢D2$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]e9KqÚ>¯û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*æNKF¯lÚHõïÎÌô÷vÑ®4Ä^^X|ùeÜ/ÅÛ]
î,ÙfïÃR´Y!´ÔÑWS¡B¼ª¹ýt¯n'¦£¼/e¥÷Å¢|vÞuË4wáH Õ]òµx¥.gB.V÷ÔCtÌSGîz [Qy$Â\%íéáÉ,;íH¤^ï`NPìþÐw.Ï®¬×\èÁw-2õÌÝWï5Å·³©u¸¥2öÇ_#%íØÉf=Íe=ÇÁêHów
Z;ClöÅ]½Øß¾í
ö+¨#$p±x*'Ãh]ÎBy©%y5&lâ¹³Ù]Ól¶òÅè|)u ¶1qg:¡ÕpD§Hãnoµð¯N¼Ságæ§ñÁ;v¦H×Ï#fÛô!<æHê8¹
>¹gæXæãêSlËc²Ñ;j|¶Ã¦ ÝüâêlkàI¯nò6Ť)7 îP<^9¨VÜõÖ¶§PâLèuÚºÃKxè\g3sGq»má&J9#$k2ͬ QL4ybyÍYÚX÷áîë°Äõßr[
Ì6Ñ03èö>òͨq$)hNE¥Û Ók"È(`Û Qa×Âbf£[²`#$Xñ-í
N&F½xóŽ¬ÄM*ü߬#%9º{± ¶ýöt5oâVj7A IÅr®¹¾æi°®¶Ú.«'ͪzæÕnHZYÚÍÉ(7`ããjß8:½á±µ"ÖmæÝû:Dtܳ¹®b1ÌEèº|3>ÜDa8-k˾0Dô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Á¶DVÐX¬lmÑYtµízªíKÈuˬ۰çßCÍîkaÌÊ,¡áH³gò8ÏÍFÎ8+°Í¬J¥>É8ÂÉQ3Æ6×ëx#$¸=8éÒÓÏdåó©®y¼bfXÜã"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àQ3o¤Áç¼Ã¡p9ÕWAâÆ6ÇGB0¦À\ZÅ©<ZÃPÌ*²Ìì&µE¥hâ¹#$À˺ WºLÓÑÂ3 å#èë0]¨gÝ4o£Ç#$.1=¾p5ÀâjãµFµZÖßWÕ#& Â(¬U,*"cÇôméDÞÎ{,2£!FNrÒisÁ¾7µ´µ±¢anJ¯.og7ß5Z¨5ê_bkuí÷#$¡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ÒaYlZl[¤fHµQ¢K![Vú/èójß*¶q!o§NîËu9í·_X¹×Û/2#ÀÄI%QUzç²îZÐCÎÑÍæjPtH
Èúé%áÀnqÏU£Fq&NhÔDÍ!}&géj+JR~lãMÝ&RÔ& <Þ~Ò¶¯³5¥5Ô´
Y¤"±_ ÈòÃê<¶UîTsÒ÷:Æôï±BáUhôPª;kBh"RÃd¨#%En²a1áña¡µ´5Ì(uM,3Wy @¡ú@!0]qØLþßhÉm«(
Ú¥=4i='½ÃEµO¯³îTCÙââѶ^¬Lð¼ªZMDŲ¸Àô#%lZÎ4·Ô[êÖ¬Pñb¡>[ pÁ2b#>>ÿF½N#iOdâCú#$#$½ÂÅ~48?ç$=¡É^ªÙY&=Ý ü}¯lg`}B4E®Ø-Öp¯ (ø.fN,M®iJ3(; ÄÒ-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í$Ò °: þç©XUGÏL0!ˬY*ª*µw¼= 轫öÃíj°?¦åýÖë,Nk>tÍyü¯Ý®)ì_»C2âmR¯OÅ.2gK¬T=o»XòüsD¨ÀÕPV"UQB6ÀiIÂ6×d,5MM 7R¦¦GÍÞÍé·¡dXY rðËÆà%Úb8TJø^æÎZêÚás(XÒêR]¥ï!»òR¤l ·rÄ#$α9£ËO¿c¸
Ýå6à®qÌ#$(¢^11ɧÓZ}7·yT"çdõñï)4Í=jYÎFyoàívþ2¤´¯ºÚݤy,²=Ñ»ÛhÛ}ø®&[0ÃX7×0Ç㪠ªi£0qæÌz[5n£öxî-GMë¾8·ÜwVÖ1p@-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¼Å¯"?ñ|Y1I^ÏÆðr3ïbv êoÅófÛºª´=Û=°Ë8ÓEq³M<©+Ú*ꬴw¬F¨æYåZqжÓ:.Ã]3âÓvN;»¦¡GN kÄô¹,×i'Õ¨¡ãh+Ec±´9yé
F9jѬËzç¿c×`cxÔè(lkÔ«UD8¦ã+a<)¾\ì]¶ð62¯ks#$îëp_w¡¶ÇÃÃéT^±`ES1È )ßÀ«ãHÑ.ÈZ^¶ú>eVsûh#%8¦D:§<vÅjm*2QHh2(&4\Ðö
Qt6[#%èN®3TÑlÒf "@ØâhdÁa Ü°PELR!träq¸KThr!´ÒÃza§íè=áÀ`ÈmJͤ´È»° ôû{4øj{f>V#)Mjí=t\x·÷t(æÔ"¨ÈfHæÀ}×G^¿YìÁð¹ªcJ+ñW2»êòæb}fakÑðÝFðrÛáK~S+B7É*¨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]KIv
²Å¤Á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øö\»ÛÙ÷¦xkSB$ÊJ.¡M@` `½¨ª¥ e öÖÆ1åA#=áR5×ËËÔôÓê94Æת|BÝÛ$>hQ1Ø!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òÄvHE"AÌHà9ÇpjFEJzJuÚ--$^ú¬|ìò|h¤ô¦ê"~s-|0¦òÚôUØÇ#$¦:¾ôoFâ+9pÔ#Ag<L%¥¶iéÞuB´£|r]çE
nXOQN®ø@{lBÅÒôX·îbGmÒ`BYRÆ öuKºÃÑû¥Q~´·ab¡¬Ýب °\X:Ã×$]ÆéSJ+ÈwZç´Äéê!Ã[ÅQDdÆk7`2fq/§Q%ïÚÝ¥\µ\hPÖ¤#$0Ëämö5óimkobÔ'TÁ¯Ys:8y:}HûzÀ]Iü[Td *5'u;|/7d®rvõæׯHI¤Í/Wv7S4F at R2îÔ=êäÌ ~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Ùñ`ÚXfø´ÈGóBÉ.çÑD qH ¾´Uí+òÛy«I)³Ê ¡iý1V1WÂùºöíózm/éõqR?c08©·MÓ ÍÜGò¤$Xÿ¯ë¤
UQR e"4$¦åÖ5£nîd±;«0Ha?%Í-Qi#%A§%á\G·~YI1Oä# ]DR.ªó×B½ðCæ½bï xÐ &S(Åù:ּÑ[\Æ·yÅ%çv½Õ¹n\~ª)¹õ1 sºP¹b¬Cd0Xio¥ìVÕkÔLîf z%XæjZUé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ÝIFI=U#$N ¬`{ªZêÓ^è«,-#èfü¼qÚÐÎdÝÓ¶S
!jlØÀ|`ø5#%ëJ©}
u¤8´ì`<åËTfÊJª3È®¯º¹UG¹ÃÓðwG§ÖTÒÇ$oâf-JCMòx5ENÿßðñ¶[2±fG.ú>x
Käp_WÑõÉÌNhcéÔwØümÙn"C¦Y±8Þ&rÌÄóë>eùûVû]áÒj:ʲ#ÊÜÍë(t8hx?1aI³¿Ñós7ýl8z!Íà=øÒ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 hxçþÍv¯d (g`r<7ôÑY;l7 ôÐ$DY®²Æ»]«J©l\i#%gÒvaYt﬽H v@çgõ¶ö5v¼Á¿©\0¨{³`XßÆ»ÛÁùp¹QéÔ9'¼Vòû{ÃÃ&g_ëA"# #$#$*Ø#Hÿ¯KÖ¯zWéV[
|jj¯Ô³EBF@X_CqYè©úeGøøȱ¿?ôsv×uoºjfæ=ç:ªdddiÅÃ<¢#$¤á¡ûÙxÂRÍÖ>]ÝÑãEx#$9`LYãD³?¢øÞjÖe#$z:à0 k#Pß#$LrMU`¦E/]d%ûÐ?Y¬¡0R SÞDNFI at 8uÄ̽Ó(¢|û)S×½ ¼öm?¶HH)Âj·¾«ëë5FLÙÅ¿½¸ûu#%ò!$ AèÒàO=`¯À¯«ÇÇ`߶(ê,÷.sà}Ê_ÛkØ`ª©«þ¿Ó>Pÿ¯ú¹ÈÏìéjîãóõ×aû ÕfPa4xzÐÒ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