/src/gui/C4StartupMainDlg.cpp

https://bitbucket.org/randrian/openclonk2 · C++ · 469 lines · 327 code · 40 blank · 102 comment · 49 complexity · 7d497d8c080f583b6e48e08848b888c3 MD5 · raw file

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