ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #03591
[Merge] lp:~karl-qdh/indicator-datetime/calendarselect into lp:indicator-datetime
Karl Lattimer has proposed merging lp:~karl-qdh/indicator-datetime/calendarselect into lp:indicator-datetime.
Requested reviews:
Ted Gould (ted)
Related bugs:
Bug #768956 in Indicator Date and Time: "Clicking a date of previous or next month does not select the right date"
https://bugs.launchpad.net/indicator-datetime/+bug/768956
For more details, see:
https://code.launchpad.net/~karl-qdh/indicator-datetime/calendarselect/+merge/60755
prevent duplicating events which causes calendar jump
--
https://code.launchpad.net/~karl-qdh/indicator-datetime/calendarselect/+merge/60755
Your team ayatana-commits is subscribed to branch lp:indicator-datetime.
=== added file 'AUTHORS'
--- AUTHORS 1970-01-01 00:00:00 +0000
+++ AUTHORS 2011-05-12 10:11:02 +0000
@@ -0,0 +1,1 @@
+Cody Russell <crussell@xxxxxxxxxxxxx>
=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'COPYING'
--- COPYING 1970-01-01 00:00:00 +0000
+++ COPYING 2011-05-12 10:11:02 +0000
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
=== added file 'COPYING.LGPL.2.1'
--- COPYING.LGPL.2.1 1970-01-01 00:00:00 +0000
+++ COPYING.LGPL.2.1 2011-05-12 10:11:02 +0000
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
=== renamed file 'COPYING' => 'COPYING.moved'
=== added file 'ChangeLog'
=== renamed file 'ChangeLog' => 'ChangeLog.moved'
=== added file 'INSTALL'
--- INSTALL 1970-01-01 00:00:00 +0000
+++ INSTALL 2011-05-12 10:11:02 +0000
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
=== added file 'Makefile.am'
--- Makefile.am 1970-01-01 00:00:00 +0000
+++ Makefile.am 2011-05-12 10:11:02 +0000
@@ -0,0 +1,19 @@
+ACLOCAL_AMFLAGS = -I build/autotools
+
+V = @
+Q = $(V:1=)
+QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
+
+SUBDIRS = build src example
+
+libido-0.1.pc: libido.pc
+ $(QUIET_GEN) cp -f libido.pc libido-0.1.pc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libido-0.1.pc
+
+CLEANFILES = libido-0.1.pc
+DISTCLEANFILES = libido.pc
+EXTRA_DIST = libido.pc.in
+
+DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc
=== renamed file 'Makefile.am' => 'Makefile.am.moved'
=== added file 'NEWS'
=== renamed file 'NEWS' => 'NEWS.moved'
=== added file 'README'
=== renamed file 'README' => 'README.moved'
=== added file 'TODO'
=== added file 'autogen.sh'
--- autogen.sh 1970-01-01 00:00:00 +0000
+++ autogen.sh 2011-05-12 10:11:02 +0000
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+PKG_NAME="ido"
+
+which gnome-autogen.sh || {
+ echo "You need gnome-common from GNOME git"
+ exit 1
+}
+
+USE_GNOME2_MACROS=1 \
+USE_COMMON_DOC_BUILD=yes \
+gnome-autogen.sh --enable-gtk-doc $@
\ No newline at end of file
=== renamed file 'autogen.sh' => 'autogen.sh.moved'
=== added directory 'build'
=== added file 'build/Makefile.am'
--- build/Makefile.am 1970-01-01 00:00:00 +0000
+++ build/Makefile.am 2011-05-12 10:11:02 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = autotools
=== added directory 'build/autotools'
=== added file 'build/autotools/Makefile.am'
--- build/autotools/Makefile.am 1970-01-01 00:00:00 +0000
+++ build/autotools/Makefile.am 2011-05-12 10:11:02 +0000
@@ -0,0 +1,3 @@
+EXTRA_DIST = shave-libtool.in shave.in shave.m4
+
+DISTCLEANFILES = shave-libtool shave
=== added file 'build/autotools/shave-libtool.in'
--- build/autotools/shave-libtool.in 1970-01-01 00:00:00 +0000
+++ build/autotools/shave-libtool.in 2011-05-12 10:11:02 +0000
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+# we need sed
+SED=@SED@
+if test -z "$SED" ; then
+SED=sed
+fi
+
+lt_unmangle ()
+{
+ last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
+}
+
+tempval=`echo $1 | sed s/\'//g`
+if test "x$tempval" = "x$SHELL"; then
+ shift
+fi
+tempval=`echo $1 | sed s/\'//g`
+LIBTOOL="$tempval"
+shift
+
+# if 1, don't print anything, the underlaying wrapper will do it
+pass_though=0
+
+# scan the arguments, keep the right ones for libtool, and discover the mode
+preserved_args=
+while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --mode=*)
+ mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'`
+ preserved_args="$preserved_args $opt"
+ ;;
+ -o)
+ lt_output="$1"
+ preserved_args="$preserved_args $opt"
+ ;;
+ *)
+ preserved_args="$preserved_args $opt"
+ ;;
+ esac
+done
+
+case "$mode" in
+compile)
+ # shave will be called and print the actual CC/CXX/LINK line
+ preserved_args="$preserved_args --shave-mode=$mode"
+ pass_though=1
+ ;;
+link)
+ preserved_args="$preserved_args --shave-mode=$mode"
+ Q=" LINK "
+ ;;
+*)
+ # let's u
+ # echo "*** libtool: Unimplemented mode: $mode, fill a bug report"
+ ;;
+esac
+
+lt_unmangle "$lt_output"
+output=$last_result
+
+if test -z $V; then
+ if test $pass_though -eq 0; then
+ echo "$Q$output"
+ fi
+ $LIBTOOL --silent $preserved_args
+else
+ echo $LIBTOOL $preserved_args
+ $LIBTOOL $preserved_args
+fi
=== added file 'build/autotools/shave.in'
--- build/autotools/shave.in 1970-01-01 00:00:00 +0000
+++ build/autotools/shave.in 2011-05-12 10:11:02 +0000
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# we need sed
+SED=@SED@
+if test -z "$SED" ; then
+SED=sed
+fi
+
+lt_unmangle ()
+{
+ last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
+}
+
+# the tool to wrap (cc, cxx, ar, ranlib, ..)
+tool="$1"
+shift
+
+# the reel tool (to call)
+REEL_TOOL="$1"
+shift
+
+pass_through=0
+preserved_args=
+while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --shave-mode=*)
+ mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'`
+ ;;
+ -o)
+ lt_output="$1"
+ preserved_args="$preserved_args $opt"
+ ;;
+ *)
+ preserved_args="$preserved_args $opt"
+ ;;
+ esac
+done
+
+# mode=link is handled in the libtool wrapper
+case "$mode,$tool" in
+link,*)
+ pass_through=1
+ ;;
+*,cxx)
+ Q=" CXX "
+ ;;
+*,cc)
+ Q=" CC "
+ ;;
+*,fc)
+ Q=" FC "
+ ;;
+*,f77)
+ Q=" F77 "
+ ;;
+*,objc)
+ Q=" OBJC "
+ ;;
+*,*)
+ # should not happen
+ Q=" CC "
+ ;;
+esac
+
+lt_unmangle "$lt_output"
+output=$last_result
+
+if test -z $V; then
+ if test $pass_through -eq 0; then
+ echo "$Q$output"
+ fi
+ $REEL_TOOL $preserved_args
+else
+ echo $REEL_TOOL $preserved_args
+ $REEL_TOOL $preserved_args
+fi
=== added file 'build/autotools/shave.m4'
--- build/autotools/shave.m4 1970-01-01 00:00:00 +0000
+++ build/autotools/shave.m4 2011-05-12 10:11:02 +0000
@@ -0,0 +1,77 @@
+dnl Make automake/libtool output more friendly to humans
+dnl Damien Lespiau <damien.lespiau@xxxxxxxxx>
+dnl
+dnl SHAVE_INIT([shavedir],[default_mode])
+dnl
+dnl shavedir: the directory where the shave scripts are, it defaults to
+dnl $(top_builddir)
+dnl default_mode: (enable|disable) default shave mode. This parameter
+dnl controls shave's behaviour when no option has been
+dnl given to configure. It defaults to disable.
+dnl
+dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just
+dnl before AC_CONFIG_FILE/AC_OUTPUT is perfect. This macro rewrites CC and
+dnl LIBTOOL, you don't want the configure tests to have these variables
+dnl re-defined.
+dnl * This macro requires GNU make's -s option.
+
+AC_DEFUN([_SHAVE_ARG_ENABLE],
+[
+ AC_ARG_ENABLE([shave],
+ AS_HELP_STRING(
+ [--enable-shave],
+ [use shave to make the build pretty [[default=$1]]]),,
+ [enable_shave=$1]
+ )
+])
+
+AC_DEFUN([SHAVE_INIT],
+[
+ dnl you can tweak the default value of enable_shave
+ m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)])
+
+ if test x"$enable_shave" = xyes; then
+ dnl where can we find the shave scripts?
+ m4_if([$1],,
+ [shavedir="$ac_pwd"],
+ [shavedir="$ac_pwd/$1"])
+ AC_SUBST(shavedir)
+
+ dnl make is now quiet
+ AC_SUBST([MAKEFLAGS], [-s])
+ AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`'])
+
+ dnl we need sed
+ AC_CHECK_PROG(SED,sed,sed,false)
+
+ dnl substitute libtool
+ SHAVE_SAVED_LIBTOOL=$LIBTOOL
+ LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'"
+ AC_SUBST(LIBTOOL)
+
+ dnl substitute cc/cxx
+ SHAVE_SAVED_CC=$CC
+ SHAVE_SAVED_CXX=$CXX
+ SHAVE_SAVED_FC=$FC
+ SHAVE_SAVED_F77=$F77
+ SHAVE_SAVED_OBJC=$OBJC
+ CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}"
+ CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}"
+ FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}"
+ F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}"
+ OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}"
+ AC_SUBST(CC)
+ AC_SUBST(CXX)
+ AC_SUBST(FC)
+ AC_SUBST(F77)
+ AC_SUBST(OBJC)
+
+ V=@
+ else
+ V=1
+ fi
+ Q='$(V:1=)'
+ AC_SUBST(V)
+ AC_SUBST(Q)
+])
+
=== added file 'configure.ac'
--- configure.ac 1970-01-01 00:00:00 +0000
+++ configure.ac 2011-05-12 10:11:02 +0000
@@ -0,0 +1,128 @@
+#
+# shamelessly stolen from clutter-gtk
+#
+m4_define([ido_major_version], [0])
+m4_define([ido_minor_version], [2])
+m4_define([ido_micro_version], [2])
+
+m4_define([ido_api_version],
+ [ido_major_version.ido_minor_version])
+m4_define([ido_version],
+ [ido_major_version.ido_minor_version.ido_micro_version])
+
+m4_define([ido_interface_age], [0])
+m4_define([ido_binary_age],
+ [m4_eval(100 * ido_minor_version + ido_micro_version)])
+
+AC_PREREQ(2.59)
+
+AC_INIT([ido],
+ [ido_version],
+ [https://bugs.launchpad.net/avani])
+AC_CONFIG_SRCDIR([src/libido.h])
+AC_CONFIG_MACRO_DIR([build/autotools])
+
+AM_CONFIG_HEADER([config.h])
+
+AM_INIT_AUTOMAKE([1.9])
+
+IDO_MAJOR_VERSION=ido_major_version
+IDO_MINOR_VERSION=ido_minor_version
+IDO_MICRO_VERSION=ido_micro_version
+IDO_VERSION=ido_version
+AC_SUBST(IDO_MAJOR_VERSION)
+AC_SUBST(IDO_MINOR_VERSION)
+AC_SUBST(IDO_MICRO_VERSION)
+AC_SUBST(IDO_VERSION)
+
+m4_define([lt_current],
+ [m4_eval(100 * ido_minor_version + ido_micro_version - ido_interface_age)])
+m4_define([lt_revision], [ido_interface_age])
+m4_define([lt_age], [m4_eval(ido_binary_age - ido_interface_age)])
+IDO_LT_CURRENT=lt_current
+IDO_LT_REV=lt_revision
+IDO_LT_AGE=lt_age
+IDO_LT_VERSION="$IDO_LT_CURRENT:$IDO_LT_REV:$IDO_LT_AGE"
+IDO_LT_LDFLAGS="-version-info $IDO_LT_VERSION"
+
+AC_SUBST(IDO_LT_VERSION)
+AC_SUBST(IDO_LT_LDFLAGS)
+
+dnl ===========================================================================
+
+# Checks for programs
+AC_PROG_CC
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums])
+
+# Checks for header files
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h])
+
+# Checks for typedefs, structures and compiler charecteristics
+AC_C_CONST
+
+# Checks for library functions
+AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_CHECK_FUNCS([memset munmap strcasecmp strdup])
+
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.19.7)
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+dnl ===========================================================================
+
+if test "x$GCC" = "xyes"; then
+ GCC_FLAGS="-g -Wall"
+fi
+AC_SUBST(GCC_FLAGS)
+
+# use strict compiler flags only on development releases
+m4_define([maintainer_flags_default], [m4_if(m4_eval(ido_minor_version % 2), [1], [yes], [no])])
+AC_ARG_ENABLE([maintainer-flags],
+ [AC_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@],
+ [Use strict compiler flags @<:@default=no@:>@])],
+ [],
+ [enable_maintainer_flags=maintainer_flags_default])
+
+MAINTAINER_CFLAGS=""
+AS_IF([test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"],
+ [
+ MAINTAINER_CFLAGS="-Werror -Wall -Wshadow -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self"
+ ]
+)
+
+AC_SUBST(MAINTAINER_CFLAGS)
+
+
+dnl = GTK Doc Check ===========================================================
+
+GTK_DOC_CHECK([1.8])
+
+dnl ===========================================================================
+
+SHAVE_INIT([build/autotools], [enable])
+
+AC_CONFIG_FILES([
+ Makefile
+ build/Makefile
+ build/autotools/Makefile
+ build/autotools/shave-libtool
+ build/autotools/shave
+ src/Makefile
+ example/Makefile
+ libido.pc
+])
+
+AC_OUTPUT
+
+echo ""
+echo " ido $VERSION"
+echo " ==============================="
+echo ""
+echo " Prefix : ${prefix}"
+echo ""
+echo " Documentation: ${enable_gtk_doc}"
+echo ""
=== renamed file 'configure.ac' => 'configure.ac.moved'
=== added directory 'example'
=== added file 'example/Makefile.am'
--- example/Makefile.am 1970-01-01 00:00:00 +0000
+++ example/Makefile.am 2011-05-12 10:11:02 +0000
@@ -0,0 +1,29 @@
+noinst_PROGRAMS = \
+ messagedialog \
+ menus
+
+messagedialog_SOURCES = \
+ messagedialog.c
+
+menus_SOURCES = \
+ menus.c
+
+messagedialog_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(GCC_FLAGS) \
+ $(GTK_CFLAGS) \
+ $(MAINTAINER_CFLAGS)
+
+menus_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(GCC_FLAGS) \
+ $(GTK_CFLAGS) \
+ $(MAINTAINER_CFLAGS)
+
+messagedialog_LDADD = $(top_builddir)/src/libido-0.1.la $(GTK_LIBS)
+
+menus_LDADD = $(top_builddir)/src/libido-0.1.la $(GTK_LIBS)
=== added file 'example/menus.c'
--- example/menus.c 1970-01-01 00:00:00 +0000
+++ example/menus.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,95 @@
+#include <gtk/gtk.h>
+
+#include "idoscalemenuitem.h"
+#include "idocalendarmenuitem.h"
+#include "idoentrymenuitem.h"
+
+static void
+slider_grabbed (GtkWidget *widget, gpointer user_data)
+{
+ g_print ("grabbed\n");
+}
+
+static void
+slider_released (GtkWidget *widget, gpointer user_data)
+{
+ g_print ("released\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ GtkWidget *root;
+ GtkWidget *menubar;
+ GtkWidget *image;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Menus");
+ gtk_widget_set_size_request (window, 300, 200);
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ menubar = gtk_menu_bar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
+
+ menu = gtk_menu_new ();
+
+ root = gtk_menu_item_new_with_label ("File");
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (root), menu);
+
+ menuitem = gtk_menu_item_new_with_label ("New");
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ menuitem = gtk_menu_item_new_with_label ("Open");
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ menuitem = ido_scale_menu_item_new_with_range ("Volume",
+ IDO_RANGE_STYLE_DEFAULT,
+ 65, 0, 100, 1);
+ ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (menuitem), IDO_SCALE_MENU_ITEM_STYLE_IMAGE);
+ image = ido_scale_menu_item_get_primary_image (IDO_SCALE_MENU_ITEM (menuitem));
+ gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
+ image = ido_scale_menu_item_get_secondary_image (IDO_SCALE_MENU_ITEM (menuitem));
+ gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ g_signal_connect (menuitem, "slider-grabbed", G_CALLBACK (slider_grabbed), NULL);
+ g_signal_connect (menuitem, "slider-released", G_CALLBACK (slider_released), NULL);
+
+ menuitem = ido_entry_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ menuitem = ido_calendar_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ menuitem = ido_scale_menu_item_new_with_range ("Volume",
+ IDO_RANGE_STYLE_SMALL,
+ 65, 0, 100, 1);
+ ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (menuitem), IDO_SCALE_MENU_ITEM_STYLE_IMAGE);
+ image = ido_scale_menu_item_get_primary_image (IDO_SCALE_MENU_ITEM (menuitem));
+ gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
+ image = ido_scale_menu_item_get_secondary_image (IDO_SCALE_MENU_ITEM (menuitem));
+ gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ g_signal_connect (menuitem, "slider-grabbed", G_CALLBACK (slider_grabbed), NULL);
+ g_signal_connect (menuitem, "slider-released", G_CALLBACK (slider_released), NULL);
+
+ /* Add the menubar */
+ gtk_menu_shell_append (GTK_MENU_SHELL (menubar), root);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
=== added file 'example/messagedialog.c'
--- example/messagedialog.c 1970-01-01 00:00:00 +0000
+++ example/messagedialog.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,57 @@
+#include <gtk/gtk.h>
+
+#include "idomessagedialog.h"
+
+static void
+response_cb (GtkDialog *dialog,
+ gint response,
+ gpointer user_data)
+{
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+button_clicked_cb (GtkWidget *button, gpointer data)
+{
+ GtkWidget *window = (GtkWidget *) data;
+ GtkWidget *dialog = ido_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE,
+ "This is a test of the emergency broadcasting system");
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
+ "If this had been an actual emergency, you'd be dead already");
+ g_signal_connect (G_OBJECT (dialog),
+ "response",
+ G_CALLBACK (response_cb), NULL);
+ gtk_widget_show (dialog);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *button;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Message Dialogs");
+ g_signal_connect (window, "destroy", gtk_main_quit, NULL);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ button = gtk_button_new_with_label ("Confirmation dialog");
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (button_clicked_cb),
+ window);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
=== added file 'libido.pc.in'
--- libido.pc.in 1970-01-01 00:00:00 +0000
+++ libido.pc.in 2011-05-12 10:11:02 +0000
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libido
+Description: Ayatana Indicator Display Objects
+Version: @VERSION@
+Libs: -L${libdir} -lido-0.1
+Cflags: -I${includedir}/libido-0.1
+Requires: gtk+-2.0
=== added directory 'src'
=== renamed directory 'src' => 'src.moved'
=== added file 'src/Makefile.am'
--- src/Makefile.am 1970-01-01 00:00:00 +0000
+++ src/Makefile.am 2011-05-12 10:11:02 +0000
@@ -0,0 +1,82 @@
+ido_built_public_sources = \
+ idotypebuiltins.h
+
+stamp_files = \
+ idotypebuiltins.h \
+ idotypebuiltins.c
+
+sources_h = \
+ idocalendarmenuitem.h \
+ idoentrymenuitem.h \
+ idomessagedialog.h \
+ idorange.h \
+ idoscalemenuitem.h \
+ idotimeline.h \
+ libido.h
+
+EXTRA_DIST = \
+ ido.list \
+ idotypebuiltins.h.template \
+ idotypebuiltins.c.template
+
+idotypebuiltins.h: stamp-idotypebuiltins.h
+
+stamp-idotypebuiltins.h: $(sources_h)
+ ( cd $(srcdir) && $(GLIB_MKENUMS) --template idotypebuiltins.h.template \
+ $(sources_h) ) >> xgen-gtbh \
+ && (cmp -s xgen-gtbh idotypebuiltins.h || cp xgen-gtbh idotypebuiltins.h ) \
+ && rm -f xgen-gtbh && echo timestamp > $(@F)
+
+idotypebuiltins.c: stamp-idotypebuiltins.h
+ ( cd $(srcdir) && $(GLIB_MKENUMS) --template idotypebuiltins.c.template \
+ $(sources_h) ) > xgen-gtbc \
+ && cp xgen-gtbc idotypebuiltins.c && rm -f xgen-gtbc
+
+INCLUDES = \
+ -I$(srcdir) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"IDO\" \
+ -DPREFIX=\"$(prefix)"\" \
+ -DLIBDIR=\"$(libdir)"\" \
+ -DG_DISABLE_DEPRECATED \
+ -DGDK_PIXBUF_DISABLE_DEPRECATED \
+ -DGDK_DISABLE_DEPRECATED \
+ -DGTK_DISABLE_DEPRECATED
+
+AM_CPPFLAGS = \
+ $(GCC_FLAGS) \
+ $(GTK_CFLAGS) \
+ $(MAINTAINER_CFLAGS)
+
+lib_LTLIBRARIES = libido-0.1.la
+
+libido_0_1_la_SOURCES = \
+ idotypebuiltins.c \
+ idocalendarmenuitem.c \
+ idoentrymenuitem.c \
+ idomessagedialog.c \
+ idorange.c \
+ idoscalemenuitem.c \
+ idotimeline.c
+
+libidoincludedir=$(includedir)/libido-0.1/libido
+
+libidoinclude_HEADERS = \
+ idocalendarmenuitem.h \
+ idoentrymenuitem.h \
+ idomessagedialog.h \
+ idorange.h \
+ idoscalemenuitem.h \
+ idotimeline.h \
+ libido.h
+
+libido_0_1_la_LIBADD = $(GTK_LIBS)
+libido_0_1_la_LDFLAGS = $(GTK_LT_LDFLAGS)
+
+idoheadersdir = $(includedir)/ido-0.1/ido
+
+DISTCLEANFILES = \
+ stamp-idotypebuiltins.h \
+ idotypebuiltins.h \
+ idotypebuiltins.c
+
=== added file 'src/ido.list'
--- src/ido.list 1970-01-01 00:00:00 +0000
+++ src/ido.list 2011-05-12 10:11:02 +0000
@@ -0,0 +1,1 @@
+VOID:POINTER,UINT
=== added file 'src/idocalendarmenuitem.c'
--- src/idocalendarmenuitem.c 1970-01-01 00:00:00 +0000
+++ src/idocalendarmenuitem.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include "idocalendarmenuitem.h"
+
+static void ido_calendar_menu_item_select (GtkItem *item);
+static void ido_calendar_menu_item_deselect (GtkItem *item);
+static gboolean ido_calendar_menu_item_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean ido_calendar_menu_item_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean ido_calendar_menu_item_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data);
+static void ido_calendar_menu_item_send_focus_change (GtkWidget *widget,
+ gboolean in);
+static void calendar_realized_cb (GtkWidget *widget,
+ IdoCalendarMenuItem *item);
+static void calendar_move_focus_cb (GtkWidget *widget,
+ GtkDirectionType direction,
+ IdoCalendarMenuItem *item);
+static void calendar_month_changed_cb (GtkWidget *widget,
+ gpointer user_data);
+static void calendar_day_selected_double_click_cb (GtkWidget *widget,
+ gpointer user_data);
+static void calendar_day_selected_cb (GtkWidget *widget,
+ gpointer user_data);
+struct _IdoCalendarMenuItemPrivate
+{
+ GtkWidget *box;
+ GtkWidget *calendar;
+ gboolean selected;
+};
+
+G_DEFINE_TYPE (IdoCalendarMenuItem, ido_calendar_menu_item, GTK_TYPE_MENU_ITEM)
+
+#define IDO_CALENDAR_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemPrivate))
+
+static void
+ido_calendar_menu_item_class_init (IdoCalendarMenuItemClass *klass)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *widget_class;
+ GtkMenuItemClass *menu_item_class;
+ GtkItemClass *item_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+ menu_item_class = GTK_MENU_ITEM_CLASS (klass);
+ item_class = GTK_ITEM_CLASS (klass);
+
+ widget_class->button_release_event = ido_calendar_menu_item_button_release;
+ widget_class->button_press_event = ido_calendar_menu_item_button_press;
+
+ item_class->select = ido_calendar_menu_item_select;
+ item_class->deselect = ido_calendar_menu_item_deselect;
+
+ menu_item_class->hide_on_activate = TRUE;
+
+ g_type_class_add_private (gobject_class, sizeof (IdoCalendarMenuItemPrivate));
+
+ g_signal_new("month-changed", G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_signal_new("day-selected", G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ g_signal_new("day-selected-double-click", G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+ido_calendar_menu_item_init (IdoCalendarMenuItem *item)
+{
+ IdoCalendarMenuItemPrivate *priv;
+ GtkBorder border;
+
+ border.left = 4;
+ border.right = 4;
+ border.top = 2;
+ border.bottom = 2;
+
+ priv = item->priv = IDO_CALENDAR_MENU_ITEM_GET_PRIVATE (item);
+
+ /* Will be disposed automatically */
+ priv->calendar = g_object_new (gtk_calendar_get_type (),
+ NULL);
+
+ g_signal_connect (priv->calendar,
+ "realize",
+ G_CALLBACK (calendar_realized_cb),
+ item);
+ g_signal_connect (priv->calendar,
+ "move-focus",
+ G_CALLBACK (calendar_move_focus_cb),
+ item);
+
+ priv->box = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->box), priv->calendar, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (item), priv->box);
+
+ gtk_widget_show_all (priv->box);
+}
+
+static void
+ido_calendar_menu_item_send_focus_change (GtkWidget *widget,
+ gboolean in)
+{
+ GdkEvent *event = gdk_event_new (GDK_FOCUS_CHANGE);
+
+ g_object_ref (widget);
+
+ if (in)
+ gtk_widget_grab_focus (widget);
+
+ event->focus_change.type = GDK_FOCUS_CHANGE;
+ event->focus_change.window = g_object_ref (widget->window);
+ event->focus_change.in = in;
+
+ gtk_widget_event (widget, event);
+
+ g_object_notify (G_OBJECT (widget), "has-focus");
+
+ g_object_unref (widget);
+ gdk_event_free (event);
+}
+
+static gboolean
+ido_calendar_menu_item_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
+{
+ IdoCalendarMenuItem *menuitem = (IdoCalendarMenuItem *)data;
+
+ if (menuitem->priv->selected)
+ {
+ GtkWidget *calendar = menuitem->priv->calendar;
+
+ gtk_widget_event (calendar,
+ ((GdkEvent *)(void*)(event)));
+
+ if (calendar->window != NULL)
+ {
+ gdk_window_raise (calendar->window);
+ }
+
+ if (!gtk_widget_has_focus (calendar))
+ {
+ gtk_widget_grab_focus (calendar);
+ }
+
+ return event->keyval != GDK_Return;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+ido_calendar_menu_item_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidget *calendar = IDO_CALENDAR_MENU_ITEM (widget)->priv->calendar;
+
+ if (event->button == 1)
+ {
+ if (calendar->window != NULL)
+ {
+ gdk_window_raise (calendar->window);
+ }
+
+ if (!gtk_widget_has_focus (calendar))
+ {
+ gtk_widget_grab_focus (calendar);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+ido_calendar_menu_item_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidget *calendar = IDO_CALENDAR_MENU_ITEM (widget)->priv->calendar;
+
+ return TRUE;
+}
+
+static void
+ido_calendar_menu_item_select (GtkItem *item)
+{
+ IDO_CALENDAR_MENU_ITEM (item)->priv->selected = TRUE;
+
+ ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), TRUE);
+}
+
+static void
+ido_calendar_menu_item_deselect (GtkItem *item)
+{
+ IDO_CALENDAR_MENU_ITEM (item)->priv->selected = FALSE;
+
+ ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), FALSE);
+}
+
+
+static void
+calendar_realized_cb (GtkWidget *widget,
+ IdoCalendarMenuItem *item)
+{
+ if (widget->window != NULL)
+ {
+ gdk_window_raise (widget->window);
+ }
+
+ g_signal_connect (GTK_WIDGET (item)->parent,
+ "key-press-event",
+ G_CALLBACK (ido_calendar_menu_item_key_press),
+ item);
+
+ g_signal_connect (item->priv->calendar,
+ "month-changed",
+ G_CALLBACK (calendar_month_changed_cb),
+ item);
+ g_signal_connect (item->priv->calendar,
+ "day-selected",
+ G_CALLBACK (calendar_day_selected_cb),
+ item);
+ g_signal_connect (item->priv->calendar,
+ "day-selected-double-click",
+ G_CALLBACK (calendar_day_selected_double_click_cb),
+ item);
+
+ ido_calendar_menu_item_send_focus_change (widget, TRUE);
+}
+
+static void
+calendar_move_focus_cb (GtkWidget *widget,
+ GtkDirectionType direction,
+ IdoCalendarMenuItem *item)
+{
+ ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), FALSE);
+
+ g_signal_emit_by_name (item,
+ "move-focus",
+ GTK_DIR_TAB_FORWARD);
+}
+
+static void
+calendar_month_changed_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data;
+ g_signal_emit_by_name (item, "month-changed", NULL);
+}
+
+static void
+calendar_day_selected_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data;
+ g_signal_emit_by_name (item, "day-selected", NULL);
+}
+
+static void
+calendar_day_selected_double_click_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data;
+ guint day, month, year;
+ gtk_calendar_get_date (GTK_CALENDAR (widget), &year, &month, &day);
+ g_signal_emit_by_name (item, "day-selected-double-click", NULL);
+}
+
+/* Public API */
+GtkWidget *
+ido_calendar_menu_item_new (void)
+{
+ return g_object_new (IDO_TYPE_CALENDAR_MENU_ITEM, NULL);
+}
+
+GtkWidget *
+ido_calendar_menu_item_get_calendar (IdoCalendarMenuItem *item)
+{
+ g_return_val_if_fail (IDO_IS_CALENDAR_MENU_ITEM (item), NULL);
+
+ return item->priv->calendar;
+}
+
+gboolean
+ido_calendar_menu_item_mark_day (IdoCalendarMenuItem *menuitem, guint day)
+{
+ g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE);
+
+ return gtk_calendar_mark_day(GTK_CALENDAR (menuitem->priv->calendar), day);
+}
+
+gboolean
+ido_calendar_menu_item_unmark_day (IdoCalendarMenuItem *menuitem, guint day)
+{
+ g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE);
+
+ return gtk_calendar_unmark_day(GTK_CALENDAR (menuitem->priv->calendar), day);
+}
+
+void
+ido_calendar_menu_item_clear_marks (IdoCalendarMenuItem *menuitem)
+{
+ g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem));
+
+ gtk_calendar_clear_marks(GTK_CALENDAR (menuitem->priv->calendar));
+}
+
+void
+ido_calendar_menu_item_set_display_options (IdoCalendarMenuItem *menuitem, GtkCalendarDisplayOptions flags)
+{
+ g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem));
+
+ gtk_calendar_set_display_options (GTK_CALENDAR (menuitem->priv->calendar), flags);
+}
+
+GtkCalendarDisplayOptions
+ido_calendar_menu_item_get_display_options (IdoCalendarMenuItem *menuitem)
+{
+ g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), 0);
+
+ return gtk_calendar_get_display_options (GTK_CALENDAR (menuitem->priv->calendar));
+}
+
+void
+ido_calendar_menu_item_get_date (IdoCalendarMenuItem *menuitem,
+ guint *year,
+ guint *month,
+ guint *day) {
+
+ g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem));
+ gtk_calendar_get_date (GTK_CALENDAR (menuitem->priv->calendar), year, month, day);
+}
+
+gboolean
+ido_calendar_menu_item_set_date (IdoCalendarMenuItem *menuitem,
+ guint year,
+ guint month,
+ guint day)
+{
+ g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE);
+ gtk_calendar_select_month (GTK_CALENDAR (menuitem->priv->calendar), month, year);
+ gtk_calendar_select_day (GTK_CALENDAR (menuitem->priv->calendar), day);
+ return TRUE;
+}
+
+
+
=== added file 'src/idocalendarmenuitem.h'
--- src/idocalendarmenuitem.h 1970-01-01 00:00:00 +0000
+++ src/idocalendarmenuitem.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO_CALENDAR_MENU_ITEM_H__
+#define __IDO_CALENDAR_MENU_ITEM_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDO_TYPE_CALENDAR_MENU_ITEM (ido_calendar_menu_item_get_type ())
+#define IDO_CALENDAR_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItem))
+#define IDO_CALENDAR_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemClass))
+#define IDO_IS_CALENDAR_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_CALENDAR_MENU_ITEM))
+#define IDO_IS_CALENDAR_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_CALENDAR_MENU_ITEM))
+#define IDO_CALENDAR_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemClass))
+
+typedef struct _IdoCalendarMenuItem IdoCalendarMenuItem;
+typedef struct _IdoCalendarMenuItemClass IdoCalendarMenuItemClass;
+typedef struct _IdoCalendarMenuItemPrivate IdoCalendarMenuItemPrivate;
+
+struct _IdoCalendarMenuItem
+{
+ GtkMenuItem parent_instance;
+
+ IdoCalendarMenuItemPrivate *priv;
+};
+
+struct _IdoCalendarMenuItemClass
+{
+ GtkMenuItemClass parent_class;
+};
+
+GType ido_calendar_menu_item_get_type (void) G_GNUC_CONST;
+
+GtkWidget *ido_calendar_menu_item_new (void);
+GtkWidget *ido_calendar_menu_item_get_calendar (IdoCalendarMenuItem *menuitem);
+gboolean ido_calendar_menu_item_mark_day (IdoCalendarMenuItem *menuitem, guint day);
+gboolean ido_calendar_menu_item_unmark_day (IdoCalendarMenuItem *menuitem, guint day);
+void ido_calendar_menu_item_clear_marks (IdoCalendarMenuItem *menuitem);
+void ido_calendar_menu_item_set_display_options (IdoCalendarMenuItem *menuitem, GtkCalendarDisplayOptions flags);
+GtkCalendarDisplayOptions ido_calendar_menu_item_get_display_options (IdoCalendarMenuItem *menuitem);
+void ido_calendar_menu_item_get_date (IdoCalendarMenuItem *menuitem,
+ guint *year,
+ guint *month,
+ guint *day);
+gboolean ido_calendar_menu_item_set_date (IdoCalendarMenuItem *menuitem,
+ guint year,
+ guint month,
+ guint day);
+G_END_DECLS
+
+#endif /* __IDO_CALENDAR_MENU_ITEM_H__ */
=== added file 'src/idoentrymenuitem.c'
--- src/idoentrymenuitem.c 1970-01-01 00:00:00 +0000
+++ src/idoentrymenuitem.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include "idoentrymenuitem.h"
+
+static void ido_entry_menu_item_select (GtkItem *item);
+static void ido_entry_menu_item_deselect (GtkItem *item);
+static gboolean ido_entry_menu_item_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean ido_entry_menu_item_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data);
+static gboolean ido_entry_menu_item_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static void ido_entry_menu_item_send_focus_change (GtkWidget *widget,
+ gboolean in);
+static void entry_realized_cb (GtkWidget *widget,
+ IdoEntryMenuItem *item);
+static void entry_move_focus_cb (GtkWidget *widget,
+ GtkDirectionType direction,
+ IdoEntryMenuItem *item);
+
+struct _IdoEntryMenuItemPrivate
+{
+ GtkWidget *box;
+ GtkWidget *entry;
+ gboolean selected;
+};
+
+G_DEFINE_TYPE (IdoEntryMenuItem, ido_entry_menu_item, GTK_TYPE_MENU_ITEM)
+
+#define IDO_ENTRY_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemPrivate))
+
+static void
+ido_entry_menu_item_class_init (IdoEntryMenuItemClass *klass)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *widget_class;
+ GtkMenuItemClass *menu_item_class;
+ GtkItemClass *item_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+ menu_item_class = GTK_MENU_ITEM_CLASS (klass);
+ item_class = GTK_ITEM_CLASS (klass);
+
+ widget_class->button_release_event = ido_entry_menu_item_button_release;
+ widget_class->button_press_event = ido_entry_menu_item_button_press;
+
+ item_class->select = ido_entry_menu_item_select;
+ item_class->deselect = ido_entry_menu_item_deselect;
+
+ menu_item_class->hide_on_activate = TRUE;
+
+ g_type_class_add_private (gobject_class, sizeof (IdoEntryMenuItemPrivate));
+}
+
+static void
+ido_entry_menu_item_init (IdoEntryMenuItem *item)
+{
+ IdoEntryMenuItemPrivate *priv;
+ GtkBorder border;
+
+ border.left = 4;
+ border.right = 4;
+ border.top = 2;
+ border.bottom = 2;
+
+ priv = item->priv = IDO_ENTRY_MENU_ITEM_GET_PRIVATE (item);
+
+ priv->entry = g_object_new (gtk_entry_get_type (),
+ "inner-border", &border,
+ NULL);
+
+ g_signal_connect (priv->entry,
+ "realize",
+ G_CALLBACK (entry_realized_cb),
+ item);
+ g_signal_connect (priv->entry,
+ "move-focus",
+ G_CALLBACK (entry_move_focus_cb),
+ item);
+
+ priv->box = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->box), priv->entry, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (item), priv->box);
+
+ gtk_widget_show_all (priv->box);
+}
+
+static gboolean
+is_key_press_valid (IdoEntryMenuItem *item,
+ gint key)
+{
+ switch (key)
+ {
+ case GDK_Escape:
+ case GDK_Up:
+ case GDK_Down:
+ case GDK_KP_Up:
+ case GDK_KP_Down:
+ return FALSE;
+
+ default:
+ return TRUE;
+ }
+}
+
+static gboolean
+ido_entry_menu_item_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
+{
+ IdoEntryMenuItem *menuitem = (IdoEntryMenuItem *)data;
+
+ if (menuitem->priv->selected &&
+ is_key_press_valid (menuitem, event->keyval))
+ {
+ GtkWidget *entry = menuitem->priv->entry;
+
+ gtk_widget_event (entry,
+ ((GdkEvent *)(void*)(event)));
+
+ /* We've handled the event, but if the key was GDK_Return
+ * we still want to forward the event up to the menu shell
+ * to ensure that the menuitem receives the activate signal.
+ */
+ return event->keyval != GDK_Return;
+ }
+
+ return FALSE;
+}
+
+static void
+ido_entry_menu_item_send_focus_change (GtkWidget *widget,
+ gboolean in)
+{
+ GdkEvent *event = gdk_event_new (GDK_FOCUS_CHANGE);
+
+ g_object_ref (widget);
+
+ event->focus_change.type = GDK_FOCUS_CHANGE;
+ event->focus_change.window = g_object_ref (widget->window);
+ event->focus_change.in = in;
+
+ gtk_widget_event (widget, event);
+
+ g_object_notify (G_OBJECT (widget), "has-focus");
+
+ g_object_unref (widget);
+ gdk_event_free (event);
+}
+
+static gboolean
+ido_entry_menu_item_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidget *entry = IDO_ENTRY_MENU_ITEM (widget)->priv->entry;
+
+ if (event->button == 1)
+ {
+ if (entry->window != NULL)
+ {
+ gdk_window_raise (entry->window);
+ }
+
+ if (!gtk_widget_has_focus (entry))
+ {
+ gtk_widget_grab_focus (entry);
+ }
+
+ gtk_widget_event (entry,
+ ((GdkEvent *)(void*)(event)));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+ido_entry_menu_item_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidget *entry = IDO_ENTRY_MENU_ITEM (widget)->priv->entry;
+
+ gtk_widget_event (entry,
+ ((GdkEvent *)(void*)(event)));
+
+ return TRUE;
+}
+
+static void
+ido_entry_menu_item_select (GtkItem *item)
+{
+ IDO_ENTRY_MENU_ITEM (item)->priv->selected = TRUE;
+
+ ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), TRUE);
+}
+
+static void
+ido_entry_menu_item_deselect (GtkItem *item)
+{
+ IDO_ENTRY_MENU_ITEM (item)->priv->selected = FALSE;
+
+ ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE);
+}
+
+
+static void
+entry_realized_cb (GtkWidget *widget,
+ IdoEntryMenuItem *item)
+{
+ if (widget->window != NULL)
+ {
+ gdk_window_raise (widget->window);
+ }
+
+ g_signal_connect (GTK_WIDGET (item)->parent,
+ "key-press-event",
+ G_CALLBACK (ido_entry_menu_item_key_press),
+ item);
+
+ ido_entry_menu_item_send_focus_change (widget, TRUE);
+}
+
+static void
+entry_move_focus_cb (GtkWidget *widget,
+ GtkDirectionType direction,
+ IdoEntryMenuItem *item)
+{
+ ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE);
+
+ g_signal_emit_by_name (item,
+ "move-focus",
+ GTK_DIR_TAB_FORWARD);
+}
+
+/* Public API */
+GtkWidget *
+ido_entry_menu_item_new (void)
+{
+ return g_object_new (IDO_TYPE_ENTRY_MENU_ITEM, NULL);
+}
+
+GtkWidget *
+ido_entry_menu_item_get_entry (IdoEntryMenuItem *item)
+{
+ g_return_val_if_fail (IDO_IS_ENTRY_MENU_ITEM (item), NULL);
+
+ return item->priv->entry;
+}
=== added file 'src/idoentrymenuitem.h'
--- src/idoentrymenuitem.h 1970-01-01 00:00:00 +0000
+++ src/idoentrymenuitem.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO_ENTRY_MENU_ITEM_H__
+#define __IDO_ENTRY_MENU_ITEM_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDO_TYPE_ENTRY_MENU_ITEM (ido_entry_menu_item_get_type ())
+#define IDO_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItem))
+#define IDO_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass))
+#define IDO_IS_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_ENTRY_MENU_ITEM))
+#define IDO_IS_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_ENTRY_MENU_ITEM))
+#define IDO_ENTRY_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass))
+
+typedef struct _IdoEntryMenuItem IdoEntryMenuItem;
+typedef struct _IdoEntryMenuItemClass IdoEntryMenuItemClass;
+typedef struct _IdoEntryMenuItemPrivate IdoEntryMenuItemPrivate;
+
+struct _IdoEntryMenuItem
+{
+ GtkMenuItem parent_instance;
+
+ IdoEntryMenuItemPrivate *priv;
+};
+
+struct _IdoEntryMenuItemClass
+{
+ GtkMenuItemClass parent_class;
+};
+
+GType ido_entry_menu_item_get_type (void) G_GNUC_CONST;
+
+GtkWidget *ido_entry_menu_item_new (void);
+GtkWidget *ido_entry_menu_item_get_entry (IdoEntryMenuItem *menuitem);
+
+G_END_DECLS
+
+#endif /* __IDO_ENTRY_MENU_ITEM_H__ */
=== added file 'src/idomessagedialog.c'
--- src/idomessagedialog.c 1970-01-01 00:00:00 +0000
+++ src/idomessagedialog.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ *
+ * Design and specification:
+ * Matthew Paul Thomas <mpt@xxxxxxxxxxxxx>
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "idomessagedialog.h"
+#include "idotimeline.h"
+
+#define IDO_MESSAGE_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogPrivate))
+
+static GtkWidget *ido_message_dialog_get_secondary_label (IdoMessageDialog *dialog);
+static GtkWidget *ido_message_dialog_get_primary_label (IdoMessageDialog *dialog);
+
+typedef struct _IdoMessageDialogPrivate IdoMessageDialogPrivate;
+typedef struct _IdoMessageDialogMorphContext IdoMessageDialogMorphContext;
+
+struct _IdoMessageDialogPrivate
+{
+ GtkWidget *action_area;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+
+ gboolean expanded;
+};
+
+struct _IdoMessageDialogMorphContext
+{
+ GtkWidget *widget;
+ IdoTimeline *timeline;
+
+ GtkRequisition start;
+ GtkRequisition end;
+};
+
+G_DEFINE_TYPE (IdoMessageDialog, ido_message_dialog, GTK_TYPE_MESSAGE_DIALOG)
+
+static void
+ido_message_dialog_map (GtkWidget *widget)
+{
+ IdoMessageDialog *dialog = IDO_MESSAGE_DIALOG (widget);
+ IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (dialog);
+
+ GTK_WIDGET_CLASS (ido_message_dialog_parent_class)->map (widget);
+
+ priv->primary_label = ido_message_dialog_get_primary_label (dialog);
+ priv->secondary_label = ido_message_dialog_get_secondary_label (dialog);
+
+ gtk_widget_hide (priv->secondary_label);
+
+ gtk_label_set_selectable (GTK_LABEL (priv->primary_label), FALSE);
+ gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), FALSE);
+
+ /* XXX: We really want to use gtk_window_set_deletable (GTK_WINDOW (widget), FALSE)
+ * here, but due to a bug in compiz this is more compatible.
+ *
+ * See: https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/240794
+ */
+ gdk_window_set_functions (widget->window,
+ GDK_FUNC_RESIZE | GDK_FUNC_MOVE);
+
+ ido_message_dialog_get_secondary_label (IDO_MESSAGE_DIALOG (widget));
+}
+
+static IdoMessageDialogMorphContext *
+ido_message_dialog_morph_context_new (GtkWidget *widget,
+ IdoTimeline *timeline,
+ gpointer identifier,
+ GtkRequisition *start,
+ GtkRequisition *end)
+{
+ IdoMessageDialogMorphContext *context;
+
+ context = g_slice_new (IdoMessageDialogMorphContext);
+
+ context->widget = widget;
+ context->timeline = timeline;
+ context->start = *start;
+ context->end = *end;
+
+ return context;
+}
+
+static void
+ido_message_dialog_morph_context_free (IdoMessageDialogMorphContext *context)
+{
+ g_object_unref (context->timeline);
+
+ g_slice_free (IdoMessageDialogMorphContext, context);
+}
+
+static void
+timeline_frame_cb (IdoTimeline *timeline,
+ gdouble progress,
+ gpointer user_data)
+{
+ IdoMessageDialogMorphContext *context = user_data;
+ GtkRequisition start = context->start;
+ GtkRequisition end = context->end;
+ gint width_diff;
+ gint height_diff;
+ gint width, height;
+
+ width_diff = (MAX(start.width, end.width) - MIN(start.width, end.width)) * progress;
+ height_diff = (MAX(start.height, end.height) - MIN(start.height, end.height)) * progress;
+
+ gtk_window_get_size (GTK_WINDOW (context->widget),
+ &width,
+ &height);
+
+ gtk_widget_set_size_request (context->widget,
+ width_diff ? start.width + width_diff : -1,
+ height_diff ? start.height + height_diff : -1);
+}
+
+static void
+timeline_finished_cb (IdoTimeline *timeline,
+ gpointer user_data)
+{
+ IdoMessageDialogMorphContext *context = user_data;
+ IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (context->widget);
+
+ gtk_widget_show (priv->action_area);
+ gtk_widget_show (priv->secondary_label);
+
+ ido_message_dialog_morph_context_free (context);
+}
+
+static gboolean
+ido_message_dialog_focus_in_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ IdoMessageDialog *dialog = IDO_MESSAGE_DIALOG (widget);
+ IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (dialog);
+
+ if (!priv->expanded)
+ {
+ GtkRequisition start;
+ GtkRequisition end;
+ IdoTimeline *timeline;
+ IdoMessageDialogMorphContext *context;
+
+ start = GTK_WIDGET (dialog)->requisition;
+
+ priv->expanded = TRUE;
+
+ gtk_widget_show (priv->action_area);
+ gtk_widget_show (priv->secondary_label);
+
+ gtk_widget_size_request (GTK_WIDGET (dialog), &end);
+
+ gtk_widget_hide (priv->action_area);
+ gtk_widget_hide (priv->secondary_label);
+
+ timeline = ido_timeline_new (500);
+ context = ido_message_dialog_morph_context_new (GTK_WIDGET (dialog),
+ timeline,
+ "foo",
+ &start,
+ &end);
+ g_signal_connect (timeline,
+ "frame",
+ G_CALLBACK (timeline_frame_cb),
+ context);
+ g_signal_connect (timeline,
+ "finished",
+ G_CALLBACK (timeline_finished_cb),
+ context);
+
+ ido_timeline_start (timeline);
+ }
+
+ return FALSE;
+}
+
+static void
+ido_message_dialog_constructed (GObject *object)
+{
+ IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (object);
+ GtkWidget *vbox;
+ GtkWidget *event_box;
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (event_box);
+
+ vbox = GTK_DIALOG (object)->vbox;
+ priv->action_area = gtk_dialog_get_action_area (GTK_DIALOG (object));
+
+ g_object_ref (G_OBJECT (vbox));
+ gtk_container_remove (GTK_CONTAINER (object), vbox);
+ gtk_container_add (GTK_CONTAINER (event_box), vbox);
+ gtk_container_add (GTK_CONTAINER (object), event_box);
+
+ gtk_widget_hide (priv->action_area);
+}
+
+static void
+ido_message_dialog_class_init (IdoMessageDialogClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->constructed = ido_message_dialog_constructed;
+
+ widget_class->map = ido_message_dialog_map;
+ widget_class->focus_in_event = ido_message_dialog_focus_in_event;
+
+ g_type_class_add_private (object_class, sizeof (IdoMessageDialogPrivate));
+}
+
+static void
+ido_message_dialog_init (IdoMessageDialog *dialog)
+{
+ IdoMessageDialogPrivate *priv;
+
+ gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE);
+
+ priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (dialog);
+}
+
+/**
+ * ido_message_dialog_new:
+ * @parent: transient parent, or %NULL for none
+ * @flags: flags
+ * @type: type of message
+ * @buttons: a set of buttons to use
+ * @message_format: printf()-style format string, or %NULL
+ * @Varargs: arguments for @message_format
+ *
+ * Creates a new message dialog, which is based upon
+ * GtkMessageDialog so it shares API and functionality
+ * with it. IdoMessageDialog differs in that it has two
+ * states. The initial state hides the action buttons
+ * and the secondary message. When a user clicks on the
+ * dialog it will expand to provide the secondary message
+ * and the action buttons.
+ *
+ * Return value: a new #IdoMessageDialog
+ **/
+GtkWidget*
+ido_message_dialog_new (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GtkMessageType type,
+ GtkButtonsType buttons,
+ const gchar *message_format,
+ ...)
+{
+ GtkWidget *widget;
+ GtkDialog *dialog;
+ gchar* msg = NULL;
+ va_list args;
+
+ g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
+
+ widget = g_object_new (IDO_TYPE_MESSAGE_DIALOG,
+ "message-type", type,
+ "buttons", buttons,
+ NULL);
+ dialog = GTK_DIALOG (widget);
+
+ if (flags & GTK_DIALOG_NO_SEPARATOR)
+ {
+ g_warning ("The GTK_DIALOG_NO_SEPARATOR flag cannot be used for IdoMessageDialog");
+ flags &= ~GTK_DIALOG_NO_SEPARATOR;
+ }
+
+ if (message_format)
+ {
+ va_start (args, message_format);
+ msg = g_strdup_vprintf (message_format, args);
+ va_end (args);
+
+ gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (widget)->label),
+ msg);
+
+ g_free (msg);
+ }
+
+ if (parent != NULL)
+ gtk_window_set_transient_for (GTK_WINDOW (widget),
+ GTK_WINDOW (parent));
+
+ if (flags & GTK_DIALOG_MODAL)
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+
+ return widget;
+}
+
+GtkWidget*
+ido_message_dialog_new_with_markup (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GtkMessageType type,
+ GtkButtonsType buttons,
+ const gchar *message_format,
+ ...)
+{
+ GtkWidget *widget;
+ va_list args;
+ gchar *msg = NULL;
+
+ g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
+
+ widget = ido_message_dialog_new (parent, flags, type, buttons, NULL);
+
+ if (message_format)
+ {
+ va_start (args, message_format);
+ msg = g_markup_vprintf_escaped (message_format, args);
+ va_end (args);
+
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (widget), msg);
+
+ g_free (msg);
+ }
+
+ return widget;
+}
+
+ /*
+ * This is almost humorously stupid. We jump through some hoops and kill
+ * a few kittens here because we want to preserve API compatibility with
+ * GtkMessageDialog and extend it instead of duplicating its functionality.
+ * If only GtkMessageDialog were easier to extend then maybe all those
+ * kittens wouldn't have had to die...
+ */
+static GtkWidget *
+ido_message_dialog_get_label (IdoMessageDialog *dialog, gboolean primary)
+{
+ GList *list;
+ gchar *text;
+ gchar *secondary_text;
+ GtkWidget *content;
+ GList *children;
+
+ g_object_get (G_OBJECT (dialog),
+ "text", &text,
+ "secondary-text", &secondary_text,
+ NULL);
+
+ g_return_val_if_fail (IDO_IS_MESSAGE_DIALOG (dialog), NULL);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ children = gtk_container_get_children (GTK_CONTAINER (content));
+
+ for (list = children; list != NULL; list = list->next)
+ {
+ if (G_TYPE_FROM_INSTANCE (list->data) == GTK_TYPE_HBOX)
+ {
+ GList *hchildren;
+ GList *hlist;
+ GtkWidget *hbox = GTK_WIDGET (list->data);
+
+ hchildren = gtk_container_get_children (GTK_CONTAINER (hbox));
+
+ for (hlist = hchildren; hlist != NULL; hlist = hlist->next)
+ {
+ if (G_TYPE_FROM_INSTANCE (hlist->data) == GTK_TYPE_VBOX)
+ {
+ GList *vlist;
+ GtkWidget *vbox = GTK_WIDGET (hlist->data);
+ GList *vchildren;
+
+ vchildren = gtk_container_get_children (GTK_CONTAINER (vbox));
+
+ for (vlist = vchildren; vlist != NULL; vlist = vlist->next)
+ {
+ GtkLabel *label;
+
+ label = GTK_LABEL (vlist->data);
+
+ if (strcmp ((primary ? text : secondary_text), label->label) == 0)
+ {
+ return GTK_WIDGET (label);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static GtkWidget *
+ido_message_dialog_get_secondary_label (IdoMessageDialog *dialog)
+{
+ return ido_message_dialog_get_label (dialog, FALSE);
+}
+
+static GtkWidget *
+ido_message_dialog_get_primary_label (IdoMessageDialog *dialog)
+{
+ return ido_message_dialog_get_label (dialog, TRUE);
+}
=== added file 'src/idomessagedialog.h'
--- src/idomessagedialog.h 1970-01-01 00:00:00 +0000
+++ src/idomessagedialog.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ *
+ * Design and specification:
+ * Matthew Paul Thomas <mpt@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO_MESSAGE_DIALOG_H__
+#define __IDO_MESSAGE_DIALOG_H__
+
+#include <gtk/gtkmessagedialog.h>
+
+#define IDO_TYPE_MESSAGE_DIALOG (ido_message_dialog_get_type ())
+#define IDO_MESSAGE_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialog))
+#define IDO_MESSAGE_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogClass))
+#define IDO_IS_MESSAGE_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_MESSAGE_DIALOG))
+#define IDO_IS_MESSAGE_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_MESSAGE_DIALOG))
+#define IDO_MESSAGE_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogClass))
+
+typedef struct _IdoMessageDialog IdoMessageDialog;
+typedef struct _IdoMessageDialogClass IdoMessageDialogClass;
+
+struct _IdoMessageDialog
+{
+ GtkMessageDialog parent_instance;
+};
+
+struct _IdoMessageDialogClass
+{
+ GtkMessageDialogClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_ido_reserved1) (void);
+ void (*_ido_reserved2) (void);
+ void (*_ido_reserved3) (void);
+ void (*_ido_reserved4) (void);
+};
+
+GType ido_message_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget* ido_message_dialog_new (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GtkMessageType type,
+ GtkButtonsType buttons,
+ const gchar *message_format,
+ ...) G_GNUC_PRINTF (5, 6);
+
+GtkWidget* ido_message_dialog_new_with_markup (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GtkMessageType type,
+ GtkButtonsType buttons,
+ const gchar *message_format,
+ ...) G_GNUC_PRINTF (5, 6);
+
+G_END_DECLS
+
+#endif /* __IDO_MESSAGE_DIALOG_H__ */
=== added file 'src/idorange.c'
--- src/idorange.c 1970-01-01 00:00:00 +0000
+++ src/idorange.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#include "idorange.h"
+#include "idotypebuiltins.h"
+
+struct _IdoRangePrivate
+{
+ IdoRangeStyle style;
+};
+
+static void ido_range_constructed (GObject *object);
+static void ido_range_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ido_range_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+#define IDO_RANGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_RANGE, IdoRangePrivate))
+
+G_DEFINE_TYPE (IdoRange, ido_range, GTK_TYPE_SCALE)
+
+enum {
+ PROP_0,
+ PROP_STYLE
+};
+
+static void
+ido_range_class_init (IdoRangeClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ gobject_class->constructed = ido_range_constructed;
+ gobject_class->set_property = ido_range_set_property;
+ gobject_class->get_property = ido_range_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_STYLE,
+ g_param_spec_enum ("range-style",
+ "Range style",
+ "The style of the range",
+ IDO_TYPE_RANGE_STYLE,
+ IDO_RANGE_STYLE_SMALL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("knob-width",
+ "The knob width",
+ "The knob width",
+ G_MININT,
+ G_MAXINT,
+ 8,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("knob-height",
+ "The knob height",
+ "The knob height",
+ G_MININT,
+ G_MAXINT,
+ 8,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (class, sizeof (IdoRangePrivate));
+}
+
+static void
+ido_range_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdoRangePrivate *priv = IDO_RANGE (object)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_STYLE:
+ g_value_set_enum (value, priv->style);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ido_range_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdoRangePrivate *priv = IDO_RANGE (object)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_STYLE:
+ priv->style = g_value_get_enum (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ido_range_constructed (GObject *object)
+{
+ IdoRange *range = IDO_RANGE (object);
+ IdoRangeStyle style;
+ char buf[1024];
+
+ g_object_get (range,
+ "range-style", &style,
+ NULL);
+
+ g_snprintf (buf, sizeof (buf), "idorange-%p", range);
+ gtk_widget_set_name (GTK_WIDGET (range), buf);
+
+ if (style == IDO_RANGE_STYLE_SMALL)
+ {
+ gint width, height;
+
+ gtk_widget_style_get (GTK_WIDGET (range),
+ "knob-width", &width,
+ "knob-height", &height,
+ NULL);
+
+ g_snprintf (buf, sizeof (buf),
+ "style \"ido-range\" {\n"
+ " GtkRange::slider-width = %d\n"
+ " GtkScale::slider-length = %d\n"
+ "} widget \"*.idorange-%p\" style \"ido-range\"\n",
+ width, height, range);
+ gtk_rc_parse_string (buf);
+ }
+
+ gtk_range_set_slider_size_fixed (GTK_RANGE (range), TRUE);
+}
+
+static void
+ido_range_init (IdoRange *range)
+{
+ range->priv = IDO_RANGE_GET_PRIVATE (range);
+}
+
+/**
+ * ido_range_new:
+ * @adj: A #GtkAdjustment providing the range values
+ * @style: The range style
+ *
+ * Creates a new #IdoRange widget.
+ **/
+GtkWidget *
+ido_range_new (GtkObject *adj,
+ IdoRangeStyle style)
+{
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (adj), NULL);
+
+ return g_object_new (IDO_TYPE_RANGE,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "adjustment", adj,
+ "range-style", style,
+ NULL);
+}
=== added file 'src/idorange.h'
--- src/idorange.h 1970-01-01 00:00:00 +0000
+++ src/idorange.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO_RANGE_H__
+#define __IDO_RANGE_H__
+
+#include <gtk/gtk.h>
+
+#define IDO_TYPE_RANGE (ido_range_get_type ())
+#define IDO_RANGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_RANGE, IdoRange))
+#define IDO_RANGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_RANGE, IdoRangeClass))
+#define IDO_IS_RANGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_RANGE))
+#define IDO_IS_RANGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_RANGE))
+#define IDO_RANGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_RANGE, IdoRangeClass))
+
+typedef enum
+{
+ IDO_RANGE_STYLE_DEFAULT,
+ IDO_RANGE_STYLE_SMALL
+} IdoRangeStyle;
+
+typedef struct _IdoRange IdoRange;
+typedef struct _IdoRangePrivate IdoRangePrivate;
+typedef struct _IdoRangeClass IdoRangeClass;
+
+struct _IdoRange
+{
+ GtkScale parent_instance;
+ IdoRangePrivate *priv;
+};
+
+struct _IdoRangeClass
+{
+ GtkScaleClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_ido_reserved1) (void);
+ void (*_ido_reserved2) (void);
+ void (*_ido_reserved3) (void);
+ void (*_ido_reserved4) (void);
+};
+
+GType ido_range_get_type (void) G_GNUC_CONST;
+
+GtkWidget* ido_range_new (GtkObject *adj,
+ IdoRangeStyle style);
+
+G_END_DECLS
+
+#endif /* __IDO_RANGE_H__ */
=== added file 'src/idoscalemenuitem.c'
--- src/idoscalemenuitem.c 1970-01-01 00:00:00 +0000
+++ src/idoscalemenuitem.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,891 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#include <gtk/gtk.h>
+#include "idorange.h"
+#include "idoscalemenuitem.h"
+#include "idotypebuiltins.h"
+
+static void ido_scale_menu_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ido_scale_menu_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
+ GdkEventButton *event);
+static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
+ GdkEventButton *event);
+static gboolean ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem,
+ GdkEventMotion *event);
+static void ido_scale_menu_item_primary_image_notify (GtkImage *image,
+ GParamSpec *pspec,
+ IdoScaleMenuItem *item);
+static void ido_scale_menu_item_secondary_image_notify (GtkImage *image,
+ GParamSpec *pspec,
+ IdoScaleMenuItem *item);
+static void ido_scale_menu_item_notify (IdoScaleMenuItem *item,
+ GParamSpec *pspec,
+ gpointer user_data);
+static void update_packing (IdoScaleMenuItem *self,
+ IdoScaleMenuItemStyle style,
+ IdoScaleMenuItemStyle old_style);
+
+struct _IdoScaleMenuItemPrivate {
+ GtkWidget *scale;
+ GtkAdjustment *adjustment;
+ GtkWidget *primary_image;
+ GtkWidget *secondary_image;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ GtkWidget *hbox;
+ GtkAllocation child_allocation;
+ gdouble left_padding;
+ gdouble right_padding;
+ gboolean reverse_scroll;
+ gboolean grabbed;
+ IdoScaleMenuItemStyle style;
+ IdoRangeStyle range_style;
+ gint toggle_size;
+};
+
+enum {
+ SLIDER_GRABBED,
+ SLIDER_RELEASED,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_ADJUSTMENT,
+ PROP_REVERSE_SCROLL_EVENTS,
+ PROP_STYLE,
+ PROP_RANGE_STYLE
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (IdoScaleMenuItem, ido_scale_menu_item, GTK_TYPE_MENU_ITEM)
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemPrivate))
+
+static void
+ido_scale_menu_item_state_changed (GtkWidget *widget,
+ GtkStateType previous_state)
+{
+ gtk_widget_set_state (widget, GTK_STATE_NORMAL);
+}
+
+static gboolean
+ido_scale_menu_item_scroll_event (GtkWidget *menuitem,
+ GdkEventScroll *event)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem);
+ GtkWidget *scale = priv->scale;
+
+ if (priv->reverse_scroll)
+ {
+ switch (event->direction)
+ {
+ case GDK_SCROLL_UP:
+ event->direction = GDK_SCROLL_DOWN;
+ break;
+
+ case GDK_SCROLL_DOWN:
+ event->direction = GDK_SCROLL_UP;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ gtk_widget_event (scale,
+ ((GdkEvent *)(void*)(event)));
+
+ return TRUE;
+}
+
+static void
+ido_scale_menu_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (widget);
+ GtkRequisition primary_req;
+ GtkRequisition secondary_req;
+ gint horizontal_padding;
+ gint primary_padding, secondary_padding;
+
+ GTK_WIDGET_CLASS (ido_scale_menu_item_parent_class)->size_allocate (widget, allocation);
+
+ switch (priv->style)
+ {
+ case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
+ gtk_widget_get_child_requisition (priv->primary_image, &primary_req);
+ gtk_widget_get_child_requisition (priv->secondary_image, &secondary_req);
+
+ primary_padding = gtk_widget_get_visible (priv->primary_image) ? primary_req.width : 0;
+ secondary_padding = gtk_widget_get_visible (priv->secondary_image) ? secondary_req.width : 0;
+ break;
+
+ case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
+ gtk_widget_get_child_requisition (priv->primary_label, &primary_req);
+ gtk_widget_get_child_requisition (priv->secondary_label, &secondary_req);
+
+ primary_padding = gtk_widget_get_visible (priv->primary_label) ? primary_req.width : 0;
+ secondary_padding = gtk_widget_get_visible (priv->secondary_label) ? secondary_req.width : 0;
+ break;
+
+ default:
+ primary_req.width = primary_req.height = 0;
+ secondary_req.width = secondary_req.height = 0;
+ primary_padding = 0;
+ secondary_padding = 0;
+ break;
+ }
+
+ gtk_widget_style_get (widget,
+ "horizontal-padding", &horizontal_padding,
+ NULL);
+
+ priv->left_padding = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ? primary_padding : secondary_padding;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ {
+ priv->left_padding = primary_padding;
+ priv->right_padding = secondary_padding;
+ }
+ else
+ {
+ priv->left_padding = secondary_padding;
+ priv->right_padding = primary_padding;
+ }
+
+ priv->child_allocation.x = GTK_CONTAINER (widget)->border_width + widget->style->xthickness;
+ priv->child_allocation.y = GTK_CONTAINER (widget)->border_width + widget->style->ythickness;
+
+ priv->child_allocation.x += horizontal_padding;
+ priv->child_allocation.x += priv->toggle_size;
+
+ priv->child_allocation.width = MAX (1, (gint)allocation->width - priv->child_allocation.x * 2);
+ priv->child_allocation.width -= (primary_padding + secondary_padding);
+ priv->child_allocation.height = MAX (1, (gint)allocation->height - priv->child_allocation.y * 2);
+
+ gtk_widget_set_size_request (priv->scale, priv->child_allocation.width, -1);
+}
+
+static void
+ido_scale_menu_item_toggle_size_allocate (IdoScaleMenuItem *item,
+ gint toggle_size,
+ gpointer user_data)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item);
+
+ priv->toggle_size = toggle_size;
+}
+
+static void
+ido_scale_menu_item_constructed (GObject *object)
+{
+ IdoScaleMenuItem *self = IDO_SCALE_MENU_ITEM (object);
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self);
+ GtkObject *adj = gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 0.0);
+ IdoRangeStyle range_style;
+ GtkWidget *hbox;
+
+ priv->adjustment = NULL;
+
+ g_object_get (self,
+ "range-style", &range_style,
+ NULL);
+
+ priv->scale = ido_range_new (adj, range_style);
+ g_object_ref (priv->scale);
+ gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+
+ priv->primary_image = gtk_image_new ();
+ g_signal_connect (priv->primary_image, "notify",
+ G_CALLBACK (ido_scale_menu_item_primary_image_notify),
+ self);
+
+ priv->secondary_image = gtk_image_new ();
+ g_signal_connect (priv->secondary_image, "notify",
+ G_CALLBACK (ido_scale_menu_item_secondary_image_notify),
+ self);
+
+ priv->primary_label = gtk_label_new ("");
+ priv->secondary_label = gtk_label_new ("");
+
+ priv->hbox = hbox;
+
+ update_packing (self, priv->style, priv->style);
+
+ g_signal_connect (self, "toggle-size-allocate",
+ G_CALLBACK (ido_scale_menu_item_toggle_size_allocate),
+ NULL);
+
+ g_signal_connect (self, "notify",
+ G_CALLBACK (ido_scale_menu_item_notify),
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (self), hbox);
+}
+
+static void
+ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (item_class);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (item_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (item_class);
+
+ widget_class->button_press_event = ido_scale_menu_item_button_press_event;
+ widget_class->button_release_event = ido_scale_menu_item_button_release_event;
+ widget_class->motion_notify_event = ido_scale_menu_item_motion_notify_event;
+ widget_class->scroll_event = ido_scale_menu_item_scroll_event;
+ widget_class->state_changed = ido_scale_menu_item_state_changed;
+ widget_class->size_allocate = ido_scale_menu_item_size_allocate;
+
+ gobject_class->constructed = ido_scale_menu_item_constructed;
+ gobject_class->set_property = ido_scale_menu_item_set_property;
+ gobject_class->get_property = ido_scale_menu_item_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_STYLE,
+ g_param_spec_enum ("accessory-style",
+ "Style of primary/secondary widgets",
+ "The style of the primary/secondary widgets",
+ IDO_TYPE_SCALE_MENU_ITEM_STYLE,
+ IDO_SCALE_MENU_ITEM_STYLE_NONE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_RANGE_STYLE,
+ g_param_spec_enum ("range-style",
+ "Range style",
+ "Style of the range",
+ IDO_TYPE_RANGE_STYLE,
+ IDO_RANGE_STYLE_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ADJUSTMENT,
+ g_param_spec_object ("adjustment",
+ "Adjustment",
+ "The adjustment containing the scale value",
+ GTK_TYPE_ADJUSTMENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_REVERSE_SCROLL_EVENTS,
+ g_param_spec_boolean ("reverse-scroll-events",
+ "Reverse scroll events",
+ "Reverses how up/down scroll events are interpreted",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[SLIDER_GRABBED] = g_signal_new ("slider-grabbed",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SLIDER_RELEASED] = g_signal_new ("slider-released",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (object_class, sizeof (IdoScaleMenuItemPrivate));
+}
+
+static void
+update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style, IdoScaleMenuItemStyle old_style)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self);
+ GtkContainer *container = GTK_CONTAINER (priv->hbox);
+
+ if (style != old_style)
+ {
+ switch (old_style)
+ {
+ case IDO_SCALE_MENU_ITEM_STYLE_NONE:
+ gtk_container_remove (container, priv->scale);
+ break;
+
+ case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
+ gtk_container_remove (container, priv->primary_image);
+ gtk_container_remove (container, priv->secondary_image);
+ gtk_container_remove (container, priv->scale);
+ break;
+
+ case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
+ gtk_container_remove (container, priv->primary_label);
+ gtk_container_remove (container, priv->secondary_label);
+ gtk_container_remove (container, priv->scale);
+ break;
+
+ default:
+ gtk_container_remove (container, priv->scale);
+ break;
+ }
+ }
+
+ switch (style)
+ {
+ case IDO_SCALE_MENU_ITEM_STYLE_NONE:
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
+ break;
+
+ case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->primary_image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->secondary_image, FALSE, FALSE, 0);
+ break;
+
+ case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->primary_label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->secondary_label, FALSE, FALSE, 0);
+ break;
+
+ default:
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
+ break;
+ }
+
+ gtk_widget_show_all (priv->hbox);
+}
+
+static void
+ido_scale_menu_item_init (IdoScaleMenuItem *self)
+{
+}
+
+static void
+ido_scale_menu_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdoScaleMenuItem *menu_item = IDO_SCALE_MENU_ITEM (object);
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+ switch (prop_id)
+ {
+ case PROP_ADJUSTMENT:
+ gtk_range_set_adjustment (GTK_RANGE (priv->scale), g_value_get_object (value));
+ break;
+
+ case PROP_REVERSE_SCROLL_EVENTS:
+ priv->reverse_scroll = g_value_get_boolean (value);
+ break;
+
+ case PROP_STYLE:
+ ido_scale_menu_item_set_style (menu_item, g_value_get_enum (value));
+ break;
+
+ case PROP_RANGE_STYLE:
+ priv->range_style = g_value_get_enum (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ido_scale_menu_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdoScaleMenuItem *menu_item = IDO_SCALE_MENU_ITEM (object);
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+ GtkAdjustment *adjustment;
+
+ switch (prop_id)
+ {
+ case PROP_ADJUSTMENT:
+ adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ g_value_set_object (value, adjustment);
+ break;
+
+ case PROP_REVERSE_SCROLL_EVENTS:
+ g_value_set_boolean (value, priv->reverse_scroll);
+ break;
+
+ case PROP_RANGE_STYLE:
+ g_value_set_enum (value, priv->range_style);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+translate_event_coordinates (GtkWidget *widget,
+ gdouble in_x,
+ gdouble *out_x)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (widget);
+
+ *out_x = in_x - priv->child_allocation.x - priv->left_padding;
+}
+
+static gboolean
+ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem);
+ GtkWidget *scale = priv->scale;
+ GtkWidget *parent;
+ gdouble x;
+
+ // can we block emissions of "grab-notify" on parent??
+ parent = gtk_widget_get_parent (GTK_WIDGET (menuitem));
+
+ translate_event_coordinates (menuitem, event->x, &x);
+ event->x = x;
+
+ translate_event_coordinates (menuitem, event->x_root, &x);
+ event->x_root = x;
+
+ ubuntu_gtk_widget_set_has_grab (scale, TRUE);
+
+ gtk_widget_event (scale,
+ ((GdkEvent *)(void*)(event)));
+
+ ubuntu_gtk_widget_set_has_grab (scale, FALSE);
+
+ if (!priv->grabbed)
+ {
+ priv->grabbed = TRUE;
+ g_signal_emit (menuitem, signals[SLIDER_GRABBED], 0);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem);
+ GtkWidget *scale = priv->scale;
+ GdkWindow *tmp = event->window;
+ gdouble x;
+
+ if (event->x > priv->child_allocation.x &&
+ event->x < priv->child_allocation.x + priv->left_padding)
+ {
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+
+ if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR)
+ {
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
+ }
+ else
+ {
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
+ }
+
+ if (priv->grabbed)
+ {
+ priv->grabbed = FALSE;
+ g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0);
+ }
+
+ return TRUE;
+ }
+
+ if (event->x < priv->child_allocation.x + priv->child_allocation.width + priv->right_padding + priv->left_padding &&
+ event->x > priv->child_allocation.x + priv->child_allocation.width + priv->left_padding)
+ {
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+
+ if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR)
+ {
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
+ }
+ else
+ {
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
+ }
+
+ if (priv->grabbed)
+ {
+ priv->grabbed = FALSE;
+ g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0);
+ }
+
+ return TRUE;
+ }
+
+ event->window = GTK_RANGE (scale)->event_window;
+
+ translate_event_coordinates (menuitem, event->x, &x);
+ event->x = x;
+
+ translate_event_coordinates (menuitem, event->x_root, &x);
+ event->x_root= x;
+
+ gtk_widget_event (scale,
+ ((GdkEvent *)(void*)(event)));
+
+ event->window = tmp;
+
+ if (priv->grabbed)
+ {
+ priv->grabbed = FALSE;
+ g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem,
+ GdkEventMotion *event)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem);
+ GtkWidget *scale = priv->scale;
+ gdouble x;
+
+ translate_event_coordinates (menuitem, event->x, &x);
+ event->x = x;
+
+ translate_event_coordinates (menuitem, event->x_root, &x);
+ event->x_root= x;
+
+ gtk_widget_event (scale,
+ ((GdkEvent *)(void*)(event)));
+
+ return TRUE;
+}
+
+static void
+menu_hidden (GtkWidget *menu,
+ IdoScaleMenuItem *scale)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (scale);
+
+ if (priv->grabbed)
+ {
+ priv->grabbed = FALSE;
+ g_signal_emit (scale, signals[SLIDER_RELEASED], 0);
+ }
+}
+
+static void
+ido_scale_menu_item_notify (IdoScaleMenuItem *item,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ if (g_strcmp0 (pspec->name, "parent"))
+ {
+ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (item));
+
+ if (parent)
+ {
+ g_signal_connect (parent, "hide",
+ G_CALLBACK (menu_hidden),
+ item);
+ }
+ }
+}
+
+static void
+ido_scale_menu_item_primary_image_notify (GtkImage *image,
+ GParamSpec *pspec,
+ IdoScaleMenuItem *item)
+{
+ if (gtk_image_get_storage_type (image) == GTK_IMAGE_EMPTY)
+ gtk_widget_hide (GTK_WIDGET (image));
+ else
+ gtk_widget_show (GTK_WIDGET (image));
+}
+
+static void
+ido_scale_menu_item_secondary_image_notify (GtkImage *image,
+ GParamSpec *pspec,
+ IdoScaleMenuItem *item)
+{
+ if (gtk_image_get_storage_type (image) == GTK_IMAGE_EMPTY)
+ gtk_widget_hide (GTK_WIDGET (image));
+ else
+ gtk_widget_show (GTK_WIDGET (image));
+}
+
+/**
+ * ido_scale_menu_item_new:
+ * @label: the text of the new menu item.
+ * @size: The size style of the range.
+ * @adjustment: A #GtkAdjustment describing the slider value.
+ * @returns: a new #IdoScaleMenuItem.
+ *
+ * Creates a new #IdoScaleMenuItem with an empty label.
+ **/
+GtkWidget*
+ido_scale_menu_item_new (const gchar *label,
+ IdoRangeStyle range_style,
+ GtkAdjustment *adjustment)
+{
+ return g_object_new (IDO_TYPE_SCALE_MENU_ITEM,
+ "adjustment", adjustment,
+ "range-style", range_style,
+ NULL);
+}
+
+/**
+ * ido_scale_menu_item_new_with_label:
+ * @label: the text of the menu item.
+ * @size: The size style of the range.
+ * @min: The minimum value of the slider.
+ * @max: The maximum value of the slider.
+ * @step: The step increment of the slider.
+ * @returns: a new #IdoScaleMenuItem.
+ *
+ * Creates a new #IdoScaleMenuItem containing a label.
+ **/
+GtkWidget*
+ido_scale_menu_item_new_with_range (const gchar *label,
+ IdoRangeStyle range_style,
+ gdouble value,
+ gdouble min,
+ gdouble max,
+ gdouble step)
+{
+ GtkObject *adjustment = gtk_adjustment_new (value, min, max, step, 10 * step, 0);
+
+ return g_object_new (IDO_TYPE_SCALE_MENU_ITEM,
+ "label", label,
+ "range-style", range_style,
+ "adjustment", adjustment,
+ NULL);
+}
+
+/**
+ * ido_scale_menu_item_get_scale:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A pointer to the scale widget.
+ *
+ * Retrieves the scale widget.
+ **/
+GtkWidget*
+ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return priv->scale;
+}
+
+/**
+ * ido_scale_menu_item_get_style:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A #IdoScaleMenuItemStyle enum describing the style.
+ *
+ * Retrieves the type of widgets being used for the primary and
+ * secondary widget slots. This could be images, labels, or nothing.
+ **/
+IdoScaleMenuItemStyle
+ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), IDO_SCALE_MENU_ITEM_STYLE_NONE);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return priv->style;
+}
+
+void
+ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem,
+ IdoScaleMenuItemStyle style)
+{
+ IdoScaleMenuItemPrivate *priv;
+ IdoScaleMenuItemStyle old_style;
+
+ g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem));
+
+ priv = GET_PRIVATE (menuitem);
+
+ old_style = priv->style;
+ priv->style = style;
+
+ update_packing (menuitem, style, old_style);
+}
+
+/**
+ * ido_scale_menu_item_get_primary_image:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A #GtkWidget pointer for the primary image.
+ *
+ * Retrieves a pointer to the image widget used in the primary slot.
+ * Whether this is visible depends upon the return value from
+ * ido_scale_menu_item_get_style().
+ **/
+GtkWidget *
+ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return priv->primary_image;
+}
+
+/**
+ * ido_scale_menu_item_get_secondary_image:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A #GtkWidget pointer for the secondary image.
+ *
+ * Retrieves a pointer to the image widget used in the secondary slot.
+ * Whether this is visible depends upon the return value from
+ * ido_scale_menu_item_get_style().
+ **/
+GtkWidget *
+ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return priv->secondary_image;
+}
+
+/**
+ * ido_scale_menu_item_get_primary_label:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A const gchar* string of the label text.
+ *
+ * Retrieves a string of the text for the primary label widget.
+ * Whether this is visible depends upon the return value from
+ * ido_scale_menu_item_get_style().
+ **/
+G_CONST_RETURN gchar*
+ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return gtk_label_get_text (GTK_LABEL (priv->primary_label));
+}
+
+/**
+ * ido_scale_menu_item_get_primary_label:
+ * @menuitem: The #IdoScaleMenuItem
+ * @returns: A const gchar* string of the label text.
+ *
+ * Retrieves a string of the text for the primary label widget.
+ * Whether this is visible depends upon the return value from
+ * ido_scale_menu_item_get_style().
+ **/
+G_CONST_RETURN gchar*
+ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL);
+
+ priv = GET_PRIVATE (menuitem);
+
+ return gtk_label_get_text (GTK_LABEL (priv->secondary_label));
+}
+
+/**
+ * ido_scale_menu_item_set_primary_label:
+ * @menuitem: The #IdoScaleMenuItem
+ * @label: A string containing the label text
+ *
+ * Sets the text for the label widget in the primary slot. This
+ * widget will only be visibile if the return value of
+ * ido_scale_menu_item_get_style() is set to %IDO_SCALE_MENU_ITEM_STYLE_LABEL.
+ **/
+void
+ido_scale_menu_item_set_primary_label (IdoScaleMenuItem *menuitem,
+ const gchar *label)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem));
+
+ priv = GET_PRIVATE (menuitem);
+
+ if (priv->primary_label)
+ {
+ gtk_label_set_text (GTK_LABEL (priv->primary_label), label);
+ }
+}
+
+/**
+ * ido_scale_menu_item_set_primary_label:
+ * @menuitem: The #IdoScaleMenuItem
+ * @label: A string containing the label text
+ *
+ * Sets the text for the label widget in the primary slot. This
+ * widget will only be visibile if the return value of
+ * ido_scale_menu_item_get_style() is set to %IDO_SCALE_MENU_ITEM_STYLE_LABEL.
+ **/
+void
+ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem *menuitem,
+ const gchar *label)
+{
+ IdoScaleMenuItemPrivate *priv;
+
+ g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem));
+
+ priv = GET_PRIVATE (menuitem);
+
+ if (priv->secondary_label)
+ {
+ gtk_label_set_text (GTK_LABEL (priv->secondary_label), label);
+ }
+}
+
+
+#define __IDO_SCALE_MENU_ITEM_C__
=== added file 'src/idoscalemenuitem.h'
--- src/idoscalemenuitem.h 1970-01-01 00:00:00 +0000
+++ src/idoscalemenuitem.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO_SCALE_MENU_ITEM_H__
+#define __IDO_SCALE_MENU_ITEM_H__
+
+#include <gtk/gtkmenuitem.h>
+#include "idorange.h"
+
+G_BEGIN_DECLS
+
+#define IDO_TYPE_SCALE_MENU_ITEM (ido_scale_menu_item_get_type ())
+#define IDO_SCALE_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItem))
+#define IDO_SCALE_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemClass))
+#define IDO_IS_SCALE_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_SCALE_MENU_ITEM))
+#define IDO_IS_SCALE_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_SCALE_MENU_ITEM))
+#define IDO_SCALE_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemClass))
+
+typedef enum
+{
+ IDO_SCALE_MENU_ITEM_STYLE_NONE,
+ IDO_SCALE_MENU_ITEM_STYLE_IMAGE,
+ IDO_SCALE_MENU_ITEM_STYLE_LABEL
+} IdoScaleMenuItemStyle;
+
+typedef struct _IdoScaleMenuItem IdoScaleMenuItem;
+typedef struct _IdoScaleMenuItemClass IdoScaleMenuItemClass;
+typedef struct _IdoScaleMenuItemPrivate IdoScaleMenuItemPrivate;
+
+struct _IdoScaleMenuItem
+{
+ GtkMenuItem parent_instance;
+
+ IdoScaleMenuItemPrivate *priv;
+};
+
+struct _IdoScaleMenuItemClass
+{
+ GtkMenuItemClass parent_class;
+};
+
+
+GType ido_scale_menu_item_get_type (void) G_GNUC_CONST;
+GtkWidget *ido_scale_menu_item_new (const gchar *label,
+ IdoRangeStyle size,
+ GtkAdjustment *adjustment);
+GtkWidget *ido_scale_menu_item_new_with_range (const gchar *label,
+ IdoRangeStyle size,
+ gdouble value,
+ gdouble min,
+ gdouble max,
+ gdouble step);
+GtkWidget *ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem);
+
+IdoScaleMenuItemStyle ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem);
+void ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem,
+ IdoScaleMenuItemStyle style);
+GtkWidget *ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem);
+GtkWidget *ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem);
+G_CONST_RETURN gchar *ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem);
+G_CONST_RETURN gchar *ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem);
+void ido_scale_menu_item_set_primary_label (IdoScaleMenuItem *menuitem,
+ const gchar *label);
+void ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem *menuitem,
+ const gchar *label);
+
+G_END_DECLS
+
+#endif /* __IDO_SCALE_MENU_ITEM_H__ */
=== added file 'src/idotimeline.c'
--- src/idotimeline.c 1970-01-01 00:00:00 +0000
+++ src/idotimeline.c 2011-05-12 10:11:02 +0000
@@ -0,0 +1,742 @@
+/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
+/* gtktimeline.c
+ *
+ * Copyright (C) 2007 Carlos Garnacho <carlos@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "idotimeline.h"
+#include "idotypebuiltins.h"
+
+#include <gtk/gtksettings.h>
+#include <math.h>
+
+#define IDO_TIMELINE_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), IDO_TYPE_TIMELINE, IdoTimelinePriv))
+#define MSECS_PER_SEC 1000
+#define FRAME_INTERVAL(nframes) (MSECS_PER_SEC / nframes)
+#define DEFAULT_FPS 30
+
+typedef struct IdoTimelinePriv IdoTimelinePriv;
+
+struct IdoTimelinePriv
+{
+ guint duration;
+ guint fps;
+ guint source_id;
+
+ GTimer *timer;
+
+ gdouble progress;
+ gdouble last_progress;
+
+ GdkScreen *screen;
+
+ guint animations_enabled : 1;
+ guint loop : 1;
+ guint direction : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_FPS,
+ PROP_DURATION,
+ PROP_LOOP,
+ PROP_DIRECTION,
+ PROP_SCREEN
+};
+
+enum {
+ STARTED,
+ PAUSED,
+ FINISHED,
+ FRAME,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+
+static void ido_timeline_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ido_timeline_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void ido_timeline_finalize (GObject *object);
+
+
+G_DEFINE_TYPE (IdoTimeline, ido_timeline, G_TYPE_OBJECT)
+
+
+static void
+ido_timeline_class_init (IdoTimelineClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = ido_timeline_set_property;
+ object_class->get_property = ido_timeline_get_property;
+ object_class->finalize = ido_timeline_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_FPS,
+ g_param_spec_uint ("fps",
+ "FPS",
+ "Frames per second for the timeline",
+ 1, G_MAXUINT,
+ DEFAULT_FPS,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DURATION,
+ g_param_spec_uint ("duration",
+ "Animation Duration",
+ "Animation Duration",
+ 0, G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_LOOP,
+ g_param_spec_boolean ("loop",
+ "Loop",
+ "Whether the timeline loops or not",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DIRECTION,
+ g_param_spec_enum ("direction",
+ "Direction",
+ "Whether the timeline moves forward or backward in time",
+ IDO_TYPE_TIMELINE_DIRECTION,
+ IDO_TIMELINE_DIRECTION_FORWARD,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_SCREEN,
+ g_param_spec_object ("screen",
+ "Screen",
+ "Screen to get the settings from",
+ GDK_TYPE_SCREEN,
+ G_PARAM_READWRITE));
+
+ signals[STARTED] =
+ g_signal_new ("started",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdoTimelineClass, started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[PAUSED] =
+ g_signal_new ("paused",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdoTimelineClass, paused),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FINISHED] =
+ g_signal_new ("finished",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdoTimelineClass, finished),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FRAME] =
+ g_signal_new ("frame",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdoTimelineClass, frame),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1,
+ G_TYPE_DOUBLE);
+
+ g_type_class_add_private (klass, sizeof (IdoTimelinePriv));
+}
+
+static void
+ido_timeline_init (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ priv->fps = DEFAULT_FPS;
+ priv->duration = 0.0;
+ priv->direction = IDO_TIMELINE_DIRECTION_FORWARD;
+ priv->screen = gdk_screen_get_default ();
+
+ priv->last_progress = 0;
+}
+
+static void
+ido_timeline_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdoTimeline *timeline;
+ IdoTimelinePriv *priv;
+
+ timeline = IDO_TIMELINE (object);
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ switch (prop_id)
+ {
+ case PROP_FPS:
+ ido_timeline_set_fps (timeline, g_value_get_uint (value));
+ break;
+ case PROP_DURATION:
+ ido_timeline_set_duration (timeline, g_value_get_uint (value));
+ break;
+ case PROP_LOOP:
+ ido_timeline_set_loop (timeline, g_value_get_boolean (value));
+ break;
+ case PROP_DIRECTION:
+ ido_timeline_set_direction (timeline, g_value_get_enum (value));
+ break;
+ case PROP_SCREEN:
+ ido_timeline_set_screen (timeline,
+ (GdkScreen*)g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ido_timeline_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdoTimeline *timeline;
+ IdoTimelinePriv *priv;
+
+ timeline = IDO_TIMELINE (object);
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ switch (prop_id)
+ {
+ case PROP_FPS:
+ g_value_set_uint (value, priv->fps);
+ break;
+ case PROP_DURATION:
+ g_value_set_uint (value, priv->duration);
+ break;
+ case PROP_LOOP:
+ g_value_set_boolean (value, priv->loop);
+ break;
+ case PROP_DIRECTION:
+ g_value_set_enum (value, priv->direction);
+ break;
+ case PROP_SCREEN:
+ g_value_set_object (value, priv->screen);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ido_timeline_finalize (GObject *object)
+{
+ IdoTimelinePriv *priv;
+
+ priv = IDO_TIMELINE_GET_PRIV (object);
+
+ if (priv->source_id)
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
+
+ if (priv->timer)
+ g_timer_destroy (priv->timer);
+
+ G_OBJECT_CLASS (ido_timeline_parent_class)->finalize (object);
+}
+
+static gboolean
+ido_timeline_run_frame (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+ gdouble delta_progress, progress;
+ guint elapsed_time;
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000);
+ g_timer_start (priv->timer);
+
+ if (priv->animations_enabled)
+ {
+ delta_progress = (gdouble) elapsed_time / priv->duration;
+ progress = priv->last_progress;
+
+ if (priv->direction == IDO_TIMELINE_DIRECTION_BACKWARD)
+ progress -= delta_progress;
+ else
+ progress += delta_progress;
+
+ priv->last_progress = progress;
+
+ progress = CLAMP (progress, 0., 1.);
+ }
+ else
+ progress = (priv->direction == IDO_TIMELINE_DIRECTION_FORWARD) ? 1.0 : 0.0;
+
+ priv->progress = progress;
+ g_signal_emit (timeline, signals [FRAME], 0, progress);
+
+ if ((priv->direction == IDO_TIMELINE_DIRECTION_FORWARD && progress == 1.0) ||
+ (priv->direction == IDO_TIMELINE_DIRECTION_BACKWARD && progress == 0.0))
+ {
+ if (!priv->loop)
+ {
+ if (priv->source_id)
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
+ g_timer_stop (priv->timer);
+ g_signal_emit (timeline, signals [FINISHED], 0);
+ return FALSE;
+ }
+ else
+ ido_timeline_rewind (timeline);
+ }
+
+ return TRUE;
+}
+
+/**
+ * ido_timeline_new:
+ * @duration: duration in milliseconds for the timeline
+ *
+ * Creates a new #IdoTimeline with the specified number of frames.
+ *
+ * Return Value: the newly created #IdoTimeline
+ **/
+IdoTimeline *
+ido_timeline_new (guint duration)
+{
+ return g_object_new (IDO_TYPE_TIMELINE,
+ "duration", duration,
+ NULL);
+}
+
+IdoTimeline *
+ido_timeline_new_for_screen (guint duration,
+ GdkScreen *screen)
+{
+ return g_object_new (IDO_TYPE_TIMELINE,
+ "duration", duration,
+ "screen", screen,
+ NULL);
+}
+
+/**
+ * ido_timeline_start:
+ * @timeline: A #IdoTimeline
+ *
+ * Runs the timeline from the current frame.
+ **/
+void
+ido_timeline_start (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+ gboolean enable_animations = FALSE;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (!priv->source_id)
+ {
+ if (priv->timer)
+ g_timer_continue (priv->timer);
+ else
+ priv->timer = g_timer_new ();
+
+ /* sanity check */
+ g_assert (priv->fps > 0);
+
+ if (priv->screen)
+ {
+#if 0
+ GtkSettings *settings = gtk_settings_get_for_screen (priv->screen);
+ g_object_get (settings, "ido-enable-animations", &enable_animations, NULL);
+#else
+ // XXX
+ enable_animations = TRUE;
+#endif
+ }
+
+ priv->animations_enabled = (enable_animations == TRUE);
+
+ g_signal_emit (timeline, signals [STARTED], 0);
+
+ if (enable_animations)
+ priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps),
+ (GSourceFunc) ido_timeline_run_frame,
+ timeline);
+ else
+ priv->source_id = gdk_threads_add_idle ((GSourceFunc) ido_timeline_run_frame,
+ timeline);
+ }
+}
+
+/**
+ * ido_timeline_pause:
+ * @timeline: A #IdoTimeline
+ *
+ * Pauses the timeline.
+ **/
+void
+ido_timeline_pause (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->source_id)
+ {
+ g_timer_stop (priv->timer);
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ g_signal_emit (timeline, signals [PAUSED], 0);
+ }
+}
+
+/**
+ * ido_timeline_rewind:
+ * @timeline: A #IdoTimeline
+ *
+ * Rewinds the timeline.
+ **/
+void
+ido_timeline_rewind (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (ido_timeline_get_direction(timeline) != IDO_TIMELINE_DIRECTION_FORWARD)
+ priv->progress = priv->last_progress = 1.;
+ else
+ priv->progress = priv->last_progress = 0.;
+
+ /* reset timer */
+ if (priv->timer)
+ {
+ g_timer_start (priv->timer);
+
+ if (!priv->source_id)
+ g_timer_stop (priv->timer);
+ }
+}
+
+/**
+ * ido_timeline_is_running:
+ * @timeline: A #IdoTimeline
+ *
+ * Returns whether the timeline is running or not.
+ *
+ * Return Value: %TRUE if the timeline is running
+ **/
+gboolean
+ido_timeline_is_running (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), FALSE);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ return (priv->source_id != 0);
+}
+
+/**
+ * ido_timeline_get_fps:
+ * @timeline: A #IdoTimeline
+ *
+ * Returns the number of frames per second.
+ *
+ * Return Value: frames per second
+ **/
+guint
+ido_timeline_get_fps (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 1);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+ return priv->fps;
+}
+
+/**
+ * ido_timeline_set_fps:
+ * @timeline: A #IdoTimeline
+ * @fps: frames per second
+ *
+ * Sets the number of frames per second that
+ * the timeline will play.
+ **/
+void
+ido_timeline_set_fps (IdoTimeline *timeline,
+ guint fps)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+ g_return_if_fail (fps > 0);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ priv->fps = fps;
+
+ if (ido_timeline_is_running (timeline))
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps),
+ (GSourceFunc) ido_timeline_run_frame,
+ timeline);
+ }
+
+ g_object_notify (G_OBJECT (timeline), "fps");
+}
+
+/**
+ * ido_timeline_get_loop:
+ * @timeline: A #IdoTimeline
+ *
+ * Returns whether the timeline loops to the
+ * beginning when it has reached the end.
+ *
+ * Return Value: %TRUE if the timeline loops
+ **/
+gboolean
+ido_timeline_get_loop (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), FALSE);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+ return priv->loop;
+}
+
+/**
+ * ido_timeline_set_loop:
+ * @timeline: A #IdoTimeline
+ * @loop: %TRUE to make the timeline loop
+ *
+ * Sets whether the timeline loops to the beginning
+ * when it has reached the end.
+ **/
+void
+ido_timeline_set_loop (IdoTimeline *timeline,
+ gboolean loop)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (loop != priv->loop)
+ {
+ priv->loop = loop;
+ g_object_notify (G_OBJECT (timeline), "loop");
+ }
+}
+
+void
+ido_timeline_set_duration (IdoTimeline *timeline,
+ guint duration)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (duration != priv->duration)
+ {
+ priv->duration = duration;
+ g_object_notify (G_OBJECT (timeline), "duration");
+ }
+}
+
+guint
+ido_timeline_get_duration (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 0);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ return priv->duration;
+}
+
+/**
+ * ido_timeline_set_direction:
+ * @timeline: A #IdoTimeline
+ * @direction: direction
+ *
+ * Sets the direction of the timeline.
+ **/
+void
+ido_timeline_set_direction (IdoTimeline *timeline,
+ IdoTimelineDirection direction)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (direction != priv->direction)
+ {
+ priv->direction = direction;
+ g_object_notify (G_OBJECT (timeline), "direction");
+ }
+}
+
+/**
+ * ido_timeline_get_direction:
+ * @timeline: A #IdoTimeline
+ *
+ * Returns the direction of the timeline.
+ *
+ * Return Value: direction
+ **/
+IdoTimelineDirection
+ido_timeline_get_direction (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), IDO_TIMELINE_DIRECTION_FORWARD);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+ return priv->direction;
+}
+
+void
+ido_timeline_set_screen (IdoTimeline *timeline,
+ GdkScreen *screen)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->screen)
+ g_object_unref (priv->screen);
+
+ priv->screen = g_object_ref (screen);
+
+ g_object_notify (G_OBJECT (timeline), "screen");
+}
+
+GdkScreen *
+ido_timeline_get_screen (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), NULL);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+ return priv->screen;
+}
+
+gdouble
+ido_timeline_get_progress (IdoTimeline *timeline)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 0.);
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+ return priv->progress;
+}
+
+void
+ido_timeline_set_progress (IdoTimeline *timeline, gdouble progress)
+{
+ IdoTimelinePriv *priv;
+
+ g_return_if_fail (IDO_IS_TIMELINE (timeline));
+
+ priv = IDO_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->source_id)
+ {
+ g_timer_stop (priv->timer);
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
+
+ priv->progress = priv->last_progress = progress;
+
+ ido_timeline_start (timeline);
+}
+
+gdouble
+ido_timeline_calculate_progress (gdouble linear_progress,
+ IdoTimelineProgressType progress_type)
+{
+ gdouble progress;
+
+ progress = linear_progress;
+
+ switch (progress_type)
+ {
+ case IDO_TIMELINE_PROGRESS_LINEAR:
+ break;
+ case IDO_TIMELINE_PROGRESS_SINUSOIDAL:
+ progress = sinf ((progress * G_PI) / 2);
+ break;
+ case IDO_TIMELINE_PROGRESS_EXPONENTIAL:
+ progress *= progress;
+ break;
+ case IDO_TIMELINE_PROGRESS_EASE_IN_EASE_OUT:
+ {
+ progress *= 2;
+
+ if (progress < 1)
+ progress = pow (progress, 3) / 2;
+ else
+ progress = (pow (progress - 2, 3) + 2) / 2;
+ }
+ }
+
+ return progress;
+}
=== added file 'src/idotimeline.h'
--- src/idotimeline.h 1970-01-01 00:00:00 +0000
+++ src/idotimeline.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 Carlos Garnacho <carlos@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IDO_TIMELINE_H__
+#define __IDO_TIMELINE_H__
+
+#include <glib-object.h>
+#include <gtk/gtkenums.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define IDO_TYPE_TIMELINE (ido_timeline_get_type ())
+#define IDO_TIMELINE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_TIMELINE, IdoTimeline))
+#define IDO_TIMELINE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_TIMELINE, IdoTimelineClass))
+#define IDO_IS_TIMELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_TIMELINE))
+#define IDO_IS_TIMELINE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_TIMELINE))
+#define IDO_TIMELINE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_TIMELINE, IdoTimelineClass))
+
+typedef struct IdoTimeline IdoTimeline;
+typedef struct IdoTimelineClass IdoTimelineClass;
+
+typedef enum {
+ IDO_TIMELINE_DIRECTION_FORWARD,
+ IDO_TIMELINE_DIRECTION_BACKWARD
+} IdoTimelineDirection;
+
+typedef enum {
+ IDO_TIMELINE_PROGRESS_LINEAR,
+ IDO_TIMELINE_PROGRESS_SINUSOIDAL,
+ IDO_TIMELINE_PROGRESS_EXPONENTIAL,
+ IDO_TIMELINE_PROGRESS_EASE_IN_EASE_OUT
+} IdoTimelineProgressType;
+
+struct IdoTimeline
+{
+ GObject parent_instance;
+};
+
+struct IdoTimelineClass
+{
+ GObjectClass parent_class;
+
+ void (* started) (IdoTimeline *timeline);
+ void (* finished) (IdoTimeline *timeline);
+ void (* paused) (IdoTimeline *timeline);
+
+ void (* frame) (IdoTimeline *timeline,
+ gdouble progress);
+
+ void (* __ido_reserved1) (void);
+ void (* __ido_reserved2) (void);
+ void (* __ido_reserved3) (void);
+ void (* __ido_reserved4) (void);
+};
+
+
+GType ido_timeline_get_type (void) G_GNUC_CONST;
+
+IdoTimeline *ido_timeline_new (guint duration);
+IdoTimeline *ido_timeline_new_for_screen (guint duration,
+ GdkScreen *screen);
+
+void ido_timeline_start (IdoTimeline *timeline);
+void ido_timeline_pause (IdoTimeline *timeline);
+void ido_timeline_rewind (IdoTimeline *timeline);
+
+gboolean ido_timeline_is_running (IdoTimeline *timeline);
+
+guint ido_timeline_get_fps (IdoTimeline *timeline);
+void ido_timeline_set_fps (IdoTimeline *timeline,
+ guint fps);
+
+gboolean ido_timeline_get_loop (IdoTimeline *timeline);
+void ido_timeline_set_loop (IdoTimeline *timeline,
+ gboolean loop);
+
+guint ido_timeline_get_duration (IdoTimeline *timeline);
+void ido_timeline_set_duration (IdoTimeline *timeline,
+ guint duration);
+
+GdkScreen *ido_timeline_get_screen (IdoTimeline *timeline);
+void ido_timeline_set_screen (IdoTimeline *timeline,
+ GdkScreen *screen);
+
+IdoTimelineDirection ido_timeline_get_direction (IdoTimeline *timeline);
+void ido_timeline_set_direction (IdoTimeline *timeline,
+ IdoTimelineDirection direction);
+
+gdouble ido_timeline_get_progress (IdoTimeline *timeline);
+void ido_timeline_set_progress (IdoTimeline *timeline,
+ gdouble progress);
+
+gdouble ido_timeline_calculate_progress (gdouble linear_progress,
+ IdoTimelineProgressType progress_type);
+
+G_END_DECLS
+
+#endif /* __IDO_TIMELINE_H__ */
=== added file 'src/idotypebuiltins.c.template'
--- src/idotypebuiltins.c.template 1970-01-01 00:00:00 +0000
+++ src/idotypebuiltins.c.template 2011-05-12 10:11:02 +0000
@@ -0,0 +1,31 @@
+/*** BEGIN file-header ***/
+#include "idotypebuiltins.h"
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type(void) {
+ static GType enum_type_id = 0;
+ if (G_UNLIKELY (!enum_type_id))
+ {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ enum_type_id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ }
+ return enum_type_id;
+}
+/*** END value-tail ***/
+
=== added file 'src/idotypebuiltins.h.template'
--- src/idotypebuiltins.h.template 1970-01-01 00:00:00 +0000
+++ src/idotypebuiltins.h.template 2011-05-12 10:11:02 +0000
@@ -0,0 +1,26 @@
+/*** BEGIN file-header ***/
+#ifndef __IDO_ENUM_TYPES_H__
+#define __IDO_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* !__IDO_ENUM_TYPES_H__ */
+/*** END file-tail ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define IDO_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+
+/*** END value-header ***/
+
=== added file 'src/libido.h'
--- src/libido.h 1970-01-01 00:00:00 +0000
+++ src/libido.h 2011-05-12 10:11:02 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __IDO__
+#define __IDO__
+
+#include <libido/idocalendarmenuitem.h>
+#include <libido/idoscalemenuitem.h>
+#include <libido/idoentrymenuitem.h>
+#include <libido/idomessagedialog.h>
+
+#endif /* __IDO__ */