From ef8d72138c2c1525de317d0acf8f6b621975d4a6 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Thu, 17 Sep 2015 00:04:27 +0200 Subject: [PATCH] common project interface renaming + works on #10 - DUB proj editor file dbl clickable - icons - filter for files and props --- src/ce_dcd.pas | 2 +- src/ce_dubproject.pas | 442 +++++++++++++++++++++------------------ src/ce_dubprojeditor.lfm | 368 +++++++++++++++++++++++++++++++- src/ce_dubprojeditor.pas | 77 ++++++- src/ce_interfaces.pas | 94 +++++---- src/ce_libmaneditor.pas | 8 +- src/ce_main.pas | 55 +++-- src/ce_mru.pas | 2 +- src/ce_nativeproject.pas | 109 ++++++---- src/ce_projinspect.pas | 14 +- src/ce_symstring.pas | 30 +-- src/ce_todolist.pas | 2 +- 12 files changed, 839 insertions(+), 364 deletions(-) diff --git a/src/ce_dcd.pas b/src/ce_dcd.pas index 5429f149..6194e635 100644 --- a/src/ce_dcd.pas +++ b/src/ce_dcd.pas @@ -146,7 +146,7 @@ begin try for i:= 0 to fProj.Sources.Count-1 do begin - fold := extractFilePath(fProj.getAbsoluteSourceName(i)); + fold := extractFilePath(fProj.sourceAbsolute(i)); if folds.IndexOf(fold) = -1 then folds.Add(fold); end; diff --git a/src/ce_dubproject.pas b/src/ce_dubproject.pas index 1d5c8265..5f271c37 100644 --- a/src/ce_dubproject.pas +++ b/src/ce_dubproject.pas @@ -10,8 +10,6 @@ uses type - TUpdaterTarget = (configs, files); - TCEDubProject = class(TComponent, ICECommonProject) private fFilename: string; @@ -31,36 +29,39 @@ type procedure udpateConfigsFromJson; procedure updateSourcesFromJson; procedure updateTargetKindFromJson; - function findTargetKindIn(value: TJSONObject): boolean; + function findTargetKindInd(value: TJSONObject): boolean; procedure dubProcOutput(proc: TProcess); function getCurrentCustomConfig: TJSONObject; - // - function getFormat: TCEProjectFormat; - function getProject: TObject; - // public constructor create(aOwner: TComponent); override; destructor destroy; override; // - function getFilename: string; + function filename: string; + function basePath: string; procedure loadFromFile(const aFilename: string); procedure saveToFile(const aFilename: string); - function getIfModified: boolean; - function getBinaryKind: TProjectBinaryKind; + // + function getFormat: TCEProjectFormat; + function getProject: TObject; + function modified: boolean; + function binaryKind: TProjectBinaryKind; function getCommandLine: string; // - function getIfIsSource(const aFilename: string): boolean; - function getOutputFilename: string; + function isSource(const aFilename: string): boolean; + function sourcesCount: integer; + function sourceRelative(index: integer): string; + function sourceAbsolute(index: integer): string; + function outputFilename: string; // - function getConfigurationCount: integer; + function configurationCount: integer; procedure setActiveConfiguration(index: integer); - function getConfigurationName(index: integer): string; + function configurationName(index: integer): string; // function compile: boolean; function run(const runArgs: string = ''): boolean; // property json: TJSONObject read fJSON; - property sources: TStringList read fSrcs; + //property sources: TStringList read fSrcs; end; // these 9 built types always exist @@ -77,6 +78,7 @@ const implementation +{$REGION Standard Comp/Obj -----------------------------------------------------} constructor TCEDubProject.create(aOwner: TComponent); begin inherited; @@ -100,6 +102,225 @@ begin fSrcs.Free; inherited; end; +{$ENDREGION --------------------------------------------------------------------} + +{$REGION ICECommonProject: project props ---------------------------------------} +function TCEDubProject.getFormat: TCEProjectFormat; +begin + exit(pfDub); +end; + +function TCEDubProject.getProject: TObject; +begin + exit(self); +end; + +function TCEDubProject.filename: string; +begin + exit(fFilename); +end; + +function TCEDubProject.basePath: string; +begin + exit(fBasePath); +end; + +procedure TCEDubProject.loadFromFile(const aFilename: string); +var + loader: TMemoryStream; + parser : TJSONParser; +begin + loader := TMemoryStream.Create; + try + fBasePath := extractFilePath(aFilename); + fFilename := aFilename; + loader.LoadFromFile(fFilename); + fJSON.Free; + parser := TJSONParser.Create(loader); + try + fJSON := parser.Parse as TJSONObject; + finally + parser.Free; + end; + finally + loader.Free; + updateFields; + subjProjChanged(fProjectSubject, self); + fModified := false; + end; +end; + +procedure TCEDubProject.saveToFile(const aFilename: string); +var + saver: TMemoryStream; + str: string; +begin + saver := TMemoryStream.Create; + try + fFilename := aFilename; + str := fJSON.FormatJSON; + saver.Write(str[1], length(str)); + saver.SaveToFile(fFilename); + finally + saver.Free; + fModified := false; + end; +end; + +function TCEDubProject.binaryKind: TProjectBinaryKind; +begin + exit(fBinKind); +end; + +function TCEDubProject.getCommandLine: string; +var + str: TStringList; +begin + str := TStringList.Create; + try + str.Add('dub' + exeExt); + if fBuiltTypeIx <> 0 then + str.Add('build=' + fBuildTypes.Strings[fBuiltTypeIx]); + if fConfigIx <> 0 then + str.Add('config=' + fConfigs.Strings[fConfigIx]); + result := str.Text; + finally + str.Free; + end; +end; + +function TCEDubProject.outputFilename: string; +begin + //TODO-cDUB: implement outputFilename + exit(''); +end; +{$ENDREGION --------------------------------------------------------------------} + +{$REGION ICECommonProject: sources ---------------------------------------------} +function TCEDubProject.isSource(const aFilename: string): boolean; +var + fname: string; +begin + fname := aFilename; + if fileExists(fname) then + fname := ExtractRelativepath(fBasePath, fname); + result := fSrcs.IndexOf(fname) <> -1; +end; + +function TCEDubProject.sourcesCount: integer; +begin + exit(fSrcs.Count); +end; + +function TCEDubProject.sourceRelative(index: integer): string; +begin + exit(fSrcs.Strings[index]); +end; + +function TCEDubProject.sourceAbsolute(index: integer): string; +var + fname: string; +begin + fname := fSrcs.Strings[index]; + if FileExists(fname) then + result := fname + else + result := expandFilenameEx(fBasePath, fname); +end; +{$ENDREGION --------------------------------------------------------------------} + +{$REGION ICECommonProject: configs ---------------------------------------------} +function TCEDubProject.configurationCount: integer; +begin + exit(fConfigsCount); +end; + +procedure TCEDubProject.setActiveConfiguration(index: integer); +begin + fBuiltTypeIx := index div fConfigs.Count; + fConfigIx := index mod fConfigs.Count; + updateSourcesFromJson; +end; + +function TCEDubProject.configurationName(index: integer): string; +begin + result := fBuildTypes.Strings[index div fConfigs.Count] + ' - ' + + fConfigs.Strings[index mod fConfigs.Count]; +end; +{$ENDREGION --------------------------------------------------------------------} + +{$REGION ICECommonProject: actions ---------------------------------------------} +function TCEDubProject.compile: boolean; +var + dubproc: TProcess; + olddir: string; + prjname: string; + msgs: ICEMessagesDisplay; +begin + result := false; + msgs := getMessageDisplay; + msgs.clearByData(Self as ICECommonProject); + prjname := shortenPath(fFilename); + dubproc := TProcess.Create(nil); + olddir := GetCurrentDir; + try + msgs.message('compiling ' + prjname, self as ICECommonProject, amcProj, amkInf); + chDir(extractFilePath(fFilename)); + dubproc.Executable := 'dub' + exeExt; + dubproc.Options := dubproc.Options + [poStderrToOutPut, poUsePipes]; + dubproc.CurrentDirectory := extractFilePath(fFilename); + dubproc.ShowWindow := swoHIDE; + if fBuiltTypeIx <> 0 then + dubproc.Parameters.Add('build=' + fBuildTypes.Strings[fBuiltTypeIx]); + if fConfigIx <> 0 then + dubproc.Parameters.Add('config=' + fConfigs.Strings[fConfigIx]); + dubproc.Execute; + while dubproc.Running do + dubProcOutput(dubproc); + if dubproc.ExitStatus = 0 then begin + msgs.message(prjname + ' has been successfully compiled', self as ICECommonProject, amcProj, amkInf); + result := true; + end else + msgs.message(prjname + ' has not been compiled', self as ICECommonProject, amcProj, amkWarn); + finally + chDir(olddir); + dubproc.Free; + end; +end; + +function TCEDubProject.run(const runArgs: string = ''): boolean; +begin + //TODO-cDUB: implement + result := false; +end; +{$ENDREGION --------------------------------------------------------------------} + + + +function isValidDubProject(const filename: string): boolean; +var + maybe: TCEDubProject; +begin + result := true; + // avoid the project to notify the observers, current project is not replaced + EntitiesConnector.beginUpdate; + maybe := TCEDubProject.create(nil); + EntitiesConnector.removeSubject(maybe); + try + try + maybe.loadFromFile(filename); + if maybe.json = nil then + result := false + else if maybe.json.Find('name') = nil then + result := false; + except + result := false; + end; + finally + maybe.Free; + EntitiesConnector.endUpdate; + end; +end; procedure TCEDubProject.dubProcOutput(proc: TProcess); var @@ -118,21 +339,6 @@ begin end; end; -function TCEDubProject.getFormat: TCEProjectFormat; -begin - exit(pfDub); -end; - -function TCEDubProject.getProject: TObject; -begin - exit(self); -end; - -function TCEDubProject.getFilename: string; -begin - exit(fFilename); -end; - function TCEDubProject.getCurrentCustomConfig: TJSONObject; var item: TJSONData; @@ -160,9 +366,8 @@ begin fBuildTypes.Clear; fConfigs.Clear; - // configs: builtype0 - config0, builtype0 - config1, ... , builtype0 - configN - // builtype1 - config0, builtype1 - config1, ... , builtype1 - configN, etc - + // the CE interface for dub doesn't make a difference betwenn build type and config + // instead, each possible combination type+build is generated. if fJSON.Find('configurations') <> nil then begin @@ -273,7 +478,7 @@ begin end; end; -function TCEDubProject.findTargetKindIn(value: TJSONObject): boolean; +function TCEDubProject.findTargetKindInd(value: TJSONObject): boolean; var tt: TJSONData; begin @@ -299,14 +504,14 @@ begin fBinKind := executable; if fJSON = nil then exit; // note: in Coedit this is only used to known if output can be launched - guess := not findTargetKindIn(fJSON); + guess := not findTargetKindInd(fJSON); conf := getCurrentCustomConfig; if conf <> nil then - guess := guess and findTargetKindIn(conf); + guess := guess and findTargetKindInd(conf); if guess then begin // TODO-cDUB: guess target kind - // app.d in source ? exe : lib + // app.d in sourceRelative ? exe : lib end; end; @@ -317,173 +522,12 @@ begin updateTargetKindFromJson; end; -function TCEDubProject.getBinaryKind: TProjectBinaryKind; -begin - exit(fBinKind); -end; - -procedure TCEDubProject.loadFromFile(const aFilename: string); -var - loader: TMemoryStream; - parser : TJSONParser; -begin - loader := TMemoryStream.Create; - try - fBasePath := extractFilePath(aFilename); - fFilename := aFilename; - loader.LoadFromFile(fFilename); - fJSON.Free; - parser := TJSONParser.Create(loader); - try - fJSON := parser.Parse as TJSONObject; - finally - parser.Free; - end; - finally - loader.Free; - updateFields; - subjProjChanged(fProjectSubject, self); - fModified := false; - end; -end; - -procedure TCEDubProject.saveToFile(const aFilename: string); -var - saver: TMemoryStream; - str: string; -begin - saver := TMemoryStream.Create; - try - fFilename := aFilename; - str := fJSON.FormatJSON; - saver.Write(str[1], length(str)); - saver.SaveToFile(fFilename); - finally - saver.Free; - fModified := false; - end; -end; - -function TCEDubProject.getCommandLine: string; -var - str: TStringList; -begin - str := TStringList.Create; - try - str.Add('dub' + exeExt); - if fBuiltTypeIx <> 0 then - str.Add('build=' + fBuildTypes.Strings[fBuiltTypeIx]); - if fConfigIx <> 0 then - str.Add('config=' + fConfigs.Strings[fConfigIx]); - result := str.Text; - finally - str.Free; - end; -end; - -function TCEDubProject.getIfModified: boolean; +function TCEDubProject.modified: boolean; begin exit(fModified); end; -function TCEDubProject.getIfIsSource(const aFilename: string): boolean; -begin - //TODO-cDUB: implement getIfIsSource - exit(false); -end; -function TCEDubProject.getOutputFilename: string; -begin - //TODO-cDUB: implement getOutputFilename - exit(''); -end; - -function TCEDubProject.getConfigurationCount: integer; -begin - exit(fConfigsCount); -end; - -procedure TCEDubProject.setActiveConfiguration(index: integer); -begin - fBuiltTypeIx := index div fConfigs.Count; - fConfigIx := index mod fConfigs.Count; - updateSourcesFromJson; -end; - -function TCEDubProject.getConfigurationName(index: integer): string; -begin - result := fBuildTypes.Strings[index div fConfigs.Count] + ' - ' + - fConfigs.Strings[index mod fConfigs.Count]; -end; - -function TCEDubProject.compile: boolean; -var - dubproc: TProcess; - olddir: string; - prjname: string; - msgs: ICEMessagesDisplay; -begin - result := false; - msgs := getMessageDisplay; - msgs.clearByData(Self as ICECommonProject); - prjname := shortenPath(fFilename); - dubproc := TProcess.Create(nil); - olddir := GetCurrentDir; - try - msgs.message('compiling ' + prjname, self as ICECommonProject, amcProj, amkInf); - chDir(extractFilePath(fFilename)); - dubproc.Executable := 'dub' + exeExt; - dubproc.Options := dubproc.Options + [poStderrToOutPut, poUsePipes]; - dubproc.CurrentDirectory := extractFilePath(fFilename); - dubproc.ShowWindow := swoHIDE; - if fBuiltTypeIx <> 0 then - dubproc.Parameters.Add('build=' + fBuildTypes.Strings[fBuiltTypeIx]); - if fConfigIx <> 0 then - dubproc.Parameters.Add('config=' + fConfigs.Strings[fConfigIx]); - dubproc.Execute; - while dubproc.Running do - dubProcOutput(dubproc); - if dubproc.ExitStatus = 0 then begin - msgs.message(prjname + ' has been successfully compiled', self as ICECommonProject, amcProj, amkInf); - result := true; - end else - msgs.message(prjname + ' has not been compiled', self as ICECommonProject, amcProj, amkWarn); - finally - chDir(olddir); - dubproc.Free; - end; -end; - -function TCEDubProject.run(const runArgs: string = ''): boolean; -begin - //TODO-cDUB: implement - result := false; -end; - -function isValidDubProject(const filename: string): boolean; -var - maybe: TCEDubProject; -begin - result := true; - // avoid the project to notify the observers, current project is not replaced - EntitiesConnector.beginUpdate; - maybe := TCEDubProject.create(nil); - EntitiesConnector.removeSubject(maybe); - try - try - maybe.loadFromFile(filename); - if maybe.json = nil then - result := false - else if maybe.json.Find('name') = nil then - result := false; - except - result := false; - end; - finally - maybe.Free; - EntitiesConnector.endUpdate; - end; -end; end. diff --git a/src/ce_dubprojeditor.lfm b/src/ce_dubprojeditor.lfm index ca7225b2..29b39ebb 100644 --- a/src/ce_dubprojeditor.lfm +++ b/src/ce_dubprojeditor.lfm @@ -21,10 +21,10 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget Height = 549 Top = 4 Width = 403 - ActivePage = TabSheet1 + ActivePage = TabSheet2 Align = alClient BorderSpacing.Around = 4 - TabIndex = 0 + TabIndex = 1 TabOrder = 0 object TabSheet1: TTabSheet Caption = 'Inspector' @@ -63,6 +63,19 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget Layout = blGlyphBottom ShowCaption = False end + object fltInspect: TTreeFilterEdit + Left = 58 + Height = 22 + Top = 2 + Width = 327 + ButtonWidth = 23 + NumGlyphs = 1 + Align = alClient + BorderSpacing.Around = 2 + MaxLength = 0 + TabOrder = 0 + FilteredTreeview = treeInspect + end end object treeInspect: TTreeView Left = 4 @@ -73,13 +86,15 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget BorderSpacing.Around = 4 DefaultItemHeight = 18 HideSelection = False + Images = imgList ReadOnly = True ScrollBars = ssAutoBoth TabOrder = 1 + OnDblClick = treeInspectDblClick Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] Items.Data = { - F9FFFFFF020002000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000 - 0000000C000000536F757263652066696C6573FFFFFFFFFFFFFFFFFFFFFFFFFF + F9FFFFFF020002000000000000000000000000000000FFFFFFFF000000000000 + 0000000C000000536F757263652066696C6573010000000100000001000000FF FFFFFF0000000000000000000E000000436F6E66696775726174696F6E73 } end @@ -107,6 +122,7 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget BorderSpacing.Around = 4 DefaultItemHeight = 18 HideSelection = False + Images = imgList ReadOnly = True ScrollBars = ssAutoBoth TabOrder = 1 @@ -146,9 +162,353 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget Layout = blGlyphBottom ShowCaption = False end + object fltEdit: TTreeFilterEdit + Left = 58 + Height = 22 + Top = 2 + Width = 327 + ButtonWidth = 23 + NumGlyphs = 1 + Align = alClient + BorderSpacing.Around = 2 + MaxLength = 0 + TabOrder = 0 + FilteredTreeview = propTree + end end end end end end + inherited contextMenu: TPopupMenu + left = 248 + top = 8 + end + object imgList: TImageList[2] + left = 208 + top = 8 + Bitmap = { + 4C690A0000001000000010000000B3B3B1EFB0B0ADFFAEAEACFFAEAEACFFAEAE + ACFFAFAFACFFAFAFADFFB1B1AFD5B4B4B100B5B5B300B5B5B300B5B5B300B5B5 + B300B5B5B300B5B5B300B5B5B300AFAFADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFEDEDEEFFB3B3B0A4B5B5B300B5B5B300B5B5B300B5B5 + B300B5B5B300B5B5B300B5B5B300AEAEACFFFFFFFFFFE3E3E2FFBEBEBCFFA8A8 + A6FFA8A8A6FFACACAAFFB0B0ADFFB2B2B0FFB3B3B1FFB4B4B2A8B4B4B200B4B4 + B200B4B4B200B5B5B300B5B5B300AEAEABFFFFFFFFFFE9E8E7FFA8A8A6FFFFFF + FFFFFFFFFFFFD1D1D0FFADADABFFADADABFFAEAEABFFADADABFFAEAEABFFAFAF + ADFFB0B0AEACB3B3B100B5B5B300ADADABFFFFFFFFFFEDECECFFA8A8A5FFFFFF + FFFFE4E4E3FFA9A9A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFE9E9E9FFAFAFADA7B3B3B100ADADABFFFFFFFFFFF1F1F0FFA7A7A5FFFFFF + FFFFEAE8E7FFA8A8A6FFFFFFFFFFE0E0DFFFE0E0DFFFE0E0DFFFFFFFFFFFA4A4 + A2FFFFFFFFFFE9E9E9FFB0B0AEACADADABFFFFFFFFFFF5F5F4FFA7A7A5FFFFFF + FFFFEDECECFFA8A8A5FFFFFFFFFFE5E4E3FFE6E5E4FFE5E4E3FFFFFFFFFFCACA + C9FFA4A4A2FFFFFFFFFFAFAFADFFADADABFFFFFFFFFFF9F8F8FFA7A7A5FFFFFF + FFFFF1F1F0FFA7A7A5FFFFFFFFFFE9E8E8FFEAE8E9FFE9E8E8FFF3F2F2FFFFFF + FFFFFFFFFFFFFFFFFFFFAEAEABFFADADABFFFFFFFFFFFDFCFCFFA6A7A4FFFFFF + FFFFF5F5F4FFA7A7A5FFFFFFFFFFECECEBFFEDEDECFFEDEDECFFECECEBFFEBEB + EAFFEBEBEAFFFFFFFFFFADADABFFAEAEABFFFFFFFFFFFFFFFFFFA7A7A4FFFFFF + FFFFF9F8F8FFA7A7A4FFFFFFFFFFF0F0EFFFF0F0EFFFF0F0EFFFF0F0EFFFEFEF + EEFFEFEFEEFFFFFFFFFFADADABFFB0B0ADFFFFFFFFFFFFFFFFFFA8A8A6FFFFFF + FFFFFDFCFCFFA6A7A4FFFFFFFFFFF4F3F3FFF4F3F3FFF4F3F3FFF4F3F3FFF4F3 + F3FFF4F3F3FFFFFFFFFFADADABFFB0B0AEF1B0B0AEFFAFAFADFFACACA9FFFFFF + FFFFFFFFFFFFA6A7A4FFFFFFFFFFF7F6F6FFF7F6F6FFF7F6F6FFF7F6F6FFF7F6 + F6FFF7F6F6FFFFFFFFFFADADABFF0000002F6666655D54545351AFAFADFFFFFF + FFFFFFFFFFFFA8A8A6FFFFFFFFFFFCFCFCFFFBFBFCFFFBFBFCFFFBFBFCFFFBFB + FCFFFCFCFCFFFFFFFFFFAEAEABFFB5B5B3000000000B00000008A4A4A2BDB0B0 + AEFFAFAFADFFADADABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFB0B0ADFFB5B5B300B5B5B300B5B5B300000000230000 + 003300000033AFAFADECAFAFADFFAEAEABFFADADABFFADADABFFADADABFFADAD + ABFFAEAEABFFAFAFADFFB1B1AFF2000000000000000000000000000000000000 + 0000000000000000002E00000033000000330000003300000033000000330000 + 0033000000330000003300000030FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF009E9E9E709C9C9CD69B9B9BFB9999 + 99FBFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF009D9D9D709B9B9BF5E4E4E4FFEEEEEEFF9696 + 96FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF009B9B9BD6E2E2E2FFE7E7E7FFB9B9B9FF9393 + 93FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00989898FBE4E4E4FFCFCFCFFF929292C2FFFF + FF008E8E8EFF8C8C8CFF8A8A8AFBFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00969696FCDDDDDDFFC5C5C5FF8F8F8FC18D8D + 8DC3ACACACFFD7D7D7FF878787FBFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0095959548939393FED4D4D4FFC8C8C8FFBCBCBCFFBABA + BAFFC2C2C2FFC4C4C4FF858585D6FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00E3AD8B92DAA788CF929292FBC7C7C7FFCCCCCCFFC7C7C7FFC6C6C6FFC3C3 + C3FFC0C0C0FF848484F582828270FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1A9 + 8992E7B99CFFE6B698FFD8A98CFFD2D2D2FFB5B5B5FF898989FE878787FB8585 + 85FB838383D681818170FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1A98792E6B7 + 9CFFEFCFBCFFEECEBAFFE2AE8CFFD29B7BFF888888F786868623FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1A78592E6B799FFEECE + BBFFE9C0A7FFE8BDA3FFECC8B3FFDFA481FFD2895DC9FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DFA58392E6B498FFEECDBAFFE9BF + A5FFE5B496FFE7B99DFFEBC6AEFFDE9F79FFD58351AAFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00DFA57F92E6B394FFEECCB8FFE9BEA5FFE5B3 + 94FFE6B79BFFEAC4ADFFDE9E78FFD3814FACFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00DD9F79FFEDCCB7FFE8BDA3FFE4B192FFE6B6 + 9AFFEAC3ACFFDE9C74FFD37F4DACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00DB976FFFEDC8B3FFE7B89BFFE6B498FFEAC3 + ABFFDE9C73FFD17D49AFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00D99165CCDFA481FFEAC2ABFFEAC0A8FFDC99 + 71FFD17B47AFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00D58757D5D58351FFD17D4BFFD179 + 45AFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000001C00000033000000360000 + 0036000000360000003600000036000000360000003600000036000000200000 + 0002FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000033F8F8F8F0FBFBFBFDFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFF8F8F8FF949494910000 + 002000000002FFFFFF00FFFFFF00FFFFFF0000000036FBFBFBFDF4F4F4FFF5F5 + F5FFF5F5F5FFF5F5F5FFF1F1F1FFEFEFEFFFE9E9E9FFFCFCFCFFE7E7E7FF9595 + 95910000002000000002FFFFFF000000000100000036FCFCFCFFF7F7F7FFF9F9 + F9FFF7F7F7FFF7F7F7FFF3F3F3FFF0F0F0FFEAEAEAFFFCFCFCFFF6F6F6FFF4F4 + F4FF9999999100000020FFFFFF000000000100000036FCFCFCFFF9F9F9FFC0C0 + C0FFBABABAFFB4B4B4FFAFAFAFFFAAAAAAFFA5A5A5FFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFBFBFBFFFCFC + FCFFFCFCFCFFFBFBFBFFF8F8F8FFF5F5F5FFF1F1F1FFECECECFFEAEAEAFFE6E6 + E6FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFC7C7 + C7FFC2C2C2FFBEBEBEFFB8B8B8FFB4B4B4FFB1B1B1FFAEAEAEFFACACACFFEDED + EDFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFBFBFFF8F8F8FFF6F6F6FFF3F3F3FFF2F2 + F2FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFCECE + CEFFCACACAFFC6C6C6FFC3C3C3FFC0C0C0FFBDBDBDFFBCBCBCFFBABABAFFF6F6 + F6FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFBFBFFF9F9F9FFF9F9F9FFF8F8 + F8FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFD6D6 + D6FFD3D3D3FFCFCFCFFFCDCDCDFFCBCBCBFFC8C8C8FFC8C8C8FFC6C6C6FFF8F8 + F8FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFBFBFBFFFBFBFBFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFDDDD + DDFFDBDBDBFFD9D9D9FFD7D7D7FFD5D5D5FFD4D4D4FFD4D4D4FFD4D4D4FFFBFB + FBFFFCFCFCFF00000036000000010000000100000036FCFCFCFEFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFD00000036FFFFFF00FFFFFF0000000034F9F9F9F5FCFCFCFDFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFDF9F9F9F300000033FFFFFF00FFFFFF000000001D00000034000000360000 + 0036000000360000003600000036000000360000003600000036000000360000 + 0036000000330000001DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0000000000000000000000000000000000898785FF898785FF0000 + 0000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00000000008D8B89FF999795FF84828044B8B6B4FFB8B6B4FF8482 + 8044999795FF8E8C8AFF00000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0000000000989694FFDDDBDAFF9F9D9BFFD3D1D0FFD3D1D0FF9F9D + 9BFFDDDBDAFF92908EFF00000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00000000006D6B6A9B9E9C9AFFBFBDBCFF999796FF999796FFBFBD + BCFF9E9C9AFF6C6B699B00000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00858381FFB2B0AFFFCFCDCCFF989693FF3332314A3332314A9896 + 93FFCECCCCFFB1AFAEFF8F8D8BFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00848280FFB1AFAEFFCCCAC9FF959392FF00000006000000069593 + 92FFCCCAC9FFB0AEADFF8E8C8AFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00000000336563618B999796FFB8B6B5FF949290FF949290FFB8B6 + B5FF999796FF6563618B00000033FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0000000000918F8DFFD1CFCEFF989695FFC8C6C5FFC8C6C5FF9896 + 95FFD1CFCEFF8A8888FF00000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0000000000868482FF8A8885FF52504F69AAA8A7FFAAA8A7FF5250 + 4F698A8886FF868482FF00000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000000000000033000000330000000E7F7D7CFF7F7D7CFF0000 + 000E000000330000003300000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000000000000000000000000000000000000033000000330000 + 0000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00EAC39DFFE6BF96FFE4BB92FFE4BB92FFD1A06CF5D09E6DF6CC96 + 5FDAC479427EB2673C09FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E5BE96FFFFFFFEFFFDF3E9FFFDF3EAFFFCF2E8FFFAEFE3FFFAF2 + E7FFEABB88FFCF8555B3B4693D0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB93FFFEF5EDFFFCDEC5FFFBE0C7FFF9DCC2FFF5D3B4FFFEF9 + F3FFFAE2C4FFECC193FFC37D4893FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB92FFFEF6F0FFFCE2CDFFFCE3CDFFFADFC8FFF7D9BCFFF5E9 + DDFFFAF3EBFFFBF8F3FFCA8353FEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB92FFFEF7F1FFFCE5D2FFFCE4D1FFFBE2CCFFF9DDC4FFF6D7 + BBFFF3D1AFFFFAEFE4FFCC8758FE34B4D9D05EC2E1FA60C3E2FA60C3E2FA60C3 + E2FA5FC3E2FAE4BB91FFFFF7F2FFFEE7D5FFFEE7D5FFFDE5D1FFFAE0CAFFF9DE + C4FFF7D9BCFFFDF2E7FFCC8757FE36B3DAF8FDFEFEFFFEFFFFFFFEFEFFFFFDFE + FFFFFEFFFFFFE4BA91FFFFF7F0FFFFE7D5FFFDE7D6FFFDE6D4FFFCE4D0FFFBE3 + CBFFFADCC2FFFEF3E8FFCC8656FE35AFDAF0F7FCFEFF8EE4F8FF91DEF5FF9FE0 + F5FFACE1F6FFCA8452FFFFF7F1FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFFF7F1FFCB8555FE36AADAF2F1FAFDFF94DEF5FF93DCF4FF64BC + E9FF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594 + DAFF3594DAFFFBF6EFFFCC8355FE35ABDAFAE8F6FBFF70BCE7FF55AAE2FF4DA5 + E0FF91C9EBFFFAF3EFFFFDFEFDFFFFFDFCFFFFFDFCFFFEFDFCFFFEFCFBFFFEFE + FDFF3594DAFFEFF2E8FFCE8156FF37A6DAFAFEFFFFFFF8FDFFFFF6FDFFFFF5FC + FFFFF3FCFEFF9AE4F4FF9AE6F7FF9BE6F6FF9DE5F5FF9EE5F5FF9FE5F4FFDAF3 + F8FF3594DAFFFDF4EEFFCA8054F936A1DAF9F6FCFEFF94E5F8FF93E5F8FF93E5 + F8FF91E5F8FF93DBE9FF93D7E3FF93D2DCFF90CED7FF8CC8CFFF86C1C6FFC9D8 + D6FF3594DAFFC57444E8CA7F53F1369ADAF8F2FAFDFF94E6F8FF92E5F8FF90E5 + F8FF8BE3F8FF86E2F7FF7FE1F7FF77DEF6FF6CDCF6FF5ED9F4FF4FD5F3FFCCF2 + FBFF3594DAFFFFFFFF00FFFFFF003594DAF7EFFAFEFF93E5F8FF8FE4F8FF89E3 + F8FF82E1F7FF7ADFF7FF71DEF6FF67DBF5FF5BD8F4FF4DD4F3FF40D1F2FFCAF2 + FBFF3594DAFFFFFFFF00FFFFFF00338ED9FBDCF0FAFF98E1F6FF95E0F6FF92DF + F6FF8EDEF5FF89DCF5FF85DAF4FF80D9F4FF7AD7F3FF74D5F3FF70D3F2FFC2EA + F8FF3594DAFFFFFFFF00FFFFFF002C86D8002D88D8F72D87D8F72D88D8F72D88 + D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D87D8F72D88 + D8F72C86D800FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF004398D2B03D94D0FF3A92CFFF3A92CFFF3D94 + D0FF4197D1D24398D2004498D2004498D2004498D2004498D2004499D2004499 + D300459AD300469AD300469AD3003D94D0FFDCFCFFFFD8F7FFFFD8F7FFFFDBFA + FFFF358ECDFF3991CEFF3A92CFFF3A92CFFF3A92CFFF3A92CFFF3B92CFFF3D94 + D0FF4398D2D7469AD300469AD3003B92CFFFD5F7FFFF60D1F9FF61D0F8FFB4EB + FDFFD9F6FFFFDAF8FFFFDAF8FFFFDBF9FFFFDCFAFFFFDCFAFFFFDCFBFFFFE0FF + FFFF3E95D0FF4599D333469AD3003B92CFFFCAF6FFFF69D5F9FF6CD5F9FF6BD5 + F9FF69D5F9FF69D5FAFF6AD7FBFF68D4FAFF5EC7F1FF5EC7F2FF5DC8F2FFB4E3 + F8FF3D94D0FF3F8FC669469AD3003C92CFFFC0F3FFFF71DAFBFF74DBFBFF75DB + FCFF75DBFCFF76DCFCFF73DAFAFF449CD4FF378CCBFF368CCBFF358CCCFF348D + CCFF3890CEFF3D94D0FF4398D2EB3D92CFFFB9F4FFFF73DBFBFF6BCCF2FF6CCD + F3FF6CCEF3FF6DCEF3FF479CD4FF56BAE9FFDAF8FFFFD7F6FFFFD6F6FFFFD5F6 + FFFFD5F7FFFFDBFCFFFF3E94D0FF3E94D0FFABF0FFFF449DD6FF368CCBFF368C + CBFF368CCBFF378BCBFF5CBEEAFF6FD9FBFF6AD6FAFF68D5F9FF67D4F9FF66D4 + F9FF82DEFCFFAAE0F6FF3885BCB94095D0FF8AD7F5FF44A1D8FFDDFDFFFFDAFA + FFFFDBFAFFFFDEFAFFFF74DCFCFF76DBFAFF75DAFAFF74DAFAFF74DAFAFF72D9 + FAFFA1E8FFFF7CBFE6FF306F9C5E4296D1FF6BBEE8FF6DBDE6FFBBF2FFFF75DE + FDFF77DEFCFF78DEFCFF7BDFFCFF7DDFFCFF7DDFFCFF7DDFFCFF7CDFFCFF80E0 + FDFFADF0FFFF4D9DD3FF0000000E4398D2FF4FA6D9FF8EDAF5FFA2EEFFFF82E5 + FEFF84E5FEFF84E5FEFF85E6FEFF85E6FEFF85E6FEFF85E6FEFF84E6FEFF96EB + FFFF8CD8F5FF3985BCB84499D2004499D2FF3F94D0FFABFBFFFF9BF3FFFF92F1 + FFFF93F1FFFF93F1FFFF93F1FFFF93F1FFFF93F1FFFF93F1FFFF93F1FFFFA6F8 + FFFF65B8E3FF31709D5F469AD3004598D1F24398D2FF4094D0FF3E92CFFF3E92 + CEFF3F92CEFF3F92CEFF3F92CEFF3F92CEFF3F92CEFF3F92CEFF3F92CEFF3F93 + CFFF4194CEF00000000E469AD300000000300000003300000033000000330000 + 0033000000330000003300000033000000330000003300000033000000330000 + 00330000002F0000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C5C5C504A9A9A9199E9E9E29BFBFBFF1B1B1B1FFB1B1B1FFBEBE + BEF19999992AAAAAAA19C5C5C504FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00B7B7B776D5D5D5FFCDCDCDFFC3C3C3FFE0E0E0FFDEDEDEFFC3C3 + C3FFCECECEFFD6D6D6FFB4B4B476FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00ACACACE4E5E5E5FFFFFFFFFFC8C8C8FFB3B3B3FFB3B3B3FFC8C8 + C8FFFFFFFFFFE5E5E5FFA0A0A0EDFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00A8A8A8FFDBDBDBFFD0D0D0FFC6C6C6FFFFFFFFFFFFFFFFFFC8C8 + C8FFCACACAFFBFBFBFFFACACACFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00AAAAAAFFF6F6F6FFE6E6E6FFCCCCCCFFD6D6D6FFD4D4D4FFBCBC + BCFFBFBFBFFFC3C3C3FFAFAFAFFF34B4D9D05EC2E1FA60C3E2FA60C3E2FA60C3 + E2FA5FC3E2FAABABABFFF6F6F6FFE8E8E8FFE1E1E1FFD7D7D7FFC0C0C0FFBFBF + BFFFC2C2C2FFC3C3C3FFACACACFF36B3DAF8FDFEFEFFFEFFFFFFFEFEFFFFFDFE + FFFFFEFFFFFFB1B2B2FFCCCCCCFFE9E9E9FFE0E0E0FFD5D5D5FFBDBDBDFFC3C3 + C3FFC2C2C2FFB2B2B2FF9D9D9DED35AFDAF0F7FCFEFF8EE4F8FF91DEF5FF9FE0 + F5FFACE1F6FFE7F2F4FFBEC2C2FFAEAFAFFFCDCDCDFFE1E1E1FFC6C6C6FFB9B9 + B9FF9FA2A3FE959595A59393931E36AADAF2F1FAFDFF94DEF5FF93DCF4FF81D5 + F2FF60C0E9FF4FAEE1FF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594 + DAFF3594DAFFFFFFFF00FFFFFF0035ABDAFAE8F6FBFF7EC5EAFF5BAEE3FF51A8 + E1FF60AFE4FFEBFAFDFFECFAFEFFE5F5FCFFE5F6FCFFE3F4FBFFE4F5FCFFFEFF + FFFF3594DAFFFFFFFF00FFFFFF0037A6DAFAFEFFFFFFF8FDFFFFF6FDFFFFF5FC + FFFFE8FAFEFFAFECFAFF8EE4F8FF87E3F8FF7DE0F7FF72DDF6FF68DBF5FFE9F9 + FDFF3594DAFFFFFFFF00FFFFFF0036A1DAF9F6FCFEFFC8F2FCFFB9EFFBFFACEC + FAFF8CE4F8FF8AE3F8FF82E1F7FF79DFF7FF6DDDF6FF61DAF5FF57D7F4FFE7F8 + FDFF3594DAFFFFFFFF00FFFFFF00369ADAF8F2FAFDFFB3EDFAFFA4E9F9FF95E6 + F8FF85E2F7FF81E1F7FF7AE0F7FF6FDDF6FF62DAF5FF54D6F3FF47D3F2FFE8F9 + FDFF3594DAFFFFFFFF00FFFFFF003594DAF7EFFAFEFFA1E9F9FF91E5F8FF81E1 + F7FF72DEF6FF63DAF5FF54D7F4FF47D3F3FF39D0F2FF2ECDF1FF26CBF0FFCAF2 + FBFF3594DAF7FFFFFF00FFFFFF00338ED9E6DCF0FAF0A7DDF4FD9EDBF4FF96DA + F3FF8ED8F3FF86D7F3FF7FD4F2FF79D3F2FF72D2F1FF6CD0F1FF69CFF1FFC2EA + F8FE338ED9F0FFFFFF00FFFFFF002C86D8002D88D8A62D87D8EA2D88D8F72D88 + D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D87D8F72D88 + D8F12C86D893FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000010000 + 00080000002E000000250000000700000003000000200000001C000000080000 + 00060000000300000001FFFFFF00FFFFFF00FFFFFF0000000001000000340000 + 00E4000000FF00000095000000190000000B0000008C000000FD000000C90000 + 0048000000110000000500000001FFFFFF00FFFFFF0000000003000000B50000 + 00ED000000690000004600000026000000100000001700000051000000EE0000 + 00C40000002B0000001000000003FFFFFF00FFFFFF0000000005000000DB0000 + 00C0000000520000003B0000001C0000000A0000000A0000001C000000BB0000 + 00E5000000420000001C00000005FFFFFF000000000100000007000000E20000 + 00BE0000004D000000290000000D00000003000000030000000D000000AC0000 + 00EB0000004B0000002400000007FFFFFF00000000030000001C000000F70000 + 00AF000000460000001F00000006FFFFFF00FFFFFF0000000006000000830000 + 00FE000000650000002C0000000DFFFFFF0000000091000000F3000000D70000 + 006B0000003F0000001800000004FFFFFF00FFFFFF00000000040000002D0000 + 00CC000000FC000000A70000001DFFFFFF000000005E000000CD000000F30000 + 007D000000390000001300000003FFFFFF00FFFFFF0000000003000000570000 + 00FC000000C9000000880000002FFFFFFF000000000F00000033000000F70000 + 00B20000003A0000001400000003FFFFFF00FFFFFF0000000003000000A00000 + 00F00000005A0000004D0000002AFFFFFF000000000700000018000000E40000 + 00C1000000410000001900000004FFFFFF00FFFFFF0000000005000000A90000 + 00E8000000530000003700000016FFFFFF00000000020000000B000000E00000 + 00C1000000460000001E00000006FFFFFF00FFFFFF0000000006000000AC0000 + 00E70000004E000000290000000BFFFFFF000000000100000008000000C90000 + 00E200000050000000250000000A000000020000000200000011000000DC0000 + 00D50000004C0000002400000008FFFFFF000000000100000006000000670000 + 00F8000000F200000089000000170000000800000072000000EE000000FD0000 + 008D000000460000001E00000006FFFFFF00FFFFFF0000000003000000130000 + 0039000000840000006C000000240000000F0000004A0000007E000000620000 + 004A000000340000001400000003FFFFFF00FFFFFF0000000001000000080000 + 001500000025000000290000001C0000000C0000000D0000001E0000002D0000 + 002A000000180000000800000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000010000001E0000003F0000 + 004300000044000000110000000500000001000000040000003C000000410000 + 00440000002800000009FFFFFF00FFFFFF000000000200000085000000FF0000 + 00FF000000FF0000003A000000110000000500000015000000FF000000FF0000 + 00FF000000950000001DFFFFFF00FFFFFF000000000400000089000000FF0000 + 00670000005F000000390000001900000007000000070000002E0000004F0000 + 00FF000000A700000037FFFFFF00FFFFFF00000000050000008C000000FF0000 + 005F00000045000000270000000F00000004000000040000000F0000002E0000 + 00FF000000AC00000043FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00590000003200000012000000050000000100000001000000050000001A0000 + 00FF000000A800000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002C0000000B00000001FFFFFF00FFFFFF0000000001000000140000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002B0000000A00000001FFFFFF00FFFFFF0000000001000000130000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002B0000000A00000001FFFFFF00FFFFFF0000000001000000130000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002B0000000A00000001FFFFFF00FFFFFF0000000001000000130000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002B0000000A00000001FFFFFF00FFFFFF0000000001000000130000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 00560000002B0000000A00000001FFFFFF00FFFFFF0000000001000000130000 + 00FF000000A700000044FFFFFF00FFFFFF00000000050000008D000000FF0000 + 0058000000300000000F00000003000000010000000100000003000000170000 + 00FF000000A800000044FFFFFF00FFFFFF00000000050000008C000000FF0000 + 00E6000000E2000000320000000D0000000300000011000000DA000000DE0000 + 00FF000000AB00000044FFFFFF00FFFFFF00000000040000004C000000970000 + 00A6000000A20000003F00000018000000060000000E00000084000000940000 + 00A20000007D0000003BFFFFFF00FFFFFF00000000020000000D000000240000 + 00390000003B0000002C000000140000000500000005000000140000002C0000 + 003B0000003900000024FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 000100000014000000170000000B00000007000000150000001700000009FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0013000000FF000000FF0000004C00000043000000FF000000FF0000002FFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0016000000FF000000FF0000006B00000057000000FF000000FF00000051FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 000B0000005A00000077000000560000003D000000670000007A0000004DFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00 + } + end end diff --git a/src/ce_dubprojeditor.pas b/src/ce_dubprojeditor.pas index 93c5e1c2..e95475bf 100644 --- a/src/ce_dubprojeditor.pas +++ b/src/ce_dubprojeditor.pas @@ -5,8 +5,8 @@ unit ce_dubprojeditor; interface uses - Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, - Menus, StdCtrls, Buttons, ComCtrls, jsonparser, fpjson, + Classes, SysUtils, FileUtil, TreeFilterEdit, Forms, Controls, Graphics, + Dialogs, ExtCtrls, Menus, StdCtrls, Buttons, ComCtrls, jsonparser, fpjson, ce_widget, ce_common, ce_interfaces, ce_observer, ce_dubproject; type @@ -19,14 +19,18 @@ type btnDelProp: TSpeedButton; btnDelProp1: TSpeedButton; edValue: TMemo; + fltEdit: TTreeFilterEdit; + imgList: TImageList; PageControl1: TPageControl; pnlToolBar: TPanel; pnlToolBar1: TPanel; propTree: TTreeView; + fltInspect: TTreeFilterEdit; treeInspect: TTreeView; TabSheet1: TTabSheet; TabSheet2: TTabSheet; procedure propTreeSelectionChanged(Sender: TObject); + procedure treeInspectDblClick(Sender: TObject); private fSelectedNode: TTreeNode; fProj: TCEDubProject; @@ -52,7 +56,7 @@ type implementation {$R *.lfm} -{$REGION Standard Comp/Obj ----------------------------------------------------} +{$REGION Standard Comp/Obj -----------------------------------------------------} constructor TCEDubProjectEditorWidget.create(aOwner: TComponent); begin inherited; @@ -205,19 +209,35 @@ procedure TCEDubProjectEditorWidget.updateEditor; begin if data.JSONType = jtObject then for i := 0 to data.Count-1 do begin + node.ImageIndex:=7; + node.SelectedIndex:=7; + node.StateIndex:=7; c := node.TreeNodes.AddChildObject(node, TJSONObject(data).Names[i], TJSONObject(data).Items[i]); case TJSONObject(data).Items[i].JSONType of - jtObject, jtArray: - addPropsFrom(c, TJSONObject(data).Items[i]); + jtObject, jtArray: + addPropsFrom(c, TJSONObject(data).Items[i]); + else begin + c.ImageIndex:=9; + c.SelectedIndex:=9; + c.StateIndex:=9; + end; end; end else if data.JSONType = jtArray then for i := 0 to data.Count-1 do begin + node.ImageIndex:=8; + node.SelectedIndex:=8; + node.StateIndex:=8; c := node.TreeNodes.AddChildObject(node, format('item %d',[i]), TJSONArray(data).Items[i]); case TJSONArray(data).Items[i].JSONType of - jtObject, jtArray: - addPropsFrom(c, TJSONArray(data).Items[i]); + jtObject, jtArray: + addPropsFrom(c, TJSONArray(data).Items[i]); + else begin + c.ImageIndex:=9; + c.SelectedIndex:=9; + c.StateIndex:=9; + end; end; end; end; @@ -237,6 +257,7 @@ end; procedure TCEDubProjectEditorWidget.updateInspector; var i: integer; + node : TTreeNode; begin if (fNodeConfig = nil) or (fNodeSources = nil) then exit; @@ -247,10 +268,44 @@ begin if (fProj = nil) then exit; // - for i:= 0 to fProj.getConfigurationCount -1 do - treeInspect.Items.AddChild(fNodeConfig, fProj.getConfigurationName(i)); - for i := 0 to fProj.sources.count-1 do - treeInspect.Items.AddChild(fNodeSources, fProj.sources.strings[i]); + treeInspect.BeginUpdate; + for i:= 0 to fProj.configurationCount-1 do + begin + node := treeInspect.Items.AddChild(fNodeConfig, fProj.configurationName(i)); + node.ImageIndex := 3; + node.SelectedIndex := 3; + node.StateIndex := 3; + end; + for i := 0 to fProj.sourcesCount-1 do + begin + node := treeInspect.Items.AddChild(fNodeSources, fProj.sourceRelative(i)); + node.ImageIndex := 2; + node.SelectedIndex := 2; + node.StateIndex := 2; + end; + treeInspect.EndUpdate; +end; + +procedure TCEDubProjectEditorWidget.treeInspectDblClick(Sender: TObject); +var + node: TTreeNode; + fname: string; +begin + if treeInspect.Selected = nil then exit; + if fProj = nil then exit; + node := treeInspect.Selected; + // open file + if node.Parent = fNodeSources then + begin + fname := fProj.sourceAbsolute(node.Index); + if isEditable(extractFileExt(fname)) then + getMultiDocHandler.openDocument(fname); + end + // select active config + else if node.Parent = fNodeConfig then + begin + fProj.setActiveConfiguration(node.Index); + end; end; {$ENDREGION} diff --git a/src/ce_interfaces.pas b/src/ce_interfaces.pas index ee3ba17a..acb02680 100644 --- a/src/ce_interfaces.pas +++ b/src/ce_interfaces.pas @@ -20,63 +20,65 @@ type * Common project interface. * * Each project format has its own dedicated editors. - * The few common properties allow some generic operations whatever is the format. + * A few common properties allow some generic operations whatever is the format. *) ICECommonProject = interface ['ICECommonProject'] - // indicates the project format - function getFormat: TCEProjectFormat; - // returns an untyped object that can be casted using getFormat() - function getProject: TObject; - // sub routines for the actions -------------------------------------------- + // general properties ------------------------------------------------------ - // tries to compile and returns true if it does - function compile: boolean; - // tries to un the project and returns true if it did - function run(const runArgs: string = ''): boolean; - - // project file - allows main form to create/load/save --------------------- - - // returns the project filename - function getFilename: string; - // loads project from filename - procedure loadFromFile(const aFilename: string); - // saves project to filename - procedure saveToFile(const aFilename: string); - // indicates of the project is modified (should be saved or not) - function getIfModified: boolean; - - // various properties used by several widgets (todo ana, dcd, ...)---------- - - //// common project properties - //function sourceCount: integer; - //function source(index: integer): string; - //function stringImportCount: integer; - //function stringImport(index: integer): string; - //function moduleImportCount: integer; - //function moduleImport(index: integer): string; - - // returns true if aFilename is a project source - function getIfIsSource(const aFilename: string): boolean; - // returns the name of the file produced when a project is compiled - function getOutputFilename: string; - // returns the binary kind produced according to the current configuration - function getBinaryKind: TProjectBinaryKind; - // returns what's gonna be executed in background for this config - function getCommandLine: string; + // indicates the project format + function getFormat: TCEProjectFormat; + // returns an untyped object that can be casted using getFormat() + function getProject: TObject; + // returns the project filename + function filename: string; + // loads project from filename + procedure loadFromFile(const aFilename: string); + // saves project to filename + procedure saveToFile(const aFilename: string); + // indicates of the project is modified (should be saved or not) + function modified: boolean; + // returns the base path used to solve relative locations + function basePath: string; + // returns the name of the file produced when a project is compiled + function outputFilename: string; + // returns the binary kind produced according to the current configuration + function binaryKind: TProjectBinaryKind; + // returns what's gonna be executed in background for this config + function getCommandLine: string; // configs ----------------------------------------------------------------- - // returns the count of configuration - function getConfigurationCount: integer; - // sets the active configuration - procedure setActiveConfiguration(index: integer); - // returns the name of the index-th configuration - function getConfigurationName(index: integer): string; + // returns the count of configuration + function configurationCount: integer; + // sets the active configuration + procedure setActiveConfiguration(index: integer); + // returns the name of the index-th configuration + function configurationName(index: integer): string; + + // project sources --------------------------------------------------------- + + // returns the count of source file in th e project + function sourcesCount: integer; + // returns the source absolute filename. + function sourceAbsolute(index: integer): string; + // returns the source relative filename. + function sourceRelative(index: integer): string; + // returns true if aFilename is a project source. + function isSource(const aFilename: string): boolean; + + // sub routines for the actions -------------------------------------------- + + // tries to compile and returns true if it does + function compile: boolean; + // tries to un the project output and returns true if it did + function run(const runArgs: string = ''): boolean; end; + + (** * An implementer declares some actions on demand. *) diff --git a/src/ce_libmaneditor.pas b/src/ce_libmaneditor.pas index 1cb71e5d..367d12d0 100644 --- a/src/ce_libmaneditor.pas +++ b/src/ce_libmaneditor.pas @@ -187,7 +187,7 @@ begin str := TStringList.Create; try for i := 0 to fProj.Sources.Count-1 do - str.Add(fProj.getAbsoluteSourceName(i)); + str.Add(fProj.sourceAbsolute(i)); // single source libs usually have the structure "src/" if str.Count = 1 then root := ExtractFileDir(str.Strings[0]) @@ -205,10 +205,10 @@ begin with List.Items.Add do begin Caption := ExtractFileNameOnly(fProj.Filename); - if ExtractFileExt(fProj.getOutputFilename) <> libExt then - SubItems.add(fProj.getOutputFilename + libExt) + if ExtractFileExt(fProj.outputFilename) <> libExt then + SubItems.add(fProj.outputFilename + libExt) else - SubItems.add(fProj.getOutputFilename); + SubItems.add(fProj.outputFilename); SubItems.add(root); if not FileExists(SubItems[0]) then dlgOkInfo('the library file does not exist, maybe the project not been already compiled ?'); diff --git a/src/ce_main.pas b/src/ce_main.pas index f6cded57..309a278a 100644 --- a/src/ce_main.pas +++ b/src/ce_main.pas @@ -480,7 +480,7 @@ begin begin itf := TCEMainForm(aSource).fProjectInterface; if itf = nil then exit; - fProject := itf.getFilename; + fProject := itf.filename; end else inherited; end; @@ -492,7 +492,7 @@ begin if aDestination is TCEMainForm then begin itf := TCEMainForm(aDestination).fProjectInterface; - if (itf <> nil) and (itf.getFilename = fProject) then + if (itf <> nil) and (itf.filename = fProject) then exit; TCEMainForm(aDestination).openProj(fProject); end else @@ -1052,7 +1052,7 @@ var begin canClose := false; SaveLastDocsAndProj; - if fProjectInterface <> nil then if fProjectInterface.getIfModified then + if fProjectInterface <> nil then if fProjectInterface.modified then if dlgOkCancel( 'The project modifications are not saved, quit anyway ?') <> mrOK then exit; @@ -1368,10 +1368,10 @@ end; procedure TCEMainForm.actProjOpenContFoldExecute(Sender: TObject); begin if fProjectInterface = nil then exit; - if not fileExists(fProjectInterface.getFilename) then exit; + if not fileExists(fProjectInterface.filename) then exit; // DockMaster.GetAnchorSite(fExplWidg).Show; - fExplWidg.expandPath(extractFilePath(fProjectInterface.getFilename)); + fExplWidg.expandPath(extractFilePath(fProjectInterface.filename)); end; procedure TCEMainForm.actFileNewExecute(Sender: TObject); @@ -1803,12 +1803,12 @@ label _rbld, _run; begin - if fProjectInterface.getBinaryKind <> executable then + if fProjectInterface.binaryKind <> executable then begin dlgOkInfo('Non executable projects cant be run'); exit; end; - if not fileExists(fProjectInterface.getOutputFilename) then + if not fileExists(fProjectInterface.outputFilename) then begin if dlgOkCancel('The project output is missing, build ?') <> mrOK then exit; @@ -1818,10 +1818,10 @@ begin // TODO-cICECommonInterface, add function to check if rebuild needed. if fProjectInterface.getFormat = pfNative then begin - dt := fileAge(fNativeProject.getOutputFilename); + dt := fileAge(fNativeProject.outputFilename); for i := 0 to fNativeProject.Sources.Count-1 do begin - if fileAge(fNativeProject.getAbsoluteSourceName(i)) > dt then + if fileAge(fNativeProject.sourceAbsolute(i)) > dt then if dlgOkCancel('The project sources have changed since last build, rebuild ?') = mrOK then goto _rbld else @@ -1835,7 +1835,7 @@ begin _rbld: fProjectInterface.compile; _run: - if fileExists(fProjectInterface.getOutputFilename) then + if fileExists(fProjectInterface.outputFilename) then fProjectInterface.run; end; @@ -1989,8 +1989,8 @@ end; {$REGION project ---------------------------------------------------------------} procedure TCEMainForm.showProjTitle; begin - if (fProjectInterface <> nil) and fileExists(fProjectInterface.getFilename) then - caption := format('Coedit - %s', [shortenPath(fProjectInterface.getFilename, 30)]) + if (fProjectInterface <> nil) and fileExists(fProjectInterface.filename) then + caption := format('Coedit - %s', [shortenPath(fProjectInterface.filename, 30)]) else caption := 'Coedit'; end; @@ -1998,10 +1998,10 @@ end; procedure TCEMainForm.saveProjSource(const aEditor: TCESynMemo); begin if fProjectInterface = nil then exit; - if fProjectInterface.getFilename <> aEditor.fileName then exit; + if fProjectInterface.filename <> aEditor.fileName then exit; // - aEditor.saveToFile(fProjectInterface.getFilename); - openProj(fProjectInterface.getFilename); + aEditor.saveToFile(fProjectInterface.filename); + openProj(fProjectInterface.filename); end; procedure TCEMainForm.closeProj; @@ -2033,7 +2033,7 @@ end; procedure TCEMainForm.saveProj; begin - fProjectInterface.saveToFile(fProjectInterface.getFilename); + fProjectInterface.saveToFile(fProjectInterface.filename); end; procedure TCEMainForm.saveProjAs(const aFilename: string); @@ -2056,17 +2056,15 @@ end; procedure TCEMainForm.mruProjItemClick(Sender: TObject); begin - if fProjectInterface <> nil then if fProjectInterface.getIfModified then if dlgOkCancel( - 'The project modifications are not saved, continue ?') - = mrCancel then exit; + if (fProjectInterface <> nil) and fProjectInterface.modified and (dlgOkCancel( + 'The project modifications are not saved, continue ?') = mrCancel) then exit; openProj(TMenuItem(Sender).Hint); end; procedure TCEMainForm.actProjNewExecute(Sender: TObject); begin - if fProjectInterface <> nil then if fProjectInterface.getIfModified then if dlgOkCancel( - 'The project modifications are not saved, continue ?') - = mrCancel then exit; + if (fProjectInterface <> nil) and fProjectInterface.modified and (dlgOkCancel( + 'The project modifications are not saved, continue ?') = mrCancel) then exit; closeProj; newNativeProj; end; @@ -2074,9 +2072,8 @@ end; procedure TCEMainForm.actProjCloseExecute(Sender: TObject); begin if fProjectInterface = nil then exit; - if fProjectInterface.getIfModified then if dlgOkCancel( - 'The project modifications are not saved, continue ?') - = mrCancel then exit; + if fProjectInterface.modified and (dlgOkCancel( + 'The project modifications are not saved, continue ?') = mrCancel) then exit; closeProj; end; @@ -2100,13 +2097,13 @@ end; procedure TCEMainForm.actProjSaveExecute(Sender: TObject); begin if fProjectInterface = nil then exit; - if fProjectInterface.getFilename <> '' then saveProj + if fProjectInterface.filename <> '' then saveProj else actProjSaveAs.Execute; end; procedure TCEMainForm.actProjOpenExecute(Sender: TObject); begin - if fProjectInterface <> nil then if fProjectInterface.getIfModified then if dlgOkCancel( + if fProjectInterface <> nil then if fProjectInterface.modified then if dlgOkCancel( 'The project modifications are not saved, continue ?') = mrCancel then exit; with TOpenDialog.Create(nil) do @@ -2130,9 +2127,9 @@ end; procedure TCEMainForm.actProjSourceExecute(Sender: TObject); begin if fProjectInterface = nil then exit; - if not fileExists(fProjectInterface.getFilename) then exit; + if not fileExists(fProjectInterface.filename) then exit; // - openFile(fProjectInterface.getFilename); + openFile(fProjectInterface.filename); //TODO-cDUB: add json highligher to edit json project in CE fDoc.Highlighter := LfmSyn; end; diff --git a/src/ce_mru.pas b/src/ce_mru.pas index 3d916f7c..cc82a00a 100644 --- a/src/ce_mru.pas +++ b/src/ce_mru.pas @@ -214,7 +214,7 @@ var begin if aProject = nil then exit; // - fname := aProject.getFilename; + fname := aProject.filename; if FileExists(fname) then Insert(0, fname); end; diff --git a/src/ce_nativeproject.pas b/src/ce_nativeproject.pas index 42f6251f..59fc10f8 100644 --- a/src/ce_nativeproject.pas +++ b/src/ce_nativeproject.pas @@ -56,9 +56,6 @@ type procedure runProcOutput(sender: TObject); // passes compilation message as "to be guessed" procedure compProcOutput(proc: TProcess); - // - function getFormat: TCEProjectFormat; - function getProject: TObject; protected procedure beforeLoad; override; procedure afterSave; override; @@ -79,28 +76,34 @@ type procedure endUpdate; procedure reset; procedure addDefaults; - function getIfIsSource(const aFilename: string): boolean; - function getAbsoluteSourceName(aIndex: integer): string; - function getAbsoluteFilename(const aFilename: string): string; procedure addSource(const aFilename: string); function addConfiguration: TCompilerConfiguration; procedure getOpts(const aList: TStrings); + // + function getFormat: TCEProjectFormat; + function getProject: TObject; + function filename: string; + function basePath: string; + function outputFilename: string; + function binaryKind: TProjectBinaryKind; + function getCommandLine: string; + function modified: boolean; + // + function configurationCount: integer; + procedure setActiveConfiguration(index: integer); + function configurationName(index: integer): string; + // + function sourcesCount: integer; + function sourceRelative(index: integer): string; + function sourceAbsolute(index: integer): string; + function isSource(const aFilename: string): boolean; + // function run(const runArgs: string = ''): Boolean; function compile: Boolean; // - function getIfModified: boolean; - function getOutputFilename: string; - function getConfigurationCount: integer; - procedure setActiveConfiguration(index: integer); - function getConfigurationName(index: integer): string; - function getFilename: string; - function getBinaryKind: TProjectBinaryKind; - function getCommandLine: string; - // property configuration[ix: integer]: TCompilerConfiguration read getConfig; property currentConfiguration: TCompilerConfiguration read getCurrConf; property onChange: TNotifyEvent read fOnChange write fOnChange; - property modified: Boolean read fModified; property canBeRun: Boolean read fCanBeRun; end; @@ -423,28 +426,16 @@ begin end; end; -function TCENativeProject.getIfIsSource(const aFilename: string): boolean; +function TCENativeProject.isSource(const aFilename: string): boolean; var i: Integer; begin for i := 0 to fSrcs.Count-1 do - if getAbsoluteSourceName(i) = aFilename then + if sourceAbsolute(i) = aFilename then exit(true); exit(false); end; -function TCENativeProject.getAbsoluteSourceName(aIndex: integer): string; -begin - if aIndex < 0 then exit(''); - if aIndex > fSrcs.Count-1 then exit(''); - result := expandFileNameEx(fBasePath, fSrcs.Strings[aIndex]); -end; - -function TCENativeProject.getAbsoluteFilename(const aFilename: string): string; -begin - result := expandFileNameEx(fBasePath, aFilename); -end; - procedure TCENativeProject.afterSave; begin fModified := false; @@ -474,7 +465,7 @@ var if fSrcs.Count = 0 then exit; allMissing := true; for i:= 0 to fSrcs.Count-1 do - if fileExists(getAbsoluteSourceName(i)) then + if fileExists(sourceAbsolute(i)) then allMissing := false; if not allMissing then exit; if dlgOkCancel( 'The project source(s) are all missing. ' + LineEnding + @@ -507,7 +498,7 @@ var begin for i:= fSrcs.Count-1 downto 0 do begin - oldsrc := getAbsoluteSourceName(i); + oldsrc := sourceAbsolute(i); if fileExists(oldsrc) then continue; if dlgOkCancel(format('a particular project source file ("%s") is missing. ' + LineEnding + 'This happends if a source file has been moved, renamed ' + @@ -603,7 +594,7 @@ begin if fOutputFilename <> '' then begin fOutputFilename := symbolExpander.get(fOutputFilename); - fOutputFilename := getAbsoluteFilename(fOutputFilename); + fOutputFilename := expandFilenameEx(fBasePath, fOutputFilename); {$IFDEF WINDOWS} // field is specified without ext or with a dot in the name. // DMD will add the ext. (e.g: "-ofresourced") @@ -758,14 +749,14 @@ begin until prm = ''; end; // - if not fileExists(getOutputFilename) then + if not fileExists(outputFilename) then begin - getMessageDisplay.message('output executable missing: ' + shortenPath(getOutputFilename, 25), + getMessageDisplay.message('output executable missing: ' + shortenPath(outputFilename, 25), self as ICECommonProject, amcProj, amkErr); exit; end; // - fRunner.Executable := getOutputFilename; + fRunner.Executable := outputFilename; if fRunner.CurrentDirectory = '' then fRunner.CurrentDirectory := extractFilePath(fRunner.Executable); if poUsePipes in fRunner.Options then begin @@ -819,17 +810,12 @@ begin end; end; -function TCENativeProject.getIfModified: boolean; -begin - exit(fModified); -end; - -function TCENativeProject.getOutputFilename: string; +function TCENativeProject.outputFilename: string; begin exit(fOutputFilename); end; -function TCENativeProject.getConfigurationCount: integer; +function TCENativeProject.configurationCount: integer; begin exit(fConfigs.Count); end; @@ -839,19 +825,29 @@ begin setConfIx(index); end; -function TCENativeProject.getConfigurationName(index: integer): string; +function TCENativeProject.configurationName(index: integer): string; begin if index > fConfigs.Count -1 then index := fConfigs.Count -1; if index < 0 then index := 0; result := getConfig(index).name; end; -function TCENativeProject.getFilename: string; +function TCENativeProject.filename: string; begin exit(fFilename); end; -function TCENativeProject.getBinaryKind: TProjectBinaryKind; +function TCENativeProject.modified: boolean; +begin + exit(fModified); +end; + +function TCENativeProject.basePath: string; +begin + exit(fBasePath); +end; + +function TCENativeProject.binaryKind: TProjectBinaryKind; begin exit(currentConfiguration.outputOptions.binaryKind); end; @@ -870,6 +866,27 @@ begin end; end; +function TCENativeProject.sourcesCount: integer; +begin + exit(fSrcs.Count); +end; + +function TCENativeProject.sourceRelative(index: integer): string; +begin + exit(fSrcs.Strings[index]); +end; + +function TCENativeProject.sourceAbsolute(index: integer): string; +var + fname: string; +begin + fname := fSrcs.Strings[index]; + if FileExists(fname) then + result := fname + else + result := expandFilenameEx(fBasePath, fname); +end; + function isValidNativeProject(const filename: string): boolean; var maybe: TCENativeProject; diff --git a/src/ce_projinspect.pas b/src/ce_projinspect.pas index 78721291..18cd82f9 100644 --- a/src/ce_projinspect.pas +++ b/src/ce_projinspect.pas @@ -211,7 +211,7 @@ begin if Tree.Selected = nil then exit; if (Tree.Selected.Parent = fFileNode) then - fLastFileOrFolder := fProject.getAbsoluteFilename(tree.Selected.Text) + fLastFileOrFolder := expandFilenameEx(fProject.basePath,tree.Selected.Text) else fLastFileOrFolder := tree.Selected.Text; end; @@ -229,7 +229,7 @@ begin fname := Tree.Selected.Text; i := fProject.Sources.IndexOf(fname); if i > -1 then - fname := fProject.getAbsoluteSourceName(i); + fname := fProject.sourceAbsolute(i); if isEditable(ExtractFileExt(fname)) and fileExists(fname) then getMultiDocHandler.openDocument(fname); end @@ -317,13 +317,13 @@ begin fname := Tree.Selected.Text; i := fProject.Sources.IndexOf(fname); if i = -1 then exit; - fname := fProject.getAbsoluteSourceName(i); + fname := fProject.sourceAbsolute(i); dir := extractFilePath(fname); if not DirectoryExists(dir) then exit; // fProject.beginUpdate; for i:= fProject.Sources.Count-1 downto 0 do - if extractFilePath(fProject.getAbsoluteSourceName(i)) = dir then + if extractFilePath(fProject.sourceAbsolute(i)) = dir then fProject.Sources.Delete(i); fProject.endUpdate; end; @@ -427,7 +427,7 @@ begin begin if fold = '' then continue; - fold := fProject.getAbsoluteFilename(fold); + fold := expandFilenameEx(fProject.basePath, fold); fold := symbolExpander.get(fold); itm := Tree.Items.AddChild(fImpsNode, fold); itm.ImageIndex := 5; @@ -439,7 +439,7 @@ begin begin if fold = '' then continue; - fold := fProject.getAbsoluteFilename(fold); + fold := expandFilenameEx(fProject.basePath, fold); fold := symbolExpander.get(fold); itm := Tree.Items.AddChild(fInclNode, fold); itm.ImageIndex := 5; @@ -451,7 +451,7 @@ begin begin if src = '' then continue; - src := fProject.getAbsoluteFilename(src); + src := expandFilenameEx(fProject.basePath, src); src := symbolExpander.get(src); lst := TStringList.Create; try diff --git a/src/ce_symstring.pas b/src/ce_symstring.pas index d5c468ce..97362719 100644 --- a/src/ce_symstring.pas +++ b/src/ce_symstring.pas @@ -181,27 +181,18 @@ begin // project interface if hasProjItf then begin - fSymbols[CPF] := fProjInterface.getFilename; + fname := fProjInterface.filename; + fSymbols[CPF] := fname; fSymbols[CPP] := ExtractFilePath(fSymbols[CPF]); fSymbols[CPN] := stripFileExt(extractFileName(fSymbols[CPF])); - end; - // TODO-cDUB: move to upper block expansion of CPO, CPFS & CPCD when implemented in ICECOmmonProject - if hasNativeProj then - begin - if fileExists(fProj.fileName) then - begin - fSymbols[CPR] := fProj.getAbsoluteFilename(fProj.RootFolder); - fSymbols[CPO] := fProj.getOutputFilename; - if fSymbols[CPR] = '' then - fSymbols[CPR] := fSymbols[CPP]; - end; - if fProj.Sources.Count <> 0 then + fSymbols[CPO] := fProjInterface.outputFilename; + if fProjInterface.sourcesCount <> 0 then begin str := TStringList.Create; try - for i := 0 to fProj.Sources.Count-1 do + for i := 0 to fProjInterface.sourcesCount-1 do begin - fname := fProj.getAbsoluteSourceName(i); + fname := fProjInterface.sourceAbsolute(i); if not isEditable(ExtractFileExt(fname)) then continue; str.Add(fname); @@ -216,6 +207,15 @@ begin end; end; end; + if hasNativeProj then + begin + if fileExists(fProj.fileName) then + begin + fSymbols[CPR] := expandFilenameEx(fProj.basePath, fProj.RootFolder); + if fSymbols[CPR] = '' then + fSymbols[CPR] := fSymbols[CPP]; + end; + end; end; function TCESymbolExpander.get(const symString: string): string; diff --git a/src/ce_todolist.pas b/src/ce_todolist.pas index c960a24d..f92fc193 100644 --- a/src/ce_todolist.pas +++ b/src/ce_todolist.pas @@ -380,7 +380,7 @@ begin if ((fProj <> nil) and (fDoc = nil)) then exit(tcProject); // - if fProj.getIfIsSource(fDoc.fileName) then + if fProj.isSource(fDoc.fileName) then exit(tcProject) else exit(tcFile);