CRVFData.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:263k
- if Result then
- exit;
- end;
- end;
- if Down then
- SubPos := rvdFirst
- else
- SubPos := rvdLast;
- SrchStart(Down, strt, offs);
- if (strt>=Items.Count) or (strt<0) then exit;
- if Items.Objects[strt]=item then begin
- if Down then
- inc(strt)
- else
- dec(strt);
- if (strt>=Items.Count) or (strt<0) then exit;
- end
- else if GetItemStyle(strt)>=0 then begin
- ItemOptions := GetItemOptions(strt);
- if not Down then begin
- s2 := RVU_Copy(Items[strt], 1, offs-1, ItemOptions);
- offs := 1;
- end
- else
- s2 := RVU_Copy(Items[strt],offs,RVU_Length(Items[strt],ItemOptions), ItemOptions);
- {$IFNDEF RVDONOTUSEUNICODE}
- if rvioUnicode in ItemOptions then
- s2 := RVU_UnicodeToAnsi(GetDefaultCodePage, s2);
- {$ENDIF}
- if not MatchCase then
- s2 := AnsiUpperCase(s2);
- if not Down then
- so := RevPos(s,s2)
- else
- so := FwdPos(s,s2);
- if so<>0 then begin
- Result := True;
- len := Length(s);
- UpdateUnicodePos(s2, s, ItemOptions, so, len);
- SrchSelectIt(strt, offs+so-1, len, not Down);
- exit;
- end;
- if Down then
- inc(strt)
- else
- dec(strt);
- end;
- if not Down then
- for i := strt downto 0 do begin
- if GetItemStyle(i)>=0 then begin
- {$IFNDEF RVDONOTUSEUNICODE}
- if rvioUnicode in GetItemOptions(i) then
- s2 := RVU_UnicodeToAnsi(GetDefaultCodePage, Items[i])
- else
- {$ENDIF}
- s2 := Items[i];
- if not MatchCase then
- offs := RevPos(s,AnsiUpperCase(s2))
- else
- offs := RevPos(s, s2);
- if offs<>0 then begin
- Result := True;
- len := Length(s);
- UpdateUnicodePos(s2, s, GetItemOptions(i), offs, len);
- SrchSelectIt(i, offs, len, not Down);
- exit;
- end;
- end
- else begin
- item := TCustomRVItemInfo(Items.Objects[i]);
- SubRVData := TCustomRVFormattedData(item.GetSubRVData(StoreSub, SubPos));
- if SubRVData<>nil then begin
- Result := SearchInItem(item, StoreSub, SubRVData);
- if Result then
- exit;
- end;
- end;
- end
- else
- for i := strt to Items.Count-1 do
- if GetItemStyle(i)>=0 then begin
- {$IFNDEF RVDONOTUSEUNICODE}
- if rvioUnicode in GetItemOptions(i) then
- s2 := RVU_UnicodeToAnsi(GetDefaultCodePage, Items[i])
- else
- {$ENDIF}
- s2 := Items[i];
- if not MatchCase then
- offs := FwdPos(s,AnsiUpperCase(s2))
- else
- offs := FwdPos(s, s2);
- if offs<>0 then begin
- Result := True;
- len := Length(s);
- UpdateUnicodePos(s2, s, GetItemOptions(i), offs, len);
- SrchSelectIt(i, offs, len, not Down);
- exit;
- end;
- end
- else begin
- item := GetItem(i);
- SubRVData := TCustomRVFormattedData(item.GetSubRVData(StoreSub, SubPos));
- if SubRVData<>nil then begin
- Result := SearchInItem(item, StoreSub, SubRVData);
- if Result then
- exit;
- end;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetSelectionBounds(var StartItemNo, StartItemOffs,
- EndItemNo, EndItemOffs: Integer;
- Normalize: Boolean);
- begin
- StoreSelBounds(StartItemNo, EndItemNo, StartItemOffs, EndItemOffs, Normalize);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetSelectionBoundsEx(var StartItemNo,
- StartItemOffs, EndItemNo, EndItemOffs: Integer; Normalize: Boolean);
- begin
- GetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs, Normalize);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AdjustSelection;
- begin
- if (FSelStartNo<0) or (FSelEndNo<0) then
- exit;
- if FSelStartOffs<GetOffsBeforeDrawItem(FSelStartNo) then
- FSelStartOffs := GetOffsBeforeDrawItem(FSelStartNo);
- if FSelStartOffs>GetOffsAfterDrawItem(FSelStartNo) then
- FSelStartOffs := GetOffsAfterDrawItem(FSelStartNo);
- if FSelEndOffs<GetOffsBeforeDrawItem(FSelEndNo) then
- FSelEndOffs := GetOffsBeforeDrawItem(FSelEndNo);
- if FSelEndOffs>GetOffsAfterDrawItem(FSelEndNo) then
- FSelEndOffs := GetOffsAfterDrawItem(FSelEndNo);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoSetSelectionBounds(StartItemNo, StartItemOffs,
- EndItemNo, EndItemOffs: Integer);
- begin
- DeselectPartiallySelectedItem(nil);
- DestroyInplaceEditor;
- {$IFNDEF RVDONOTUSELISTS}
- if (StartItemNo>=0) and (EndItemNo>=0) then begin
- if (StartItemNo+1<Items.Count) and (GetItemStyle(StartItemNo)=rvsListMarker) then begin
- inc(StartItemNo);
- StartItemOffs := GetOffsBeforeItem(StartItemNo);
- end;
- if (EndItemNo+1<Items.Count) and (GetItemStyle(EndItemNo)=rvsListMarker) then begin
- inc(EndItemNo);
- EndItemOffs := GetOffsBeforeItem(EndItemNo);
- end;
- end;
- {$ENDIF}
- RestoreSelBounds(StartItemNo, EndItemNo, StartItemOffs, EndItemOffs);
- AdjustSelection;
- // if GetRVStyle.SelectionMode=rvsmParagraph then
- // ExpandSelectionToParagraph(True);
- DoOnSelection(True);
- DoSelect;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.SetSelectionBounds(StartItemNo, StartItemOffs,
- EndItemNo, EndItemOffs: Integer);
- begin
- {$IFNDEF RVDONOTUSELIVESPELL}
- LiveSpellingCheckCurrentItem;
- {$ENDIF}
- DoSetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetWordAt(X,Y: Integer;
- var RVData: TCustomRVFormattedData; var ItemNo: Integer;
- var Word: String);
- var StyleNo, Offs: Integer;
- begin
- if not FindWordAt(Word, X,Y, StyleNo, ItemNo, Offs, RVData) then
- ItemNo := -1;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetClientSelectionRect: TRect;
- var i: Integer;
- StartNo, EndNo, StartOffs, EndOffs, x,y: Integer;
- R: TRect;
- begin
- // This is very rough function for returning selection rectangle
- // It does not count offsets in text items.
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- Result := TCustomRVFormattedData(GetChosenRVData).GetClientSelectionRect;
- exit;
- end;
- {$ENDIF}
- if SelectionExists(False, False) then begin
- ResetSubCoords;
- GetSelBounds(StartNo, EndNo, StartOffs, EndOffs, True);
- Result := Rect(0,0,0,0);
- for i:= StartNo to EndNo do begin
- with DrawItems[i] do
- R := Bounds(Left-GetZHOffs,Top-GetZVOffs, Width, Height);
- UnionRect(Result, Result, R);
- end;
- R := Rect(0,0,GetWidth,GetHeight);
- IntersectRect(Result, Result, R);
- GetOrigin(x,y);
- OffsetRect(Result, x,y);
- end
- else begin
- GetOriginEx(x,y);
- Result := Bounds(x,y,GetWidth,GetHeight);
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.OnTimerScroll;
- begin
- //LastSelectionRect.Left := 1;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetSelectionRect:TRect;
- var P: TPoint;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetInplaceEditor<>nil) and (GetInplaceEditor is TCustomRichView) then begin
- Result := TCustomRichView(GetInplaceEditor).RVData.GetSelectionRect;
- exit;
- end;
- {$ENDIF}
- Result := GetClientSelectionRect;
- P := Point(0,0);
- P := ClientToScreen(P);
- OffsetRect(Result, P.x, P.y);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.SelectWordAt(X,Y: Integer);
- var StyleNo, ItemNo, Offs: Integer;
- Word: String;
- RVData: TCustomRVFormattedData;
- begin
- if not (rvoAllowSelection in Options) then exit;
- if FindWordAt(Word, X, Y, StyleNo, ItemNo, Offs, RVData) then begin
- if StyleNo>=0 then
- RVData.SetSelectionBounds(ItemNo, Offs, ItemNo, Offs+RVU_Length(Word, GetItemOptions(ItemNo)))
- else
- RVData.SetSelectionBounds(ItemNo, 0, ItemNo, 1);
- Invalidate;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetCheckpointXY(CheckpointData: TCheckpointData;
- var X,Y: Integer);
- begin
- if CheckpointData = nil then
- raise ERichViewError.Create(errRVNil);
- if CheckpointData = NotAddedCP then begin
- X := 0;
- Y := DocumentHeight;
- end
- else
- with TRVCPInfo(CheckpointData) do begin
- if (ItemInfo=nil) or (ItemInfo.DrawItemNo=-1) then
- raise ERichViewError.Create(errRVNotFormatted);
- X := DrawItems[ItemInfo.DrawItemNo].Left;
- Y := DrawItems[ItemInfo.DrawItemNo].Top;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetCheckpointYEx(CheckpointData: TCheckpointData): Integer;
- begin
- if CheckpointData = nil then
- raise ERichViewError.Create(errRVNil);
- if CheckpointData = NotAddedCP then
- Result := DocumentHeight
- else
- with TRVCPInfo(CheckpointData) do begin
- if (ItemInfo=nil) or (ItemInfo.DrawItemNo=-1) then
- raise ERichViewError.Create(errRVNotFormatted);
- Result := DrawItems[ItemInfo.DrawItemNo].Top;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetJumpPointY(id: Integer): Integer;
- var i: Integer;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- Result := TCustomRVFormattedData(GetChosenRVData).GetJumpPointY(id);
- if Result>0 then
- exit;
- end;
- {$ENDIF}
- Result := 0;
- for i := 0 to Jumps.Count-1 do
- if TRVJumpInfo(Jumps[i]).id = id-FirstJumpNo then begin
- Result := TRVJumpInfo(Jumps[i]).t;
- exit;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetJumpPointItemNo(id: Integer): Integer;
- var i: Integer;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- Result := TCustomRVFormattedData(GetChosenRVData).GetJumpPointItemNo(id);
- if Result>=0 then
- exit;
- end;
- {$ENDIF}
- Result := -1;
- for i :=0 to Jumps.Count-1 do
- if TRVJumpInfo(Jumps[i]).id = id-FirstJumpNo then begin
- Result := TRVJumpInfo(Jumps[i]).RVData.DrawItems[TRVJumpInfo(Jumps[i]).DrawItemNo].ItemNo;
- exit;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetJumpPointLocation(id: Integer;
- var RVData: TCustomRVFormattedData; var ItemNo: Integer);
- var i: Integer;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).GetJumpPointLocation(id,RVData,ItemNo);
- if ItemNo>=0 then
- exit;
- end;
- {$ENDIF}
- ItemNo := -1;
- RVData := nil;
- for i :=0 to Jumps.Count-1 do
- if TRVJumpInfo(Jumps[i]).id = id-FirstJumpNo then begin
- RVData := TRVJumpInfo(Jumps[i]).RVData;
- ItemNo := RVData.DrawItems[TRVJumpInfo(Jumps[i]).DrawItemNo].ItemNo;
- exit;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyText_;
- begin
- if SelectionExists(True, True) then begin
- Clipboard.SetTextBuf(PChar(GetSelText(False)));
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyTextW_;
- var mem: Cardinal;
- ptr: Pointer;
- s: String;
- zero: Word;
- begin
- if SelectionExists(True, True) then begin
- s := GetSelText(True);
- mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Length(s)+2);
- if mem=0 then raise ERichViewError.Create(errRVNoMemory);
- ptr := GlobalLock(mem);
- Move(PChar(s)^,ptr^, Length(s));
- zero := 0;
- Move(zero,(PChar(ptr)+Length(s))^, 2);
- GlobalUnlock(mem);
- Clipboard.SetAsHandle(CF_UNICODETEXT ,mem);
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyImage_;
- var gr: TGraphic;
- begin
- gr := GetSelectedImage;
- if gr<>nil then
- try
- Clipboard.Assign(gr);
- except;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.Copy(Color: TColor; Background: TRVBackground);
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).Copy(clNone, nil);
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True, True) then begin
- Clipboard.Clear;
- Clipboard.Open;
- try
- DoCopy;
- {$IFNDEF RVDONOTUSERVF}
- CopyRVF_(Color, Background);
- {$ENDIF}
- CopyText_;
- CopyImage_;
- {$IFNDEF RVDONOTUSEUNICODE}
- CopyTextW_;
- {$ENDIF}
- {$IFNDEF RVDONOTUSERTF}
- CopyRTF_(Color, Background);
- {$ENDIF}
- finally
- Clipboard.Close;
- end;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.CopyDef(Color: TColor; Background: TRVBackground): Boolean;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- Result := TCustomRVFormattedData(GetChosenRVData).CopyDef(clNone, nil);
- exit;
- end;
- {$ENDIF}
- Result := ((rvoAutoCopyText in Options) or
- {$IFNDEF RVDONOTUSERVF}
- (rvoAutoCopyRVF in Options) or
- {$ENDIF}
- {$IFNDEF RVDONOTUSEUNICODE}
- (rvoAutoCopyUnicodeText in Options) or
- {$ENDIF}
- {$IFNDEF RVDONOTUSERTF}
- (rvoAutoCopyRTF in Options) or
- {$ENDIF}
- (rvoAutoCopyImage in Options) or
- IsAssignedCopy
- );
- if Result and SelectionExists(True, True) then begin
- Clipboard.Clear;
- Clipboard.Open;
- DoCopy;
- {$IFNDEF RVDONOTUSERVF}
- if (rvoAutoCopyRVF in Options) then CopyRVF_(Color, Background);
- {$ENDIF}
- if (rvoAutoCopyText in Options) and not (RVNT and (rvoAutoCopyUnicodeText in Options)) then CopyText_;
- if (rvoAutoCopyImage in Options) then CopyImage_;
- {$IFNDEF RVDONOTUSEUNICODE}
- if (rvoAutoCopyUnicodeText in Options) then CopyTextW_;
- {$ENDIF}
- {$IFNDEF RVDONOTUSERTF}
- if (rvoAutoCopyRTF in Options) then CopyRTF_(Color, Background);
- {$ENDIF}
- Clipboard.Close;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyImage;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).CopyImage;
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True, True) then begin
- Clipboard.Clear;
- CopyImage_;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyText;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).CopyText;
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True, True) then begin
- Clipboard.Clear;
- CopyText_;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyTextW;
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).CopyTextW;
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True, True) then begin
- Clipboard.Clear;
- CopyTextW_;
- end;
- end;
- {------------------------------------------------------------------------------}
- {$IFNDEF RVDONOTUSERTF}
- procedure TCustomRVFormattedData.CopyRTF(Color: TColor; Background: TRVBackground);
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).CopyRTF(clNone, nil);
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True, True) then begin
- Clipboard.Clear;
- CopyRTF_(Color, Background);
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyRTF_(Color: TColor; Background: TRVBackground);
- var mem: Cardinal;
- ptr: Pointer;
- Stream: TMemoryStream;
- begin
- Stream := TMemoryStream.Create;
- try
- SaveRTFToStream(Stream, '', True, 0, Color, Background,
- nil, nil, nil, nil, nil, 0.0);
- mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Stream.Size);
- if mem=0 then raise ERichViewError.Create(errRVNoMemory);
- ptr := GlobalLock(mem);
- Move(Stream.Memory^,ptr^,Stream.Size);
- GlobalUnlock(mem);
- finally
- Stream.Free;
- end;
- Clipboard.SetAsHandle(CFRV_RTF, mem);
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- {$IFNDEF RVDONOTUSERVF}
- procedure TCustomRVFormattedData.RVFGetLimits(SaveScope: TRVFSaveScope;
- var StartItem, EndItem, StartOffs, EndOffs: Integer;
- var StartPart, EndPart: TRVMultiDrawItemPart);
- begin
- if SaveScope=rvfss_Selection then begin
- StartPart := nil;
- EndPart := nil;
- StoreSelBounds(StartItem, EndItem, StartOffs, EndOffs, True);
- end
- else
- inherited RVFGetLimits(SaveScope, StartItem, EndItem, StartOffs, EndOffs, StartPart, EndPart);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyRVF_(Color: TColor; Background: TRVBackground);
- var mem: Cardinal;
- ptr: Pointer;
- Size: Integer;
- Stream: TMemoryStream;
- begin
- Stream := TMemoryStream.Create;
- try
- Size := 0;
- Stream.WriteBuffer(Size, SizeOf(Size));
- SaveRVFToStream(Stream, True, Color, Background, nil);
- Size := Stream.Position-SizeOf(Size);
- Stream.Position := 0;
- Stream.WriteBuffer(Size, SizeOf(Size));
- mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Stream.Size);
- if mem=0 then raise ERichViewError.Create(errRVNoMemory);
- ptr := GlobalLock(mem);
- Move(Stream.Memory^,ptr^,Stream.Size);
- GlobalUnlock(mem);
- finally
- Stream.Free;
- end;
- Clipboard.SetAsHandle(CFRV_RVF,mem);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CopyRVF(Color: TColor; Background: TRVBackground);
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- if (GetChosenRVData<>nil) then begin
- TCustomRVFormattedData(GetChosenRVData).CopyRVF(clNone, nil);
- exit;
- end;
- {$ENDIF}
- if SelectionExists(True,True) then begin
- Clipboard.Clear;
- CopyRVF_(Color, Background);
- end;
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AfterVScroll;
- var CP: TRVCPInfo;
- y, ymin, ymax: Integer;
- {..........................................................}
- function FindCPBefore(EndCP: TRVCPInfo): TRVCPInfo;
- begin
- Result := EndCP;
- while (Result<>nil) and (not Result.RaiseEvent) do
- Result := Result.Prev;
- end;
- {..........................................................}
- begin
- if not IsAssignedCheckpointVisible or (GetCPEventKind=cpeNone) then
- exit;
- ymin := GetVOffs;
- ymax := ymin+GetHeight;
- CP := FirstCP;
- case GetCPEventKind of
- cpeWhenVisible: // raise event for first visible cp
- begin
- while CP<>nil do begin
- if CP.RaiseEvent then begin
- if CP.ItemInfo.DrawItemNo=-1 then exit; // not formatted
- y := DrawItems[CP.ItemInfo.DrawItemNo].Top;
- if y>=ymin then begin
- if y>ymax then begin
- if LastRaisedCP<>nil then begin
- LastRaisedCP := nil;
- DoCheckpointVisible(nil);
- end;
- exit;
- end;
- if CP=LastRaisedCP then exit;
- LastRaisedCP := CP;
- DoCheckpointVisible(CP);
- exit;
- end;
- end;
- CP := CP.Next;
- end;
- if (NotAddedCP<>nil) and (NotAddedCP.RaiseEvent) and (NotAddedCP<>LastRaisedCP) and
- (DocumentHeight<ymax) then begin
- LastRaisedCP := NotAddedCP;
- DoCheckpointVisible(NotAddedCP);
- exit;
- end;
- if LastRaisedCP<>nil then begin
- LastRaisedCP := nil;
- DoCheckpointVisible(nil);
- end;
- end;
- cpeAsSectionStart: // raise event for first visible cp
- // if there is no such cp, raise event for the closest cp
- // before visible area
- begin
- while CP<>nil do begin
- if CP.RaiseEvent then begin
- if CP.ItemInfo.DrawItemNo=-1 then exit; // not formatted
- y := DrawItems[CP.ItemInfo.DrawItemNo].Top;
- if y>=ymin then begin
- if y>ymax then
- CP := FindCPBefore(CP.Prev);
- if CP<>nil then begin
- if CP=LastRaisedCP then exit;
- LastRaisedCP := CP;
- DoCheckpointVisible(CP);
- end;
- exit;
- end;
- end;
- CP := CP.Next;
- end;
- if (NotAddedCP<>nil) and (NotAddedCP.RaiseEvent) and (DocumentHeight<ymax) then begin
- if NotAddedCP=LastRaisedCP then exit;
- LastRaisedCP := NotAddedCP;
- DoCheckpointVisible(NotAddedCP);
- exit;
- end;
- CP := FindCPBefore(LastCP);
- if CP<>nil then begin
- y := DrawItems[CP.ItemInfo.DrawItemNo].Top;
- if y<=ymin then begin
- if CP=LastRaisedCP then exit;
- LastRaisedCP := CP;
- DoCheckpointVisible(CP);
- exit;
- end;
- end;
- end;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.UpdateBackgroundPaletteInfo(Background: TRVBackground);
- begin
- State := State + [rvstChangingBkPalette];
- Background.UpdatePaletted(GetDoInPaletteMode, GetRVPalette, GetRVLogPalette);
- State := State - [rvstChangingBkPalette];
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.UpdatingBackgroundPalette: Boolean;
- begin
- Result := rvstChangingBkPalette in State;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.StartFormatting;
- begin
- State := State + [rvstSkipformatting];
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.EndFormatting;
- begin
- State := State - [rvstSkipformatting];
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetParaBounds(DINo1, DINo2: Integer; var ParaStart,
- ParaEnd: Integer);
- var ItemNo: Integer;
- item: TCustomRVItemInfo;
- begin
- { calculating paragraphs bounds }
- ParaStart := DINo1;
- while (ParaStart>0) do begin
- item := GetItem(DrawItems[ParaStart].ItemNo);
- if not item.SameAsPrev and not item.BR and
- (DrawItems[ParaStart-1].ItemNo<>DrawItems[ParaStart].ItemNo) then break;
- dec(ParaStart);
- end;
- { and prev. paragraph...}
- if ParaStart<>0 then dec(ParaStart);
- while (ParaStart>0) do begin
- item := GetItem(DrawItems[ParaStart].ItemNo);
- if not item.SameAsPrev and not item.BR and
- (DrawItems[ParaStart-1].ItemNo<>DrawItems[ParaStart].ItemNo) then break;
- dec(ParaStart);
- end;
- ParaEnd := DINo2;
- ItemNo := DrawItems[ParaEnd].ItemNo;
- while (ParaEnd<DrawItems.Count) and (DrawItems[ParaEnd].ItemNo=ItemNo) do
- inc(ParaEnd);
- while (ParaEnd<DrawItems.Count) and (DrawItems[ParaEnd].ItemNo<Items.Count) do begin
- item := GetItem(DrawItems[ParaEnd].ItemNo);
- if not item.SameAsPrev and not item.BR then
- break;
- inc(ParaEnd);
- end;
- { and next paragraph...}
- if (ParaEnd<DrawItems.Count) then begin
- ItemNo := DrawItems[ParaEnd].ItemNo;
- while (ParaEnd<DrawItems.Count) and
- (DrawItems[ParaEnd].ItemNo=ItemNo) do inc(ParaEnd);
- while (ParaEnd<DrawItems.Count) and (DrawItems[ParaEnd].ItemNo<Items.Count) do begin
- item := GetItem(DrawItems[ParaEnd].ItemNo);
- if not item.SameAsPrev and not item.BR then
- break;
- inc(ParaEnd);
- end;
- end;
- dec(ParaEnd);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.FormatParas(StartDrawItemNo, EndDrawItemNo,
- ItemsInserted: Integer);
- var First,Last, ItemNo: Integer;
- begin
- { calculating paragraphs bounds }
- First := StartDrawItemNo;
- while (First>0) do begin
- if not GetItem(DrawItems[First].ItemNo).SameAsPrev and
- (DrawItems[First-1].ItemNo<>DrawItems[First].ItemNo) then break;
- dec(First);
- end;
- Last := EndDrawItemNo;
- ItemNo := DrawItems[Last].ItemNo;
- if ItemNo>=Items.Count-1 then
- Last := DrawItems.Count-1
- else begin
- while (Last<DrawItems.Count) and
- (DrawItems[Last].ItemNo=ItemNo) do inc(Last);
- if Last<DrawItems.Count then begin
- ItemNo := DrawItems[Last].ItemNo;
- if ItemNo>=Items.Count-1 then
- Last := DrawItems.Count-1
- else begin
- while (Last<DrawItems.Count) and
- (DrawItems[Last].ItemNo+ItemsInserted<Items.Count) and
- TCustomRVItemInfo(Items.Objects[DrawItems[Last].ItemNo+ItemsInserted]).SameAsPrev do
- inc(Last);
- if Last<>DrawItems.Count-1 then dec(Last);
- end;
- end
- else
- Last := DrawItems.Count-1;
- end;
- FormatParasExact(First, Last,ItemsInserted, False);
- end;
- {-----------------------------------------------------------------------}
- procedure TCustomRVFormattedData.FormatParasExact(StartDrawItemNo,EndDrawItemNo,
- ItemsInserted: Integer; NoCaching: Boolean);
- function GetParagraphBottom(EndDrawItemNo: Integer):Integer;
- var i: Integer;
- begin
- Result := GetTopMargin;
- i := EndDrawItemNo;
- while (i>=0) do
- with DrawItems[i] do begin
- if Top+Height+ExtraSpaceBelow>Result then
- Result := Top+Height+ExtraSpaceBelow;
- if FromNewLine then
- break;
- dec(i);
- end;
- end;
- function GetParagraphTop(StartDrawItemNo: Integer):Integer;
- var i: Integer;
- begin
- Result := DrawItems[StartDrawItemNo].Top;
- i := StartDrawItemNo+1;
- while (i<DrawItems.Count) and
- not DrawItems[i].FromNewLine do
- with DrawItems[i] do begin
- if Top<Result then
- Result := Top;
- inc(i);
- end;
- end;
- procedure FormatParasExact_(var StartItemNo,EndItemNo: Integer);
- var PrevParBottom, ParBottom, NextParTop: Integer;
- i: Integer;
- sad: TRVScreenAndDevice;
- DLC: Integer;
- Canvas: TCanvas;
- item: TCustomRVItemInfo;
- RVStyle: TRVStyle;
- ExtraSpaceBelowLine: Integer;
- RepaintRect: TRect;
- SavedVOffs: Integer;
- Params: TRVFormatParams;
- begin
- Canvas := GetCanvas;
- DLC := DrawItems.Count;
- Params.SpaceEaten := False;
- Params.NoCaching := NoCaching;
- Params.LastTextStyle := -1;
- Params.FirstParaItemNo := -1;
- StartItemNo := DrawItems[StartDrawItemNo].ItemNo;
- EndItemNo := DrawItems[EndDrawItemNo ].ItemNo+ItemsInserted;
- AdjustInItemsRange(StartItemNo);
- if EndItemNo<StartItemNo then
- EndItemNo := StartItemNo;
- AdjustInItemsRange(EndItemNo);
- //ExpandToPara(StartItemNo, EndItemNo, StartItemNo, EndItemNo);
- PrevParBottom := GetParagraphBottom(StartDrawItemNo-1);
- if EndDrawItemNo<>DrawItems.Count-1 then
- NextParTop := GetParagraphTop(EndDrawItemNo+1)
- else
- NextParTop := -1;
- RepaintRect.Top := PrevParBottom-10-GetVOffs;
- RepaintRect.Left := 0;
- RepaintRect.Right := GetWidth;
- Params.x := 0;
- Params.prevdesc := 0;
- Params.prevabove := 0;
- Params.baseline := PrevParBottom;
- Params.LastTabDrawItemNo := -1;
- GetSADForFormatting(GetCanvas, sad);
- sad.LeftMargin := MulDiv(GetLeftMargin, sad.ppixDevice, sad.ppixScreen);
- sad.RightMargin := MulDiv(GetRightMargin, sad.ppixDevice, sad.ppixScreen);
- Params.IsParaStart := True;
- Params.LineWidth := 0;
- Params.FirstIndent := 0;
- Params.LastDrawItem := StartDrawItemNo;
- DrawItems.MarkForDelete(StartDrawItemNo,EndDrawItemNo);
- Params.DontFSL := True;
- RVStyle := GetRVStyle;
- CreateFontInfoCache(Canvas);
- Params.FontInfoCache := GetFontInfoCache(Canvas, Self);
- Params.FormatCanvas := Canvas;
- Params.FormatCanvasHandle := Canvas.Handle;
- for i:=StartItemNo to EndItemNo do
- with TCustomRVItemInfo(Items.Objects[i]) do begin
- if not SameAsPrev and not BR then
- Params.FirstParaItemNo := i;
- if (StyleNo>=0) then
- if (RVStyle.ParaStyles[ParaNo].Alignment = rvaJustify) then
- FormatWords(i, Canvas, sad, Params)
- else
- FormatLine(
- RV_ReturnProcessedString(Items[i],
- RVStyle.TextStyles[GetActualStyleNo(RVStyle)], False,
- rvoShowSpecialCharacters in Options, False),
- Items[i], 0,
- {$IFNDEF RVDONOTUSEUNICODE}
- RVU_Length(Items[i], ItemOptions),
- {$ELSE}
- Length(Items[i]),
- {$ENDIF}
- i, Canvas, sad, Params)
- else
- FormatLine('', '', 0, Length(Items[i]),i, Canvas, sad, Params);
- end;
- UpdateLastTab(Params);
- FinishScreenLine(sad, Params.LineWidth+Params.FirstIndent, Params.LastDrawItem, True,
- ExtraSpaceBelowLine, Params.DontFSL, Params.FormatCanvas);
- DestroyFontInfoCache(Params.FontInfoCache);
- inc(Params.baseline, ExtraSpaceBelowLine);
- DrawItems.DeleteMarked;
- if (EndItemNo=Items.Count-1) or GetItem(EndItemNo+1).CanBeBorderStart then
- inc(Params.prevdesc, GetRVStyle.ParaStyles[GetItemPara(EndItemNo)].SpaceAfter);
- if (EndItemNo<Items.Count-1) and GetItem(EndItemNo+1).CanBeBorderStart then
- inc(Params.prevdesc, GetRVStyle.ParaStyles[GetItemPara(EndItemNo+1)].SpaceBefore);
- RepaintRect.Bottom := Params.baseline+Params.prevdesc+10-GetVOffs;
- if (ItemsInserted<>0) or (DLC<>DrawItems.Count) or
- (NextParTop<>Params.baseline+Params.prevdesc) then begin
- ParBottom := Params.baseline+Params.prevdesc;
- // RepaintRect.Bottom := GetHeight;
- for i:=Params.LastDrawItem to DrawItems.Count-1 do
- with DrawItems[i] do begin
- Top := Top-NextParTop+(Params.baseline+Params.prevdesc);
- if Top+Height>ParBottom then
- ParBottom := Top+Height;
- ItemNo := ItemNo + ItemsInserted;
- item := TCustomRVItemInfo(Items.Objects[ItemNo]);
- if GetOffsBeforeItem(ItemNo)=Offs then
- item.DrawItemNo := i;
- end;
- if (EndItemNo<Items.Count-1) then
- inc(ParBottom, GetRVStyle.ParaStyles[GetItemPara(Items.Count-1)].SpaceAfter);
- RepaintRect.Bottom := ParBottom-GetVOffs+10;
- if DocumentHeight-GetBottomMargin+10>RepaintRect.Bottom then
- RepaintRect.Bottom := DocumentHeight-GetBottomMargin+10;
- if RepaintRect.Bottom>GetHeight then
- RepaintRect.Bottom := GetHeight;
- if DocumentHeight <> (ParBottom+GetBottomMargin) then begin
- SavedVOffs := GetVOffs;
- DocumentHeight := ParBottom+GetBottomMargin;
- AdjustVScrollUnits;
- AlreadyFormatted := True;
- SetDocumentAreaSize(GetAreaWidth, DocumentHeight, False);
- AlreadyFormatted := False;
- if SavedVOffs<>GetVOffs then
- RepaintRect := GetParentControl.ClientRect;
- end;
- end;
- AdjustChildrenCoords;
- LastItemFormatted := Items.Count-1;
- InvalidateRect(RepaintRect);
- GetParentControl.Update;
- end;
- var StartItemNo,EndItemNo: Integer;
- begin
- FormatParasExact_(StartItemNo,EndItemNo);
- Formatted(StartItemNo,EndItemNo,True);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoOnSelection(AllowScrolling: Boolean);
- begin
- {$IFNDEF RVDONOTUSEANIMATION}
- ResetAniBackground;
- {$ENDIF}
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.XorDrawing;
- begin
- if Assigned(FXORDrawing) then begin
- FXORDrawing(Self, [], MouseX, MouseY);
- XorImageDrawn := not XorImageDrawn;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.XorDrawingEx(X, Y: Integer);
- begin
- MouseX := X;
- MouseY := Y;
- XorDrawing;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.UnAssignXorDrawing(P: TMouseMoveEvent);
- begin
- if @FXORDrawing=@P then begin
- if XorImageDrawn and not (csDestroying in GetParentControl.ComponentState) then
- XorDrawing;
- FXORDrawing := nil;
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AssignXorDrawing(P: TMouseMoveEvent);
- begin
- if XorImageDrawn then
- XorDrawing;
- FXORDrawing := P;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.UsingThisXorDrawing(P: TMouseMoveEvent): Boolean;
- begin
- Result := @FXORDrawing=@P;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.ClearXorDrawing: Boolean;
- begin
- Result := XorImageDrawn;
- if XorImageDrawn then
- XorDrawing;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.InternalFreeItem(item: TCustomRVItemInfo;
- Clearing: Boolean);
- begin
- if item=FCaptureMouseItem then
- FCaptureMouseItem := nil;
- // if item=GetChosenItem then
- // UnassignChosenRVData(GetChosenRVData);
- inherited InternalFreeItem(item, Clearing);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.ReleaseMouseCapture(Item: TCustomRVItemInfo);
- begin
- if Item=FCaptureMouseItem then
- FCaptureMouseItem := nil;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.SetMouseCapture(Item: TCustomRVItemInfo;
- var Left,Top: Integer);
- begin
- if (LastDIMovedAbove<0) or (LastDIMovedAbove>=DrawItems.Count) or
- (Item <> Items.Objects[DrawItems[LastDIMovedAbove].ItemNo]) then
- Item2FirstDrawItem(Items.IndexOfObject(Item),LastDIMovedAbove);
- Left := DrawItems[LastDIMovedAbove].Left;
- Top := DrawItems[LastDIMovedAbove].Top;
- FCaptureMouseItem := Item;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetCPEventKind: TCPEventKind;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).GetCPEventKind;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoSelect;
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).DoSelect;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoCurrentTextStyleConversion(
- var StyleNo: Integer; ParaStyleNo, ItemNo, UserData: Integer;
- ToWholeParagraphs: Boolean);
- begin
- if not (rvflRoot in Flags) then
- TCustomRVFormattedData(GetAbsoluteRootData).DoCurrentTextStyleConversion(
- StyleNo, ParaStyleNo, ItemNo, UserData, ToWholeParagraphs);
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.IsAssignedRVDblClick: Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).IsAssignedRVDblClick;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoRVDblClick(const ClickedWord: String;
- StyleNo: Integer);
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).DoRVDblClick(ClickedWord, StyleNo);
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.IsAssignedRVRightClick: Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).IsAssignedRVRightClick;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoRVRightClick(const ClickedWord: String;
- StyleNo, X, Y: Integer);
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).DoRVRightClick(ClickedWord, StyleNo, X,Y);
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetCanvas: TCanvas;
- begin
- Result := TCustomRVFormattedData(GetRootData).GetCanvas;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DeselectPartiallySelectedItem(NewPartiallySelected: TCustomRVItemInfo);
- begin
- if (FPartialSelectedItem<>nil) and (FPartialSelectedItem<>NewPartiallySelected) then begin
- //if not (csDestroying in GetParentControl.ComponentState) then
- FPartialSelectedItem.DeselectPartial;
- FPartialSelectedItem := nil;
- end;
- if (GetChosenItem<>nil) and (GetChosenItem<>NewPartiallySelected) then begin
- if not (csDestroying in GetParentControl.ComponentState) then
- UnassignChosenRVData(GetChosenRVData);
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.SetPartialSelectedItem(Item: TCustomRVItemInfo);
- begin
- if FPartialSelectedItem<>Item then begin
- Deselect(Item, True);
- FPartialSelectedItem := Item;
- DoSelect;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetItemCoords(ItemNo: Integer; var Left, Top: Integer): Boolean;
- begin
- Item2FirstDrawItem(ItemNo, ItemNo);
- Result := ItemNo<>-1;
- if Result then begin
- Left := DrawItems[ItemNo].Left;
- Top := DrawItems[ItemNo].Top;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetItemClientCoords(ItemNo: Integer; var Left, Top: Integer): Boolean;
- begin
- Result := GetItemCoords(ItemNo, Left, Top);
- if Result then begin
- dec(Left, GetHOffs);
- dec(Top, GetVOffs);
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DoCopy;
- var root: TCustomRVData;
- begin
- root := GetRootData;
- if root is TCustomRVFormattedData then
- TCustomRVFormattedData(GetRootData).DoCopy;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.IsAssignedCopy: Boolean;
- var root: TCustomRVData;
- begin
- root := GetRootData;
- if root is TCustomRVFormattedData then
- Result := TCustomRVFormattedData(GetRootData).IsAssignedCopy
- else
- Result := False;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AssignChosenRVData(RVData: TCustomRVFormattedData;
- Item: TCustomRVItemInfo);
- begin
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.SilentReplaceChosenRVData(RVData: TCustomRVFormattedData);
- begin
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.UnassignChosenRVData(RVData: TCustomRVData);
- begin
- Include(State,rvstForceStyleChangeEvent);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.Formatted(FirstItemNo, LastItemNo: Integer;Partial: Boolean);
- begin
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetInplaceEditor: TControl;
- begin
- Result := nil
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DestroyInplaceEditor;
- begin
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetNextFocusedItem(ItemNo: Integer; GoForward: Boolean;
- var TopLevelRVData: TCustomRVFormattedData;
- var TopLevelItemNo: Integer): Integer;
- var i: Integer;
- Style: TRVStyle;
- {...........................................}
- function CheckItem(ItemNo: Integer): Boolean;
- begin
- if GetItem(i).GetBoolValueEx(rvbpAllowsFocus, Style) then begin
- TopLevelRVData := Self;
- TopLevelItemNo := ItemNo;
- Result := True;
- exit;
- end;
- Result := GetItem(i).MoveFocus(GoForward, TPersistent(TopLevelRVData), TopLevelItemNo);
- end;
- {...........................................}
- begin
- if (FocusedItemNo<0) or (FocusedItemNo>=Items.Count) then
- FocusedItemNo := -1;
- Style := GetRVStyle;
- if GoForward then begin
- if (ItemNo<0) or
- GetItem(ItemNo).GetBoolValueEx(rvbpAllowsFocus, Style) then
- inc(ItemNo);
- for i := ItemNo to Items.Count-1 do
- if CheckItem(i) then begin
- Result := i;
- exit;
- end;
- end
- else begin
- if ItemNo<0 then
- ItemNo := Items.Count;
- if (ItemNo=Items.Count) or
- GetItem(ItemNo).GetBoolValueEx(rvbpAllowsFocus, Style) then
- dec(ItemNo);
- for i := ItemNo downto 0 do
- if CheckItem(i) then begin
- Result := i;
- exit;
- end;
- end;
- Result := -1;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.ClearFocus;
- begin
- if (FocusedItemNo<0) or (FocusedItemNo>=Items.Count) then
- FocusedItemNo := -1;
- if FocusedItemNo<>-1 then
- GetItem(FocusedItemNo).ClearFocus;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AdjustFocus(NewFocusedItemNo: Integer;
- TopLevelRVData: TPersistent; TopLevelItemNo: Integer);
- begin
- FocusedItemNo := NewFocusedItemNo;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.ShowRectangle(Left, Top, Width, Height: Integer);
- begin
- if (Left<GetHOffs) then begin
- HScrollTo(Left-GetWidth div 4);
- end
- else if (Left+Width>GetHOffs+GetWidth) then begin
- HScrollTo(Left-GetWidth div 4);
- end;
- if (Top+Height>GetVOffs+GetHeight-GetVSmallStep*2) and (Top<GetVOffs+GetVSmallStep) then exit;
- if (Top+Height>GetVOffs+GetHeight) then begin
- ScrollTo(Top+Height-GetHeight+GetVSmallStep,True);
- end
- else if (Top<GetVOffs) then begin
- ScrollTo(Top,True);
- end;
- end;
- {------------------------------------------------------------------------------}
- {
- procedure TCustomRVFormattedData.SetZoomPercent(const Value: Integer);
- begin
- FZoomPercent := Value;
- end;
- }
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetZHOffs: Integer;
- begin
- Result := GetHOffs;
- ZoomInt(Result);
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetZVOffs: Integer;
- begin
- Result := GetVOffs;
- ZoomInt(Result);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.BuildJumpsCoords(var StartJumpNo: Integer; jumps: TList);
- var i: Integer;
- LastItemNo,tmp: Integer;
- jmpinfo: TRVJumpInfo;
- Style: TRVStyle;
- item: TCustomRVItemInfo;
- begin
- if jumps=nil then
- jumps := Self.jumps;
- Style := GetRVStyle;
- if Style=nil then exit;
- nJmps := 0;
- LastItemNo := -1;
- for i := 0 to DrawItems.Count-1 do begin
- item := GetItem(DrawItems[i].ItemNo);
- if item.GetBoolValueEx(rvbpJump, Style) then
- with DrawItems[i] do begin
- jmpinfo := TRVJumpInfo.Create;
- jmpinfo.l := Left;
- jmpinfo.t := Top;
- jmpinfo.w := Width;
- jmpinfo.h := Height;
- jmpinfo.id := nJmps+StartJumpNo;
- if LastItemNo=DrawItems[i].ItemNo then
- dec(jmpinfo.id);
- jmpinfo.RVData := Self;
- jmpinfo.DrawItemNo := i;
- GetItem(DrawItems[i].ItemNo).JumpID := jmpinfo.id;
- if (item.StyleNo<0) then
- jmpinfo.Cursor := item.GetHypertextCursor(Style)
- else
- jmpinfo.Cursor := Style.TextStyles[GetActualStyle(item)].JumpCursor;
- jumps.Add(jmpinfo);
- if LastItemNo<>DrawItems[i].ItemNo then begin
- inc(nJmps);
- LastItemNo := DrawItems[i].ItemNo;
- end;
- end
- else if item.StyleNo<0 then
- with DrawItems[i] do begin
- tmp := nJmps+ StartJumpNo;
- item.BuildJumps(Left, Top, tmp, jumps);
- nJmps := tmp-StartJumpNo;
- end;
- end;
- inc(StartJumpNo,nJmps);
- end;
- {------------------------------------------------------------------------------}
- { Coordinates of the top left corner of this RVData relative to the closest
- top left of the parent RichView's document (root one or inplace editor)
- (overriden in TRVTableCellData) }
- procedure TCustomRVFormattedData.GetOrigin(var ALeft, ATop: Integer);
- begin
- ALeft := 0;
- ATop := 0;
- end;
- {------------------------------------------------------------------------------}
- { Coordinates of the top left corner of this RVData relative to the top left of
- the root parent RichView's document
- (overriden in TRVTableCellData, TRVTableInplaceRVData) }
- procedure TCustomRVFormattedData.GetOriginEx(var ALeft, ATop: Integer);
- begin
- ALeft := 0;
- ATop := 0;
- end;
- {------------------------------------------------------------------------------}
- { Is the specified position (drawing item, offset in it) inside the selection? }
- function TCustomRVFormattedData.DItem_InsideSelection(DItemNo,
- DItemOffs: Integer): Boolean;
- var sno,soff,eno,eoff: Integer;
- begin
- Result := False;
- if not SelectionExists(False, False) then
- exit;
- GetSelBounds(sno, eno, soff,eoff, True);
- Result :=
- (sno>=0) and
- ((DItemNo>sno) or ((DItemNo=sno) and (DItemOffs>=soff))) and
- ((DItemNo<eno) or ((DItemNo=eno) and (DItemOffs<=eoff)));
- end;
- {------------------------------------------------------------------------------}
- { Is the specified position (item, offset in it) inside the selection?
- Unlike DItem_InsideSelection, checks if the current RVData is completely
- selected in its parent RVData }
- function TCustomRVFormattedData.Item_InsideSelection(ItemNo,
- ItemOffs: Integer): Boolean;
- var sno,soff,eno,eoff: Integer;
- PItemNo: Integer;
- Location: TRVStoreSubRVData;
- begin
- Result := False;
- if GetParentData<>nil then begin
- GetParentInfo(PItemNo, Location);
- Location.Free;
- if (PItemNo>=0) then
- Result := TCustomRVFormattedData(GetParentData).Item_InsideSelection(PItemNo, 0);
- end;
- if Result then
- exit;
- if not SelectionExists(False, False) then
- exit;
- GetSelectionBounds(sno, soff, eno, eoff, True);
- Result :=
- (sno>=0) and
- ((sno<>eno) or (soff<>eoff)) and
- ((ItemNo>sno) or ((ItemNo=sno) and (ItemOffs>=soff))) and
- ((ItemNo<eno) or ((ItemNo=eno) and (ItemOffs<=eoff)));
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.AfterDeleteStyles(Data: TRVDeleteUnusedStylesData);
- {$IFNDEF RVDONOTUSEINPLACE}
- var inplace: TControl;
- {$ENDIF}
- begin
- {$IFNDEF RVDONOTUSEINPLACE}
- inplace := GetInplaceEditor;
- if inplace is TCustomRichView then
- TCustomRichView(inplace).RVData.AfterDeleteStyles(Data);
- {$ENDIF}
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetItemAt(X, Y: Integer; var ItemNo,
- OffsetInItem: Integer);
- begin
- FindDrawItemForSel(X, Y, ItemNo, OffsetInItem, True);
- if ItemNo<>-1 then
- DrawItem2Item(ItemNo, OffsetInItem, ItemNo, OffsetInItem);
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.GetItemAtEx(X,Y: Integer;
- var RVData: TCustomRVFormattedData; var ItemNo, OffsetInItem: Integer;
- Strict: Boolean; var InSubRVDataOwnerItem: Boolean);
- var AX, AY, BX,BY: Integer;
- begin
- InSubRVDataOwnerItem := False;
- RVData := Self;
- FindDrawItemForSel(X, Y, ItemNo, OffsetInItem, Strict);
- if ItemNo<>-1 then begin
- DrawItem2Item(ItemNo, OffsetInItem, ItemNo, OffsetInItem);
- GetItemCoords(ItemNo, AX, AY);
- RVData := TCustomRVFormattedData(GetItem(ItemNo).GetSubRVDataAt(X-AX,Y-AY));
- if RVData=nil then begin
- RVData := Self;
- InSubRVDataOwnerItem := GetItem(ItemNo).GetBoolValue(rvbpHasSubRVData);
- end
- else begin
- RVData.GetOriginEx(BX,BY);
- GetOriginEx(AX,AY);
- X := X+AX-BX;
- Y := Y+AY-BY;
- RVData.GetItemAtEx(X,Y, RVData, ItemNo, OffsetInItem, Strict, InSubRVDataOwnerItem);
- end;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.FindWordAt(var Word: String; X,Y: Integer;
- var StyleNo, ItemNo, Offs: Integer;
- var RVData: TCustomRVFormattedData): Boolean;
- var no: Integer;
- arr: PRVIntegerArray;
- i,max,min,first,len: Integer;
- Canvas: TCanvas;
- ItemOptions: TRVItemOptions;
- item: TCustomRVItemInfo;
- ditem: TRVDrawLineInfo;
- AX, AY: Integer;
- ARVData: TCustomRVFormattedData;
- s: String;
- begin
- Canvas := GetCanvas;
- Result := False;
- RVData := Self;
- no := FindDrawItemAtPos(X+GetZHOffs, Y+GetZVOffs);
- ItemNo := -1;
- if no<>-1 then begin
- ditem := DrawItems[no];
- ItemNo := ditem.ItemNo;
- Word := Items[ItemNo];
- StyleNo := GetItemStyle(ItemNo);
- if StyleNo>=0 then begin
- GetRVStyle.ApplyStyle(Canvas, StyleNo, GetParaBiDiMode(GetItemPara(ItemNo)),
- rvflCanUseCustomPPI in Flags);
- ItemOptions := GetItemOptions(ItemNo);
- s := DrawItems.GetString(no,Items);
- s := RV_ReturnProcessedString(s, GetRVStyle.TextStyles[StyleNo],
- IsDrawItemLastOnWrappedLine(no), rvoShowSpecialCharacters in Options, False);
- GetMem(arr, (ditem.Length+2)*sizeof(Integer));
- try
- if (GetItemBiDiMode(ditem.ItemNo)<>rvbdUnspecified) and
- RVU_GetTextCaretPos(Canvas, s, arr, ItemOptions,
- ditem.Width{$IFNDEF RVDONOTUSEJUSTIFY}-DrawItems[no].SpaceBefore{$ENDIF}) then begin
- min := Abs(X-arr[0]-ditem.Left{$IFNDEF RVDONOTUSEJUSTIFY}-ditem.SpaceBefore{$ENDIF});
- max := 0;
- for i := 1 to ditem.Length do
- if Abs(X-arr[i]-ditem.Left{$IFNDEF RVDONOTUSEJUSTIFY}-ditem.SpaceBefore{$ENDIF})<min then begin
- max := i;
- min := Abs(X-arr[i]-ditem.Left{$IFNDEF RVDONOTUSEJUSTIFY}-ditem.SpaceBefore{$ENDIF});
- end;
- end
- else begin
- RVU_GetTextExtentExPoint(Canvas, s, X+GetZHOffs-ditem.Left
- {$IFNDEF RVDONOTUSEJUSTIFY}-ditem.SpaceBefore{$ENDIF},
- max,
- {$IFDEF RICHVIEWDEF4}nil,{$ELSE}@(arr[0]),{$ENDIF} ItemOptions);
- end;
- finally
- FreeMem(arr);
- end;
- inc(max,DrawItems[no].Offs);
- if max>RVU_Length(Word,ItemOptions) then
- max := RVU_Length(Word,ItemOptions);
- first := max;
- if IsDelimiter(Word, first, ItemOptions) then begin
- Offs := First;
- Word := '';
- Result := True;
- exit;
- end;
- while (first>1) and not IsDelimiter(Word, first-1, ItemOptions) do
- dec(first);
- len := max-first+1;
- while (first+len-1<RVU_Length(Word,ItemOptions)) and
- not IsDelimiter(Word, first+len, ItemOptions) do
- inc(len);
- Word := RVU_Copy(Word, first, len, ItemOptions);
- Offs := First;
- end
- else begin
- item := GetItem(ItemNo);
- item.ResetSubCoords;
- GetItemClientCoords(ItemNo,AX,AY);
- ARVData := TCustomRVFormattedData(item.GetSubRVDataAt(X-AX,Y-AY));
- if ARVData<>nil then begin
- if ARVData.GetRVData.GetParentControl.Parent=GetParentControl then begin
- dec(X, ARVData.GetRVData.GetParentControl.Left);
- dec(Y, ARVData.GetRVData.GetParentControl.Top);
- end;
- Result := TCustomRVFormattedData(ARVData.GetRVData).FindWordAt(Word,
- X,Y,StyleNo,ItemNo,Offs, RVData);
- exit;
- end;
- end;
- Result := True;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetEditor: TWinControl;
- begin
- Result := nil;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.ResetSubCoords;
- begin
- end;
- {------------------------------------------------------------------------------}
- { Selects the screen line containing (ItemNo, Offs) location. }
- procedure TCustomRVFormattedData.SelectLine(ItemNo, Offs: Integer);
- var DItemNo, DOffs: Integer;
- DStrt, DEnd: Integer;
- ItemNo1,ItemNo2,Offs1, Offs2: Integer;
- begin
- Item2DrawItem(ItemNo,Offs,DItemNo,DOffs);
- DStrt := DItemNo;
- while not DrawItems[DStrt].FromNewLine do
- dec(DStrt);
- DEnd := DItemNo+1;
- while (DEnd<Items.Count) and not DrawItems[DEnd].FromNewLine do
- inc(DEnd);
- dec(DEnd);
- DrawItem2Item(DStrt, GetOffsBeforeDrawItem(Dstrt), ItemNo1, Offs1);
- DrawItem2Item(DEnd, GetOffsAfterDrawItem(DEnd), ItemNo2, Offs2);
- SetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2);
- end;
- {------------------------------------------------------------------------------}
- { Fills the list of soft page breaks by information form RVPrint (must be of
- TCustomRVPrint class).
- RVPrint must be formatted for printing. }
- procedure TCustomRVFormattedData.AssignSoftPageBreaks(RVPrint: TComponent);
- var i: Integer;
- Item: TRVSoftPageBreakInfo;
- begin
- ClearSoftPageBreaks;
- FSoftPageBreaks := TRVSoftPageBreakList.Create;
- for i := 1 to TCustomRVPrint(RVPrint).PagesCount do begin
- item := TRVSoftPageBreakInfo.Create;
- TCustomRVPrint(RVPrint).GetFirstItemOnPageEx(i, item.ItemNo, item.Offset,
- item.ExtraData);
- FSoftPageBreaks.Add(Item);
- end;
- if rvoShowPageBreaks in Options then
- Invalidate;
- end;
- {------------------------------------------------------------------------------}
- { Clears, destorys and nils the list of soft page breaks }
- function TCustomRVFormattedData.ClearSoftPageBreaks: Boolean;
- begin
- Result := FSoftPageBreaks<>nil;
- if Result then begin
- FSoftPageBreaks.Free;
- FSoftPageBreaks := nil;
- end;
- end;
- {------------------------------------------------------------------------------}
- { Returns a line number of location (ItemNo, ItemOffs). Line numbers are
- started from 1. Line number are counted from the beginning of each RVData.
- This method is relatively slow: iteration from the beginning of this RVData
- items. }
- function TCustomRVFormattedData.GetLineNo(ItemNo, ItemOffs: Integer): Integer;
- var i, DItemNo, DItemOffs: Integer;
- begin
- Item2DrawItem(ItemNo, ItemOffs, DItemNo, DItemOffs);
- Result := 0;
- for i := DItemNo downto 0 do
- if DrawItems[i].FromNewLine then
- inc(Result);
- end;
- {------------------------------------------------------------------------------}
- { Called in MouseUp. Adjusts selection. Overriden in TRVEditRVData (where
- selects resizable item if needed) }
- procedure TCustomRVFormattedData.AdjustMouseUpSelection;
- begin
- end;
- {------------------------------------------------------------------------------}
- { Searching for the item containing AControl and selecting it. Search is
- recursive, it includes nested RVData-s. }
- function TCustomRVFormattedData.SelectControl(AControl: TControl): Boolean;
- {........................................................}
- function SearchInItem(item: TCustomRVItemInfo): Boolean;
- var SubRVData: TCustomRVFormattedData;
- StoreSub: TRVStoreSubRVData;
- begin
- Result := False;
- SubRVData := TCustomRVFormattedData(item.GetSubRVData(StoreSub, rvdFirst));
- if SubRVData=nil then
- exit;
- repeat
- Result := TCustomRVFormattedData(SubRVData.GetRVData).SelectControl(AControl);
- if Result then
- break;
- SubRVData := TCustomRVFormattedData(item.GetSubRVData(StoreSub, rvdNext));
- until SubRVData=nil;
- StoreSub.Free;
- end;
- {........................................................}
- var i: Integer;
- RVData: TCustomRVFormattedData;
- begin
- Result := False;
- for i := 0 to ItemCount-1 do
- if GetItemStyle(i)<0 then begin
- if (GetItem(i) is TRVControlItemInfo) and
- GetItem(i).OwnsControl(AControl) then begin
- RVData := TCustomRVFormattedData(Edit);
- RVData.SetSelectionBounds(i, 0, i, 1);
- RVData.Invalidate;
- Result := True;
- exit;
- end;
- Result := SearchInItem(GetItem(i));
- if Result then
- break;
- end;
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the position (DrawItemNo,DrawItemOffs) is inside a word }
- function TCustomRVFormattedData.InsideWord(DrawItemNo,
- DrawItemOffs: Integer): Boolean;
- var s: String;
- StyleNo : Integer;
- ItemOptions: TRVItemOptions;
- begin
- Result := False;
- StyleNo := GetDrawItemStyle(DrawItemNo);
- if (StyleNo<0) or
- (DrawItemOffs<=GetOffsBeforeDrawItem(DrawItemNo)) or
- (DrawItemOffs>=GetOffsAfterDrawItem(DrawItemNo)) then
- exit;
- s := DrawItems.GetString(DrawItemNo, Items);
- ItemOptions := GetItemOptions(DrawItems[DrawItemNo].ItemNo);
- Result := not IsDelimiter(s, DrawItemOffs-1, ItemOptions) and
- not IsDelimiter(s, DrawItemOffs, ItemOptions);
- end;
- {------------------------------------------------------------------------------}
- { Returns bounds of word containing position (DrawItemNo,DrawItemOffs).
- Returns:
- DrawItemWordOffs1 - index of the first word character (1-based),
- DrawItemWordOffs2 - index of the first character after the word (1-based).
- This procedure assumes that position is inside word (check by InsideWord()) }
- procedure TCustomRVFormattedData.GetWordBounds(DrawItemNo,
- DrawItemOffs: Integer; var DrawItemWordOffs1, DrawItemWordOffs2: Integer);
- var s: String;
- ItemOptions: TRVItemOptions;
- Len: Integer;
- begin
- s := DrawItems.GetString(DrawItemNo, Items);
- ItemOptions := GetItemOptions(DrawItems[DrawItemNo].ItemNo);
- DrawItemWordOffs1 := DrawItemOffs-1;
- while (DrawItemWordOffs1-1>0) and
- not IsDelimiter(s, DrawItemWordOffs1-1, ItemOptions) do
- dec(DrawItemWordOffs1);
- DrawItemWordOffs2 := DrawItemOffs;
- Len := RVU_Length(s, ItemOptions);
- while (DrawItemWordOffs2<=Len) and
- not IsDelimiter(s, DrawItemWordOffs2, ItemOptions) do
- inc(DrawItemWordOffs2);
- end;
- {------------------------------------------------------------------------------}
- { Adjusts selection bounds depending on RVStyle.SelectionMode.
- (X,Y) is coordinate of mouse making selection (relative to the top left
- corner of the document).
- Returns True if the new selection bounds are different from their previous
- values. }
- function TCustomRVFormattedData.AdjustSelectionByMode(X, Y: Integer): Boolean;
- var w1, w2: Integer;
- AdjustSelEnd: Boolean;
- OldSelSNo, OldSelENo, OldSelSOffs, OldSelEOffs: Integer;
- DrawItemNo, DrawItemOffs: Integer;
- {...........................................................}
- function IsSelectionChanged: Boolean;
- begin
- Result := (OldSelSNo<>FSelStartNo) or (OldSelENo<>FSelEndNo) or
- (OldSelSOffs<>FSelStartOffs) or (OldSelEOffs<>FSelEndOffs);
- end;
- {...........................................................}
- begin
- GetSelectionBounds(OldSelSNo, OldSelSOffs, OldSelENo, OldSelEOffs, False);
- FindDrawItemForSel(X, Y, DrawItemNo, DrawItemOffs, False);
- if FSelectingInfo<>nil then begin
- if FSelectingInfo.SWordState=rvsesParaMode then begin
- FSelectingInfo.DrawItemENo := DrawItemNo;
- FSelectingInfo.DrawItemEOffs := DrawItemOffs;
- FSelStartNo := FSelectingInfo.DrawItemSNo;
- FSelStartOffs := FSelectingInfo.DrawItemSOffs;
- FSelEndNo := DrawItemNo;
- FSelEndOffs := DrawItemOffs;
- ExpandSelectionToParagraph(True);
- Result := IsSelectionChanged;
- exit;
- end;
- AdjustSelEnd := True;
- // 1. Adjusting selection start
- case FSelectingInfo.SWordState of
- rvsesInWord: // mouse is inside the initial word
- begin
- // checking mouse leaving the initial word
- // when it leaves, setting SWordState := rvsesOutsideWord and
- // adjusting the selection start to the word bound
- if FSelectingInfo.IsAboveSWord(DrawItemNo, DrawItemOffs) then begin
- FSelectingInfo.SWordState := rvsesOutsideWord;
- FSelStartOffs := FSelectingInfo.DrawItemSWordOffs2;
- end
- else if FSelectingInfo.IsBelowSWord(DrawItemNo, DrawItemOffs) then begin
- FSelectingInfo.SWordState := rvsesOutsideWord;
- FSelStartOffs := FSelectingInfo.DrawItemSWordOffs1;
- end
- else
- AdjustSelEnd := False;
- end;
- rvsesOutsideWord: // mouse is outside the initial word
- begin
- // checking mouse returning to the initial word
- // when it returns, stopping adjusting the selection start,
- // setting SWordState := rvsesFreeMode
- if FSelectingInfo.IsInSWord(DrawItemNo, DrawItemOffs) then begin
- FSelStartOffs := FSelectingInfo.DrawItemSOffs;
- FSelectingInfo.SWordState := rvsesFreeMode;
- AdjustSelEnd := False;
- end;
- end;
- end;
- // 1. Adjusting selection end
- if AdjustSelEnd then begin
- if InsideWord(DrawItemNo, DrawItemOffs) then begin
- GetWordBounds(DrawItemNo, DrawItemOffs, w1, w2);
- if FSelectingInfo.IsEWord(DrawItemNo, w1, w2) then
- // mouse is in the same word as before
- case FSelectingInfo.EWordState of
- rvsesInWord:
- begin
- // if it's moved in backward direction, allowing selection
- // by characters (setting EWordState := rvsesFreeMode)
- if FSelectingInfo.IsEFreeStateNeeded(DrawItemNo, DrawItemOffs) then begin
- FSelectingInfo.EWordState := rvsesFreeMode;
- AdjustSelEnd := False;
- end
- else
- // if it's moved in forward direction, updating DrawItemEOffs
- FSelectingInfo.DrawItemEOffs := DrawItemOffs;
- end;
- rvsesFreeMode:
- AdjustSelEnd := False;
- end
- else begin
- // mouse is entered a new word
- FSelectingInfo.EWordState := rvsesInWord;
- FSelectingInfo.DrawItemEWordOffs1 := w1;
- FSelectingInfo.DrawItemEWordOffs2 := w2;
- FSelectingInfo.DrawItemEOffs := DrawItemOffs;
- end;
- // adjusting the selection end
- if AdjustSelEnd then
- if FSelectingInfo.IsAboveSWord(DrawItemNo, DrawItemOffs) then begin
- DrawItemOffs := w1;
- end
- else if FSelectingInfo.IsBelowSWord(DrawItemNo, DrawItemOffs) then begin
- DrawItemOffs := w2;
- end;
- end
- else begin
- // mouse is outside word
- FSelectingInfo.EWordState := rvsesInWord;
- FSelectingInfo.DrawItemEWordOffs1 := -1;
- FSelectingInfo.DrawItemEWordOffs2 := -1;
- end;
- end;
- end;
- FSelEndNo := DrawItemNo;
- FSelEndOffs := DrawItemOffs;
- Result := IsSelectionChanged;
- end;
- {------------------------------------------------------------------------------}
- { Making selection by lines.
- (X,Y) is coordinate of mouse making selection (relative to the top left
- corner of the document). }
- function TCustomRVFormattedData.AdjustLineSelection(X, Y: Integer): Boolean;
- var OldSelSNo, OldSelENo, OldSelSOffs, OldSelEOffs: Integer;
- {...........................................................}
- function IsSelectionChanged: Boolean;
- begin
- Result := (OldSelSNo<>FSelStartNo) or (OldSelENo<>FSelEndNo) or
- (OldSelSOffs<>FSelStartOffs) or (OldSelEOffs<>FSelEndOffs);
- end;
- {...........................................................}
- begin
- GetSelectionBounds(OldSelSNo, OldSelSOffs, OldSelENo, OldSelEOffs, False);
- FindDrawItemForSel(X, Y, FSelEndNo, FSelEndOffs, False);
- ExpandSelectionToLines(False);
- if GetRVStyle.SelectionMode=rvsmParagraph then
- ExpandSelectionToParagraph(True);
- Result := IsSelectionChanged;
- end;
- {------------------------------------------------------------------------------}
- { Expands the selection (if it is not empty) to the paragraphs boundaries
- Does nothing if OnlyIfMultiple=True and selection does not include
- more than 1 paragraph. }
- function TCustomRVFormattedData.ExpandSelectionToParagraph(
- OnlyIfMultiple: Boolean): Boolean;
- {..........................................................}
- procedure ExpandUp(var DrawItemNo, DrawItemOffs: Integer);
- begin
- while DrawItemNo>0 do begin
- if IsDrawItemParaStart(DrawItemNo) then
- break;
- dec(DrawItemNo);
- end;
- DrawItemOffs := GetOffsBeforeDrawItem(DrawItemNo);
- end;
- {..........................................................}
- procedure ExpandDown(var DrawItemNo, DrawItemOffs: Integer);
- begin
- while DrawItemNo+1<DrawItems.Count do begin
- if IsDrawItemParaStart(DrawItemNo+1) then
- break;
- inc(DrawItemNo);
- end;
- DrawItemOffs := GetOffsAfterDrawItem(DrawItemNo);
- end;
- begin
- Result := (FSelStartNo>=0) and
- not ((FSelStartNo=FSelEndNo) and (FSelStartOffs=FSelEndOffs));
- if not Result then
- exit;
- Result := not OnlyIfMultiple or IsMultiParagraphSelection;
- if not Result then
- exit;
- if IsSelectionTopDown then begin
- ExpandUp(FSelStartNo, FSelStartOffs);
- ExpandDown(FSelEndNo, FSelEndOffs);
- end
- else begin
- ExpandDown(FSelStartNo, FSelStartOffs);
- ExpandUp(FSelEndNo, FSelEndOffs);
- end;
- end;
- {------------------------------------------------------------------------------}
- { If OneLine=False, expands selection to the lines boundaries.
- If OneLine=True, selects the line containing the beginning of selection,
- from the beginning to the end of the line }
- procedure TCustomRVFormattedData.ExpandSelectionToLines(OneLine: Boolean);
- {..........................................................}
- procedure ExpandUp(var DrawItemNo, DrawItemOffs: Integer);
- begin
- while (DrawItemNo>0) and not DrawItems[DrawItemNo].FromNewLine do
- dec(DrawItemNo);
- DrawItemOffs := GetOffsBeforeDrawItem(DrawItemNo);
- end;
- {..........................................................}
- procedure ExpandDown(var DrawItemNo, DrawItemOffs: Integer);
- begin
- while (DrawItemNo+1<DrawItems.Count) and
- not DrawItems[DrawItemNo+1].FromNewLine do
- inc(DrawItemNo);
- DrawItemOffs := GetOffsAfterDrawItem(DrawItemNo);
- end;
- {..........................................................}
- begin
- if FSelStartNo<0 then
- exit;
- if OneLine then begin
- FSelEndNo := FSelStartNo;
- ExpandUp(FSelStartNo, FSelStartOffs);
- ExpandDown(FSelEndNo, FSelEndOffs);
- end
- else begin
- if IsSelectionTopDown then begin
- ExpandUp(FSelStartNo, FSelStartOffs);
- ExpandDown(FSelEndNo, FSelEndOffs);
- end
- else begin
- ExpandDown(FSelStartNo, FSelStartOffs);
- ExpandUp(FSelEndNo, FSelEndOffs);
- end;
- end;
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the selection is in top-down direction. }
- function TCustomRVFormattedData.IsSelectionTopDown: Boolean;
- begin
- Result := (FSelStartNo<FSelEndNo) or
- ((FSelStartNo=FSelEndNo) and (FSelStartOffs<=FSelEndOffs));
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the drawing item starts a new paragraph. }
- function TCustomRVFormattedData.IsDrawItemParaStart(DrawItemNo: Integer): Boolean;
- begin
- Result := (DrawItemNo=0) or
- ((DrawItems[DrawItemNo].ItemNo<>DrawItems[DrawItemNo-1].ItemNo) and
- IsParaStart(DrawItems[DrawItemNo].ItemNo));
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the drawing item is the first drawing item for an item }
- function TCustomRVFormattedData.IsDrawItemItemStart(DrawItemNo: Integer): Boolean;
- begin
- Result := (DrawItemNo=0) or
- (DrawItems[DrawItemNo].ItemNo<>DrawItems[DrawItemNo-1].ItemNo);
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the drawing item starts a new paragraph or section inside
- paragraph }
- function TCustomRVFormattedData.IsDrawItemParaSectionStart(DrawItemNo: Integer): Boolean;
- begin
- Result := (DrawItemNo=0) or
- ((DrawItems[DrawItemNo].ItemNo<>DrawItems[DrawItemNo-1].ItemNo) and
- IsFromNewLine(DrawItems[DrawItemNo].ItemNo));
- end;
- {------------------------------------------------------------------------------}
- { Returns True if the drawing item ends a paragraph. }
- function TCustomRVFormattedData.IsDrawItemParaEnd(DrawItemNo: Integer): Boolean;
- begin
- Result := (DrawItemNo=DrawItems.Count-1) or IsDrawItemParaStart(DrawItemNo+1);
- end;
- {------------------------------------------------------------------------------}
- { Returns true, if the given DrawItem either starts a new line
- or follows a marker }
- function TCustomRVFormattedData.IsDrawItemFromNewLine(DrawItemNo: Integer): Boolean;
- begin
- Result := DrawItems[DrawItemNo].FromNewLine;
- {$IFNDEF RVDONOTUSELISTS}
- if not Result and (DrawItemNo>0) and
- (DrawItems[DrawItemNo].ItemNo<>DrawItems[DrawItemNo-1].ItemNo) and
- (GetDrawItemStyle(DrawItemNo-1)=rvsListMarker) then
- Result := True;
- {$ENDIF}
- end;
- {------------------------------------------------------------------------------}
- { Returns true, if the given DrawItem is the last item on the line, and this
- line is not the last line of the paragraph }
- function TCustomRVFormattedData.IsDrawItemLastOnWrappedLine(DrawItemNo: Integer): Boolean;
- begin
- Result := (DrawItemNo<DrawItems.Count-1) and DrawItems[DrawItemNo+1].FromNewLine and
- not IsDrawItemParaSectionStart(DrawItemNo+1);
- end;
- {------------------------------------------------------------------------------}
- { Returns the style of item associated with the given drawing item
- // Result := GetItemStyle(DrawItems[DrawItemNo].ItemNo) }
- function TCustomRVFormattedData.GetDrawItemStyle(DrawItemNo: Integer): Integer;
- begin
- Result := TCustomRVItemInfo(Items.Objects[DrawItems[DrawItemNo].ItemNo]).StyleNo;
- end;
- {------------------------------------------------------------------------------}
- { Returns True if there is a character (space) missed between the DrawItemNo-th
- and the next drawing item }
- function TCustomRVFormattedData.IsSpaceBetweenDrawItems(DrawItemNo: Integer): Boolean;
- var ditem: TRVDrawLineInfo;
- begin
- Result := False;
- ditem := DrawItems[DrawItemNo];
- if ditem.Offs+ditem.Length-1>=ItemLength(ditem.ItemNo) then
- exit;
- if (DrawItemNo+1<DrawItems.Count) and (DrawItems[DrawItemNo+1].ItemNo=ditem.ItemNo) and
- (DrawItems[DrawItemNo+1].Offs = ditem.Offs+ditem.Length) then
- exit;
- Result := True;
- end;
- {------------------------------------------------------------------------------}
- { Returns True, if the selection includes more than one paragraphs (at least
- partially. }
- function TCustomRVFormattedData.IsMultiParagraphSelection: Boolean;
- var StartDrawItemNo, EndDrawItemNo, i: Integer;
- begin
- Result := FSelStartNo>=0;
- if not Result then
- exit;
- if IsSelectionTopDown then begin
- StartDrawItemNo := FSelStartNo;
- EndDrawItemNo := FSelEndNo;
- end
- else begin
- StartDrawItemNo := FSelEndNo;
- EndDrawItemNo := FSelStartNo;
- end;
- Result := False;
- for i := StartDrawItemNo+1 to EndDrawItemNo do
- if IsDrawItemParaStart(i) then begin
- Result := True;
- exit;
- end;
- end;
- {$IFNDEF RVDONOTUSEDRAGDROP}
- {------------------------------------------------------------------------------}
- { Drag&Drop: IDropTarget related }
- {------------------------------------------------------------------------------}
- { Sets the position of drag&drop target to (X,Y).
- (X,Y) - client coordinates.
- Usually it's called for the root (or inplace editor's) RVData.
- Calls SetDragDropCaret for the RVData containing
- d&d caret. Redraws d&d caret. Scrolls to make it visible. }
- procedure TCustomRVFormattedData.SetDragDropCaretTo(X,Y: Integer);
- var RVData: TCustomRVFormattedData;
- ItemNo, Offs: Integer;
- DragDropCaretInfo: TRVDragDropCaretInfo;
- var NoScroll: Boolean;
- begin
- inc(X, GetHOffs);
- inc(Y, GetVOffs);
- DrawDragDropCaret(GetCanvas, False);
- GetItemAtEx(X,Y, RVData, ItemNo, Offs, False, NoScroll);
- if (RVData<>nil) and (ItemNo>=0) then
- RVData.SetDragDropCaret(ItemNo, Offs);
- DrawDragDropCaret(GetCanvas, False);
- if not NoScroll then begin
- DragDropCaretInfo := GetDragDropCaretInfo;
- if DragDropCaretInfo<>nil then
- with DragDropCaretInfo do
- TCustomRVFormattedData(RVData).ShowRectangle(X, Y, 1, Height);
- end;
- end;
- {------------------------------------------------------------------------------}
- { Draw drag&drop caret. Usually called to remove it. }
- procedure TCustomRVFormattedData.RemoveDragDropCaret;
- begin
- DrawDragDropCaret(GetCanvas, False);
- end;
- {------------------------------------------------------------------------------}
- { Sets the position of drag&drop caret
- (fills the field of GetDragDropCaretInfo) }
- procedure TCustomRVFormattedData.SetDragDropCaret(ItemNo, Offs: Integer);
- var s: String;
- StyleNo, DItemNo, DOffs, max: Integer;
- ItemOptions: TRVItemOptions;
- arr: PRVIntegerArray;
- ditem: TRVDrawLineInfo;
- DragDropCaretInfo: TRVDragDropCaretInfo;
- begin
- DragDropCaretInfo := GetDragDropCaretInfo;
- if DragDropCaretInfo=nil then
- exit;
- DragDropCaretInfo.RVData := Self;
- DragDropCaretInfo.ItemNo := ItemNo;
- DragDropCaretInfo.ItemOffs := Offs;
- StyleNo := GetActualStyle(GetItem(ItemNo));
- Item2DrawItem(ItemNo, Offs, DItemNo, DOffs);
- ditem := DrawItems[DItemNo];
- DragDropCaretInfo.Y := ditem.Top;
- DragDropCaretInfo.Height := ditem.Height;
- DragDropCaretInfo.X := ditem.Left;
- if (StyleNo>=0) and (ditem.Length>0) then begin
- GetRVStyle.ApplyStyle(GetCanvas, StyleNo, GetParaBiDiMode(GetItemPara(ItemNo)), True);
- ItemOptions := GetItemOptions(ItemNo);
- s := DrawItems.GetString(DItemNo,Items);
- s := RV_ReturnProcessedString(s, GetRVStyle.TextStyles[StyleNo],
- IsDrawItemLastOnWrappedLine(DItemNo), rvoShowSpecialCharacters in Options, False);
- GetMem(arr, (ditem.Length+2)*sizeof(Integer));
- try
- if (GetItemBiDiMode(ItemNo)=rvbdUnspecified) or
- not RVU_GetTextCaretPos(GetCanvas, s, arr, ItemOptions, ditem.Width-ditem.SpaceBefore) then begin
- if DOffs=1 then
- DragDropCaretInfo.X := ditem.Left
- else begin
- RVU_GetTextExtentExPoint(GetCanvas, s, ditem.Width*10, max, arr, ItemOptions);
- DragDropCaretInfo.X := ditem.Left+arr[DOffs-2];
- end;
- end
- else
- DragDropCaretInfo.X := ditem.Left+arr[DOffs-1];
- finally
- FreeMem(arr);
- end;
- end
- else if Offs<=GetOffsBeforeItem(ItemNo) then
- DragDropCaretInfo.X := ditem.Left
- else
- DragDropCaretInfo.X := ditem.Left+ditem.Width;
- end;
- {------------------------------------------------------------------------------}
- { Returns information about drag&drop caret location.
- Returned value <> nil only if dragging to this RichViewEdit is in process.
- Physically, returned object is a field of the root TRichViewEdit.
- This method is overriden in TRVEditRVData and
- in TRichViewRVData (returns nil) }
- function TCustomRVFormattedData.GetDragDropCaretInfo: TRVDragDropCaretInfo;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).GetDragDropCaretInfo;
- end;
- {------------------------------------------------------------------------------}
- { Drawing drag&drop caret (using inverted color).
- Draws something only when d&d cursor is above the editor.
- If OnlyForSelf, drawing is performed only if this RVData contains
- d&d caret. Otherwise, drawing is performed by RVData contained d&d caret.
- Canvas - canvas for drawing to. If drawing is performed not by this RVData,
- its own Canvas is used instead. }
- procedure TCustomRVFormattedData.DrawDragDropCaret(Canvas: TCanvas;
- OnlyForSelf: Boolean);
- var DragDropCaretInfo: TRVDragDropCaretInfo;
- i: Integer;
- dx,dy: Integer;
- begin
- DragDropCaretInfo := GetDragDropCaretInfo;
- if (DragDropCaretInfo=nil) or (DragDropCaretInfo.RVData=nil) then
- exit;
- if (DragDropCaretInfo.RVData<>Self) then begin
- if not OnlyForSelf then
- TCustomRVFormattedData(DragDropCaretInfo.RVData).DrawDragDropCaret(
- TCustomRVFormattedData(DragDropCaretInfo.RVData).GetCanvas, True);
- exit;
- end;
- Canvas.Pen.Mode := pmNot;
- Canvas.Pen.Width := 1;
- Canvas.Brush.Style := bsClear;
- Canvas.Pen.Style := psDot;
- GetOrigin(dx,dy);
- dec(dy, GetRVDataExtraVOffs);
- dec(dx, TCustomRVFormattedData(GetRootData).GetHOffs);
- dec(dy, TCustomRVFormattedData(GetRootData).GetVOffs);
- for i := DragDropCaretInfo.Y+dy to DragDropCaretInfo.Y+DragDropCaretInfo.Height+dy do
- if i mod 2=0 then begin
- Canvas.MoveTo(dx+DragDropCaretInfo.X,i);
- Canvas.LineTo(dx+DragDropCaretInfo.X+2,i);
- end;
- Canvas.Pen.Style := psSolid;
- Canvas.Pen.Mode := pmCopy;
- end;
- {------------------------------------------------------------------------------}
- { Drag&Drop: IDropSource related }
- {------------------------------------------------------------------------------}
- { Can dragging from this TRichView be started?
- Overriden in TRichViewRVData. }
- function TCustomRVFormattedData.CanStartDragging: Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).CanStartDragging;
- end;
- {------------------------------------------------------------------------------}
- { Is dragging from this TRichView in process? Overriden in TRichViewRVData. }
- function TCustomRVFormattedData.IsDragging: Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).IsDragging;
- end;
- {------------------------------------------------------------------------------}
- { Initializing dragging. Overriden in TRichViewRVData.
- Returns True on success.
- Returns DropSource and OKEffect for call of DoDragDrop. }
- function TCustomRVFormattedData.InitDragging(var DropSource: TRVDropSource;
- var OKEffect: Integer): Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).InitDragging(DropSource, OKEffect);
- end;
- {------------------------------------------------------------------------------}
- { Finalizing dragging. Overriden in TRichViewRVData. }
- procedure TCustomRVFormattedData.DoneDragging(FDeleteSelection: Boolean);
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).DoneDragging(FDeleteSelection);
- end;
- {------------------------------------------------------------------------------}
- { Perform drag & drop from this RVData (called only for absolute root RVData) }
- procedure TCustomRVFormattedData.DoDrag;
- var Effect, OKEffect: LongInt;
- DropSource: TRVDropSource;
- pt: TPoint;
- RVData: TCustomRVFormattedData;
- ItemNo, Offs: Integer;
- Dummy: Boolean;
- begin
- State := State-[rvstStartingDragDrop]+
- [rvstCanDragDropDeleteSelection,rvstDragDropCursorNotMoved];
- try
- if InitDragging(DropSource, OKEffect) then begin
- DoDragDrop(DropSource as IDataObject, DropSource as IDropSource,
- OKEffect, Effect);
- DoneDragging((Effect=DROPEFFECT_MOVE) and (rvstCanDragDropDeleteSelection in State));
- if (Effect=DROPEFFECT_NONE) and (rvstDragDropCursorNotMoved in State) then begin
- GetCursorPos(pt);
- pt := GetParentControl.ScreenToClient(pt);
- GetItemAtEx(pt.X+GetHOffs,pt.Y+GetVOffs, RVData, ItemNo, Offs, False, Dummy);
- if ItemNo>=0 then begin
- RVData := TCustomRVFormattedData(RVData.Edit);
- RVData.SetSelectionBounds(ItemNo, Offs, ItemNo, Offs);
- RVData.Invalidate;
- end;
- {
- MouseDown(mbLeft, [ssLeft], pt.X, pt.Y);
- MouseUp(mbLeft, [], pt.X, pt.Y);
- }
- end;
- end;
- finally
- State := State-[rvstCanDragDropDeleteSelection,rvstDragDropCursorNotMoved];
- end;
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- { Returns true, if insertion in the specified location is possible.
- Used by drag&drop functions. }
- function TCustomRVFormattedData.CanInsertHere(ItemNo, Offs: Integer): Boolean;
- begin
- Result := False;
- if IsItemParaProtected(ItemNo) then
- exit;
- if Offs<=GetOffsBeforeItem(ItemNo) then
- Result := not IsSticking(ItemNo-1, True)
- else if Offs>=GetOffsAfterItem(ItemNo) then
- Result := not IsSticking(ItemNo, True)
- else
- Result := not IsProtected(ItemNo, rvprModifyProtect);
- end;
- {------------------------------------------------------------------------------}
- { Returns true if the ItemNo-th item has the specified protection.
- There is a special processing of rvprDeleteProtect - for non-text items,
- their DeleteProtect property is returned.
- This function used in editor and by CanInsertHere(). }
- function TCustomRVFormattedData.IsProtected(ItemNo: Integer;
- Option: TRVProtectOption): Boolean;
- var item: TCustomRVItemInfo;
- TextStyleNo: Integer;
- begin
- item := GetItem(ItemNo);
- if item.StyleNo>=0 then
- Result := Option in GetRVStyle.TextStyles[GetActualStyle(item)].Protection
- else begin
- TextStyleNo := item.AssociatedTextStyleNo;
- if TextStyleNo>=0 then
- Result := Option in GetRVStyle.TextStyles[TextStyleNo].Protection
- else
- Result := False;
- if Option = rvprDeleteProtect then
- Result := Result or TRVNonTextItemInfo(item).DeleteProtect
- end;
- end;
- {------------------------------------------------------------------------------}
- { Returns true if the ParaNo-th paragraph style has the specified option.
- This function used in editor and by CanInsertHere(). }
- function TCustomRVFormattedData.IsParaProtected(ParaNo: Integer;
- Option: TRVParaOption): Boolean;
- begin
- Result := Option in GetRVStyle.ParaStyles[ParaNo].Options;
- end;
- {------------------------------------------------------------------------------}
- { Returns true if the ItemNo-th item's paragraph style is read-only.
- This function used in editor and by CanInsertHere(). }
- function TCustomRVFormattedData.IsItemParaProtected(ItemNo: Integer): Boolean;
- begin
- Result := IsParaProtected(GetItemPara(ItemNo), rvpaoReadOnly);
- end;
- {------------------------------------------------------------------------------}
- { Returns true if insertion between FirstItemNo and (FirstItemNo+1) items is
- forbidden.
- FirstItemNo=-1 and FirstItemNo=Items.Count-1 are valid indices.
- This function used in editor and by CanInsertHere().
- If the function returns True and not NoSound, the function beeps }
- function TCustomRVFormattedData.IsSticking(FirstItemNo: Integer;
- NoSound: Boolean): Boolean;
- begin
- if (FirstItemNo=-1) then
- Result := IsProtected(0, rvprStickToTop)
- else if (FirstItemNo=Items.Count-1) then
- Result := IsProtected(FirstItemNo, rvprStickToBottom)
- else
- Result := IsProtected(FirstItemNo, rvprSticking) and
- IsProtected(FirstItemNo+1, rvprSticking);
- if Result and not NoSound then
- Beep;
- end;
- {------------------------------------------------------------------------------}
- {$IFNDEF RVDONOTUSELIVESPELL}
- procedure TCustomRVFormattedData.LiveSpellingCheckCurrentItem;
- begin
- if not (rvflRoot in Flags) then
- TCustomRVFormattedData(GetAbsoluteRootData).LiveSpellingCheckCurrentItem;
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- {$IFNDEF RVDONOTUSEANIMATION}
- procedure TCustomRVFormattedData.InsertAnimator(var Animator: TObject);
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).InsertAnimator(Animator);
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.AllowAnimation: Boolean;
- begin
- Result := TCustomRVFormattedData(GetAbsoluteRootData).AllowAnimation;
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.ResetAniBackground;
- begin
- TCustomRVFormattedData(GetAbsoluteRootData).ResetAniBackground;
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- {$IFNDEF RVDONOTUSESMARTPOPUP}
- procedure TCustomRVFormattedData.AdjustSpecialControlsCoords(
- RVData: TCustomRVFormattedData);
- begin
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.CreateFontInfoCache(ACanvas: TCanvas);
- begin
- end;
- {------------------------------------------------------------------------------}
- procedure TCustomRVFormattedData.DestroyFontInfoCache(var Cache: TRVFontInfoCache);
- begin
- if (Cache<>nil) and (Cache.FOwner=Self) then begin
- Cache.Free;
- Cache := nil;
- end;
- end;
- {------------------------------------------------------------------------------}
- function TCustomRVFormattedData.GetFontInfoCache(ACanvas: TCanvas;
- RVData: TCustomRVFormattedData): TRVFontInfoCache;
- begin
- Result := TCustomRVFormattedData(GetRootData).GetFontInfoCache(ACanvas,Self);
- end;
- {=========================== TRVFontInfoCache =================================}
- constructor TRVFontInfoCache.Create(const AData: TCustomRVFormattedData;
- const ARVStyle: TRVStyle; const ACanvas: TCanvas; ACanUseCustomPPI: Boolean);
- var i: Integer;
- begin
- FRVStyle := ARVStyle;
- FCanvas := ACanvas;
- FCanUseCustomPPI := ACanUseCustomPPI;
- FOwner := AData;
- LastTextStyle := -1;
- Capacity := ARVStyle.TextStyles.Count;
- for i := 0 to ARVStyle.TextStyles.Count-1 do
- Add(nil);
- end;
- end.