1 |
< |
///////////////////////////////////////////////////////////////////////////// |
2 |
< |
// Name: aeinstallerapp.cpp |
3 |
< |
// Purpose: |
4 |
< |
// Author: |
5 |
< |
// Modified by: |
6 |
< |
// Created: 07/05/2009 17:23:39 |
7 |
< |
// RCS-ID: |
8 |
< |
// Copyright: |
9 |
< |
// Licence: |
10 |
< |
///////////////////////////////////////////////////////////////////////////// |
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> |
12 |
> |
#include "boost/thread/mutex.hpp" |
13 |
|
#include <fstream> |
14 |
< |
#include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations |
15 |
< |
#include "boost/lexical_cast.hpp" //int -> string |
16 |
< |
using namespace boost::filesystem; |
17 |
< |
// For compilers that support precompilation, includes "wx/wx.h". |
18 |
< |
#include "wx/wxprec.h" |
19 |
< |
|
20 |
< |
#ifdef __BORLANDC__ |
21 |
< |
#pragma hdrstop |
22 |
< |
#endif |
23 |
< |
|
24 |
< |
#ifndef WX_PRECOMP |
25 |
< |
#include "wx/wx.h" |
26 |
< |
#endif |
14 |
> |
#include <string> |
15 |
> |
#include "installer.h" |
16 |
> |
#include "aeinstallerapp.h" |
17 |
|
|
18 |
|
////@begin includes |
19 |
|
////@end includes |
20 |
|
|
21 |
< |
#include "aeinstallerapp.h" |
22 |
< |
#include <string> |
21 |
> |
Install_info_cfg currentAE, updateAE; |
22 |
> |
MainWindow* TheWindow; |
23 |
|
|
24 |
|
////@begin XPM images |
25 |
|
////@end XPM images |
77 |
|
* Initialisation for AEInstallerApp |
78 |
|
*/ |
79 |
|
|
80 |
+ |
/* The OnInit() routine is used to check whether the Installer has the software *\ |
81 |
+ |
| it needs to install mods, whether there is an available update, and whether | |
82 |
+ |
\* the user has globalized yet, to allow mods to be installed. */ |
83 |
|
bool AEInstallerApp::OnInit() |
84 |
|
{ |
85 |
|
////@begin AEInstallerApp initialisation |
86 |
|
// Remove the comment markers above and below this block |
87 |
|
// to make permanent changes to the code. |
95 |
– |
|
88 |
|
#if wxUSE_XPM |
89 |
|
wxImage::AddHandler(new wxXPMHandler); |
90 |
|
#endif |
102 |
|
////@end AEInstallerApp initialisation |
103 |
|
TheWindow = mainWindow; |
104 |
|
|
105 |
+ |
// Anything after this is done after the window appears... |
106 |
+ |
|
107 |
+ |
if (!CheckForRequiredSoftware()) |
108 |
+ |
{ |
109 |
+ |
TheWindow->Close(); // CheckForRequiredSoftware() will have notified the user of what they are missing, so we just quit now |
110 |
+ |
return true; |
111 |
+ |
} |
112 |
+ |
|
113 |
+ |
bool installerJustUpdated = false; |
114 |
+ |
int updateStatus = GetUpdateStatus(¤tAE, &updateAE, &installerJustUpdated); |
115 |
+ |
if (updateStatus) // otherwise there's no update |
116 |
+ |
{ |
117 |
+ |
string updateMsg = "An update for the Anniversary Edition is available.\n"; // for some reason we can't set the initial value while using the '+' operator... |
118 |
+ |
updateMsg = updateMsg + "Do you wish to update to Edition version " + updateAE.AEVersion + "?\n" + |
119 |
+ |
"(Current version is " + currentAE.AEVersion + ")\n"; // ...so 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(¤tAE, &updateAE, &installerJustUpdated); |
141 |
+ |
break; |
142 |
+ |
case UPDATE_GLOB_AVAIL: // there's an update with globalization strings attached |
143 |
+ |
updateMsg = updateMsg + "**Note that the update requires you to reglobalize, which will take 5-20 minutes.**\n" + |
144 |
+ |
"Before clicking Yes, MAKE SURE you have backed up any mods not installed through\n " + |
145 |
+ |
"the Installer, such as plug-ins or direct OniSplit imports."; |
146 |
+ |
updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition); |
147 |
+ |
if (updateNotification->ShowModal() == wxID_YES) |
148 |
+ |
ProcessAEUpdate(¤tAE, &updateAE, &installerJustUpdated); |
149 |
+ |
break; |
150 |
+ |
case UPDATE_INST_AVAIL: // there's an update with Installer strings attached (globalization is irrelevant while the Installer is not yet updated) |
151 |
+ |
updateMsg = updateMsg + "**Note that the update requires the Installer to update itself.**\n" + |
152 |
+ |
"If you click Yes, the Installer will quit and re-launch itself, then\n" + |
153 |
+ |
"you will be prompted to begin the installation."; |
154 |
+ |
updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition); |
155 |
+ |
updateNotification->ShowModal(); |
156 |
+ |
if (updateNotification->ShowModal() == wxID_YES) |
157 |
+ |
{ |
158 |
+ |
if (ProcessInstallerUpdate(¤tAE, &updateAE)) // there's an intentional logic gap here: if the user clicks "Yes"... |
159 |
+ |
{ // ...and then ProcessInstallerUpdate has an error and returns false, the logic gap results... |
160 |
+ |
TheWindow->Close(); // ...in the code continuing to execute down through case UPDATE_INST_REPL_ERR |
161 |
+ |
return true; |
162 |
+ |
} |
163 |
+ |
} |
164 |
+ |
else |
165 |
+ |
break; |
166 |
+ |
case UPDATE_INST_REPL_ERR: // the Installer replacement failed, user has to do it :-( |
167 |
+ |
updateMsg = "The Installer replacement process failed for some reason.\n"; |
168 |
+ |
updateMsg = updateMsg + "Please quit, go into the folder Edition/Updates/" + strEUFN + "/install/ and drag the Installer to Edition/install/, " + |
169 |
+ |
"replacing the current Installer application, then launch the new version."; |
170 |
+ |
updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition); |
171 |
+ |
updateNotification->ShowModal(); |
172 |
+ |
TheWindow->Close(); |
173 |
+ |
return true; |
174 |
+ |
} |
175 |
+ |
} |
176 |
+ |
|
177 |
+ |
CheckForGlobalization(false); // function will prompt user and initiate globalization if not done already |
178 |
+ |
|
179 |
+ |
return true; |
180 |
+ |
} |
181 |
+ |
|
182 |
+ |
bool CheckForRequiredSoftware(void) |
183 |
+ |
{ |
184 |
|
#ifdef WIN32 |
185 |
< |
HKEY hKey; |
186 |
< |
if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v2.0", 0L, KEY_READ , &hKey) == ERROR_SUCCESS) { |
187 |
< |
wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, "You don't have .NET 2.0 installed! .NET is a framework required by the Edition. You can download it from:\nhttp://gumby.oni2.net/dotnet\nPlease install .NET 2.0, then open this Installer again. \n\nWould you like to open the download webpage?", "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION , wxDefaultPosition); |
188 |
< |
if(MonoDialogOfDeath->ShowModal() == wxID_YES) { |
185 |
> |
// test for .NET 2.0 or higher |
186 |
> |
HKEY hKey; |
187 |
> |
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v2.0", 0L, KEY_READ , &hKey) == ERROR_SUCCESS) |
188 |
> |
{ |
189 |
> |
string dotnetMsg = "You don't have .NET 2.0 installed! .NET is a framework required by the Edition.\n"; |
190 |
> |
dotnetMsg = dotnetMsg + "You can download it from:\n" + |
191 |
> |
"http://gumby.oni2.net/dotnet\n" + |
192 |
> |
"Please install .NET 2.0, then open this Installer again.\n\n" + |
193 |
> |
"Would you like to open the download webpage?"; |
194 |
> |
wxMessageDialog* DotNetDialogOfDeath = new wxMessageDialog(TheWindow, dotnetMsg.c_str(), "AE Installer Alert", |
195 |
> |
wxYES_NO | wxICON_EXCLAMATION , wxDefaultPosition); |
196 |
> |
if (DotNetDialogOfDeath->ShowModal() == wxID_YES) |
197 |
|
system("start http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5"); |
119 |
– |
} |
198 |
|
RegCloseKey(hKey); |
199 |
< |
TheWindow->Close(); |
122 |
< |
} |
123 |
< |
#else |
124 |
< |
// test for the third-party mono framework, because without it, on Mac, we are up a creek |
125 |
< |
char monoCommand[300] = "which mono >> "; |
126 |
< |
strcat(monoCommand, escapePath(system_complete("mono_check.log").string()).c_str()); |
127 |
< |
system(monoCommand); |
128 |
< |
fstream file; |
129 |
< |
file.open("mono_check.log"); |
130 |
< |
string line; |
131 |
< |
int line_count = 0; |
132 |
< |
while (!file.eof()) |
133 |
< |
{ |
134 |
< |
line_count++; |
135 |
< |
getline(file, line); |
199 |
> |
return false; |
200 |
|
} |
201 |
< |
file.close(); |
202 |
< |
remove("mono_check.log"); |
201 |
> |
#else // on Mac... |
202 |
> |
// test for the third-party "mono" framework, because without it, we are up a creek |
203 |
> |
FILE *fWhichMono = NULL; |
204 |
> |
char chrWhichMono[32]; |
205 |
> |
fWhichMono = popen("which mono", "r"); |
206 |
> |
fgets(chrWhichMono, sizeof(chrWhichMono), fWhichMono); |
207 |
> |
pclose(fWhichMono); |
208 |
> |
string strWhichMono = (string)chrWhichMono; |
209 |
> |
string::size_type loc = strWhichMono.find("mono", 0); |
210 |
|
|
211 |
< |
if (line_count <= 1) // this means that "which mono" returned nothing -- abort! abort! abort! |
211 |
> |
if (loc == string::npos) // this means that "which mono" did not return a path leading to the mono binary -- abort! abort! abort! |
212 |
|
{ |
213 |
< |
wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, "You don't have 'mono' installed! 'mono' is a command-line tool required by the Edition. You can download it from:\nhttp://www.go-mono.com/mono-downloads/download.html (OS X 10.4+) or\nhttp://edt.oni2.net/AE/MonoFramework10.3.dmg (OS X 10.3)\n\nPlease install 'mono', then open this Installer again.", "AE Installer Alert", wxOK | wxICON_EXCLAMATION , wxDefaultPosition); |
213 |
> |
string monoMsg = "You don't have 'mono' installed! 'mono' is a command-line tool required by the Edition.\n"; |
214 |
> |
monoMsg = monoMsg + "You can download it from: http://www.go-mono.com/mono-downloads/download.html (OS X 10.4+)\n" + |
215 |
> |
"or http://edt.oni2.net/AE/MonoFramework10.3.dmg (OS X 10.3)\n\n" + |
216 |
> |
"Please install 'mono', then open this Installer again."; |
217 |
> |
wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, monoMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition); |
218 |
|
MonoDialogOfDeath->ShowModal(); |
219 |
< |
TheWindow->Close(); |
145 |
< |
return true; // it's quittin' time, Joe |
219 |
> |
return false; // it's quittin' time, Joe |
220 |
|
} |
221 |
|
#endif |
222 |
+ |
return true; |
223 |
+ |
} |
224 |
|
|
225 |
< |
//anything after this is done after the window appears... |
226 |
< |
|
227 |
< |
if ( !exists("../GameDataFolder") ) |
225 |
> |
bool CheckForGlobalization(bool justDoIt) |
226 |
> |
{ |
227 |
> |
if (!exists("../GameDataFolder")) |
228 |
|
{ |
229 |
< |
wxMessageDialog* YesNoDialog = new wxMessageDialog(TheWindow, "You haven't globalized yet! \nYou must globalize to use the Anniversary Edition framework. \nWould you like to globalize now? (This could take a while...)\n(Selecting \"No\" will exit this program...)", "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION , wxDefaultPosition); |
230 |
< |
|
229 |
> |
string globMsg = "You haven't globalized yet!\n"; |
230 |
> |
globMsg = globMsg + "You must globalize to use the Anniversary Edition framework.\n" + |
231 |
> |
"Would you like to globalize now? (This could take a while...)\n" + |
232 |
> |
"(Selecting \"No\" will exit this program...)"; |
233 |
> |
wxMessageDialog* YesNoDialog = new wxMessageDialog(TheWindow, globMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition); |
234 |
> |
|
235 |
|
if (YesNoDialog->ShowModal() == wxID_NO) // if the user said no... |
156 |
– |
TheWindow->Close(); |
157 |
– |
else |
236 |
|
{ |
237 |
< |
|
238 |
< |
|
161 |
< |
#ifdef WIN32 |
162 |
< |
boost::thread thrd3(globalize2); |
163 |
< |
//globalizeData(); |
164 |
< |
//boost::thread::create_thread(&globalizeData); |
165 |
< |
// boost::thread_group Tg; |
166 |
< |
// Tg.create_thread( &globalizeData(), this ); |
167 |
< |
#else |
168 |
< |
TheWindow->InstallButton->Disable(); |
169 |
< |
TheWindow->ReglobalizeButton->Disable(); |
170 |
< |
globalizeData(); |
171 |
< |
TheWindow->InstallButton->Enable(); |
172 |
< |
TheWindow->ReglobalizeButton->Enable(); |
173 |
< |
#endif |
174 |
< |
|
175 |
< |
|
237 |
> |
TheWindow->Close(); |
238 |
> |
return true; |
239 |
|
} |
240 |
|
} |
241 |
< |
|
241 |
> |
else if (!justDoIt) |
242 |
> |
return false; |
243 |
> |
// Code below this point runs if user clicks "Yes" or if they are never asked but justDoIt is true |
244 |
> |
#ifdef WIN32 |
245 |
> |
boost::thread thrd3(globalize2); |
246 |
> |
#else // cannot use multi-threading in Mac build |
247 |
> |
TheWindow->InstallButton->Disable(); |
248 |
> |
TheWindow->ReglobalizeButton->Disable(); |
249 |
> |
globalizeData(); |
250 |
> |
TheWindow->InstallButton->Enable(); |
251 |
> |
TheWindow->ReglobalizeButton->Enable(); |
252 |
> |
#endif |
253 |
> |
|
254 |
|
return true; |
255 |
|
} |
256 |
|
|
257 |
< |
|
258 |
< |
void setStatusArea( string s ) { |
257 |
> |
void setStatusArea(string s) |
258 |
> |
{ |
259 |
|
wxString wxs(s.c_str(), wxConvUTF8); |
260 |
|
|
261 |
< |
TheWindow->StatusArea->SetStatusText( wxs ); |
187 |
< |
//TheWindow->StatusArea->SetStatusText(s.c_str()); |
188 |
< |
//StatusArea->SetStatusText(_(s.c_str())); |
189 |
< |
//(*TheStatusBar)->SetStatusText(_(s.c_str())); |
190 |
< |
//AEInstallerApp:: |
191 |
< |
// TheWindow->StatusArea->SetStatusText("hi"); |
192 |
< |
//mainWindow |
193 |
< |
//itemFrame1->StatusArea->SetStatusText(_"lol"); |
194 |
< |
//MainWindow.StatusArea->SetStatusText("hi"); |
195 |
< |
// class AbstractStatusNotifier { public: virtual void NotifyStatus(const wxString &statusString) = 0; }; |
196 |
< |
//class StatusBarStatusNotifier : public AbstractStatusNotifier { wxStatusBar *statusbar; StatusBarStatusNotifier(wxStatusBar *bar) : statusbar(bar) { } ; |
197 |
< |
//void NotifyStatus(const wxString &status) { statusbar->SetStatus(status); } } |
198 |
< |
|
199 |
< |
|
200 |
< |
//MainWindow::StatusArea-> |
201 |
< |
//MainWindow::MainWindow().SetSize(MainWindow::MainWindow().GetRect().GetWidth(), MainWindow::MainWindow().GetRect().GetHeight()+1); |
202 |
< |
|
203 |
< |
//MainWindow::StatusBar->SetLabel("Importing Files..."); |
204 |
< |
//StatusBar->SetLabel(s); |
205 |
< |
//->SetLabel(s); |
206 |
< |
|
261 |
> |
TheWindow->StatusArea->SetStatusText(wxs); |
262 |
|
} |
263 |
|
|
264 |
|
|
272 |
|
return wxApp::OnExit(); |
273 |
|
////@end AEInstallerApp cleanup |
274 |
|
} |
275 |
< |
void doglobalizeData() { |
276 |
< |
//TheWindow->Disable(); |
275 |
> |
void doglobalizeData() |
276 |
> |
{ |
277 |
|
globalizeData(); |
278 |
|
#ifdef WIN32 |
279 |
|
while(1) Sleep(-1); |
280 |
|
#endif |
226 |
– |
//TheWindow->Enable(); |
227 |
– |
//setStatusArea((string)"Test1"); |
281 |
|
} |