Example #1
0
        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 */
}