You've already forked lazarus-ccr
richmemo: * added tabstops support for the RichMemo and Win32Implementation
* added initialization to factory unit to prevent a warning on package compilation * clean up uses for richedit helpers * code cleanup (removing empty lines) git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4040 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -90,6 +90,18 @@ type
|
|||||||
// thus length = lengthNoBr
|
// thus length = lengthNoBr
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TTabAlignment = (taHead, taCenter, taTail, taDecimal, taWordBar);
|
||||||
|
|
||||||
|
TTabStop = record
|
||||||
|
Offset : Double;
|
||||||
|
Align : TTabAlignment; // not used
|
||||||
|
end;
|
||||||
|
|
||||||
|
TTabStopList = record
|
||||||
|
Count : Integer;
|
||||||
|
Tabs : array of TTabStop;
|
||||||
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
TRichMemoObject = class(TObject);
|
TRichMemoObject = class(TObject);
|
||||||
@ -150,6 +162,9 @@ type
|
|||||||
function GetParaRange(CharOfs: Integer; var ParaRange: TParaRange): Boolean; virtual;
|
function GetParaRange(CharOfs: Integer; var ParaRange: TParaRange): Boolean; virtual;
|
||||||
function GetParaRange(CharOfs: Integer; var TextStart, TextLength: Integer): Boolean;
|
function GetParaRange(CharOfs: Integer; var TextStart, TextLength: Integer): Boolean;
|
||||||
|
|
||||||
|
procedure SetParaTabs(TextStart, TextLen: Integer; const AStopList: TTabStopList); virtual;
|
||||||
|
function GetParaTabs(CharOfs: Integer; var AStopList: TTabStopList): Boolean; virtual;
|
||||||
|
|
||||||
procedure SetTextAttributes(TextStart, TextLen: Integer; AFont: TFont);
|
procedure SetTextAttributes(TextStart, TextLen: Integer; AFont: TFont);
|
||||||
procedure SetRangeColor(TextStart, TextLength: Integer; FontColor: TColor);
|
procedure SetRangeColor(TextStart, TextLength: Integer; FontColor: TColor);
|
||||||
procedure SetRangeParams(TextStart, TextLength: Integer; ModifyMask: TTextModifyMask;
|
procedure SetRangeParams(TextStart, TextLength: Integer; ModifyMask: TTextModifyMask;
|
||||||
@ -253,6 +268,9 @@ procedure InitParaMetric(var m: TParaMetric);
|
|||||||
procedure InitParaNumbering(var n: TParaNumbering);
|
procedure InitParaNumbering(var n: TParaNumbering);
|
||||||
procedure InitParaNumber(var n: TParaNumbering; ASepChar: WideChar = SepPar; StartNum: Integer = 1);
|
procedure InitParaNumber(var n: TParaNumbering; ASepChar: WideChar = SepPar; StartNum: Integer = 1);
|
||||||
procedure InitParaBullet(var n: TParaNumbering);
|
procedure InitParaBullet(var n: TParaNumbering);
|
||||||
|
procedure InitTabStopList(var tabs: TTabStopList); overload;
|
||||||
|
procedure InitTabStopList(var tabs: TTabStopList; const TabStopsPt: array of double); overload;
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
RTFLoadStream : function (AMemo: TCustomRichMemo; Source: TStream): Boolean = nil;
|
RTFLoadStream : function (AMemo: TCustomRichMemo; Source: TStream): Boolean = nil;
|
||||||
@ -379,6 +397,23 @@ begin
|
|||||||
n.Style:=pnBullet;
|
n.Style:=pnBullet;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure InitTabStopList(var tabs: TTabStopList);
|
||||||
|
begin
|
||||||
|
FillChar(tabs, sizeof(tabs), 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure InitTabStopList(var tabs: TTabStopList; const TabStopsPt: array of double);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
InitTabStopList(tabs);
|
||||||
|
tabs.count:=length(TabStopsPt);
|
||||||
|
SetLength(tabs.tabs, tabs.Count);
|
||||||
|
for i:=0 to tabs.Count-1 do begin
|
||||||
|
tabs.tabs[i].Offset:=TabStopsPt[i];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TRichMemoInline }
|
{ TRichMemoInline }
|
||||||
|
|
||||||
procedure TRichMemoInline.Draw(Canvas: TCanvas; const ASize: TSize);
|
procedure TRichMemoInline.Draw(Canvas: TCanvas; const ASize: TSize);
|
||||||
@ -611,6 +646,21 @@ begin
|
|||||||
TextLength:=p.length;
|
TextLength:=p.length;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomRichMemo.SetParaTabs(TextStart, TextLen: Integer;
|
||||||
|
const AStopList: TTabStopList);
|
||||||
|
begin
|
||||||
|
if HandleAllocated then
|
||||||
|
TWSCustomRichMemoClass(WidgetSetClass).SetParaTabs(Self, TextStart, TextLen, AStopList);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomRichMemo.GetParaTabs(CharOfs: Integer; var AStopList: TTabStopList): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
if not HandleAllocated then HandleNeeded;
|
||||||
|
if HandleAllocated then
|
||||||
|
Result:=TWSCustomRichMemoClass(WidgetSetClass).GetParaTabs(Self, CharOfs, AStopList);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomRichMemo.GetContStyleLength(TextStart: Integer): Integer;
|
function TCustomRichMemo.GetContStyleLength(TextStart: Integer): Integer;
|
||||||
var
|
var
|
||||||
ofs, len : Integer;
|
ofs, len : Integer;
|
||||||
|
@ -51,6 +51,10 @@ begin
|
|||||||
{$ifdef NoRichMemo}RegisterWSComponent(TCustomRichMemo, TWSCustomRichMemo);{$endif}
|
{$ifdef NoRichMemo}RegisterWSComponent(TCustomRichMemo, TWSCustomRichMemo);{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
// initialization is here just to prevent compiler warning about not being used
|
||||||
|
// the unit is actually used by providing an implementation for WSREgisterCustomRichMemo class
|
||||||
|
// thus it shouldn't be smart-linked out by a smartlinker. hmm
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@ interface
|
|||||||
|
|
||||||
{$IFDEF FPC_FULLVERSION >= 20600}
|
{$IFDEF FPC_FULLVERSION >= 20600}
|
||||||
uses
|
uses
|
||||||
SysUtils, StrUtils, Graphics,
|
SysUtils, Graphics, RichMemo;
|
||||||
RichMemo;
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TRichEditFromRichMemo = class(TObject);
|
TRichEditFromRichMemo = class(TObject);
|
||||||
|
@ -99,6 +99,11 @@ type
|
|||||||
class procedure SetParaNumbering(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
class procedure SetParaNumbering(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
const ANumber: TIntParaNumbering); override;
|
const ANumber: TIntParaNumbering); override;
|
||||||
|
|
||||||
|
class procedure SetParaTabs(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
|
const AStopList: TTabStopList); override;
|
||||||
|
class function GetParaTabs(const AWinControl: TWinControl; TextStart: integer;
|
||||||
|
var AStopList: TTabStopList): Boolean; override;
|
||||||
|
|
||||||
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
||||||
|
|
||||||
class function Search(const AWinControl: TWinControl; const ANiddle: string;
|
class function Search(const AWinControl: TWinControl; const ANiddle: string;
|
||||||
@ -140,6 +145,10 @@ const
|
|||||||
{ taCenter } ES_CENTER
|
{ taCenter } ES_CENTER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const
|
||||||
|
TAB_OFFSET_MASK = $7FFFFF;
|
||||||
|
TAB_OFFSET_BITS = 24;
|
||||||
|
TWIP_PT = 20; // Twips in Point. Twips are commonly used measurement unit for RichEdit inteface
|
||||||
|
|
||||||
procedure LockRedraw(AHandle: HWND);
|
procedure LockRedraw(AHandle: HWND);
|
||||||
begin
|
begin
|
||||||
@ -617,12 +626,12 @@ begin
|
|||||||
|
|
||||||
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
||||||
|
|
||||||
AMetrics.FirstLine:=para.dxStartIndent/20;
|
AMetrics.FirstLine:=para.dxStartIndent/TWIP_PT;
|
||||||
AMetrics.TailIndent:=para.dxRightIndent/20;
|
AMetrics.TailIndent:=para.dxRightIndent/TWIP_PT;
|
||||||
AMetrics.HeadIndent:=(para.dxStartIndent+para.dxOffset)/20;
|
AMetrics.HeadIndent:=(para.dxStartIndent+para.dxOffset)/TWIP_PT;
|
||||||
AMetrics.SpaceAfter:=para.dySpaceAfter/20;
|
AMetrics.SpaceAfter:=para.dySpaceAfter/TWIP_PT;
|
||||||
AMetrics.SpaceBefore:=para.dySpaceBefore/20;
|
AMetrics.SpaceBefore:=para.dySpaceBefore/TWIP_PT;
|
||||||
AMetrics.LineSpacing:=para.dyLineSpacing*DefLineSpacing/20;
|
AMetrics.LineSpacing:=para.dyLineSpacing*DefLineSpacing/TWIP_PT;
|
||||||
|
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
end;
|
end;
|
||||||
@ -643,14 +652,14 @@ begin
|
|||||||
or PFM_OFFSET
|
or PFM_OFFSET
|
||||||
or PFM_SPACEAFTER or PFM_SPACEBEFORE
|
or PFM_SPACEAFTER or PFM_SPACEBEFORE
|
||||||
or PFM_LINESPACING;
|
or PFM_LINESPACING;
|
||||||
para.dxStartIndent:=round(AMetrics.FirstLine*20);
|
para.dxStartIndent:=round(AMetrics.FirstLine*TWIP_PT);
|
||||||
para.dxRightIndent:=round(AMetrics.TailIndent*20);
|
para.dxRightIndent:=round(AMetrics.TailIndent*TWIP_PT);
|
||||||
para.dxOffset:=round((AMetrics.HeadIndent-AMetrics.FirstLine)*20);
|
para.dxOffset:=round((AMetrics.HeadIndent-AMetrics.FirstLine)*TWIP_PT);
|
||||||
//round(AMetrics.HeadIndent*20);
|
//round(AMetrics.HeadIndent*TWIP_PT);
|
||||||
para.dySpaceAfter:=round(AMetrics.SpaceAfter*20);
|
para.dySpaceAfter:=round(AMetrics.SpaceAfter*TWIP_PT);
|
||||||
para.dySpaceBefore:=round(AMetrics.SpaceBefore*20);
|
para.dySpaceBefore:=round(AMetrics.SpaceBefore*TWIP_PT);
|
||||||
if AMetrics.LineSpacing > 0 then begin
|
if AMetrics.LineSpacing > 0 then begin
|
||||||
para.dyLineSpacing:=round(AMetrics.LineSpacing/DefLineSpacing*20);
|
para.dyLineSpacing:=round(AMetrics.LineSpacing/DefLineSpacing*TWIP_PT);
|
||||||
para.bLineSpacingRule:=5; // always line spacing?
|
para.bLineSpacingRule:=5; // always line spacing?
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -713,7 +722,7 @@ begin
|
|||||||
ANumber.SepChar:=SepDot
|
ANumber.SepChar:=SepDot
|
||||||
else if (ANumber.Style<>pnNone) and ((para.wNumberingStyle and PFNS_SOMESEPCHAR)= 0) then
|
else if (ANumber.Style<>pnNone) and ((para.wNumberingStyle and PFNS_SOMESEPCHAR)= 0) then
|
||||||
ANumber.SepChar:=SepPar;
|
ANumber.SepChar:=SepPar;
|
||||||
ANumber.Indent:=para.wNumberingTab/20;
|
ANumber.Indent:=para.wNumberingTab/TWIP_PT;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -762,12 +771,86 @@ begin
|
|||||||
para.wNumberingStyle:=numbstyle;
|
para.wNumberingStyle:=numbstyle;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
para.wNumberingTab:=round(ANumber.Indent*20);
|
para.wNumberingTab:=round(ANumber.Indent*TWIP_PT);
|
||||||
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLen, para);
|
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLen, para);
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask)
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure TWin32WSCustomRichMemo.SetParaTabs(
|
||||||
|
const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
|
const AStopList: TTabStopList);
|
||||||
|
var
|
||||||
|
para : PARAFORMAT2;
|
||||||
|
eventmask: Integer;
|
||||||
|
cnt : Integer;
|
||||||
|
i : Integer;
|
||||||
|
const
|
||||||
|
PARAALIGN : array [TTabAlignment] of LongWord = (
|
||||||
|
0 shl TAB_OFFSET_BITS, // taHead,
|
||||||
|
1 shl TAB_OFFSET_BITS, // taCenter,
|
||||||
|
2 shl TAB_OFFSET_BITS, // taTail,
|
||||||
|
3 shl TAB_OFFSET_BITS, // taDecimal,
|
||||||
|
4 shl TAB_OFFSET_BITS // taWordBar
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
||||||
|
FillChar(para, SizeOf(para), 0);
|
||||||
|
|
||||||
|
para.cbSize:=sizeof(para);
|
||||||
|
para.dwMask:=PFM_TABSTOPS;
|
||||||
|
|
||||||
|
if AStopList.Count > MAX_TAB_STOPS then cnt:=MAX_TAB_STOPS
|
||||||
|
else cnt:=AStopList.Count;
|
||||||
|
|
||||||
|
para.cTabCount:=cnt;
|
||||||
|
for i:=0 to cnt-1 do begin
|
||||||
|
para.rgxTabs[i]:=((round(AStopList.Tabs[i].Offset*TWIP_PT)) and TAB_OFFSET_MASK) or PARAALIGN[AStopList.Tabs[i].Align] ;
|
||||||
|
end;
|
||||||
|
|
||||||
|
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
|
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLen, para);
|
||||||
|
|
||||||
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TWin32WSCustomRichMemo.GetParaTabs(
|
||||||
|
const AWinControl: TWinControl; TextStart: integer;
|
||||||
|
var AStopList: TTabStopList): Boolean;
|
||||||
|
var
|
||||||
|
para : PARAFORMAT2;
|
||||||
|
eventmask: Integer;
|
||||||
|
v : LongWord;
|
||||||
|
al : TTabAlignment;
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
||||||
|
|
||||||
|
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
||||||
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
|
|
||||||
|
InitTabStopList(AStopList);
|
||||||
|
AStopList.Count:=para.cTabCount;
|
||||||
|
SetLength(AStopList.Tabs, AStopList.Count);
|
||||||
|
for i:=0 to AStopList.Count-1 do begin
|
||||||
|
v:=para.rgxTabs[i];
|
||||||
|
AStopList.Tabs[i].Offset:=(v and TAB_OFFSET_MASK) / TWIP_PT;
|
||||||
|
case v shr TAB_OFFSET_BITS of
|
||||||
|
1: al:=taCenter;
|
||||||
|
2: al:=taTail;
|
||||||
|
3: al:=taDecimal;
|
||||||
|
4: al:=taWordBar;
|
||||||
|
else
|
||||||
|
al:=taHead
|
||||||
|
end;
|
||||||
|
AStopList.Tabs[i].Align:=al;
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TWin32WSCustomRichMemo.InDelText(const AWinControl:TWinControl;
|
class procedure TWin32WSCustomRichMemo.InDelText(const AWinControl:TWinControl;
|
||||||
const TextUTF8:String;DstStart,DstLen:Integer);
|
const TextUTF8:String;DstStart,DstLen:Integer);
|
||||||
var
|
var
|
||||||
|
@ -602,9 +602,7 @@ var
|
|||||||
begin
|
begin
|
||||||
GetSelection(RichEditWnd, s, l);
|
GetSelection(RichEditWnd, s, l);
|
||||||
SetSelection(RichEditWnd, TextStart, TextLen);
|
SetSelection(RichEditWnd, TextStart, TextLen);
|
||||||
|
|
||||||
SendMessagea(RichEditWnd, EM_SETPARAFORMAT, 0, LPARAM(@para));
|
SendMessagea(RichEditWnd, EM_SETPARAFORMAT, 0, LPARAM(@para));
|
||||||
|
|
||||||
SetSelection(RichEditWnd, s, l);
|
SetSelection(RichEditWnd, s, l);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -37,18 +37,6 @@ type
|
|||||||
TIntParaMetric = RichMemo.TParaMetric;
|
TIntParaMetric = RichMemo.TParaMetric;
|
||||||
TIntParaNumbering = RichMemo.TParaNumbering;
|
TIntParaNumbering = RichMemo.TParaNumbering;
|
||||||
|
|
||||||
TTabAlignment = (taLeft, taCenter, taRight, taDecimal, taWordBar);
|
|
||||||
|
|
||||||
TTabInfo = record
|
|
||||||
Offset : Double;
|
|
||||||
Align : TTabAlignment;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TIntParaTabs = record
|
|
||||||
Count : Integer;
|
|
||||||
Tabs : array of TTabInfo;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TIntSearchOpt = record
|
TIntSearchOpt = record
|
||||||
start : Integer;
|
start : Integer;
|
||||||
len : Integer;
|
len : Integer;
|
||||||
@ -84,6 +72,12 @@ type
|
|||||||
class function GetParaRange(const AWinControl: TWinControl; TextStart: Integer; var rng: TParaRange): Boolean; virtual;
|
class function GetParaRange(const AWinControl: TWinControl; TextStart: Integer; var rng: TParaRange): Boolean; virtual;
|
||||||
class procedure SetParaNumbering(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
class procedure SetParaNumbering(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
const ANumber: TIntParaNumbering); virtual;
|
const ANumber: TIntParaNumbering); virtual;
|
||||||
|
|
||||||
|
class procedure SetParaTabs(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
|
const AStopList: TTabStopList); virtual;
|
||||||
|
class function GetParaTabs(const AWinControl: TWinControl; TextStart: integer;
|
||||||
|
var AStopList: TTabStopList): Boolean; virtual;
|
||||||
|
|
||||||
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); virtual;
|
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); virtual;
|
||||||
//class procedure SetHideSelection(const ACustomEdit: TCustomEdit; AHideSelection: Boolean); override;
|
//class procedure SetHideSelection(const ACustomEdit: TCustomEdit; AHideSelection: Boolean); override;
|
||||||
class function LoadRichText(const AWinControl: TWinControl; Source: TStream): Boolean; virtual;
|
class function LoadRichText(const AWinControl: TWinControl; Source: TStream): Boolean; virtual;
|
||||||
@ -194,6 +188,18 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure TWSCustomRichMemo.SetParaTabs(const AWinControl: TWinControl;
|
||||||
|
TextStart, TextLen: Integer; const AStopList: TTabStopList);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TWSCustomRichMemo.GetParaTabs(const AWinControl: TWinControl;
|
||||||
|
TextStart: integer; var AStopList: TTabStopList): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TWSCustomRichMemo.InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer);
|
class procedure TWSCustomRichMemo.InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer);
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user