IDE: Allow selecting the header line in Messages window's multi-line selection.

git-svn-id: trunk@65318 -
This commit is contained in:
juha 2021-06-27 22:21:18 +00:00
parent 12341ca190
commit 769e991253

View File

@ -37,7 +37,7 @@ uses
Forms, Buttons, ExtCtrls, Controls, LMessages, LCLType, LCLIntf, Forms, Buttons, ExtCtrls, Controls, LMessages, LCLType, LCLIntf,
Graphics, Themes, ImgList, Menus, Clipbrd, Dialogs, StdCtrls, Graphics, Themes, ImgList, Menus, Clipbrd, Dialogs, StdCtrls,
// LazUtils // LazUtils
GraphType, UTF8Process, LazUTF8, LazFileCache, LazFileUtils, IntegerList, GraphType, UTF8Process, LazUTF8, LazFileCache, LazFileUtils, IntegerList, LazLoggerBase,
// SynEdit // SynEdit
SynEdit, SynEditMarks, SynEdit, SynEditMarks,
// BuildIntf // BuildIntf
@ -256,7 +256,6 @@ type
// select, search // select, search
procedure AddToSelection(View: TLMsgWndView; LineNumber: integer); procedure AddToSelection(View: TLMsgWndView; LineNumber: integer);
procedure ExtendSelection(View: TLMsgWndView; LineNumber: integer); procedure ExtendSelection(View: TLMsgWndView; LineNumber: integer);
function HasSelection: boolean;
function SearchNext(StartView: TLMsgWndView; StartLine: integer; function SearchNext(StartView: TLMsgWndView; StartLine: integer;
SkipStart, Downwards: boolean; SkipStart, Downwards: boolean;
out View: TLMsgWndView; out LineNumber: integer): boolean; out View: TLMsgWndView; out LineNumber: integer): boolean;
@ -1128,7 +1127,7 @@ begin
Invalidate; Invalidate;
// auto scroll // auto scroll
if (SelectedView<>nil) and (SelectedLine1<SelectedView.Lines.Count) then if SelectedView<>nil then
exit; // user has selected a non progress line -> do not auto scroll exit; // user has selected a non progress line -> do not auto scroll
for i:=0 to ViewCount-1 do for i:=0 to ViewCount-1 do
@ -1252,21 +1251,19 @@ end;
procedure TMessagesCtrl.SetSelectedLine(AValue: integer); procedure TMessagesCtrl.SetSelectedLine(AValue: integer);
// Select the given line, clear possibly existing selections. // Select the given line, clear possibly existing selections.
var
LineCnt: Integer;
begin begin
Assert(AValue>=-1, 'TMessagesCtrl.SetSelectedLine: AValue < -1.'); Assert(AValue>=-1, 'TMessagesCtrl.SetSelectedLine: AValue < -1.');
Assert(Assigned(SelectedView), 'TMessagesCtrl.SetSelectedLine: View = Nil.'); Assert(Assigned(SelectedView), 'TMessagesCtrl.SetSelectedLine: View = Nil.');
AValue:=Min(AValue, SelectedView.GetShownLineCount(false,true)-1); LineCnt:=SelectedView.GetShownLineCount(false,true)-1;
if AValue=-1 then begin Assert(AValue<=LineCnt, 'TMessagesCtrl.SetSelectedLine: Value '+IntToStr(AValue)
if FSelectedLines.Count=0 then + ' > line count ' + IntToStr(LineCnt));
Exit; //AValue:=Min(AValue, SelectedView.GetShownLineCount(false,true)-1);
FSelectedLines.Clear; // -1 = no selection. if (FSelectedLines.Count>0) and (FSelectedLines[0]=AValue) then
end Exit;
else begin FSelectedLines.Count:=1; // One line.
if (FSelectedLines.Count>0) and (FSelectedLines[0]=AValue) then FSelectedLines[0]:=AValue;
Exit;
FSelectedLines.Count:=1; // One line.
FSelectedLines[0]:=AValue;
end;
Invalidate; Invalidate;
end; end;
@ -1614,7 +1611,7 @@ begin
Canvas.Line(NodeRect.Left,NodeRect.Top,NodeRect.Right,NodeRect.Top); Canvas.Line(NodeRect.Left,NodeRect.Top,NodeRect.Right,NodeRect.Top);
Canvas.Pen.Style:=psSolid; Canvas.Pen.Style:=psSolid;
DrawText(NodeRect,GetHeaderText(View), DrawText(NodeRect,GetHeaderText(View),
(fSelectedView=View) and (FSelectedLines.Count=0),TextColor); (fSelectedView=View) and (FSelectedLines.IndexOf(-1)>=0),TextColor);
Canvas.Brush.Color:=BackgroundColor; Canvas.Brush.Color:=BackgroundColor;
end; end;
inc(y,ItemHeight); inc(y,ItemHeight);
@ -2006,44 +2003,39 @@ procedure TMessagesCtrl.AddToSelection(View: TLMsgWndView; LineNumber: integer);
var var
i: Integer; i: Integer;
begin begin
if LineNumber=-1 then Exit;
BeginUpdate; BeginUpdate;
SelectedView:=View; SelectedView:=View;
if FSelectedLines.Count=0 then // No existing selection. if FSelectedLines.Count=0 then // No existing selection.
SelectedLine1:=LineNumber i:=-1
else begin else
i:=FSelectedLines.IndexOf(LineNumber); i:=FSelectedLines.IndexOf(LineNumber);
if i=-1 then if i=-1 then
FSelectedLines.Add(LineNumber) FSelectedLines.Add(LineNumber)
else else
FSelectedLines.Delete(i); // Was already selected -> toggle. FSelectedLines.Delete(i); // Was already selected -> toggle.
Invalidate; Invalidate;
end;
EndUpdate; EndUpdate;
end; end;
procedure TMessagesCtrl.ExtendSelection(View: TLMsgWndView; LineNumber: integer); procedure TMessagesCtrl.ExtendSelection(View: TLMsgWndView; LineNumber: integer);
var var
i: Integer; i: Integer;
Empty: Boolean;
begin begin
if LineNumber=-1 then Exit;
BeginUpdate; BeginUpdate;
SelectedView:=View; SelectedView:=View;
if FSelectedLines.Count=0 then // No existing selection. Empty:=FSelectedLines.Count=0;
SelectedLine1:=LineNumber FSelectedLines.Count:=1; // Delete possible earlier selections except first one.
else begin if Empty then
FSelectedLines.Count:=1; // Delete earlier selections except the first one. FSelectedLines[0]:=LineNumber // No earlier selection.
if LineNumber<FSelectedLines[0] then begin else if LineNumber<FSelectedLines[0] then
for i:=LineNumber to FSelectedLines[0]-1 do for i:=LineNumber to FSelectedLines[0]-1 do
FSelectedLines.Add(i); FSelectedLines.Add(i)
end else if LineNumber>FSelectedLines[0] then
else if LineNumber>FSelectedLines[0] then begin for i:=FSelectedLines[0]+1 to LineNumber do
for i:=FSelectedLines[0]+1 to LineNumber do FSelectedLines.Add(i);
FSelectedLines.Add(i); // if LineNumber=FSelectedLines[0] then do nothing.
end; Invalidate;
// if LineNumber=FSelectedLines[0] then do nothing.
Invalidate;
end;
EndUpdate; EndUpdate;
end; end;
@ -2064,7 +2056,8 @@ begin
if (Msg=nil) or (Msg.Lines=nil) or not (Msg.Lines.Owner is TLMsgWndView) then if (Msg=nil) or (Msg.Lines=nil) or not (Msg.Lines.Owner is TLMsgWndView) then
begin begin
SelectedView:=nil; SelectedView:=nil;
SelectedLine1:=-1; FSelectedLines.Clear;
Invalidate;
end else begin end else begin
SelectedView:=TLMsgWndView(Msg.Lines.Owner); SelectedView:=TLMsgWndView(Msg.Lines.Owner);
SelectedLine1:=Msg.Index; SelectedLine1:=Msg.Index;
@ -2395,36 +2388,33 @@ begin
Result+=Line.Msg; Result+=Line.Msg;
end; end;
function TMessagesCtrl.GetHeaderText(View: TLMsgWndView): string; function GetStats(Lines: TMessageLines): string;
var
function GetStats(Lines: TMessageLines): string; ErrCnt, WarnCnt, HintCnt: Integer;
var c: TMessageLineUrgency;
ErrCnt: Integer; begin
WarnCnt: Integer; Result:='';
HintCnt: Integer; ErrCnt:=0;
c: TMessageLineUrgency; WarnCnt:=0;
begin HintCnt:=0;
Result:=''; for c:=Low(Lines.UrgencyCounts) to high(Lines.UrgencyCounts) do begin
ErrCnt:=0; //debugln(['GetStats cat=',dbgs(c),' count=',Lines.UrgencyCounts[c]]);
WarnCnt:=0; if c>=mluError then
HintCnt:=0; inc(ErrCnt,Lines.UrgencyCounts[c])
for c:=Low(Lines.UrgencyCounts) to high(Lines.UrgencyCounts) do begin else if c=mluWarning then
//debugln(['GetStats cat=',dbgs(c),' count=',Lines.UrgencyCounts[c]]); inc(WarnCnt,Lines.UrgencyCounts[c])
if c>=mluError then else if c in [mluHint,mluNote] then
inc(ErrCnt,Lines.UrgencyCounts[c]) inc(HintCnt,Lines.UrgencyCounts[c]);
else if c=mluWarning then
inc(WarnCnt,Lines.UrgencyCounts[c])
else if c in [mluHint,mluNote] then
inc(HintCnt,Lines.UrgencyCounts[c]);
end;
if ErrCnt>0 then
Result+=Format(lisErrors2, [IntToStr(ErrCnt)]);
if WarnCnt>0 then
Result+=Format(lisWarnings, [IntToStr(WarnCnt)]);
if HintCnt>0 then
Result+=Format(lisHints, [IntToStr(HintCnt)]);
end; end;
if ErrCnt>0 then
Result+=Format(lisErrors2, [IntToStr(ErrCnt)]);
if WarnCnt>0 then
Result+=Format(lisWarnings, [IntToStr(WarnCnt)]);
if HintCnt>0 then
Result+=Format(lisHints, [IntToStr(HintCnt)]);
end;
function TMessagesCtrl.GetHeaderText(View: TLMsgWndView): string;
begin begin
Result:=View.Caption; Result:=View.Caption;
if Result='' then if Result='' then
@ -2667,8 +2657,8 @@ begin
fSomeViewsRunning:=true; fSomeViewsRunning:=true;
end; end;
function TMessagesCtrl.GetLineAt(Y: integer; out View: TLMsgWndView; out function TMessagesCtrl.GetLineAt(Y: integer; out View: TLMsgWndView;
Line: integer): boolean; out Line: integer): boolean;
var var
i: Integer; i: Integer;
begin begin
@ -2755,16 +2745,6 @@ begin
Invalidate; Invalidate;
end; end;
function TMessagesCtrl.HasSelection: boolean;
var
View: TLMsgWndView;
begin
Result:=false;
View:=SelectedView;
if View=nil then exit;
Result:=SelectedLine1<View.GetShownLineCount(false,true);
end;
{ TMessagesFrame } { TMessagesFrame }
procedure TMessagesFrame.MsgCtrlPopupMenuPopup(Sender: TObject); procedure TMessagesFrame.MsgCtrlPopupMenuPopup(Sender: TObject);
@ -2887,20 +2867,13 @@ procedure TMessagesFrame.MsgCtrlPopupMenuPopup(Sender: TObject);
end; end;
var var
HasText: Boolean;
View: TLMsgWndView; View: TLMsgWndView;
HasFilename: Boolean;
LineNumber: Integer;
Line: TMessageLine;
i: Integer;
HasViewContent: Boolean;
Running: Boolean;
MsgType: String;
CanFilterMsgType: Boolean;
MinUrgency: TMessageLineUrgency; MinUrgency: TMessageLineUrgency;
ToolData: TIDEExternalToolData; ToolData: TIDEExternalToolData;
ToolOptionsCaption: String; Line: TMessageLine;
VisibleCnt: Integer; i, LineNumber, VisibleCnt: Integer;
HasText, HasFilename, HasViewContent, Running, CanFilterMsgType: Boolean;
MsgType, ToolOptionsCaption: String;
begin begin
MessagesMenuRoot.MenuItem:=MsgCtrlPopupMenu.Items; MessagesMenuRoot.MenuItem:=MsgCtrlPopupMenu.Items;
//MessagesMenuRoot.BeginUpdate; //MessagesMenuRoot.BeginUpdate;
@ -2927,11 +2900,17 @@ begin
// check selection // check selection
View:=MessagesCtrl.SelectedView; View:=MessagesCtrl.SelectedView;
if View<>nil then begin if View<>nil then begin
LineNumber:=MessagesCtrl.SelectedLine1; for i:=0 to MessagesCtrl.FSelectedLines.Count-1 do begin
if (LineNumber>=0) and (LineNumber<View.Lines.Count) then begin LineNumber:=MessagesCtrl.FSelectedLines[i];
Line:=View.Lines[LineNumber]; if LineNumber=-1 then Continue; // header
HasFilename:=Line.Filename<>''; if LineNumber=View.Lines.Count then
HasText:=Line.Msg<>''; Line:=View.ProgressLine // progress line
else
Line:=View.Lines[LineNumber]; // normal messages
if Line.Filename<>'' then
HasFilename:=True;
if Line.Msg<>'' then
HasText:=True;
if (Line.SubTool<>'') and (Line.MsgID<>0) then begin if (Line.SubTool<>'') and (Line.MsgID<>0) then begin
MsgType:=GetMsgPattern(Line.SubTool,Line.MsgID,true,40); MsgType:=GetMsgPattern(Line.SubTool,Line.MsgID,true,40);
CanFilterMsgType:=ord(Line.Urgency)<ord(mluError); CanFilterMsgType:=ord(Line.Urgency)<ord(mluError);
@ -3215,11 +3194,21 @@ begin
Result:=MessagesCtrl.GetLastViewWithContent; Result:=MessagesCtrl.GetLastViewWithContent;
end; end;
procedure TMessagesFrame.CopyFilenameMenuItemClick(Sender: TObject);
begin
CopyMsgToClipboard(true);
end;
procedure TMessagesFrame.CopyMsgMenuItemClick(Sender: TObject); procedure TMessagesFrame.CopyMsgMenuItemClick(Sender: TObject);
begin begin
CopyMsgToClipboard(false); CopyMsgToClipboard(false);
end; end;
procedure TMessagesFrame.CopyAllMenuItemClick(Sender: TObject);
begin
CopyAllClicked(false);
end;
procedure TMessagesFrame.CopyShownMenuItemClick(Sender: TObject); procedure TMessagesFrame.CopyShownMenuItemClick(Sender: TObject);
begin begin
CopyAllClicked(true); CopyAllClicked(true);
@ -3305,16 +3294,6 @@ begin
LazarusIDE.DoOpenIDEOptions(TMsgWndOptionsFrame); LazarusIDE.DoOpenIDEOptions(TMsgWndOptionsFrame);
end; end;
procedure TMessagesFrame.CopyFilenameMenuItemClick(Sender: TObject);
begin
CopyMsgToClipboard(true);
end;
procedure TMessagesFrame.CopyAllMenuItemClick(Sender: TObject);
begin
CopyAllClicked(false);
end;
procedure TMessagesFrame.AboutToolMenuItemClick(Sender: TObject); procedure TMessagesFrame.AboutToolMenuItemClick(Sender: TObject);
var var
View: TLMsgWndView; View: TLMsgWndView;
@ -3526,25 +3505,27 @@ begin
// Here we need the line numbers sorted. // Here we need the line numbers sorted.
OrderedSelection.Assign(MessagesCtrl.FSelectedLines); OrderedSelection.Assign(MessagesCtrl.FSelectedLines);
OrderedSelection.Sort; OrderedSelection.Sort;
if OrderedSelection.Count=0 then begin for i:=0 to OrderedSelection.Count-1 do begin
if OnlyFilename then exit; LineNumber:=OrderedSelection[i];
Txt:=MessagesCtrl.GetHeaderText(View); // header Assert(LineNumber<=View.Lines.Count, 'TMessagesFrame.CopyMsgToClipboard: LineNumber is too big.');
end if LineNumber=-1 then begin
else begin if OnlyFilename then
for i:=0 to OrderedSelection.Count-1 do begin Txt:=rsResourceFileName
LineNumber:=OrderedSelection[i];
Assert(LineNumber<=View.Lines.Count, 'TMessagesFrame.CopyMsgToClipboard: LineNumber is too big.');
if LineNumber=View.Lines.Count then
Line:=View.ProgressLine // progress line
else else
Line:=View.Lines[LineNumber]; // normal messages Txt:=MessagesCtrl.GetHeaderText(View); // header
end
else begin
if LineNumber=View.Lines.Count then
Line:=View.ProgressLine // progress line
else
Line:=View.Lines[LineNumber]; // normal messages
if OnlyFilename then if OnlyFilename then
Txt+=Line.Filename Txt+=Line.Filename
else else
Txt+=MessagesCtrl.GetLineText(Line); Txt+=MessagesCtrl.GetLineText(Line);
if i<OrderedSelection.Count-1 then
Txt+=LineEnding;
end; end;
if i<OrderedSelection.Count-1 then
Txt+=LineEnding;
end; end;
finally finally
OrderedSelection.Free; OrderedSelection.Free;