[Goodies-commits] r6418 - in xfce4-clipman-plugin/branches/xfce-4-6: . panel-plugin po

Mike Massonnet mmassonnet at xfce.org
Fri Jan 9 01:28:20 CET 2009


Author: mmassonnet
Date: 2009-01-09 00:28:20 +0000 (Fri, 09 Jan 2009)
New Revision: 6418

Added:
   xfce4-clipman-plugin/branches/xfce-4-6/AUTHORS
   xfce4-clipman-plugin/branches/xfce-4-6/COPYING
   xfce4-clipman-plugin/branches/xfce-4-6/ChangeLog
   xfce4-clipman-plugin/branches/xfce-4-6/Makefile.am
   xfce4-clipman-plugin/branches/xfce-4-6/NEWS
   xfce4-clipman-plugin/branches/xfce-4-6/README
   xfce4-clipman-plugin/branches/xfce-4-6/TODO
   xfce4-clipman-plugin/branches/xfce-4-6/autogen.sh
   xfce4-clipman-plugin/branches/xfce-4-6/configure.ac.in
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/Makefile.am
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.c
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.h
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.c
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.h
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.c
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.h
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/panel-plugin.c
   xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/xfce4-clipman-plugin.desktop.in.in
   xfce4-clipman-plugin/branches/xfce-4-6/po/
   xfce4-clipman-plugin/branches/xfce-4-6/po/ChangeLog
   xfce4-clipman-plugin/branches/xfce-4-6/po/LINGUAS
   xfce4-clipman-plugin/branches/xfce-4-6/po/POTFILES.in
   xfce4-clipman-plugin/branches/xfce-4-6/po/POTFILES.skip
Log:
Major rewrite of the plugin using GObjects and Xfconf.file:///dev/shm/branches/xfce-4-6/ChangeLog

Added: xfce4-clipman-plugin/branches/xfce-4-6/AUTHORS
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/AUTHORS	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/AUTHORS	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,3 @@
+Eduard Roccatello <eduard at xfce.org>
+Nick Schermer <nick at xfce.org>
+Mike Massonnet <mmassonnet at xfce.org>

Added: xfce4-clipman-plugin/branches/xfce-4-6/COPYING
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/COPYING	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/COPYING	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, 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 Lesser 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 Street, 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 Lesser General
+Public License instead of this License.

Added: xfce4-clipman-plugin/branches/xfce-4-6/ChangeLog
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/ChangeLog	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/ChangeLog	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,9 @@
+2009-01-09	Mike Massonnet
+Major rewrite of the plugin using GObjects and Xfconf.
+
+	- The plugin now uses GObjects with properties binded to Xfconf for easy
+	configuration.
+	- The plugin is able to store texts and images.
+	- The changes over the clipboards are noticed with signals and no more
+	a timeout which saves a lot of CPU wakeups.
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/Makefile.am
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/Makefile.am	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/Makefile.am	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,41 @@
+NULL = 
+
+SUBDIRS =								\
+	panel-plugin							\
+	po								\
+	$(NULL)
+
+distclean-local:
+	rm -rf *.cache *~
+
+EXTRA_DIST =								\
+	AUTHORS								\
+	ChangeLog							\
+	COPYING								\
+	INSTALL								\
+	NEWS								\
+	README								\
+	intltool-extract.in						\
+	intltool-merge.in						\
+	intltool-update.in						\
+	$(NULL)
+
+DISTCLEANFILES =							\
+	aclocal.m4							\
+	compile								\
+	config.guess							\
+	config.h.in							\
+	config.sub							\
+	configure							\
+	configure.ac							\
+	depcomp								\
+	install-sh							\
+	ltmain.sh							\
+	missing								\
+	mkinstalldirs							\
+	intltool-extract						\
+	intltool-merge							\
+	intltool-update							\
+	$(NULL)
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Added: xfce4-clipman-plugin/branches/xfce-4-6/NEWS
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/NEWS	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/NEWS	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,9 @@
+Version 1.0.0 - 2009-xx-xx
+
+Major rewrite of the plugin, using GObjects and Xfconf.
+
+Version 0.9.0 - 2009-xx-xx
+
+A rewrite to make it more user-friendly and introduce image support.  Work done
+by David Collins.
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/README
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/README	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/README	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,42 @@
+ Xfce4-clipman-plugin
+======================
+
+A simple clipboard history for the Xfce4 Panel.
+
+
+ Homepage
+----------
+
+http://goodies.xfce.org/projects/panel-plugins/xfce4-clipman-plugin/
+
+
+ Dependencies
+--------------
+
+* glib-2.0 2.16
+* gtk+-2.0 2.12
+* exo-0.3 0.3.0
+* libxfce4util 4.4.0
+* libxfcegui4 4.4.0
+* xfconf 4.5.92
+
+
+ Install
+---------
+
+% tar xf xfce4-clipman-plugin-<version>.tar.bz2
+% ./configure
+% make
+% make install
+
+See the INSTALL file for more instructions.
+
+
+ Report bugs
+-------------
+You can report bugs and feature requests at http://bugs.xfce.org.  Choose the
+product Xfce Panel Plugins and the component clipman.
+
+You can also join the Xfce Goodies mailing-list:
+http://foo-projects.org/mailman/listinfo/goodies-dev.
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/TODO
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/TODO	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/TODO	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,3 @@
+- Store the history
+- Add a properties dialog
+- Add actions

Added: xfce4-clipman-plugin/branches/xfce-4-6/autogen.sh
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/autogen.sh	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/autogen.sh	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# $Id: autogen.sh 23241 2006-09-29 19:05:15Z kelnos $
+#
+# Copyright (c) 2002-2005
+#         The Xfce development team. All rights reserved.
+#
+# Written for Xfce by Benedikt Meurer <benny at xfce.org>.
+#
+
+(type xdt-autogen) >/dev/null 2>&1 || {
+  cat >&2 <<EOF
+autogen.sh: You don't seem to have the Xfce development tools installed on
+            your system, which are required to build this software.
+            Please install the xfce4-dev-tools package first, available from
+            http://xfce.org/~benny/projects/xfce4-dev-tools/.
+EOF
+  exit 1
+}
+
+# verify that po/LINGUAS is present
+(test -f po/LINGUAS) >/dev/null 2>&1 || {
+  cat >&2 <<EOF
+autogen.sh: The file po/LINGUAS could not be found. Please check your snapshot
+            or try to checkout again.
+EOF
+  exit 1
+}
+
+echo 'dnl *** This file is automatically generated from configure.ac.in ***' \
+    >configure.ac
+echo 'dnl *** DO NOT EDIT! ***' >>configure.ac
+echo >>configure.ac
+
+# substitute revision and linguas
+linguas=$(sed -e '/^#/d' po/LINGUAS)
+if [ -d .git/svn ]; then
+    revision=$(git svn find-rev trunk 2>/dev/null ||
+               git svn find-rev origin/trunk 2>/dev/null ||
+               git svn find-rev HEAD 2>/dev/null ||
+               git svn find-rev master 2>/dev/null)
+elif [ -d .svn ]; then
+    revision=$(LC_ALL=C svn info $0 | awk '/^Revision: / {printf "%05d\n", $2}')
+else
+    revision=UNKNOWN
+fi
+sed -e "s/@LINGUAS@/${linguas}/g" \
+    -e "s/@REVISION@/${revision}/g" \
+    < "configure.ac.in" >> "configure.ac"
+
+xdt-autogen $@
+
+# vi:set ts=2 sw=2 et ai:


Property changes on: xfce4-clipman-plugin/branches/xfce-4-6/autogen.sh
___________________________________________________________________
Added: svn:executable
   + *

Added: xfce4-clipman-plugin/branches/xfce-4-6/configure.ac.in
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/configure.ac.in	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/configure.ac.in	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,94 @@
+dnl $Id$
+dnl
+dnl Clipman plugin - Clipboards manager for the Xfce4 panel
+dnl
+dnl 2005      Eduard Roccatello <eduard at xfce.org>
+dnl 2006-2007 Nick Schermer <nick at xfce.org>
+dnl 2008-2009 Mike Massonnet <mmassonnet at xfce.org>
+dnl
+
+dnl ***************************
+dnl *** Version information ***
+dnl ***************************
+m4_define([project_version_major], [1])
+m4_define([project_version_minor], [0])
+m4_define([project_version_micro], [0])
+m4_define([project_version_build], [r at REVISION@])
+m4_define([project_version_tag], [svn]) # leave empty for release
+m4_define([project_version], [project_version_major().project_version_minor().project_version_micro()ifelse(project_version_tag(), [svn], [project_version_tag()-project_version_build()], [project_version_tag()])])
+
+dnl ***************************
+dnl *** Initialize autoconf ***
+dnl ***************************
+AC_COPYRIGHT([Copyright (c) 2005-2009
+        The Xfce development team. All rights reserved.])
+AC_INIT([xfce4-clipman-plugin], [project_version], [http://bugzilla.xfce.org/], [xfce4-clipman-plugin])
+AC_PREREQ([2.50])
+AC_CANONICAL_TARGET()
+AC_REVISION([project_version_build])
+
+dnl ***************************
+dnl *** Initialize automake ***
+dnl ***************************
+AM_INIT_AUTOMAKE([1.8 dist-bzip2 tar-ustar])
+AM_CONFIG_HEADER([config.h])
+AM_MAINTAINER_MODE()
+
+dnl ********************************
+dnl *** Check for basic programs ***
+dnl ********************************
+AC_PROG_CC()
+AM_PROG_CC_C_O()
+AC_PROG_LD()
+AC_PROG_INSTALL()
+AC_PROG_LIBTOOL()
+AC_PROG_INTLTOOL()
+
+dnl **********************************
+dnl *** Check for standard headers ***
+dnl **********************************
+AC_HEADER_STDC()
+
+dnl *******************************
+dnl *** Check for X11 installed ***
+dnl *******************************
+XDT_CHECK_LIBX11_REQUIRE()
+
+dnl ***********************************
+dnl *** Check for required packages ***
+dnl ***********************************
+XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.12.0])
+XDT_CHECK_PACKAGE([EXO], [exo-0.3], [0.3.0])
+XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
+XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.4.0])
+XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.4.0])
+XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.5.92])
+
+dnl ******************************
+dnl *** Check for i18n support ***
+dnl ******************************
+XDT_I18N([@LINGUAS@])
+
+dnl ***********************************
+dnl *** Check for debugging support ***
+dnl ***********************************
+XDT_FEATURE_DEBUG()
+
+dnl ************************
+dnl *** Makefile outputs ***
+dnl ************************
+AC_OUTPUT([
+Makefile
+panel-plugin/Makefile
+po/Makefile.in
+])
+
+dnl ***************************
+dnl *** Print configuration ***
+dnl ***************************
+echo
+echo "Build Configuration:"
+echo
+echo "* Debug Support:    $enable_debug"
+echo
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/Makefile.am
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/Makefile.am	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/Makefile.am	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,52 @@
+NULL = 
+
+INCLUDES =								\
+	-I${top_srcdir}							\
+	-DDATADIR=\"$(datadir)\"					\
+	-DSRCDIR=\"$(top_srcdir)\"					\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
+	-DLOCALEDIR=\"$(localedir)\"					\
+	$(NULL)
+
+plugindir = $(libexecdir)/xfce4/panel-plugins
+plugin_PROGRAMS = xfce4-clipman-plugin
+
+xfce4_clipman_plugin_SOURCES =						\
+	panel-plugin.c							\
+	collector.c			collector.h			\
+	history.c			history.h			\
+	menu.c				menu.h				\
+	$(NULL)
+
+xfce4_clipman_plugin_CFLAGS =						\
+	@GTK_CFLAGS@							\
+	@EXO_CFLAGS@							\
+	@LIBXFCE4UTIL_CFLAGS@						\
+	@LIBXFCEGUI4_CFLAGS@						\
+	@LIBXFCE4PANEL_CFLAGS@						\
+	@XFCONF_CFLAGS@							\
+	$(NULL)
+
+xfce4_clipman_plugin_LDADD =						\
+	@GTK_LIBS@							\
+	@EXO_LIBS@							\
+	@LIBXFCE4UTIL_LIBS@						\
+	@LIBXFCEGUI4_LIBS@						\
+	@LIBXFCE4PANEL_LIBS@						\
+	@XFCONF_LIBS@							\
+	$(NULL)
+
+desktopdir = $(datadir)/xfce4/panel-plugins
+desktop_in_in_files = xfce4-clipman-plugin.desktop.in.in
+desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+%.desktop.in: %.desktop.in.in
+	sed -e "s^@EXTERNAL_PLUGIN_PATH@^$(libexecdir)/xfce4/panel-plugins^" \
+		$< > $@
+
+CLEANFILES =								\
+	$(desktop_DATA)							\
+	$(NULL)
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.c
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.c	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.c	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,359 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <xfconf/xfconf.h>
+
+#include "history.h"
+
+#include "collector.h"
+
+/*
+ * GObject declarations
+ */
+
+G_DEFINE_TYPE (ClipmanCollector, clipman_collector, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLIPMAN_TYPE_COLLECTOR, ClipmanCollectorPrivate))
+
+struct _ClipmanCollectorPrivate
+{
+  ClipmanHistory       *history;
+  GtkClipboard         *default_clipboard;
+  GtkClipboard         *primary_clipboard;
+  guint                 primary_clipboard_timeout;
+  gboolean              ignore_primary_clipboard;
+  gboolean              restoring;
+};
+
+enum
+{
+  IGNORE_PRIMARY_CLIPBOARD = 1,
+};
+
+static void             clipman_collector_class_init        (ClipmanCollectorClass *klass);
+static void             clipman_collector_init              (ClipmanCollector *collector);
+static void             clipman_collector_constructed       (GObject *object);
+static void             clipman_collector_finalize          (GObject *object);
+static void             clipman_collector_set_property      (GObject *object,
+                                                             guint property_id,
+                                                             const GValue *value,
+                                                             GParamSpec *pspec);
+static void             clipman_collector_get_property      (GObject *object,
+                                                             guint property_id,
+                                                             GValue *value,
+                                                             GParamSpec *pspec);
+
+/*
+ * Private methods declarations
+ */
+
+static void            _clipman_collector_restore_clipboard (ClipmanCollector *collector,
+                                                             GtkClipboard *clipboard);
+
+/*
+ * Callbacks declarations
+ */
+
+static void             cb_clipboard_owner_change           (ClipmanCollector *collector,
+                                                             GdkEventOwnerChange *event);
+static gboolean         cb_check_primary_clipboard          (ClipmanCollector *collector);
+
+
+
+/*
+ * Callbacks
+ */
+
+static void
+cb_clipboard_owner_change (ClipmanCollector *collector,
+                           GdkEventOwnerChange *event)
+{
+  gboolean has_text;
+  gboolean has_image;
+  gchar *text;
+  GdkPixbuf *image;
+
+  /* Jump over if the content is set from within clipman */
+  if (collector->priv->restoring)
+    {
+      collector->priv->restoring = FALSE;
+      return;
+    }
+
+  /* Prevent the clipboard from getting empty */
+  if (event->reason == GDK_OWNER_CHANGE_DESTROY || event->reason == GDK_OWNER_CHANGE_CLOSE)
+    {
+      if (event->selection == GDK_SELECTION_CLIPBOARD)
+        {
+          DBG ("The default clipboard is empty");
+          _clipman_collector_restore_clipboard (collector, collector->priv->default_clipboard);
+        }
+      else if (event->selection == GDK_SELECTION_PRIMARY)
+        {
+          DBG ("The primary clipboard is empty");
+          /* This case is seldomly reached, the experience showed that it only
+           * happens when the application is properly quit through the menu
+           * (Ctrl+Q in general).  Most of the time the primary clipboard will
+           * be set empty ("") instead of being destroyed when the application
+           * closes (Alt+F4). */
+          if (!collector->priv->ignore_primary_clipboard)
+            _clipman_collector_restore_clipboard (collector, collector->priv->primary_clipboard);
+        }
+
+      return;
+    }
+
+  /* Save the clipboard content to ClipmanHistory */
+  if (event->selection == GDK_SELECTION_CLIPBOARD)
+    {
+      has_text = gtk_clipboard_wait_is_text_available (collector->priv->default_clipboard);
+      has_image = gtk_clipboard_wait_is_image_available (collector->priv->default_clipboard);
+
+      if (has_text)
+        {
+          text = gtk_clipboard_wait_for_text (collector->priv->default_clipboard);
+          if (text != NULL && text[0] != '\0')
+            clipman_history_add_text (collector->priv->history, text, collector->priv->default_clipboard);
+          g_free (text);
+        }
+      else if (has_image)
+        {
+          image = gtk_clipboard_wait_for_image (collector->priv->default_clipboard);
+          clipman_history_add_image (collector->priv->history, image, collector->priv->default_clipboard);
+          g_object_unref (image);
+        }
+    }
+  else if (event->selection == GDK_SELECTION_PRIMARY)
+    {
+      /* This clipboard is due to many changes while selecting, therefore we
+       * actually check inside a delayed timeout if the mouse is still pressed
+       * or if the shift key is hold down, and once both are released the
+       * content will go to the history. */
+      if (!collector->priv->ignore_primary_clipboard)
+        {
+          if (collector->priv->primary_clipboard_timeout == 0)
+            collector->priv->primary_clipboard_timeout =
+              g_timeout_add (500, (GSourceFunc)cb_check_primary_clipboard, collector);
+        }
+    }
+}
+
+static gboolean
+cb_check_primary_clipboard (ClipmanCollector *collector)
+{
+  GdkModifierType state;
+  gchar *text;
+
+  /* Postpone until the selection is done */
+  gdk_window_get_pointer (NULL, NULL, NULL, &state);
+  if (state & (GDK_BUTTON1_MASK|GDK_SHIFT_MASK))
+    return TRUE;
+
+  /* Copy the text to the history */
+  if (gtk_clipboard_wait_is_text_available (collector->priv->primary_clipboard))
+    {
+      text = gtk_clipboard_wait_for_text (collector->priv->primary_clipboard);
+      if (text != NULL && text[0] != '\0')
+        clipman_history_add_text (collector->priv->history, text, collector->priv->primary_clipboard);
+      g_free (text);
+    }
+  else
+    {
+      DBG ("The primary clipboard is empty");
+      _clipman_collector_restore_clipboard (collector, collector->priv->primary_clipboard);
+    }
+
+  collector->priv->primary_clipboard_timeout = 0;
+  return FALSE;
+}
+
+/*
+ * Private methods
+ */
+
+static void
+_clipman_collector_restore_clipboard (ClipmanCollector *collector,
+                                      GtkClipboard *clipboard)
+{
+  /* TODO See how to store the content in clipman, instead of trying to restore
+   * empty clipboards. */
+  const ClipmanHistoryItem *item;
+
+  DBG ("Restore the clipboard with the most recent content from ClipmanHistory");
+
+  collector->priv->restoring = TRUE;
+
+  item = clipman_history_get_item_to_restore (collector->priv->history);
+  switch (item->type)
+    {
+    case CLIPMAN_HISTORY_TYPE_TEXT:
+      gtk_clipboard_set_text (clipboard, item->content.text, -1);
+      break;
+
+    case CLIPMAN_HISTORY_TYPE_IMAGE:
+      gtk_clipboard_set_image (clipboard, item->content.image);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/*
+ * Public methods
+ */
+
+/**
+ * clipman_collector_set_is_restoring:
+ * @collector: a #ClipmanCollector
+ *
+ * Call this function before modifing the content of a #GtkClipboard so that
+ * the new content won't be looked by #ClipmanCollector.  Useful to prevent an
+ * image from being saved twice.  Note that for text this is useless because
+ * texts are compared, and a match throws the text in the history to the top of
+ * the list.
+ * See also clipman_history_set_item_to_restore().
+ */
+void
+clipman_collector_set_is_restoring (ClipmanCollector *collector)
+{
+  collector->priv->restoring = TRUE;
+}
+
+ClipmanCollector *
+clipman_collector_get ()
+{
+  static ClipmanCollector *singleton = NULL;
+
+  if (singleton == NULL)
+    {
+      singleton = g_object_new (CLIPMAN_TYPE_COLLECTOR, NULL);
+      g_object_add_weak_pointer (G_OBJECT (singleton), (gpointer)&singleton);
+    }
+  else
+    g_object_ref (G_OBJECT (singleton));
+
+  return singleton;
+}
+
+/*
+ * GObject
+ */
+
+static void
+clipman_collector_class_init (ClipmanCollectorClass *klass)
+{
+  GObjectClass *object_class;
+
+  g_type_class_add_private (klass, sizeof (ClipmanCollectorPrivate));
+
+  clipman_collector_parent_class = g_type_class_peek_parent (klass);
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->constructed = clipman_collector_constructed;
+  object_class->finalize = clipman_collector_finalize;
+  object_class->set_property = clipman_collector_set_property;
+  object_class->get_property = clipman_collector_get_property;
+
+  g_object_class_install_property (object_class, IGNORE_PRIMARY_CLIPBOARD,
+                                   g_param_spec_boolean ("ignore-primary-clipboard",
+                                                         "IgnorePrimaryClipboard",
+                                                         "Ignore the primary clipboard",
+                                                         TRUE,
+                                                         G_PARAM_CONSTRUCT|G_PARAM_READWRITE));
+}
+
+static void
+clipman_collector_init (ClipmanCollector *collector)
+{
+  collector->priv = GET_PRIVATE (collector);
+
+  /* This bit is set to TRUE when a clipboard has to be set from within clipman
+   * while avoiding to re-add it to the history. */
+  collector->priv->restoring = FALSE;
+
+  /* ClipmanHistory */
+  collector->priv->history = clipman_history_get ();
+
+  /* Clipboards */
+  collector->priv->default_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+  collector->priv->primary_clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+}
+
+static void
+clipman_collector_constructed (GObject *object)
+{
+  ClipmanCollector *collector = CLIPMAN_COLLECTOR (object);
+
+  g_signal_connect_swapped (collector->priv->default_clipboard, "owner-change",
+                            G_CALLBACK (cb_clipboard_owner_change), collector);
+  g_signal_connect_swapped (collector->priv->primary_clipboard, "owner-change",
+                            G_CALLBACK (cb_clipboard_owner_change), collector);
+}
+
+static void
+clipman_collector_finalize (GObject *object)
+{
+  ClipmanCollector *collector = CLIPMAN_COLLECTOR (object);
+  g_object_unref (collector->priv->history);
+}
+
+static void
+clipman_collector_set_property (GObject *object,
+                                guint property_id,
+                                const GValue *value,
+                                GParamSpec *pspec)
+{
+  ClipmanCollectorPrivate *priv = CLIPMAN_COLLECTOR (object)->priv;
+
+  switch (property_id)
+    {
+    case IGNORE_PRIMARY_CLIPBOARD:
+      priv->ignore_primary_clipboard = g_value_get_boolean (value);
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+clipman_collector_get_property (GObject *object,
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+  ClipmanCollectorPrivate *priv = CLIPMAN_COLLECTOR (object)->priv;
+
+  switch (property_id)
+    {
+    case IGNORE_PRIMARY_CLIPBOARD:
+      g_value_set_boolean (value, priv->ignore_primary_clipboard);
+      break;
+
+    default:
+      break;
+    }
+}
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.h
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.h	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/collector.h	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __CLIPMAN_COLLECTOR_H__
+#define __CLIPMAN_COLLECTOR_H__
+
+#include <glib-object.h>
+
+#define CLIPMAN_TYPE_COLLECTOR                  (clipman_collector_get_type())
+
+#define CLIPMAN_COLLECTOR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPMAN_TYPE_COLLECTOR, ClipmanCollector))
+#define CLIPMAN_COLLECTOR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), CLIPMAN_TYPE_COLLECTOR, ClipmanCollectorClass))
+
+#define CLIPMAN_IS_COLLECTOR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLIPMAN_TYPE_COLLECTOR))
+#define CLIPMAN_IS_COLLECTOR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), CLIPMAN_TYPE_COLLECTOR))
+
+#define CLIPMAN_COLLECTOR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), CLIPMAN_TYPE_COLLECTOR, ClipmanCollectorClass))
+
+typedef struct _ClipmanCollectorClass           ClipmanCollectorClass;
+typedef struct _ClipmanCollector                ClipmanCollector;
+typedef struct _ClipmanCollectorPrivate         ClipmanCollectorPrivate;
+
+struct _ClipmanCollectorClass
+{
+  GObjectClass              parent_class;
+};
+
+struct _ClipmanCollector
+{
+  GObject                   parent;
+
+  /* Private */
+  ClipmanCollectorPrivate  *priv;
+};
+
+GType                   clipman_collector_get_type              ();
+
+ClipmanCollector *      clipman_collector_get                   ();
+void                    clipman_collector_set_is_restoring      (ClipmanCollector *collector);
+
+#endif /* !__CLIPMAN_COLLECTOR_H__ */
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.c
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.c	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.c	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,446 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <exo/exo.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "history.h"
+
+/*
+ * GObject declarations
+ */
+
+G_DEFINE_TYPE (ClipmanHistory, clipman_history, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLIPMAN_TYPE_HISTORY, ClipmanHistoryPrivate))
+
+struct _ClipmanHistoryPrivate
+{
+  GSList               *texts;
+  GSList               *images;
+  guint                 max_texts_in_history;
+  guint                 max_images_in_history;
+  const ClipmanHistoryItem *item_to_restore;
+};
+
+enum
+{
+  MAX_TEXTS_IN_HISTORY = 1,
+  MAX_IMAGES_IN_HISTORY,
+};
+
+static void             clipman_history_class_init         (ClipmanHistoryClass *klass);
+static void             clipman_history_init               (ClipmanHistory *history);
+static void             clipman_history_finalize           (GObject *object);
+static void             clipman_history_set_property       (GObject *object,
+                                                            guint property_id,
+                                                            const GValue *value,
+                                                            GParamSpec *pspec);
+static void             clipman_history_get_property       (GObject *object,
+                                                            guint property_id,
+                                                            GValue *value,
+                                                            GParamSpec *pspec);
+
+/*
+ * Private methods declarations
+ */
+
+static void            _clipman_history_add_item           (ClipmanHistory *history,
+                                                            ClipmanHistoryItem *item);
+
+/*
+ * Misc functions declarations
+ */
+
+static void           __clipman_history_item_free          (ClipmanHistoryItem *item);
+static gint           __g_slist_compare_texts              (gconstpointer a,
+                                                            gconstpointer b);
+
+
+
+/*
+ * Private methods
+ */
+
+static void
+_clipman_history_add_item (ClipmanHistory *history,
+                           ClipmanHistoryItem *item)
+{
+  GSList *list, *last;
+  guint max_items;
+  guint list_length;
+
+  /* Pick up values */
+  switch (item->type)
+    {
+    case CLIPMAN_HISTORY_TYPE_TEXT:
+      list = history->priv->texts;
+      max_items = history->priv->max_texts_in_history;
+      break;
+
+    case CLIPMAN_HISTORY_TYPE_IMAGE:
+      list = history->priv->images;
+      max_items = history->priv->max_images_in_history;
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  /* Check if the history is full */
+  list_length = g_slist_length (list);
+  while (list_length >= max_items)
+    {
+      DBG ("Delete oldest content from the history");
+      last = g_slist_last (list);
+      __clipman_history_item_free (last->data);
+      list = g_slist_delete_link (list, last);
+      list_length--;
+    }
+
+  /* Add the new item to the history */
+  list = g_slist_prepend (list, item);
+  history->priv->item_to_restore = item;
+
+  /* Update list pointer in private data */
+  switch (item->type)
+    {
+    case CLIPMAN_HISTORY_TYPE_TEXT:
+      history->priv->texts = list;
+      break;
+
+    case CLIPMAN_HISTORY_TYPE_IMAGE:
+      history->priv->images = list;
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/*
+ * Misc functions
+ */
+
+static void
+__clipman_history_item_free (ClipmanHistoryItem *item)
+{
+  switch (item->type)
+    {
+    case CLIPMAN_HISTORY_TYPE_TEXT:
+      DBG ("Delete text `%s'", item->content.text);
+      g_free (item->content.text);
+      g_free (item->preview.text);
+      break;
+
+    case CLIPMAN_HISTORY_TYPE_IMAGE:
+      DBG ("Delete image (%p)", item->content.image);
+      g_object_unref (item->content.image);
+      g_object_unref (item->preview.image);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+  g_slice_free (ClipmanHistoryItem, item);
+}
+
+static gint
+__g_slist_compare_texts (gconstpointer a,
+                         gconstpointer b)
+{
+  const ClipmanHistoryItem *item = a;
+  const gchar *text = b;
+  return g_ascii_strcasecmp (item->content.text, text);
+}
+
+/*
+ * Public methods
+ */
+
+void
+clipman_history_add_text (ClipmanHistory *history,
+                          const gchar *text,
+                          GtkClipboard *clipboard)
+{
+  ClipmanHistoryItem *item;
+  gchar *tmp1, *tmp2;
+  const gchar *offset;
+  gint preview_length = 48;
+  GSList *list;
+
+  /* Search for a previously existing content */
+  list = g_slist_find_custom (history->priv->texts, text, (GCompareFunc)__g_slist_compare_texts);
+  if (list != NULL)
+    {
+      DBG ("Found a previous occurence for text `%s'", text);
+      __clipman_history_item_free (list->data);
+      history->priv->texts = g_slist_delete_link (history->priv->texts, list);
+    }
+
+  /* Store the text */
+  DBG ("Store text `%s' from clipboard (%p)", text, clipboard);
+
+  item = g_slice_new0 (ClipmanHistoryItem);
+  item->clipboard = clipboard;
+  item->type = CLIPMAN_HISTORY_TYPE_TEXT;
+  item->content.text = g_strdup (text);
+
+  /* Strip white spaces for preview */
+  tmp1 = g_strstrip (g_strdup (text));
+  while (g_strstr_len (tmp1, preview_length, "  "))
+    {
+      tmp2 = exo_str_replace (tmp1, "  ", " ");
+      g_free (tmp1);
+      tmp1 = tmp2;
+    }
+
+  /* Shorten preview */
+  if (g_utf8_strlen (tmp1, -1) > preview_length)
+    {
+      offset = g_utf8_offset_to_pointer (tmp1, preview_length);
+      tmp2 = g_strndup (tmp1, offset - tmp1);
+      g_free (tmp1);
+      tmp1 = g_strconcat (tmp2, "...", NULL);
+      g_free (tmp2);
+    }
+
+  /* Cleanup special characters from preview */
+  tmp2 = g_strdelimit (tmp1, "\n\r\t", ' ');
+  tmp1 = g_markup_escape_text (tmp2, -1);
+  g_free (tmp2);
+
+  /* Set preview */
+  item->preview.text = tmp1;
+
+  _clipman_history_add_item (history, item);
+}
+
+void
+clipman_history_add_image (ClipmanHistory *history,
+                           const GdkPixbuf *image,
+                           GtkClipboard *clipboard)
+{
+  ClipmanHistoryItem *item;
+
+  if (history->priv->max_images_in_history == 0)
+    return;
+
+  DBG ("Store image (%p) from clipboard (%p)", image, clipboard);
+
+  item = g_slice_new0 (ClipmanHistoryItem);
+  item->clipboard = clipboard;
+  item->type = CLIPMAN_HISTORY_TYPE_IMAGE;
+  item->content.image = gdk_pixbuf_copy (image);
+  item->preview.image = exo_gdk_pixbuf_scale_ratio (GDK_PIXBUF (image), 128);
+
+  DBG ("Copy of image (%p) is (%p)", image, item->content.image);
+
+  _clipman_history_add_item (history, item);
+}
+
+const GSList *
+clipman_history_get_texts (ClipmanHistory *history)
+{
+  return history->priv->texts;
+}
+
+const GSList *
+clipman_history_get_images (ClipmanHistory *history)
+{
+  return history->priv->images;
+}
+
+/**
+ * clipman_history_get_item_to_restore:
+ * @history: a #ClipmanHistory
+ *
+ * Returns the most recent item that has been added to #ClipmanHistory.
+ *
+ * Returns: a #const #ClipmanHistoryItem
+ */
+const ClipmanHistoryItem *
+clipman_history_get_item_to_restore (ClipmanHistory *history)
+{
+  return history->priv->item_to_restore;
+}
+
+/**
+ * clipman_history_set_item_to_restore:
+ * @history: a #ClipmanHistory
+ * @item: a #ClipmanHistoryItem that must exist inside #ClipmanHistory
+ *
+ * This function is used as a hack around the images as they cannot be
+ * compared.  Before setting the clipboard with an image, the #ClipmanCollector
+ * must be set as being restored with clipman_collector_set_is_restoring(),
+ * than this function is called with the item that contains the image that is
+ * getting restored.
+ * Instead of being destroyed/recreated inside the history, it will remain at
+ * the same position in the history (unlike being pushed to the top) but will
+ * be marked as being the most recent item in the history.
+ */
+void
+clipman_history_set_item_to_restore (ClipmanHistory *history,
+                                     const ClipmanHistoryItem *item)
+{
+  /* TODO Verify that the item exists in the history */
+  history->priv->item_to_restore = item;
+}
+
+/**
+ * clipman_history_clear:
+ * @history: a #ClipmanHistory
+ *
+ * Clears the lists containing the history of the texts and the images.
+ */
+void
+clipman_history_clear (ClipmanHistory *history)
+{
+  GSList *list;
+
+  DBG ("Clear the history");
+
+  for (list = history->priv->texts; list != NULL; list = list->next)
+    __clipman_history_item_free (list->data);
+
+  for (list = history->priv->images; list != NULL; list = list->next)
+    __clipman_history_item_free (list->data);
+
+  g_slist_free (history->priv->texts);
+  g_slist_free (history->priv->images);
+
+  history->priv->texts = NULL;
+  history->priv->images = NULL;
+}
+
+ClipmanHistory *
+clipman_history_get ()
+{
+  static ClipmanHistory *singleton = NULL;
+
+  if (singleton == NULL)
+    {
+      singleton = g_object_new (CLIPMAN_TYPE_HISTORY, NULL);
+      g_object_add_weak_pointer (G_OBJECT (singleton), (gpointer)&singleton);
+    }
+  else
+    g_object_ref (G_OBJECT (singleton));
+
+  return singleton;
+}
+
+/*
+ * GObject
+ */
+
+static void
+clipman_history_class_init (ClipmanHistoryClass *klass)
+{
+  GObjectClass *object_class;
+
+  g_type_class_add_private (klass, sizeof (ClipmanHistoryPrivate));
+
+  clipman_history_parent_class = g_type_class_peek_parent (klass);
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->finalize = clipman_history_finalize;
+  object_class->set_property = clipman_history_set_property;
+  object_class->get_property = clipman_history_get_property;
+
+  g_object_class_install_property (object_class,
+                                   MAX_TEXTS_IN_HISTORY,
+                                   g_param_spec_uint ("max-texts-in-history",
+                                                      "MaxTextsInHistory",
+                                                      "The number of maximum texts in history",
+                                                      5, 100, 10,
+                                                      G_PARAM_CONSTRUCT|G_PARAM_READWRITE));
+  g_object_class_install_property (object_class,
+                                   MAX_IMAGES_IN_HISTORY,
+                                   g_param_spec_uint ("max-images-in-history",
+                                                      "MaxImagesInHistory",
+                                                      "The number of maximum images in history",
+                                                      0, 5, 1,
+                                                      G_PARAM_CONSTRUCT|G_PARAM_READWRITE));
+}
+
+static void
+clipman_history_init (ClipmanHistory *history)
+{
+  history->priv = GET_PRIVATE (history);
+}
+
+static void
+clipman_history_finalize (GObject *object)
+{
+  /* TODO Free the GSLists */
+  G_OBJECT_CLASS (clipman_history_parent_class)->finalize (object);
+}
+
+static void
+clipman_history_set_property (GObject *object,
+                              guint property_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+  ClipmanHistoryPrivate *priv = CLIPMAN_HISTORY (object)->priv;
+
+  switch (property_id)
+    {
+    case MAX_TEXTS_IN_HISTORY:
+      priv->max_texts_in_history = g_value_get_uint (value);
+      break;
+
+    case MAX_IMAGES_IN_HISTORY:
+      priv->max_images_in_history = g_value_get_uint (value);
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+clipman_history_get_property (GObject *object,
+                              guint property_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+  ClipmanHistoryPrivate *priv = CLIPMAN_HISTORY (object)->priv;
+
+  switch (property_id)
+    {
+    case MAX_TEXTS_IN_HISTORY:
+      g_value_set_uint (value, priv->max_texts_in_history);
+      break;
+
+    case MAX_IMAGES_IN_HISTORY:
+      g_value_set_uint (value, priv->max_images_in_history);
+      break;
+
+    default:
+      break;
+    }
+}
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.h
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.h	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/history.h	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,100 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __CLIPMAN_HISTORY_H__
+#define __CLIPMAN_HISTORY_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+/*
+ * ClipmanHistoryItem
+ */
+
+typedef enum
+{
+  CLIPMAN_HISTORY_TYPE_TEXT,
+  CLIPMAN_HISTORY_TYPE_IMAGE,
+} ClipmanHistoryType;
+
+typedef struct _ClipmanHistoryItem ClipmanHistoryItem;
+struct _ClipmanHistoryItem
+{
+  GtkClipboard             *clipboard;
+  ClipmanHistoryType        type;
+  union
+    {
+      gchar                *text;
+      GdkPixbuf            *image;
+    } content;
+  union
+    {
+      gchar                *text;
+      GdkPixbuf            *image;
+    } preview;
+};
+
+/*
+ * ClipmanHistory
+ */
+
+#define CLIPMAN_TYPE_HISTORY                  (clipman_history_get_type())
+
+#define CLIPMAN_HISTORY(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPMAN_TYPE_HISTORY, ClipmanHistory))
+#define CLIPMAN_HISTORY_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), CLIPMAN_TYPE_HISTORY, ClipmanHistoryClass))
+
+#define CLIPMAN_IS_HISTORY(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLIPMAN_TYPE_HISTORY))
+#define CLIPMAN_IS_HISTORY_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), CLIPMAN_TYPE_HISTORY))
+
+#define CLIPMAN_HISTORY_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), CLIPMAN_TYPE_HISTORY, ClipmanHistoryClass))
+
+typedef struct _ClipmanHistoryClass           ClipmanHistoryClass;
+typedef struct _ClipmanHistory                ClipmanHistory;
+typedef struct _ClipmanHistoryPrivate         ClipmanHistoryPrivate;
+
+struct _ClipmanHistoryClass
+{
+  GObjectClass              parent_class;
+};
+
+struct _ClipmanHistory
+{
+  GObject                   parent;
+
+  /* Private */
+  ClipmanHistoryPrivate    *priv;
+};
+
+GType                       clipman_history_get_type               ();
+
+ClipmanHistory *            clipman_history_get                    ();
+void                        clipman_history_add_text               (ClipmanHistory *history,
+                                                                    const gchar *text,
+                                                                    GtkClipboard *clipboard);
+void                        clipman_history_add_image              (ClipmanHistory *history,
+                                                                    const GdkPixbuf *image,
+                                                                    GtkClipboard *clipboard);
+const GSList *              clipman_history_get_texts              (ClipmanHistory *history);
+const GSList *              clipman_history_get_images             (ClipmanHistory *history);
+const ClipmanHistoryItem *  clipman_history_get_item_to_restore    (ClipmanHistory *history);
+void                        clipman_history_set_item_to_restore    (ClipmanHistory *history,
+                                                                    const ClipmanHistoryItem *item);
+void                        clipman_history_clear                  (ClipmanHistory *history);
+
+#endif /* !__CLIPMAN_HISTORY_H__ */
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.c
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.c	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.c	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,263 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfcegui4/libxfcegui4.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "collector.h"
+#include "history.h"
+
+#include "menu.h"
+
+/*
+ * GObject declarations
+ */
+
+G_DEFINE_TYPE (ClipmanMenu, clipman_menu, GTK_TYPE_MENU)
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLIPMAN_TYPE_MENU, ClipmanMenuPrivate))
+
+struct _ClipmanMenuPrivate
+{
+  ClipmanHistory       *history;
+  GSList               *list;
+};
+
+static void             clipman_menu_class_init         (ClipmanMenuClass *klass);
+static void             clipman_menu_init               (ClipmanMenu *menu);
+static void             clipman_menu_finalize           (GObject *object);
+
+/*
+ * Private methods declarations
+ */
+
+static void            _clipman_menu_free_list          (ClipmanMenu *menu);
+
+/*
+ * Callbacks declarations
+ */
+
+static void             cb_set_clipboard                (const ClipmanHistoryItem *item);
+static void             cb_clear_history                (ClipmanMenu *menu);
+
+
+
+/*
+ * Callbacks
+ */
+
+static void
+cb_set_clipboard (const ClipmanHistoryItem *item)
+{
+  GtkClipboard *clipboard;
+  ClipmanCollector *collector;
+  ClipmanHistory *history;
+
+  switch (item->type)
+    {
+    case CLIPMAN_HISTORY_TYPE_TEXT:
+      clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+      gtk_clipboard_set_text (clipboard, item->content.text, -1);
+
+      clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+      gtk_clipboard_set_text (clipboard, item->content.text, -1);
+      break;
+
+    case CLIPMAN_HISTORY_TYPE_IMAGE:
+      DBG ("Copy image (%p) to default clipboard", item->content.image);
+
+      collector = clipman_collector_get ();
+      clipman_collector_set_is_restoring (collector);
+      g_object_unref (collector);
+
+      history = clipman_history_get ();
+      clipman_history_set_item_to_restore (history, item);
+      g_object_unref (history);
+
+      clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+      gtk_clipboard_set_image (clipboard, GDK_PIXBUF (item->content.image));
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+cb_clear_history (ClipmanMenu *menu)
+{
+  GtkClipboard *clipboard;
+
+  if (!xfce_confirm (_("Are you sure you want to clear the history?"), GTK_STOCK_YES, NULL))
+    return;
+
+  clipman_history_clear (menu->priv->history);
+
+  clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+  gtk_clipboard_clear (clipboard);
+
+  clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+  gtk_clipboard_clear (clipboard);
+}
+
+/*
+ * Private methods
+ */
+
+static void
+_clipman_menu_update_list (ClipmanMenu *menu)
+{
+  GtkWidget *mi, *image;
+  ClipmanHistoryItem *item;
+  const ClipmanHistoryItem *item_to_restore;
+  const GSList *list;
+  gint pos = 0, i;
+
+  /* Get the most recent item in the history */
+  item_to_restore = clipman_history_get_item_to_restore (menu->priv->history);
+
+  /* Clear the previous menu items */
+  _clipman_menu_free_list (menu);
+
+  /* Insert an updated list of menu items */
+  for (i = 0; i < 2; i++)
+    {
+      if (i == 0)
+        list = clipman_history_get_images (menu->priv->history);
+      else if (i == 1)
+        list = clipman_history_get_texts (menu->priv->history);
+
+      for (; list != NULL; list = list->next)
+        {
+          item = list->data;
+
+          switch (item->type)
+            {
+            case CLIPMAN_HISTORY_TYPE_TEXT:
+              mi = gtk_image_menu_item_new_with_label (item->preview.text);
+              g_signal_connect_swapped (mi, "activate", G_CALLBACK (cb_set_clipboard), item);
+              break;
+
+            case CLIPMAN_HISTORY_TYPE_IMAGE:
+              mi = gtk_image_menu_item_new ();
+              image = gtk_image_new_from_pixbuf (item->preview.image);
+              gtk_container_add (GTK_CONTAINER (mi), image);
+              g_signal_connect_swapped (mi, "activate", G_CALLBACK (cb_set_clipboard), item);
+              break;
+
+            default:
+              g_assert_not_reached ();
+            }
+
+          if (item == item_to_restore)
+            {
+              image = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU);
+              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
+            }
+
+          menu->priv->list = g_slist_prepend (menu->priv->list, mi);
+          gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, pos++);
+          gtk_widget_show_all (mi);
+        }
+    }
+
+  if (pos == 0)
+    {
+      mi = gtk_menu_item_new_with_label (_("Clipboard is empty"));
+      menu->priv->list = g_slist_prepend (menu->priv->list, mi);
+      gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, 0);
+      gtk_widget_set_sensitive (mi, FALSE);
+      gtk_widget_show (mi);
+    }
+}
+
+static void
+_clipman_menu_free_list (ClipmanMenu *menu)
+{
+  GSList *list;
+  for (list = menu->priv->list; list != NULL; list = list->next)
+    gtk_widget_destroy (GTK_WIDGET (list->data));
+  g_slist_free (menu->priv->list);
+  menu->priv->list = NULL;
+}
+
+/*
+ * Public methods
+ */
+
+GtkWidget *
+clipman_menu_new ()
+{
+  return g_object_new (CLIPMAN_TYPE_MENU, NULL);
+}
+
+/*
+ * GObject
+ */
+
+static void
+clipman_menu_class_init (ClipmanMenuClass *klass)
+{
+  GObjectClass *object_class;
+
+  g_type_class_add_private (klass, sizeof (ClipmanMenuPrivate));
+
+  clipman_menu_parent_class = g_type_class_peek_parent (klass);
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->finalize = clipman_menu_finalize;
+}
+
+static void
+clipman_menu_init (ClipmanMenu *menu)
+{
+  GtkWidget *mi;
+
+  menu->priv = GET_PRIVATE (menu);
+
+  /* ClipmanHistory */
+  menu->priv->history = clipman_history_get ();
+
+  /* Connect signal on show to update the items */
+  g_signal_connect_swapped (menu, "show", G_CALLBACK (_clipman_menu_update_list), menu);
+
+  /* Footer items */
+  mi = gtk_separator_menu_item_new ();
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+  mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+  g_signal_connect_swapped (mi, "activate",
+                            G_CALLBACK (cb_clear_history), menu);
+
+  /* Show all the items */
+  gtk_widget_show_all (GTK_WIDGET (menu));
+}
+
+static void
+clipman_menu_finalize (GObject *object)
+{
+  _clipman_menu_free_list (CLIPMAN_MENU (object));
+  G_OBJECT_CLASS (clipman_menu_parent_class)->finalize (object);
+}
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.h
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.h	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/menu.h	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __CLIPMAN_MENU_H__
+#define __CLIPMAN_MENU_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#define CLIPMAN_TYPE_MENU                  (clipman_menu_get_type())
+
+#define CLIPMAN_MENU(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPMAN_TYPE_MENU, ClipmanMenu))
+#define CLIPMAN_MENU_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), CLIPMAN_TYPE_MENU, ClipmanMenuClass))
+
+#define CLIPMAN_IS_MENU(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLIPMAN_TYPE_MENU))
+#define CLIPMAN_IS_MENU_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), CLIPMAN_TYPE_MENU))
+
+#define CLIPMAN_MENU_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), CLIPMAN_TYPE_MENU, ClipmanMenuClass))
+
+typedef struct _ClipmanMenuClass           ClipmanMenuClass;
+typedef struct _ClipmanMenu                ClipmanMenu;
+typedef struct _ClipmanMenuPrivate         ClipmanMenuPrivate;
+
+struct _ClipmanMenuClass
+{
+  GtkMenuClass           parent_class;
+};
+
+struct _ClipmanMenu
+{
+  GtkMenu                parent;
+
+  /* Private */
+  ClipmanMenuPrivate    *priv;
+};
+
+GType                   clipman_menu_get_type           ();
+
+GtkWidget *             clipman_menu_new                ();
+
+#endif /* !__CLIPMAN_MENU_H__ */
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/panel-plugin.c
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/panel-plugin.c	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/panel-plugin.c	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,242 @@
+/*
+ *  Copyright (c) 2008-2009 Mike Massonnet <mmassonnet at xfce.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-panel-convenience.h>
+#include <xfconf/xfconf.h>
+
+#include "collector.h"
+#include "history.h"
+#include "menu.h"
+
+
+
+/*
+ * MyPlugin structure
+ */
+
+typedef struct _MyPlugin MyPlugin;
+struct _MyPlugin
+{
+  XfcePanelPlugin      *panel_plugin;
+  XfconfChannel        *channel;
+  ClipmanCollector     *collector;
+  ClipmanHistory       *history;
+  GtkWidget            *button;
+  GtkWidget            *image;
+  GtkWidget            *menu;
+};
+
+/*
+ * Panel Plugin registration
+ */
+
+static void panel_plugin_register (XfcePanelPlugin *panel_plugin);
+XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL (panel_plugin_register);
+
+/*
+ * Panel Plugin functions declarations
+ */
+
+static gboolean         panel_plugin_set_size           (XfcePanelPlugin *panel_plugin,
+                                                         int size,
+                                                         MyPlugin *plugin);
+static void             panel_plugin_free               (XfcePanelPlugin *panel_plugin,
+                                                         MyPlugin *plugin);
+static void             cb_button_toggled               (GtkToggleButton *button,
+                                                         MyPlugin *plugin);
+static void             cb_menu_deactivate              (GtkMenuShell *menu,
+                                                         MyPlugin *plugin);
+static void             my_plugin_position_menu         (GtkMenu *menu,
+                                                         gint *x,
+                                                         gint *y,
+                                                         gboolean *push_in,
+                                                         MyPlugin *plugin);
+
+
+
+/*
+ * Panel Plugin functions
+ */
+
+static void
+panel_plugin_register (XfcePanelPlugin *panel_plugin)
+{
+  MyPlugin *plugin;
+
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+  xfconf_init (NULL);
+
+  /* XfcePanelPlugin widget */
+#if GTK_CHECK_VERSION (2,12,0)
+  gtk_widget_set_tooltip_text (GTK_WIDGET (panel_plugin), _("Clipman"));
+#endif
+
+  /* MyPlugin */
+  plugin = g_slice_new0 (MyPlugin);
+
+  /* Keep a pointer on the panel plugin */
+  plugin->panel_plugin = panel_plugin;
+
+  /* XfconfChannel */
+  plugin->channel = xfconf_channel_new_with_property_base ("xfce4-panel", "/plugins/clipman");
+
+  /* ClipmanHistory */
+  plugin->history = clipman_history_get ();
+  xfconf_g_property_bind (plugin->channel, "/settings/max-texts-in-history",
+                          G_TYPE_UINT, plugin->history, "max-texts-in-history");
+  xfconf_g_property_bind (plugin->channel, "/settings/max-images-in-history",
+                          G_TYPE_UINT, plugin->history, "max-images-in-history");
+
+  /* ClipmanCollector */
+  plugin->collector = clipman_collector_get ();
+  xfconf_g_property_bind (plugin->channel, "/settings/ignore-primary-clipboard",
+                          G_TYPE_BOOLEAN, plugin->collector, "ignore-primary-clipboard");
+
+  /* Panel Button */
+  plugin->button = xfce_create_panel_toggle_button ();
+  /* The image is set through the set_size callback */
+  plugin->image = gtk_image_new ();
+  gtk_container_add (GTK_CONTAINER (plugin->button), plugin->image);
+  gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->button);
+  xfce_panel_plugin_add_action_widget (panel_plugin, plugin->button);
+  g_signal_connect (plugin->button, "toggled",
+                    G_CALLBACK (cb_button_toggled), plugin);
+
+  /* ClipmanMenu */
+  plugin->menu = clipman_menu_new ();
+  g_signal_connect (plugin->menu, "deactivate",
+                    G_CALLBACK (cb_menu_deactivate), plugin);
+
+  /* Panel Plugin Signals */
+  g_signal_connect (panel_plugin, "size-changed",
+                    G_CALLBACK (panel_plugin_set_size), plugin);
+  g_signal_connect (panel_plugin, "free-data",
+                    G_CALLBACK (panel_plugin_free), plugin);
+
+  gtk_widget_show_all (GTK_WIDGET (panel_plugin));
+}
+
+static gboolean
+panel_plugin_set_size (XfcePanelPlugin *panel_plugin,
+                       int size,
+                       MyPlugin *plugin)
+{
+  GdkPixbuf *pixbuf;
+
+  gtk_widget_set_size_request (plugin->button, size, size);
+
+  size -= 2 + 2 * MAX (plugin->button->style->xthickness,
+                       plugin->button->style->ythickness);
+  pixbuf = xfce_themed_icon_load (GTK_STOCK_PASTE, size);
+  gtk_image_set_from_pixbuf (GTK_IMAGE (plugin->image), pixbuf);
+  g_object_unref (G_OBJECT (pixbuf));
+
+  return TRUE;
+}
+
+static void
+panel_plugin_free (XfcePanelPlugin *panel_plugin,
+                   MyPlugin *plugin)
+{
+  gtk_widget_destroy (plugin->menu);
+  gtk_widget_destroy (plugin->button);
+  g_object_unref (plugin->channel);
+  g_object_unref (plugin->collector);
+  g_object_unref (plugin->history);
+  g_slice_free (MyPlugin, plugin);
+  xfconf_shutdown ();
+}
+
+static void
+cb_button_toggled (GtkToggleButton *button,
+                   MyPlugin *plugin)
+{
+  if (gtk_toggle_button_get_active (button))
+    {
+      gtk_menu_set_screen (GTK_MENU (plugin->menu), gtk_widget_get_screen (plugin->button));
+      xfce_panel_plugin_register_menu (plugin->panel_plugin, GTK_MENU (plugin->menu));
+      gtk_menu_popup (GTK_MENU (plugin->menu), NULL, NULL,
+                      (GtkMenuPositionFunc)my_plugin_position_menu, plugin,
+                      0, gtk_get_current_event_time ());
+    }
+}
+
+static void
+cb_menu_deactivate (GtkMenuShell *menu,
+                    MyPlugin *plugin)
+{
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->button), FALSE);
+}
+
+static void
+my_plugin_position_menu (GtkMenu *menu,
+                         gint *x,
+                         gint *y,
+                         gboolean *push_in,
+                         MyPlugin *plugin)
+{
+  GtkWidget *button;
+  GtkRequisition requisition;
+  GtkOrientation orientation;
+
+  button = plugin->button;
+  orientation = xfce_panel_plugin_get_orientation (plugin->panel_plugin);
+  gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+  gdk_window_get_origin (button->window, x, y);
+
+  switch (orientation)
+    {
+    case GTK_ORIENTATION_HORIZONTAL:
+      if (*y + button->allocation.height + requisition.height > gdk_screen_height ())
+        /* Show menu above */
+        *y -= requisition.height;
+      else
+        /* Show menu below */
+        *y += button->allocation.height;
+
+      if (*x + requisition.width > gdk_screen_width ())
+        /* Adjust horizontal position */
+        *x = gdk_screen_width () - requisition.width;
+      break;
+
+    case GTK_ORIENTATION_VERTICAL:
+      if (*x + button->allocation.width + requisition.width > gdk_screen_width ())
+        /* Show menu on the right */
+        *x -= requisition.width;
+      else
+        /* Show menu on the left */
+        *x += button->allocation.width;
+
+      if (*y + requisition.height > gdk_screen_height ())
+        /* Adjust vertical position */
+        *y = gdk_screen_height () - requisition.height;
+      break;
+
+    default:
+      break;
+    }
+}
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/xfce4-clipman-plugin.desktop.in.in
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/xfce4-clipman-plugin.desktop.in.in	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/panel-plugin/xfce4-clipman-plugin.desktop.in.in	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,8 @@
+[Xfce Panel]
+Type=X-XFCE-PanelPlugin
+Encoding=UTF-8
+_Name=Clipman
+_Comment=Clipboards manager
+Icon=gtk-paste
+X-XFCE-Exec=@EXTERNAL_PLUGIN_PATH@/xfce4-clipman-plugin
+X-XFCE-Unique=true

Added: xfce4-clipman-plugin/branches/xfce-4-6/po/LINGUAS
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/po/LINGUAS	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/po/LINGUAS	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,2 @@
+# set of available languages (in alphabetic order)
+

Added: xfce4-clipman-plugin/branches/xfce-4-6/po/POTFILES.in
===================================================================
--- xfce4-clipman-plugin/branches/xfce-4-6/po/POTFILES.in	                        (rev 0)
+++ xfce4-clipman-plugin/branches/xfce-4-6/po/POTFILES.in	2009-01-09 00:28:20 UTC (rev 6418)
@@ -0,0 +1,5 @@
+panel-plugin/xfce4-clipman-plugin.desktop.in.in
+panel-plugin/panel-plugin.c
+panel-plugin/collector.c
+panel-plugin/history.c
+panel-plugin/menu.c




More information about the Goodies-commits mailing list