diff --git a/src/ce_common.pas b/src/ce_common.pas index faeb17cc..509e8001 100644 --- a/src/ce_common.pas +++ b/src/ce_common.pas @@ -5,7 +5,7 @@ unit ce_common; interface uses - Classes, SysUtils, ActnList, dialogs, forms; + Classes, SysUtils, ActnList, dialogs, forms, controls; const @@ -19,6 +19,7 @@ type TMRUList = class(TStringList) private fMaxCount: Integer; + fObj: TObject; protected procedure setMaxCount(aValue: Integer); function checkItem(const S: string): boolean; virtual; @@ -28,6 +29,7 @@ type public constructor Create; procedure Insert(Index: Integer; const S: string); override; + property objectTag: TObject read fObj write fObj; end; (** @@ -81,6 +83,12 @@ type *) function uniqueObjStr(const aObject: Tobject): string; + (** + * Reduce a filename if its length is over the threshold defined by charThresh. + * Even if the result is not usable anymore, it avoids any "visually-overloaded" MRU menus. + *) + function displayShortFilename(const aPath: string; charThresh: Word = 80): string; + implementation constructor TMRUList.Create; @@ -291,4 +299,27 @@ begin {$HINTS ON}{$WARNINGS ON} end; +function displayShortFilename(const aPath: string; charThresh: Word = 80): string; +var + i: NativeInt; + sepCnt: NativeInt; + drv: string; + pth1: string; +begin + sepCnt := 0; + if length(aPath) <= charThresh then + exit(aPath); + + drv := extractFileDrive(aPath); + i := length(aPath); + while(i <> length(drv)+1) do + begin + Inc(sepCnt, Byte(aPath[i] = directorySeparator)); + if sepCnt = 2 then break; + Dec(i); + end; + pth1 := aPath[i..length(aPath)]; + exit( format('%s%s...%s',[drv,directorySeparator,pth1]) ); +end; + end. diff --git a/src/ce_dmdwrap.pas b/src/ce_dmdwrap.pas index 34b54ad0..4556aea5 100644 --- a/src/ce_dmdwrap.pas +++ b/src/ce_dmdwrap.pas @@ -97,7 +97,7 @@ type (***************************************************************************** * Encapsulates the options/args related to the analysis & the code gen. *) - TOutputOpts= class(TOptsGroup) + TOutputOpts = class(TOptsGroup) private fTrgKind: TTargetSystem; fBinKind: TBinaryKind; diff --git a/src/ce_main.lfm b/src/ce_main.lfm index f053778d..2a217bce 100644 --- a/src/ce_main.lfm +++ b/src/ce_main.lfm @@ -135,6 +135,10 @@ object CEMainForm: TCEMainForm D0FF3C94D1FF3E97D3EE000000000000000000000000FFFFFF00 } end + object mnuItemMruFile: TMenuItem + Caption = 'Open recent file' + ImageIndex = 9 + end object MenuItem43: TMenuItem Action = actFileClose Bitmap.Data = { @@ -861,6 +865,10 @@ object CEMainForm: TCEMainForm D0FF3C94D1FF3E97D3EE000000000000000000000000FFFFFF00 } end + object mnuItemMruProj: TMenuItem + Caption = 'Open recent project' + ImageIndex = 9 + end object MenuItem42: TMenuItem Action = actProjClose Bitmap.Data = { diff --git a/src/ce_main.pas b/src/ce_main.pas index 90390c07..115ee5c2 100644 --- a/src/ce_main.pas +++ b/src/ce_main.pas @@ -98,6 +98,8 @@ type MenuItem52: TMenuItem; MenuItem53: TMenuItem; MenuItem54: TMenuItem; + mnuItemMruFile: TMenuItem; + mnuItemMruProj: TMenuItem; mnuItemWin: TMenuItem; MenuItem4: TMenuItem; MenuItem5: TMenuItem; @@ -151,6 +153,8 @@ type fPrjCfWidg: TCEProjectConfigurationWidget; fStExpWidg: TCEStaticExplorerWidget; fFindWidg: TCESearchWidget; + fProjMru: TMruFileList; + fFileMru: TMruFileList; // widget interfaces subroutines procedure checkWidgetActions(const aWidget: TCEWidget); @@ -178,6 +182,12 @@ type procedure closeProj; procedure addSource(const aFilename: string); + // mru + procedure mruChange(Sender: TObject); + procedure mruFileItemClick(Sender: TObject); + procedure mruProjItemClick(Sender: TObject); + procedure mruClearClick(Sender: TObject); + public constructor create(aOwner: TComponent); override; destructor destroy; override; @@ -210,6 +220,13 @@ var begin inherited create(aOwner); // + fProjMru := TMruFileList.Create; + fFileMru := TMruFileList.Create; + fProjMru.objectTag := mnuItemMruProj; + fFileMru.objectTag := mnuItemMruFile; + fProjMru.OnChange := @mruChange; + fFileMru.OnChange := @mruChange; + // fWidgList := TCEWidgetList.Create; fMesgWidg := TCEMessagesWidget.create(nil); fEditWidg := TCEEditorWidget.create(nil); @@ -270,6 +287,8 @@ begin fStExpWidg.Free; fFindWidg.Free; fProject.Free; + fProjMru.Free; + fFileMru.Free; // inherited; end; @@ -370,6 +389,60 @@ begin end; end; +procedure TCEMainForm.mruChange(Sender: TObject); +var + srcLst: TMruFileList; + trgMnu: TMenuItem; + itm: TMenuItem; + fname: string; + clickTrg: TNotifyEvent; +begin + srcLst := TMruFileList(Sender); + if srcLst = nil then exit; + trgMnu := TMenuItem(srcLst.objectTag); + if trgMnu = nil then exit; + + if fUpdateCount > 0 then exit; + Inc(fUpdateCount); + try + if srcLst = fFileMru then + clickTrg := @mruFileItemClick + else if srcLst = fProjMru then + clickTrg := @mruProjItemClick; + + trgMnu.Clear; + + itm := TMenuItem.Create(trgMnu); + itm.Caption := 'Clear'; + itm.OnClick := @mruClearClick; + itm.Tag := PtrInt(srcLst); + trgMnu.Add(itm); + trgMnu.AddSeparator; + + for fname in srcLst do + begin + itm := TMenuItem.Create(trgMnu); + itm.Hint := fname; + itm.Caption := displayShortFilename(fname, 50); + itm.OnClick := clickTrg; + trgMnu.Add(itm); + end; + + finally + Dec(fUpdateCount); + end; +end; + +procedure TCEMainForm.mruClearClick(Sender: TObject); +var + srcLst: TMruFileList; +begin + srcLst := TMruFileList(TmenuItem(Sender).Tag); + if srcLst = nil then exit; + // + srcLst.Clear; +end; + procedure TCEMainForm.FormShow(Sender: TObject); begin end; @@ -429,6 +502,7 @@ begin fEditWidg.editor[i].Lines.LoadFromFile(aFilename); fEditWidg.editor[i].fileName := aFilename; fEditWidg.focusedEditorChanged; + fFileMru.Insert(0,aFilename); end; procedure TCEMainForm.saveFile(const edIndex: NativeInt); @@ -468,6 +542,7 @@ begin finally fEditWidg.editor[edIndex].fileName := aFilename; fEditWidg.editor[edIndex].modified := false; + fFileMru.Insert(0,aFilename); end; end; @@ -489,6 +564,11 @@ begin fWidgList.widget[i].docFocused(fEditWidg.editor[aIndex]); end; +procedure TCEMainForm.mruFileItemClick(Sender: TObject); +begin + openFile(TMenuItem(Sender).Hint); +end; + procedure TCEMainForm.actFileOpenExecute(Sender: TObject); begin if fEditWidg = nil then exit; @@ -999,6 +1079,7 @@ procedure TCEMainForm.saveProjAs(const aFilename: string); begin fProject.fileName := aFilename; fProject.saveToFile(fProject.fileName); + fProjMru.Insert(0,fProject.fileName); end; procedure TCEMainForm.openProj(const aFilename: string); @@ -1006,6 +1087,12 @@ begin closeProj; newProj; fProject.loadFromFile(aFilename); + fProjMru.Insert(0,aFilename); +end; + +procedure TCEMainForm.mruProjItemClick(Sender: TObject); +begin + openProj(TMenuItem(Sender).Hint); end; procedure TCEMainForm.actProjNewExecute(Sender: TObject); diff --git a/src/ce_search.lfm b/src/ce_search.lfm index e7c4035a..926c35de 100644 --- a/src/ce_search.lfm +++ b/src/ce_search.lfm @@ -1,20 +1,20 @@ inherited CESearchWidget: TCESearchWidget - Left = 1468 - Height = 237 - Top = 516 + Left = 1492 + Height = 239 + Top = 468 Width = 394 Caption = 'Search & replace' - ClientHeight = 237 + ClientHeight = 239 ClientWidth = 394 inherited Back: TPanel - Height = 237 + Height = 239 Width = 394 - ClientHeight = 237 + ClientHeight = 239 ClientWidth = 394 inherited Content: TPanel - Height = 237 + Height = 239 Width = 394 - ClientHeight = 237 + ClientHeight = 239 ClientWidth = 394 object cbToFind: TComboBox[0] Left = 4 @@ -30,7 +30,7 @@ inherited CESearchWidget: TCESearchWidget object btnFind: TBitBtn[1] Left = 4 Height = 24 - Top = 153 + Top = 155 Width = 386 Align = alBottom BorderSpacing.Around = 4 @@ -76,7 +76,7 @@ inherited CESearchWidget: TCESearchWidget object btnReplace: TBitBtn[2] Left = 4 Height = 24 - Top = 181 + Top = 183 Width = 386 Align = alBottom BorderSpacing.Around = 4 @@ -121,13 +121,13 @@ inherited CESearchWidget: TCESearchWidget end object grpOpts: TGroupBox[3] Left = 4 - Height = 88 + Height = 90 Top = 61 Width = 386 Align = alClient BorderSpacing.Around = 4 Caption = 'Options' - ClientHeight = 70 + ClientHeight = 72 ClientWidth = 382 TabOrder = 3 object chkWWord: TCheckBox @@ -176,7 +176,7 @@ inherited CESearchWidget: TCESearchWidget object btnReplaceAll: TBitBtn[4] Left = 4 Height = 24 - Top = 209 + Top = 211 Width = 386 Align = alBottom BorderSpacing.Around = 4 diff --git a/src/ce_staticexplorer.lfm b/src/ce_staticexplorer.lfm index 3f0127b2..ec8a7809 100644 --- a/src/ce_staticexplorer.lfm +++ b/src/ce_staticexplorer.lfm @@ -1,7 +1,7 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget - Left = 999 + Left = 1592 Height = 276 - Top = 284 + Top = 609 Width = 261 Caption = 'Static explorer' ClientHeight = 276 @@ -29,13 +29,14 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget HideSelection = False Images = imgList ReadOnly = True + RightClickSelect = True RowSelect = True ScrollBars = ssAutoBoth SelectionColor = clActiveBorder TabOrder = 0 OnDeletion = TreeDeletion OnKeyPress = TreeKeyPress - Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] + Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] Items.Data = { F9FFFFFF02000A000000000000000000000000000000FFFFFFFF000000000000 00000005000000416C6961730100000001000000FFFFFFFFFFFFFFFF00000000