From 66c4a28b49d9480064ce297e9e016214d893b06c Mon Sep 17 00:00:00 2001 From: mattias Date: Sun, 21 Jan 2007 12:16:13 +0000 Subject: [PATCH] IDE: message window: replaced TListBox with TTreeView, LCL: TTreeView: fixed normal left click selection with multiselections git-svn-id: trunk@10484 - --- ide/msgview.lfm | 15 ++-- ide/msgview.lrs | 24 +++--- ide/msgview.pp | 144 ++++++++++++++++++--------------- lcl/comctrls.pp | 2 +- lcl/include/control.inc | 2 +- lcl/include/customlistview.inc | 44 ---------- lcl/include/treeview.inc | 12 +-- 7 files changed, 107 insertions(+), 136 deletions(-) diff --git a/ide/msgview.lfm b/ide/msgview.lfm index 105977507b..78046fb9ab 100644 --- a/ide/msgview.lfm +++ b/ide/msgview.lfm @@ -1,28 +1,25 @@ -object MessagesView: TMessagesView +inherited MessagesView: TMessagesView Left = 262 Height = 79 Top = 518 Width = 722 HorzScrollBar.Page = 721 VertScrollBar.Page = 78 - ActiveControl = MessageListBox + ActiveControl = MessageTreeView BorderStyle = bsSizeToolWin Caption = 'MessagesView' - ClientHeight = 79 - ClientWidth = 722 KeyPreview = True OnDeactivate = FormDeactivate OnKeyDown = MessagesViewKeyDown - PixelsPerInch = 95 - object MessageListBox: TListBox + object MessageTreeView: TTreeView Height = 79 Width = 722 Align = alClient - MultiSelect = True - OnExit = MessageViewExit + DefaultItemHeight = 14 PopupMenu = MainPopupMenu TabOrder = 0 - TopIndex = -1 + OnExit = MessageViewExit + Options = [tvoAllowMultiselect, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips] end object MainPopupMenu: TPopupMenu OnPopup = MainPopupMenuPopup diff --git a/ide/msgview.lrs b/ide/msgview.lrs index 0358748220..21cb1b282b 100644 --- a/ide/msgview.lrs +++ b/ide/msgview.lrs @@ -1,12 +1,16 @@ +{ This is an automatically generated lazarus resource file } + LazarusResources.Add('TMessagesView','FORMDATA',[ - 'TPF0'#13'TMessagesView'#12'MessagesView'#4'Left'#3#6#1#6'Height'#2'O'#3'Top' - +#3#6#2#5'Width'#3#210#2#18'HorzScrollBar.Page'#3#209#2#18'VertScrollBar.Page' - +#2'N'#13'ActiveControl'#7#14'MessageListBox'#11'BorderStyle'#7#13'bsSizeTool' - +'Win'#7'Caption'#6#12'MessagesView'#12'ClientHeight'#2'O'#11'ClientWidth'#3 - +#210#2#10'KeyPreview'#9#12'OnDeactivate'#7#14'FormDeactivate'#9'OnKeyDown'#7 - +#19'MessagesViewKeyDown'#13'PixelsPerInch'#2'_'#0#8'TListBox'#14'MessageList' - +'Box'#6'Height'#2'O'#5'Width'#3#210#2#5'Align'#7#8'alClient'#11'MultiSelect' - +#9#6'OnExit'#7#15'MessageViewExit'#9'PopupMenu'#7#13'MainPopupMenu'#8'TabOrd' - +'er'#2#0#8'TopIndex'#2#255#0#0#10'TPopupMenu'#13'MainPopupMenu'#7'OnPopup'#7 - +#18'MainPopupMenuPopup'#4'left'#2'.'#3'top'#2')'#0#0#0 + 'TPF0'#241#13'TMessagesView'#12'MessagesView'#4'Left'#3#6#1#6'Height'#2'O'#3 + +'Top'#3#6#2#5'Width'#3#210#2#18'HorzScrollBar.Page'#3#209#2#18'VertScrollBar' + +'.Page'#2'N'#13'ActiveControl'#7#15'MessageTreeView'#11'BorderStyle'#7#13'bs' + +'SizeToolWin'#7'Caption'#6#12'MessagesView'#10'KeyPreview'#9#12'OnDeactivate' + +#7#14'FormDeactivate'#9'OnKeyDown'#7#19'MessagesViewKeyDown'#0#9'TTreeView' + +#15'MessageTreeView'#6'Height'#2'O'#5'Width'#3#210#2#5'Align'#7#8'alClient' + +#17'DefaultItemHeight'#2#14#9'PopupMenu'#7#13'MainPopupMenu'#8'TabOrder'#2#0 + +#6'OnExit'#7#15'MessageViewExit'#7'Options'#11#19'tvoAllowMultiselect'#17'tv' + +'oAutoItemHeight'#16'tvoHideSelection'#21'tvoKeepCollapsedNodes'#14'tvoShowB' + +'uttons'#12'tvoShowLines'#11'tvoShowRoot'#11'tvoToolTips'#0#0#0#10'TPopupMen' + +'u'#13'MainPopupMenu'#7'OnPopup'#7#18'MainPopupMenuPopup'#4'left'#2'.'#3'top' + +#2')'#0#0#0 ]); diff --git a/ide/msgview.pp b/ide/msgview.pp index cbf10ed576..36a4b0d249 100644 --- a/ide/msgview.pp +++ b/ide/msgview.pp @@ -39,7 +39,7 @@ interface uses Classes, SysUtils, AVL_Tree, LCLProc, LResources, ClipBrd, Controls, Dialogs, FileUtil, Forms, Menus, - StdCtrls, + StdCtrls, ComCtrls, IDEExternToolIntf, IDECommands, MenuIntf, IDEMsgIntf, DialogProcs, EnvironmentOpts, LazarusIDEStrConsts, IDEOptionDefs, IDEProcs, InputHistory, KeyMapping; @@ -64,7 +64,7 @@ type { TMessagesView } TMessagesView = class(TIDEMessagesWindowInterface) - MessageListBox: TListBox; + MessageTreeView: TTreeView; MainPopupMenu: TPopupMenu; procedure CopyAllMenuItemClick(Sender: TObject); procedure CopyAllAndHiddenMenuItemClick(Sender: TObject); @@ -78,8 +78,8 @@ type procedure MessageViewExit(Sender: TObject); procedure MessagesViewKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); - procedure MessageViewDrawItem(Control: TWinControl; Index: Integer; - ARect: TRect; State: TOwnerDrawState); + procedure MessageViewDrawItem(Sender: TCustomTreeView; Node: TTreeNode; + State: TCustomDrawState; var DefaultDraw: Boolean); procedure SaveAllToFileMenuItemClick(Sender: TObject); procedure OnQuickFixClick(Sender: TObject); private @@ -126,6 +126,7 @@ type function VisibleItemCount: integer; function MsgCount: integer; procedure FilterLines(Filter: TOnFilterLine); + function GetVisibleMessagesAsText: string; procedure SaveMessagesToFile(const Filename: string); procedure SrcEditLinesInsertedDeleted(const Filename: string; FirstLine, LineCount: Integer); @@ -279,9 +280,7 @@ begin FLastSelectedIndex := -1; Caption := lisMenuViewMessages; - MessageListBox.Style := lbOwnerDrawFixed; - MessageListBox.OnDrawItem := @MessageViewDrawItem; - MessageListBox.ClickOnSelChange := false; + MessageTreeView.OnCustomDrawItem := @MessageViewDrawItem; // assign the root TMenuItem to the registered menu root. // This will automatically create all registered items @@ -298,6 +297,8 @@ begin EnvironmentOptions.IDEWindowLayoutList.Apply(Self, Name); FQuickFixItems:=TFPList.Create; + + DebugLn(['TMessagesView.Create ',MessageTreeView.Items.Count]); end; destructor TMessagesView.Destroy; @@ -331,7 +332,7 @@ begin VisibleIndex := Line.VisiblePosition; if VisibleIndex >= 0 then begin - MessageListBox.Items.Delete(VisibleIndex); + MessageTreeView.Items[VisibleIndex].Free; FVisibleItems.Delete(VisibleIndex); end; @@ -360,7 +361,7 @@ var LastItem: TLazMessageLine; begin //ConsistencyCheck; - //DebugLn('TMessagesView.Add START ItemCount=',dbgs(ItemCount),' VisibleCount=',dbgs(VisibleItemCount),' ListBoxCount=',dbgs(MessageListBox.Items.Count),' ProgressLine=',dbgs(ProgressLine),' VisibleLine=',dbgs(VisibleLine),' OriginalIndex=',dbgs(OriginalIndex),' Msg="',Msg,'"'); + //DebugLn('TMessagesView.Add START ItemCount=',dbgs(ItemCount),' VisibleCount=',dbgs(VisibleItemCount),' ListBoxCount=',dbgs(MessageTreeView.Items.Count),' ProgressLine=',dbgs(ProgressLine),' VisibleLine=',dbgs(VisibleLine),' OriginalIndex=',dbgs(OriginalIndex),' Msg="',Msg,'"'); NewMsg:=nil; if LinesCount>0 then begin LastItem:=Items[LinesCount-1]; @@ -388,17 +389,18 @@ begin i := FVisibleItems.Count - 1; VisibleItems[i].VisiblePosition := -1; FVisibleItems.Delete(i); - MessageListBox.Items[i] := Msg; + MessageTreeView.Items[i].Text := Msg; end else begin // add new line - MessageListBox.Items.Add(Msg)// add line + MessageTreeView.Items.Add(nil,Msg)// add line end; NewMsg.VisiblePosition := FVisibleItems.Count; FVisibleItems.Add(NewMsg); FLastLineIsProgress := ProgressLine; - MessageListBox.TopIndex := MessageListBox.Items.Count - 1; - //DebugLn(['TMessagesView.Add ',MessageListBox.TopIndex]); + if MessageTreeView.Items.Count>0 then + MessageTreeView.Items[MessageTreeView.Items.Count-1].MakeVisible; + //DebugLn(['TMessagesView.Add ',MessageTreeView.TopIndex]); end; //ConsistencyCheck; end; @@ -527,8 +529,8 @@ end; procedure TMessagesView.ShowTopMessage; begin - if MessageListBox.Items.Count > 0 then begin - MessageListBox.TopIndex := 0; + if MessageTreeView.Items.Count > 0 then begin + MessageTreeView.Items[MessageTreeView.Items.Count-1].MakeVisible; //DebugLn(['TMessagesView.ShowTopMessage ']); end; end; @@ -563,24 +565,37 @@ begin else Line.VisiblePosition := -1; end; - // rebuild MessageListBox.Items - MessageListBox.Items.BeginUpdate; + // rebuild MessageTreeView.Items + MessageTreeView.BeginUpdate; for i := 0 to FVisibleItems.Count - 1 do begin Line := VisibleItems[i]; - if MessageListBox.Items.Count > i then - MessageListBox.Items[i] := Line.Msg + if MessageTreeView.Items.Count > i then + MessageTreeView.Items[i].Text := Line.Msg else - MessageListBox.Items.Add(Line.Msg); + MessageTreeView.Items.Add(nil,Line.Msg); end; - while MessageListBox.Items.Count > FVisibleItems.Count do - MessageListBox.Items.Delete(MessageListBox.Items.Count - 1); - MessageListBox.Items.EndUpdate; + while MessageTreeView.Items.Count > FVisibleItems.Count do + MessageTreeView.Items[MessageTreeView.Items.Count - 1].Free; + MessageTreeView.EndUpdate; +end; + +function TMessagesView.GetVisibleMessagesAsText: string; +var + sl: TStringList; + i: Integer; +begin + sl:=TStringList.Create; + for i:=0 to MessageTreeView.Items.Count-1 do + sl.Add(MessageTreeView.Items[i].Text); + Result:=sl.Text; + sl.Free; end; procedure TMessagesView.SaveMessagesToFile(const Filename: string); +// save visible messages to file begin - SaveStringToFile(Filename, MessageListBox.Items.Text, []); + SaveStringToFile(Filename, GetVisibleMessagesAsText, []); end; procedure TMessagesView.SrcEditLinesInsertedDeleted(const Filename: string; @@ -623,8 +638,8 @@ end; procedure TMessagesView.UpdateMsgLineInListBox(Line: TLazMessageLine); begin if (Line.VisiblePosition>=0) - and (Line.VisiblePosition 0) and (MessageListBox.SelCount > 0) then - Result := MessageListBox.Items.Strings[GetSelectedLineIndex]; + if (MessageTreeView.Selected<>nil) then + Result := MessageTreeView.Selected.Text; end; function TMessagesView.GetMessageLine: TLazMessageLine; @@ -761,7 +776,7 @@ end; procedure TMessagesView.CopyAllMenuItemClick(Sender: TObject); begin - Clipboard.AsText := MessageListBox.Items.Text; + Clipboard.AsText := GetVisibleMessagesAsText; end; procedure TMessagesView.CopyAllAndHiddenMenuItemClick(Sender: TObject); @@ -771,9 +786,8 @@ end; procedure TMessagesView.CopyMenuItemClick(Sender: TObject); begin - if MessageListBox.ItemIndex < 0 then - exit; - Clipboard.AsText := MessageListBox.GetSelectedText; + if MessageTreeView.Selected=nil then exit; + Clipboard.AsText := MessageTreeView.Selected.Text; end; procedure TMessagesView.FormDeactivate(Sender: TObject); @@ -839,11 +853,12 @@ begin ExecuteIDEShortCut(Self, Key, Shift); end; -procedure TMessagesView.MessageViewDrawItem(Control: TWinControl; - Index: Integer; ARect: TRect; State: TOwnerDrawState); +procedure TMessagesView.MessageViewDrawItem(Sender: TCustomTreeView; + Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); var TheText: string; cl: TColor; + ARect: TRect; const cHint = 'Hint: User defined:'; cNote = 'Note: User defined:'; @@ -853,25 +868,26 @@ const clMsgWarning = clRed; cLeftSpacer = 3; begin - MessageListBox.Canvas.FillRect(ARect); - //DebugLn('TMessagesView.MessageViewDrawItem Index=',dbgs(Index),' Count=',dbgs(MessageListBox.Items.Count)); - TheText := MessageListBox.Items[Index]; + ARect:=Node.DisplayRect(true); + MessageTreeView.Canvas.FillRect(ARect); + //DebugLn('TMessagesView.MessageViewDrawItem Index=',dbgs(Index),' Count=',dbgs(MessageTreeView.Items.Count)); + TheText := Node.Text; - cl := MessageListBox.Canvas.Font.Color; // save original color + cl := MessageTreeView.Canvas.Font.Color; // save original color { Only use custom colors if not selected, otherwise it is difficult to read } - if not (odSelected in State) + if not (cdsSelected in State) then begin if Pos(cNote, TheText) > 0 then - MessageListBox.Canvas.Font.Color := clMsgNote + MessageTreeView.Canvas.Font.Color := clMsgNote else if Pos(cHint, TheText) > 0 then - MessageListBox.Canvas.Font.Color := clMsgHint + MessageTreeView.Canvas.Font.Color := clMsgHint else if Pos(cWarning, TheText) > 0 then - MessageListBox.Canvas.Font.Color := clMsgWarning; + MessageTreeView.Canvas.Font.Color := clMsgWarning; end; - MessageListBox.Canvas.TextOut(ARect.Left + cLeftSpacer, ARect.Top + 1, TheText); - MessageListBox.Canvas.Font.Color := cl; // restore original color + MessageTreeView.Canvas.TextOut(ARect.Left + cLeftSpacer, ARect.Top + 1, TheText); + MessageTreeView.Canvas.Font.Color := cl; // restore original color end; procedure TMessagesView.SaveAllToFileMenuItemClick(Sender: TObject); @@ -942,25 +958,18 @@ begin end; function TMessagesView.GetSelectedLineIndex: integer; -var - I: integer; begin Result := -1; - if (MessageListBox.Items.Count > 0) and (MessageListBox.SelCount > 0) then - for i := 0 to MessageListBox.Items.Count - 1 do - if MessageListBox.Selected[I] then - begin - Result := I; - Break; - end; + if (MessageTreeView.Selected<>nil) then + Result:=MessageTreeView.Selected.AbsoluteIndex; end; procedure TMessagesView.SetLastLineIsProgress(const AValue: boolean); begin if FLastLineIsProgress = AValue then exit; - if FLastLineIsProgress then - MessageListBox.Items.Delete(MessageListBox.Items.Count - 1); + if FLastLineIsProgress and (MessageTreeView.Items.Count>0) then + MessageTreeView.Items[MessageTreeView.Items.Count - 1].Free; FLastLineIsProgress := AValue; end; @@ -968,7 +977,7 @@ procedure TMessagesView.DoSelectionChange; var NewSelectedIndex: LongInt; begin - if (MessageListBox.Items.Count > 0) and (MessageListBox.SelCount > 0) then + if (MessageTreeView.Selected<>nil) then begin NewSelectedIndex:=GetSelectedLineIndex; if NewSelectedIndex<>FLastSelectedIndex then begin @@ -981,8 +990,11 @@ end; procedure TMessagesView.SetSelectedLineIndex(const AValue: integer); begin - MessageListBox.ItemIndex := AValue; - MessageListBox.TopIndex := MessageListBox.ItemIndex; + if AValue>=0 then begin + MessageTreeView.Items[AValue].Selected := true; + //MessageTreeView.TopItem := MessageTreeView.Selected; + end else + MessageTreeView.Selected := nil; end; procedure TMessagesView.UpdateMsgSrcPos(Line: TLazMessageLine); @@ -1015,8 +1027,8 @@ begin RaiseGDBException('TMessagesView.ConsistencyCheck i='+dbgs(i)+' "'+Line.Msg+'" Position='+dbgs(Line.Position)); if (Line.VisiblePosition>=0) and (VisibleItems[Line.VisiblePosition]<>Line) then RaiseGDBException('TMessagesView.ConsistencyCheck i='+dbgs(i)+' "'+Line.Msg+'" VisiblePosition='+dbgs(Line.VisiblePosition)+' '+VisibleItems[Line.VisiblePosition].Msg); - if (Line.VisiblePosition>=0) and (MessageListBox.Items[Line.VisiblePosition]<>Line.Msg) then - RaiseGDBException('TMessagesView.ConsistencyCheck i='+dbgs(i)+' "'+Line.Msg+'" VisiblePosition='+dbgs(Line.VisiblePosition)+' Listbox="'+MessageListBox.Items[Line.VisiblePosition]+'"'); + if (Line.VisiblePosition>=0) and (MessageTreeView.Items[Line.VisiblePosition].Text<>Line.Msg) then + RaiseGDBException('TMessagesView.ConsistencyCheck i='+dbgs(i)+' "'+Line.Msg+'" VisiblePosition='+dbgs(Line.VisiblePosition)+' Listbox="'+MessageTreeView.Items[Line.VisiblePosition].Text+'"'); end; for i:=0 to FVisibleItems.Count-1 do begin Line:=VisibleItems[i]; diff --git a/lcl/comctrls.pp b/lcl/comctrls.pp index cbba54d083..fbb7e7132a 100644 --- a/lcl/comctrls.pp +++ b/lcl/comctrls.pp @@ -1950,7 +1950,7 @@ type procedure Assign(Source: TPersistent); override; procedure BeginUpdate; procedure Clear; - procedure ClearMultiSelection; + procedure ClearMultiSelection(ClearSelected: boolean = false); function IsMultiSelection: boolean; procedure Delete(Node: TTreeNode); procedure EndUpdate; diff --git a/lcl/include/control.inc b/lcl/include/control.inc index a4695cd67f..3f3f855306 100644 --- a/lcl/include/control.inc +++ b/lcl/include/control.inc @@ -1454,7 +1454,7 @@ begin end; {------------------------------------------------------------------------------ - function TControl.GetClientScrollOffset: TPoint; + function TControl.GetControlOrigin: TPoint; Returns the screen coordinate of the topleft pixel of the control. ------------------------------------------------------------------------------} diff --git a/lcl/include/customlistview.inc b/lcl/include/customlistview.inc index fc148f83bd..7fb91a0fcf 100644 --- a/lcl/include/customlistview.inc +++ b/lcl/include/customlistview.inc @@ -860,55 +860,11 @@ begin end; procedure TCustomListView.UpdateScrollbars; -var - ScrollInfo: TScrollInfo; begin // this needs to be done in the widgetset DebugLn('TODO: TCustomListView.UpdateScrollbars'); exit; if not HandleAllocated then exit; -{ - // Exclude(FStates,tvsScrollbarChanged); - if fScrollBars = ssNone then Exit; - - ScrollInfo.cbSize := SizeOf(ScrollInfo); - ScrollInfo.fMask := SIF_ALL or SIF_DISABLENOSCROLL; - ScrollInfo.nTrackPos := 0; - if fScrollBars in [ssBoth, ssHorizontal] - then begin - // horizontal scrollbar - ScrollInfo.nMin := 0; - ScrollInfo.nPage := (ClientWidth-ScrollBarWidth)-2*BorderWidth; - if ScrollInfo.nPage<1 then ScrollInfo.nPage:=1; - ScrollInfo.nMax := {GetMaxScrollLeft+}ScrollInfo.nPage; - if ScrollInfo.nMax<1 then ScrollInfo.nMax:=1; - ScrollInfo.nPos := FScrolledLeft; - if not CompareMem(@ScrollInfo,@FLastHorzScrollInfo,SizeOf(TScrollInfo)) - then begin - FLastHorzScrollInfo:=ScrollInfo; - SetScrollInfo(Handle, SB_HORZ, ScrollInfo, True); - ShowScrollBar(Handle,SB_HORZ,True); - end; - end; - if fScrollBars in [ssBoth, ssVertical] then begin - // vertical scrollbar - ScrollInfo.nMin := 0; - ScrollInfo.nPage := (ClientHeight-ScrollBarWidth)-FDefaultItemHeight; - if ScrollInfo.nPage<1 then ScrollInfo.nPage:=1; - ScrollInfo.nMax := {GetMaxScrollTop+}ScrollInfo.nPage; - if ScrollInfo.nMax<1 then ScrollInfo.nMax:=1; - ScrollInfo.nTrackPos := 0; - ScrollInfo.nPos := FScrolledTop; - if not CompareMem(@ScrollInfo,@FLastVertScrollInfo,SizeOf(TScrollInfo)) - then begin - FLastVertScrollInfo:=ScrollInfo; - SetScrollInfo(Handle, SB_VERT, ScrollInfo, True); - ShowScrollBar(Handle,SB_VERT,True); - end; - end; - end; - end; -} end; diff --git a/lcl/include/treeview.inc b/lcl/include/treeview.inc index 3ccacdc50b..79f1d3acfe 100644 --- a/lcl/include/treeview.inc +++ b/lcl/include/treeview.inc @@ -1695,7 +1695,7 @@ begin GetLastNode.Delete; end; -procedure TTreeNodes.ClearMultiSelection; +procedure TTreeNodes.ClearMultiSelection(ClearSelected: boolean = false); var ANode, OldNode: TTreeNode; begin @@ -1706,6 +1706,8 @@ begin ANode:=ANode.GetNextMultiSelected; OldNode.MultiSelected:=false; end; + if ClearSelected then + Owner.Selected:=nil; if Owner<>nil then Owner.UnlockSelectionChangeEvent; end; @@ -3374,8 +3376,8 @@ begin lNode.MultiSelectGroup else begin LockSelectionChangeEvent; - FTreeNodes.ClearMultiSelection; - lNode.MultiSelected := true; + FTreeNodes.ClearMultiSelection(true); + lNode.Selected := true; UnlockSelectionChangeEvent; end; end else @@ -4250,8 +4252,8 @@ begin end else begin if (Selected<>CursorNode) or Items.IsMultiSelection then begin LockSelectionChangeEvent; - Items.ClearMultiSelection; - CursorNode.MultiSelected:=true; + Items.ClearMultiSelection(true); + CursorNode.Selected:=true; UnlockSelectionChangeEvent; end; end;