fpspreadsheet: Add "replace" to search engine.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4316 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
50f0b2fbe6
commit
a5cbacff27
@ -500,6 +500,7 @@ begin
|
|||||||
SearchForm.OnFound := @SearchFound;
|
SearchForm.OnFound := @SearchFound;
|
||||||
SearchForm.OnClose := @SearchClose;
|
SearchForm.OnClose := @SearchClose;
|
||||||
SearchForm.SearchParams := DefaultSearchParams;
|
SearchForm.SearchParams := DefaultSearchParams;
|
||||||
|
SearchForm.ReplaceParams := DefaultReplaceParams;
|
||||||
SearchForm.Execute(WorkbookSource.Workbook);
|
SearchForm.Execute(WorkbookSource.Workbook);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -609,6 +610,7 @@ procedure TMainForm.SearchClose(Sender: TObject; var CloseAction: TCloseAction);
|
|||||||
begin
|
begin
|
||||||
Unused(CloseAction);
|
Unused(CloseAction);
|
||||||
DefaultSearchParams := TSearchForm(Sender).SearchParams;
|
DefaultSearchParams := TSearchForm(Sender).SearchParams;
|
||||||
|
DefaultReplaceParams := TSearchForm(Sender).ReplaceParams;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.SearchFound(Sender: TObject; AFound: Boolean;
|
procedure TMainForm.SearchFound(Sender: TObject; AFound: Boolean;
|
||||||
|
@ -1,112 +1,39 @@
|
|||||||
object SearchForm: TSearchForm
|
object SearchForm: TSearchForm
|
||||||
Left = 238
|
Left = 238
|
||||||
Height = 272
|
Height = 341
|
||||||
Top = 157
|
Top = 157
|
||||||
Width = 483
|
Width = 487
|
||||||
BorderStyle = bsDialog
|
BorderStyle = bsDialog
|
||||||
Caption = 'Search'
|
Caption = 'Search'
|
||||||
ClientHeight = 272
|
ClientHeight = 341
|
||||||
ClientWidth = 483
|
ClientWidth = 487
|
||||||
FormStyle = fsStayOnTop
|
FormStyle = fsStayOnTop
|
||||||
OnClose = FormClose
|
OnClose = FormClose
|
||||||
OnCreate = FormCreate
|
OnCreate = FormCreate
|
||||||
OnShow = FormShow
|
OnShow = FormShow
|
||||||
LCLVersion = '1.5'
|
LCLVersion = '1.5'
|
||||||
object LblSearchText: TLabel
|
|
||||||
Left = 14
|
|
||||||
Height = 15
|
|
||||||
Top = 18
|
|
||||||
Width = 53
|
|
||||||
Caption = 'Search for'
|
|
||||||
ParentColor = False
|
|
||||||
end
|
|
||||||
object CbSearchText: TComboBox
|
|
||||||
Left = 93
|
|
||||||
Height = 23
|
|
||||||
Top = 14
|
|
||||||
Width = 374
|
|
||||||
Anchors = [akTop, akLeft, akRight]
|
|
||||||
ItemHeight = 15
|
|
||||||
TabOrder = 0
|
|
||||||
end
|
|
||||||
object CgSearchOptions: TCheckGroup
|
|
||||||
Left = 16
|
|
||||||
Height = 163
|
|
||||||
Top = 53
|
|
||||||
Width = 192
|
|
||||||
AutoFill = True
|
|
||||||
Caption = 'Search options'
|
|
||||||
ChildSizing.LeftRightSpacing = 6
|
|
||||||
ChildSizing.TopBottomSpacing = 6
|
|
||||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
|
||||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
|
||||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
|
||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
|
||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
|
||||||
ChildSizing.ControlsPerLine = 1
|
|
||||||
ClientHeight = 143
|
|
||||||
ClientWidth = 188
|
|
||||||
Items.Strings = (
|
|
||||||
'Compare entire cell '
|
|
||||||
'Match case'
|
|
||||||
'Regular expression'
|
|
||||||
'Search along rows'
|
|
||||||
'Continue at start/end'
|
|
||||||
)
|
|
||||||
TabOrder = 1
|
|
||||||
Data = {
|
|
||||||
050000000202020202
|
|
||||||
}
|
|
||||||
end
|
|
||||||
object RgSearchWithin: TRadioGroup
|
|
||||||
Left = 232
|
|
||||||
Height = 67
|
|
||||||
Top = 53
|
|
||||||
Width = 232
|
|
||||||
AutoFill = True
|
|
||||||
Caption = 'Search within'
|
|
||||||
ChildSizing.LeftRightSpacing = 6
|
|
||||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
|
||||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
|
||||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
|
||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
|
||||||
ChildSizing.Layout = cclTopToBottomThenLeftToRight
|
|
||||||
ChildSizing.ControlsPerLine = 2
|
|
||||||
ClientHeight = 47
|
|
||||||
ClientWidth = 228
|
|
||||||
ColumnLayout = clVerticalThenHorizontal
|
|
||||||
Columns = 2
|
|
||||||
ItemIndex = 0
|
|
||||||
Items.Strings = (
|
|
||||||
'workbook'
|
|
||||||
'worksheet'
|
|
||||||
'column'
|
|
||||||
'row'
|
|
||||||
)
|
|
||||||
TabOrder = 2
|
|
||||||
end
|
|
||||||
object ButtonPanel: TPanel
|
object ButtonPanel: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 38
|
Height = 38
|
||||||
Top = 234
|
Top = 303
|
||||||
Width = 483
|
Width = 487
|
||||||
Align = alBottom
|
Align = alBottom
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
ClientHeight = 38
|
ClientHeight = 38
|
||||||
ClientWidth = 483
|
ClientWidth = 487
|
||||||
TabOrder = 3
|
TabOrder = 0
|
||||||
object Bevel1: TBevel
|
object Bevel1: TBevel
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 3
|
Height = 3
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 471
|
Width = 475
|
||||||
Align = alTop
|
Align = alTop
|
||||||
BorderSpacing.Left = 6
|
BorderSpacing.Left = 6
|
||||||
BorderSpacing.Right = 6
|
BorderSpacing.Right = 6
|
||||||
Shape = bsTopLine
|
Shape = bsTopLine
|
||||||
end
|
end
|
||||||
object BtnSearchBack: TBitBtn
|
object BtnSearchBack: TBitBtn
|
||||||
Left = 240
|
Left = 244
|
||||||
Height = 25
|
Height = 25
|
||||||
Top = 7
|
Top = 7
|
||||||
Width = 75
|
Width = 75
|
||||||
@ -148,12 +75,12 @@ object SearchForm: TSearchForm
|
|||||||
0000000000000000000000000000000000000000000054545411555555405555
|
0000000000000000000000000000000000000000000054545411555555405555
|
||||||
555A555555655555555A55555540545454110000000000000000
|
555A555555655555555A55555540545454110000000000000000
|
||||||
}
|
}
|
||||||
OnClick = SearchButtonClick
|
OnClick = ExecuteClick
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
Visible = False
|
Visible = False
|
||||||
end
|
end
|
||||||
object BtnClose: TBitBtn
|
object BtnClose: TBitBtn
|
||||||
Left = 400
|
Left = 404
|
||||||
Height = 25
|
Height = 25
|
||||||
Top = 7
|
Top = 7
|
||||||
Width = 75
|
Width = 75
|
||||||
@ -165,7 +92,7 @@ object SearchForm: TSearchForm
|
|||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
end
|
end
|
||||||
object BtnSearch: TBitBtn
|
object BtnSearch: TBitBtn
|
||||||
Left = 320
|
Left = 324
|
||||||
Height = 25
|
Height = 25
|
||||||
Top = 7
|
Top = 7
|
||||||
Width = 75
|
Width = 75
|
||||||
@ -208,32 +135,178 @@ object SearchForm: TSearchForm
|
|||||||
0000000000000000000000000000000000000000000054545411555555405555
|
0000000000000000000000000000000000000000000054545411555555405555
|
||||||
555A555555655555555A55555540545454110000000000000000
|
555A555555655555555A55555540545454110000000000000000
|
||||||
}
|
}
|
||||||
OnClick = SearchButtonClick
|
OnClick = ExecuteClick
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
object RgSearchStart: TRadioGroup
|
object TabControl: TTabControl
|
||||||
Left = 232
|
Left = 8
|
||||||
Height = 56
|
Height = 287
|
||||||
Top = 160
|
Top = 8
|
||||||
Width = 232
|
Width = 471
|
||||||
AutoFill = True
|
OnChange = TabControlChange
|
||||||
Caption = 'Start search at'
|
OnChanging = TabControlChanging
|
||||||
ChildSizing.LeftRightSpacing = 6
|
TabIndex = 0
|
||||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
Tabs.Strings = (
|
||||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
'Search'
|
||||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
'Replace'
|
||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
|
||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
|
||||||
ChildSizing.ControlsPerLine = 2
|
|
||||||
ClientHeight = 36
|
|
||||||
ClientWidth = 228
|
|
||||||
Columns = 2
|
|
||||||
ItemIndex = 0
|
|
||||||
Items.Strings = (
|
|
||||||
'active cell'
|
|
||||||
'beginning/end'
|
|
||||||
)
|
)
|
||||||
TabOrder = 4
|
Align = alClient
|
||||||
|
BorderSpacing.Around = 8
|
||||||
|
TabOrder = 1
|
||||||
|
object SearchTextPanel: TPanel
|
||||||
|
Left = 2
|
||||||
|
Height = 33
|
||||||
|
Top = 23
|
||||||
|
Width = 467
|
||||||
|
Align = alTop
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 33
|
||||||
|
ClientWidth = 467
|
||||||
|
Color = clNone
|
||||||
|
ParentColor = False
|
||||||
|
TabOrder = 1
|
||||||
|
object LblSearchText: TLabel
|
||||||
|
Left = 14
|
||||||
|
Height = 15
|
||||||
|
Top = 12
|
||||||
|
Width = 53
|
||||||
|
Caption = 'Search for'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object CbSearchText: TComboBox
|
||||||
|
Left = 104
|
||||||
|
Height = 23
|
||||||
|
Top = 8
|
||||||
|
Width = 351
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
ItemHeight = 15
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object ReplaceTextPanel: TPanel
|
||||||
|
Left = 2
|
||||||
|
Height = 33
|
||||||
|
Top = 56
|
||||||
|
Width = 467
|
||||||
|
Align = alTop
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 33
|
||||||
|
ClientWidth = 467
|
||||||
|
Color = clNone
|
||||||
|
ParentColor = False
|
||||||
|
TabOrder = 2
|
||||||
|
Visible = False
|
||||||
|
object LblSearchText1: TLabel
|
||||||
|
Left = 14
|
||||||
|
Height = 15
|
||||||
|
Top = 12
|
||||||
|
Width = 67
|
||||||
|
Caption = 'Replace with'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object CbReplaceText: TComboBox
|
||||||
|
Left = 104
|
||||||
|
Height = 23
|
||||||
|
Top = 8
|
||||||
|
Width = 351
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
ItemHeight = 15
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object SearchParamsPanel: TPanel
|
||||||
|
Left = 2
|
||||||
|
Height = 196
|
||||||
|
Top = 89
|
||||||
|
Width = 467
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 196
|
||||||
|
ClientWidth = 467
|
||||||
|
Color = clNone
|
||||||
|
ParentColor = False
|
||||||
|
TabOrder = 3
|
||||||
|
object CgOptions: TCheckGroup
|
||||||
|
Left = 16
|
||||||
|
Height = 163
|
||||||
|
Top = 16
|
||||||
|
Width = 192
|
||||||
|
AutoFill = True
|
||||||
|
Caption = 'Options'
|
||||||
|
ChildSizing.LeftRightSpacing = 6
|
||||||
|
ChildSizing.TopBottomSpacing = 6
|
||||||
|
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||||
|
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||||
|
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||||
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
|
ChildSizing.ControlsPerLine = 1
|
||||||
|
ClientHeight = 143
|
||||||
|
ClientWidth = 188
|
||||||
|
Items.Strings = (
|
||||||
|
'Compare entire cell '
|
||||||
|
'Match case'
|
||||||
|
'Regular expression'
|
||||||
|
'Search along rows'
|
||||||
|
'Continue at start/end'
|
||||||
|
)
|
||||||
|
TabOrder = 0
|
||||||
|
Data = {
|
||||||
|
050000000202020202
|
||||||
|
}
|
||||||
|
end
|
||||||
|
object RgSearchWithin: TRadioGroup
|
||||||
|
Left = 232
|
||||||
|
Height = 67
|
||||||
|
Top = 16
|
||||||
|
Width = 223
|
||||||
|
AutoFill = True
|
||||||
|
Caption = 'Search within'
|
||||||
|
ChildSizing.LeftRightSpacing = 6
|
||||||
|
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||||
|
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||||
|
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||||
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
|
ChildSizing.Layout = cclTopToBottomThenLeftToRight
|
||||||
|
ChildSizing.ControlsPerLine = 2
|
||||||
|
ClientHeight = 47
|
||||||
|
ClientWidth = 219
|
||||||
|
ColumnLayout = clVerticalThenHorizontal
|
||||||
|
Columns = 2
|
||||||
|
ItemIndex = 0
|
||||||
|
Items.Strings = (
|
||||||
|
'workbook'
|
||||||
|
'worksheet'
|
||||||
|
'column'
|
||||||
|
'row'
|
||||||
|
)
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object RgSearchStart: TRadioGroup
|
||||||
|
Left = 232
|
||||||
|
Height = 56
|
||||||
|
Top = 123
|
||||||
|
Width = 223
|
||||||
|
AutoFill = True
|
||||||
|
Caption = 'Start search at'
|
||||||
|
ChildSizing.LeftRightSpacing = 6
|
||||||
|
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||||
|
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||||
|
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||||
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
|
ChildSizing.ControlsPerLine = 2
|
||||||
|
ClientHeight = 36
|
||||||
|
ClientWidth = 219
|
||||||
|
Columns = 2
|
||||||
|
ItemIndex = 0
|
||||||
|
Items.Strings = (
|
||||||
|
'active cell'
|
||||||
|
'beginning/end'
|
||||||
|
)
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
||||||
StdCtrls, ExtCtrls, Buttons, fpsTypes, fpspreadsheet, fpsSearch;
|
StdCtrls, ExtCtrls, Buttons, ComCtrls, fpsTypes, fpspreadsheet, fpsSearch;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsSearchEvent = procedure (Sender: TObject; AFound: Boolean;
|
TsSearchEvent = procedure (Sender: TObject; AFound: Boolean;
|
||||||
@ -20,29 +20,46 @@ type
|
|||||||
BtnClose: TBitBtn;
|
BtnClose: TBitBtn;
|
||||||
BtnSearch: TBitBtn;
|
BtnSearch: TBitBtn;
|
||||||
CbSearchText: TComboBox;
|
CbSearchText: TComboBox;
|
||||||
CgSearchOptions: TCheckGroup;
|
CbReplaceText: TComboBox;
|
||||||
|
CgOptions: TCheckGroup;
|
||||||
LblSearchText: TLabel;
|
LblSearchText: TLabel;
|
||||||
ButtonPanel: TPanel;
|
ButtonPanel: TPanel;
|
||||||
|
LblSearchText1: TLabel;
|
||||||
|
SearchParamsPanel: TPanel;
|
||||||
|
SearchTextPanel: TPanel;
|
||||||
RgSearchStart: TRadioGroup;
|
RgSearchStart: TRadioGroup;
|
||||||
RgSearchWithin: TRadioGroup;
|
RgSearchWithin: TRadioGroup;
|
||||||
|
ReplaceTextPanel: TPanel;
|
||||||
|
TabControl: TTabControl;
|
||||||
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure FormShow(Sender: TObject);
|
procedure FormShow(Sender: TObject);
|
||||||
procedure SearchButtonClick(Sender: TObject);
|
procedure ExecuteClick(Sender: TObject);
|
||||||
|
procedure TabControlChange(Sender: TObject);
|
||||||
|
procedure TabControlChanging(Sender: TObject; var AllowChange: Boolean);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
{ private declarations }
|
||||||
FSearchEngine: TsSearchEngine;
|
FSearchEngine: TsSearchEngine;
|
||||||
FWorkbook: TsWorkbook;
|
FWorkbook: TsWorkbook;
|
||||||
FFoundWorksheet: TsWorksheet;
|
FFoundWorksheet: TsWorksheet;
|
||||||
FFoundRow, FFoundCol: Cardinal;
|
FFoundRow, FFoundCol: Cardinal;
|
||||||
|
FSearchParams: TsSearchParams;
|
||||||
|
FReplaceParams: TsReplaceParams;
|
||||||
FOnFound: TsSearchEvent;
|
FOnFound: TsSearchEvent;
|
||||||
function GetParams: TsSearchParams;
|
function GetReplaceParams: TsReplaceParams;
|
||||||
procedure SetParams(const AValue: TsSearchParams);
|
function GetSearchParams: TsSearchParams;
|
||||||
|
procedure SetReplaceParams(const AValue: TsReplaceParams);
|
||||||
|
procedure SetSearchParams(const AValue: TsSearchParams);
|
||||||
|
protected
|
||||||
|
procedure ConfirmReplacementHandler(Sender: TObject; AWorksheet: TsWorksheet;
|
||||||
|
ARow, ACol: Cardinal; const ASearchText, AReplaceText: String; var Allow: Boolean);
|
||||||
|
procedure PopulateOptions;
|
||||||
public
|
public
|
||||||
{ public declarations }
|
{ public declarations }
|
||||||
procedure Execute(AWorkbook: TsWorkbook);
|
procedure Execute(AWorkbook: TsWorkbook);
|
||||||
property Workbook: TsWorkbook read FWorkbook;
|
property Workbook: TsWorkbook read FWorkbook;
|
||||||
property SearchParams: TsSearchParams read GetParams write SetParams;
|
property SearchParams: TsSearchParams read GetSearchParams write SetSearchParams;
|
||||||
|
property ReplaceParams: TsReplaceParams read GetReplaceParams write SetReplaceParams;
|
||||||
property OnFound: TsSearchEvent read FOnFound write FOnFound;
|
property OnFound: TsSearchEvent read FOnFound write FOnFound;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -54,6 +71,10 @@ var
|
|||||||
Options: [];
|
Options: [];
|
||||||
Within: swWorksheet
|
Within: swWorksheet
|
||||||
);
|
);
|
||||||
|
DefaultReplaceParams: TsReplaceParams = (
|
||||||
|
ReplaceText: '';
|
||||||
|
Options: [roConfirm]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -66,21 +87,108 @@ uses
|
|||||||
const
|
const
|
||||||
MAX_SEARCH_ITEMS = 10;
|
MAX_SEARCH_ITEMS = 10;
|
||||||
|
|
||||||
|
// Search & replace
|
||||||
COMPARE_ENTIRE_CELL = 0;
|
COMPARE_ENTIRE_CELL = 0;
|
||||||
MATCH_CASE = 1;
|
MATCH_CASE = 1;
|
||||||
REGULAR_EXPRESSION = 2;
|
REGULAR_EXPRESSION = 2;
|
||||||
SEARCH_ALONG_ROWS = 3;
|
SEARCH_ALONG_ROWS = 3;
|
||||||
CONTINUE_AT_START_END = 4;
|
CONTINUE_AT_START_END = 4;
|
||||||
|
// Replace only
|
||||||
|
REPLACE_ENTIRE_CELL = 5;
|
||||||
|
REPLACE_ALL = 6;
|
||||||
|
CONFIRM_REPLACEMENT = 7;
|
||||||
|
|
||||||
|
BASE_HEIGHT = 340; // Design height of SearchForm
|
||||||
|
|
||||||
|
SEARCH_TAB = 0;
|
||||||
|
REPLACE_TAB = 1;
|
||||||
|
|
||||||
{ TSearchForms }
|
{ TSearchForms }
|
||||||
|
|
||||||
|
procedure TSearchForm.ConfirmReplacementHandler(Sender: TObject;
|
||||||
|
AWorksheet: TsWorksheet; ARow, ACol: Cardinal;
|
||||||
|
const ASearchText, AReplaceText: String; var Allow: Boolean);
|
||||||
|
begin
|
||||||
|
Unused(AWorksheet, ARow, ACol);
|
||||||
|
Unused(ASearchText, AReplaceText);
|
||||||
|
Allow := MessageDlg('Replace?', mtConfirmation, [mbYes, mbNo], 0) = mrYes;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSearchForm.Execute(AWorkbook: TsWorkbook);
|
procedure TSearchForm.Execute(AWorkbook: TsWorkbook);
|
||||||
begin
|
begin
|
||||||
FWorkbook := AWorkbook;
|
FWorkbook := AWorkbook;
|
||||||
Show;
|
Show;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSearchForm.ExecuteClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
sp: TsSearchParams;
|
||||||
|
rp: TsReplaceParams;
|
||||||
|
found: Boolean;
|
||||||
|
crs: TCursor;
|
||||||
|
begin
|
||||||
|
sp := GetSearchParams;
|
||||||
|
if sp.SearchText = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if TabControl.TabIndex = REPLACE_TAB then
|
||||||
|
rp := GetReplaceParams;
|
||||||
|
|
||||||
|
if CbSearchText.Items.IndexOf(sp.SearchText) = -1 then
|
||||||
|
begin
|
||||||
|
CbSearchText.Items.Insert(0, sp.SearchText);
|
||||||
|
while CbSearchText.Items.Count > MAX_SEARCH_ITEMS do
|
||||||
|
CbSearchText.Items.Delete(CbSearchText.Items.Count-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (TabControl.TabIndex = REPLACE_TAB) and
|
||||||
|
(CbReplaceText.Items.IndexOf(rp.ReplaceText) = -1) then
|
||||||
|
begin
|
||||||
|
CbReplaceText.items.Insert(0, rp.ReplaceText);
|
||||||
|
while CbReplaceText.Items.Count > MAX_SEARCH_ITEMS do
|
||||||
|
CbReplaceText.Items.Delete(CbReplaceText.Items.Count-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
crs := Screen.Cursor;
|
||||||
|
try
|
||||||
|
Screen.Cursor := crHourglass;
|
||||||
|
if FSearchEngine = nil then
|
||||||
|
begin
|
||||||
|
FSearchEngine := TsSearchEngine.Create(FWorkbook);
|
||||||
|
FSearchEngine.OnConfirmReplacement := @ConfirmReplacementHandler;
|
||||||
|
if (soBackward in sp.Options) then
|
||||||
|
Include(sp.Options, soBackward) else
|
||||||
|
Exclude(sp.Options, soBackward);
|
||||||
|
case Tabcontrol.TabIndex of
|
||||||
|
0: found := FSearchEngine.FindFirst(sp, FFoundWorksheet, FFoundRow, FFoundCol);
|
||||||
|
1: found := FSearchEngine.ReplaceFirst(sp, rp, FFoundWorksheet, FFoundRow, FFoundCol);
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
if (Sender = BtnSearchBack) then
|
||||||
|
Include(sp.Options, soBackward) else
|
||||||
|
Exclude(sp.Options, soBackward);
|
||||||
|
// User may select a different worksheet/different cell to continue search!
|
||||||
|
FFoundWorksheet := FWorkbook.ActiveWorksheet;
|
||||||
|
FFoundRow := FFoundWorksheet.ActiveCellRow;
|
||||||
|
FFoundCol := FFoundWorksheet.ActiveCellCol;
|
||||||
|
case TabControl.TabIndex of
|
||||||
|
0: found := FSearchEngine.FindNext(sp, FFoundWorksheet, FFoundRow, FFoundCol);
|
||||||
|
1: found := FSearchEngine.ReplaceNext(sp, rp, FFoundWorksheet, FFoundRow, FFoundCol);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
Screen.Cursor := crs;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(FOnFound) then
|
||||||
|
FOnFound(self, found, FFoundWorksheet, FFoundRow, FFoundCol);
|
||||||
|
|
||||||
|
BtnSearchBack.Visible := true;
|
||||||
|
BtnSearch.Caption := 'Next';
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSearchForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
procedure TSearchForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||||
var
|
var
|
||||||
P: TPoint;
|
P: TPoint;
|
||||||
@ -97,6 +205,7 @@ end;
|
|||||||
procedure TSearchForm.FormCreate(Sender: TObject);
|
procedure TSearchForm.FormCreate(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
Position := poMainFormCenter;
|
Position := poMainFormCenter;
|
||||||
|
PopulateOptions;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSearchForm.FormShow(Sender: TObject);
|
procedure TSearchForm.FormShow(Sender: TObject);
|
||||||
@ -109,78 +218,115 @@ begin
|
|||||||
FFoundWorksheet := nil;
|
FFoundWorksheet := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSearchForm.GetParams: TsSearchParams;
|
function TSearchForm.GetReplaceParams: TsReplaceParams;
|
||||||
|
begin
|
||||||
|
if TabControl.TabIndex = 0 then
|
||||||
|
Result := FReplaceParams
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Result.ReplaceText := CbReplaceText.Text;
|
||||||
|
Result.Options := [];
|
||||||
|
if CgOptions.Checked[REPLACE_ENTIRE_CELL] then
|
||||||
|
Include(Result.Options, roReplaceEntireCell);
|
||||||
|
if CgOptions.Checked[REPLACE_ALL] then
|
||||||
|
Include(Result.Options, roReplaceAll);
|
||||||
|
if CgOptions.Checked[CONFIRM_REPLACEMENT] then
|
||||||
|
Include(Result.Options, roConfirm);
|
||||||
|
FReplaceParams := Result;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSearchForm.GetSearchParams: TsSearchParams;
|
||||||
begin
|
begin
|
||||||
Result.SearchText := CbSearchText.Text;
|
Result.SearchText := CbSearchText.Text;
|
||||||
Result.Options := [];
|
Result.Options := [];
|
||||||
if CgSearchOptions.Checked[COMPARE_ENTIRE_CELL] then
|
if CgOptions.Checked[COMPARE_ENTIRE_CELL] then
|
||||||
Include(Result.Options, soCompareEntireCell);
|
Include(Result.Options, soCompareEntireCell);
|
||||||
if CgSearchOptions.Checked[MATCH_CASE] then
|
if CgOptions.Checked[MATCH_CASE] then
|
||||||
Include(Result.Options, soMatchCase);
|
Include(Result.Options, soMatchCase);
|
||||||
if CgSearchOptions.Checked[REGULAR_EXPRESSION] then
|
if CgOptions.Checked[REGULAR_EXPRESSION] then
|
||||||
Include(Result.Options, soRegularExpr);
|
Include(Result.Options, soRegularExpr);
|
||||||
if CgSearchOptions.Checked[SEARCH_ALONG_ROWS] then
|
if CgOptions.Checked[SEARCH_ALONG_ROWS] then
|
||||||
Include(Result.Options, soAlongRows);
|
Include(Result.Options, soAlongRows);
|
||||||
if CgSearchOptions.Checked[CONTINUE_AT_START_END] then
|
if CgOptions.Checked[CONTINUE_AT_START_END] then
|
||||||
Include(Result.Options, soWrapDocument);
|
Include(Result.Options, soWrapDocument);
|
||||||
if RgSearchStart.ItemIndex = 1 then
|
if RgSearchStart.ItemIndex = 1 then
|
||||||
Include(Result.Options, soEntireDocument);
|
Include(Result.Options, soEntireDocument);
|
||||||
Result.Within := TsSearchWithin(RgSearchWithin.ItemIndex);
|
Result.Within := TsSearchWithin(RgSearchWithin.ItemIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSearchForm.SearchButtonClick(Sender: TObject);
|
procedure TSearchForm.PopulateOptions;
|
||||||
var
|
|
||||||
params: TsSearchParams;
|
|
||||||
found: Boolean;
|
|
||||||
begin
|
begin
|
||||||
params := GetParams;
|
with CgOptions.Items do
|
||||||
if params.SearchText = '' then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
if CbSearchText.Items.IndexOf(params.SearchText) = -1 then
|
|
||||||
begin
|
begin
|
||||||
CbSearchText.Items.Insert(0, params.SearchText);
|
Clear;
|
||||||
while CbSearchText.Items.Count > MAX_SEARCH_ITEMS do
|
Add('Compare entire cell');
|
||||||
CbSearchText.Items.Delete(CbSearchText.Items.Count-1);
|
Add('Match case');
|
||||||
|
Add('Regular expression');
|
||||||
|
Add('Search along rows');
|
||||||
|
Add('Continue at start/end');
|
||||||
|
if TabControl.TabIndex = REPLACE_TAB then
|
||||||
|
begin
|
||||||
|
Add('Replace entire cell');
|
||||||
|
Add('Replace all');
|
||||||
|
Add('Confirm replacement');
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FSearchEngine = nil then
|
|
||||||
begin
|
|
||||||
FSearchEngine := TsSearchEngine.Create(FWorkbook);
|
|
||||||
if (soBackward in params.Options) then
|
|
||||||
Include(params.Options, soBackward) else
|
|
||||||
Exclude(params.Options, soBackward);
|
|
||||||
found := FSearchEngine.FindFirst(params.SearchText, params, FFoundWorksheet, FFoundRow, FFoundCol);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
if (Sender = BtnSearchBack) then
|
|
||||||
Include(params.Options, soBackward) else
|
|
||||||
Exclude(params.Options, soBackward);
|
|
||||||
// User may select a different worksheet/different cell to continue search!
|
|
||||||
FFoundWorksheet := FWorkbook.ActiveWorksheet;
|
|
||||||
FFoundRow := FFoundWorksheet.ActiveCellRow;
|
|
||||||
FFoundCol := FFoundWorksheet.ActiveCellCol;
|
|
||||||
found := FSearchEngine.FindNext(params.SearchText, params, FFoundWorksheet, FFoundRow, FFoundCol);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Assigned(FOnFound) then
|
|
||||||
FOnFound(self, found, FFoundWorksheet, FFoundRow, FFoundCol);
|
|
||||||
|
|
||||||
BtnSearchBack.Visible := true;
|
|
||||||
BtnSearch.Caption := 'Next';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSearchForm.SetParams(const AValue: TsSearchParams);
|
procedure TSearchForm.SetSearchParams(const AValue: TsSearchParams);
|
||||||
begin
|
begin
|
||||||
CbSearchText.Text := Avalue.SearchText;
|
CbSearchText.Text := Avalue.SearchText;
|
||||||
CgSearchOptions.Checked[COMPARE_ENTIRE_CELL] := (soCompareEntireCell in AValue.Options);
|
CgOptions.Checked[COMPARE_ENTIRE_CELL] := (soCompareEntireCell in AValue.Options);
|
||||||
CgSearchOptions.Checked[MATCH_CASE] := (soMatchCase in AValue.Options);
|
CgOptions.Checked[MATCH_CASE] := (soMatchCase in AValue.Options);
|
||||||
CgSearchOptions.Checked[REGULAR_EXPRESSION] := (soRegularExpr in Avalue.Options);
|
CgOptions.Checked[REGULAR_EXPRESSION] := (soRegularExpr in Avalue.Options);
|
||||||
CgSearchOptions.Checked[SEARCH_ALONG_ROWS] := (soAlongRows in AValue.Options);
|
CgOptions.Checked[SEARCH_ALONG_ROWS] := (soAlongRows in AValue.Options);
|
||||||
CgSearchOptions.Checked[CONTINUE_AT_START_END] := (soWrapDocument in Avalue.Options);
|
CgOptions.Checked[CONTINUE_AT_START_END] := (soWrapDocument in Avalue.Options);
|
||||||
RgSearchWithin.ItemIndex := ord(AValue.Within);
|
RgSearchWithin.ItemIndex := ord(AValue.Within);
|
||||||
RgSearchStart.ItemIndex := ord(soEntireDocument in AValue.Options);
|
RgSearchStart.ItemIndex := ord(soEntireDocument in AValue.Options);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSearchForm.SetReplaceParams(const AValue: TsReplaceParams);
|
||||||
|
begin
|
||||||
|
FReplaceParams := AValue;
|
||||||
|
if TabControl.TabIndex = REPLACE_TAB then
|
||||||
|
begin
|
||||||
|
CbReplaceText.Text := AValue.ReplaceText;
|
||||||
|
CgOptions.Checked[REPLACE_ENTIRE_CELL] := (roReplaceEntireCell in AValue.Options);
|
||||||
|
CgOptions.Checked[REPLACE_ALL] := (roReplaceAll in AValue.Options);
|
||||||
|
CgOptions.Checked[CONFIRM_REPLACEMENT] := (roConfirm in AValue.Options);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSearchForm.TabControlChange(Sender: TObject);
|
||||||
|
var
|
||||||
|
h, d: Integer;
|
||||||
|
begin
|
||||||
|
ReplaceTextPanel.Visible := (TabControl.TabIndex = REPLACE_TAB);
|
||||||
|
PopulateOptions;
|
||||||
|
SetSearchParams(FSearchParams);
|
||||||
|
SetReplaceParams(FReplaceParams);
|
||||||
|
h := RgSearchStart.Top + RgSearchStart.Height - CgOptions.Top;
|
||||||
|
if TabControl.TabIndex = 0 then
|
||||||
|
begin
|
||||||
|
CgOptions.Height := h;
|
||||||
|
Height := BASE_HEIGHT - ReplaceTextPanel.Height;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
d := 3 * 16;
|
||||||
|
CgOptions.Height := h + d;
|
||||||
|
Height := BASE_HEIGHT + d;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSearchForm.TabControlChanging(Sender: TObject;
|
||||||
|
var AllowChange: Boolean);
|
||||||
|
begin
|
||||||
|
AllowChange := true;
|
||||||
|
FSearchParams := GetSearchParams;
|
||||||
|
FReplaceParams := GetReplaceParams;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -737,6 +737,9 @@ type
|
|||||||
out ARow, ACol: Cardinal): Boolean;
|
out ARow, ACol: Cardinal): Boolean;
|
||||||
*)
|
*)
|
||||||
{ Utilities }
|
{ Utilities }
|
||||||
|
procedure DisableNotifications;
|
||||||
|
procedure EnableNotifications;
|
||||||
|
function NotificationsEnabled: Boolean;
|
||||||
procedure UpdateCaches;
|
procedure UpdateCaches;
|
||||||
|
|
||||||
{ Error messages }
|
{ Error messages }
|
||||||
@ -1530,7 +1533,7 @@ begin
|
|||||||
CalcFormulas;
|
CalcFormulas;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Assigned(FOnChangeCell) then
|
if FWorkbook.NotificationsEnabled and Assigned(FOnChangeCell) then
|
||||||
FOnChangeCell(Self, ARow, ACol);
|
FOnChangeCell(Self, ARow, ACol);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1543,7 +1546,7 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsWorksheet.ChangedFont(ARow, ACol: Cardinal);
|
procedure TsWorksheet.ChangedFont(ARow, ACol: Cardinal);
|
||||||
begin
|
begin
|
||||||
if FWorkbook.FReadWriteFlag = rwfRead then
|
if (FWorkbook.FReadWriteFlag = rwfRead) or not FWorkbook.NotificationsEnabled then
|
||||||
exit;
|
exit;
|
||||||
if Assigned(FOnChangeFont) then
|
if Assigned(FOnChangeFont) then
|
||||||
FOnChangeFont(Self, ARow, ACol);
|
FOnChangeFont(Self, ARow, ACol);
|
||||||
@ -3521,6 +3524,9 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsWorksheet.SelectCell(ARow, ACol: Cardinal);
|
procedure TsWorksheet.SelectCell(ARow, ACol: Cardinal);
|
||||||
begin
|
begin
|
||||||
|
if not FWorkbook.NotificationsEnabled then
|
||||||
|
exit;
|
||||||
|
|
||||||
FActiveCellRow := ARow;
|
FActiveCellRow := ARow;
|
||||||
FActiveCellCol := ACol;
|
FActiveCellCol := ACol;
|
||||||
if Assigned(FOnSelectCell) then
|
if Assigned(FOnSelectCell) then
|
||||||
@ -6361,6 +6367,31 @@ begin
|
|||||||
Result := (FSearchEngine as TsSearchEngine).FindNext(AWorksheet, ARow, ACol);
|
Result := (FSearchEngine as TsSearchEngine).FindNext(AWorksheet, ARow, ACol);
|
||||||
end;
|
end;
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Helper method to disable notification of visual controls
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsWorkbook.DisableNotifications;
|
||||||
|
begin
|
||||||
|
inc(FLockCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Helper method to enable notification of visual controls
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsWorkbook.EnableNotifications;
|
||||||
|
begin
|
||||||
|
dec(FLockCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Helper method to determine whether visual controls are notified of changes
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsWorkbook.NotificationsEnabled: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (FLockCount = 0);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Helper method to update internal caching variables
|
Helper method to update internal caching variables
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
|
@ -8,14 +8,21 @@ uses
|
|||||||
Classes, SysUtils, RegExpr, fpstypes, fpspreadsheet;
|
Classes, SysUtils, RegExpr, fpstypes, fpspreadsheet;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
TsConfirmReplacementEvent = procedure (Sender: TObject; AWorksheet: TsWorksheet;
|
||||||
|
ARow, ACol: Cardinal; const ASearchText, AReplaceText: String;
|
||||||
|
var Allow: Boolean) of object;
|
||||||
|
|
||||||
TsSearchEngine = class
|
TsSearchEngine = class
|
||||||
private
|
private
|
||||||
FWorkbook: TsWorkbook;
|
FWorkbook: TsWorkbook;
|
||||||
FSearchText: String;
|
FSearchText: String;
|
||||||
FParams: TsSearchParams;
|
FSearchParams: TsSearchParams;
|
||||||
|
FReplaceParams: TsReplaceParams;
|
||||||
FCurrSel: Integer;
|
FCurrSel: Integer;
|
||||||
FRegEx: TRegExpr;
|
FRegEx: TRegExpr;
|
||||||
|
FOnConfirmReplacement: TsConfirmReplacementEvent;
|
||||||
protected
|
protected
|
||||||
|
function ExecReplace(AWorksheet: TsWorksheet; ARow, ACol: Cardinal): boolean;
|
||||||
function ExecSearch(var AWorksheet: TsWorksheet;
|
function ExecSearch(var AWorksheet: TsWorksheet;
|
||||||
var ARow, ACol: Cardinal): Boolean;
|
var ARow, ACol: Cardinal): Boolean;
|
||||||
procedure GotoFirst(out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal);
|
procedure GotoFirst(out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal);
|
||||||
@ -34,10 +41,19 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook);
|
constructor Create(AWorkbook: TsWorkbook);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function FindFirst(const ASearchText: String; const AParams: TsSearchParams;
|
function FindFirst(const ASearchParams: TsSearchParams;
|
||||||
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
|
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
|
||||||
function FindNext(const ASearchText: String; const AParams: TsSearchParams;
|
function FindNext(const ASearchParams: TsSearchParams;
|
||||||
var AWorksheet: TsWorksheet; var ARow, ACol: Cardinal): Boolean;
|
var AWorksheet: TsWorksheet; var ARow, ACol: Cardinal): Boolean;
|
||||||
|
function ReplaceFirst(const ASearchParams: TsSearchParams;
|
||||||
|
const AReplaceParams: TsReplaceParams;
|
||||||
|
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
|
||||||
|
function ReplaceNext(const ASearchParams: TsSearchParams;
|
||||||
|
const AReplaceParams: TsReplaceParams;
|
||||||
|
var AWorksheet: TsWorksheet; var ARow, ACol: Cardinal): Boolean;
|
||||||
|
|
||||||
|
property OnConfirmReplacement: TsConfirmReplacementEvent
|
||||||
|
read FOnConfirmReplacement write FOnConfirmReplacement;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -57,6 +73,44 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSearchEngine.ExecReplace(AWorksheet: TsWorksheet; ARow, ACol: Cardinal) : Boolean;
|
||||||
|
var
|
||||||
|
res: Integer;
|
||||||
|
s: String;
|
||||||
|
allow: Boolean;
|
||||||
|
flags: TReplaceFlags;
|
||||||
|
begin
|
||||||
|
if roConfirm in FReplaceParams.Options then
|
||||||
|
begin
|
||||||
|
allow := false;
|
||||||
|
if Assigned(FOnConfirmReplacement) then
|
||||||
|
begin
|
||||||
|
FOnConfirmReplacement(self, AWorksheet, ARow, ACol,
|
||||||
|
FSearchParams.SearchText, FReplaceParams.ReplaceText, allow);
|
||||||
|
if not allow then
|
||||||
|
exit(false);
|
||||||
|
end else
|
||||||
|
raise Exception.Create('[TsSearchEngine.ExecReplace] OnConfirmReplacement handler needed.');
|
||||||
|
end;
|
||||||
|
|
||||||
|
if roReplaceEntireCell in FReplaceParams.Options then
|
||||||
|
AWorksheet.WriteCellValueAsString(ARow, ACol, FReplaceParams.ReplaceText)
|
||||||
|
else begin
|
||||||
|
s := AWorksheet.ReadAsText(ARow, ACol);
|
||||||
|
if soCompareEntireCell in FSearchParams.Options then
|
||||||
|
AWorksheet.WriteCellValueAsString(ARow, ACol, FReplaceParams.ReplaceText)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
flags := [];
|
||||||
|
if not (soMatchCase in FSearchParams.Options) then
|
||||||
|
Include(flags, rfIgnoreCase);
|
||||||
|
s := UTF8StringReplace(s, FSearchparams.SearchText, FReplaceParams.ReplaceText, flags);
|
||||||
|
AWorksheet.WritecellValueAsString(ARow, ACol, s);
|
||||||
|
// to do: RegEx to be added
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TsSearchEngine.ExecSearch(var AWorksheet: TsWorksheet;
|
function TsSearchEngine.ExecSearch(var AWorksheet: TsWorksheet;
|
||||||
var ARow, ACol: Cardinal): Boolean;
|
var ARow, ACol: Cardinal): Boolean;
|
||||||
var
|
var
|
||||||
@ -70,7 +124,7 @@ begin
|
|||||||
complete := false;
|
complete := false;
|
||||||
while (not complete) and (not Matches(AWorksheet, ARow, ACol)) do
|
while (not complete) and (not Matches(AWorksheet, ARow, ACol)) do
|
||||||
begin
|
begin
|
||||||
if soBackward in FParams.Options then
|
if soBackward in FSearchParams.Options then
|
||||||
complete := not GotoPrev(AWorkSheet, ARow, ACol) else
|
complete := not GotoPrev(AWorkSheet, ARow, ACol) else
|
||||||
complete := not GotoNext(AWorkSheet, ARow, ACol);
|
complete := not GotoNext(AWorkSheet, ARow, ACol);
|
||||||
// Avoid infinite loop if search phrase does not exist in document.
|
// Avoid infinite loop if search phrase does not exist in document.
|
||||||
@ -90,28 +144,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSearchEngine.FindFirst(const ASearchText: String;
|
function TsSearchEngine.FindFirst(const ASearchParams: TsSearchParams;
|
||||||
const AParams: TsSearchParams; out AWorksheet: TsWorksheet;
|
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
|
||||||
out ARow, ACol: Cardinal): Boolean;
|
|
||||||
begin
|
begin
|
||||||
FParams := AParams;
|
FSearchParams := ASearchParams;
|
||||||
PrepareSearchText(ASearchText);
|
PrepareSearchText(FSearchParams.SearchText);
|
||||||
|
|
||||||
if soBackward in FParams.Options then
|
if soBackward in FSearchParams.Options then
|
||||||
GotoLast(AWorksheet, ARow, ACol) else
|
GotoLast(AWorksheet, ARow, ACol) else
|
||||||
GotoFirst(AWorksheet, ARow, ACol);
|
GotoFirst(AWorksheet, ARow, ACol);
|
||||||
|
|
||||||
Result := ExecSearch(AWorksheet, ARow, ACol);
|
Result := ExecSearch(AWorksheet, ARow, ACol);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSearchEngine.FindNext(const ASearchText: String;
|
function TsSearchEngine.FindNext(const ASearchParams: TsSearchParams;
|
||||||
const AParams: TsSearchParams; var AWorksheet: TsWorksheet;
|
var AWorksheet: TsWorksheet; var ARow, ACol: Cardinal): Boolean;
|
||||||
var ARow, ACol: Cardinal): Boolean;
|
|
||||||
begin
|
begin
|
||||||
FParams := AParams;
|
FSearchParams := ASearchParams;
|
||||||
PrepareSearchText(ASearchText);
|
PrepareSearchText(FSearchParams.SearchText);
|
||||||
|
|
||||||
if soBackward in FParams.Options then
|
if soBackward in FSearchParams.Options then
|
||||||
GotoPrev(AWorksheet, ARow, ACol) else
|
GotoPrev(AWorksheet, ARow, ACol) else
|
||||||
GotoNext(AWorksheet, ARow, ACol);
|
GotoNext(AWorksheet, ARow, ACol);
|
||||||
|
|
||||||
@ -121,9 +173,9 @@ end;
|
|||||||
procedure TsSearchEngine.GotoFirst(out AWorksheet: TsWorksheet;
|
procedure TsSearchEngine.GotoFirst(out AWorksheet: TsWorksheet;
|
||||||
out ARow, ACol: Cardinal);
|
out ARow, ACol: Cardinal);
|
||||||
begin
|
begin
|
||||||
if soEntireDocument in FParams.Options then
|
if soEntireDocument in FSearchParams.Options then
|
||||||
// Search entire document forward from start
|
// Search entire document forward from start
|
||||||
case FParams.Within of
|
case FSearchParams.Within of
|
||||||
swWorkbook :
|
swWorkbook :
|
||||||
begin
|
begin
|
||||||
AWorksheet := FWorkbook.GetWorksheetByIndex(0);
|
AWorksheet := FWorkbook.GetWorksheetByIndex(0);
|
||||||
@ -153,6 +205,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Search starts at active cell
|
// Search starts at active cell
|
||||||
AWorksheet := FWorkbook.ActiveWorksheet;
|
AWorksheet := FWorkbook.ActiveWorksheet;
|
||||||
|
if AWorksheet = nil then AWorksheet := FWorkbook.GetFirstWorksheet;
|
||||||
ARow := AWorksheet.ActiveCellRow;
|
ARow := AWorksheet.ActiveCellRow;
|
||||||
ACol := AWorksheet.ActiveCellCol;
|
ACol := AWorksheet.ActiveCellCol;
|
||||||
end;
|
end;
|
||||||
@ -164,9 +217,9 @@ var
|
|||||||
cell: PCell;
|
cell: PCell;
|
||||||
sel: TsCellRangeArray;
|
sel: TsCellRangeArray;
|
||||||
begin
|
begin
|
||||||
if soEntireDocument in FParams.Options then
|
if soEntireDocument in FSearchParams.Options then
|
||||||
// Search entire document backward from end
|
// Search entire document backward from end
|
||||||
case FParams.Within of
|
case FSearchParams.Within of
|
||||||
swWorkbook :
|
swWorkbook :
|
||||||
begin
|
begin
|
||||||
AWorksheet := FWorkbook.GetWorksheetByIndex(FWorkbook.GetWorksheetCount-1);
|
AWorksheet := FWorkbook.GetWorksheetByIndex(FWorkbook.GetWorksheetCount-1);
|
||||||
@ -212,7 +265,7 @@ begin
|
|||||||
if GotoNextInWorksheet(AWorksheet, ARow, ACol) then
|
if GotoNextInWorksheet(AWorksheet, ARow, ACol) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
case FParams.Within of
|
case FSearchParams.Within of
|
||||||
swWorkbook:
|
swWorkbook:
|
||||||
begin
|
begin
|
||||||
// Need to go to next sheet
|
// Need to go to next sheet
|
||||||
@ -225,7 +278,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
// Continue search with first worksheet
|
// Continue search with first worksheet
|
||||||
if (soWrapDocument in FParams.Options) then
|
if (soWrapDocument in FSearchParams.Options) then
|
||||||
begin
|
begin
|
||||||
AWorksheet := FWorkbook.GetWorksheetByIndex(0);
|
AWorksheet := FWorkbook.GetWorksheetByIndex(0);
|
||||||
ARow := 0;
|
ARow := 0;
|
||||||
@ -235,21 +288,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
swWorksheet:
|
swWorksheet:
|
||||||
if soWrapDocument in FParams.Options then begin
|
if soWrapDocument in FSearchParams.Options then begin
|
||||||
ARow := 0;
|
ARow := 0;
|
||||||
ACol := 0;
|
ACol := 0;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
swColumn:
|
swColumn:
|
||||||
if soWrapDocument in FParams.Options then begin
|
if soWrapDocument in FSearchParams.Options then begin
|
||||||
ARow := 0;
|
ARow := 0;
|
||||||
ACol := AWorksheet.ActiveCellCol;
|
ACol := AWorksheet.ActiveCellCol;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
swRow:
|
swRow:
|
||||||
if soWrapDocument in FParams.Options then begin
|
if soWrapDocument in FSearchParams.Options then begin
|
||||||
ARow := AWorksheet.ActiveCellRow;
|
ARow := AWorksheet.ActiveCellRow;
|
||||||
ACol := 0;
|
ACol := 0;
|
||||||
exit;
|
exit;
|
||||||
@ -264,12 +317,12 @@ function TsSearchEngine.GotoNextInWorksheet(AWorksheet: TsWorksheet;
|
|||||||
var ARow, ACol: Cardinal): Boolean;
|
var ARow, ACol: Cardinal): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := true;
|
Result := true;
|
||||||
if (soAlongRows in FParams.Options) or (FParams.Within = swRow) then
|
if (soAlongRows in FSearchParams.Options) or (FSearchParams.Within = swRow) then
|
||||||
begin
|
begin
|
||||||
inc(ACol);
|
inc(ACol);
|
||||||
if ACol <= AWorksheet.GetLastColIndex then
|
if ACol <= AWorksheet.GetLastColIndex then
|
||||||
exit;
|
exit;
|
||||||
if (FParams.Within <> swRow) then
|
if (FSearchParams.Within <> swRow) then
|
||||||
begin
|
begin
|
||||||
ACol := 0;
|
ACol := 0;
|
||||||
inc(ARow);
|
inc(ARow);
|
||||||
@ -277,12 +330,12 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
if not (soAlongRows in FParams.Options) or (FParams.Within = swColumn) then
|
if not (soAlongRows in FSearchParams.Options) or (FSearchParams.Within = swColumn) then
|
||||||
begin
|
begin
|
||||||
inc(ARow);
|
inc(ARow);
|
||||||
if ARow <= AWorksheet.GetLastRowIndex then
|
if ARow <= AWorksheet.GetLastRowIndex then
|
||||||
exit;
|
exit;
|
||||||
if (FParams.Within <> swColumn) then
|
if (FSearchParams.Within <> swColumn) then
|
||||||
begin
|
begin
|
||||||
ARow := 0;
|
ARow := 0;
|
||||||
inc(ACol);
|
inc(ACol);
|
||||||
@ -305,7 +358,7 @@ begin
|
|||||||
if GotoPrevInWorksheet(AWorksheet, ARow, ACol) then
|
if GotoPrevInWorksheet(AWorksheet, ARow, ACol) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
case FParams.Within of
|
case FSearchParams.Within of
|
||||||
swWorkbook:
|
swWorkbook:
|
||||||
begin
|
begin
|
||||||
// Need to go to previous sheet
|
// Need to go to previous sheet
|
||||||
@ -317,7 +370,7 @@ begin
|
|||||||
ACol := AWorksheet.GetlastColIndex;
|
ACol := AWorksheet.GetlastColIndex;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (soWrapDocument in FParams.Options) then
|
if (soWrapDocument in FSearchParams.Options) then
|
||||||
begin
|
begin
|
||||||
AWorksheet := FWorkbook.GetWorksheetByIndex(FWorkbook.GetWorksheetCount-1);
|
AWorksheet := FWorkbook.GetWorksheetByIndex(FWorkbook.GetWorksheetCount-1);
|
||||||
ARow := AWorksheet.GetLastRowIndex;
|
ARow := AWorksheet.GetLastRowIndex;
|
||||||
@ -327,7 +380,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
swWorksheet:
|
swWorksheet:
|
||||||
if soWrapDocument in FParams.Options then
|
if soWrapDocument in FSearchParams.Options then
|
||||||
begin
|
begin
|
||||||
ARow := AWorksheet.GetLastRowIndex;
|
ARow := AWorksheet.GetLastRowIndex;
|
||||||
ACol := AWorksheet.GetLastColIndex;
|
ACol := AWorksheet.GetLastColIndex;
|
||||||
@ -335,7 +388,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
swColumn:
|
swColumn:
|
||||||
if soWrapDocument in FParams.Options then
|
if soWrapDocument in FSearchParams.Options then
|
||||||
begin
|
begin
|
||||||
ARow := AWorksheet.GetLastRowIndex;
|
ARow := AWorksheet.GetLastRowIndex;
|
||||||
ACol := AWorksheet.ActiveCellCol;
|
ACol := AWorksheet.ActiveCellCol;
|
||||||
@ -343,7 +396,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
swRow:
|
swRow:
|
||||||
if soWrapDocument in FParams.Options then
|
if soWrapDocument in FSearchParams.Options then
|
||||||
begin
|
begin
|
||||||
ARow := AWorksheet.ActiveCellRow;
|
ARow := AWorksheet.ActiveCellRow;
|
||||||
ACol := AWorksheet.GetLastColIndex;
|
ACol := AWorksheet.GetLastColIndex;
|
||||||
@ -358,13 +411,13 @@ function TsSearchEngine.GotoPrevInWorksheet(AWorksheet: TsWorksheet;
|
|||||||
var ARow, ACol: Cardinal): Boolean;
|
var ARow, ACol: Cardinal): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := true;
|
Result := true;
|
||||||
if (soAlongRows in FParams.Options) or (FParams.Within = swRow) then
|
if (soAlongRows in FSearchParams.Options) or (FSearchParams.Within = swRow) then
|
||||||
begin
|
begin
|
||||||
if ACol > 0 then begin
|
if ACol > 0 then begin
|
||||||
dec(ACol);
|
dec(ACol);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (FParams.Within <> swRow) then
|
if (FSearchParams.Within <> swRow) then
|
||||||
begin
|
begin
|
||||||
ACol := AWorksheet.GetLastColIndex;
|
ACol := AWorksheet.GetLastColIndex;
|
||||||
if ARow > 0 then
|
if ARow > 0 then
|
||||||
@ -374,13 +427,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
if not (soAlongRows in FParams.Options) or (FParams.Within = swColumn) then
|
if not (soAlongRows in FSearchParams.Options) or (FSearchParams.Within = swColumn) then
|
||||||
begin
|
begin
|
||||||
if ARow > 0 then begin
|
if ARow > 0 then begin
|
||||||
dec(ARow);
|
dec(ARow);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (FParams.Within <> swColumn) then
|
if (FSearchParams.Within <> swColumn) then
|
||||||
begin
|
begin
|
||||||
ARow := AWorksheet.GetlastRowIndex;
|
ARow := AWorksheet.GetlastRowIndex;
|
||||||
if ACol > 0 then
|
if ACol > 0 then
|
||||||
@ -404,13 +457,13 @@ begin
|
|||||||
celltxt := AWorksheet.ReadAsText(cell) else
|
celltxt := AWorksheet.ReadAsText(cell) else
|
||||||
celltxt := '';
|
celltxt := '';
|
||||||
|
|
||||||
if soRegularExpr in FParams.Options then
|
if soRegularExpr in FSearchParams.Options then
|
||||||
Result := FRegEx.Exec(celltxt)
|
Result := FRegEx.Exec(celltxt)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if not (soMatchCase in FParams.Options) then
|
if not (soMatchCase in FSearchParams.Options) then
|
||||||
celltxt := UTF8Lowercase(celltxt);
|
celltxt := UTF8Lowercase(celltxt);
|
||||||
if soCompareEntireCell in FParams.Options then
|
if soCompareEntireCell in FSearchParams.Options then
|
||||||
exit(celltxt = FSearchText);
|
exit(celltxt = FSearchText);
|
||||||
if UTF8Pos(FSearchText, celltxt) > 0 then
|
if UTF8Pos(FSearchText, celltxt) > 0 then
|
||||||
exit(true);
|
exit(true);
|
||||||
@ -420,16 +473,72 @@ end;
|
|||||||
|
|
||||||
procedure TsSearchEngine.PrepareSearchText(const ASearchText: String);
|
procedure TsSearchEngine.PrepareSearchText(const ASearchText: String);
|
||||||
begin
|
begin
|
||||||
if soRegularExpr in FParams.Options then
|
if soRegularExpr in FSearchParams.Options then
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FRegEx);
|
FreeAndNil(FRegEx);
|
||||||
FRegEx := TRegExpr.Create;
|
FRegEx := TRegExpr.Create;
|
||||||
FRegEx.Expression := ASearchText
|
FRegEx.Expression := ASearchText
|
||||||
end else
|
end else
|
||||||
if (soMatchCase in FParams.Options) then
|
if (soMatchCase in FSearchParams.Options) then
|
||||||
FSearchText := ASearchText else
|
FSearchText := ASearchText else
|
||||||
FSearchText := UTF8Lowercase(ASearchText);
|
FSearchText := UTF8Lowercase(ASearchText);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSearchEngine.ReplaceFirst(const ASearchParams: TsSearchParams;
|
||||||
|
const AReplaceParams: TsReplaceParams; out AWorksheet: TsWorksheet;
|
||||||
|
out ARow, ACol: Cardinal): Boolean;
|
||||||
|
var
|
||||||
|
r,c: Cardinal;
|
||||||
|
sheet: TsWorksheet;
|
||||||
|
begin
|
||||||
|
Result := FindFirst(ASearchParams, AWorksheet, ARow, ACol);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
FReplaceParams := AReplaceParams;
|
||||||
|
Result := ExecReplace(AWorksheet, ARow, ACol);
|
||||||
|
if roReplaceAll in FReplaceParams.Options then
|
||||||
|
begin
|
||||||
|
FWorkbook.DisableNotifications;
|
||||||
|
while FindNext(FSearchParams, AWorksheet, ARow, ACol) do
|
||||||
|
begin
|
||||||
|
r := ARow;
|
||||||
|
c := ACol;
|
||||||
|
sheet := AWorksheet;
|
||||||
|
ExecReplace(AWorksheet, ARow, ACol);
|
||||||
|
end;
|
||||||
|
FWorkbook.EnableNotifications;
|
||||||
|
sheet.SelectCell(r, c);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsSearchEngine.ReplaceNext(const ASearchParams: TsSearchParams;
|
||||||
|
const AReplaceParams: TsReplaceParams; var AWorksheet: TsWorksheet;
|
||||||
|
var ARow, ACol: Cardinal): Boolean;
|
||||||
|
var
|
||||||
|
r, c: Cardinal;
|
||||||
|
sheet: TsWorksheet;
|
||||||
|
begin
|
||||||
|
Result := FindNext(ASearchParams, AWorksheet, ARow, ACol);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
FReplaceParams := AReplaceParams;
|
||||||
|
Result := ExecReplace(AWorksheet, ARow, ACol);
|
||||||
|
if roReplaceAll in FReplaceParams.Options then
|
||||||
|
begin
|
||||||
|
FWorkbook.DisableNotifications;
|
||||||
|
while FindNext(FSearchParams, AWorksheet, ARow, ACol) do
|
||||||
|
begin
|
||||||
|
r := ARow;
|
||||||
|
c := ACol;
|
||||||
|
sheet := AWorksheet;
|
||||||
|
ExecReplace(AWorksheet, ARow, ACol);
|
||||||
|
end;
|
||||||
|
FWorkbook.EnableNotifications;
|
||||||
|
sheet.SelectCell(r, c);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -724,6 +724,19 @@ type
|
|||||||
Within: TsSearchWithin;
|
Within: TsSearchWithin;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ Replace option }
|
||||||
|
TsReplaceOption = (roReplaceEntirecell, roReplaceAll, roConfirm);
|
||||||
|
|
||||||
|
{@@ A set of replace options }
|
||||||
|
TsReplaceOptions = set of TsReplaceOption;
|
||||||
|
|
||||||
|
{@@ Replace parameters }
|
||||||
|
TsReplaceParams = record
|
||||||
|
ReplaceText: String;
|
||||||
|
Options: TsReplaceOptions;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user