X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Feditor%2Fg_language.pas;h=7d4f2d83c869aca819ce76a250843520163f549d;hb=refs%2Fheads%2Fmaster;hp=bcb99cabcaa1d79d4a8a60697b569bd088bfad58;hpb=3360cb5c3e96b591451afa67a0f8a281db79e8c5;p=d2df-editor.git diff --git a/src/editor/g_language.pas b/src/editor/g_language.pas index bcb99ca..7d4f2d8 100644 --- a/src/editor/g_language.pas +++ b/src/editor/g_language.pas @@ -4,7 +4,7 @@ Interface - uses g_Basic, MAPDEF; + uses g_Basic, MAPDEF, Classes; resourcestring MsgNotAccessible = 'N/A'; @@ -59,7 +59,7 @@ Interface MsgArrayItemRocketLauncher = 'Rocket Launcher'; MsgArrayItemPlasmaRifle = 'Plasma Rifle'; MsgArrayItemBfg = 'BFG9000'; - MsgArrayItemSuperMinigun = 'Super Chaingun'; + MsgArrayItemSuperChaingun = 'Super Chaingun'; MsgArrayItemFlamethrower = 'Flamethrower'; MsgArrayItemClip = 'Clip'; MsgArrayItemAmmoBox = 'Box of Bullets'; @@ -307,19 +307,19 @@ Interface MsgMsgChooseTexture = 'Select Texture'; MsgMsgChooseRes = 'Resource hasn''t been selected'; MsgMsgExit = 'Exit'; - MsgMsgExitPromt = 'Leaving so soon?'; + MsgMsgExitPrompt = 'Leaving so soon?'; MsgMsgDelTexture = 'Delete the texture'; - MsgMsgDelTexturePromt = 'Delete the texture "%s" ?'; + MsgMsgDelTexturePrompt = 'Delete the texture "%s" ?'; MsgMsgDelTextureCant = 'Can''t delete texture in use. Replace it on all panels with this texture.'; MsgMsgDelRecent = 'File does not longer exist'; - MsgMsgDelRecentPromt = 'Remove entry from recent list?'; + MsgMsgDelRecentPrompt = 'Remove entry from recent list?'; MsgMsgClearMap = 'New map'; - MsgMsgClearMapPromt = 'Clear the entire map?'; + MsgMsgClearMapPrompt = 'Clear the entire map?'; MsgMsgDeleteMap = 'Delete the map'; - MsgMsgDeleteMapPromt = 'Delete the map "%s" from "%s" ?'; + MsgMsgDeleteMapPrompt = 'Delete the map "%s" from "%s" ?'; MsgMsgMapDeleted = 'Map is deleted'; - MsgMsgMapDeletedPromt = 'Map "%s" is deleted'; - MsgMsgReopenMapPromt = 'Reopen this map?'; + MsgMsgMapDeletedPrompt = 'Map "%s" is deleted'; + MsgMsgReopenMapPrompt = 'Reopen this map?'; MsgMsgExecError = 'Game start error'; MsgMsgSoundError = 'Can''t play sound'; MsgMsgWadError = 'Can''t open WAD: %s'; @@ -339,17 +339,23 @@ Interface MsgHintWidth = 'Width: %d'; MsgHintHeight = 'Height: %d'; + MsgMenuAppleAbout = 'About Editor'; + MsgMenuApplePref = 'Preferences...'; + MsgMenuFile = 'File'; MsgMenuFileNew = 'New'; MsgMenuFileOpen = 'Open...'; + MsgMenuFileRecentMac = 'Open Recent'; + MsgMenuFileRecentClearMac = 'Clear Recent'; MsgMenuFileSave = 'Save'; MsgMenuFileSaveAs = 'Save As...'; MsgMenuFileOpenWad = 'Select Map...'; MsgMenuFileReopen = 'Revert to Saved'; MsgMenuFileSaveMini = 'Save Minimap...'; - MsgMenuFileDelete = 'Delete from WAD...'; + MsgMenuFileDelete = 'Remove from WAD...'; MsgMenuFilePackMap = 'Pack to WAD...'; - MsgMenuFileExit = 'Exit'; + MsgMenuFileRecentWin = 'Recent Files'; + MsgMenuFileExitWin = 'Exit'; MsgMenuEdit = 'Edit'; MsgMenuEditUndo = 'Undo'; @@ -357,29 +363,30 @@ Interface MsgMenuEditCut = 'Cut'; MsgMenuEditPaste = 'Paste'; MsgMenuEditSelectAll = 'Select All'; + MsgMenuEditSnapGrid = 'Snap to Grid'; + MsgMenuEditStepGrid = 'Switch Grid Step'; MsgMenuEditToFore = 'Bring to Front'; MsgMenuEditToBack = 'Send to Back'; + MsgMenuEditMapProps = 'Map Properties...'; + MsgMenuEditPrefWin = 'Preferences...'; - MsgMenuTools = 'Tools'; - MsgMenuToolsSnapGrid = 'Snap to Grid'; - MsgMenuToolsMinimap = 'Show Minimap'; - MsgMenuToolsStepGrid = 'Switch Grid Granularity'; - MsgMenuToolsShowEdges = 'Show Map Bounds'; - MsgMenuToolsLayers = 'Layers'; + MsgMenuView = 'View'; + MsgMenuViewLayers = 'Layers'; + MsgMenuViewMinimap = 'Show Minimap Navigator'; + MsgMenuViewBounds = 'Show Map Bounds'; + MsgMenuViewPreview = 'Preview Mode'; MsgMenuServ = 'Service'; MsgMenuServTest = 'Analyse Map...'; MsgMenuServOpt = 'Optimize Map...'; - MsgMenuServPreview = 'Preview Mode'; MsgMenuServLaunch = 'Run Test'; - MsgMenuSets = 'Settings'; - MsgMenuSetsMap = 'Map Properties...'; - MsgMenuSetsEditor = 'Preferences...'; - MsgMenuSetsLaunch = 'In-game test settings'; + MsgMenuWindow = 'Window'; + MsgMenuWindowMinimize = 'Minimize'; + MsgMenuWindowZoom = 'Zoom'; MsgMenuHelp = 'Help'; - MsgMenuHelpAbout = 'About'; + MsgMenuHelpAboutWin = 'About Editor'; MsgMenuLayerBack = '1. Background'; MsgMenuLayerWall = '2. Walls'; @@ -416,7 +423,7 @@ Interface MsgCapOpt = 'Optimize Map'; MsgCapSets = 'Map Properties'; MsgCapLaunch = 'In-game test Settings'; - MsgCapEs = 'Editor Preferences'; + MsgCapEs = 'Preferences'; MsgCapPack = 'Pack Map'; MsgCapSave = 'Save Map'; MsgCapMini = 'Save Minimap'; @@ -480,6 +487,7 @@ Interface MsgCtrlSetsStats = 'Statistics:'; MsgCtrlSetsSizes = 'Map Size:'; + MsgCtrlEsTesting = 'Testing'; MsgCtrlLaunchDm = 'Deathmatch'; MsgCtrlLaunchTdm = 'Team Deathmatch'; MsgCtrlLaunchCtf = 'Capture the Flag'; @@ -492,6 +500,7 @@ Interface MsgCtrlLaunchClose = 'Close the game after exiting the map'; MsgCtrlLaunchOpen = 'Select Doom 2D: Forever executable'; + MsgCtrlEsGeneral = 'General'; MsgCtrlEsGrid = 'Show Grid'; MsgCtrlEsTexture = 'Show Panel Texture'; MsgCtrlEsPanelSize = 'Show Panel Size'; @@ -539,7 +548,9 @@ Interface MsgLabLaunchTime = 'Time Limit:'; MsgLabLaunchSecs = 'seconds'; MsgLabLaunchScore = 'Score Limit:'; - MsgLabLaunchPath = 'Path to Doom2DF.exe:'; + MsgLabLaunchPathWin = 'Path to Doom2DF.exe:'; + MsgLabLaunchPathMac = 'Path to Doom 2D Forever.app:'; + MsgLabLaunchPathUnix = 'Path to Doom2DF:'; MsgLabLaunchArgs = 'Launch Arguments:'; MsgLabEsGrid = 'Grid Step:'; @@ -550,8 +561,9 @@ Interface MsgLabEsMinimap = 'Mini-map Scale:'; MsgLabEsRecent = 'Recent Maps List Contains:'; MsgLabEsLanguage = 'Language:'; - MsgLabEsCompress = 'Compress archive when save'; - MsgLabEsBackup = 'Make backup before save'; + MsgLabEsLanguageAuto = 'System Default'; + + MsgCtrlEsFiles = 'Files'; MsgLabPackSaveTo = 'Save to:'; MsgLabPackMapName = 'Map Resource Name:'; @@ -613,10 +625,15 @@ Interface MsgOptPanelsAfter = 'Panels after Optimization:'; MsgWadSpecialMap = ''; - MsgWadSpecialTexs = ''; + MsgWadSpecialTexs = ''; - MsgFileFilterAll = 'Doom 2D: Forever Maps (*.dfz, *.dfzip, *.zip, *.wad)|*.dfz;*.dfzip;*.zip;*.wad|Doom 2D: Forever 0.30 Maps (*.ini)|*.ini|All Files (*.*)|*.*'; - MsgFileFilterWad = 'Doom 2D: Forever Maps (*.dfz)|*.dfz|Doom 2D: Forever Maps (*.dfzip)|*.dfzip|Doom 2D: Forever Maps (*.zip)|*.zip|Doom 2D: Forever Maps (*.wad)|*.wad|All Files (*.*)|*.*'; + MsgFileFilterSaveDFWAD = 'Doom 2D: Forever Maps in DFWAD packages (*.wad)|*.wad'; + MsgFileFilterSaveDFZIP = 'Doom 2D: Forever Maps in DFZIP archives (*.dfz)|*.dfz'; + MsgFileFilterAll = 'Doom 2D: Forever Maps (*.dfz, *.wad)|*.wad;*.dfz|Doom 2D: Forever 0.30 Maps (*.ini)|*.ini|All Files (*.*)|*.*'; + MsgFileFilterWad = 'Doom 2D: Forever Maps (*.dfz, *.wad)|*.wad;*.dfz|All Files (*.*)|*.*'; + MsgFileFilterExeMac = 'Doom 2D Forever.app|*.app|Doom 2D Forever (Unix Executable)|Doom2DF;*'; + MsgFileFilterExeWin = 'Doom2DF.exe|Doom2DF.exe;*.exe'; + MsgFileFilterExeUnix = 'Doom2DF|Doom2DF;*'; MsgEditorTitle = 'Doom 2D: Forever Map Editor'; @@ -633,18 +650,22 @@ Var AreaNames: Array [AREA_PLAYERPOINT1..AREA_BLUETEAMPOINT] of String; TriggerNames: Array [TRIGGER_EXIT..TRIGGER_MAX] of String; +function g_Language_GetList (): TStringList; procedure g_Language_Set(lang: String); Implementation Uses - gettext, + g_options, IniFiles, gettext, LazFileUtils, SysUtils, e_log, f_main, f_about, f_activationtype, f_addresource_sky, f_addresource_sound, f_addresource_texture, f_choosetype, f_keys, f_mapcheck, f_mapoptions, f_mapoptimization, f_options, f_packmap, f_savemap, f_saveminimap, f_selectmap, Forms, utils; + const + InSourceLanguage = 'en_US'; + procedure SetupArrays(); var i: Integer; @@ -710,7 +731,7 @@ begin ItemNames[ITEM_WEAPON_ROCKETLAUNCHER] := MsgArrayItemRocketLauncher; ItemNames[ITEM_WEAPON_PLASMA] := MsgArrayItemPlasmaRifle; ItemNames[ITEM_WEAPON_BFG] := MsgArrayItemBfg; - ItemNames[ITEM_WEAPON_SUPERPULEMET] := MsgArrayItemSuperMinigun; + ItemNames[ITEM_WEAPON_SUPERCHAINGUN] := MsgArrayItemSuperChaingun; ItemNames[ITEM_WEAPON_FLAMETHROWER] := MsgArrayItemFlamethrower; ItemNames[ITEM_AMMO_BULLETS] := MsgArrayItemClip; ItemNames[ITEM_AMMO_BULLETS_BOX] := MsgArrayItemAmmoBox; @@ -725,7 +746,7 @@ begin ItemNames[ITEM_KEY_RED] := MsgArrayItemKeyRed; ItemNames[ITEM_KEY_GREEN] := MsgArrayItemKeyGreen; ItemNames[ITEM_KEY_BLUE] := MsgArrayItemKeyBlue; - ItemNames[ITEM_WEAPON_KASTET] := '?'; + ItemNames[ITEM_WEAPON_IRONFIST] := '?'; ItemNames[ITEM_WEAPON_PISTOL] := '??'; ItemNames[ITEM_BOTTLE] := MsgArrayItemBottle; ItemNames[ITEM_HELMET] := MsgArrayItemHelmet; @@ -877,11 +898,16 @@ begin end else Caption := FormCaption; - // Главное меню: - // "Файл": + + // Apple menu: + miAppleAbout.Caption := MsgMenuAppleAbout; + miApplePref.Caption := MsgMenuApplePref; + // File menu: miMenuFile.Caption := MsgMenuFile; miNewMap.Caption := MsgMenuFileNew; miOpenMap.Caption := MsgMenuFileOpen; + miMacRecentSubMenu.Caption := MsgMenuFileRecentMac; + miMacRecentClear.Caption := MsgMenuFileRecentClearMac; miSaveMap.Caption := MsgMenuFileSave; miSaveMapAs.Caption := MsgMenuFileSaveAs; miOpenWadMap.Caption := MsgMenuFileOpenWad; @@ -889,22 +915,24 @@ begin miSaveMiniMap.Caption := MsgMenuFileSaveMini; miDeleteMap.Caption := MsgMenuFileDelete; miPackMap.Caption := MsgMenuFilePackMap; - miExit.Caption := MsgMenuFileExit; - // "Правка": + miWinRecent.Caption := MsgMenuFileRecentWin; + miExit.Caption := MsgMenuFileExitWin; + // Edit menu: miMenuEdit.Caption := MsgMenuEdit; miUndo.Caption := MsgMenuEditUndo; miCopy.Caption := MsgMenuEditCopy; miCut.Caption := MsgMenuEditCut; miPaste.Caption := MsgMenuEditPaste; miSelectAll.Caption := MsgMenuEditSelectAll; + miSnapToGrid.Caption := MsgMenuEditSnapGrid; + miSwitchGrid.Caption := MsgMenuEditStepGrid; miToFore.Caption := MsgMenuEditToFore; miToBack.Caption := MsgMenuEditToBack; - // "Инструменты": - miSnapToGrid.Caption := MsgMenuToolsSnapGrid; - miMiniMap.Caption := MsgMenuToolsMinimap; - miSwitchGrid.Caption := MsgMenuToolsStepGrid; - miShowEdges.Caption := MsgMenuToolsShowEdges; - miLayers.Caption := MsgMenuToolsLayers; + miMapOptions.Caption := MsgMenuEditMapProps; + miOptions.Caption := MsgMenuEditPrefWin; + // View menu: + miMenuView.Caption := MsgMenuView; + miLayers.Caption := MsgMenuViewLayers; miLayer1.Caption := MsgMenuLayerBack; miLayer2.Caption := MsgMenuLayerWall; miLayer3.Caption := MsgMenuLayerFore; @@ -914,29 +942,29 @@ begin miLayer7.Caption := MsgMenuLayerMonster; miLayer8.Caption := MsgMenuLayerArea; miLayer9.Caption := MsgMenuLayerTrigger; - miMapOptions.Caption := MsgMenuSetsMap; - miOptions.Caption := MsgMenuSetsEditor; - // "Сервис": + miMiniMap.Caption := MsgMenuViewMinimap; + miShowEdges.Caption := MsgMenuViewBounds; + miMapPreview.Caption := MsgMenuViewPreview; + // Service menu: miMenuService.Caption := MsgMenuServ; miCheckMap.Caption := MsgMenuServTest; miOptimmization.Caption := MsgMenuServOpt; - miMapPreview.Caption := MsgMenuServPreview; miTestMap.Caption := MsgMenuServLaunch; - // "Справка": + // Window menu: + miMenuWindow.Caption := MsgMenuWindow; + miMacMinimize.Caption := MsgMenuWindowMinimize; + miMacZoom.Caption := MsgMenuWindowZoom; + // Help menu: miMenuHelp.Caption := MsgMenuHelp; - miAbout.Caption := MsgMenuHelpAbout; + miAbout.Caption := MsgMenuHelpAboutWin; - // Панель инструментов: + // Toolbar: tbNewMap.Hint := MsgMenuTbNew; tbOpenMap.Hint := MsgMenuTbOpen; tbSaveMap.Hint := MsgMenuTbSave; tbOpenWadMap.Hint := MsgMenuTbOpenWad; tbShowMap.Hint := MsgMenuTbMinimap; tbShow.Hint := MsgMenuTbLayers; - tbGridOn.Hint := MsgMenuTbGrid; - tbGrid.Hint := MsgMenuTbGridStep; - tbTestMap.Hint := MsgMenuTbLaunch; - // Всплывающее меню для кнопки слоев: miLayerP1.Caption := MsgMenuLayerBack; miLayerP2.Caption := MsgMenuLayerWall; miLayerP3.Caption := MsgMenuLayerFore; @@ -946,18 +974,19 @@ begin miLayerP7.Caption := MsgMenuLayerMonster; miLayerP8.Caption := MsgMenuLayerArea; miLayerP9.Caption := MsgMenuLayerTrigger; + tbGridOn.Hint := MsgMenuTbGrid; + tbGrid.Hint := MsgMenuTbGridStep; + tbTestMap.Hint := MsgMenuTbLaunch; - // Кнопка применения свойств: + // Object property editor: bApplyProperty.Caption := MsgBtnApplyProps; - // Редактор свойств объектов: vleObjectProperty.TitleCaptions[0] := MsgCtrlPropKey; vleObjectProperty.TitleCaptions[1] := MsgCtrlPropValue; - // Вкладка "Панели": + // Panels Tab: tsPanels.Caption := MsgCtrlPanels; lbPanelType.Hint := MsgPropPanelType; lbTextureList.Hint := MsgCtrlListTexture; - // Панель настройки текстур: LabelTxW.Caption := MsgLabTexWidth; LabelTxH.Caption := MsgLabTexHeight; cbPreview.Caption := MsgCtrlPreview; @@ -965,25 +994,25 @@ begin bbRemoveTexture.Hint := MsgBtnTextureDelete; bClearTexture.Hint := MsgBtnTextureEmpty; - // Вкладка "Предметы": + // Items Tab: tsItems.Caption := MsgCtrlItems; lbItemList.Hint := MsgCtrlListItem; cbOnlyDM.Caption := MsgCtrlItemDm; cbFall.Caption := MsgCtrlItemFalls; - // Вкладка "Монстры": + // Monters Tab: tsMonsters.Caption := MsgCtrlMonsters; lbMonsterList.Hint := MsgCtrlListMonster; rbMonsterLeft.Caption := MsgCtrlLeft; rbMonsterRight.Caption := MsgCtrlRight; - // Вкладка "Области": + // Areas Tab: tsAreas.Caption := MsgCtrlAreas; lbAreasList.Hint := MsgCtrlListArea; rbAreaLeft.Caption := MsgCtrlLeft; rbAreaRight.Caption := MsgCtrlRight; - // Вкладка "Триггеры": + // Triggers Tab: tsTriggers.Caption := MsgCtrlTriggers; lbTriggersList.Hint := MsgCtrlListTrigger; clbActivationType.Hint := MsgCtrlListActive; @@ -1125,13 +1154,14 @@ begin bCancel.Caption := MsgBtnCancel; end; -// From "Editor settings": +// Form preferences: with OptionsForm do begin Caption := MsgCapEs; bOK.Caption := MsgBtnOk; bCancel.Caption := MsgBtnCancel; // TabGeneral: + TabGeneral.Caption := MsgCtrlEsGeneral; cbShowDots.Caption := MsgCtrlEsGrid; cbShowTexture.Caption := MsgCtrlEsTexture; cbShowSize.Caption := MsgCtrlEsPanelSize; @@ -1144,10 +1174,10 @@ begin LabelMinimap.Caption := MsgLabEsMinimap; LabelLanguage.Caption := MsgLabEsLanguage; // TabFiles: - cbCompress.Caption := MsgLabEsCompress; - cbBackup.Caption := MsgLabEsBackup; + TabFiles.Caption := MsgCtrlEsFiles; LabelRecent.Caption := MsgLabEsRecent; // TabTesting: + TabTesting.Caption := MsgCtrlEsTesting; rbDM.Caption := MsgCtrlLaunchDm; rbTDM.Caption := MsgCtrlLaunchTdm; rbCTF.Caption := MsgCtrlLaunchCtf; @@ -1161,8 +1191,19 @@ begin LabelTime.Caption := MsgLabLaunchTime; LabelSecs.Caption := MsgLabLaunchSecs; LabelScore.Caption := MsgLabLaunchScore; - LabelPath.Caption := MsgLabLaunchPath; - FindD2dDialog.Title := MsgCtrlLaunchOpen; + {$IF DEFINED(DARWIN)} + LabelPath.Caption := MsgLabLaunchPathMac; + ExeEdit.DialogTitle := MsgCtrlLaunchOpen; + ExeEdit.Filter := MsgFileFilterExeMac; + {$ELSEIF DEFINED(WINDOWS)} + LabelPath.Caption := MsgLabLaunchPathWin; + ExeEdit.DialogTitle := MsgCtrlLaunchOpen; + ExeEdit.Filter := MsgFileFilterExeWin; + {$ELSE} + LabelPath.Caption := MsgLabLaunchPathUnix; + ExeEdit.DialogTitle := MsgCtrlLaunchOpen; + ExeEdit.Filter := MsgFileFilterExeUnix; + {$ENDIF} LabelArgs.Caption := MsgLabLaunchArgs; end; @@ -1213,31 +1254,131 @@ begin Application.Title := MsgEditorTitle; end; -procedure g_Language_Set(lang: String); - var syslang, fallbacklang: String; +type + TResArg = record + ini: TIniFile; + ignored: TStringList; + end; + PResArg = ^TResArg; + +function gResourceItarator (name, value: AnsiString; hash: LongInt; arg: Pointer): AnsiString; + var res: PResArg; orig: AnsiString; begin - e_WriteLog('g_Language_Set: requested lang is "' + lang + '"', MSG_NOTIFY); - GetLanguageIDs(syslang, fallbacklang); - if lang = '' then lang := syslang; + res := PResArg(arg); + orig := res.ini.ReadString('resourcestring', name + '$', ''); + if (orig = '') or (orig = value) then + begin + if res.ini.ValueExists('resourcestring', name) then + begin + result := res.ini.ReadString('resourcestring', name, ''); + end + else + begin + result := value; + if res.ignored.IndexOf(Copy(name, 1, Pos('.', name) - 1)) < 0 then + e_WriteLog(' Seems that key ' + name + ' not translated', MSG_NOTIFY); + end; + end + else + begin + e_WriteLog(' Original resource string for ' + name + ' do not match, translation are outdated?', MSG_WARNING); + e_WriteLog(' [' + value + '] -> [' + orig + ']', MSG_WARNING); + result := value; + end; +end; - ResetResourceTables; +procedure gSetLanguageFormStream (const lang: AnsiString; stream: TStream; out ok: Boolean); + var res: TResArg; +begin + ok := False; try - e_WriteLog('g_Language_Set: try language "' + lang + '"', MSG_NOTIFY); - TranslateResourceStrings('data/lang/editor.' + lang + '.mo'); + res.ini := TIniFile.Create(stream, [ifoStripComments, ifoStripQuotes, ifoEscapeLineFeeds]); except + res.ini := nil; + end; + if res.ini <> nil then + begin try - e_WriteLog('g_Language_Set: try system language "' + syslang + '"', MSG_NOTIFY); - TranslateResourceStrings('data/lang/editor.' + syslang + '.mo'); - except - try - e_WriteLog('g_Language_Set: try fallback language "' + fallbacklang + '"', MSG_NOTIFY); - TranslateResourceStrings('data/lang/editor.' + fallbacklang + '.mo'); - except - e_WriteLog('g_Language_Set: use default strings', MSG_NOTIFY); + ok := res.ini.SectionExists('resourcestring'); + if ok then + begin + res.ignored := TStringList.Create; + res.ignored.CaseSensitive := False; + res.ini.ReadSection('ignore', res.ignored); + res.ignored.Sort; + SetResourceStrings(gResourceItarator, @res); + res.ignored.Free(); end; + finally + res.ini.Free(); + end; + end; + if not ok then e_WriteLog('Translation file for ' + lang + ' are invalid ', MSG_FATALERROR); +end; + +procedure gSetLanguageFromFile (const lang: AnsiString; out ok: Boolean); + const langfilename = 'editor'; + var stream: TFileStream; name: AnsiString; +begin + name := LangDir + DirectorySeparator + langfilename + '.' + lang + '.lng'; + try + stream := TFileStream.Create(name, fmOpenRead); + try + gSetLanguageFormStream(lang, stream, ok); + finally + stream.Free(); end; + except on E: EFOpenError do + ok := False; end; - e_WriteLog('g_Language_Set: ok', MSG_NOTIFY); +end; + +procedure gSetLanguage (const lang: AnsiString; out ok: Boolean); +begin + gSetLanguageFromFile(lang, ok); +end; + +function g_Language_GetList (): TStringList; + const langfilename = 'editor'; + var list: TStringList; info: TSearchRec; +begin + list := TStringList.Create; + list.Duplicates := dupIgnore; + list.Add(InSourceLanguage); + if FindFirst(LangDir + DirectorySeparator + langfilename + '.*.lng', faReadOnly, info) = 0 then + begin + repeat + list.Add(Copy(ExtractFileNameWithoutExt(info.Name), Length(langfilename) + 2)); + until FindNext(info) <> 0; + FindClose(info); + end; + list.Sort; + result := list; +end; + +procedure g_Language_Set(lang: String); + var syslang, fallbacklang: String; ok: Boolean; +begin + ResetResourceTables; + + if lang = '' then + begin + GetLanguageIDs(syslang, fallbacklang); // TODO: remove dependency on gettext + e_WriteLog('g_Language_Set: try strings "' + syslang + '" (system)', MSG_NOTIFY); + gSetLanguage(syslang, ok); + if not ok then + begin + e_WriteLog('g_Language_Set: try strings "' + fallbacklang + '" (fallback)', MSG_NOTIFY); + gSetLanguage(syslang, ok); + end; + end + else + begin + e_WriteLog('g_Language_Set: try strings "' + lang + '" (user specified)', MSG_NOTIFY); + gSetLanguage(lang, ok); + end; + if not ok then e_WriteLog('g_Language_Set: use default strings "' + InSourceLanguage + '" (in-source)', MSG_NOTIFY); + SetupArrays(); SetupCaptions(); RemoveSelectFromObjects();