/src/gui/C4StartupMainDlg.cpp
C++ | 469 lines | 327 code | 40 blank | 102 comment | 49 complexity | 7d497d8c080f583b6e48e08848b888c3 MD5 | raw file
Possible License(s): WTFPL, 0BSD, LGPL-2.1, CC-BY-3.0
1/*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 2005-2007 Sven Eberhardt
5 * Copyright (c) 2005-2008 Matthes Bender
6 * Copyright (c) 2006 G?nther Brammer
7 * Copyright (c) 2009 Nicolas Hake
8 * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de
9 *
10 * Portions might be copyrighted by other authors who have contributed
11 * to OpenClonk.
12 *
13 * Permission to use, copy, modify, and/or distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
16 * See isc_license.txt for full license and disclaimer.
17 *
18 * "Clonk" is a registered trademark of Matthes Bender.
19 * See clonk_trademark_license.txt for full license.
20 */
21// Startup screen for non-parameterized engine start (stub)
22
23#include <C4Include.h>
24#include <C4StartupMainDlg.h>
25#include <C4UpdateDlg.h>
26#include <C4Version.h>
27
28#ifndef BIG_C4INCLUDE
29#include <C4StartupNetDlg.h>
30#include <C4StartupScenSelDlg.h>
31#include <C4StartupOptionsDlg.h>
32#include <C4StartupAboutDlg.h>
33#include <C4StartupPlrSelDlg.h>
34#include <C4Startup.h>
35#include <C4Game.h>
36#include <C4Log.h>
37#include <C4Language.h>
38#include <C4GraphicsResource.h>
39#endif
40
41
42C4StartupMainDlg::C4StartupMainDlg() : C4StartupDlg(NULL) // create w/o title; it is drawn in custom draw proc
43 {
44 // ctor
45 fFirstShown = true;
46 // screen calculations
47 int iButtonPadding = 2;
48 int iButtonHeight = C4GUI_BigButtonHgt;
49 C4GUI::ComponentAligner caMain(rcBounds, 0,0,true);
50 C4GUI::ComponentAligner caRightPanel(caMain.GetFromLeft(rcBounds.Wdt*2/5), rcBounds.Wdt/26,40+rcBounds.Hgt/8);
51 //C4GUI::ComponentAligner caButtons(caRightPanel.GetCentered(caRightPanel.GetWidth(), (iButtonHeight+iButtonPadding) * iButtonCount - iButtonPadding), 0, iButtonPadding);
52 C4GUI::ComponentAligner caButtons(caRightPanel.GetAll(), 0, iButtonPadding);
53 // main menu buttons
54 C4GUI::CallbackButton<C4StartupMainDlg> *btn;
55 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_LOCALGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnStartBtn));
56 btn->SetToolTip(LoadResStr("IDS_DLGTIP_STARTGAME"));
57 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
58 pStartButton = btn;
59 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_NETWORKGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnNetJoinBtn));
60 btn->SetToolTip(LoadResStr("IDS_DLGTIP_NETWORKGAME"));
61 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
62 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_PLAYERSELECTION"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnPlayerSelectionBtn));
63 btn->SetToolTip(LoadResStr("IDS_DLGTIP_PLAYERSELECTION"));
64 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
65 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_OPTIONS"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnOptionsBtn));
66 btn->SetToolTip(LoadResStr("IDS_DLGTIP_OPTIONS"));
67 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
68 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_ABOUT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnAboutBtn));
69 btn->SetToolTip(LoadResStr("IDS_DLGTIP_ABOUT"));
70 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
71 AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_EXIT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnExitBtn));
72 btn->SetToolTip(LoadResStr("IDS_DLGTIP_EXIT"));
73 btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
74 // list of selected players
75 AddElement(pParticipantsLbl = new C4GUI::Label("test", GetClientRect().Wdt*39/40, GetClientRect().Hgt*9/10, ARight, 0xffffffff, &C4GUI::GetRes()->TitleFont, false));
76 pParticipantsLbl->SetToolTip(LoadResStr("IDS_DLGTIP_SELECTEDPLAYERS"));
77 // player selection shortcut - to be made optional
78 UpdateParticipants();
79 pParticipantsLbl->SetContextHandler(new C4GUI::CBContextHandler<C4StartupMainDlg>(this, &C4StartupMainDlg::OnPlayerSelContext));
80 /*new C4GUI::ContextButton(pParticipantsLbl, true, 0,0);*/
81 // key bindings
82 C4CustomKey::CodeList keys;
83 keys.push_back(C4KeyCodeEx(K_DOWN)); keys.push_back(C4KeyCodeEx(K_RIGHT));
84 if (Config.Controls.GamepadGuiControl)
85 {
86 keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Down))); // right will be done by Dialog already
87 }
88 pKeyDown = new C4KeyBinding(keys, "StartupMainCtrlNext", KEYSCOPE_Gui,
89 new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, false, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride);
90 keys.clear(); keys.push_back(C4KeyCodeEx(K_UP)); keys.push_back(C4KeyCodeEx(K_LEFT));
91 if (Config.Controls.GamepadGuiControl)
92 {
93 keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Up))); // left will be done by Dialog already
94 }
95 pKeyUp = new C4KeyBinding(keys, "StartupMainCtrlPrev", KEYSCOPE_Gui,
96 new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, true, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride);
97 keys.clear(); keys.push_back(C4KeyCodeEx(K_RETURN));
98 pKeyEnter = new C4KeyBinding(keys, "StartupMainOK", KEYSCOPE_Gui,
99 new C4GUI::DlgKeyCB<C4StartupMainDlg>(*this, &C4StartupMainDlg::KeyEnterDown, &C4StartupMainDlg::KeyEnterUp), C4CustomKey::PRIO_CtrlOverride);
100 keys.clear(); keys.push_back(C4KeyCodeEx(K_F6));
101 pKeyEditor = new C4KeyBinding(keys, "StartupMainEditor", KEYSCOPE_Gui,
102 new C4GUI::DlgKeyCB<C4StartupMainDlg>(*this, &C4StartupMainDlg::SwitchToEditor, false), C4CustomKey::PRIO_CtrlOverride);
103 }
104
105C4StartupMainDlg::~C4StartupMainDlg()
106 {
107 // dtor
108 delete pKeyEnter;
109 delete pKeyUp;
110 delete pKeyDown;
111 delete pKeyEditor;
112 }
113
114void C4StartupMainDlg::DrawElement(C4TargetFacet &cgo)
115 {
116 // inherited
117 typedef C4GUI::FullscreenDialog Base;
118 Base::DrawElement(cgo);
119 // draw logo
120 C4Facet &fctLogo = ::GraphicsResource.fctLogo;
121 float fLogoZoom = 1.0f;
122 fctLogo.DrawX(cgo.Surface, rcBounds.Wdt *1/21, rcBounds.Hgt/14 - 5, int32_t(fLogoZoom*fctLogo.Wdt), int32_t(fLogoZoom*fctLogo.Hgt));
123 // draw version info
124 StdStrBuf sVer;
125 sVer.Format(LoadResStr("IDS_DLG_VERSION"), C4VERSION);
126 if (!Config.Registered())
127 { sVer += " <c ff0000>["; sVer += LoadResStr("IDS_CTL_UNREGISTERED"); sVer += "]</c>"; }
128 lpDDraw->TextOut(sVer.getData(), C4GUI::GetRes()->TextFont, 1.0f, cgo.Surface, rcBounds.Wdt*1/40, rcBounds.Hgt/12 + int32_t(fLogoZoom*fctLogo.Hgt) - 10, 0xffffffff, ALeft, true);
129 }
130
131C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContext(C4GUI::Element *pBtn, int32_t iX, int32_t iY)
132 {
133 // preliminary player selection via simple context menu
134 C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu();
135 pCtx->AddItem("Add", "Add participant", C4GUI::Ico_None, NULL, new C4GUI::CBContextHandler<C4StartupMainDlg>(this, &C4StartupMainDlg::OnPlayerSelContextAdd));
136 pCtx->AddItem("Remove", "Remove participant", C4GUI::Ico_None, NULL, new C4GUI::CBContextHandler<C4StartupMainDlg>(this, &C4StartupMainDlg::OnPlayerSelContextRemove));
137 return pCtx;
138 }
139
140C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextAdd(C4GUI::Element *pBtn, int32_t iX, int32_t iY)
141 {
142 C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu();
143 const char *szFn;
144 StdStrBuf sSearchPath(Config.General.UserDataPath);
145// sSearchPath.Format("%s%s", (const char *) Config.General.ExePath, (const char *) Config.General.PlayerPath);
146 for (DirectoryIterator i(sSearchPath.getData()); szFn=*i; i++)
147 {
148 szFn = Config.AtRelativePath(szFn);
149 if (*GetFilename(szFn) == '.') continue;
150 if (!WildcardMatch(C4CFN_PlayerFiles, GetFilename(szFn))) continue;
151 if (!SIsModule(Config.General.Participants, szFn, NULL, false))
152 pCtx->AddItem(C4Language::IconvClonk(GetFilenameOnly(szFn)).getData(), "Let this player join in next game", C4GUI::Ico_Player,
153 new C4GUI::CBMenuHandlerEx<C4StartupMainDlg, StdCopyStrBuf>(this, &C4StartupMainDlg::OnPlayerSelContextAddPlr, StdCopyStrBuf(szFn)), NULL);
154 }
155 return pCtx;
156 }
157
158C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextRemove(C4GUI::Element *pBtn, int32_t iX, int32_t iY)
159 {
160 C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu();
161 char szPlayer[1024+1];
162 for (int i = 0; SCopySegment(Config.General.Participants, i, szPlayer, ';', 1024, true); i++)
163 if (*szPlayer)
164 pCtx->AddItem(GetFilenameOnly(szPlayer), "Remove this player from participation list", C4GUI::Ico_Player, new C4GUI::CBMenuHandlerEx<C4StartupMainDlg, int>(this, &C4StartupMainDlg::OnPlayerSelContextRemovePlr, i), NULL);
165 return pCtx;
166 }
167
168void C4StartupMainDlg::OnPlayerSelContextAddPlr(C4GUI::Element *pTarget, const StdCopyStrBuf &rsFilename)
169 {
170 SAddModule(Config.General.Participants, rsFilename.getData());
171 UpdateParticipants();
172 }
173
174void C4StartupMainDlg::OnPlayerSelContextRemovePlr(C4GUI::Element *pTarget, const int &iIndex)
175 {
176 char szPlayer[1024+1];
177 if (SCopySegment(Config.General.Participants, iIndex, szPlayer, ';', 1024, true))
178 SRemoveModule(Config.General.Participants, szPlayer, false);
179 UpdateParticipants();
180 }
181
182void C4StartupMainDlg::UpdateParticipants()
183 {
184 // First validate all participants (files must exist)
185 std::string strPlayers(Config.General.Participants);
186 std::string strPlayer;
187 strPlayer.reserve(1025);
188 *Config.General.Participants=0;
189 for (int i = 0; SCopySegment(strPlayers.c_str(), i, &strPlayer[0], ';', 1024, true); i++)
190 {
191 const char *szPlayer = strPlayer.c_str();
192 std::string strPlayerFile(Config.General.UserDataPath);
193 strPlayerFile.append(szPlayer);
194 if (!szPlayer || !*szPlayer) continue;
195 if (!FileExists(strPlayerFile.c_str())) continue;
196 if (!SEqualNoCase(GetExtension(szPlayer), "c4p")) continue; // additional sanity check to clear strange exe-path-only entries in player list?
197 SAddModule(Config.General.Participants, szPlayer);
198 }
199 // Draw selected players - we are currently displaying the players stored in Config.General.Participants.
200 // Existence of the player files is not validated and player filenames are displayed directly
201 // (names are not loaded from the player core).
202 strPlayers = LoadResStr("IDS_DESC_PLRS");
203 if (!Config.General.Participants[0])
204 strPlayers.append(LoadResStr("IDS_DLG_NOPLAYERSSELECTED"));
205 else
206 for (int i = 0; SCopySegment(Config.General.Participants, i, &strPlayer[0], ';', 1024, true); i++)
207 {
208 if (i > 0) strPlayers.append(", ");
209 strPlayers.append(C4Language::IconvClonk(GetFilenameOnly(strPlayer.c_str())).getData());
210 }
211 pParticipantsLbl->SetText(strPlayers.c_str());
212 }
213
214void C4StartupMainDlg::OnClosed(bool fOK)
215 {
216 // if dlg got aborted (by user), quit startup
217 // if it got closed with OK, the user pressed one of the buttons and dialog switching has been done already
218 if (!fOK) C4Startup::Get()->Exit();
219 }
220
221void C4StartupMainDlg::OnStartBtn(C4GUI::Control *btn)
222 {
223 // no regular game start if no players were selected
224 /*if (!*Config.General.Participants)
225 {
226 StdStrBuf buf(LoadResStrNoAmp("IDS_DLG_STARTGAME"), true);
227 GetScreen()->ShowMessageModal(LoadResStr("IDS_MSG_NOPLAYERSELECTED"), buf.getData(), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Notify);
228 // let's go to the player selection dlg then instead
229 OnPlayerSelectionBtn(NULL);
230 return;
231 }*/
232 // advance to scenario selection screen
233 C4Startup::Get()->SwitchDialog(C4Startup::SDID_ScenSel);
234 }
235
236void C4StartupMainDlg::OnPlayerSelectionBtn(C4GUI::Control *btn)
237 {
238 // advance to player selection screen
239 C4Startup::Get()->SwitchDialog(C4Startup::SDID_PlrSel);
240 }
241
242void C4StartupMainDlg::OnNetJoinBtn(C4GUI::Control *btn)
243 {
244 // simple net join dlg
245 //GetScreen()->ShowDialog(new C4GUI::InputDialog("Enter host IP", "Direct join", C4GUI::Ico_Host, new C4GUI::InputCallback<C4StartupMainDlg>(this, &C4StartupMainDlg::OnNetJoin)), false);
246 // advanced net join and host dlg!
247 C4Startup::Get()->SwitchDialog(C4Startup::SDID_NetJoin);
248 }
249
250void C4StartupMainDlg::OnNetJoin(const StdStrBuf &rsHostAddress)
251 {
252 // no IP given: No join
253 if (!rsHostAddress || !*rsHostAddress.getData()) return;
254 // set default startup parameters
255 *Game.ScenarioFilename=0;
256 SCopy("Objects.c4d", Game.DefinitionFilenames);
257 Game.NetworkActive = true;
258 Game.fLobby = true;
259 Game.fObserve = false;
260 SCopy(rsHostAddress.getData(), Game.DirectJoinAddress, sizeof(Game.DirectJoinAddress)-1);
261 // start with this set!
262 C4Startup::Get()->Start();
263 }
264
265void C4StartupMainDlg::OnOptionsBtn(C4GUI::Control *btn)
266 {
267 // advance to options screen
268 C4Startup::Get()->SwitchDialog(C4Startup::SDID_Options);
269 }
270
271void C4StartupMainDlg::OnAboutBtn(C4GUI::Control *btn)
272 {
273 // advance to about screen
274 C4Startup::Get()->SwitchDialog(C4Startup::SDID_About);
275 }
276
277void C4StartupMainDlg::OnExitBtn(C4GUI::Control *btn)
278 {
279 // callback: exit button pressed
280 C4Startup::Get()->Exit();
281 }
282
283void C4StartupMainDlg::OnTODO(C4GUI::Control *btn)
284 {
285 GetScreen()->ShowMessage("not yet implemented", "2do", C4GUI::Ico_Error);
286 }
287
288bool C4StartupMainDlg::KeyEnterDown()
289 {
290 // just execute selected button: Re-Send as space
291 return Game.DoKeyboardInput(K_SPACE, KEYEV_Down, false, false, false, false, this);
292 }
293
294bool C4StartupMainDlg::KeyEnterUp()
295 {
296 // just execute selected button: Re-Send as space
297 return Game.DoKeyboardInput(K_SPACE, KEYEV_Up, false, false, false, false, this);
298 }
299
300void C4StartupMainDlg::OnShown()
301 {
302
303 // New valid registration key found (in working directory or key path)
304 if (Config.Registered() && !Config.Security.WasRegistered)
305 HandleIncomingKeyfile(Config.GetKeyFilename());
306 // Incoming key file from command line
307 else if (Application.IncomingKeyfile)
308 HandleIncomingKeyfile(Application.IncomingKeyfile.getData());
309 // An invalid key file was found: handle it to show warning message
310 else if (!Config.Registered() && *Config.GetInvalidKeyFilename())
311 HandleIncomingKeyfile(Config.GetInvalidKeyFilename());
312 // Clear incoming key info
313 Application.IncomingKeyfile.Clear();
314 // Update registration status
315 Config.Security.WasRegistered = Config.Registered();
316
317 // Incoming update
318 if (Application.IncomingUpdate)
319 {
320 C4UpdateDlg::ApplyUpdate(Application.IncomingUpdate.getData(), false, GetScreen());
321 Application.IncomingUpdate.Clear();
322 }
323 // Manual update by command line or url
324 if (Application.CheckForUpdates)
325 {
326 C4UpdateDlg::CheckForUpdates(GetScreen(), false);
327 Application.CheckForUpdates = false;
328 }
329 // Automatic update
330 else
331 {
332 if (Config.Network.AutomaticUpdate)
333 C4UpdateDlg::CheckForUpdates(GetScreen(), true);
334 }
335
336 // first start evaluation
337 if (Config.General.FirstStart)
338 {
339 Config.General.FirstStart = false;
340 }
341 // first thing that's needed is a new player, if there's none - independent of first start
342 bool fHasPlayer = false;
343 StdStrBuf sSearchPath(Config.General.UserDataPath);
344 const char *szFn;
345// sSearchPath.Format("%s%s", (const char *) Config.General.ExePath, (const char *) Config.General.PlayerPath);
346 for (DirectoryIterator i(sSearchPath.getData()); szFn=*i; i++)
347 {
348 szFn = Config.AtRelativePath(szFn);
349 if (*GetFilename(szFn) == '.') continue; // ignore ".", ".." and private files (".*")
350 if (!WildcardMatch(C4CFN_PlayerFiles, GetFilename(szFn))) continue;
351 fHasPlayer = true;
352 break;
353 }
354 if (!fHasPlayer)
355 {
356 // no player created yet: Create one
357 C4GUI::Dialog *pDlg;
358 GetScreen()->ShowModalDlg(pDlg=new C4StartupPlrPropertiesDlg(NULL, NULL), true);
359 }
360 // make sure participants are updated after switching back from player selection
361 UpdateParticipants();
362
363 // First show
364 if (fFirstShown)
365 {
366 // Activate the application (trying to prevent flickering half-focus in win32...)
367 Application.Activate();
368 // Set the focus to the start button (we might still not have the focus after the update-check sometimes... :/)
369 SetFocus(pStartButton, false);
370 }
371 fFirstShown = false;
372 }
373
374bool C4StartupMainDlg::SwitchToEditor()
375{
376
377#ifdef _WIN32
378 // No editor executable available
379 if (!FileExists(Config.AtExePath(C4CFN_Editor))) return false;
380 // Flag editor launch
381 Application.launchEditor = true;
382 // Quit
383 C4Startup::Get()->Exit();
384#endif
385
386 return true;
387}
388
389void C4StartupMainDlg::HandleIncomingKeyfile(const char *strIncomingKey)
390{
391 static bool fWarnedInvalidKeyfile = false;
392
393 // Copy filename parameter to keep it valid
394 StdCopyStrBuf strKeyFilename; strKeyFilename = strIncomingKey;
395
396 // Key file doesn't even exist? Do nothing.
397 if (!FileExists(strKeyFilename.getData())) return;
398
399 // Try loading registration from the incoming keyfile to verify it
400 Config.ClearRegistrationError();
401 if (!Config.LoadRegistration(strKeyFilename.getData()))
402 {
403 // Invalid keyfile: show message (but only once)
404 if (!fWarnedInvalidKeyfile)
405 {
406 StdStrBuf strMessage; strMessage.Format(LoadResStr("IDS_MSG_INVALIDKEY"), Config.GetRegistrationError());
407 GetScreen()->ShowMessageModal(strMessage.getData(), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
408 }
409 fWarnedInvalidKeyfile = true;
410 // Try to reload any existing registration
411 Config.LoadRegistration();
412 // Bail out
413 return;
414 }
415
416 // See where the key is coming from
417 char strIncomingPath[_MAX_PATH + 1];
418 GetParentPath(strKeyFilename.getData(), strIncomingPath);
419 AppendBackslash(strIncomingPath);
420
421 // The key is already in the key path: that's how we like it
422 if (SEqualNoCase(strIncomingPath, Config.GetKeyPath()))
423 {
424 // Just say thank you
425 GetScreen()->ShowMessageModal(LoadResStr("IDS_CTL_REGISTERED"), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Notify);
426 return;
427 }
428
429 // The key is currently in the work dir (ExePath)
430 if (SEqualNoCase(strIncomingPath, Config.General.ExePath))
431 {
432 // Ask whether to move it to the key path (preferred)
433 StdStrBuf strMessage; strMessage.Format("%s||%s", LoadResStr("IDS_CTL_REGISTERED"), LoadResStr("IDS_MSG_MOVEKEY"));
434 if (GetScreen()->ShowMessageModal(strMessage.getData(), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnYesNo, C4GUI::Ico_Confirm))
435 {
436 // Create key path if it doesn't already exist
437 CreatePath(Config.GetKeyPath());
438 // Move key into key path
439 StdStrBuf strTarget; strTarget.Format("%s%s", Config.GetKeyPath(), GetFilename(strKeyFilename.getData()));
440 if (!MoveItem(strKeyFilename.getData(), strTarget.getData()))
441 GetScreen()->ShowMessageModal(LoadResStr("IDS_FAIL_MOVE"), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
442 // Update registration
443 Config.LoadRegistration();
444 }
445 return;
446 }
447
448 // The key is coming from the outside
449 else
450 {
451 // Say thank you
452 GetScreen()->ShowMessageModal(LoadResStr("IDS_CTL_REGISTERED"), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Notify);
453 // Create key path if it doesn't already exist
454 CreatePath(Config.GetKeyPath());
455 // Now try to copy it into the key path (preferred)
456 StdStrBuf strTarget; strTarget.Format("%s%s", Config.GetKeyPath(), GetFilename(strKeyFilename.getData()));
457 if (!CopyItem(strKeyFilename.getData(), strTarget.getData()))
458 {
459 // Failed for some reason, try copy it into the work dir instead (emergency backup)
460 strTarget.Format("%s%s", Config.General.ExePath, GetFilename(strKeyFilename.getData()));
461 if (!CopyItem(strKeyFilename.getData(), strTarget.getData()))
462 GetScreen()->ShowMessageModal(LoadResStr("IDS_FAIL_COPY"), LoadResStr("IDS_DLG_REGISTRATION"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
463 }
464 // Update registration
465 Config.LoadRegistration();
466 return;
467 }
468
469}