source: AE/Installer/trunk/source/aeinstallerapp.cpp @ 516

Last change on this file since 516 was 516, checked in by iritscen, 10 years ago

Removed TODO lines for things we've done; small fix to package update msg text.

File size: 11.1 KB
Line 
1/***************************************************************************\
2| Project: AE Installer                                                                                                         |
3| By: Gumby & Iritscen                                                                                                          |
4| File: AEInstallerApp.cpp                                                                                                      |
5| Function: Sets up the main application window.                                                        |
6| Created: 07/05/2009 17:23:39                                                                                          |
7\***************************************************************************/
8
9#include "boost/filesystem.hpp"
10#include "boost/lexical_cast.hpp" // int -> string
11#include "boost/thread.hpp"
12#include "boost/thread/mutex.hpp"
13#include <fstream>
14#include <string>
15#include "installer.h"
16#include "aeinstallerapp.h"
17
18////@begin includes
19////@end includes
20
21extern int updateStatus;
22extern bool installerJustUpdated;
23Install_info_cfg currentAE, updateAE;
24MainWindow* TheWindow;
25
26////@begin XPM images
27////@end XPM images
28
29
30/*
31 * Application instance implementation
32 */
33
34////@begin implement app
35IMPLEMENT_APP( AEInstallerApp )
36////@end implement app
37
38
39/*
40 * AEInstallerApp type definition
41 */
42
43IMPLEMENT_CLASS( AEInstallerApp, wxApp )
44
45
46/*
47 * AEInstallerApp event table definition
48 */
49
50BEGIN_EVENT_TABLE( AEInstallerApp, wxApp )
51
52////@begin AEInstallerApp event table entries
53////@end AEInstallerApp event table entries
54
55END_EVENT_TABLE()
56
57
58/*
59 * Constructor for AEInstallerApp
60 */
61
62AEInstallerApp::AEInstallerApp()
63{
64    Init();
65}
66
67
68/*
69 * Member initialisation
70 */
71
72void AEInstallerApp::Init()
73{
74        ////@begin AEInstallerApp member initialisation
75        ////@end AEInstallerApp member initialisation
76}
77
78/*
79 * Initialisation for AEInstallerApp
80 */
81
82/* The OnInit() routine is used to check whether the Installer has the software *\
83|  it needs to install mods, whether there is an available update, and whether   |
84\* the user has globalized yet, to allow mods to be installed.                                  */
85bool AEInstallerApp::OnInit()
86{   
87        ////@begin AEInstallerApp initialisation
88        // Remove the comment markers above and below this block
89        // to make permanent changes to the code.
90#if wxUSE_XPM
91        wxImage::AddHandler(new wxXPMHandler);
92#endif
93#if wxUSE_LIBPNG
94        wxImage::AddHandler(new wxPNGHandler);
95#endif
96#if wxUSE_LIBJPEG
97        wxImage::AddHandler(new wxJPEGHandler);
98#endif
99#if wxUSE_GIF
100        wxImage::AddHandler(new wxGIFHandler);
101#endif
102        MainWindow* mainWindow = new MainWindow( NULL );
103        mainWindow->Show(true);
104        ////@end AEInstallerApp initialisation
105        TheWindow = mainWindow;
106       
107        // Anything after this is done after the window appears...
108       
109        if (!CheckForRequiredSoftware())
110        {
111                TheWindow->Close(); // CheckForRequiredSoftware() will have notified the user of what they are missing, so we just quit now
112                return true;
113        }
114       
115        if (updateStatus) // updateStatus was set when MainWindow::CreateControls() was called during initialization of the window
116        {
117                string updateMsg = "An update for the Anniversary Edition is available.\n"
118                                                   "Do you wish to update to Edition version " + updateAE.AEVersion + "?\n"
119                                                   "(Current version is " + currentAE.AEVersion + ")\n"; // ...so we tack the rest on in a second command
120                wxMessageDialog* updateNotification;
121               
122                switch (updateStatus) // for the meanings of these return values, see the comments preceding installer.cpp's GetUpdateStatus()
123                {
124                        case UPDATE_LOG_READ_ERR:
125                        {
126                                if (exists("Update.log")) remove("Update.log");
127                                ofstream logfile("Update.log");
128                                logfile << "Error: A necessary .cfg file could not be read.";
129                        } // brackets are needed due to the initialization of the ofstream; silly C!
130                                break;
131                        case UPDATE_MNTH_REQD_ERR:
132                                updateMsg = "There is a patch in the updates/ folder, but it patches the\n";
133                                updateMsg = updateMsg + updateAE.AEVersion.substr(0, updateAE.AEVersion.length() - 1) + " release; it cannot update this version of the Edition.";
134                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition);
135                                updateNotification->ShowModal();
136                                break;
137                        case UPDATE_SIMP_AVAIL: // there's an update with no globalization or Installer strings attached
138                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
139                                if (updateNotification->ShowModal() == wxID_YES)
140                                        ProcessAEUpdate(&currentAE, &updateAE, &installerJustUpdated);
141                                break;
142                        case UPDATE_PKG_AVAIL: // there's an update with no globalization or Installer strings attached
143                                updateMsg = (string)"One or individual package updates for the Anniversary Edition is available.\n\n" +
144                                        (string)"Please note that the AE team assumes no responsibility for the content of third party mods " +
145                                        (string)"nor effects that a third party mod may have on your install.\n\n" +
146                                        (string)"Do you wish to install these update(s)?";
147                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
148                                if (updateNotification->ShowModal() == wxID_YES)
149                                        ProcessPackageUpdates("../updates", "./packages");
150                                break;
151                        case UPDATE_GLOB_AVAIL: // there's an update with globalization strings attached
152                                updateMsg = updateMsg + "**Note that the update requires you to reglobalize, which will take 5-20 minutes.**\n" +
153                                                                                "Before clicking Yes, MAKE SURE you have backed up any mods not installed through\n " +
154                                                                                "the Installer, such as plug-ins or direct OniSplit imports.";
155                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
156                                if (updateNotification->ShowModal() == wxID_YES)
157                                        ProcessAEUpdate(&currentAE, &updateAE, &installerJustUpdated);
158                                break;
159                        case UPDATE_INST_AVAIL: // there's an update with Installer strings attached (globalization is irrelevant while the Installer is not yet updated)
160                                updateMsg = updateMsg + "**Note that the update requires the Installer to update itself.**\n" +
161                                                                                "If you click Yes, the Installer will quit and re-launch itself, then\n" +
162                                                                                "you will be prompted to begin the installation.";
163                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
164                                if (updateNotification->ShowModal() == wxID_YES)
165                                {
166                                        if (ProcessInstallerUpdate(&currentAE, &updateAE)) // there's an intentional logic gap here: if the user clicks "Yes"...
167                                        {                                                                                                  // ...and then ProcessInstallerUpdate has an error and returns false, the logic gap results...
168                                                TheWindow->Close();                                                        // ...in the code continuing to execute down through case UPDATE_INST_REPL_ERR
169                                                return true;
170                                        }
171                                }
172                                else
173                                        break;
174                        case UPDATE_INST_REPL_ERR: // the Installer replacement failed, user has to do it :-(
175                                updateMsg = "The Installer replacement process failed for some reason.\n";
176                                updateMsg = updateMsg + "In order for the update to continue, go into the folder Edition/updates/" + strEUFN + "/install/ and " + 
177                                                                                "drag the Installer to Edition/install/, replacing the current Installer application, then launch the " +
178                                                                                "new version. Click Yes to quit.";
179                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
180                                if (updateNotification->ShowModal() == wxID_YES)
181                                        TheWindow->Close();
182                                return true;
183                }
184        }
185
186        CheckForGlobalization(false); // function will prompt user and initiate globalization if not done already
187       
188        return true;
189}
190
191bool CheckForRequiredSoftware(void)
192{
193#ifdef WIN32
194        // test for .NET 2.0 or higher
195        HKEY hKey;
196        if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v2.0", 0L, KEY_READ , &hKey) == ERROR_SUCCESS)
197        {
198                string dotnetMsg = "You don't have .NET 2.0 installed! .NET is a framework required by the Edition.\n";
199                dotnetMsg = dotnetMsg + "You can download it from:\n" +
200                                                                "http://gumby.oni2.net/dotnet\n" +
201                                                                "Please install .NET 2.0, then open this Installer again.\n\n" +
202                                                                "Would you like to open the download webpage?";
203                wxMessageDialog* DotNetDialogOfDeath = new wxMessageDialog(TheWindow, dotnetMsg.c_str(), "AE Installer Alert",
204                                                                                                                                 wxYES_NO | wxICON_EXCLAMATION  , wxDefaultPosition);
205                if (DotNetDialogOfDeath->ShowModal() == wxID_YES)
206                        system("start http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5");
207                RegCloseKey(hKey);
208                return false;
209        }
210#else // on Mac...
211        // test for the third-party "mono" framework, because without it, we are up a creek
212        FILE *fWhichMono = NULL;
213        char chrWhichMono[32];
214        fWhichMono = popen("which mono", "r");
215        fgets(chrWhichMono, sizeof(chrWhichMono), fWhichMono);
216        pclose(fWhichMono);
217        string strWhichMono = (string)chrWhichMono;
218        string::size_type loc = strWhichMono.find("mono", 0);
219       
220        if (loc == string::npos) // this means that "which mono" did not return a path leading to the mono binary -- abort! abort! abort!
221        {
222                string monoMsg = "You don't have 'mono' installed! 'mono' is a command-line tool required by the Edition.\n";
223                monoMsg = monoMsg + "You can download it from: http://www.go-mono.com/mono-downloads/download.html (OS X 10.4+)\n" +
224                                                        "or http://edt.oni2.net/AE/MonoFramework10.3.dmg (OS X 10.3)\n\n" +
225                                                        "Please install 'mono', then open this Installer again.";
226                wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, monoMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition);
227                MonoDialogOfDeath->ShowModal();
228                return false; // it's quittin' time, Joe
229        }
230#endif
231        return true;
232}
233
234bool CheckForGlobalization(bool justDoIt)
235{
236        if (!exists("../GameDataFolder"))
237        {
238                string globMsg = "You haven't globalized yet!\n";
239                globMsg = globMsg + "You must globalize to use the Anniversary Edition framework.\n" +
240                                                        "Would you like to globalize now? (This could take a while...)\n" +
241                                                        "(Selecting \"No\" will exit this program...)";
242                wxMessageDialog* YesNoDialog = new wxMessageDialog(TheWindow, globMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
243               
244                if (YesNoDialog->ShowModal() == wxID_NO) // if the user said no...
245                {
246                        TheWindow->Close();
247                        return true;
248                }
249        }
250        else if (!justDoIt)
251                return false;
252        // Code below this point runs if user clicks "Yes" or if they are never asked but justDoIt is true
253#ifdef WIN32
254        boost::thread thrd3(globalize2);
255#else // cannot use multi-threading in Mac build
256        TheWindow->InstallButton->Disable();
257        TheWindow->ReglobalizeButton->Disable();
258        globalizeData();
259        TheWindow->InstallButton->Enable();
260        TheWindow->ReglobalizeButton->Enable();
261#endif
262       
263        return true;
264}
265
266void setStatusArea(string s)
267{
268        wxString wxs(s.c_str(), wxConvUTF8);
269       
270        TheWindow->StatusArea->SetStatusText(wxs);
271}
272
273
274/*
275 * Cleanup for AEInstallerApp
276 */
277
278int AEInstallerApp::OnExit()
279{   
280        ////@begin AEInstallerApp cleanup
281        return wxApp::OnExit();
282        ////@end AEInstallerApp cleanup
283}
284void doglobalizeData()
285{
286        globalizeData();
287#ifdef WIN32
288        while(1) Sleep(-1);
289#endif
290}
Note: See TracBrowser for help on using the repository browser.