Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwkendrick <wkendrick>2011-06-17 01:37:53 (GMT)
committer wkendrick <wkendrick>2011-06-17 01:37:53 (GMT)
commit9996c67f2b86848a77c25cf1dc74c212e28b870e (patch)
treea42140512ebe01447921fb01885030c160ba46d5
parenta3911b9317fc421ebbfd0f5c7d01d35e38ccda3a (diff)
Integrated OpenCandy (as an option; secret key needed).
-rw-r--r--docs/CHANGES.txt16
-rw-r--r--docs/COPYING-OC.txt371
-rw-r--r--win32/OCSetupHlp.dllbin0 -> 768328 bytes
-rw-r--r--win32/OCSetupHlp.iss719
-rw-r--r--win32/tuxpaint-opencandy.iss2
-rw-r--r--win32/tuxpaint.iss866
6 files changed, 1589 insertions, 385 deletions
diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt
index 3b73fdf..1c8e620 100644
--- a/docs/CHANGES.txt
+++ b/docs/CHANGES.txt
@@ -6,9 +6,9 @@ Copyright (c) 2002-2011 by Bill Kendrick and others
bill@newbreedsoftware.com
http://www.tuxpaint.org/
-$Id: CHANGES.txt,v 1.780 2011/05/29 17:24:57 wkendrick Exp $
+$Id: CHANGES.txt,v 1.781 2011/06/17 01:37:53 wkendrick Exp $
-2011.May.29 (0.9.22)
+2011.June.16 (0.9.22)
* New Tools:
----------
@@ -49,6 +49,18 @@ $Id: CHANGES.txt,v 1.780 2011/05/29 17:24:57 wkendrick Exp $
* Added support for building under Haiku OS
Scott McCreary <scottmc@users.sourceforge.net>
+ * Integrated OpenCandy-powered recommendation service
+ into Windows installation scripts (InnoSetup), as an option.
+ <http://www.opencandy.com/>
+
+ Note: "tuxpaint.iss" still builds standard, OpenCandy-less
+ Tux Paint installer; "tuxpaint-opencandy.iss", along with a file
+ with secret key info (not included in CVS, of course!), build
+ an OpenCandy-enabled version. The OC account is currently
+ maintained by Bill Kendrick <nbs@sonic.net>, lead developer.
+
+ For more info, see http://www.tuxpaint.org/docs/opencandy/
+
* Accessibility Improvements:
---------------------------
* Added a mouse accessibility mode to avoid the need to drag the mouse.
diff --git a/docs/COPYING-OC.txt b/docs/COPYING-OC.txt
new file mode 100644
index 0000000..a9b685d
--- /dev/null
+++ b/docs/COPYING-OC.txt
@@ -0,0 +1,371 @@
+COPYING.txt for Tux Paint
+
+Tux Paint - A simple drawing program for children.
+
+Copyright (c) 2005 by Bill Kendrick and others
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/tuxpaint/
+
+
+Note: Also see the respective "COPYING.txt" license documentation
+included with the TrueType Fonts that come with Tux Paint.
+See: ../fonts/locale/LL_docs/, where "LL" corresponds to a font filename.
+
+Bill Kendrick, 2005.October.10
+$Id: COPYING-OC.txt,v 1.1 2011/06/17 01:37:53 wkendrick Exp $
+
+----------------------------------------
+
+OpenCandy End User License Agreement
+
+Jan 26 2010
+
+This installer uses the OpenCandy network to recommend other software you may
+find valuable during the installation of this software. OpenCandy collects
+NON-personally identifiable information about this installation and the
+recommendation process. Collection of this information ONLY occurs during
+this installation and the recommendation process; in accordance with
+OpenCandy's Privacy Policy, available at www.opencandy.com/privacy-policy
+
+----------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/win32/OCSetupHlp.dll b/win32/OCSetupHlp.dll
new file mode 100644
index 0000000..1d1c5e6
--- /dev/null
+++ b/win32/OCSetupHlp.dll
Binary files differ
diff --git a/win32/OCSetupHlp.iss b/win32/OCSetupHlp.iss
new file mode 100644
index 0000000..a7fea26
--- /dev/null
+++ b/win32/OCSetupHlp.iss
@@ -0,0 +1,719 @@
+//
+// OCSetupHlp.iss
+// --------------
+//
+// OpenCandy Helper Include File
+//
+// This file defines functions and procedures that need to
+// be called from your main installer script in order to
+// initialize and setup OpenCandy.
+//
+// Please consult the accompanying SDK documentation for
+// integration details and contact partner support for
+// assistance with any advanced integration needs.
+//
+// IMPORTANT:
+// ----------
+// Publishers should have no need to modify the content
+// of this file. If you are modifying this file for any
+// reason other than as directed by partner support
+// you are probably making a mistake. Please contact
+// partner support instead.
+//
+// Copyright (c) 2008 - 2011 OpenCandy, Inc.
+//
+
+[Code]
+
+//--------------------------------
+// OpenCandy types
+//--------------------------------
+
+#ifdef UNICODE
+type OCWString = String;
+type OCAString = AnsiString;
+type OCTString = OCWString;
+#else
+type OCAString = String;
+type OCTString = OCAString;
+#endif
+
+
+
+//--------------------------------
+// OpenCandy definitions
+//--------------------------------
+
+// Size of strings (including terminating character)
+#define OC_STR_CHARS 1024
+
+// Values used with OCInit2A(), OCInit2W() APIs
+#define OC_INIT_SUCCESS 0
+#define OC_INIT_MODE_NORMAL 0
+#define OC_INIT_MODE_REMNANT 1
+
+// Values used with OCGetNoCandy() API
+#define OC_CANDY_ENABLED 0
+#define OC_CANDY_DISABLED 1
+
+// Offer types returned by OCGetOfferType() API
+# define OC_OFFER_TYPE_NORMAL 1
+# define OC_OFFER_TYPE_EMBEDDED 2
+
+// Values returned by OCGetBannerInfo() API
+#define OC_OFFER_BANNER_FOUNDNEITHER 0
+#define OC_OFFER_BANNER_FOUNDTITLE 1
+#define OC_OFFER_BANNER_FOUNDDESCRIPTION 2
+#define OC_OFFER_BANNER_FOUNDBOTH 3
+
+// User choice indicators returned by OCGetOfferState() API
+#define OC_OFFER_CHOICE_ACCEPTED 1
+#define OC_OFFER_CHOICE_DECLINED 0
+#define OC_OFFER_CHOICE_NOCHOICE -1
+
+// Values used with OCCanLeaveOfferPage() API
+#define OC_OFFER_LEAVEPAGE_ALLOWED 1
+#define OC_OFFER_LEAVEPAGE_DISALLOWED 0
+
+// Values used for OCGetAsyncOfferStatus() API
+#define OC_OFFER_STATUS_CANOFFER_READY 0
+#define OC_OFFER_STATUS_CANOFFER_NOTREADY 1
+#define OC_OFFER_STATUS_QUERYING_NOTREADY 2
+#define OC_OFFER_STATUS_NOOFFERSAVAILABLE 3
+
+// Values returned by OCRunDialog() API
+#define OC_OFFER_RUNDIALOG_FAILURE -1
+
+// Values returned by OCLoadOpenCandyDLL() API
+#define OC_LOADOCDLL_FAILURE 0
+
+// Values used with LogDevModeMessage() API
+#define OC_DEVMSG_ERROR_TRUE 1
+#define OC_DEVMSG_ERROR_FALSE 0
+
+// Values used in the sample installer script
+//
+// IMPORTANT:
+// Do not modify these definitions or disable the warnings below.
+// If you see warnings when you compile your script you must
+// modify the values you set where you !insertmacro OpenCandyInit
+// (i.e. in your .iss file) before releasing your installer publicly.
+#define OC_SAMPLE_PUBLISHERNAME "Open Candy Sample"
+#define OC_SAMPLE_KEY "748ad6d80864338c9c03b664839d8161"
+#define OC_SAMPLE_SECRET "dfb3a60d6bfdb55c50e1ef53249f1198"
+
+// Compile-time checks and defaults
+#if OC_STR_MY_PRODUCT_NAME == OC_SAMPLE_PUBLISHERNAME
+ #pragma warning "Do not forget to change the product name from '" + OC_SAMPLE_PUBLISHERNAME + "' to your company's product name before releasing this installer."
+#endif
+#if OC_STR_KEY == OC_SAMPLE_KEY
+ #pragma warning "Do not forget to change the sample key '" + OC_SAMPLE_KEY + "' to your company's product key before releasing this installer."
+#endif
+#if OC_STR_SECRET == OC_SAMPLE_SECRET
+ #pragma warning "Do not forget to change the sample secret '" + OC_SAMPLE_SECRET + "' to your company's product secret before releasing this installer."
+#endif
+#if Pos(LowerCase("\OCSetupHlp.dll"),LowerCase(OC_OCSETUPHLP_FILE_PATH)) == 0
+ #pragma error "The definition OC_OCSETUPHLP_FILE_PATH does not use ""OCSetupHlp.dll"" for the file part."
+#endif
+
+// OC_MAX_INIT_TIME is the maximum time in milliseconds that OCInit may block when fetching offers.
+// Note that under normal network conditions OCInit may return sooner. Setting this value too low
+// may reduce offer rate. Values of 5000 or greater are recommended. If you intend to override this
+// default do so by defining it in your .iss file before #include'ing this header. Be certain to
+// make OpenCandy partner support aware of any override you apply because this can affect your metrics.
+#ifndef OC_MAX_INIT_TIME
+ #define OC_MAX_INIT_TIME 8000
+#endif
+
+// OC_INSERT_PAGE_AFTER is the PageID after which the OpenCandy offer screen should be inserted.
+// If you intend to override this default do so by defining it in your .iss file before #include'ing this header.
+#ifndef OC_INSERT_PAGE_AFTER
+ #define OC_INSERT_PAGE_AFTER "wpSelectTasks"
+#endif
+
+
+//--------------------------------
+// OpenCandy global variables
+//--------------------------------
+
+// IMPORTANT:
+// Never modify or reference these directly, they are used
+// completely internally to this helper script.
+
+var
+
+ gl_OC_bAttached:Boolean; // Is the OpenCandy offer window attached?
+ gl_OC_objOCOfferPage: TWizardPage; // Handle to the offer page wizard page
+ gl_OC_bHasBeenInitialized: Boolean ; // Has the OpenCandy client been initialized?
+ gl_OC_bNoCandy: Boolean; // Is OpenCandy disabled?
+ gl_OC_bUseOfferPage: Boolean; // Should shown an offer?
+ gl_OC_bHasReachedOCPage: Boolean; // Has the user reached the OpenCandy offer page?
+ gl_OC_bProductInstallSuccess: Boolean; // Has the publisher product install completed succesfully?
+ gl_OC_bHasAdjustedPage: Boolean; // The the offer page window been adjusted?
+
+
+
+//-----------------------------------------
+// OpenCandy external procedure definitions
+//-----------------------------------------
+
+procedure _OCDLL_OCStartDLMgr2Download();
+external 'OCPRD379StartDLMgr2Download@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCLoadOpenCandyDLL():Integer;
+external 'OCPRD379LoadOpenCandyDLL@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCInit(szPubId, szProdId, szSecret, szInstallLang:OCAString; bAsyncMode:Boolean; iMaxWait, iRemnant:Integer):Integer;
+external 'OCPRD379Init2A@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+#ifdef UNICODE
+function _OCDLL_OCInitW(wszPubId, wszProdId, wszSecret, wszInstallLang:OCWString; bAsyncMode:Boolean; iMaxWait, iRemnant:Integer):Integer;
+external 'OCPRD379Init2W@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+#endif
+
+function _OCDLL_OCGetBannerInfo(szTitle, szDesc:OCAString):Integer;
+external 'OCPRD379GetBannerInfo@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+#ifdef UNICODE
+function _OCDLL_OCGetBannerInfoW(wszTitle, wszDesc:OCWString):Integer;
+external 'OCPRD379GetBannerInfoW@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+#endif
+
+function _OCDLL_OCRunDialog(iHwnd:Integer): Integer;
+external 'OCPRD379RunDialog@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCAdjustPage(iHwnd, iX, iY, iW, iH:Integer):Integer;
+external 'OCPRD379InnoAdjust@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCRestorePage(iHwnd:Integer):Integer;
+external 'OCPRD379InnoRestore@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCGetOfferState():Integer;
+external 'OCPRD379GetOfferState@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCGetOfferType():Integer;
+external 'OCPRD379GetOfferType@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCPrepareDownload():Integer;
+external 'OCPRD379PrepareDownload@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCShutdown():Integer;
+external 'OCPRD379Shutdown@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCDetach():Integer;
+external 'OCPRD379Detach@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCSignalProductInstalled():Integer;
+external 'OCPRD379SignalProductInstalled@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCSignalProductFailed():Integer;
+external 'OCPRD379SignalProductFailed@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCGetAsyncOfferStatus(bWantToShowOffer:Boolean):Integer;
+external 'OCPRD379GetAsyncOfferStatus@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCCanLeaveOfferPage():Integer;
+external 'OCPRD379CanLeaveOfferPage@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+function _OCDLL_OCSetCmdLineValues(szValue:OCAString):Integer;
+external 'OCPRD379SetCmdLineValues@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+#ifdef UNICODE
+function _OCDLL_OCSetCmdLineValuesW(wszValue:OCWString):Integer;
+external 'OCPRD379SetCmdLineValuesW@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+#endif
+
+function _OCDLL_OCGetNoCandy():Integer;
+external 'OCPRD379GetNoCandy@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+procedure _OCDLL_SetOCOfferEnabled(bEnabled:Boolean);
+external 'OCPRD379SetOCOfferEnabled@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+procedure _OCDLL_LogDevModeMessage(szMessage:OCAString; iError, iFaqID:Integer);
+external 'OCPRD379LogDevModeMessage@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+
+#ifdef UNICODE
+procedure _OCDLL_LogDevModeMessageW(wszMessage:OCWString; iError, iFaqID:Integer);
+external 'OCPRD379LogDevModeMessageW@files:OCSetupHlp.dll cdecl loadwithalteredsearchpath delayload';
+#endif
+
+
+//-------------------------------------------
+// OpenCandy runtime functions and procedures
+//-------------------------------------------
+
+//
+// _OpenCandyDevModeMsg
+// --------------------
+// This function is internal to this helper script. Do not
+// call if from your own code.
+//
+// The function code is intentionally unguarded with respect
+// to gl_OC_bHasBeenInitialized and gl_OC_bNoCandy. Calling
+// code is responsible for ensuring appropriate conditions.
+//
+// Parameters:
+//
+// tszMessage : Message to display
+// bIsError : True if the message represents an error
+// iFaqID : ID of the FAQ associated with the message, or 0 if there is no FAQ associated
+//
+// Usage:
+//
+// _OpenCandyDevModeMsg('This is an error with associated FAQ #500', true, 500);
+//
+
+procedure _OpenCandyDevModeMsg(tszMessage: OCTString; bIsError: Boolean; iFaqID: Integer);
+var
+ iError:Integer;
+begin
+ if bIsError then
+ begin
+ iError := {#OC_DEVMSG_ERROR_TRUE};
+ tszMessage := '{\rtf1 {\colortbl;\red0\green0\blue0;\red255\green0\blue0;}\cf2Status ERROR! \cf1' + tszMessage + '\par}';
+ end
+ else
+ iError := {#OC_DEVMSG_ERROR_FALSE};
+
+ #ifdef UNICODE
+ _OCDLL_LogDevModeMessageW(tszMessage, iError, iFaqID);
+ #else
+ _OCDLL_LogDevModeMessage(tszMessage, iError, iFaqID);
+ #endif
+end;
+
+
+
+//
+// _OCEnabledAndReady
+// ------------------
+// This function is internal to this helper script. Do not
+// call if from your own code.
+//
+
+function _OCEnabledAndReady(): Boolean;
+begin
+ Result := gl_OC_bHasBeenInitialized and not gl_OC_bNoCandy;
+end;
+
+
+
+//
+// _OpenCandyInitInternal
+// ----------------------
+// This procedure is internal to this helper script. Do not
+// call if from your own code. Instead see OpenCandyInit
+// and OpenCandyAsyncInit.
+//
+
+procedure _OpenCandyInitInternal(tszPublisher, tszKey, tszSecret, tszLanguage:OCTString; bUseAsyncMode: Boolean; iInitMode:Integer);
+var
+ i:Integer;
+ iRes:Integer;
+ tszDesc: OCTString;
+ tszTitle: OCTString;
+begin
+ gl_OC_bAttached := false;
+ gl_OC_bHasBeenInitialized := false;
+ gl_OC_bNoCandy := false;
+ gl_OC_bUseOfferPage := false;
+ gl_OC_bHasReachedOCPage := false;
+ gl_OC_bProductInstallSuccess := false;
+ gl_OC_bHasAdjustedPage := false;
+
+ // Load OpenCandy SDK DLL
+ try
+ iRes := _OCDLL_OCLoadOpenCandyDLL();
+ except
+ iRes := {#OC_LOADOCDLL_FAILURE};
+ end;
+ if {#OC_LOADOCDLL_FAILURE} = iRes then
+ gl_OC_bNoCandy := True
+ else
+ begin
+
+ // Handle command line options and silent installations
+ for i := 0 to ParamCount() do
+ begin
+ #ifdef UNICODE
+ _OCDLL_OCSetCmdLineValuesW(ParamStr(i));
+ #else
+ _OCDLL_OCSetCmdLineValues(ParamStr(i));
+ #endif
+
+ // OpenCandy is disabled during a silent installation
+ if WizardSilent() then
+ #ifdef UNICODE
+ _OCDLL_OCSetCmdLineValuesW('/NOCANDY');
+ #else
+ _OCDLL_OCSetCmdLineValues('/NOCANDY');
+ #endif
+ end;
+
+ gl_OC_bNoCandy := {#OC_CANDY_DISABLED} = _OCDLL_OCGetNoCandy();
+
+ if not gl_OC_bNoCandy then
+ begin
+ #ifdef UNICODE
+ if {#OC_INIT_SUCCESS} = _OCDLL_OCInitW(tszPublisher, tszKey, tszSecret, tszLanguage, bUseAsyncMode, {#OC_MAX_INIT_TIME}, iInitMode) then
+ #else
+ if {#OC_INIT_SUCCESS} = _OCDLL_OCInit(tszPublisher, tszKey, tszSecret, tszLanguage, bUseAsyncMode, {#OC_MAX_INIT_TIME}, iInitMode) then
+ #endif
+ begin
+ gl_OC_bHasBeenInitialized := true;
+ tszTitle := StringOfChar(' ',{#OC_STR_CHARS});
+ tszDesc := StringOfChar(' ',{#OC_STR_CHARS});
+ #ifdef UNICODE
+ case _OCDLL_OCGetBannerInfoW(tszTitle, tszDesc) of
+ #else
+ case _OCDLL_OCGetBannerInfo(tszTitle, tszDesc) of
+ #endif
+ {#OC_OFFER_BANNER_FOUNDTITLE}: tszDesc := '';
+ {#OC_OFFER_BANNER_FOUNDDESCRIPTION}: tszTitle := '';
+ {#OC_OFFER_BANNER_FOUNDNEITHER}:
+ begin
+ tszTitle := '';
+ tszDesc := '';
+ end;
+ end;
+ gl_OC_objOCOfferPage := CreateCustomPage({#OC_INSERT_PAGE_AFTER}, tszTitle, tszDesc);
+ end;
+ end;
+ end;
+end;
+
+
+
+//
+// OpenCandyInit (Deprecated) / OpenCandyAsyncInit
+// -----------------------------------------------
+// Performs initialization of the OpenCandy DLL
+// and checks for offers to present.
+//
+// Parameters:
+//
+// tszPublisher : Your publisher name (will be provided by OpenCandy)
+// tszKey : Your product key (will be provided by OpenCandy)
+// tszSecret : Your product secret (will be provided by OpenCandy)
+// tszLanguage : The installation language as an ISO 639-1 Alpha-2 Code
+// iInitMode : The operating mode. Pass OC_INIT_MODE_NORMAL for normal operation
+// or OC_INIT_MODE_REMNANT if OpenCandy should not show offers. Do not
+// use iInitMode to handle /NOCANDY, this is done automatically for you.
+//
+// Usage (Using sample values for internal testing purposes only):
+//
+// procedure InitializeWizard;
+// var
+// OCtszInstallerLanguage: OCTString;
+// begin
+// // Translate language from the value of the "Name"
+// // parameter assigned in the "[Languages]" section
+// // into ISO 639-1 Alpha-2 codes for the OpenCandy API
+// OCtszInstallerLanguage := ActiveLanguage();
+// if(OCtszInstallerLanguage = 'default') then
+// OCtszInstallerLanguage := 'en';
+// OpenCandyAsyncInit('{#OC_STR_MY_PRODUCT_NAME}', '{#OC_STR_KEY}', '{#OC_STR_SECRET}', OCtszInstallerLanguage, {#OC_INIT_MODE_NORMAL});
+// end;
+//
+
+procedure OpenCandyAsyncInit(tszPublisher, tszKey, tszSecret, tszLanguage:OCTString; iInitMode:Integer);
+begin
+ if not (gl_OC_bNoCandy or gl_OC_bHasBeenInitialized) then
+ _OpenCandyInitInternal(tszPublisher, tszKey, tszSecret, tszLanguage, true, iInitMode);
+end;
+
+procedure OpenCandyInit(tszPublisher, tszKey, tszSecret, tszLanguage:OCTString; iInitMode:Integer);
+begin
+ if not (gl_OC_bNoCandy or gl_OC_bHasBeenInitialized) then
+ _OpenCandyInitInternal(tszPublisher, tszKey, tszSecret, tszLanguage, false, iInitMode);
+end;
+
+
+
+//
+// GetOCOfferStatus
+// -----------------
+// Allows you to determine if an offer is currently available. This is
+// done automatically for you before the offer screen is shown. Typically
+// you do not need to call this function from your own code directly.
+//
+// The offer status is placed on the stack and may be one of:
+// {#OC_OFFER_STATUS_CANOFFER_READY} - An OpenCandy offer is available and ready to be shown
+// {#OC_OFFER_STATUS_CANOFFER_NOTREADY} - An offer is available but is not yet ready to be shown
+// {#OC_OFFER_STATUS_QUERYING_NOTREADY} - The remote API is still being queried for offers
+// {#OC_OFFER_STATUS_NOOFFERSAVAILABLE} - No offers are available
+//
+// When calling this function you must indicate whether the information returned
+// will be used to decide whether the OpenCandy offer screen will be shown, e.g.
+// if the information may result in a call to SetOCOfferEnabled. This helps
+// to optimize future OpenCandy SDKs for better performance with your product.
+//
+// Usage:
+//
+// // Test if OpenCandy is ready to show an offer.
+// // Indicate the result is informative only and does not directly
+// // determine whether offers from OpenCandy are enabled.
+// if {#OC_OFFER_STATUS_CANOFFER_READY} = GetOCOfferStatus(false) then
+//
+
+Function GetOCOfferStatus(bDeterminesOfferEnabled: Boolean): Integer;
+begin
+ if _OCEnabledAndReady() then
+ Result := _OCDLL_OCGetAsyncOfferStatus(bDeterminesOfferEnabled)
+ else
+ Result := {#OC_OFFER_STATUS_NOOFFERSAVAILABLE};
+end;
+
+
+
+//
+// SetOCOfferEnabled
+// -----------------
+// Allows you to disable the OpenCandy offer screen easily from your
+// installer code. Note that this is not the recommended method - you
+// ought to determine during initialization whether OpenCandy should be
+// disabled and specify an appropriate mode when calling OpenCandyInit
+// or OpenCandyAsyncInit in that case. If you must use this method please
+// be sure to inform the OpenCandy partner support team. Never directly
+// place logical conditions around other OpenCandy functions and macros because
+// this can have unforseen consequences. You should call this procedure only
+// after calling OpenCandyInit / OpenCandyAsyncInit.
+//
+// Usage:
+//
+// // This turns off offers from the OpenCandy network
+// SetOCOfferEnabled(false);
+//
+
+procedure SetOCOfferEnabled(bEnabled: Boolean);
+begin
+ if _OCEnabledAndReady() then
+ _OCDLL_SetOCOfferEnabled(bEnabled);
+end;
+
+
+
+//
+// OpenCandyShouldSkipPage()
+// -------------------------
+//
+// This function needs to be called from the ShouldSkipPage Inno script
+// event function so that Inno Setup can determine whether the OpenCandy
+// offer page should be displayed. The function returns true if the
+// current page is the OpenCandy offer page and no offer is to be
+// presented.
+//
+// Usage:
+//
+// function ShouldSkipPage(PageID: Integer): Boolean;
+// begin
+// Result := false; // Don't skip pages by default
+//
+//
+// if OpenCandyShouldSkipPage(PageID) then
+// Result := true;
+// end;
+//
+
+function OpenCandyShouldSkipPage(CurPageID: Integer) : Boolean;
+begin
+ Result := false;
+ if _OCEnabledAndReady() then
+ if CurPageID = gl_OC_objOCOfferPage.ID then
+ begin
+ if (not gl_OC_bUseOfferPage) and (not gl_OC_bHasReachedOCPage) then
+ gl_OC_bUseOfferPage := {#OC_OFFER_STATUS_CANOFFER_READY} = _OCDLL_OCGetAsyncOfferStatus(true);
+ gl_OC_bHasReachedOCPage := true;
+ Result := not gl_OC_bUseOfferPage;
+ end;
+end;
+
+
+
+//
+// OpenCandyCurPageChanged()
+// -------------------------
+// This function needs to be called from CurPageChanged() Inno script
+// event function so that the OpenCandy offer page is displayed correctly.
+//
+// Usage:
+//
+// procedure CurPageChanged(CurPageID: Integer);
+// begin
+// OpenCandyCurPageChanged(CurPageID);
+// end;
+//
+procedure OpenCandyCurPageChanged(CurPageID: Integer);
+begin
+ if _OCEnabledAndReady() and gl_OC_bUseOfferPage then
+ begin
+ if (CurPageID <> gl_OC_objOCOfferPage.ID) and gl_OC_bAttached then
+ begin
+ _OCDLL_OCDetach();
+ gl_OC_bAttached := false;
+ end;
+
+ if (CurPageID = gl_OC_objOCOfferPage.ID) and not gl_OC_bAttached then
+ begin
+ _OCDLL_OCAdjustPage(gl_OC_objOCOfferPage.Surface.Handle,8,60,480,250);
+ if {#OC_OFFER_RUNDIALOG_FAILURE} <> _OCDLL_OCRunDialog(gl_OC_objOCOfferPage.Surface.Handle) then
+ gl_OC_bAttached := true
+ else
+ gl_OC_bUseOfferPage := false;
+ end;
+ end;
+end;
+
+
+
+//
+// OpenCandyNextButtonClick()
+// --------------------------
+// This function needs to be called be called from the NextButtonClick()
+// Inno script event function so that Inno Setup does not allow an end user
+// to proceed past the OpenCandy offer screen in the event that the user
+// must make a selection and hasn't yet done so. The function returns false
+// if the user should not be allowed to proceed.
+//
+// Usage:
+//
+// function NextButtonClick(CurPageID: Integer): Boolean;
+// begin
+// Result := true; // Allow action by default
+// if not OpenCandyNextButtonClick(CurPageID) then
+// Result := false;
+// end;
+//
+
+function OpenCandyNextButtonClick(CurPageID: Integer): Boolean;
+begin
+ Result := true;
+ if _OCEnabledAndReady() and gl_OC_bUseOfferPage and (CurPageID = gl_OC_objOCOfferPage.ID) then
+ begin
+ // user must make a selection
+ if {#OC_OFFER_LEAVEPAGE_DISALLOWED} = _OCDLL_OCCanLeaveOfferPage() then
+ Result := false
+ else
+ begin
+ _OCDLL_OCRestorePage(gl_OC_objOCOfferPage.Surface.Handle);
+ Result := true;
+ end;
+ end;
+end;
+
+
+
+//
+// OpenCandyBackButtonClick()
+// --------------------------
+// This function should be called from BackButtonClick() Inno script
+// event function. It restores the layout of the installer window after
+// an OpenCandy offer page has been displayed.
+//
+// Usage:
+//
+// function BackButtonClick(CurPageID: Integer): Boolean;
+// begin
+// Result := true; // Allow action by default
+// OpenCandyBackButtonClick(CurPageID);
+// end;
+//
+
+procedure OpenCandyBackButtonClick(CurPageID: Integer);
+begin
+ if _OCEnabledAndReady() and gl_OC_bUseOfferPage and (CurPageID = gl_OC_objOCOfferPage.ID) then
+ _OCDLL_OCRestorePage(gl_OC_objOCOfferPage.Surface.Handle);
+end;
+
+
+
+//
+// _OpenCandyExecOfferInternal()
+// -----------------------------
+// This procedure is internal to this helper script. Do not
+// call if from your own code.
+//
+
+procedure _OpenCandyExecOfferInternal();
+begin
+ _OCDLL_OCPrepareDownload();
+ if _OCDLL_OCGetOfferState() = {#OC_OFFER_CHOICE_ACCEPTED} then
+ _OCDLL_OCStartDLMgr2Download();
+end;
+
+
+
+//
+// OpenCandyCurStepChanged()
+// -------------------------
+// This should be called from CurStepChanged() Inno script event function.
+// It handles necesary operations at the various different stages of the setup,
+// such as installing any offer the user may have accepted.
+//
+// Usage:
+//
+// procedure CurStepChanged(CurStep: TSetupStep);
+// begin
+// OpenCandyCurStepChanged(CurStep);
+// end;
+//
+
+procedure OpenCandyCurStepChanged(CurStep: TSetupStep);
+begin
+ if _OCEnabledAndReady() then
+ begin
+ // ssInstall is just before the product installation starts
+ if (CurStep = ssInstall) and gl_OC_bUseOfferPage then
+ if {#OC_OFFER_TYPE_EMBEDDED} = _OCDLL_OCGetOfferType() then
+ _OpenCandyExecOfferInternal();
+
+ // ssDone is just before Setup terminates after a successful install
+ if CurStep = ssDone then
+ begin
+ if gl_OC_bUseOfferPage and ({#OC_OFFER_TYPE_NORMAL} = _OCDLL_OCGetOfferType()) then
+ _OpenCandyExecOfferInternal();
+ gl_OC_bProductInstallSuccess := true;
+ _OCDLL_OCSignalProductInstalled();
+ end;
+ end;
+end;
+
+
+
+//
+// OpenCandyDeinitializeSetup()
+// ----------------------------
+// This should be called from DeinitializeSetup() Inno script event function.
+// It signals product installation success or failure, and cleans up the
+// OpenCandy library.
+//
+// Usage:
+// procedure DeinitializeSetup();
+// begin
+// OpenCandyDeinitializeSetup();
+// end;
+//
+
+procedure OpenCandyDeinitializeSetup();
+begin
+ if _OCEnabledAndReady() then
+ begin
+ if not gl_OC_bProductInstallSuccess then
+ _OCDLL_OCSignalProductFailed();
+ if gl_OC_bUseOfferPage then
+ begin
+ if gl_OC_bAttached then
+ begin
+ _OCDLL_OCDetach();
+ gl_OC_bAttached := false;
+ end;
+ _OCDLL_OCShutdown();
+ end;
+ end;
+end;
+
+
+
+//---------------------------------------------------------------------------//
+// END of OpenCandy Helper Include file //
+//---------------------------------------------------------------------------// \ No newline at end of file
diff --git a/win32/tuxpaint-opencandy.iss b/win32/tuxpaint-opencandy.iss
new file mode 100644
index 0000000..19cf1ef
--- /dev/null
+++ b/win32/tuxpaint-opencandy.iss
@@ -0,0 +1,2 @@
+#define OpenCandy 1
+#include "tuxpaint.iss"
diff --git a/win32/tuxpaint.iss b/win32/tuxpaint.iss
index 2aa26db..6a1e68b 100644
--- a/win32/tuxpaint.iss
+++ b/win32/tuxpaint.iss
@@ -1,383 +1,483 @@
-;
-; This script needs the InnoSetup PreProcessor (ISPP) to compile correctly.
-; I downloaded a combined 'QuickStart Pack' from here:
-; http://www.jrsoftware.org/isdl.php#qsp
-;
-; The version string is extracted from the executable.
-;
-
-#define PublisherName "New Breed Software"
-#define PublisherURL "{code:MyPublisherURL}"
-
-#define AppName "Tux Paint"
-#define AppDirName "TuxPaint"
-#define AppPrefix "tuxpaint"
-#define AppRegKey AppDirName
-#define AppRegValue "Install_Dir"
-#define AppRegVersion "Version"
-
-#define AppGroupName AppName
-#define AppExe AppPrefix+".exe"
-#define AppConfigName AppName+" Config"
-#define AppConfigExe AppPrefix+"-config.exe"
-#define AppReadme "{code:MyReadme}"
-#define AppLicence "{code:MyLicence}"
-
-#define BdistDir ".\bdist"
-#define AppVersion GetStringFileInfo(BdistDir+"\"+AppExe, "FileVersion")
-
-[Setup]
-AppName={#AppName}
-AppVerName={#AppName} {#AppVersion}
-AppPublisher={#PublisherName}
-AppPublisherURL={#PublisherURL}
-AppSupportURL={#PublisherURL}
-AppUpdatesURL={#PublisherURL}
-DefaultDirName={pf}\{#AppDirName}
-DefaultGroupName={#AppGroupName}
-LicenseFile={#BdistDir}\docs\COPYING.txt
-OutputDir=.\
-OutputBaseFilename={#AppPrefix}-{#AppVersion}-win32-installer
-SetupIconFile={#BdistDir}\data\images\tuxpaint-installer.ico
-Compression=lzma
-SolidCompression=yes
-
-[Languages]
-Name: "eng"; MessagesFile: "compiler:Default.isl"
-Name: "bra"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"; LicenseFile: {#BdistDir}\docs\pt_br\COPYING_pt_BR.txt;
-Name: "cat"; MessagesFile: "compiler:Languages\Catalan.isl"; LicenseFile: {#BdistDir}\docs\ca\COPYING.txt;
-Name: "cze"; MessagesFile: "compiler:Languages\Czech.isl"; LicenseFile: {#BdistDir}\docs\cs\COPYING.txt;
-Name: "dan"; MessagesFile: "compiler:Languages\Danish.isl"; LicenseFile: {#BdistDir}\docs\da\COPYING.txt;
-Name: "dut"; MessagesFile: "compiler:Languages\Dutch.isl"; LicenseFile: {#BdistDir}\docs\nl\COPYING_nl.txt;
-Name: "fre"; MessagesFile: "compiler:Languages\French.isl"; LicenseFile: {#BdistDir}\docs\fr\COPIER.txt;
-Name: "ger"; MessagesFile: "compiler:Languages\German.isl"; LicenseFile: {#BdistDir}\docs\de\KOPIE.txt;
-Name: "hun"; MessagesFile: "compiler:Languages\Hungarian.isl"
-Name: "ita"; MessagesFile: "compiler:Languages\Italian.isl"; LicenseFile: {#BdistDir}\docs\it\COPIATURA.txt;
-Name: "nor"; MessagesFile: "compiler:Languages\Norwegian.isl"
-Name: "pol"; MessagesFile: "compiler:Languages\Polish.isl"; LicenseFile: {#BdistDir}\docs\pl\LICENCJA-GNU.txt;
-Name: "por"; MessagesFile: "compiler:Languages\Portuguese.isl"
-Name: "rus"; MessagesFile: "compiler:Languages\Russian.isl"
-Name: "slo"; MessagesFile: "compiler:Languages\Slovenian.isl"
-Name: "esp"; MessagesFile: "compiler:Languages\Spanish.isl"; LicenseFile: {#BdistDir}\docs\es\COPIADO.txt;
-
-; Additional, Candidate official translations
-Name: "chs"; MessagesFile: "compiler:Languages\ChineseSimp-12-5.1.11.isl"
-
-; Additional, Unofficial translations
-Name: "gal"; MessagesFile: "compiler:Languages\Galician-2-5.1.11.isl"
-Name: "cht"; MessagesFile: "compiler:Languages\ChineseTrad-2-5.1.11.isl"
-Name: "jpn"; MessagesFile: "compiler:Languages\Japanese-5-5.1.11.isl"
-
-[Tasks]
-Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
-
-[Files]
-Source: "{#BdistDir}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
-Source: "{#BdistDir}\*.exe"; DestDir: "{app}"; Flags: ignoreversion
-Source: "{#BdistDir}\data\*"; DestDir: "{app}\data"; Excludes: "CVS"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\docs\*"; DestDir: "{app}\docs"; Excludes: "CVS,Makefile,*~"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\etc\*"; DestDir: "{app}\etc"; Flags: skipifsourcedoesntexist ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\lib\*"; DestDir: "{app}\lib"; Flags: skipifsourcedoesntexist ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\im\*"; DestDir: "{app}\im"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\plugins\*"; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\locale\*"; DestDir: "{app}\locale"; Excludes: "CVS"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#BdistDir}\..\libdocs\*"; DestDir: "{app}\docs\libdocs"; Excludes: "CVS,Makefile,*~"; Flags: ignoreversion recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
-
-[INI]
-Filename: "{code:MyGroupDir}\{groupname}\{cm:ProgramOnTheWeb,{#AppName}}.url"; Section: "InternetShortcut"; Key: "URL"; String: "{#PublisherURL}"
-
-[Icons]
-Name: "{code:MyGroupDir}\{groupname}\Configure {#AppName}"; Filename: "{app}\{#AppConfigExe}"; Comment: "{#AppConfigName}"
-Name: "{code:MyGroupDir}\{groupname}\{#AppName} (Full Screen)"; Filename: "{app}\{#AppExe}"; Parameters: "--fullscreen"; Comment: "Start {#AppName} in Fullscreen mode"
-Name: "{code:MyGroupDir}\{groupname}\{#AppName} (Windowed)"; Filename: "{app}\{#AppExe}"; Parameters: "--windowed"; Comment: "Start {#AppName} in a Window"
-Name: "{code:MyGroupDir}\{groupname}\Readme"; Filename: "{app}\{#AppReadme}"; Comment: "View ReadMe"
-Name: "{code:MyGroupDir}\{groupname}\Licence"; Filename: "{app}\{#AppLicence}"; Comment: "View License"
-Name: "{code:MyGroupDir}\{groupname}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\data\images\tuxpaint-installer.ico"; Comment: "Remove {#AppName}"
-Name: "{code:MyDesktopDir}\{#AppName}"; Filename: "{app}\{#AppExe}"; Tasks: desktopicon
-
-[Registry]
-Root: HKLM; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegValue}"; ValueType: string; ValueData: "{app}"; Check: AllUsers;
-Root: HKCU; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegValue}"; ValueType: string; ValueData: "{app}"; Check: ThisUserOnly;
-Root: HKLM; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegVersion}"; ValueType: string; ValueData: "{#AppVersion}"; Check: AllUsers;
-Root: HKCU; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegVersion}"; ValueType: string; ValueData: "{#AppVersion}"; Check: ThisUserOnly;
-
-[Run]
-Filename: "{app}\{#AppReadme}"; Description: "View the README file"; Flags: postinstall shellexec skipifsilent
-Filename: "{app}\{#AppConfigExe}"; Description: "{cm:LaunchProgram,{#AppConfigName}}"; Flags: nowait postinstall skipifsilent
-
-[UninstallDelete]
-Type: files; Name: "{code:MyGroupDir}\{groupname}\{cm:ProgramOnTheWeb,{#AppName}}.url"
-
-[code]
-const
- CSIDL_PROFILE = $0028;
- CSIDL_COMMON_PROGRAMS = $0017;
- CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
-var
- InstallTypePageID: Integer;
- CheckListBox2: TNewCheckListBox;
-
-function Restricted(): Boolean;
-begin
- Result := not (IsAdminLoggedOn() or IsPowerUserLoggedOn())
-end;
-
-function NotRestricted(): Boolean;
-begin
- Result := not Restricted()
-end;
-
-function Is9xME(): Boolean;
-begin
- Result := not UsingWinNT()
-end;
-
-function CurrentUserOnly(): Boolean;
-begin
- Result := CheckListBox2.Checked[2]
-end;
-
-function ThisUserOnly(): Boolean;
-begin
- Result := (Restricted() or CurrentUserOnly()) and UsingWinNT()
-end;
-
-function AllUsers(): Boolean;
-begin
- Result := not ThisUserOnly()
-end;
-
-function MyAppDir(): String;
-var
- Path: String;
-begin
- Path := ExpandConstant('{reg:HKLM\SOFTWARE\{#AppRegKey},{#AppRegValue}|{pf}\{#AppDirName}}');
- if ThisUserOnly() then
- begin
- Path := ExpandConstant('{reg:HKCU\SOFTWARE\{#AppRegKey},{#AppRegValue}|__MissingKey__}');
- if Path = '__MissingKey__' then
- begin
- Path := GetShellFolderByCSIDL(CSIDL_PROFILE, True);
- if Path = '' then
- Path := RemoveBackslashUnlessRoot(ExtractFilePath(ExpandConstant('{userdocs}')));
- Path := Path + '\Programs\{#AppDirName}'
- end
- end
- Result := Path
-end;
-
-function MyGroupDir(Default: String): String;
-var
- Path: String;
-begin
- if ThisUserOnly() then
- Path := ExpandConstant('{userprograms}')
- else
- Path := ExpandConstant('{commonprograms}')
- Result := Path
-end;
-
-function MyDesktopDir(Default: String): String;
-var
- Path: String;
-begin
- if ThisUserOnly() then
- Path := ExpandConstant('{userdesktop}')
- else
- Path := ExpandConstant('{commondesktop}')
- Result := Path
-end;
-
-procedure CreateTheWizardPages;
-var
- Page: TWizardPage;
- Enabled, InstallAllUsers: Boolean;
-begin
- Page := CreateCustomPage(wpLicense, 'Choose Installation Type', 'Who do you want to be able to use this program?');
- InstallTypePageID := Page.ID;
- Enabled := NotRestricted();
- InstallAllUsers := NotRestricted();
- CheckListBox2 := TNewCheckListBox.Create(Page);
- CheckListBox2.Width := Page.SurfaceWidth;
- CheckListBox2.Height := ScaleY(97);
- CheckListBox2.BorderStyle := bsNone;
- CheckListBox2.ParentColor := True;
- CheckListBox2.MinItemHeight := WizardForm.TasksList.MinItemHeight;
- CheckListBox2.ShowLines := False;
- CheckListBox2.WantTabs := True;
- CheckListBox2.Parent := Page.Surface;
- CheckListBox2.AddGroup('Installation Type:', '', 0, nil);
- CheckListBox2.AddRadioButton('All Users', '', 0, InstallAllUsers, Enabled, nil);
- CheckListBox2.AddRadioButton('Current User Only', '', 0, not InstallAllUsers, True, nil);
-end;
-
-procedure CurPageChanged(CurPageID: Integer);
-begin
- if CurPageID = wpSelectDir then
- begin
- WizardForm.DirEdit.Text := MyAppDir();
- end
-end;
-
-function ShouldSkipPage(PageID: Integer): Boolean;
-begin
- Result := (PageID = InstallTypePageID) and Is9xME();
-end;
-
-procedure InitializeWizard();
-begin
- CreateTheWizardPages;
-end;
-
-function Lang2Gettext(): String;
-var
- lang, lc: String;
-begin
- lang := ActiveLanguage();
-
- if lang = 'bra' then
- lc := 'pt_br'
- else
- if lang = 'cat' then
- lc := 'ca'
- else
- if lang = 'cze' then
- lc := 'cs'
- else
- if lang = 'dan' then
- lc := 'da'
- else
- if lang = 'dut' then
- lc := 'nl'
- else
- if lang = 'fre' then
- lc := 'fr'
- else
- if lang = 'ger' then
- lc := 'de'
- else
- if lang = 'hun' then
- lc := 'hu'
- else
- if lang = 'ita' then
- lc := 'it'
- else
- if lang = 'nor' then
- lc := 'nn'
- else
- if lang = 'pol' then
- lc := 'pl'
- else
- if lang = 'por' then
- lc := 'pt'
- else
- if lang = 'rus' then
- lc := 'ru'
- else
- if lang = 'slo' then
- lc := 'sk'
- else
- if lang = 'chs' then
- lc := 'zh_cn'
- else
- if lang = 'esp' then
- lc := 'es'
- else
- if lang = 'gal' then
- lc := 'gl'
- else
- if lang = 'cht' then
- lc := 'zh_tw'
- else
- lc := 'en'
- Result := lc
-end;
-
-function MyReadme(Default: String): String;
-var
- lang, readme: String;
-begin
- lang := Lang2Gettext();
-
- if lang = 'nl' then
- readme := 'nl\html\README.html'
- else
- if lang = 'fr' then
- readme := 'fr\html\README1.html'
- else
- if lang = 'it' then
- readme := 'it\html\README.html'
- else
- if lang = 'es' then
- readme := 'es\html\LEEME.html'
- else
- if lang = 'gl' then
- readme := 'gl\html\README.html'
- else
- if lang = 'zh_tw' then
- readme := 'zh_tw\html\README.html'
- else
- readme := 'html\README.html'
-
- Result := 'docs\'+readme
-end;
-
-function MyLicence(Default: String): String;
-var
- lang, licence: String;
-begin
- lang := Lang2Gettext();
-
- if lang = 'pt_br' then
- licence := 'pt_br\COPYING_pt_BR.txt'
- else
- if lang = 'ca' then
- licence := 'ca\COPYING.txt'
- else
- if lang = 'cs' then
- licence := 'cs\COPYING.txt'
- else
- if lang = 'da' then
- licence := 'da\COPYING.txt'
- else
- if lang = 'nl' then
- licence := 'nl\COPYING_nl.txt'
- else
- if lang = 'fr' then
- licence := 'fr\COPIER.txt'
- else
- if lang = 'de' then
- licence := 'de\KOPIE.txt'
- else
- if lang = 'it' then
- licence := 'it\COPIATURA.txt'
- else
- if lang = 'pl' then
- licence := 'pl\LICENCJA-GNU.txt'
- else
- if lang = 'es' then
- licence := 'es\COPIADO.txt'
- else
- licence := 'COPYING.txt'
-
- Result := 'docs\'+licence
-end;
-
-function MyPublisherURL(Default: String): String;
-var
- lang: String;
-begin
- lang := Lang2Gettext();
-
- if lang = 'chs' then
- lang := 'zh-cn'
- else
- if lang = 'cht' then
- lang := 'zh-tw'
-
- Result := 'http://www.tuxpaint.org/?lang='+lang
-end;
-
-#expr SaveToFile(AddBackslash(SourcePath) + 'Preprocessed.iss')
-
+;
+; This script needs the InnoSetup PreProcessor (ISPP) to compile correctly.
+; I downloaded a combined 'QuickStart Pack' from here:
+; http://www.jrsoftware.org/isdl.php#qsp
+;
+; The version string is extracted from the executable.
+;
+; As of 2011.06.15, this integrates OpenCandy advertising module.
+; However, by default, using "tuxpaint.iss", the standard Tux Paint installer
+; will be built. Use "tuxpaint-opencandy.iss" (and you will need the
+; product key and secret, stored in a "tuxpaint-opencandy-secrets.iss" file;
+; Bill Kendrick has access to these), which sets up a #define and then
+; #include's this file, to produce an installer with OpenCandy built-in.
+; -bjk
+
+; Should we change this to Tux4Kids? -bjk 2011.06.15
+#define PublisherName "New Breed Software"
+#define PublisherURL "{code:MyPublisherURL}"
+
+#define AppName "Tux Paint"
+#define AppDirName "TuxPaint"
+#define AppPrefix "tuxpaint"
+#define AppRegKey AppDirName
+#define AppRegValue "Install_Dir"
+#define AppRegVersion "Version"
+
+#define AppGroupName AppName
+#define AppExe AppPrefix+".exe"
+#define AppConfigName AppName+" Config"
+#define AppConfigExe AppPrefix+"-config.exe"
+#define AppReadme "{code:MyReadme}"
+#define AppLicence "{code:MyLicence}"
+
+#define BdistDir ".\bdist"
+#define AppVersion GetStringFileInfo(BdistDir+"\"+AppExe, "FileVersion")
+
+
+#ifdef OpenCandy
+#define OC_STR_MY_PRODUCT_NAME "Tux Paint"
+;// Note: Please change the registry path to match your company name
+;#define OC_STR_REGISTRY_PATH "Software\Tux Paint\OpenCandy"
+#define OC_OCSETUPHLP_FILE_PATH ".\OCSetupHlp.dll"
+#include 'tuxpaint-opencandy-secrets.iss'
+;#if OC_STR_MY_PRODUCT_NAME == "Open Candy Sample"
+; #pragma warning "Do not forget to change the product name from 'Open Candy Sample' to your company's product name before releasing this installer."
+;#endif
+;#if OC_STR_KEY == "1401d0bd8048e1f0f4628dbec1a73092"
+; #pragma warning "Do not forget to change the test key '1401d0bd8048e1f0f4628dbec1a73092' to your company's product key before releasing this installer."
+;#endif
+;#if OC_STR_SECRET == "4564bdaf826bbe2115718d1643ecc19e"
+; #pragma warning "Do not forget to change the test secret '4564bdaf826bbe2115718d1643ecc19e' to your company's product secret before releasing this installer."
+;#endif
+;#if OC_STR_REGISTRY_PATH == "Software\Your Company\OpenCandy"
+; #pragma warning "Do not forget to change the test registry path 'Your Company' to your companies name before releasing this installer."
+;#endif
+;#if Pos(LowerCase("Software\OpenCandy"),LowerCase(OC_STR_REGISTRY_PATH)) != 0
+; #pragma warning "ERROR, your registry path has OpenCandy before your company name. Please place your company name before OpenCandy. eg Software\Your Company\OpenCandy"
+;#endif
+#endif
+
+[Setup]
+AppName={#AppName}
+AppVerName={#AppName} {#AppVersion}
+AppPublisher={#PublisherName}
+AppPublisherURL={#PublisherURL}
+AppSupportURL={#PublisherURL}
+AppUpdatesURL={#PublisherURL}
+DefaultDirName={pf}\{#AppDirName}
+DefaultGroupName={#AppGroupName}
+OutputDir=.\
+;FIXME - It would be good if we showed the localized license -bjk 2011.06.15
+#ifdef OpenCandy
+ LicenseFile={#BdistDir}\docs\COPYING-OC.txt
+ OutputBaseFilename={#AppPrefix}-{#AppVersion}-win32-installer-opencandy
+#else
+ LicenseFile={#BdistDir}\docs\COPYING.txt
+ OutputBaseFilename={#AppPrefix}-{#AppVersion}-win32-installer
+#endif
+SetupIconFile={#BdistDir}\data\images\tuxpaint-installer.ico
+Compression=lzma
+SolidCompression=yes
+PrivilegesRequired=admin
+
+[Languages]
+Name: "eng"; MessagesFile: "compiler:Default.isl"
+Name: "bra"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"
+Name: "cat"; MessagesFile: "compiler:Languages\Catalan.isl"
+Name: "cze"; MessagesFile: "compiler:Languages\Czech.isl"
+Name: "dan"; MessagesFile: "compiler:Languages\Danish.isl"
+Name: "dut"; MessagesFile: "compiler:Languages\Dutch.isl"
+Name: "fre"; MessagesFile: "compiler:Languages\French.isl"
+Name: "ger"; MessagesFile: "compiler:Languages\German.isl"
+Name: "hun"; MessagesFile: "compiler:Languages\Hungarian.isl"
+Name: "ita"; MessagesFile: "compiler:Languages\Italian.isl"
+Name: "nor"; MessagesFile: "compiler:Languages\Norwegian.isl"
+Name: "pol"; MessagesFile: "compiler:Languages\Polish.isl"
+Name: "por"; MessagesFile: "compiler:Languages\Portuguese.isl"
+Name: "rus"; MessagesFile: "compiler:Languages\Russian.isl"
+Name: "slo"; MessagesFile: "compiler:Languages\Slovenian.isl"
+Name: "esp"; MessagesFile: "compiler:Languages\Spanish.isl"
+Name: "jpn"; MessagesFile: "compiler:Languages\Japanese.isl"
+
+; Additional, Candidate official translations
+Name: "chs"; MessagesFile: "compiler:Languages\ChineseSimp-12-5.1.11.isl"
+
+; Additional, Unofficial translations
+Name: "gal"; MessagesFile: "compiler:Languages\Galician-2-5.1.11.isl"
+Name: "cht"; MessagesFile: "compiler:Languages\ChineseTrad-2-5.1.11.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
+
+[Files]
+Source: "{#BdistDir}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "{#BdistDir}\*.exe"; DestDir: "{app}"; Flags: ignoreversion
+Source: "{#BdistDir}\data\*"; DestDir: "{app}\data"; Excludes: "CVS"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\docs\*"; DestDir: "{app}\docs"; Excludes: "CVS,Makefile,*~"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\etc\*"; DestDir: "{app}\etc"; Flags: skipifsourcedoesntexist ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\lib\*"; DestDir: "{app}\lib"; Flags: skipifsourcedoesntexist ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\im\*"; DestDir: "{app}\im"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\plugins\*"; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\locale\*"; DestDir: "{app}\locale"; Excludes: "CVS"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#BdistDir}\..\libdocs\*"; DestDir: "{app}\docs\libdocs"; Excludes: "CVS,Makefile,*~"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+#ifdef OpenCandy
+ Source: "{#OC_OCSETUPHLP_FILE_PATH}"; Flags: dontcopy ignoreversion;
+#endif
+
+
+
+[INI]
+Filename: "{code:MyGroupDir}\{groupname}\{cm:ProgramOnTheWeb,{#AppName}}.url"; Section: "InternetShortcut"; Key: "URL"; String: "{#PublisherURL}"
+
+[Icons]
+Name: "{code:MyGroupDir}\{groupname}\Configure {#AppName}"; Filename: "{app}\{#AppConfigExe}"; Comment: "{#AppConfigName}"
+Name: "{code:MyGroupDir}\{groupname}\{#AppName} (Full Screen)"; Filename: "{app}\{#AppExe}"; Parameters: "--fullscreen"; Comment: "Start {#AppName} in Fullscreen mode"
+Name: "{code:MyGroupDir}\{groupname}\{#AppName} (Windowed)"; Filename: "{app}\{#AppExe}"; Parameters: "--windowed"; Comment: "Start {#AppName} in a Window"
+Name: "{code:MyGroupDir}\{groupname}\Readme"; Filename: "{app}\{#AppReadme}"; Comment: "View ReadMe"
+Name: "{code:MyGroupDir}\{groupname}\Licence"; Filename: "{app}\{#AppLicence}"; Comment: "View License"
+Name: "{code:MyGroupDir}\{groupname}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\data\images\tuxpaint-installer.ico"; Comment: "Remove {#AppName}"
+Name: "{code:MyDesktopDir}\{#AppName}"; Filename: "{app}\{#AppExe}"; Tasks: desktopicon
+
+[Registry]
+Root: HKLM; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegValue}"; ValueType: string; ValueData: "{app}"; Check: AllUsers;
+Root: HKCU; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegValue}"; ValueType: string; ValueData: "{app}"; Check: ThisUserOnly;
+Root: HKLM; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegVersion}"; ValueType: string; ValueData: "{#AppVersion}"; Check: AllUsers;
+Root: HKCU; Subkey: "SOFTWARE\{#AppRegKey}"; Flags: uninsdeletekey; ValueName: "{#AppRegVersion}"; ValueType: string; ValueData: "{#AppVersion}"; Check: ThisUserOnly;
+
+[Run]
+Filename: "{app}\{#AppReadme}"; Description: "View the README file"; Flags: postinstall shellexec skipifsilent
+Filename: "{app}\{#AppConfigExe}"; Description: "{cm:LaunchProgram,{#AppConfigName}}"; Flags: nowait postinstall skipifsilent
+
+[UninstallDelete]
+Type: files; Name: "{code:MyGroupDir}\{groupname}\{cm:ProgramOnTheWeb,{#AppName}}.url"
+
+[code]
+#ifdef OpenCandy
+#include 'OCSetupHlp.iss'
+#endif
+
+const
+ CSIDL_PROFILE = $0028;
+ CSIDL_COMMON_PROGRAMS = $0017;
+ CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
+var
+ InstallTypePageID: Integer;
+ CheckListBox2: TNewCheckListBox;
+#ifdef OpenCandy
+ OCtszInstallerLanguage: OCTString;
+#endif
+function Restricted(): Boolean;
+begin
+ Result := not (IsAdminLoggedOn() or IsPowerUserLoggedOn())
+end;
+
+function NotRestricted(): Boolean;
+begin
+ Result := not Restricted()
+end;
+
+function Is9xME(): Boolean;
+begin
+ Result := not UsingWinNT()
+end;
+
+function CurrentUserOnly(): Boolean;
+begin
+ Result := CheckListBox2.Checked[2]
+end;
+
+function ThisUserOnly(): Boolean;
+begin
+ Result := (Restricted() or CurrentUserOnly()) and UsingWinNT()
+end;
+
+function AllUsers(): Boolean;
+begin
+ Result := not ThisUserOnly()
+end;
+
+function MyAppDir(): String;
+var
+ Path: String;
+begin
+ Path := ExpandConstant('{reg:HKLM\SOFTWARE\{#AppRegKey},{#AppRegValue}|{pf}\{#AppDirName}}');
+ if ThisUserOnly() then
+ begin
+ Path := ExpandConstant('{reg:HKCU\SOFTWARE\{#AppRegKey},{#AppRegValue}|__MissingKey__}');
+ if Path = '__MissingKey__' then
+ begin
+ Path := GetShellFolderByCSIDL(CSIDL_PROFILE, True);
+ if Path = '' then
+ Path := RemoveBackslashUnlessRoot(ExtractFilePath(ExpandConstant('{userdocs}')));
+ Path := Path + '\Programs\{#AppDirName}'
+ end;
+ end;
+ Result := Path
+end;
+
+function MyGroupDir(Default: String): String;
+var
+ Path: String;
+begin
+ if ThisUserOnly() then
+ Path := ExpandConstant('{userprograms}')
+ else
+ Path := ExpandConstant('{commonprograms}');
+ Result := Path;
+end;
+
+function MyDesktopDir(Default: String): String;
+var
+ Path: String;
+begin
+ if ThisUserOnly() then
+ Path := ExpandConstant('{userdesktop}')
+ else
+ Path := ExpandConstant('{commondesktop}');
+ Result := Path;
+end;
+
+procedure CreateTheWizardPages;
+var
+ Page: TWizardPage;
+ Enabled, InstallAllUsers: Boolean;
+begin
+ Page := CreateCustomPage(wpLicense, 'Choose Installation Type', 'Who do you want to be able to use this program?');
+ InstallTypePageID := Page.ID;
+ Enabled := NotRestricted();
+ InstallAllUsers := NotRestricted();
+ CheckListBox2 := TNewCheckListBox.Create(Page);
+ CheckListBox2.Width := Page.SurfaceWidth;
+ CheckListBox2.Height := ScaleY(97);
+ CheckListBox2.BorderStyle := bsNone;
+ CheckListBox2.ParentColor := True;
+ CheckListBox2.MinItemHeight := WizardForm.TasksList.MinItemHeight;
+ CheckListBox2.ShowLines := False;
+ CheckListBox2.WantTabs := True;
+ CheckListBox2.Parent := Page.Surface;
+ CheckListBox2.AddGroup('Installation Type:', '', 0, nil);
+ CheckListBox2.AddRadioButton('All Users', '', 0, InstallAllUsers, Enabled, nil);
+ CheckListBox2.AddRadioButton('Current User Only', '', 0, not InstallAllUsers, True, nil);
+end;
+
+procedure CurPageChanged(CurPageID: Integer);
+begin
+ if CurPageID = wpSelectDir then
+ begin
+ WizardForm.DirEdit.Text := MyAppDir();
+ end;
+ begin
+ #ifdef OpenCandy
+ OpenCandyCurPageChanged(CurPageID);
+ #endif
+ end;
+end;
+
+function ShouldSkipPage(PageID: Integer): Boolean;
+begin
+ Result := (PageID = InstallTypePageID) and Is9xME();
+ begin
+ #ifdef OpenCandy
+ Result := OpenCandyShouldSkipPage(PageID);
+ #endif
+ end;
+end;
+
+#ifdef OpenCandy
+function NextButtonClick(CurPageID: Integer): Boolean;
+begin
+ Result := OpenCandyNextButtonClick(CurPageID);
+end;
+#endif
+
+function BackButtonClick(CurPageID: Integer): Boolean;
+begin
+ Result := true; // Allow action by default
+
+ #ifdef OpenCandy
+ OpenCandyBackButtonClick(CurPageID);
+ #endif
+end;
+
+procedure DeinitializeSetup();
+begin
+ #ifdef OpenCandy
+ OpenCandyDeinitializeSetup();
+ #endif
+end;
+
+procedure CurStepChanged(CurStep: TSetupStep);
+begin
+ #ifdef OpenCandy
+ OpenCandyCurStepChanged(CurStep);
+ #endif
+end;
+
+function Lang2Gettext(): String;
+var
+ lang, lc: String;
+begin
+ lang := ActiveLanguage();
+
+ if lang = 'bra' then
+ lc := 'pt_br'
+ else
+ if lang = 'cat' then
+ lc := 'ca'
+ else
+ if lang = 'cze' then
+ lc := 'cs'
+ else
+ if lang = 'dan' then
+ lc := 'da'
+ else
+ if lang = 'dut' then
+ lc := 'nl'
+ else
+ if lang = 'fre' then
+ lc := 'fr'
+ else
+ if lang = 'ger' then
+ lc := 'de'
+ else
+ if lang = 'hun' then
+ lc := 'hu'
+ else
+ if lang = 'ita' then
+ lc := 'it'
+ else
+ if lang = 'nor' then
+ lc := 'nn'
+ else
+ if lang = 'pol' then
+ lc := 'pl'
+ else
+ if lang = 'por' then
+ lc := 'pt'
+ else
+ if lang = 'rus' then
+ lc := 'ru'
+ else
+ if lang = 'slo' then
+ lc := 'sk'
+ else
+ if lang = 'chs' then
+ lc := 'zh_cn'
+ else
+ if lang = 'esp' then
+ lc := 'es'
+ else
+ if lang = 'gal' then
+ lc := 'gl'
+ else
+ if lang = 'cht' then
+ lc := 'zh_tw'
+ else
+ lc := 'en';
+ Result := lc
+end;
+
+procedure InitializeWizard();
+#ifdef OpenCandy
+Var OCstrInstallerLanguage: String;
+#endif
+begin
+ begin
+ CreateTheWizardPages;
+ end
+#ifdef OpenCandy
+ OCstrInstallerLanguage := Lang2Gettext();
+ OpenCandyAsyncInit('{#OC_STR_MY_PRODUCT_NAME}', '{#OC_STR_KEY}', '{#OC_STR_SECRET}', OCtszInstallerLanguage, {#OC_INIT_MODE_NORMAL});
+ #endif
+end;
+
+function MyReadme(Default: String): String;
+var
+ lang, readme: String;
+begin
+ lang := Lang2Gettext();
+
+ if lang = 'nl' then
+ readme := 'nl\html\README.html'
+ else
+ if lang = 'fr' then
+ readme := 'fr\html\README1.html'
+ else
+ if lang = 'it' then
+ readme := 'it\html\README.html'
+ else
+ if lang = 'es' then
+ readme := 'es\html\LEEME.html'
+ else
+ if lang = 'gl' then
+ readme := 'gl\html\README.html'
+ else
+ if lang = 'zh_tw' then
+ readme := 'zh_tw\html\README.html'
+ else
+ readme := 'html\README.html';
+
+ Result := 'docs\'+readme
+end;
+
+function MyLicence(Default: String): String;
+var
+ lang, licence: String;
+begin
+ lang := Lang2Gettext();
+
+ if lang = 'pt_br' then
+ licence := 'pt_br\COPYING_pt_BR.txt'
+ else
+ if lang = 'ca' then
+ licence := 'ca\COPYING.txt'
+ else
+ if lang = 'cs' then
+ licence := 'cs\COPYING.txt'
+ else
+ if lang = 'da' then
+ licence := 'da\COPYING.txt'
+ else
+ if lang = 'nl' then
+ licence := 'nl\COPYING_nl.txt'
+ else
+ if lang = 'fr' then
+ licence := 'fr\COPIER.txt'
+ else
+ if lang = 'de' then
+ licence := 'de\KOPIE.txt'
+ else
+ if lang = 'it' then
+ licence := 'it\COPIATURA.txt'
+ else
+ if lang = 'pl' then
+ licence := 'pl\LICENCJA-GNU.txt'
+ else
+ if lang = 'es' then
+ licence := 'es\COPIADO.txt'
+ else
+ licence := 'COPYING.txt';
+
+ Result := 'docs\'+licence
+end;
+
+function MyPublisherURL(Default: String): String;
+var
+ lang: String;
+begin
+ lang := Lang2Gettext();
+
+ if lang = 'chs' then
+ lang := 'zh-cn'
+ else
+ if lang = 'cht' then
+ lang := 'zh-tw';
+
+ Result := 'http://www.tuxpaint.org/?lang='+lang
+end;
+
+#expr SaveToFile(AddBackslash(SourcePath) + 'Preprocessed.iss')
+