diff --git a/components/turbopower_ipro/iphtml.pas b/components/turbopower_ipro/iphtml.pas
index 9bb7f88261..b705514892 100644
--- a/components/turbopower_ipro/iphtml.pas
+++ b/components/turbopower_ipro/iphtml.pas
@@ -127,7 +127,7 @@ type
{$ENDIF}
TIpHtml = class;
-
+
{$IFDEF IP_LAZARUS}
TIpAbstractHtmlDataProvider = class;
{$DEFINE CSS_INTERFACE}
@@ -332,7 +332,7 @@ type
procedure UnmarkControl; virtual;
procedure HideUnmarkedControl; virtual;
procedure EnumChildren(EnumProc: TIpHtmlNodeEnumProc; UserData: Pointer); virtual;
- procedure AppendSelection(var S : string); virtual;
+ procedure AppendSelection(var S : string; var Completed: Boolean); virtual;
public
constructor Create(ParentNode : TIpHtmlNode);
destructor Destroy; override;
@@ -368,7 +368,7 @@ type
protected
procedure ReportDrawRects(M : TRectMethod); override;
procedure ReportMapRects(M : TRectMethod); override;
- procedure AppendSelection(var S : string); override;
+ procedure AppendSelection(var S : string; var Completed: Boolean); override;
procedure EnumChildren(EnumProc: TIpHtmlNodeEnumProc; UserData: Pointer); override;
public
constructor Create(ParentNode : TIpHtmlNode);
@@ -487,7 +487,6 @@ type
TIpHtmlNodeBlock = class(TIpHtmlNodeCore)
private
- function CheckSelection(aSelIndex: Integer): Boolean;
function GetPageRect: TRect;
protected
FLayouter : TIpHtmlBaseLayouter;
@@ -502,7 +501,7 @@ type
function GetHeight(const RenderProps: TIpHtmlProps; const Width: Integer): Integer;
procedure InvalidateSize; override;
procedure ReportCurDrawRects(aOwner: TIpHtmlNode; M : TRectMethod); override;
- procedure AppendSelection(var S : string); override;
+ procedure AppendSelection(var S : string; var Completed: Boolean); override;
procedure SetBackground(const AValue: string);
procedure SetBgColor(const AValue: TColor);
procedure SetTextColor(const AValue: TColor);
@@ -1472,7 +1471,7 @@ type
procedure SetBgColor(const AValue: TColor);
procedure SetTextColor(const AValue: TColor);
protected
- procedure AppendSelection(var S: String); override;
+ procedure AppendSelection(var S: String; var Completed: Boolean); override;
public
constructor Create(ParentNode : TIpHtmlNode);
procedure SetProps(const RenderProps: TIpHtmlProps); override;
@@ -1499,7 +1498,7 @@ type
FWidth: TIpHtmlLength;
FVAlign: TIpHtmlVAlign3;
protected
- procedure AppendSelection(var S: String); override;
+ procedure AppendSelection(var S: String; var Completed: Boolean); override;
procedure DimChanged(Sender: TObject);
public
FPadRect : TRect;
@@ -2693,7 +2692,7 @@ uses
{$IFDEF Html_Print}
Printers, PrintersDlgs, IpHtmlPv,
{$ENDIF}
- ipHtmlBlockLayout, ipHtmlTableLayout;
+ StrUtils, ipHtmlBlockLayout, ipHtmlTableLayout;
{$R *.res}
@@ -3841,7 +3840,7 @@ begin
FParentNode.ReportCurDrawRects(Owner, M);
end;
-procedure TIpHtmlNode.AppendSelection(var S: string);
+procedure TIpHtmlNode.AppendSelection(var S: string; var Completed: Boolean);
begin
end;
@@ -4286,13 +4285,17 @@ begin
TIpHtmlNode(FChildren[i]).EnumChildren(EnumProc, UserData);
end;
-procedure TIpHtmlNodeMulti.AppendSelection(var S: string);
+procedure TIpHtmlNodeMulti.AppendSelection(var S: string; var Completed: Boolean);
var
i : Integer;
begin
- inherited;
+ if Completed then
+ exit;
for i := 0 to Pred(FChildren.Count) do
- TIpHtmlNode(FChildren[i]).AppendSelection(S);
+ begin
+ TIpHtmlNode(FChildren[i]).AppendSelection(S, Completed);
+ if Completed then exit;
+ end;
end;
{ TIpHtmlNodeBODY }
@@ -7767,7 +7770,6 @@ begin
if not FAllSelected
and ((FStartSel.x < 0) or (FEndSel.x < 0)) then Exit;
-
if not FAllSelected then begin
CurBlock := nil;
@@ -8551,11 +8553,14 @@ end;
procedure TIpHtml.CopyToClipboard;
var
S : string;
+ completed: Boolean;
begin
if HaveSelection then begin
S := '';
- if FHtml <> nil then
- FHtml.AppendSelection(S);
+ if FHtml <> nil then begin
+ completed := false; // terminate recursion if selection-end-point is found
+ FHtml.AppendSelection(S, completed);
+ end;
if S <> '' then begin
Clipboard.Open;
try
@@ -9121,56 +9126,67 @@ begin
end;
end;
-function TIpHtmlNodeBlock.CheckSelection(aSelIndex: Integer): Boolean;
-var
- CurElem : PIpHtmlElement;
- R : TRect;
-begin
- CurElem := PIpHtmlElement(FLayouter.FElementQueue[aSelIndex]);
- R := CurElem.WordRect2;
- if (R.Bottom <> 0) and (R.Top > Owner.FStartSel.Y)
- and (R.Bottom < Owner.FEndSel.Y) then
- Exit(False)
- else
- if PtInRect(R, Owner.FStartSel) or PtInRect(R, Owner.FEndSel) then
- Exit(False)
- else
- if (R.Bottom >= Owner.FStartSel.Y) and (R.Top <= Owner.FEndSel.Y)
- and (R.Left >= Owner.FStartSel.X) and (R.Right <= Owner.FEndSel.X) then
- Exit(False);
- Result := True;
-end;
-
function TIpHtmlNodeBlock.GetPageRect: TRect;
begin
Result := FLayouter.FPageRect;
end;
-procedure TIpHtmlNodeBlock.AppendSelection(var S: string);
+procedure TIpHtmlNodeBlock.AppendSelection(var S: string; var Completed: Boolean);
var
- LastY, StartSelIndex, EndSelIndex, i : Integer;
+ //LastY,
+ StartSelIndex, EndSelIndex, i, istart, iend : Integer;
CurElem : PIpHtmlElement;
R : TRect;
LFDone : Boolean;
+ EndPt: TPoint;
begin
- if not Owner.FAllSelected then begin
- StartSelIndex := 0;
- while StartSelIndex < FLayouter.FElementQueue.Count do begin
- if not CheckSelection(StartSelIndex) then
- Break;
- Inc(StartSelIndex);
+ if Completed then
+ exit;
+
+ StartSelIndex := 0;
+ EndSelIndex := pred(FLayouter.FElementQueue.Count);
+ if not Owner.FAllSelected then
+ begin
+ // Find elements which contain the start-/end-selection-points
+ // Note: they may not be in correct order because the y coords of the start/end
+ // clicks may be reversed if in the same line of an etObject element!
+ istart := -1;
+ iend := -1;
+ for i:=0 to pred(FLayouter.FElementQueue.Count) do
+ begin
+ CurElem := PIpHtmlElement(FLayouter.FElementQueue[i]);
+ if PtInRect(CurElem^.WordRect2, Owner.FStartSel) then
+ istart := i;
+ if PtInRect(CurElem^.WordRect2, Owner.FEndSel) then
+ iend := i;
+ if (istart <> -1) and (iend <> -1) then
+ break;
end;
- EndSelIndex := Pred(FLayouter.FElementQueue.Count);
- while EndSelIndex >= 0 do begin
- if not CheckSelection(EndSelIndex) then
- Break;
- Dec(EndSelIndex);
+ if (istart <> -1) and (iend <> -1) then
+ begin
+ if istart < iend then
+ begin
+ StartSelIndex := istart;
+ EndSelIndex := iend;
+ EndPt := Owner.FEndSel;
+ end else
+ begin
+ StartSelIndex := iend;
+ EndSelIndex := istart;
+ EndPt := Owner.FStartSel;
+ end;
+ end else
+ if (istart <> -1) and (iend = -1) then
+ StartSelIndex := istart
+ else
+ if (istart = -1) and (iend <> -1) then
+ begin
+ EndSelIndex := iend;
+ EndPt := Owner.FEndSel;
end;
- end else begin
- StartSelIndex := 0;
- EndSelIndex := FLayouter.FElementQueue.Count - 1;
end;
- LastY := -1;
+
+ //LastY := -1;
LFDone := True;
for i := StartSelIndex to EndSelIndex do begin
CurElem := PIpHtmlElement(FLayouter.FElementQueue[i]);
@@ -9181,6 +9197,7 @@ begin
LFDone := True;
end;
}
+
case CurElem.ElementType of
etWord :
begin
@@ -9189,7 +9206,7 @@ begin
end;
etObject :
begin
- TIpHtmlNodeAlignInline(CurElem.Owner).AppendSelection(S);
+ TIpHtmlNodeAlignInline(CurElem.Owner).AppendSelection(S, Completed);
LFDone := False;
end;
etSoftLF..etClearBoth :
@@ -9198,7 +9215,16 @@ begin
LFDone := True;
end;
end;
- LastY := R.Top;
+ //LastY := R.Top;
+
+ // Prevent running over selection end if there is a etObject at this level
+ // of recursion.
+ if not Owner.FAllSelected then
+ if PtInRect(R, EndPt) then
+ begin
+ Completed := true;
+ exit;
+ end;
end;
end;
@@ -10346,13 +10372,15 @@ begin
FTextColor := -1;
end;
-procedure TIpHtmlNodeTR.AppendSelection(var S: String);
+procedure TIpHtmlNodeTR.AppendSelection(var S: String; var Completed: Boolean);
var
prev: TIpHtmlNode;
begin
+ if Completed then
+ exit;
prev := GetPrevSiblingNode(Self);
if prev is TIpHtmlNodeTR then S := S + LineEnding;
- inherited AppendSelection(S);
+ inherited AppendSelection(S, Completed);
end;
procedure TIpHtmlNodeTR.SetBgColor(const AValue: TColor);
@@ -12476,13 +12504,16 @@ begin
inherited;
end;
-procedure TIpHtmlNodeTableHeaderOrCell.AppendSelection(var S: String);
+procedure TIpHtmlNodeTableHeaderOrCell.AppendSelection(var S: String;
+ var Completed: Boolean);
var
prev: TIpHtmlNode;
begin
+ if Completed then
+ exit;
prev := GetPrevSiblingNode(self);
if prev is TIpHtmlNodeTableHeaderOrCell then S := S + #9;
- inherited AppendSelection(S);
+ inherited AppendSelection(S, Completed);
end;
procedure TIpHtmlNodeTableHeaderOrCell.CalcMinMaxPropWidth(RenderProps: TIpHtmlProps;