void CreateDirectories(const Path& path) const { if (path.IsEmpty() || this->DirectoryExists(path)) { return; } auto parentPath = path.GetContainingPath(); this->CreateDirectories(parentPath); #ifdef _WIN32 if (CreateDirectory(path.ToString().c_str(), nullptr) == 0) { throw std::system_error( GetLastError(), std::system_category(), "error while trying to create path " + path.ToShortString()); } #else if (mkdir(path.ToShortString().c_str(), 0777) != 0) { throw std::system_error( errno, std::system_category(), "error while trying to create path " + path.ToShortString()); } #endif }
/** * @brief キーマップ定義を読み込みます。initInstance の処理で呼ばれます。 */ void WinCoveredCalcApp::loadKeyMappingsOnInit() { Path keymapFile; AppSettings* appSettings = GetAppSettings(); keymapFile = appSettings->GetKeymapFilePath(); if (keymapFile.IsEmpty()) { // 設定になければデフォルト // FIXME: ユーザに尋ねる? // トリック: // 1.8.x まではカスタマイズがなくて日本語 JIS キーボードしかなかった。 // デフォルト設定としては US QWERTY(標準的な 101/104 拡張キーボード)がよいが、 // 言語が日本語の場合は以前のまま日本語 JIS キーボードの方が好ましい。 // それ以外の場合に US QWERTY キーボードにする。 MBCString langCode; GetCurrentLanguageCode(langCode); if (0 == langCode.Compare(LANG_CODE_JAJP)) { keymapFile.AssignFromSlashSeparated(ALITERAL("${") VPATH_APP_KEYMAPS ALITERAL("}/JapaneseJIS.cckxw")); } else { keymapFile.AssignFromSlashSeparated(ALITERAL("${") VPATH_APP_KEYMAPS ALITERAL("}/UsQWERTY.cckxw")); } appSettings->SetKeymapFilePath(keymapFile); } Path absolutePath = ExpandVirtualPath(keymapFile); try { LoadKeyMappings(absolutePath); } catch (Exception* ex) { // キーマッピング定義が読み込めませんでした。 ExceptionMessageUtils::DoExceptionMessageBoxWithText(this, ex, NSID_EMSG_LOAD_KEYMAPPINGS, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Warning); ex->Delete(); } }
/** * @brief Returns the path of folder in which user settings is stored. * @return user settings folder path. */ const Path& WinCoveredCalcApp::getUserSettingsPath() { if (userSettingsPath.IsEmpty()) { Path path; // Application Data の下 ITEMIDLIST* pIdList; HRESULT hResult = ::SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pIdList); if(S_OK == hResult) { // 得られた ITEMIDLIST からフォルダ名を取得 TCHAR pathString[MAX_PATH]; if (::SHGetPathFromIDList(pIdList, pathString)) { path.Assign(pathString); } // システムが確保した ITEMIDLIST を解放 IMalloc* pMalloc; ::SHGetMalloc(&pMalloc); if (NULL != pMalloc) { pMalloc->Free(pIdList); pMalloc->Release(); } } if (!path.IsEmpty()) { userSettingsPath = path.Append(ALITERAL("Hironytic")).Append(ALITERAL("CoveredCalc")); } else { // Application Data が得られなかったら、アプリケーションのあるフォルダに保存 userSettingsPath = getAppFolderPath(); } } return userSettingsPath; }
// --------------------------------------------------------------------- BOOL WinCoveredCalcApp::initInstance() { bool langFileLoaded = false; if (!base::initInstance()) { return FALSE; } // コモンコントロール初期化 ::InitCommonControls(); // レイヤードウィンドウ関連の API apiLayeredWindow.Initialize(); // ウェイトカーソルを取得しておく waitCursor = ::LoadCursor(NULL, IDC_WAIT); // モニタ情報を取得しておく monitorInfo.Update(); // ベースクラス初期化 if (!init()) { return FALSE; } // コマンドラインパラメータ解析 CommandLineParam* clParam = GetCommandLineParam(); clParam->SetParameter(__argc, __targv); // 言語ファイルの読み込み if (clParam->IsLangFileSpecified()) { try { loadLangFile(clParam->GetLangFile()); langFileLoaded = true; } catch (Exception* ex) { ex->Delete(); // コマンドラインパラメータで指定された言語ファイルが読み込めなかったので無視します。 DoMessageBox(NSID_EMSG_LOAD_COMMANDLINE_LANGFILE, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Warning); } } // ウィンドウクラスの登録 WinMainWindow::RegisterClass(); //設定ファイルを準備 Path settingFile; if (clParam->IsSettingFileSpecified()) { // コマンドラインで設定ファイルが指定されていればそれを使う settingFile.Assign(clParam->GetSettingFile()); } else { // デフォルト設定ファイルを使う try { readyDefaultSettingFilePath(settingFile); } catch (Exception* ex) { ExceptionMessageUtils::DoExceptionMessageBoxWithText(this, ex, NSID_EMSG_READY_DEFAULT_SETTING_FILE, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Stop); ex->Delete(); return FALSE; } } // 設定の読み込み try { loadSettings(settingFile); } catch (Exception* ex) { ex->Delete(); return FALSE; } // 設定に保存された言語ファイルを読み込む if (!langFileLoaded) { AppSettings* appSettings = GetAppSettings(); const Path settingPath = appSettings->GetLanguageFilePath(); if (!settingPath.IsEmpty()) { Path langFileFullPath = MakeAbsoluteLangFilePath(settingPath); if (!langFileFullPath.IsEmpty()) { try { loadLangFile(langFileFullPath); langFileLoaded = true; } catch (Exception* ex) { ex->Delete(); // 設定ファイルに書かれた言語ファイルが読めません。 DoMessageBox(NSID_EMSG_LOAD_SETTING_LANGFILE, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Warning); } } } } if (!langFileLoaded) { // 設定に保存されていなければ、ユーザーに問い合わせる WinSelectLanguageDlg selectLangDlg; try { selectLangDlg.SetRelativeLangFilePath(Path(ALITERAL("enUS.cclxw"))); int dlgResult = selectLangDlg.DoModal(NULL); if (IDOK != dlgResult) { return FALSE; } } catch (Exception* ex) { ExceptionMessageUtils::DoExceptionMessageBox(this, ex); ex->Delete(); return FALSE; } Path langFilePath = selectLangDlg.GetRelativeLangFilePath(); Path langFileFullPath = MakeAbsoluteLangFilePath(langFilePath); if (!langFileFullPath.IsEmpty()) { try { loadLangFile(langFileFullPath); langFileLoaded = true; GetAppSettings()->SetLanguageFilePath(langFilePath); } catch (Exception* ex) { ex->Delete(); // 言語ファイルが読めません。 DoMessageBox(NSID_EMSG_LOAD_LANGFILE, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Warning); } } } // キー定義名 DB のロード loadKeyNameDB(); // キーマッピング読み込み loadKeyMappingsOnInit(); // カバー読み込み try { AppSettings* appSettings = GetAppSettings(); loadCoverDef(appSettings->GetBaseFolder(), appSettings->GetLastCoverDef(), appSettings->GetLastCoverNo()); } catch (Exception* ex) { ExceptionMessageUtils::DoExceptionMessageBox(this, ex); ex->Delete(); // デフォルトカバーで復活を試みる if (!restoreByDefaultCoverDef()) { // ダメでした…。 return FALSE; } } // メインウィンドウ生成 DWORD exStyle = 0; if (GetAppSettings()->IsMainWindowAlwaysOnTop()) { exStyle = WS_EX_TOPMOST; } const Point32& lastMainWindowPos = GetAppSettings()->GetLastMainWindowPos(); if (!mainWindow.CreateEx(exStyle, WinMainWindow::GetWindowClassName(), ALITERAL("CoveredCalc"), WS_SYSMENU | WS_POPUP | WS_MINIMIZEBOX, lastMainWindowPos.x, lastMainWindowPos.y, 0, 0, NULL, NULL)) { // デフォルトカバーにして再チャレンジ bool restored = false; if (restoreByDefaultCoverDef()) { if (mainWindow.CreateEx(exStyle, WinMainWindow::GetWindowClassName(), ALITERAL("CoveredCalc"), WS_SYSMENU | WS_POPUP | WS_MINIMIZEBOX, lastMainWindowPos.x, lastMainWindowPos.y, 0, 0, NULL, NULL)) { restored = true; } } if (!restored) { DoMessageBox(NSID_EMSG_CREATE_MAIN_WINDOW, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Stop); return FALSE; } } ::ShowWindow(mainWindow.m_hWnd, SW_SHOW); // カバーブラウザ生成 Path baseFolderPath = GetAppSettings()->GetBaseFolder(); if (baseFolderPath.IsEmpty()) { baseFolderPath = getAppFolderPath(); } coverBrowser.SetCoversFolderPath(baseFolderPath.Append(ALITERAL("Covers"))); if (!coverBrowser.Create(NULL)) { DoMessageBox(NSID_EMSG_CREATE_COVER_BROWSER, MessageBoxProvider::ButtonType_OK, MessageBoxProvider::AlertType_Stop); } ::ShowWindow(mainWindow.m_hWnd, SW_SHOW); if (GetAppSettings()->IsCoverBrowserVisible()) { ::ShowWindow(coverBrowser.m_hWnd, SW_SHOW); } ::SetForegroundWindow(mainWindow.m_hWnd); return TRUE; }
void InterfaceConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) { const UISettings &settings = CommonInterface::GetUISettings(); RowFormWidget::Prepare(parent, rc); AddInteger(_("Text size"), nullptr, _T("%d %%"), _T("%d"), 75, 200, 5, settings.scale); AddFile(_("Events"), _("The Input Events file defines the menu system and how XCSoar responds to " "button presses and events from external devices."), ProfileKeys::InputFile, _T("*.xci\0")); SetExpertRow(InputFile); #ifndef HAVE_NATIVE_GETTEXT WndProperty *wp; wp = AddEnum(_("Language"), _("The language options selects translations for English texts to other " "languages. Select English for a native interface or Automatic to localise " "XCSoar according to the system settings.")); if (wp != nullptr) { DataFieldEnum &df = *(DataFieldEnum *)wp->GetDataField(); df.addEnumText(_("Automatic")); df.addEnumText(_T("English")); #ifdef HAVE_BUILTIN_LANGUAGES for (const BuiltinLanguage *l = language_table; l->resource != nullptr; ++l) { StaticString<100> display_string; display_string.Format(_T("%s (%s)"), l->name, l->resource); df.addEnumText(l->resource, display_string); } #endif LanguageFileVisitor lfv(df); VisitDataFiles(_T("*.mo"), lfv); df.Sort(2); auto value_buffer = Profile::GetPath(ProfileKeys::LanguageFile); Path value = value_buffer; if (value.IsNull()) value = Path(_T("")); if (value == Path(_T("none"))) df.Set(1); else if (!value.IsEmpty() && value != Path(_T("auto"))) { const Path base = value.GetBase(); if (base != nullptr) df.Set(base.c_str()); } wp->RefreshDisplay(); } #endif /* !HAVE_NATIVE_GETTEXT */ AddTime(_("Menu timeout"), _("This determines how long menus will appear on screen if the user does not make any button " "presses or interacts with the computer."), 1, 60, 1, settings.menu_timeout / 2); SetExpertRow(MenuTimeout); static constexpr StaticEnumChoice text_input_list[] = { { (unsigned)DialogSettings::TextInputStyle::Default, N_("Default") }, { (unsigned)DialogSettings::TextInputStyle::Keyboard, N_("Keyboard") }, { (unsigned)DialogSettings::TextInputStyle::HighScore, N_("HighScore Style") }, { 0 } }; AddEnum(_("Text input style"), _("Determines how the user is prompted for text input (filename, teamcode etc.)"), text_input_list, (unsigned)settings.dialog.text_input_style); SetExpertRow(TextInput); /* on-screen keyboard doesn't work without a pointing device (mouse or touch screen) */ SetRowVisible(TextInput, HasPointer()); #ifdef HAVE_VIBRATOR static constexpr StaticEnumChoice haptic_feedback_list[] = { { (unsigned)UISettings::HapticFeedback::DEFAULT, N_("OS settings") }, { (unsigned)UISettings::HapticFeedback::OFF, N_("Off") }, { (unsigned)UISettings::HapticFeedback::ON, N_("On") }, { 0 } }; wp = AddEnum(_("Haptic feedback"), _("Determines if haptic feedback like vibration is used."), haptic_feedback_list, (unsigned)settings.haptic_feedback); SetExpertRow(HapticFeedback); #endif /* HAVE_VIBRATOR */ }