diff --git a/components/todolist/tododlg.lfm b/components/todolist/tododlg.lfm index 4419bae775..0563669801 100644 --- a/components/todolist/tododlg.lfm +++ b/components/todolist/tododlg.lfm @@ -20,7 +20,7 @@ object TodoDialog: TTodoDialog AnchorSideLeft.Control = Owner AnchorSideTop.Control = Owner Left = 8 - Height = 19 + Height = 18 Top = 4 Width = 29 BorderSpacing.Left = 8 @@ -35,9 +35,9 @@ object TodoDialog: TTodoDialog AnchorSideTop.Side = asrBottom AnchorSideBottom.Control = PriorityEdit Left = 8 - Height = 19 - Top = 93 - Width = 46 + Height = 18 + Top = 95 + Width = 45 Anchors = [akLeft, akBottom] BorderSpacing.Top = 4 BorderSpacing.Bottom = 2 @@ -48,8 +48,8 @@ object TodoDialog: TTodoDialog AnchorSideLeft.Control = OwnerEdit AnchorSideBottom.Control = OwnerEdit Left = 74 - Height = 19 - Top = 91 + Height = 18 + Top = 95 Width = 43 Anchors = [akLeft, akBottom] BorderSpacing.Top = 4 @@ -61,9 +61,9 @@ object TodoDialog: TTodoDialog AnchorSideLeft.Control = CategoryEdit AnchorSideBottom.Control = CategoryEdit Left = 235 - Height = 19 - Top = 91 - Width = 58 + Height = 18 + Top = 95 + Width = 56 Anchors = [akLeft, akBottom] BorderSpacing.Top = 4 BorderSpacing.Bottom = 2 @@ -78,8 +78,8 @@ object TodoDialog: TTodoDialog AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = PriorityLabel Left = 8 - Height = 64 - Top = 25 + Height = 67 + Top = 24 Width = 381 Anchors = [akTop, akLeft, akRight, akBottom] ScrollBars = ssAutoBoth @@ -92,8 +92,8 @@ object TodoDialog: TTodoDialog AnchorSideRight.Control = Bevel2 AnchorSideBottom.Control = grpboxToDoType Left = 74 - Height = 31 - Top = 112 + Height = 32 + Top = 115 Width = 153 Anchors = [akLeft, akRight, akBottom] BorderSpacing.Left = 8 @@ -108,8 +108,8 @@ object TodoDialog: TTodoDialog AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = grpboxToDoType Left = 235 - Height = 31 - Top = 112 + Height = 32 + Top = 115 Width = 154 Anchors = [akLeft, akRight, akBottom] BorderSpacing.Right = 8 @@ -119,8 +119,8 @@ object TodoDialog: TTodoDialog object BtnPanel: TButtonPanel AnchorSideTop.Side = asrBottom Left = 6 - Height = 34 - Top = 250 + Height = 29 + Top = 255 Width = 385 OKButton.Name = 'OKButton' OKButton.DefaultCaption = True @@ -139,8 +139,8 @@ object TodoDialog: TTodoDialog AnchorSideTop.Side = asrBottom AnchorSideBottom.Control = grpboxToDoType Left = 8 - Height = 29 - Top = 114 + Height = 32 + Top = 115 Width = 58 Anchors = [akLeft, akBottom] BorderSpacing.Bottom = 8 @@ -150,18 +150,18 @@ object TodoDialog: TTodoDialog AnchorSideTop.Side = asrBottom Left = 8 Height = 66 - Top = 151 + Top = 155 Width = 381 Align = alBottom BorderSpacing.Left = 8 BorderSpacing.Right = 8 Caption = 'ToDo type' - ClientHeight = 46 - ClientWidth = 379 + ClientHeight = 36 + ClientWidth = 377 TabOrder = 4 object rdoToDo: TRadioButton Left = 6 - Height = 21 + Height = 22 Top = 0 Width = 56 BorderSpacing.Left = 6 @@ -177,9 +177,9 @@ object TodoDialog: TTodoDialog AnchorSideLeft.Control = grpboxToDoType AnchorSideLeft.Side = asrCenter Left = 162 - Height = 21 + Height = 22 Top = 0 - Width = 58 + Width = 57 Anchors = [akTop] Caption = 'Done' TabOrder = 1 @@ -189,10 +189,10 @@ object TodoDialog: TTodoDialog Tag = 2 AnchorSideRight.Control = grpboxToDoType AnchorSideRight.Side = asrBottom - Left = 318 - Height = 21 + Left = 317 + Height = 22 Top = 0 - Width = 55 + Width = 54 Anchors = [akTop, akRight] BorderSpacing.Right = 6 Caption = 'Note' @@ -203,8 +203,8 @@ object TodoDialog: TTodoDialog object chkAlternateTokens: TCheckBox AnchorSideTop.Side = asrBottom Left = 8 - Height = 21 - Top = 223 + Height = 22 + Top = 227 Width = 381 Align = alBottom Anchors = [akLeft, akBottom] diff --git a/components/todolist/tododlg.pas b/components/todolist/tododlg.pas index 606f57202b..08e708630e 100644 --- a/components/todolist/tododlg.pas +++ b/components/todolist/tododlg.pas @@ -78,11 +78,15 @@ var ViewToDoListCmd: TIDECommand; procedure Register; -procedure InsertToDoForActiveSourceEditor(Sender: TObject); +// ToDo List procedure ViewToDoList(Sender: TObject); procedure CreateIDEToDoWindow(Sender: TObject; aFormName: string; var AForm: TCustomForm; DoDisableAutoSizing: boolean); -function ExecuteTodoDialog: TTodoItem; +// ToDo Dialog +function ExecuteTodoDialog(const aCaption: string; var aTodoItem: TTodoItem): TModalResult; +procedure InsertToDoForActiveSourceEditor(Sender: TObject); +procedure EditToDo(aTodoItem: TTodoItem); + implementation @@ -137,23 +141,6 @@ begin IDEWindowCreators.Add(ToDoWindowName,@CreateIDEToDoWindow,nil,'250','250','',''); end; -procedure InsertToDoForActiveSourceEditor(Sender: TObject); -var - SrcEdit: TSourceEditorInterface; - aTodoItem: TTodoItem; -begin - SrcEdit:=SourceEditorManagerIntf.ActiveEditor; - if SrcEdit=nil then exit; - if SrcEdit.ReadOnly then exit; - aTodoItem := ExecuteTodoDialog; - try - if Assigned(aTodoItem) then - SrcEdit.Selection:=aTodoItem.AsComment; - finally - aTodoItem.Free; - end; -end; - procedure ViewToDoList(Sender: TObject); var Pkg: TIDEPackage; @@ -171,41 +158,92 @@ end; procedure CreateIDEToDoWindow(Sender: TObject; aFormName: string; var AForm: TCustomForm; DoDisableAutoSizing: boolean); begin - if CompareText(aFormName,ToDoWindowName)<>0 then exit; + Assert(aFormName=ToDoWindowName, 'CreateIDEToDoWindow: aFormName<>ToDoWindowName'); IDEWindowCreators.CreateForm(IDETodoWindow,TIDETodoWindow,DoDisableAutoSizing, LazarusIDE.OwningComponent); + IDETodoWindow.OnEditItem:=@EditToDo; // Edit the selected ToDo item. AForm:=IDETodoWindow; end; -function ExecuteTodoDialog: TTodoItem; +function ExecuteTodoDialog(const aCaption: string; var aTodoItem: TTodoItem): TModalResult; var aTodoDialog: TTodoDialog; begin - Result := nil; aTodoDialog := TTodoDialog.Create(nil); + aTodoDialog.Caption:=aCaption; + if Assigned(aTodoItem) then begin + aTodoDialog.CategoryEdit.Text := aTodoItem.Category; + aTodoDialog.grpboxToDoType.Tag := PtrInt(aTodoItem.ToDoType); + case aTodoItem.ToDoType of + tdToDo: aTodoDialog.rdoToDo.Checked := True; + tdDone: aTodoDialog.rdoDone.Checked := True; + tdNote: aTodoDialog.rdoNote.Checked := True; + end; + aTodoDialog.chkAlternateTokens.Checked := aTodoItem.TokenStyle=tsAlternate; + aTodoDialog.OwnerEdit.Text := aTodoItem.Owner; + aTodoDialog.TodoMemo.Text := aTodoItem.Text; + aTodoDialog.PriorityEdit.Value := aTodoItem.Priority; + end; aTodoDialog.ShowModal; - if aTodoDialog.ModalResult = mrOk then + Result := aTodoDialog.ModalResult; + if Result = mrOk then begin - Result := TTodoItem.Create; - Result.Category := aTodoDialog.CategoryEdit.Text; - Result.ToDoType := TToDoType(aTodoDialog.grpboxToDoType.Tag); + if aTodoItem=nil then begin + aTodoItem := TTodoItem.Create; + aTodoItem.CommentType := '{'; + aTodoItem.HasColon := True; + end; + aTodoItem.Category := aTodoDialog.CategoryEdit.Text; + aTodoItem.ToDoType := TToDoType(aTodoDialog.grpboxToDoType.Tag); if aTodoDialog.chkAlternateTokens.Checked then - Result.TokenStyle:=tsAlternate + aTodoItem.TokenStyle:=tsAlternate else - Result.TokenStyle:=tsNormal; - Result.Owner := aTodoDialog.OwnerEdit.Text; - Result.Text := aTodoDialog.TodoMemo.Text; - Result.Priority := aTodoDialog.PriorityEdit.Value; + aTodoItem.TokenStyle:=tsNormal; + aTodoItem.Owner := aTodoDialog.OwnerEdit.Text; + aTodoItem.Text := aTodoDialog.TodoMemo.Text; + aTodoItem.Priority := aTodoDialog.PriorityEdit.Value; end; aTodoDialog.Free; end; +procedure InsertToDoForActiveSourceEditor(Sender: TObject); +var + SrcEdit: TSourceEditorInterface; + TodoItem: TTodoItem; +begin + SrcEdit := SourceEditorManagerIntf.ActiveEditor; + if (SrcEdit=nil) or SrcEdit.ReadOnly then exit; + TodoItem := nil; + if ExecuteTodoDialog(lisTDDInsertToDo, TodoItem) <> mrOK then exit; + try + if Assigned(TodoItem) then + SrcEdit.Selection := TodoItem.AsComment; + finally + TodoItem.Free; + end; + IDETodoWindow.UpdateTodos; +end; + +procedure EditToDo(aTodoItem: TTodoItem); +var + SrcEdit: TSourceEditorInterface; + EndPos: TPoint; +begin + SrcEdit := SourceEditorManagerIntf.ActiveEditor; + if (SrcEdit=nil) or SrcEdit.ReadOnly then exit; + if ExecuteTodoDialog(lisTDDEditToDo, aTodoItem) <> mrOK then exit; + EndPos.X := aTodoItem.CodePos.X + aTodoItem.CommentLen; + EndPos.Y := aTodoItem.CodePos.Y; // ToDo -oJuha : Deal with multiline comments. + SrcEdit.SelectText(aTodoItem.CodePos, EndPos); + SrcEdit.Selection := aTodoItem.AsComment; + IDETodoWindow.UpdateTodos; { TODO -oJuha : Retain selection in the list. } +end; + { TTodoDialog } procedure TTodoDialog.FormCreate(Sender: TObject); begin ActiveControl:=TodoMemo; - Caption:=lisTDDInsertToDo; TodoLabel.Caption:=lisPkgFileTypeText; PriorityLabel.Caption:=lisToDoLPriority; OwnerLabel.Caption:=lisToDoLOwner; diff --git a/components/todolist/todolist.lfm b/components/todolist/todolist.lfm index 8a699bba13..479cc79d48 100644 --- a/components/todolist/todolist.lfm +++ b/components/todolist/todolist.lfm @@ -14,7 +14,7 @@ object IDETodoWindow: TIDETodoWindow OnCloseQuery = FormCloseQuery OnCreate = FormCreate OnKeyDown = FormKeyDown - OnShow = DoUpdateToDos + OnShow = acRefreshExecute object lvTodo: TListView Left = 6 Height = 176 @@ -29,7 +29,7 @@ object IDETodoWindow: TIDETodoWindow item AutoSize = True Caption = 'Type' - Width = 40 + Width = 100 end item Caption = 'Description' @@ -38,26 +38,27 @@ object IDETodoWindow: TIDETodoWindow item AutoSize = True Caption = 'Priority' - Width = 53 + Width = 100 end item AutoSize = True Caption = 'Module' - Width = 56 + Width = 100 end item AutoSize = True Caption = 'Line' - Width = 37 + Width = 100 end item AutoSize = True Caption = 'Owner' + Width = 100 end item AutoSize = True Caption = 'Category' - Width = 63 + Width = 100 end> ReadOnly = True RowSelect = True @@ -81,10 +82,10 @@ object IDETodoWindow: TIDETodoWindow ShowCaptions = True ShowHint = True TabOrder = 0 - object tbRefresh: TToolButton + object tbEdit: TToolButton Left = 1 Top = 2 - Action = acRefresh + Action = acEdit AutoSize = True end object tbGoto: TToolButton @@ -93,26 +94,34 @@ object IDETodoWindow: TIDETodoWindow Action = acGoto AutoSize = True end - object tbExport: TToolButton - Left = 95 - Top = 2 - Action = acExport - AutoSize = True - end object N1: TToolButton - Left = 142 + Left = 95 Height = 46 Top = 2 Caption = 'N1' Style = tbsDivider end - object tbHelp: TToolButton - Left = 501 + object tbRefresh: TToolButton + Left = 100 Top = 2 - Action = acHelp + Action = acRefresh + AutoSize = True + end + object tbExport: TToolButton + Left = 155 + Top = 2 + Action = acExport + AutoSize = True + end + object N2: TToolButton + Left = 203 + Height = 46 + Top = 2 + Caption = 'N2' + Style = tbsDivider end object pnlShowWhat: TPanel - Left = 147 + Left = 208 Height = 46 Top = 2 Width = 115 @@ -122,7 +131,7 @@ object IDETodoWindow: TIDETodoWindow TabOrder = 0 object lblShowWhat: TLabel Left = 4 - Height = 15 + Height = 18 Top = 0 Width = 107 Align = alTop @@ -134,14 +143,14 @@ object IDETodoWindow: TIDETodoWindow object cboShowWhat: TComboBox AnchorSideBottom.Control = pnlShowWhat Left = 6 - Height = 23 - Top = 17 + Height = 24 + Top = 20 Width = 103 Align = alClient BorderSpacing.Left = 4 BorderSpacing.Right = 4 BorderSpacing.Around = 2 - ItemHeight = 15 + ItemHeight = 24 ItemIndex = 0 Items.Strings = ( 'All' @@ -152,42 +161,35 @@ object IDETodoWindow: TIDETodoWindow 'ToDo and Notes' 'Done and Notes' ) - OnChange = DoUpdateToDos TabOrder = 0 Text = 'All' + OnChange = acRefreshExecute end end object N3: TToolButton - Left = 496 + Left = 323 Height = 46 Top = 2 Caption = 'N3' Style = tbsDivider end - object N2: TToolButton - Left = 262 - Height = 46 - Top = 2 - Caption = 'N2' - Style = tbsDivider - end object pnlOptions: TPanel - Left = 267 - Height = 36 + Left = 328 + Height = 42 Top = 2 - Width = 229 + Width = 281 AutoSize = True BevelOuter = bvNone - ClientHeight = 36 - ClientWidth = 229 + ClientHeight = 42 + ClientWidth = 281 TabOrder = 1 object lblOptions: TLabel AnchorSideLeft.Control = pnlOptions AnchorSideTop.Control = pnlOptions Left = 4 - Height = 15 + Height = 18 Top = 0 - Width = 42 + Width = 49 BorderSpacing.Left = 4 BorderSpacing.Bottom = 2 Caption = 'Options' @@ -198,73 +200,89 @@ object IDETodoWindow: TIDETodoWindow AnchorSideTop.Side = asrBottom AnchorSideBottom.Side = asrBottom Left = 4 - Height = 19 - Top = 17 - Width = 49 + Height = 22 + Top = 20 + Width = 61 BorderSpacing.Left = 4 BorderSpacing.Right = 4 Caption = '&Listed' Checked = True - OnChange = DoUpdateToDos State = cbChecked TabOrder = 0 + OnChange = acRefreshExecute end object chkUsed: TCheckBox AnchorSideLeft.Control = chkListed AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = chkListed - Left = 57 - Height = 19 - Top = 17 - Width = 44 + Left = 69 + Height = 22 + Top = 20 + Width = 56 BorderSpacing.Left = 4 BorderSpacing.Right = 4 Caption = '&Used' Checked = True - OnChange = DoUpdateToDos State = cbChecked TabOrder = 1 + OnChange = acRefreshExecute end object chkSourceEditor: TCheckBox AnchorSideLeft.Control = chkUsed AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = chkListed - Left = 105 - Height = 19 - Top = 17 - Width = 49 + Left = 129 + Height = 22 + Top = 20 + Width = 62 BorderSpacing.Right = 4 Caption = 'Editor' Checked = True - OnChange = DoUpdateToDos State = cbChecked TabOrder = 2 + OnChange = acRefreshExecute end object chkPackages: TCheckBox AnchorSideLeft.Control = chkSourceEditor AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = chkListed - Left = 158 - Height = 19 - Top = 17 - Width = 67 + Left = 195 + Height = 22 + Top = 20 + Width = 82 BorderSpacing.Right = 4 Caption = '&Packages' - OnChange = DoUpdateToDos TabOrder = 3 + OnChange = acRefreshExecute end end + object N4: TToolButton + Left = 609 + Height = 46 + Top = 2 + Caption = 'N4' + Style = tbsDivider + end + object tbHelp: TToolButton + Left = 614 + Top = 2 + Action = acHelp + end end object ActionList: TActionList Left = 584 Top = 152 + object acEdit: TAction + Caption = 'Edit' + OnExecute = acEditExecute + end object acGoto: TAction Caption = 'Goto' OnExecute = acGotoExecute end object acRefresh: TAction Caption = 'Refresh' - OnExecute = DoUpdateToDos + OnExecute = acRefreshExecute end object acExport: TAction Caption = 'Export' diff --git a/components/todolist/todolist.pas b/components/todolist/todolist.pas index 153cd8a236..c837d30eae 100644 --- a/components/todolist/todolist.pas +++ b/components/todolist/todolist.pas @@ -31,6 +31,7 @@ Alexander du Plessis Silvio Clecio Kevin Jesshope + Juha Manninen Abstract: List all to do comments of current project and the file @@ -70,7 +71,7 @@ uses // Codetools CodeToolManager, FileProcs, // IDEIntf - LazIDEIntf, IDEImagesIntf, PackageIntf, ProjectIntf, + LazIDEIntf, IDEImagesIntf, PackageIntf, ProjectIntf, SrcEditorIntf, IDECommands, // ToDoList ToDoListCore, ToDoListStrConsts; @@ -78,12 +79,12 @@ Const ToDoWindowName = 'IDETodoWindow'; type - TOnOpenFile = procedure(Sender: TObject; const Filename: string; - const LineNumber: integer) of object; + TOnEditToDo = procedure(aTodoItem: TTodoItem); { TIDETodoWindow } TIDETodoWindow = class(TForm) + acEdit: TAction; acGoto: TAction; acRefresh: TAction; acExport: TAction; @@ -97,25 +98,28 @@ type lblOptions: TLabel; lblShowWhat: TLabel; lvTodo: TListView; + N1: TToolButton; pnlOptions: TPanel; pnlShowWhat: TPanel; SaveDialog: TSaveDialog; + tbEdit: TToolButton; ToolBar: TToolBar; tbGoto: TToolButton; tbRefresh: TToolButton; tbExport: TToolButton; - N1: TToolButton; N2: TToolButton; N3: TToolButton; + N4: TToolButton; tbHelp: TToolButton; XMLPropStorage: TXMLPropStorage; + procedure acEditExecute(Sender: TObject); procedure acExportExecute(Sender: TObject); procedure acGotoExecute(Sender: TObject); + procedure acRefreshExecute(Sender: TObject); procedure acHelpExecute(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var {%H-}CanClose: boolean); procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; {%H-}Shift:TShiftState); - procedure DoUpdateToDos(Sender: TObject); procedure lvTodoClick(Sender: TObject); procedure lvTodoCompare(Sender : TObject; Item1, Item2 : TListItem; {%H-}Data : Integer; var Compare : Integer); @@ -130,9 +134,10 @@ type FLoadingOptions: boolean; FStartFilename: String; FOwnerProjPack: TObject; // Project or package owning the FStartFilename. - FOnOpenFile : TOnOpenFile; FScannedFiles: TAvlTree;// tree of TTLScannedFile FScannedIncFiles: TStringMap; + FOnEditItem: TOnEditToDo; + procedure GotoTodo(aTodoItem: TTodoItem); procedure SetIDEItem(AValue: string); procedure SetIdleConnected(const AValue: boolean); function ProjectOpened(Sender: TObject; AProject: TLazProject): TModalResult; @@ -149,8 +154,9 @@ type property IDEItem: string read FIDEItem write SetIDEItem; // package name or empty for active project property BaseDirectory: string read FBaseDirectory; - property OnOpenFile: TOnOpenFile read FOnOpenFile write FOnOpenFile; property IdleConnected: boolean read FIdleConnected write SetIdleConnected; + + property OnEditItem: TOnEditToDo read FOnEditItem write FOnEditItem; end; var @@ -171,6 +177,7 @@ begin if Name<>ToDoWindowName then RaiseGDBException(''); ToolBar.Images := IDEImages.Images_16; + acEdit.ImageIndex := IDEImages.LoadImage('laz_edit'); acGoto.ImageIndex := IDEImages.LoadImage('menu_goto_line'); acRefresh.ImageIndex := IDEImages.LoadImage('laz_refresh'); acExport.ImageIndex := IDEImages.LoadImage('menu_saveas'); @@ -270,11 +277,6 @@ begin ModalResult:=mrCancel; end; -procedure TIDETodoWindow.DoUpdateToDos(Sender: TObject); -begin - UpdateTodos; -end; - procedure TIDETodoWindow.lvTodoClick(Sender: TObject); begin acGoto.Execute; @@ -312,9 +314,10 @@ begin 2, 4 : begin if TryStrToInt(Item1.SubItems.Strings[lvTodo.SortColumn-1], Int1) - and TryStrToInt(Item2.SubItems.Strings[lvTodo.SortColumn-1], Int2) then - Compare := CompareValue(Int1, Int2) - else Compare := 0; + and TryStrToInt(Item2.SubItems.Strings[lvTodo.SortColumn-1], Int2) then + Compare := CompareValue(Int1, Int2) + else + Compare := 0; end; else Compare := 0; end; @@ -457,26 +460,42 @@ begin XMLPropStorage.Active := True; end; +procedure TIDETodoWindow.GotoTodo(aTodoItem: TTodoItem); +begin + LazarusIDE.DoOpenFileAndJumpToPos(aTodoItem.Filename, aTodoItem.CodePos,-1,-1,-1, + [ofOnlyIfExists,ofRegularFile,ofVirtualFile,ofDoNotLoadResource]); +end; + +procedure TIDETodoWindow.acEditExecute(Sender: TObject); +var + ListItem: TListItem; + TodoItem: TTodoItem; + SrcEdit: TSourceEditorInterface; +begin + Assert(Assigned(OnEditItem), 'TIDETodoWindow.acEditExecute: OnEditItem=Nil'); + ListItem := lvtodo.Selected; + if (ListItem=nil) or (ListItem.Data=nil) then exit; + TodoItem := TTodoItem(ListItem.Data); + SrcEdit := SourceEditorManagerIntf.ActiveEditor; + if (SrcEdit=nil) or SrcEdit.ReadOnly then exit; + debugln(['TIDETodoWindow.acEditExecute ToDo=', TodoItem.Filename, ', Src=', SrcEdit.FileName]); + if (TodoItem.Filename<>SrcEdit.FileName) or (TodoItem.CodePos<>SrcEdit.CursorTextXY) then + GotoTodo(TodoItem); // Move to the right place if not there already. + OnEditItem(TodoItem); // Open the dialog for editing. +end; + procedure TIDETodoWindow.acGotoExecute(Sender: TObject); var - CurFilename: String; - aTodoItem: TTodoItem; - aListItem: TListItem; - TheLine: integer; + ListItem: TListItem; begin - CurFilename:=''; - aListItem:= lvtodo.Selected; - if Assigned(aListItem) and Assigned(aListItem.Data) then - begin - aTodoItem := TTodoItem(aListItem.Data); - CurFileName := aTodoItem.Filename; - TheLine := aTodoItem.LineNumber; - if Assigned(OnOpenFile) then - OnOpenFile(Self,CurFilename,TheLine) - else - LazarusIDE.DoOpenFileAndJumpToPos(CurFilename,Point(1,TheLine),-1,-1,-1, - [ofOnlyIfExists,ofRegularFile,ofVirtualFile,ofDoNotLoadResource]); - end; + ListItem := lvtodo.Selected; + if Assigned(ListItem) and Assigned(ListItem.Data) then + GotoTodo(TTodoItem(ListItem.Data)); +end; + +procedure TIDETodoWindow.acRefreshExecute(Sender: TObject); +begin + UpdateTodos; end; procedure TIDETodoWindow.acHelpExecute(Sender: TObject); @@ -499,7 +518,7 @@ end; procedure TIDETodoWindow.AddListItem(aTodoItem: TTodoItem); - function ShowThisToDoItem:boolean; + function ShowThisToDoItem: boolean; // Add this ToDoItem based on the cboShowWhat selection begin case cboShowWhat.ItemIndex of @@ -514,7 +533,6 @@ procedure TIDETodoWindow.AddListItem(aTodoItem: TTodoItem); var aListItem: TListItem; aFilename: String; - begin if Assigned(aTodoItem) and ShowThisToDoItem then begin @@ -528,7 +546,7 @@ begin if (BaseDirectory<>'') and FilenameIsAbsolute(aFilename) then aFilename:=CreateRelativePath(aFilename,BaseDirectory); aListitem.SubItems.Add(aFilename); - aListitem.SubItems.Add(IntToStr(aTodoItem.LineNumber)); + aListitem.SubItems.Add(IntToStr(aTodoItem.CodePos.Y)); aListitem.SubItems.Add(aTodoItem.Owner); aListitem.SubItems.Add(aTodoItem.Category); end; diff --git a/components/todolist/todolistcore.pas b/components/todolist/todolistcore.pas index d3c37f9e0d..26ba7cc6f5 100644 --- a/components/todolist/todolistcore.pas +++ b/components/todolist/todolistcore.pas @@ -65,13 +65,16 @@ type TTodoItem = class(TObject) private FCategory: string; - FToDoType: TToDoType; FTokenStyle: TTokenStyle; - FFilename: string; - FLineNumber: integer; - FOwner: string; + FToDoType: TToDoType; FPriority: integer; FText: string; + FHasColon: Boolean; + FCodePos: TPoint; // Column : line in file. + FCommentLen: integer; // Original length including comment characters. + FCommentType: char; // Characters of comment start / end. + FFilename: string; + FOwner: string; function GetQuotedCategory: string; function GetQuotedOwner: string; function GetAsComment: string; @@ -80,13 +83,16 @@ type function Parse(const aTokenString: string; aRequireColon: Boolean): Boolean; public property Category: string read FCategory write FCategory; - property QuotedCategory:string read GetQuotedCategory; + property QuotedCategory: string read GetQuotedCategory; property TokenStyle: TTokenStyle read FTokenStyle write FTokenStyle; - property ToDoType:TToDoType read FToDoType write FToDoType; - property LineNumber: integer read FLineNumber write FLineNumber; + property ToDoType: TToDoType read FToDoType write FToDoType; + property HasColon: Boolean read FHasColon write FHasColon; + property CodePos: TPoint read FCodePos write FCodePos; + property CommentLen: integer read FCommentLen write FCommentLen; + property CommentType: char read FCommentType write FCommentType; property Filename: string read FFilename write FFilename; property Owner: string read FOwner write FOwner; - property QuotedOwner:string read GetQuotedOwner; + property QuotedOwner: string read GetQuotedOwner; property Priority: integer read FPriority write FPriority; property Text: string read FText write FText; property AsString: string read GetAsString; @@ -107,8 +113,7 @@ type FScannedIncFiles: TStringMap; function GetCount: integer; function GetItems(Index: integer): TTodoItem; - procedure CreateToDoItem(const aStartComment, aEndComment: string; - aLineNumber: Integer); + procedure CreateToDoItem(aCommentType: char; aCodePos: TPoint); procedure ScanPascalToDos; procedure ScanToDoFile; public @@ -162,7 +167,7 @@ begin s:=LIST_INDICATORS[lToDoItem.ToDoType] + ','; t:=DelChars(lToDoItem.Text,',');{Strip any commas that can cause a faulty csv file} s:=s+t+','+IntToStr(lToDoItem.Priority)+','+lToDoItem.Filename+ - ','+IntToStr(lToDoItem.LineNumber)+','+lToDoItem.Owner+','+lToDoItem.Category; + ','+IntToStr(lToDoItem.CodePos.Y)+','+lToDoItem.Owner+','+lToDoItem.Category; lCommaList.Add(s); Inc(i); end; @@ -235,24 +240,30 @@ begin Result:=TTodoItem(FItems[Index]); end; -procedure TTLScannedFile.CreateToDoItem(const aStartComment, aEndComment: string; - aLineNumber: Integer); +procedure TTLScannedFile.CreateToDoItem(aCommentType: char; aCodePos: TPoint); var TheToken: string; lTokenFound: boolean; + lCommentLen, lStartLen, lEndLen: Integer; lTodoType, lFoundToDoType: TToDoType; lTokenStyle, lFoundTokenStyle: TTokenStyle; NewToDoItem: TTodoItem; begin //DebugLn(['TTLScannedFile.CreateToDoItem FileName=',FRealFilename, - // ', LineNumber=',aLineNumber, ', FCommentStr=',FCommentStr]); + // ', aCodePos=',aCodePos.X,':',aCodePos.Y,', FCommentStr=',FCommentStr]); + lCommentLen := Length(FCommentStr); // Remove beginning and ending comment characters from the string - if aStartComment <> '' then - Delete(FCommentStr, 1, Length(aStartComment)); - if aEndComment <> '' then begin - Assert(LazEndsStr(aEndComment, FCommentStr), 'TTLScannedFile.CreateToDoItem: No comment end.'); - SetLength(FCommentStr, Length(FCommentStr)-Length(aEndComment)); + case aCommentType of + #0 : begin lStartLen := 0; lEndLen := 0; end; // A dedicated .todo file + '/' : begin lStartLen := 2; lEndLen := 0; end; // // + '{' : begin lStartLen := 1; lEndLen := 1; end; // { } + '(' : begin lStartLen := 2; lEndLen := 2; end; // (* *) + else raise Exception.Create('TTLScannedFile.CreateToDoItem: Wrong comment char.'); end; + if lStartLen > 0 then + Delete(FCommentStr, 1, lStartLen); + if lEndLen > 0 then + SetLength(FCommentStr, Length(FCommentStr)-lEndLen); FCommentStr := TextToSingleLine(FCommentStr); // Determine Token and Style @@ -291,7 +302,9 @@ begin begin NewToDoItem.ToDoType := lFoundToDoType; NewToDoItem.TokenStyle := lFoundTokenStyle; - NewToDoItem.LineNumber := aLineNumber; + NewToDoItem.CodePos := aCodePos; + NewToDoItem.CommentLen := lCommentLen; + NewToDoItem.CommentType:= aCommentType; NewToDoItem.Filename := FRealFilename; Add(NewToDoItem); // Add to list. end @@ -337,7 +350,8 @@ var Src, LocationIncTodo: String; p, CommentEnd: Integer; NestedComment: Boolean; - CodePos: TCodeXYPosition; + CaretPos: TCodeXYPosition; + CodePos: TPoint; begin Src:=FTool.Src; Assert(FCode.Filename=FTool.MainFilename, 'TTLScannedFile.ScanPascalToDos: aCode.Filename<>FTool.MainFilename'); @@ -347,15 +361,15 @@ begin p:=FindNextComment(Src,p); if p>length(Src) then // No more comments found, break loop break; - if not FTool.CleanPosToCaret(p,CodePos) then + if not FTool.CleanPosToCaret(p,CaretPos) then begin ShowMessageFmt(errScanFileFailed, [ExtractFileName(FFilename)]); Exit; end; // Study include file names. Use heuristics, assume name ends with ".inc". - FRealFilename:=CodePos.Code.Filename; + FRealFilename:=CaretPos.Code.Filename; if FilenameExtIs(FRealFilename, 'inc') then // Filename and location in an include file. - LocationIncTodo:=FRealFilename+'_'+IntToStr(CodePos.Y) + LocationIncTodo:=FRealFilename+'_'+IntToStr(CaretPos.Y) else LocationIncTodo:=''; // Process a comment @@ -364,12 +378,9 @@ begin // Process each include file location only once. Units are processed always. if (LocationIncTodo='') or not FScannedIncFiles.Contains(LocationIncTodo) then begin - if Src[p]='/' then - CreateToDoItem('//', '', CodePos.Y) - else if Src[p]='{' then - CreateToDoItem('{', '}', CodePos.Y) - else if Src[p]='(' then - CreateToDoItem('(*', '*)', CodePos.Y); + CodePos.X:=CaretPos.X; + CodePos.Y:=CaretPos.Y; + CreateToDoItem(Src[p], CodePos); if LocationIncTodo<>'' then // Store include file location for future. FScannedIncFiles.Add(LocationIncTodo); end; @@ -380,6 +391,7 @@ end; procedure TTLScannedFile.ScanToDoFile; var List: TStringList; + CodePos: TPoint; i: Integer; begin List:=TStringList.Create; @@ -389,7 +401,9 @@ begin begin FRealFilename:=FCode.Filename; FCommentStr:=List[i]; - CreateToDoItem('', '', i+1) + CodePos.X:=1; + CodePos.Y:=i+1; + CreateToDoItem(#0, CodePos) end; finally List.Free; @@ -435,7 +449,13 @@ end; function TTodoItem.GetAsComment: string; begin - Result := '{ '+AsString+' }'; + case CommentType of + #0 : Result := AsString; // A dedicated .todo file + '/' : Result := '// '+AsString; + '{' : Result := '{ ' +AsString+' }'; + '(' : Result := '(* '+AsString+' *)'; + else raise Exception.Create('TTodoItem.GetAsComment: Wrong comment char.'); + end; end; type @@ -452,7 +472,6 @@ function TTodoItem.Parse(const aTokenString: string; aRequireColon: Boolean): Bo var lParseState: TParseState; i, lPriorityStart: Integer; - HasColon: Boolean; lTempStr, lStr: string; lpTemp: PChar; begin diff --git a/components/todolist/todoliststrconsts.pas b/components/todolist/todoliststrconsts.pas index 8d77215e4c..31868c081d 100644 --- a/components/todolist/todoliststrconsts.pas +++ b/components/todolist/todoliststrconsts.pas @@ -53,6 +53,7 @@ resourcestring lisSourceEditorHint = 'Add units in source editor'; dlgUnitDepRefresh = 'Refresh'; lisTDDInsertToDo = 'Insert a ToDo/Done/Note'; + lisTDDEditToDo = 'Edit the ToDo/Done/Note'; lisViewToDoList = 'View ToDo List'; lisToDoList = 'ToDo List'; lisPkgFileTypeText = 'Text';