Componentes.Terceros.RemObj.../official/5.0.35.741/Everwood/Source/Delphi/uEWOTAHelpers.pas
2009-02-27 15:16:56 +00:00

415 lines
11 KiB
ObjectPascal

unit uEWOTAHelpers;
{$I Everwood.inc}
interface
uses
{$IFDEF DELPHI5}ComObj,{$ENDIF}
ToolsAPI, Classes;
function GetDelphiVersion: Integer;
function GetDllPath: String;
function ModuleServices: IOTAModuleServices;
function CurrentProject: IOTAProject;
function ProjectByName(const aName: string): IOTAProject;
function CurrentProjectGroup: IOTAProjectGroup;
function GetUniqueProjectFilename(aProject: IOTAProject; aName: string): string;
function FindModuleByUnitName(const aProject: IOTAProject; const aModuleName: string): IOTAModule;
function RemoveInitialT(const aString:string):string;
function AddInitialT(const aString:string):string;
function ProjectName: string;
function LoadStringFromFile(iFilename:string):string;
procedure SaveStringToFile(const iFilename,iString:string);
function ReplaceVariables(const aString: string; aVariables: TStrings): string;
function ReadModuleSource(const aModule: IOTAModule): string;
procedure WriteModuleSource(const aModule: IOTAModule; const aCode, aHeader: string);
procedure AddOrReplaceNamedModule(const aProject: IOTAProject; aName, aCode: string);
function LanguageFromPersonality(aProject: IOTAProject): string;
function LanguageFromPersonalityEx(aProject: IOTAProject): string;
implementation
uses {$IFDEF MSWINDOWS}Windows, ActiveX, {$ENDIF} SysUtils, Forms, uEWHelpers;
function LoadStringFromFile(iFilename:string):string;
{$IFDEF DELPHI2009UP}
begin
With TStringList.Create do try
LoadFromFile(iFilename);
Result := Text;
finally
Free;
end;
end;
{$ELSE}
var t:text;
s:string;
begin
try
AssignFile(t,iFilename);
Reset(t);
try
result := '';
while not Eof(t) do begin
Readln(t,s);
result := result+s+#13#10;
end;
finally
CloseFile(t);
end;
except
on E:Exception do
raise EInOutError.Create('Error loading file '+iFilename+' ('+E.ClassName+': '+E.Message+')');
end;
end;
{$ENDIF}
procedure SaveStringToFile(const iFilename,iString:string);
{$IFDEF DELPHI2009UP}
begin
With TStringList.Create do try
Text := iString;
SaveToFile(iFilename);
finally
free;
end;
end;
{$ELSE}
var t:TextFile;
begin
try
AssignFile(t,iFilename);
Rewrite(t);
try
Write(t,iString);
finally
CloseFile(t);
end;
except
on E:Exception do
raise EInOutError.Create('Error saving file '+iFilename+' ('+E.ClassName+': '+E.Message+')');
end;
end;
{$ENDIF}
function NewGuid:TGUID;
begin
{$IFDEF MSWINDOWS}
CoCreateGuid(result);
{$ENDIF MSWINDOWS}
{$IFDEF LINUX}
CreateGuid(result);
{$ENDIF}
end;
function NewGuidAsString:string;
begin
result := GuidToString(NewGuid());
end;
function NewGuidAsStringNoBrackets:string;
begin
result := GuidToString(NewGuid());
result := Copy(result,2,Length(result)-2);
end;
function ReplaceVariables(const aString: string; aVariables: TStrings): string;
var
i:integer;
begin
{ No, this isn't efficient code. But given the fact that this is used at designtime and
in a place where the execution is abolutely not time-critical, clarity is preferable to
efficiency, imho. mh. }
result := aString;
if Assigned(aVariables) then begin
for i := 0 to aVariables.Count-1 do begin
result := StringReplace(result,'$('+aVariables.Names[i]+')',aVariables.Values[aVariables.Names[i]],[rfReplaceAll,rfIgnoreCase]);
end;
end;
result := StringReplace(result,'$(NewID)',NewGuidAsString(),[rfReplaceAll,rfIgnoreCase]);
result := StringReplace(result,'$(NewID2)',NewGuidAsStringNoBrackets(),[rfReplaceAll,rfIgnoreCase]);
end;
function ProjectName: string;
var
lProjectName:string;
begin
if Assigned(CurrentProject()) then begin
lProjectName := (CurrentProject as IOTAModule).FileName;
lProjectName := ChangeFileExt(ExtractFileName(lProjectName),'');
end
else begin
lProjectName := '';
end;
result := lProjectName;
end;
function RemoveInitialT(const aString:string):string;
begin
result := aString;
if (result <> '') and (result[1] = 'T') then Delete(result,1,1);
end;
function AddInitialT(const aString:string):string;
begin
result := aString;
if (result <> '') and (result[1] <> 'T') then result := 'T'+result;
end;
function GetDllPath: String;
var TheFileName : array[0..MAX_PATH] of char;
begin
FillChar(TheFileName, SizeOf(TheFileName), #0);
{$IFDEF KYLIX}System.{$ENDIF}GetModuleFileName(hInstance, TheFileName, sizeof(TheFileName));
Result := ExtractFilePath(TheFileName);
end;
function ModuleServices: IOTAModuleServices;
begin
result := (BorlandIDEServices as IOTAModuleServices);
end;
function CurrentProject: IOTAProject;
var
services: IOTAModuleServices;
module: IOTAModule;
project: IOTAProject;
projectgroup: IOTAProjectGroup;
multipleprojects: Boolean;
i: Integer;
begin
result := nil;
multipleprojects := False;
services := ModuleServices;
if (services = nil) then Exit;
for I := 0 to (services.ModuleCount - 1) do begin
module := services.Modules[I];
if (module.QueryInterface(IOTAProjectGroup, ProjectGroup) = S_OK) then begin
result := ProjectGroup.ActiveProject;
Exit;
end
else if module.QueryInterface(IOTAProject, Project) = S_OK then begin
if (result = nil) then
result := Project // Found the first project, so save it
else
multipleprojects := True; // It doesn't look good, but keep searching for a project group
end;
end;
if multipleprojects then result := nil;
end;
function ProjectByName(const aName: string): IOTAProject;
var
services: IOTAModuleServices;
module: IOTAModule;
project: IOTAProject;
i: Integer;
begin
result := nil;
services := ModuleServices;
if (services = nil) then Exit;
for I := 0 to (services.ModuleCount - 1) do begin
module := services.Modules[I];
if module.QueryInterface(IOTAProject, Project) = S_OK then begin
if module.FileName = aName then begin
result := Project;
exit;
end;
end;
end;
end;
function CurrentProjectGroup: IOTAProjectGroup;
var
services: IOTAModuleServices;
i: Integer;
begin
Result := nil;
services := ModuleServices;
for i := 0 to ModuleServices.ModuleCount - 1 do begin
if Supports(ModuleServices.Modules[i], IOTAProjectGroup, Result) then begin
Break;
end;
end;
end;
function GetUniqueProjectFilename(aProject: IOTAProject; aName: string): string;
var
lBaseName, lName: string;
lCount: integer;
function ProjectHasFile: boolean;
var
i: integer;
begin
result := false;
for i := 0 to aProject.GetModuleCount-1 do begin
if (aProject.GetModule(i).Name = lName) or (aProject.GetModule(i).Name = ChangeFileExt(lName, '')) then begin
result := true;
break;
end;
end;
end;
begin
lName := aName;
lBaseName := ChangeFileExt(aName, '');
lCount := 0;
while ProjectHasFile() do begin
inc(lCount);
lName := lBaseName+IntToStr(lCount)+ExtractFileExt(aName);
end;
result := lName;
end;
function FindModuleByUnitName(const aProject: IOTAProject; const aModuleName: string): IOTAModule;
var
i: integer;
begin
result := nil;
for i := 0 to aProject.GetModuleCount - 1 do
if (CompareText(ExtractFileName(aModuleName), ExtractFileName(aProject.GetModule(i).FileName)) = 0) then begin
result := aProject.GetModule(i).OpenModule;
Exit;
end;
end;
const
MaxSourceSize = 10000;
function ReadModuleSource(const aModule: IOTAModule): String;
var
l, i: integer;
editor: IOTASourceEditor;
reader: IOTAEditReader;
lSource: AnsiString;
begin
result := '';
with aModule do
for i := 0 to GetModuleFileCount - 1 do begin
if Supports(GetModuleFileEditor(i), IOTASourceEditor, editor) then begin
// TODO: find a way not to depend on files smaller than 10k... I only use this for DPRs so it's fine for now
SetLength(lSource, MaxSourceSize);
//l := 0; to remove warning
reader := editor.CreateReader;
l := reader.GetText(0, @lSource[1], MaxSourceSize);
reader := nil;
SetLength(lSource, l);
result := {$IFDEF DELPHI2009UP}UTF8ToString{$ENDIF}(lSource);
Exit;
end;
end;
end;
procedure WriteModuleSource(const aModule: IOTAModule; const aCode, aHeader: string);
var
i: integer;
lEditor: IOTASourceEditor;
writer: IOTAEditWriter;
begin
with aModule do begin
for i := 0 to GetModuleFileCount - 1 do begin
if Supports(GetModuleFileEditor(i), IOTASourceEditor, lEditor) then begin
if LowerCase(ExtractFileExt(GetModuleFileEditor(i).FileName)) = '.h' then begin
if aHeader <> '' then begin
writer := lEditor.CreateWriter;
writer.DeleteTo(MaxInt);
writer.Insert(PAnsiChar({$IFDEF DELPHI2009UP}UTF8Encode{$ENDIF}(aHeader)));
writer := nil;
end;
end
else begin
writer := lEditor.CreateWriter;
writer.DeleteTo(MaxInt);
writer.Insert(PAnsiChar({$IFDEF DELPHI2009UP}UTF8Encode{$ENDIF}(aCode)));
writer := nil;
end;
end;
end;
end;
end;
procedure AddOrReplaceNamedModule(const aProject: IOTAProject; aName, aCode: string);
var
lModule: IOTAModule;
begin
lModule := FindModuleByUnitName(aProject, aName);
if assigned(lModule) then begin
WriteModuleSource(lModule, aCode, '');
end
else begin
aName := ExtractFilePath(CurrentProject.FileName)+aName;
SaveStringToFile(aName, aCode);
CurrentProject.AddFile(aName, true);
lModule := FindModuleByUnitName(CurrentProject, aName);
{$IFDEF DELPHI9UP}
if assigned(lModule) then lModule.Show();
{$ENDIF DELPHI9UP}
end;
end;
function GetDelphiVersion: Integer;
begin
{$IFDEF DELPHI5}
result := 5;
{$ELSE}
{$IFDEF DELPHI2007}
result := 11;
{$ELSE}
result := Trunc(RTLVersion)-8;
{$ENDIF}
{$ENDIF}
end;
function LanguageFromPersonality(aProject: IOTAProject): string;
{$IFDEF BDS}
var s: string;
{$ENDIF}
begin
{$IFDEF BDS}
s := aProject.Personality;
if s = sDelphiPersonality then result := 'Delphi for Win32'
else if s = sDelphiDotNetPersonality then result := 'Delphi for .NET'
else if s = sCSharpPersonality then result := 'C#'
else if s = sVBPersonality then result := 'Visual Basic'
else if s = sCBuilderPersonality then result := 'C++'
else result := 'Unknown';
{$ELSE}
result := 'Delphi for Win32';
{$ENDIF}
end;
function LanguageFromPersonalityEx(aProject: IOTAProject): string;
begin
result := LanguageFromPersonality(aProject);
{$IFDEF BDS}
if result = 'Delphi for .NET' then
result := result+'/'+IntToStr(GetDelphiVersion);
{$ENDIF}
end;
end.