mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-16 19:07:33 +00:00
295 lines
7.2 KiB
ObjectPascal
295 lines
7.2 KiB
ObjectPascal
(*
|
|
Name: Keyman.Developer.UI.Project.ProjectFileUI
|
|
Copyright: Copyright (C) SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 4 May 2015
|
|
|
|
Modified Date: 27 May 2015
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 04 May 2015 - mcdurdin - I4687 - V9.0 - Split project UI actions into separate classes
|
|
04 May 2015 - mcdurdin - I4694 - V9.0 - Split UI actions from non-UI actions in projects
|
|
05 May 2015 - mcdurdin - I4698 - V9.0 - Split project and user preferences files
|
|
11 May 2015 - mcdurdin - I4706 - V9.0 - Update compile logging for silent and warning-as-error cleanness
|
|
27 May 2015 - mcdurdin - I4703 - Loading a non-project file as a project crashes Developer [CrashID:tike.exe_9.0.497.0_00813E09_EProjectLoader]
|
|
27 May 2015 - mcdurdin - I4654 - Project display crashes if project render output file is locked [CrashID:tike.exe_9.0.489.0_0045876A_EFCreateError]
|
|
|
|
*)
|
|
unit Keyman.Developer.UI.Project.ProjectFileUI; // I4687
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Classes,
|
|
VCL.Menus,
|
|
Keyman.Developer.System.Project.ProjectFile,
|
|
Keyman.Developer.System.Project.ProjectLog,
|
|
TempFileManager;
|
|
|
|
type
|
|
TProjectFileAction = (pfaCompile, pfaInstall, pfaUninstall, pfaDebug, pfaPackage, pfaEncrypt,
|
|
pfaTestKeymanWeb, pfaCompileInstaller, pfaFontHelper, pfaFontDialog, pfaClean); // I4057
|
|
|
|
TProjectUI = class(TProject)
|
|
private
|
|
FRenderFileName: TTempFile;
|
|
function GetRenderFileName: string;
|
|
procedure Refresh;
|
|
|
|
protected
|
|
procedure DoRefresh; override;
|
|
procedure DoRefreshCaption; override;
|
|
|
|
public
|
|
constructor Create(AProjectType: TProjectType; AFileName: string; ALoadPersistedUntitledProject: Boolean = False); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure Log(AState: TProjectLogState; Filename, Msg: string); override; // I4706
|
|
|
|
function DoAction(action: TProjectFileAction; FSilent: Boolean): Boolean;
|
|
|
|
function DisplayFileName: string;
|
|
function Render: WideString;
|
|
|
|
function Save: Boolean; override; // I4694
|
|
function Load: Boolean; override; // I4694
|
|
|
|
property RenderFileName: string read GetRenderFileName; // I4181
|
|
end;
|
|
|
|
TProjectFileUI = class
|
|
protected
|
|
FOwner: TProjectFile;
|
|
procedure OpenFile; virtual; abstract;
|
|
function WindowOpen: Boolean; virtual;
|
|
public
|
|
constructor Create(AOwner: TProjectFile);
|
|
destructor Destroy; override;
|
|
|
|
function DoAction(action: TProjectFileAction; FSilent: Boolean): Boolean; virtual; abstract;
|
|
|
|
procedure NewFile; virtual; abstract;
|
|
procedure DefaultEvent(Sender: TObject); virtual; abstract;
|
|
end;
|
|
|
|
TProjectFileUIClass = class of TProjectFileUI;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.Win.ComObj,
|
|
Vcl.Dialogs,
|
|
Winapi.msxml,
|
|
Xml.Win.msxmldom,
|
|
Xml.XMLDoc,
|
|
Xml.Xmldom,
|
|
Xml.xmlintf,
|
|
|
|
System.SysUtils,
|
|
|
|
utilhttp,
|
|
|
|
Keyman.Developer.System.Project.Project,
|
|
Keyman.Developer.System.Project.ProjectLoader,
|
|
UfrmMessages;
|
|
|
|
{ MRU functions }
|
|
|
|
function TProjectUI.DoAction(action: TProjectFileAction; FSilent: Boolean): Boolean;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := False;
|
|
for i := 0 to Files.Count - 1 do
|
|
if not (Files[i].UI as TProjectFileUI).DoAction(action, FSilent) then Exit;
|
|
|
|
case action of
|
|
pfaCompile: Log(plsInfo, FileName, 'All files compiled successfully.'); // I4706
|
|
end;
|
|
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TProjectUI.DoRefresh;
|
|
begin
|
|
Refresh;
|
|
end;
|
|
|
|
procedure TProjectUI.DoRefreshCaption;
|
|
begin
|
|
if Assigned(FGlobalProjectRefreshCaption) then
|
|
FGlobalProjectRefreshCaption(Self);
|
|
end;
|
|
|
|
{ TProjectUI }
|
|
|
|
constructor TProjectUI.Create(AProjectType: TProjectType; AFileName: string;
|
|
ALoadPersistedUntitledProject: Boolean);
|
|
begin
|
|
inherited;
|
|
FRenderFileName := TTempFileManager.Get('.html'); // I4181
|
|
end;
|
|
|
|
destructor TProjectUI.Destroy;
|
|
begin
|
|
FreeAndNil(FRenderFileName); // I4181
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TProjectUI.DisplayFileName: string;
|
|
begin
|
|
if Untitled
|
|
then Result := '(untitled project)'
|
|
else Result := ExtractFileName(FileName);
|
|
end;
|
|
|
|
function TProjectUI.Load: Boolean; // I4694
|
|
begin
|
|
try
|
|
Result := inherited Load;
|
|
except
|
|
on E:EOleException do
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Result := False;
|
|
end;
|
|
on E:EProjectLoader do // I4703
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Result := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectUI.Log(AState: TProjectLogState; Filename, Msg: string); // I4706
|
|
begin
|
|
case AState of
|
|
plsInfo: ;
|
|
plsWarning: Msg := 'Warning: '+Msg;
|
|
plsError: Msg := 'Error: '+Msg;
|
|
plsFatal: Msg := 'Error: '+Msg;
|
|
end;
|
|
frmMessages.Add(Filename, Msg);
|
|
end;
|
|
|
|
procedure TProjectUI.Refresh;
|
|
begin
|
|
if State = psReady then
|
|
if Assigned(FGlobalProjectRefresh) then FGlobalProjectRefresh(Self);
|
|
end;
|
|
|
|
function TProjectUI.Render: WideString;
|
|
var
|
|
doc, userdoc, xsl: IXMLDomDocument;
|
|
output: WideString;
|
|
FLastDir: string;
|
|
i: Integer;
|
|
begin
|
|
if not FileExists(SavedFileName) then Save;
|
|
|
|
Result := FRenderFileName.Name; // I4181
|
|
FLastDir := GetCurrentDir;
|
|
SetCurrentDir(StringsTemplatePath);
|
|
try
|
|
doc := MSXMLDOMDocumentFactory.CreateDOMDocument;
|
|
try
|
|
doc.async := False;
|
|
doc.load(SavedFileName);
|
|
|
|
//
|
|
// Inject the user settings to the loaded file
|
|
//
|
|
|
|
if FileExists(SavedUserFileName) then // I4698
|
|
begin
|
|
userdoc := MSXMLDOMDocumentFactory.CreateDOMDocument;
|
|
try
|
|
userdoc.async := False;
|
|
userdoc.load(SavedUserFileName);
|
|
for i := 0 to userdoc.documentElement.childNodes.length - 1 do
|
|
doc.documentElement.appendChild(userdoc.documentElement.childNodes.item[i].cloneNode(true));
|
|
finally
|
|
userdoc := nil;
|
|
end;
|
|
end;
|
|
|
|
xsl := MSXMLDOMDocumentFactory.CreateDOMDocument;
|
|
try
|
|
xsl.async := False;
|
|
xsl.resolveExternals := True;
|
|
xsl.validateOnParse := False;
|
|
xsl.load(StringsTemplatePath + 'project.xsl');
|
|
output := doc.transformNode(xsl);
|
|
finally
|
|
xsl := nil;
|
|
end;
|
|
finally
|
|
doc := nil;
|
|
end;
|
|
finally
|
|
SetCurrentDir(FLastDir);
|
|
end;
|
|
|
|
with TStringList.Create do
|
|
try
|
|
Text := output;
|
|
try
|
|
SaveToFile(Result, TEncoding.UTF8); // I3310
|
|
except
|
|
on E:EFCreateError do // I4654
|
|
begin
|
|
// Try again once, in case of file lock
|
|
FreeAndNil(FRenderFileName);
|
|
FRenderFileName := TTempFileManager.Get('.html');
|
|
Result := FRenderFileName.Name;
|
|
SaveToFile(Result, TEncoding.UTF8); // I3310
|
|
end;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
function TProjectUI.Save: Boolean; // I4694
|
|
begin
|
|
try
|
|
Result := inherited Save;
|
|
except
|
|
on E:EOleException do
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Result := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TProjectUI.GetRenderFileName: string;
|
|
begin
|
|
Result := FRenderFileName.Name; // I4181
|
|
end;
|
|
|
|
{ TProjectFileUI }
|
|
|
|
constructor TProjectFileUI.Create(AOwner: TProjectFile);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
destructor TProjectFileUI.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TProjectFileUI.WindowOpen: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
end.
|