2016-12-04 15:13:38 +00:00
|
|
|
unit umain;
|
2016-12-07 11:27:22 +00:00
|
|
|
|
|
|
|
{$DEFINE PO_BUILTINRES}// Use built-in resources for .po files
|
2016-12-07 12:01:37 +00:00
|
|
|
// If compiling with Laz Version < 1.7 then use lazres to make a translate.lrs from the .po files
|
|
|
|
// If compiling Laz V >=1.7 then add the .po files in Project/Options/resources
|
|
|
|
// Without this DEFINE, include the /locale folder in the distribution
|
2016-12-07 11:27:22 +00:00
|
|
|
|
|
|
|
{ OnlinePackageManager Update JSON Editor
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
Copyright (C)2016 usernames lainz, minesadorada, GetMem @ http://forum.lazarus.freepascal.org/index.php
|
2016-12-04 15:13:38 +00:00
|
|
|
|
|
|
|
This source is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free
|
|
|
|
Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
details.
|
|
|
|
|
|
|
|
A copy of the GNU General Public License is available on the World Wide Web
|
|
|
|
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
|
|
|
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
|
|
MA 02111-1307, USA.
|
|
|
|
|
|
|
|
Version History
|
|
|
|
===============
|
|
|
|
0.0.0.0 Original code by lainz
|
2016-12-04 18:05:35 +00:00
|
|
|
..to 0.1.6.0 Refactored and updated (minesadorada)
|
|
|
|
0.1.7.0: Bugfix (lainz)
|
|
|
|
0.1.8.0: Config file change (minesadorada)
|
2016-12-04 18:31:18 +00:00
|
|
|
0.1.9.0: Error check for duplicate lpk entries (minesadorada)
|
2016-12-04 18:05:35 +00:00
|
|
|
0.1.10.0: Exception handling for Load + Save (minesadorada)
|
2016-12-05 08:41:51 +00:00
|
|
|
0.1.11.0: Cleaned up code formatting etc. (minesadorada)
|
2016-12-05 11:04:45 +00:00
|
|
|
0.1.12.0: Rename Global DownloadURL to DownloadZipURL (minesadorada)
|
|
|
|
0.1.13.0: Renamed TPackageData -> TUpdatePackageData (GetMem)
|
|
|
|
Renamed TPackageFiles -> TUpdatePackageFiles (GetMem)
|
|
|
|
Comment out Self.AutoAdjustLayout line in Form.Create (GetMem)
|
|
|
|
Removed StrUtils from uses (minesadorada)
|
|
|
|
Fixed memory leaks with CFG and slErrorList (minesadorada)
|
2016-12-06 11:02:40 +00:00
|
|
|
Moved inline procedure CreateUniqueINI to separate function (minesadorada)
|
|
|
|
Added Const C_DEBUGMESSAGES=TRUE/FALSE (minesadorada)
|
2016-12-05 14:22:18 +00:00
|
|
|
0.1.14.0: Various changes (GetMem)
|
2016-12-06 11:02:40 +00:00
|
|
|
BugFix: FormCloseQuery(minesadorada)
|
|
|
|
0.1.15.0: BugFix: File/Save didn't add the '.json' suffix in Linux (minesadorada)
|
|
|
|
Addition: After Loading, run validation tests(minesadorada)
|
|
|
|
0.1.16.0: Renamed ForceUpdate to ForceNotify (GetMem/minesadorada)
|
2016-12-09 10:13:04 +00:00
|
|
|
0.1.17.0: po files stored in executable's resources (minesadorada)
|
|
|
|
Use Project/Options/Resources in Laz 1.7+ to add the .po files
|
|
|
|
or.. Use (Gl)LazRes to make a file 'translate.lrs' in older Laz (minesadorada)
|
|
|
|
This can be disabled by commenting out $DEFINE PO_BUILTINRES
|
|
|
|
This system means you do not have to deploy the /locale folder - just the executable.
|
|
|
|
Portability: On startup, it will make a unique cfg file in the GetAppConfig folder based
|
|
|
|
on the executable's location on disk, so you can have copies of jsoneditor
|
|
|
|
in each component's dev folder that uses its own config file, language and updates folder.
|
2016-12-09 08:59:02 +00:00
|
|
|
0.1.18.0: Bugfix: Linux path error when creating locale folder (minesadorada)
|
2016-12-09 10:13:04 +00:00
|
|
|
0.1.19.0: Added IntrnalVersion integer field to json (getmem/minesadorada)
|
2016-12-09 08:59:02 +00:00
|
|
|
Added SpinEdit to control the above (minesadorada)
|
2016-12-09 10:13:04 +00:00
|
|
|
In Laz 1.7 DPIAwareness configured
|
2016-12-09 08:59:02 +00:00
|
|
|
0.1.20.0: ??
|
2016-12-04 15:13:38 +00:00
|
|
|
}
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
2016-12-09 10:13:04 +00:00
|
|
|
{DefaultTranslator not used}
|
2016-12-04 15:13:38 +00:00
|
|
|
uses
|
|
|
|
Classes, Forms, Controls, StdCtrls, Menus, ActnList, StdActns, Grids,
|
2016-12-09 08:59:02 +00:00
|
|
|
Graphics, Buttons, fileutil, LazFileUtils, fileinfo, ugenericcollection,
|
|
|
|
fpjsonrtti, Dialogs, LCLTranslator, PopupNotifier, SysUtils, inifiles,
|
|
|
|
lclintf, lclVersion, LResources, Spin, {$IFDEF PO_BUILTINRES}LazUTF8Classes{$ENDIF};
|
2016-12-05 11:16:14 +00:00
|
|
|
|
2016-12-07 11:27:22 +00:00
|
|
|
const
|
|
|
|
C_DEBUGMESSAGES = False;
|
2016-12-07 09:47:36 +00:00
|
|
|
|
2016-12-04 15:13:38 +00:00
|
|
|
type
|
|
|
|
|
2016-12-07 11:27:22 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
{ TUpdatePackageFiles }
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
TUpdatePackageFiles = class(TCollectionItem)
|
2016-12-04 15:13:38 +00:00
|
|
|
private
|
|
|
|
FName: string;
|
|
|
|
FVersion: string;
|
|
|
|
published
|
|
|
|
property Name: string read FName write FName;
|
|
|
|
property Version: string read FVersion write FVersion;
|
|
|
|
end;
|
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
TPackageFilesList = specialize TGenericCollection<TUpdatePackageFiles>;
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
{ TUpdatePackageData }
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
TUpdatePackageData = class(TPersistent)
|
2016-12-04 15:13:38 +00:00
|
|
|
private
|
2016-12-05 08:41:51 +00:00
|
|
|
FDownloadZipURL: string;
|
2016-12-06 11:02:40 +00:00
|
|
|
FForceNotify: boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
FName: string;
|
2016-12-09 08:59:02 +00:00
|
|
|
FInternalVersion:Integer;
|
2016-12-04 15:13:38 +00:00
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
published
|
|
|
|
property Name: string read FName write FName;
|
2016-12-06 11:02:40 +00:00
|
|
|
property ForceNotify: boolean read FForceNotify write FForceNotify;
|
2016-12-05 08:41:51 +00:00
|
|
|
property DownloadZipURL: string read FDownloadZipURL write FDownloadZipURL;
|
2016-12-09 08:59:02 +00:00
|
|
|
property InternalVersion: integer read FInternalVersion write FInternalVersion;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
{ TUpdatePackage }
|
|
|
|
|
|
|
|
TUpdatePackage = class(TPersistent)
|
2016-12-04 15:13:38 +00:00
|
|
|
private
|
2016-12-05 14:22:18 +00:00
|
|
|
FUpdatePackageData: TUpdatePackageData;
|
|
|
|
FUpdatePackageFiles: TPackageFilesList;
|
2016-12-04 15:13:38 +00:00
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
2016-12-04 18:31:18 +00:00
|
|
|
function LoadFromFile(AFileName: string): boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
function SaveToFile(AFileName: string): boolean;
|
|
|
|
published
|
2016-12-07 11:27:22 +00:00
|
|
|
property UpdatePackageData: TUpdatePackageData
|
|
|
|
read FUpdatePackageData write FUpdatePackageData;
|
|
|
|
property UpdatePackageFiles: TPackageFilesList
|
|
|
|
read FUpdatePackageFiles write FUpdatePackageFiles;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
2016-12-04 18:31:18 +00:00
|
|
|
|
2016-12-04 15:13:38 +00:00
|
|
|
{ TfrmMain }
|
|
|
|
|
|
|
|
TfrmMain = class(TForm)
|
|
|
|
ActionList1: TActionList;
|
2016-12-09 08:59:02 +00:00
|
|
|
cbForceNotify: TCheckBox;
|
2016-12-04 15:13:38 +00:00
|
|
|
cmd_Close: TBitBtn;
|
|
|
|
cmd_save: TBitBtn;
|
|
|
|
btnAdd: TButton;
|
|
|
|
btnRemove: TButton;
|
|
|
|
editName: TEdit;
|
2016-12-05 08:41:51 +00:00
|
|
|
editDownloadZipURL: TEdit;
|
2016-12-04 15:13:38 +00:00
|
|
|
FileOpen1: TFileOpen;
|
|
|
|
FileSaveAs1: TFileSaveAs;
|
2016-12-09 08:59:02 +00:00
|
|
|
grp_ForceNotify: TGroupBox;
|
|
|
|
lbl_InternalVersion: TLabel;
|
2016-12-04 15:13:38 +00:00
|
|
|
lblPackageFiles: TLabel;
|
|
|
|
lblName: TLabel;
|
2016-12-05 08:41:51 +00:00
|
|
|
lblDownloadZipURL: TLabel;
|
2016-12-04 15:13:38 +00:00
|
|
|
MainMenu1: TMainMenu;
|
|
|
|
FileMenu: TMenuItem;
|
|
|
|
LoadItem: TMenuItem;
|
|
|
|
mnu_fileNew: TMenuItem;
|
|
|
|
mnu_helpDisableWarnings: TMenuItem;
|
|
|
|
mnu_lang_es: TMenuItem;
|
|
|
|
mnu_lang_en: TMenuItem;
|
|
|
|
mnu_lang: TMenuItem;
|
|
|
|
mnu_helpAbout: TMenuItem;
|
|
|
|
mnu_helpShowHints: TMenuItem;
|
|
|
|
mnu_help: TMenuItem;
|
|
|
|
mnu_fileSave: TMenuItem;
|
|
|
|
mypopup: TPopupNotifier;
|
|
|
|
SaveAsItem: TMenuItem;
|
|
|
|
sb_editName: TSpeedButton;
|
|
|
|
spd_CheckURL: TSpeedButton;
|
2016-12-09 08:59:02 +00:00
|
|
|
Spin_InternalVersion: TSpinEdit;
|
2016-12-04 15:13:38 +00:00
|
|
|
stringPackageFiles: TStringGrid;
|
|
|
|
procedure btnAddClick(Sender: TObject);
|
|
|
|
procedure btnRemoveClick(Sender: TObject);
|
2016-12-06 11:02:40 +00:00
|
|
|
procedure cbForceNotifyMouseUp(Sender: TObject; Button: TMouseButton;
|
2016-12-04 15:13:38 +00:00
|
|
|
Shift: TShiftState; X, Y: integer);
|
|
|
|
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
|
|
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
|
|
procedure FormCreate(Sender: TObject);
|
2016-12-05 15:33:48 +00:00
|
|
|
procedure FormDestroy(Sender: TObject);
|
2016-12-04 15:13:38 +00:00
|
|
|
procedure FormShow(Sender: TObject);
|
2016-12-09 08:59:02 +00:00
|
|
|
procedure lbl_InternalVersionClick(Sender: TObject);
|
2016-12-04 15:13:38 +00:00
|
|
|
procedure LoadItemClick(Sender: TObject);
|
|
|
|
procedure mnu_fileNewClick(Sender: TObject);
|
|
|
|
procedure mnu_fileSaveClick(Sender: TObject);
|
|
|
|
procedure mnu_helpAboutClick(Sender: TObject);
|
|
|
|
procedure mnu_helpDisableWarningsClick(Sender: TObject);
|
|
|
|
procedure mnu_helpShowHintsClick(Sender: TObject);
|
|
|
|
procedure mnu_lang_enClick(Sender: TObject);
|
|
|
|
procedure mnu_lang_esClick(Sender: TObject);
|
|
|
|
procedure SaveAsItemClick(Sender: TObject);
|
|
|
|
procedure sb_editNameClick(Sender: TObject);
|
|
|
|
procedure spd_CheckURLClick(Sender: TObject);
|
|
|
|
private
|
|
|
|
{ private declarations }
|
2016-12-05 14:22:18 +00:00
|
|
|
JSONPackage: TUpdatePackage;
|
2016-12-04 18:31:18 +00:00
|
|
|
bForceSaveAs, bShowPopupHints, bDisableWarnings, bDirty, bIsVirgin: boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
sJSONFilePath: string;
|
|
|
|
sUpdateDirectory, sZipDirectory: string;
|
|
|
|
slErrorList: TStrings;
|
2016-12-05 11:04:45 +00:00
|
|
|
CFG: TIniFile;
|
2016-12-07 11:27:22 +00:00
|
|
|
INIFilePath: string;
|
2016-12-04 15:13:38 +00:00
|
|
|
function ValidationFailed: boolean;
|
|
|
|
procedure CtrlShowPopup(Sender: TObject);
|
|
|
|
procedure CtrlHidePopup(Sender: TObject);
|
|
|
|
procedure CtrlSetUpPopupHandlers;
|
|
|
|
procedure CtrlMakeDirty(Sender: TObject);
|
2016-12-04 18:31:18 +00:00
|
|
|
function FoundADuplicateLPK: boolean;
|
2016-12-07 11:27:22 +00:00
|
|
|
function CreateUniqueINI(var aCount: integer): boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
public
|
|
|
|
{ public declarations }
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
frmMain: TfrmMain;
|
2016-12-07 11:27:22 +00:00
|
|
|
sPoPath_en, sPoPath_es: string;
|
|
|
|
{$IFDEF PO_BUILTINRES}
|
2016-12-07 09:47:36 +00:00
|
|
|
aLRes: TLResource;
|
|
|
|
aSS: TStringListUTF8;
|
2016-12-07 11:27:22 +00:00
|
|
|
S: TResourceStream;
|
|
|
|
F: TFileStream;
|
|
|
|
{$ENDIF}
|
2016-12-04 15:13:38 +00:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
{$R *.lfm}
|
|
|
|
resourcestring
|
|
|
|
rsOneOfTheReq1 =
|
|
|
|
'One of the required fields is missing or wrong.';
|
|
|
|
rsOneOfTheReqn =
|
|
|
|
'One or more of the required fields are missing or wrong.';
|
|
|
|
rsSavedOK = 'Saved OK';
|
|
|
|
rsSaveUnsucces = 'Save unsuccessful';
|
|
|
|
rsOverwrite = 'Overwrite';
|
|
|
|
rsTurnHintsOff = '(You can toggle these hints on/off in the Help menu)';
|
|
|
|
rsHelpAndInfor = 'Help and Information';
|
|
|
|
rsAbout = 'About';
|
|
|
|
rsUpdate = 'Update';
|
|
|
|
rsFileMayBeUns = 'JSON may be unsaved. Are you sure you want to quit?';
|
|
|
|
rsMypackagenam = 'mypackagename.zip';
|
|
|
|
rsHttpWwwUpdat = 'http://www.updatesite.com/myupdate/mypackagename.zip';
|
|
|
|
rsLpkFileName = 'lpk FileName';
|
|
|
|
rsVersion0000 = 'Version (n.n.n.n)';
|
|
|
|
rsFixThenTryAg = 'Fix, then try again.';
|
|
|
|
rsUpdateZipNam = '- Update zip name is too short or missing';
|
2016-12-05 08:41:51 +00:00
|
|
|
rsDownloadZipURLI = '- Download URL is too short or missing';
|
2016-12-04 15:13:38 +00:00
|
|
|
rsThereAreNoLp = '- There are no .lpk files in the list yet';
|
|
|
|
rsUpdateZipNam2 = '- Update zip name missing extension ".zip"';
|
2016-12-05 08:41:51 +00:00
|
|
|
rsDownloadZipURLI2 = '- Download URL is incomplete';
|
|
|
|
rsDownloadZipURLS = '- Download URL should start with "http"';
|
|
|
|
rsDownloadZipURLD = '- Download URL does not contain the zipfile name';
|
2016-12-04 15:13:38 +00:00
|
|
|
rsWouldYouLike = 'Would you like to copy %s to the %s folder?';
|
|
|
|
rsSWasSuccessf = '%s was successfully copied to the %s folder';
|
|
|
|
rsSorryCopyOpe = 'Sorry - copy operation was unsuccessful';
|
|
|
|
rsCompiledWith2 = 'Compiled with FPC V:%s and Lazarus V:%d.%d%s for the %s -' +
|
|
|
|
' %s platform%s%s';
|
|
|
|
rsVersionEntry = 'Version Entry #%d is absent';
|
|
|
|
rsVersionEntry2 = 'Version entry #%d needs to be of the form n.n.n.n';
|
|
|
|
rsTheLpkEntryD = 'The .lpk entry #%d is missing the .lpk extension';
|
|
|
|
rsTheLpkEntryD2 = 'The .lpk entry #%d is is absent';
|
|
|
|
rsThisOptionSh =
|
|
|
|
'This option should only be used for crucial updates or bug-fixed packages. Are you OK with that?';
|
|
|
|
rsLanguageChan = 'Language changed to "%s".';
|
|
|
|
rsSorryThisLan = 'Sorry, this language is unavailable at this time.';
|
|
|
|
rsYouMayNeedTo = '(You may need to restart the app to see the change)';
|
2016-12-07 11:27:22 +00:00
|
|
|
rsThereAreOneO = '- There are one or more .lpk entries with the same name.%s' +
|
|
|
|
'- Every .lpk entry must have a unique name.';
|
2016-12-06 09:19:23 +00:00
|
|
|
rsUpdateJsonSF = 'Update file "%s" failed to load correctly.';
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
{ TUpdatePackageData }
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
constructor TUpdatePackageData.Create;
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
FName := '';
|
2016-12-06 11:02:40 +00:00
|
|
|
FForceNotify := False;
|
2016-12-05 08:41:51 +00:00
|
|
|
FDownloadZipURL := '';
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{ TfrmMain }
|
|
|
|
procedure TfrmMain.CtrlMakeDirty(Sender: TObject);
|
|
|
|
begin
|
|
|
|
bDirty := True;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.CtrlHidePopup(Sender: TObject);
|
|
|
|
// Get rid of highlighting
|
|
|
|
begin
|
|
|
|
mypopup.Hide;
|
|
|
|
slErrorList.Clear;
|
|
|
|
if Sender.ClassName <> 'TLabel' then
|
|
|
|
TControl(Sender).Color := clWindow;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.CtrlShowPopup(Sender: TObject);
|
|
|
|
// Use the control's Hint property to populate the popup text
|
|
|
|
begin
|
|
|
|
if not bShowPopupHints then
|
|
|
|
exit;
|
|
|
|
MyPopup.Text := '';
|
|
|
|
MyPopup.Title := '';
|
2016-12-04 18:31:18 +00:00
|
|
|
if (Sender.InheritsFrom(TControl) = False) then
|
|
|
|
exit;
|
2016-12-04 15:13:38 +00:00
|
|
|
|
|
|
|
myPopup.Text := TControl(Sender).Hint;
|
|
|
|
if (MyPopup.Text <> '') then
|
|
|
|
begin
|
|
|
|
mypopup.Title := rsHelpAndInfor;
|
|
|
|
mypopup.Text := mypopup.Text;
|
2016-12-04 18:31:18 +00:00
|
|
|
if bIsVirgin then
|
|
|
|
mypopup.Text := mypopup.Text + LineEnding + rsTurnHintsOff;
|
2016-12-04 15:13:38 +00:00
|
|
|
mypopup.showatpos(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.CtrlSetUpPopupHandlers;
|
|
|
|
// Use different handlers for some controls
|
|
|
|
var
|
2016-12-09 08:59:02 +00:00
|
|
|
iCount,jCount: integer;
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
with frmMain do
|
|
|
|
begin
|
|
|
|
for iCount := 0 to Pred(ControlCount) do
|
|
|
|
begin
|
2016-12-04 18:31:18 +00:00
|
|
|
if (Controls[iCount].InheritsFrom(TControl) = False) then
|
|
|
|
continue;
|
2016-12-09 08:59:02 +00:00
|
|
|
if (Controls[iCount] is TGroupBox) then
|
|
|
|
// Iterate through the children of GroupBox
|
|
|
|
for jCount := 0 to Pred(TGroupBox(Controls[iCount]).ControlCount) do
|
|
|
|
Begin
|
|
|
|
if TGroupBox(Controls[iCount]).Controls[jCount] is TSpinEdit then
|
|
|
|
begin
|
|
|
|
TSpinEdit(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TSpinEdit(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TSpinEdit(TGroupBox(Controls[iCount]).Controls[jCount]).OnClick := @CtrlHidePopup;
|
|
|
|
TSpinEdit(TGroupBox(Controls[iCount]).Controls[jCount]).OnChange := @CtrlMakeDirty;
|
|
|
|
end;
|
|
|
|
if TGroupBox(Controls[iCount]).Controls[jCount] is TCheckBox then
|
|
|
|
begin
|
|
|
|
TCheckBox(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TCheckBox(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TCheckBox(TGroupBox(Controls[iCount]).Controls[jCount]).OnClick := @CtrlHidePopup;
|
|
|
|
TCheckBox(TGroupBox(Controls[iCount]).Controls[jCount]).OnEditingDone := @CtrlMakeDirty;
|
|
|
|
end;
|
|
|
|
if TGroupBox(Controls[iCount]).Controls[jCount] is TLabel then
|
|
|
|
begin
|
|
|
|
TLabel(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TLabel(TGroupBox(Controls[iCount]).Controls[jCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TLabel(TGroupBox(Controls[iCount]).Controls[jCount]).OnClick := @CtrlHidePopup;
|
|
|
|
end;
|
|
|
|
end;
|
2016-12-04 15:13:38 +00:00
|
|
|
if (Controls[iCount] is TEdit) then
|
|
|
|
begin
|
|
|
|
TEdit(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TEdit(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TEdit(Controls[iCount]).OnClick := @CtrlHidePopup;
|
|
|
|
TEdit(Controls[iCount]).OnEditingDone := @CtrlMakeDirty;
|
|
|
|
end;
|
|
|
|
if (Controls[iCount] is TStringGrid) then
|
|
|
|
begin
|
|
|
|
TStringGrid(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TStringGrid(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TStringGrid(Controls[iCount]).OnClick := @CtrlHidePopup;
|
|
|
|
TStringGrid(Controls[iCount]).OnEditingDone := @CtrlMakeDirty;
|
|
|
|
end;
|
|
|
|
if (Controls[iCount] is TLabel) then
|
|
|
|
begin
|
|
|
|
TLabel(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TLabel(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
TLabel(Controls[iCount]).OnClick := @CtrlHidePopup;
|
|
|
|
end;
|
|
|
|
if (Controls[iCount] is TButton) then
|
|
|
|
begin
|
|
|
|
TButton(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TButton(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
end;
|
|
|
|
if (Controls[iCount] is TSpeedButton) then
|
|
|
|
begin
|
|
|
|
TSpeedButton(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TSpeedButton(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
end;
|
|
|
|
if (Controls[iCount] is TBitBtn) then
|
|
|
|
begin
|
|
|
|
TBitBtn(Controls[iCount]).OnMouseEnter := @CtrlShowPopup;
|
|
|
|
TBitBtn(Controls[iCount]).OnMouseLeave := @CtrlHidePopup;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2016-12-04 18:31:18 +00:00
|
|
|
function TfrmMain.FoundADuplicateLPK: boolean;
|
2016-12-09 10:13:04 +00:00
|
|
|
// Add lpk entries one-by-one to a temp stringlist looking for a duplicate
|
2016-12-04 18:31:18 +00:00
|
|
|
var
|
|
|
|
TempStringList: TStrings;
|
|
|
|
iCount: integer;
|
2016-12-04 17:48:43 +00:00
|
|
|
begin
|
2016-12-04 18:31:18 +00:00
|
|
|
Result := False;
|
|
|
|
TempStringList := TStringList.Create;
|
|
|
|
try
|
|
|
|
for iCount := 0 to Pred(stringPackageFiles.RowCount) do
|
|
|
|
begin
|
|
|
|
if TempStringlist.IndexOf(stringPackageFiles.Cells[0, iCount]) = -1 then
|
|
|
|
TempStringList.Add(stringPackageFiles.Cells[0, iCount])
|
|
|
|
else
|
|
|
|
Result := True;
|
|
|
|
end;
|
2016-12-04 17:48:43 +00:00
|
|
|
finally
|
|
|
|
TempStringList.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-12-04 15:13:38 +00:00
|
|
|
procedure TfrmMain.btnAddClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
stringPackageFiles.RowCount := stringPackageFiles.RowCount + 1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.btnRemoveClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if stringPackageFiles.RowCount > 1 then
|
|
|
|
stringPackageFiles.RowCount := stringPackageFiles.RowCount - 1;
|
|
|
|
end;
|
|
|
|
|
2016-12-06 11:02:40 +00:00
|
|
|
procedure TfrmMain.cbForceNotifyMouseUp(Sender: TObject; Button: TMouseButton;
|
2016-12-04 15:13:38 +00:00
|
|
|
Shift: TShiftState; X, Y: integer);
|
|
|
|
var
|
|
|
|
s: string;
|
|
|
|
begin
|
|
|
|
if bDisableWarnings then
|
|
|
|
exit;
|
2016-12-06 11:02:40 +00:00
|
|
|
if cbForceNotify.Checked then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
s := rsThisOptionSh;
|
|
|
|
if MessageDlg(s, mtConfirmation, [mbOK, mbAbort], 0, mbAbort) = mrAbort then
|
2016-12-09 08:59:02 +00:00
|
|
|
cbForceNotify.Checked := False
|
|
|
|
else
|
|
|
|
If Spin_InternalVersion.Value = 0 then Spin_InternalVersion.Value :=1;
|
|
|
|
end
|
|
|
|
else Spin_InternalVersion.Value :=0;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
|
|
begin
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
|
|
begin
|
|
|
|
CanClose := True;
|
2016-12-07 11:27:22 +00:00
|
|
|
if ((bDirty = True) and (bDisableWarnings = False)) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
if MessageDlg(rsFileMayBeUns, mtConfirmation, [mbYes, mbNo], 0, mbNo) = mrNo then
|
|
|
|
CanClose := False;
|
2016-12-05 15:25:48 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
CFG.WriteBool('Options', 'Virgin', False);
|
|
|
|
CFG.WriteBool('Options', 'DiableWarnings', bDisableWarnings);
|
|
|
|
CFG.UpdateFile;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
end;
|
2016-12-07 11:27:22 +00:00
|
|
|
|
|
|
|
function TfrmMain.CreateUniqueINI(var aCount: integer): boolean;
|
|
|
|
// Recursively loop until correct INI found, or new one created
|
2016-12-05 11:04:45 +00:00
|
|
|
begin
|
2016-12-07 11:27:22 +00:00
|
|
|
Result := False;
|
2016-12-05 11:04:45 +00:00
|
|
|
INIFilePath := GetAppConfigFile(False) + IntToStr(aCount);
|
|
|
|
CFG := TIniFile.Create(INIFilePath);
|
2016-12-07 11:27:22 +00:00
|
|
|
CFG.CacheUpdates := True;
|
2016-12-05 11:04:45 +00:00
|
|
|
if CFG.ReadString('Options', 'AppPath', ProgramDirectory) <> ProgramDirectory then
|
2016-12-04 18:31:18 +00:00
|
|
|
begin
|
2016-12-05 11:04:45 +00:00
|
|
|
FreeAndNil(CFG); // Ditch the old one
|
|
|
|
Inc(aCount);
|
2016-12-07 11:27:22 +00:00
|
|
|
Result := True;
|
2016-12-05 11:04:45 +00:00
|
|
|
CreateUniqueINI(aCount); // Make a new one
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
2016-12-05 11:04:45 +00:00
|
|
|
end;
|
2016-12-04 15:13:38 +00:00
|
|
|
|
2016-12-05 11:04:45 +00:00
|
|
|
procedure TfrmMain.FormCreate(Sender: TObject);
|
|
|
|
var
|
|
|
|
sLang: string;
|
2016-12-07 11:27:22 +00:00
|
|
|
iIniCount: integer;
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-07 09:47:36 +00:00
|
|
|
{
|
2016-12-04 15:13:38 +00:00
|
|
|
Self.AutoAdjustLayout(lapAutoAdjustForDPI, Self.DesignTimeDPI,
|
|
|
|
Screen.PixelsPerInch, Self.Width, ScaleX(Self.Width, Self.DesignTimeDPI));
|
2016-12-07 09:47:36 +00:00
|
|
|
}
|
2016-12-04 15:13:38 +00:00
|
|
|
// Enable AutoSize again to get correct Height
|
|
|
|
editName.AutoSize := True;
|
2016-12-05 08:41:51 +00:00
|
|
|
editDownloadZipURL.AutoSize := True;
|
2016-12-04 15:13:38 +00:00
|
|
|
// Furniture
|
|
|
|
Caption := Application.Title;
|
|
|
|
Icon := Application.Icon;
|
2016-12-05 11:23:20 +00:00
|
|
|
{$IFNDEF IGNOREPICTURE}
|
2016-12-04 15:13:38 +00:00
|
|
|
MyPopup.Icon := TPicture(Application.Icon);
|
2016-12-05 11:23:20 +00:00
|
|
|
{$ENDIF}
|
2016-12-04 15:13:38 +00:00
|
|
|
editname.Text := rsMypackagenam;
|
2016-12-05 08:41:51 +00:00
|
|
|
editDownloadZipURL.Text := rsHttpWwwUpdat;
|
2016-12-04 15:13:38 +00:00
|
|
|
stringPackageFiles.Columns[0].Title.Caption := rsLpkFileName;
|
|
|
|
stringPackageFiles.Columns[1].Title.Caption := rsVersion0000;
|
|
|
|
// Defaults
|
2016-12-05 11:04:45 +00:00
|
|
|
slErrorList := TStringList.Create;
|
2016-12-04 15:13:38 +00:00
|
|
|
bForceSaveAs := True;
|
|
|
|
bShowPopupHints := True;
|
|
|
|
// Encourage the user to maintain an updates folder
|
|
|
|
sUpdateDirectory := ProgramDirectory + 'updates';
|
|
|
|
if not FileExistsUTF8(sUpdateDirectory) then
|
|
|
|
if not ForceDirectoriesUTF8(ProgramDirectory + 'updates') then
|
|
|
|
sUpdateDirectory := ProgramDirectory;
|
|
|
|
// Enable options persistence
|
|
|
|
// If program location is different, create a new CFG file
|
|
|
|
// Because each component's location might be different
|
2016-12-07 11:27:22 +00:00
|
|
|
iIniCount := 0;
|
|
|
|
if CreateUniqueINI(iIniCount) then
|
2016-12-05 11:04:45 +00:00
|
|
|
CFG.WriteString('Options', 'AppPath', ProgramDirectory);
|
|
|
|
CFG.UpdateFile;
|
2016-12-07 11:27:22 +00:00
|
|
|
if C_DEBUGMESSAGES = True then
|
|
|
|
ShowMessageFmt('Inifile=%s, Count=%d', [INIFilePath, iIniCount]);
|
2016-12-04 15:13:38 +00:00
|
|
|
// Pop-up hints (show on first run, then not again unless the user chooses)
|
2016-12-04 18:31:18 +00:00
|
|
|
bIsVirgin := CFG.ReadBool('Options', 'Virgin', True);
|
2016-12-04 15:13:38 +00:00
|
|
|
bShowPopupHints := bIsVirgin;
|
|
|
|
mnu_helpShowHints.Checked := bShowPopupHints;
|
|
|
|
// Override here if the user has re-enabled them
|
|
|
|
bShowPopupHints := CFG.ReadBool('Options', 'ShowPopupHints', bShowPopupHints);
|
|
|
|
mnu_helpShowHints.Checked := bShowPopupHints;
|
|
|
|
bDisableWarnings := CFG.ReadBool('Options', 'DiableWarnings', False);
|
|
|
|
mnu_helpDisableWarnings.Checked := bDisableWarnings;
|
|
|
|
CtrlSetUpPopupHandlers; // Set the Hint property of various controls to show a Popup
|
|
|
|
// Language translation
|
|
|
|
sLang := CFG.ReadString('Options', 'Language', 'en'); // First default is English
|
|
|
|
SetDefaultLang(sLang, 'locale', True);
|
|
|
|
// Add more translations here
|
|
|
|
if sLang = 'en' then
|
|
|
|
mnu_lang_en.Checked := True;
|
|
|
|
if sLang = 'es' then
|
|
|
|
mnu_lang_es.Checked := True;
|
|
|
|
|
|
|
|
bDirty := False; // No effect :(
|
|
|
|
end;
|
|
|
|
|
2016-12-05 15:33:48 +00:00
|
|
|
procedure TfrmMain.FormDestroy(Sender: TObject);
|
|
|
|
begin
|
2016-12-07 11:27:22 +00:00
|
|
|
CFG.Free;
|
|
|
|
slErrorList.Free;
|
2016-12-05 15:33:48 +00:00
|
|
|
end;
|
|
|
|
|
2016-12-04 15:13:38 +00:00
|
|
|
procedure TfrmMain.FormShow(Sender: TObject);
|
|
|
|
begin
|
|
|
|
bDirty := False;
|
|
|
|
end;
|
|
|
|
|
2016-12-09 08:59:02 +00:00
|
|
|
procedure TfrmMain.lbl_InternalVersionClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
2016-12-04 15:13:38 +00:00
|
|
|
procedure TfrmMain.LoadItemClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
FileOpen1.Dialog.InitialDir :=
|
|
|
|
CFG.ReadString('Options', 'LastLoadedJSONPath', sUpdateDirectory);
|
|
|
|
FileOpen1.Dialog.Filter := 'JSON|*.json';
|
|
|
|
if FileOpen1.Dialog.Execute then
|
|
|
|
begin
|
|
|
|
sJSONFilePath := FileOpen1.Dialog.Filename;
|
|
|
|
CFG.WriteString('Options', 'LastLoadedJSONPath', ExtractFileDir(sJSONFilePath));
|
2016-12-05 14:22:18 +00:00
|
|
|
JSONPackage := TUpdatePackage.Create;
|
2016-12-04 18:31:18 +00:00
|
|
|
try
|
|
|
|
if JSONPackage.LoadFromFile(FileOpen1.Dialog.FileName) then
|
2016-12-04 18:05:35 +00:00
|
|
|
begin
|
2016-12-05 14:22:18 +00:00
|
|
|
editName.Text := JSONPackage.UpdatePackageData.Name;
|
|
|
|
editDownloadZipURL.Text := JSONPackage.UpdatePackageData.DownloadZipURL;
|
2016-12-06 11:02:40 +00:00
|
|
|
cbForceNotify.Checked := JSONPackage.UpdatePackageData.ForceNotify;
|
2016-12-09 08:59:02 +00:00
|
|
|
Spin_InternalVersion.Value:=JSONPackage.UpdatePackageData.InternalVersion;
|
2016-12-05 14:22:18 +00:00
|
|
|
stringPackageFiles.RowCount := JSONPackage.UpdatePackageFiles.Count + 1;
|
|
|
|
for i := 0 to JSONPackage.UpdatePackageFiles.Count - 1 do
|
2016-12-04 18:31:18 +00:00
|
|
|
begin
|
2016-12-07 11:27:22 +00:00
|
|
|
stringPackageFiles.Cells[0, i + 1] :=
|
|
|
|
JSONPackage.UpdatePackageFiles.Items[i].Name;
|
|
|
|
stringPackageFiles.Cells[1, i + 1] :=
|
|
|
|
JSONPackage.UpdatePackageFiles.Items[i].Version;
|
|
|
|
end;
|
|
|
|
if ValidationFailed then
|
|
|
|
begin
|
|
|
|
if (slErrorList.Count > 1) then
|
|
|
|
ShowMessage(Format(rsUpdateJsonSF, [ExtractFileName(sJSONFilePath)]) +
|
|
|
|
LineEnding + LineEnding + rsOneOfTheReqn + LineEnding +
|
|
|
|
slErrorList.Text + LineEnding + rsFixThenTryAg)
|
|
|
|
else
|
|
|
|
ShowMessage(Format(rsUpdateJsonSF, [ExtractFileName(sJSONFilePath)]) +
|
|
|
|
LineEnding + LineEnding + rsOneOfTheReq1 + LineEnding +
|
|
|
|
slErrorList.Text + LineEnding + rsFixThenTryAg);
|
|
|
|
Exit;
|
2016-12-04 18:31:18 +00:00
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
ShowMessageFmt('There was a problem loading "%s" - is it corrupted or in the wrong format?',
|
|
|
|
[ExtractFilename(FileOpen1.Dialog.FileName)]);
|
2016-12-04 18:05:35 +00:00
|
|
|
finally
|
2016-12-04 18:31:18 +00:00
|
|
|
JSONPackage.Free;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_fileNewClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
editname.Text := rsMypackagenam;
|
2016-12-05 08:41:51 +00:00
|
|
|
editDownloadZipURL.Text := rsHttpWwwUpdat;
|
2016-12-06 11:02:40 +00:00
|
|
|
cbForceNotify.Checked := False;
|
2016-12-04 18:31:18 +00:00
|
|
|
stringPackageFiles.RowCount := 1;
|
|
|
|
sJSONFilePath := '';
|
|
|
|
sZipDirectory := '';
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_fileSaveClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
bForceSaveAs := False;
|
|
|
|
SaveAsItem.Click;
|
|
|
|
bForceSaveAs := True;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_helpAboutClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
s: string;
|
|
|
|
Quad: TVersionQuad;
|
|
|
|
VInfo: TFileVersionInfo;
|
|
|
|
EqualsPos: integer;
|
|
|
|
begin
|
|
|
|
s := Application.Title + LineEnding;
|
|
|
|
if GetProgramVersion(Quad) then
|
|
|
|
s += 'Version: ' + VersionQuadToStr(Quad) + LineEnding;
|
|
|
|
Vinfo := TFileVersionInfo.Create(Application);
|
|
|
|
try
|
|
|
|
Vinfo.Filter.Add('LegalCopyright'); // Set In Project/Options/Version Info
|
|
|
|
Vinfo.Filter.Add('FileDescription'); // Set In Project/Options/Version Info
|
|
|
|
Vinfo.ReadFileInfo;
|
|
|
|
if VInfo.VersionStrings.Count > 0 then
|
|
|
|
begin
|
|
|
|
EqualsPos := Pos('=', VInfo.VersionStrings[1]); // Copyright
|
|
|
|
if (EqualsPos > 0) then
|
|
|
|
s += RightStr(VInfo.VersionStrings[1], Length(VInfo.VersionStrings[1]) -
|
|
|
|
EqualsPos) + LineEnding;
|
|
|
|
end;
|
|
|
|
s+=Format(rsCompiledWith2,
|
|
|
|
[{$I %FPCVERSION%},lcl_major,lcl_minor,LineEnding,{$I %FPCTARGETCPU%},{$I %FPCTARGETOS%},LineEnding,LineEnding]);
|
|
|
|
if VInfo.VersionStrings.Count > 1 then
|
|
|
|
begin
|
|
|
|
EqualsPos := Pos('=', VInfo.VersionStrings[0]); // File Deswcription
|
|
|
|
if (EqualsPos > 0) then
|
|
|
|
s += RightStr(VInfo.VersionStrings[0], Length(VInfo.VersionStrings[0]) -
|
|
|
|
EqualsPos) + LineEnding;
|
|
|
|
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
Vinfo.Free;
|
|
|
|
end;
|
|
|
|
MessageDlg(rsAbout + ' ' + Application.Title, s, mtInformation, [mbOK], 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_helpDisableWarningsClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
bDisableWarnings := not bDisableWarnings;
|
|
|
|
mnu_helpDisableWarnings.Checked := bDisableWarnings;
|
|
|
|
CFG.WriteBool('Options', 'DiableWarnings', bDisableWarnings);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_helpShowHintsClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
bShowPopupHints := mnu_helpShowHints.Checked;
|
|
|
|
CFG.WriteBool('Options', 'ShowPopupHints', bShowPopupHints);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_lang_enClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
SetDefaultLang('en', 'locale', True);
|
|
|
|
if Length(GetDefaultLang) > 0 then
|
|
|
|
begin
|
|
|
|
ShowMessageFmt(rsLanguageChan, [GetDefaultLang]);
|
|
|
|
CFG.WriteString('Options', 'Language', GetDefaultLang);
|
|
|
|
mnu_lang_en.Checked := True;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
mnu_lang_en.Checked := False;
|
2016-12-07 11:27:22 +00:00
|
|
|
// SetDefaultLang(''); // Back to default?
|
2016-12-04 15:13:38 +00:00
|
|
|
ShowMessage(rsSorryThisLan + LineEnding + rsYouMayNeedTo);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.mnu_lang_esClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
SetDefaultLang('es', 'locale', True);
|
|
|
|
if Length(GetDefaultLang) > 0 then
|
|
|
|
begin
|
|
|
|
ShowMessageFmt(rsLanguageChan, [GetDefaultLang]);
|
|
|
|
CFG.WriteString('Options', 'Language', GetDefaultLang);
|
|
|
|
mnu_lang_es.Checked := True;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
mnu_lang_es.Checked := False;
|
2016-12-07 09:47:36 +00:00
|
|
|
SetDefaultLang(''); // Back to DefaultTranslator
|
2016-12-04 15:13:38 +00:00
|
|
|
ShowMessage(rsSorryThisLan);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TfrmMain.ValidationFailed: boolean;
|
|
|
|
// Add checks as needed here
|
|
|
|
var
|
|
|
|
iCount: integer;
|
|
|
|
Quad: TVersionQuad; // fileinfo unit
|
|
|
|
begin
|
|
|
|
Result := False;
|
|
|
|
// Check Zipname and URL http:// length
|
|
|
|
if (Length(editName.Text) < 5) then
|
|
|
|
begin
|
|
|
|
editName.Color := clYellow;
|
|
|
|
slErrorList.Add(rsUpdateZipNam);
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
// URL implausable?
|
2016-12-05 08:41:51 +00:00
|
|
|
if (Length(editDownloadZipURL.Text) < 10) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-05 08:41:51 +00:00
|
|
|
slErrorList.Add(rsDownloadZipURLI);
|
|
|
|
editDownloadZipURL.Color := clYellow;
|
2016-12-04 15:13:38 +00:00
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
// No lpk file?
|
|
|
|
if (stringPackageFiles.RowCount = 1) then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(rsThereAreNoLp);
|
|
|
|
stringPackageFiles.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
// Remembered to type 'zip'?
|
|
|
|
if (Length(editName.Text) > 4) then
|
|
|
|
if (RightStr(LowerCase(editName.Text), 4) <> '.zip') then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(rsUpdateZipNam2);
|
|
|
|
editName.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
// A full URL?
|
2016-12-07 11:27:22 +00:00
|
|
|
if ((Length(editDownloadZipURL.Text) > 0) and
|
|
|
|
(RightStr(editDownloadZipURL.Text, 1) = '/')) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-05 08:41:51 +00:00
|
|
|
slErrorList.Add(rsDownloadZipURLI2);
|
|
|
|
editDownloadZipURL.Color := clYellow;
|
2016-12-04 15:13:38 +00:00
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
|
2016-12-05 08:41:51 +00:00
|
|
|
if ((Length(editDownloadZipURL.Text) > 4) and
|
|
|
|
(LeftStr(LowerCase(editDownloadZipURL.Text), 4) <> 'http')) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-05 08:41:51 +00:00
|
|
|
slErrorList.Add(rsDownloadZipURLS);
|
|
|
|
editDownloadZipURL.Color := clYellow;
|
2016-12-04 15:13:38 +00:00
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
|
2016-12-05 08:41:51 +00:00
|
|
|
if (Pos(Lowercase(editName.Text), Lowercase(editDownloadZipURL.Text)) = 0) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-05 08:41:51 +00:00
|
|
|
slErrorList.Add(rsDownloadZipURLD);
|
|
|
|
editDownloadZipURL.Color := clYellow;
|
2016-12-04 15:13:38 +00:00
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Check package files entries
|
|
|
|
if (stringPackageFiles.RowCount > 1) then
|
|
|
|
for iCount := 1 to stringPackageFiles.RowCount - 1 do
|
|
|
|
begin
|
|
|
|
if (Length(stringPackageFiles.Cells[0, iCount]) = 0) then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(Format(rsTheLpkEntryD2, [iCount]));
|
|
|
|
stringPackageFiles.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
if (Length(stringPackageFiles.Cells[1, iCount]) = 0) then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(Format(rsVersionEntry, [iCount]));
|
|
|
|
stringPackageFiles.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
if (TryStrToVersionQuad(stringPackageFiles.Cells[1, iCount], Quad) = False) then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(Format(rsVersionEntry2, [iCount]));
|
|
|
|
stringPackageFiles.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
if (RightStr(LowerCase(stringPackageFiles.Cells[0, iCount]), 4) <> '.lpk') then
|
|
|
|
begin
|
|
|
|
slErrorList.Add(Format(rsTheLpkEntryD, [iCount]));
|
|
|
|
stringPackageFiles.Color := clYellow;
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
end;
|
2016-12-04 18:31:18 +00:00
|
|
|
|
|
|
|
// Check for duplicate .lpk entries
|
|
|
|
if FoundADuplicateLPK then
|
2016-12-04 17:48:43 +00:00
|
|
|
begin
|
|
|
|
stringPackageFiles.Color := clYellow;
|
2016-12-04 18:31:18 +00:00
|
|
|
slErrorList.Add(Format(rsThereAreOneO, [LineEnding]));
|
2016-12-04 17:48:43 +00:00
|
|
|
Result := True;
|
|
|
|
end;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.SaveAsItemClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
if ValidationFailed then
|
|
|
|
begin
|
|
|
|
if (slErrorList.Count > 1) then
|
|
|
|
ShowMessage(rsOneOfTheReqn + LineEnding + slErrorList.Text +
|
|
|
|
LineEnding + rsFixThenTryAg)
|
|
|
|
else
|
|
|
|
ShowMessage(rsOneOfTheReq1 + LineEnding + slErrorList.Text +
|
|
|
|
LineEnding + rsFixThenTryAg);
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
if bForceSaveAs or (sJSONFilePath = '') then
|
|
|
|
begin
|
|
|
|
FileSaveAs1.Dialog.InitialDir := sUpdateDirectory;
|
2016-12-07 11:27:22 +00:00
|
|
|
FileSaveAs1.Dialog.FileName :=
|
|
|
|
'update_' + ExtractFilenameOnly(editName.Text) + '.json';
|
2016-12-04 15:13:38 +00:00
|
|
|
if FileSaveAs1.Dialog.Execute then
|
|
|
|
sJSONFilePath := FileSaveAs1.Dialog.FileName
|
|
|
|
else
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
JSONPackage := TUpdatePackage.Create;
|
2016-12-04 15:13:38 +00:00
|
|
|
try
|
2016-12-05 14:22:18 +00:00
|
|
|
JSONPackage.UpdatePackageData.Name := editName.Text;
|
|
|
|
JSONPackage.UpdatePackageData.DownloadZipURL := editDownloadZipURL.Text;
|
2016-12-06 11:02:40 +00:00
|
|
|
JSONPackage.UpdatePackageData.ForceNotify := cbForceNotify.Checked;
|
2016-12-09 08:59:02 +00:00
|
|
|
JSONPackage.UpdatePackageData.InternalVersion:=Spin_InternalVersion.Value;
|
2016-12-04 15:13:38 +00:00
|
|
|
|
|
|
|
for i := 1 to stringPackageFiles.RowCount - 1 do
|
|
|
|
begin
|
2016-12-05 14:22:18 +00:00
|
|
|
with JSONPackage.UpdatePackageFiles.Add do
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
Name := stringPackageFiles.Cells[0, i];
|
|
|
|
Version := stringPackageFiles.Cells[1, i];
|
|
|
|
end;
|
|
|
|
end;
|
2016-12-04 18:31:18 +00:00
|
|
|
if FileExistsUTF8(sJSONFilePath) and (bDisableWarnings = False) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
if MessageDlg(rsOverwrite + ' ' + sJSONFilePath + '?', mtConfirmation,
|
|
|
|
[mbYes, mbNo], 0, mbYes) = mrYes then
|
|
|
|
if JSONPackage.SaveToFile(sJSONFilePath) then
|
|
|
|
ShowMessage(sJSONFilePath + ' ' + rsSavedOK);
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if JSONPackage.SaveToFile(sJSONFilePath) then
|
2016-12-04 18:05:35 +00:00
|
|
|
ShowMessage(sJSONFilePath + rsSavedOK)
|
|
|
|
else
|
|
|
|
ShowMessage(rsSaveUnsucces);
|
2016-12-04 15:13:38 +00:00
|
|
|
bDirty := False;
|
|
|
|
finally
|
|
|
|
JSONPackage.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.sb_editNameClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
s: string;
|
|
|
|
begin
|
|
|
|
FileOpen1.Dialog.InitialDir :=
|
|
|
|
CFG.ReadString('Options', 'LastLoadedZipPath', sZipDirectory);
|
|
|
|
FileOpen1.Dialog.Filter := rsUpdate + ' ZIP|*.zip';
|
|
|
|
if FileOpen1.Dialog.Execute then
|
|
|
|
begin
|
|
|
|
// Offer to copy to /updates?
|
|
|
|
sZipDirectory := ExtractFileDir(FileOpen1.Dialog.Filename);
|
|
|
|
CFG.WriteString('Options', 'LastLoadedZipPath', sZipDirectory);
|
|
|
|
s := ExtractFileName(FileOpen1.Dialog.Filename);
|
|
|
|
editName.Text := s;
|
|
|
|
if MessageDlg(Format(rsWouldYouLike, [s, sUpdateDirectory]),
|
|
|
|
mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
|
|
|
|
begin
|
|
|
|
if CopyFile(FileOpen1.Dialog.Filename, sUpdateDirectory +
|
|
|
|
DirectorySeparator + s) then
|
|
|
|
ShowMessageFmt(rsSWasSuccessf, [s, sUpdateDirectory])
|
|
|
|
else
|
|
|
|
ShowMessage(rsSorryCopyOpe);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmMain.spd_CheckURLClick(Sender: TObject);
|
|
|
|
// Show a popup notification because it takes time to open a browser window
|
|
|
|
var
|
|
|
|
bTemp: boolean;
|
|
|
|
begin
|
2016-12-05 08:41:51 +00:00
|
|
|
if OpenURL(editDownloadZipURL.Text) then
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
|
|
|
bTemp := bShowPopupHints;
|
|
|
|
bShowPopupHints := True;
|
|
|
|
CtrlShowPopup(spd_CheckURL);
|
|
|
|
bShowPopupHints := bTemp;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TPackage }
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
constructor TUpdatePackage.Create;
|
2016-12-04 15:13:38 +00:00
|
|
|
begin
|
2016-12-05 14:22:18 +00:00
|
|
|
FUpdatePackageData := TUpdatePackageData.Create;
|
|
|
|
FUpdatePackageFiles := TPackageFilesList.Create;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
destructor TUpdatePackage.Destroy;
|
2016-12-04 15:13:38 +00:00
|
|
|
var
|
|
|
|
c: TCollectionItem;
|
|
|
|
begin
|
2016-12-05 14:22:18 +00:00
|
|
|
FUpdatePackageData.Free;
|
|
|
|
for c in FUpdatePackageFiles do
|
2016-12-04 15:13:38 +00:00
|
|
|
c.Free;
|
2016-12-05 14:22:18 +00:00
|
|
|
FUpdatePackageFiles.Free;
|
2016-12-04 15:13:38 +00:00
|
|
|
inherited Destroy;
|
|
|
|
end;
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
function TUpdatePackage.LoadFromFile(AFileName: string): boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
var
|
|
|
|
DeStreamer: TJSONDeStreamer;
|
|
|
|
s: TStringList;
|
|
|
|
begin
|
2016-12-04 18:31:18 +00:00
|
|
|
Result := True;
|
2016-12-04 15:13:38 +00:00
|
|
|
s := TStringList.Create;
|
2016-12-04 18:31:18 +00:00
|
|
|
try
|
|
|
|
s.LoadFromFile(AFileName);
|
|
|
|
DeStreamer := TJSONDeStreamer.Create(nil);
|
|
|
|
try
|
|
|
|
DeStreamer.JSONToObject(s.Text, Self);
|
|
|
|
except
|
|
|
|
// Eat the exception
|
|
|
|
On E: Exception do
|
|
|
|
Result := False;
|
|
|
|
end;
|
|
|
|
finally
|
2016-12-04 17:48:43 +00:00
|
|
|
DeStreamer.Free;
|
|
|
|
s.Free;
|
|
|
|
end;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
|
2016-12-05 14:22:18 +00:00
|
|
|
function TUpdatePackage.SaveToFile(AFileName: string): boolean;
|
2016-12-04 15:13:38 +00:00
|
|
|
var
|
|
|
|
Streamer: TJSONStreamer;
|
|
|
|
s: TStringList;
|
|
|
|
begin
|
2016-12-04 18:31:18 +00:00
|
|
|
Result := True;
|
2016-12-04 15:13:38 +00:00
|
|
|
s := TStringList.Create;
|
|
|
|
try
|
|
|
|
Streamer := TJSONStreamer.Create(nil);
|
|
|
|
Streamer.Options := Streamer.Options + [jsoUseFormatString];
|
|
|
|
s.AddText(Streamer.ObjectToJSONString(Self));
|
|
|
|
try
|
|
|
|
s.SaveToFile(AFileName);
|
|
|
|
except
|
2016-12-04 18:31:18 +00:00
|
|
|
// Eat the exception
|
|
|
|
On E: Exception do
|
|
|
|
Result := False;
|
2016-12-04 15:13:38 +00:00
|
|
|
end;
|
|
|
|
finally
|
|
|
|
Streamer.Free;
|
|
|
|
s.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-12-07 09:47:36 +00:00
|
|
|
// Use embedded .po resources if not distributed with executable
|
2016-12-07 11:27:22 +00:00
|
|
|
initialization
|
2016-12-07 15:04:47 +00:00
|
|
|
{$IFDEF PO_BUILTINRES}
|
|
|
|
sPoPath_en := ProgramDirectory + 'locale' + PathDelim + ExtractFilenameOnly(
|
2016-12-07 11:27:22 +00:00
|
|
|
Application.EXEName) + '.en.po';
|
2016-12-07 15:04:47 +00:00
|
|
|
sPoPath_es := ProgramDirectory + 'locale' + PathDelim + ExtractFilenameOnly(
|
2016-12-07 11:27:22 +00:00
|
|
|
Application.EXEName) + '.es.po';
|
|
|
|
if (lcl_major > 0) and (lcl_minor > 6) then
|
2016-12-07 09:47:36 +00:00
|
|
|
begin
|
2016-12-07 11:27:22 +00:00
|
|
|
// This uses a resource file added via Project/Options
|
|
|
|
if not FileExistsUTF8(sPoPath_en) then
|
|
|
|
begin
|
|
|
|
// create a resource stream which points to the po file
|
|
|
|
S := TResourceStream.Create(HInstance, 'JSONEDITOR.EN', MakeIntResource(10));
|
|
|
|
try
|
|
|
|
ForceDirectory(ProgramDirectory + 'locale');
|
|
|
|
F := TFileStream.Create(sPoPath_en, fmCreate);
|
|
|
|
try
|
|
|
|
F.CopyFrom(S, S.Size); // copy data from the resource stream to file stream
|
|
|
|
finally
|
|
|
|
F.Free; // destroy the file stream
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
S.Free; // destroy the resource stream
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if not FileExistsUTF8(sPoPath_es) then
|
|
|
|
begin
|
|
|
|
S := TResourceStream.Create(HInstance, 'JSONEDITOR.ES', MakeIntResource(10));
|
|
|
|
try
|
|
|
|
ForceDirectory(ProgramDirectory + 'locale');
|
|
|
|
F := TFileStream.Create(sPoPath_es, fmCreate);
|
|
|
|
try
|
|
|
|
F.CopyFrom(S, S.Size);
|
|
|
|
finally
|
|
|
|
F.Free
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
S.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin // Older version of laz
|
|
|
|
// This uses an lrs file generated from lazres
|
|
|
|
{$I translate.lrs}
|
|
|
|
if not FileExistsUTF8(sPoPath_es) then
|
|
|
|
begin
|
|
|
|
aLRes := LazarusResources.Find('jsoneditor.es');
|
|
|
|
if assigned(aLRes) then
|
|
|
|
begin
|
|
|
|
ForceDirectory(ProgramDirectory + 'locale');
|
|
|
|
aSS := TStringListUTF8.Create;
|
|
|
|
try
|
|
|
|
Ass.Add(aLRes.Value);
|
|
|
|
aSS.SaveToFile(sPoPath_es);
|
|
|
|
finally
|
|
|
|
aSS.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if not FileExistsUTF8(sPoPath_en) then
|
|
|
|
begin
|
|
|
|
aLRes := LazarusResources.Find('jsoneditor.en');
|
|
|
|
if assigned(aLRes) then
|
|
|
|
begin
|
|
|
|
ForceDirectory(ProgramDirectory + 'locale');
|
|
|
|
aSS := TStringListUTF8.Create;
|
|
|
|
try
|
|
|
|
Ass.Add(aLRes.Value);
|
|
|
|
aSS.SaveToFile(sPoPath_en);
|
|
|
|
finally
|
|
|
|
aSS.Free;
|
|
|
|
end;
|
|
|
|
end;
|
2016-12-07 09:47:36 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{$ENDIF}
|
2016-12-04 15:13:38 +00:00
|
|
|
end.
|