mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 11:17:57 +08:00
Issue #1482: text editor dialog and customize highlighter dialog
This commit is contained in:
14
heidisql.lpi
14
heidisql.lpi
@ -250,6 +250,20 @@
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="source\texteditor.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="frmTextEditor"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="source\customize_highlighter.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="frmCustomizeHighlighter"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -19,8 +19,8 @@ uses
|
||||
dbstructures.sqlite, change_password, loginform, data_sorting, extra_controls,
|
||||
column_selection, loaddata, csv_detector, createdatabase, editvar, copytable,
|
||||
exportgrid, usermanager, selectdbobject, reformatter, searchreplace,
|
||||
connections, jsonregistry, sqlhelp, updatecheck, insertfiles {, printlist (EnablePrint not defined) }
|
||||
;
|
||||
connections, jsonregistry, sqlhelp, updatecheck, insertfiles, texteditor,
|
||||
customize_highlighter;
|
||||
|
||||
{$R *.res}
|
||||
{.$R resources.rc}
|
||||
|
147
source/customize_highlighter.lfm
Normal file
147
source/customize_highlighter.lfm
Normal file
@ -0,0 +1,147 @@
|
||||
object frmCustomizeHighlighter: TfrmCustomizeHighlighter
|
||||
Left = 0
|
||||
Height = 311
|
||||
Top = 0
|
||||
Width = 551
|
||||
BorderStyle = bsDialog
|
||||
Caption = 'Customize highlighter'
|
||||
ClientHeight = 311
|
||||
ClientWidth = 551
|
||||
Color = clBtnFace
|
||||
DesignTimePPI = 120
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -15
|
||||
Font.Name = 'Segoe UI'
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
Position = poOwnerFormCenter
|
||||
object lblBackground: TLabel
|
||||
Left = 199
|
||||
Height = 20
|
||||
Top = 46
|
||||
Width = 82
|
||||
Caption = 'Background:'
|
||||
end
|
||||
object lblForeground: TLabel
|
||||
Left = 199
|
||||
Height = 20
|
||||
Top = 81
|
||||
Width = 80
|
||||
Caption = 'Foreground:'
|
||||
end
|
||||
object lblStyle: TLabel
|
||||
Left = 199
|
||||
Height = 20
|
||||
Top = 112
|
||||
Width = 35
|
||||
Caption = 'Style:'
|
||||
end
|
||||
object comboHighlighter: TComboBox
|
||||
Left = 10
|
||||
Height = 28
|
||||
Top = 10
|
||||
Width = 181
|
||||
ItemHeight = 20
|
||||
Sorted = True
|
||||
Style = csDropDownList
|
||||
TabOrder = 0
|
||||
OnSelect = comboHighlighterSelect
|
||||
end
|
||||
object listboxAttributes: TListBox
|
||||
Left = 10
|
||||
Height = 216
|
||||
Top = 46
|
||||
Width = 181
|
||||
ItemHeight = 0
|
||||
TabOrder = 1
|
||||
OnClick = listboxAttributesClick
|
||||
end
|
||||
object chkBold: TCheckBox
|
||||
Left = 346
|
||||
Height = 24
|
||||
Top = 112
|
||||
Width = 195
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
Caption = 'Bold'
|
||||
TabOrder = 4
|
||||
OnClick = Modified
|
||||
end
|
||||
object chkItalic: TCheckBox
|
||||
Left = 346
|
||||
Height = 24
|
||||
Top = 141
|
||||
Width = 195
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
Caption = 'Italic'
|
||||
TabOrder = 5
|
||||
OnClick = Modified
|
||||
end
|
||||
object btnCancel: TButton
|
||||
Left = 346
|
||||
Height = 31
|
||||
Top = 270
|
||||
Width = 94
|
||||
Anchors = [akRight, akBottom]
|
||||
Cancel = True
|
||||
Caption = 'Cancel'
|
||||
ModalResult = 2
|
||||
TabOrder = 7
|
||||
end
|
||||
object btnOK: TButton
|
||||
Left = 245
|
||||
Height = 31
|
||||
Top = 270
|
||||
Width = 94
|
||||
Anchors = [akRight, akBottom]
|
||||
Caption = 'OK'
|
||||
Default = True
|
||||
ModalResult = 1
|
||||
TabOrder = 6
|
||||
OnClick = SaveSettings
|
||||
end
|
||||
object editBackground: TEditButton
|
||||
Left = 346
|
||||
Height = 28
|
||||
Top = 42
|
||||
Width = 195
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ButtonHint = 'Color picker'
|
||||
ButtonWidth = 29
|
||||
Images = MainForm.ImageListIcons8
|
||||
ImageIndex = 33
|
||||
MaxLength = 0
|
||||
NumGlyphs = 1
|
||||
OnButtonClick = editColorRightButtonClick
|
||||
OnExit = Modified
|
||||
PasswordChar = #0
|
||||
TabOrder = 2
|
||||
end
|
||||
object editForeground: TEditButton
|
||||
Left = 346
|
||||
Height = 28
|
||||
Top = 78
|
||||
Width = 195
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ButtonHint = 'Color picker'
|
||||
ButtonWidth = 29
|
||||
Images = MainForm.ImageListIcons8
|
||||
ImageIndex = 33
|
||||
MaxLength = 0
|
||||
NumGlyphs = 1
|
||||
OnButtonClick = editColorRightButtonClick
|
||||
OnExit = Modified
|
||||
PasswordChar = #0
|
||||
TabOrder = 3
|
||||
end
|
||||
object btnApply: TButton
|
||||
Left = 447
|
||||
Height = 31
|
||||
Top = 270
|
||||
Width = 94
|
||||
Anchors = [akRight, akBottom]
|
||||
Caption = 'Apply'
|
||||
TabOrder = 8
|
||||
OnClick = SaveSettings
|
||||
end
|
||||
end
|
198
source/customize_highlighter.pas
Normal file
198
source/customize_highlighter.pas
Normal file
@ -0,0 +1,198 @@
|
||||
unit customize_highlighter;
|
||||
|
||||
{$mode delphi}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Variants, Classes, Graphics, EditBtn,
|
||||
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, GraphUtil, Math,
|
||||
StrUtils, SynEditHighlighter, apphelpers, extra_controls;
|
||||
|
||||
type
|
||||
TfrmCustomizeHighlighter = class(TExtForm)
|
||||
comboHighlighter: TComboBox;
|
||||
listboxAttributes: TListBox;
|
||||
lblBackground: TLabel;
|
||||
lblForeground: TLabel;
|
||||
lblStyle: TLabel;
|
||||
chkBold: TCheckBox;
|
||||
chkItalic: TCheckBox;
|
||||
btnCancel: TButton;
|
||||
btnOK: TButton;
|
||||
editBackground: TEditButton;
|
||||
editForeground: TEditButton;
|
||||
btnApply: TButton;
|
||||
procedure listboxAttributesClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure comboHighlighterSelect(Sender: TObject);
|
||||
procedure SaveSettings(Sender: TObject);
|
||||
procedure editColorRightButtonClick(Sender: TObject);
|
||||
procedure Modified(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
{ Private-Deklarationen }
|
||||
FHighlighter: TSynCustomHighlighter;
|
||||
FAttr: TSynHighlighterAttributes;
|
||||
FOnChange: TNotifyEvent;
|
||||
procedure SetFriendlyLanguageName(FriendlyLanguageName: String);
|
||||
function GetFriendlyLanguageName: String;
|
||||
public
|
||||
{ Public-Deklarationen }
|
||||
property FriendlyLanguageName: String read GetFriendlyLanguageName write SetFriendlyLanguageName;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses main;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
procedure TfrmCustomizeHighlighter.SaveSettings(Sender: TObject);
|
||||
begin
|
||||
// Save highlighter settings
|
||||
FHighlighter.SaveToFile(AppSettings.DirnameHighlighters + FHighlighter.LanguageName + '.ini');
|
||||
if Assigned(FOnChange) then
|
||||
FOnChange(Self);
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.Modified(Sender: TObject);
|
||||
begin
|
||||
// Apply modification to current attribute
|
||||
// Silence exception caused by invalid color strings
|
||||
FAttr.Background := StringToColorDef(editBackground.Text, clNone);
|
||||
FAttr.Foreground := StringToColorDef(editForeground.Text, clNone);
|
||||
if chkBold.Checked then
|
||||
FAttr.Style := FAttr.Style + [fsBold]
|
||||
else
|
||||
FAttr.Style := FAttr.Style - [fsBold];
|
||||
if chkItalic.Checked then
|
||||
FAttr.Style := FAttr.Style + [fsItalic]
|
||||
else
|
||||
FAttr.Style := FAttr.Style - [fsItalic];
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.comboHighlighterSelect(Sender: TObject);
|
||||
var
|
||||
i: Integer;
|
||||
Highlighters: TSynHighlighterList;
|
||||
h: TSynCustomHighlighterClass;
|
||||
begin
|
||||
// Highlighter selected
|
||||
listboxAttributes.Clear;
|
||||
if Assigned(FHighlighter) then
|
||||
FHighlighter.Free;
|
||||
Highlighters := SynEditHighlighter.GetPlaceableHighlighters;
|
||||
for i:=0 to Highlighters.Count-1 do begin
|
||||
if Highlighters[i].GetLanguageName = comboHighlighter.Text then begin
|
||||
FHighlighter := Highlighters[i].Create(Self);
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
FHighlighter.LoadFromFile(AppSettings.DirnameHighlighters + FHighlighter.GetLanguageName + '.ini');
|
||||
for i:=0 to FHighlighter.AttrCount-1 do begin
|
||||
listboxAttributes.Items.Add(FHighlighter.Attribute[i].Name);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.editColorRightButtonClick(
|
||||
Sender: TObject);
|
||||
var
|
||||
Dialog: TColorDialog;
|
||||
Edit: TEditButton;
|
||||
begin
|
||||
// Color picker
|
||||
Edit := Sender as TEditButton;
|
||||
Dialog := TColorDialog.Create(Self);
|
||||
//Dialog.Options := [cdFullOpen, cdAnyColor];
|
||||
Dialog.Color := StringToColorDef(Edit.Text, clNone);
|
||||
if Dialog.Execute then begin
|
||||
Edit.Text := ColorToString(Dialog.Color);
|
||||
end;
|
||||
Dialog.Free;
|
||||
Modified(Sender);
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.FormCreate(Sender: TObject);
|
||||
var
|
||||
Highlighters: TSynHighlighterList;
|
||||
i: Integer;
|
||||
begin
|
||||
// Form created
|
||||
FHighlighter := nil;
|
||||
FAttr := nil;
|
||||
FOnChange := nil;
|
||||
Highlighters := SynEditHighlighter.GetPlaceableHighlighters;
|
||||
for i:=0 to Highlighters.Count-1 do begin
|
||||
comboHighlighter.Items.Add(Highlighters[i].GetLanguageName);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
// Form destroyed
|
||||
if Assigned(FHighlighter) then
|
||||
FHighlighter.Free;
|
||||
// causes an exception when closing:
|
||||
//if Assigned(FAttr) then
|
||||
// FAttr.Free;
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.FormShow(Sender: TObject);
|
||||
begin
|
||||
// Ensure controls are disabled as long as no attribute is selected
|
||||
listboxAttributes.OnClick(Sender);
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.listboxAttributesClick(Sender: TObject);
|
||||
var
|
||||
i: Integer;
|
||||
AttrSelected: Boolean;
|
||||
begin
|
||||
// Attribute selected
|
||||
FAttr := nil;
|
||||
if listboxAttributes.ItemIndex > -1 then begin
|
||||
for i:=0 to FHighlighter.AttrCount-1 do begin
|
||||
if listboxAttributes.Items[listboxAttributes.ItemIndex] = FHighlighter.Attribute[i].Name then begin
|
||||
FAttr := FHighlighter.Attribute[i];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
// Enable/disable controls
|
||||
AttrSelected := FAttr <> nil;
|
||||
editBackground.Enabled := AttrSelected;
|
||||
editForeground.Enabled := AttrSelected;
|
||||
chkBold.Enabled := AttrSelected;
|
||||
chkItalic.Enabled := AttrSelected;
|
||||
// Overtake values
|
||||
if AttrSelected then begin
|
||||
editBackground.Text := IfThen(FAttr.Background <> clNone, ColorToString(FAttr.Background), '');
|
||||
editForeground.Text := IfThen(FAttr.Foreground <> clNone, ColorToString(FAttr.Foreground), '');
|
||||
chkBold.Checked := fsBold in FAttr.Style;
|
||||
chkItalic.Checked := fsItalic in FAttr.Style;
|
||||
end
|
||||
else begin
|
||||
editBackground.Text := '';
|
||||
editForeground.Text := '';
|
||||
chkBold.Checked := False;
|
||||
chkItalic.Checked := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmCustomizeHighlighter.SetFriendlyLanguageName(FriendlyLanguageName: String);
|
||||
begin
|
||||
// Set current highlighter by its language name
|
||||
comboHighlighter.ItemIndex := comboHighlighter.Items.IndexOf(FriendlyLanguageName);
|
||||
comboHighlighter.OnSelect(comboHighlighter);
|
||||
end;
|
||||
|
||||
function TfrmCustomizeHighlighter.GetFriendlyLanguageName: String;
|
||||
begin
|
||||
Result := FHighlighter.GetLanguageName;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
@ -1418,7 +1418,7 @@ implementation
|
||||
uses
|
||||
FileInfo, winpeimagereader, elfreader, machoreader, About, data_sorting, column_selection, loaddata, editvar,
|
||||
copytable, csv_detector, exportgrid, usermanager, selectdbobject, reformatter, connections, sqlhelp, updatecheck,
|
||||
insertfiles;
|
||||
insertfiles, texteditor;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
@ -12995,9 +12995,9 @@ begin
|
||||
end;
|
||||
if (not Assigned(Result)) and QueryTabs.HasActiveTab then
|
||||
Result := QueryTabs.ActiveMemo;
|
||||
//if (not Assigned(Result)) and (Screen.ActiveForm is TfrmTextEditor) then begin
|
||||
// Result := TfrmTextEditor(Screen.ActiveForm).MemoText;
|
||||
//end;
|
||||
if (not Assigned(Result)) and (Screen.ActiveForm is TfrmTextEditor) then begin
|
||||
Result := TfrmTextEditor(Screen.ActiveForm).MemoText;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
@ -8,7 +8,7 @@ uses
|
||||
SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls,
|
||||
ExtCtrls, SynEdit, SynEditTypes, laz.VirtualTrees, RegExpr,
|
||||
SynEditRegexSearch, SynEditMiscClasses, SynEditSearch, extra_controls,
|
||||
Menus{, texteditor};
|
||||
Menus, texteditor;
|
||||
|
||||
type
|
||||
TfrmSearchReplace = class(TExtForm)
|
||||
@ -123,7 +123,7 @@ begin
|
||||
AnySynMemo := MainForm.ActiveSynMemo(True);
|
||||
if Assigned(AnySynMemo) then begin
|
||||
IsEditorWritable := not AnySynMemo.ReadOnly; // Support views and procedure editors
|
||||
IsGridTextEditor := False; //GetParentForm(AnySynMemo) is TfrmTextEditor; // Support grid text editor, read-only or not
|
||||
IsGridTextEditor := GetParentForm(AnySynMemo) is TfrmTextEditor; // Support grid text editor, read-only or not
|
||||
if IsEditorWritable or IsGridTextEditor then
|
||||
UsedSynMemo := AnySynMemo;
|
||||
end;
|
||||
|
316
source/texteditor.lfm
Normal file
316
source/texteditor.lfm
Normal file
@ -0,0 +1,316 @@
|
||||
object frmTextEditor: TfrmTextEditor
|
||||
Left = 0
|
||||
Height = 191
|
||||
Top = 0
|
||||
Width = 602
|
||||
Caption = 'Text editor'
|
||||
ClientHeight = 191
|
||||
ClientWidth = 602
|
||||
Color = clBtnFace
|
||||
Constraints.MinHeight = 125
|
||||
Constraints.MinWidth = 375
|
||||
DesignTimePPI = 120
|
||||
OnClose = FormClose
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '3.8.0.0'
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 28
|
||||
Top = 125
|
||||
Width = 472
|
||||
Align = alBottom
|
||||
BevelOuter = bvNone
|
||||
Caption = 'Panel1'
|
||||
ClientHeight = 28
|
||||
ClientWidth = 472
|
||||
ParentBackground = False
|
||||
TabOrder = 0
|
||||
object lblTextLength: TLabel
|
||||
Left = 409
|
||||
Height = 16
|
||||
Top = 3
|
||||
Width = 76
|
||||
Align = alLeft
|
||||
Caption = 'lblTextLength'
|
||||
Layout = tlCenter
|
||||
ParentBidiMode = False
|
||||
end
|
||||
object tlbStandard: TToolBar
|
||||
Left = 0
|
||||
Height = 22
|
||||
Top = 0
|
||||
Width = 261
|
||||
Align = alLeft
|
||||
AutoSize = True
|
||||
Caption = 'tlbStandard'
|
||||
ParentShowHint = False
|
||||
ShowHint = True
|
||||
TabOrder = 0
|
||||
Wrapable = False
|
||||
object btnWrap: TToolButton
|
||||
Left = 0
|
||||
Hint = 'Wrap long lines'
|
||||
Top = 0
|
||||
Caption = 'Wrap long lines'
|
||||
ImageIndex = 62
|
||||
OnClick = btnWrapClick
|
||||
end
|
||||
object btnLinebreaks: TToolButton
|
||||
Left = 29
|
||||
Top = 0
|
||||
Caption = 'Linebreaks'
|
||||
DropdownMenu = popupLinebreaks
|
||||
ImageIndex = 123
|
||||
Style = tbsDropDown
|
||||
end
|
||||
object btnLoadText: TToolButton
|
||||
Left = 81
|
||||
Hint = 'Load textfile'
|
||||
Top = 0
|
||||
Caption = 'Load textfile'
|
||||
ImageIndex = 52
|
||||
OnClick = btnLoadTextClick
|
||||
end
|
||||
object btnCancel: TToolButton
|
||||
Left = 110
|
||||
Hint = 'Cancel'
|
||||
Top = 0
|
||||
Caption = 'Cancel'
|
||||
ImageIndex = 26
|
||||
OnClick = btnCancelClick
|
||||
end
|
||||
object btnApply: TToolButton
|
||||
Left = 139
|
||||
Hint = 'Apply changes'
|
||||
Top = 0
|
||||
Caption = 'Apply changes'
|
||||
ImageIndex = 55
|
||||
OnClick = btnApplyClick
|
||||
end
|
||||
object btnSeparator1: TToolButton
|
||||
Left = 168
|
||||
Top = 0
|
||||
Width = 10
|
||||
Caption = 'btnSeparator1'
|
||||
ImageIndex = 60
|
||||
Style = tbsSeparator
|
||||
end
|
||||
object btnSearchFind: TToolButton
|
||||
Left = 178
|
||||
Top = 0
|
||||
Action = MainForm.actQueryFind
|
||||
end
|
||||
object btnSearchFindNext: TToolButton
|
||||
Left = 206
|
||||
Top = 0
|
||||
Action = MainForm.actQueryFindAgain
|
||||
end
|
||||
object btnSearchReplace: TToolButton
|
||||
Left = 235
|
||||
Top = 0
|
||||
Action = MainForm.actQueryReplace
|
||||
end
|
||||
object ToolButton1: TToolButton
|
||||
Left = 264
|
||||
Top = 0
|
||||
Width = 10
|
||||
Caption = 'ToolButton1'
|
||||
ImageIndex = 60
|
||||
Style = tbsSeparator
|
||||
end
|
||||
object btnCustomizeHighlighter: TToolButton
|
||||
Left = 274
|
||||
Top = 0
|
||||
Caption = 'Customize highlighter'
|
||||
DropdownMenu = popupHighlighter
|
||||
ImageIndex = 39
|
||||
OnClick = btnCustomizeHighlighterClick
|
||||
Style = tbsDropDown
|
||||
end
|
||||
end
|
||||
object comboHighlighter: TComboBox
|
||||
Left = 261
|
||||
Height = 22
|
||||
Top = 0
|
||||
Width = 181
|
||||
Align = alLeft
|
||||
ItemHeight = 0
|
||||
Sorted = True
|
||||
Style = csDropDownList
|
||||
TabOrder = 1
|
||||
OnSelect = comboHighlighterSelect
|
||||
end
|
||||
end
|
||||
inline MemoText: TSynEdit
|
||||
Left = 0
|
||||
Height = 131
|
||||
Top = 0
|
||||
Width = 482
|
||||
Align = alClient
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Courier New'
|
||||
Font.Pitch = fpFixed
|
||||
Font.Quality = fqNonAntialiased
|
||||
ParentColor = False
|
||||
ParentFont = False
|
||||
PopupMenu = popupEditor
|
||||
TabOrder = 1
|
||||
OnClick = MemoTextClick
|
||||
OnKeyDown = MemoTextKeyDown
|
||||
Gutter.Width = 72
|
||||
Gutter.MouseActions = <>
|
||||
RightGutter.Width = 0
|
||||
RightGutter.MouseActions = <>
|
||||
Keystrokes = <>
|
||||
MouseActions = <>
|
||||
MouseTextActions = <>
|
||||
MouseSelActions = <>
|
||||
Lines.Strings = (
|
||||
'MemoText'
|
||||
)
|
||||
Options = [eoAutoIndent, eoGroupUndo, eoShowScrollHint, eoSmartTabs, eoTabIndent, eoTabsToSpaces, eoDragDropEditing]
|
||||
MouseOptions = [emDragDropEditing]
|
||||
VisibleSpecialChars = [vscSpace, vscTabAtLast]
|
||||
RightEdge = 0
|
||||
SelectedColor.BackPriority = 50
|
||||
SelectedColor.ForePriority = 50
|
||||
SelectedColor.FramePriority = 50
|
||||
SelectedColor.BoldPriority = 50
|
||||
SelectedColor.ItalicPriority = 50
|
||||
SelectedColor.UnderlinePriority = 50
|
||||
SelectedColor.StrikeOutPriority = 50
|
||||
BracketHighlightStyle = sbhsBoth
|
||||
BracketMatchColor.Background = clNone
|
||||
BracketMatchColor.Foreground = clNone
|
||||
BracketMatchColor.Style = [fsBold]
|
||||
FoldedCodeColor.Background = clNone
|
||||
FoldedCodeColor.Foreground = clGray
|
||||
FoldedCodeColor.FrameColor = clGray
|
||||
MouseLinkColor.Background = clNone
|
||||
MouseLinkColor.Foreground = clBlue
|
||||
LineHighlightColor.Background = clNone
|
||||
LineHighlightColor.Foreground = clNone
|
||||
OnChange = MemoTextChange
|
||||
inline SynLeftGutterPartList1: TSynGutterPartList
|
||||
object SynGutterMarks1: TSynGutterMarks
|
||||
Width = 30
|
||||
MouseActions = <>
|
||||
end
|
||||
object SynGutterLineNumber1: TSynGutterLineNumber
|
||||
Width = 21
|
||||
MouseActions = <>
|
||||
MarkupInfo.Background = clBtnFace
|
||||
MarkupInfo.Foreground = clNone
|
||||
DigitCount = 2
|
||||
ShowOnlyLineNumbersMultiplesOf = 1
|
||||
ZeroStart = False
|
||||
LeadingZeros = False
|
||||
end
|
||||
object SynGutterChanges1: TSynGutterChanges
|
||||
Width = 5
|
||||
MouseActions = <>
|
||||
ModifiedColor = 59900
|
||||
SavedColor = clGreen
|
||||
end
|
||||
object SynGutterSeparator1: TSynGutterSeparator
|
||||
Width = 3
|
||||
MouseActions = <>
|
||||
MarkupInfo.Background = clWhite
|
||||
MarkupInfo.Foreground = clGray
|
||||
end
|
||||
object SynGutterCodeFolding1: TSynGutterCodeFolding
|
||||
Width = 13
|
||||
MouseActions = <>
|
||||
MarkupInfo.Background = clNone
|
||||
MarkupInfo.Foreground = clGray
|
||||
MouseActionsExpanded = <>
|
||||
MouseActionsCollapsed = <>
|
||||
end
|
||||
end
|
||||
end
|
||||
object popupLinebreaks: TPopupMenu
|
||||
Left = 10
|
||||
Top = 20
|
||||
object menuWindowsLB: TMenuItem
|
||||
Caption = 'Windows linebreaks'
|
||||
ImageIndex = 123
|
||||
OnClick = SelectLinebreaks
|
||||
end
|
||||
object menuUnixLB: TMenuItem
|
||||
Caption = 'UNIX linebreaks'
|
||||
ImageIndex = 125
|
||||
OnClick = SelectLinebreaks
|
||||
end
|
||||
object menuMacLB: TMenuItem
|
||||
Caption = 'Mac OS linebreaks'
|
||||
ImageIndex = 124
|
||||
OnClick = SelectLinebreaks
|
||||
end
|
||||
object menuWideLB: TMenuItem
|
||||
Caption = 'Unicode linebreaks'
|
||||
ImageIndex = 68
|
||||
OnClick = SelectLinebreaks
|
||||
end
|
||||
object menuMixedLB: TMenuItem
|
||||
Caption = 'Mixed linebreaks'
|
||||
ImageIndex = 122
|
||||
OnClick = SelectLinebreaks
|
||||
end
|
||||
end
|
||||
object TimerMemoChange: TTimer
|
||||
Interval = 200
|
||||
OnTimer = TimerMemoChangeTimer
|
||||
Left = 150
|
||||
Top = 20
|
||||
end
|
||||
object popupEditor: TPopupMenu
|
||||
Left = 300
|
||||
Top = 20
|
||||
object Selectall1: TMenuItem
|
||||
Action = MainForm.actSelectAll
|
||||
end
|
||||
object Copy1: TMenuItem
|
||||
Action = MainForm.actCopy
|
||||
end
|
||||
object Paste1: TMenuItem
|
||||
Action = MainForm.actPaste
|
||||
end
|
||||
object Undo1: TMenuItem
|
||||
Action = MainForm.actUndo
|
||||
end
|
||||
object N1: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object Findtext1: TMenuItem
|
||||
Action = MainForm.actQueryFind
|
||||
end
|
||||
object Findorreplaceagain1: TMenuItem
|
||||
Action = MainForm.actQueryFindAgain
|
||||
end
|
||||
object Replacetext1: TMenuItem
|
||||
Action = MainForm.actQueryReplace
|
||||
end
|
||||
end
|
||||
object popupHighlighter: TPopupMenu
|
||||
Left = 440
|
||||
Top = 40
|
||||
object menuCustomizeHighlighter: TMenuItem
|
||||
Caption = 'Customize highlighter'
|
||||
ImageIndex = 39
|
||||
OnClick = btnCustomizeHighlighterClick
|
||||
end
|
||||
object menuFormatCodeOnce: TMenuItem
|
||||
Caption = 'Format code once'
|
||||
OnClick = menuFormatCodeOnceClick
|
||||
end
|
||||
object menuAlwaysFormatCode: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = 'Always format code'
|
||||
OnClick = menuAlwaysFormatCodeClick
|
||||
end
|
||||
end
|
||||
end
|
539
source/texteditor.pas
Normal file
539
source/texteditor.pas
Normal file
@ -0,0 +1,539 @@
|
||||
unit texteditor;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Graphics, Forms, Controls, StdCtrls, laz.VirtualTrees,
|
||||
ComCtrls, ToolWin, Dialogs, SysUtils, Menus, ExtDlgs, LCLType,
|
||||
apphelpers, ActnList, extra_controls,
|
||||
ExtCtrls, dbconnection, SynEdit, SynEditHighlighter, customize_highlighter,
|
||||
reformatter,
|
||||
|
||||
SynHighlighterBat,
|
||||
SynHighlighterCpp, SynHighlighterCss,
|
||||
SynHighlighterHashEntries, SynHighlighterHtml,
|
||||
SynHighlighterIni, SynHighlighterJScript,
|
||||
SynHighlighterJava,
|
||||
SynHighlighterPHP, SynHighlighterPas, SynHighlighterPerl,
|
||||
SynHighlighterPython,
|
||||
SynHighlighterSQL,
|
||||
SynHighlighterTeX, SynHighlighterUNIXShellScript,
|
||||
SynHighlighterVB,
|
||||
SynHighlighterXML
|
||||
;
|
||||
|
||||
{$I const.inc}
|
||||
|
||||
type
|
||||
TfrmTextEditor = class(TExtForm)
|
||||
Panel1: TPanel;
|
||||
tlbStandard: TToolBar;
|
||||
btnWrap: TToolButton;
|
||||
btnLoadText: TToolButton;
|
||||
btnApply: TToolButton;
|
||||
btnCancel: TToolButton;
|
||||
lblTextLength: TLabel;
|
||||
btnLinebreaks: TToolButton;
|
||||
popupLinebreaks: TPopupMenu;
|
||||
menuWindowsLB: TMenuItem;
|
||||
menuUnixLB: TMenuItem;
|
||||
menuMacLB: TMenuItem;
|
||||
menuMixedLB: TMenuItem;
|
||||
menuWideLB: TMenuItem;
|
||||
btnSearchFind: TToolButton;
|
||||
btnSearchReplace: TToolButton;
|
||||
btnSearchFindNext: TToolButton;
|
||||
btnSeparator1: TToolButton;
|
||||
TimerMemoChange: TTimer;
|
||||
comboHighlighter: TComboBox;
|
||||
MemoText: TSynEdit;
|
||||
popupEditor: TPopupMenu;
|
||||
Copy1: TMenuItem;
|
||||
Paste1: TMenuItem;
|
||||
Selectall1: TMenuItem;
|
||||
Undo1: TMenuItem;
|
||||
Findtext1: TMenuItem;
|
||||
Findorreplaceagain1: TMenuItem;
|
||||
Replacetext1: TMenuItem;
|
||||
N1: TMenuItem;
|
||||
ToolButton1: TToolButton;
|
||||
btnCustomizeHighlighter: TToolButton;
|
||||
popupHighlighter: TPopupMenu;
|
||||
menuCustomizeHighlighter: TMenuItem;
|
||||
menuFormatCodeOnce: TMenuItem;
|
||||
menuAlwaysFormatCode: TMenuItem;
|
||||
procedure btnApplyClick(Sender: TObject);
|
||||
procedure btnCancelClick(Sender: TObject);
|
||||
procedure btnLoadTextClick(Sender: TObject);
|
||||
procedure btnWrapClick(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure MemoTextChange(Sender: TObject);
|
||||
procedure MemoTextKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure MemoTextClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
||||
procedure SelectLinebreaks(Sender: TObject);
|
||||
procedure TimerMemoChangeTimer(Sender: TObject);
|
||||
procedure comboHighlighterSelect(Sender: TObject);
|
||||
procedure btnCustomizeHighlighterClick(Sender: TObject);
|
||||
procedure menuFormatCodeOnceClick(Sender: TObject);
|
||||
procedure menuAlwaysFormatCodeClick(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
FModified: Boolean;
|
||||
FClosingByApplyButton: Boolean;
|
||||
FClosingByCancelButton: Boolean;
|
||||
FDetectedLineBreaks,
|
||||
FSelectedLineBreaks: TLineBreaks;
|
||||
FMaxLength: Integer;
|
||||
FTableColumn: TTableColumn;
|
||||
FHighlighter: TSynCustomHighlighter;
|
||||
FHighlighterFormatters: TStringList;
|
||||
procedure SetModified(NewVal: Boolean);
|
||||
procedure CustomizeHighlighterChanged(Sender: TObject);
|
||||
public
|
||||
function GetText: String;
|
||||
procedure SetText(text: String);
|
||||
procedure SetTitleText(Title: String);
|
||||
procedure SetMaxLength(len: integer);
|
||||
procedure SetFont(font: TFont);
|
||||
property Modified: Boolean read FModified write SetModified;
|
||||
property TableColumn: TTableColumn read FTableColumn write FTableColumn;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses main;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
|
||||
function TfrmTextEditor.GetText: String;
|
||||
var
|
||||
LB: String;
|
||||
begin
|
||||
Result := MemoText.Text;
|
||||
// Convert linebreaks back to selected
|
||||
LB := GetLineBreak(FSelectedLineBreaks);
|
||||
if LB <> CRLF then
|
||||
Result := StringReplace(Result, CRLF, LB, [rfReplaceAll]);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.SetText(text: String);
|
||||
var
|
||||
Detected, Item: TMenuItem;
|
||||
begin
|
||||
// Apply text string, and detect type of line breaks in it
|
||||
FDetectedLineBreaks := ScanLineBreaks(text);
|
||||
Detected := nil;
|
||||
if FDetectedLineBreaks = lbsNone then
|
||||
FDetectedLineBreaks := TLineBreaks(AppSettings.ReadInt(asLineBreakStyle));
|
||||
for Item in popupLinebreaks.Items do begin
|
||||
if Item.Tag = Integer(FDetectedLineBreaks) then begin
|
||||
Detected := Item;
|
||||
end;
|
||||
end;
|
||||
if Assigned(Detected) then
|
||||
SelectLineBreaks(Detected);
|
||||
if (Length(text) > SIZE_MB) then begin
|
||||
MainForm.LogSQL(_('Auto-disabling wordwrap for large text'));
|
||||
btnWrap.Enabled := False;
|
||||
end else begin
|
||||
btnWrap.Enabled := True;
|
||||
end;
|
||||
|
||||
MemoText.Text := text;
|
||||
MemoText.SelectAll;
|
||||
Modified := False;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.SetTitleText(Title: String);
|
||||
begin
|
||||
// Add column name to window title bar
|
||||
if Title <> '' then
|
||||
Caption := Title + ' - ' + Caption;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.TimerMemoChangeTimer(Sender: TObject);
|
||||
var
|
||||
MaxLen, CursorPos: String;
|
||||
begin
|
||||
// Timer based onchange handler, so we don't scan the whole text on every typed character
|
||||
TimerMemoChange.Enabled := False;
|
||||
if FMaxLength = 0 then
|
||||
MaxLen := '?'
|
||||
else
|
||||
MaxLen := FormatNumber(FMaxLength);
|
||||
CursorPos := FormatNumber(MemoText.CaretY) + ':' + FormatNumber(MemoText.CaretX);
|
||||
lblTextLength.Caption := f_('%s characters (max: %s), %s lines, cursor at %s', [FormatNumber(MemoText.GetTextLen), MaxLen, FormatNumber(MemoText.Lines.Count), CursorPos]);
|
||||
if MemoText.ReadOnly then
|
||||
lblTextLength.Caption := lblTextLength.Caption + ', read-only';
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.btnCustomizeHighlighterClick(Sender: TObject);
|
||||
var
|
||||
Dialog: TfrmCustomizeHighlighter;
|
||||
begin
|
||||
// let user customize highlighter colors
|
||||
Dialog := TfrmCustomizeHighlighter.Create(Self);
|
||||
Dialog.FriendlyLanguageName := MemoText.Highlighter.GetLanguageName;
|
||||
Dialog.OnChange := CustomizeHighlighterChanged;
|
||||
Dialog.ShowModal;
|
||||
Dialog.Free;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.CustomizeHighlighterChanged(Sender: TObject);
|
||||
var
|
||||
Dialog: TfrmCustomizeHighlighter;
|
||||
begin
|
||||
Dialog := Sender as TfrmCustomizeHighlighter;
|
||||
comboHighlighter.ItemIndex := comboHighlighter.Items.IndexOf(Dialog.FriendlyLanguageName);
|
||||
comboHighlighter.OnSelect(comboHighlighter);
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.SelectLinebreaks(Sender: TObject);
|
||||
var
|
||||
Selected, Item: TMenuItem;
|
||||
begin
|
||||
Selected := Sender as TMenuItem;
|
||||
menuWindowsLB.Caption := _('Windows linebreaks');
|
||||
menuUnixLB.Caption := _('UNIX linebreaks');
|
||||
menuMacLB.Caption := _('Mac OS linebreaks');
|
||||
menuWideLB.Caption := _('Unicode linebreaks');
|
||||
menuMixedLB.Caption := _('Mixed linebreaks');
|
||||
for Item in popupLinebreaks.Items do begin
|
||||
if Item.Tag = Integer(FDetectedLineBreaks) then begin
|
||||
Item.Caption := Item.Caption + ' (' + _('detected') + ')';
|
||||
end;
|
||||
end;
|
||||
|
||||
Selected.Default := True;
|
||||
btnLineBreaks.Hint := Selected.Caption;
|
||||
btnLineBreaks.ImageIndex := Selected.ImageIndex;
|
||||
FSelectedLineBreaks := TLineBreaks(Selected.Tag);
|
||||
Modified := True;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.SetMaxLength(len: integer);
|
||||
begin
|
||||
// Input: Length in number of bytes.
|
||||
FMaxLength := len;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.SetFont(font: TFont);
|
||||
begin
|
||||
MemoText.Font.Name := font.Name;
|
||||
MemoText.Font.Size := font.Size;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.FormCreate(Sender: TObject);
|
||||
var
|
||||
Highlighters: TSynHighlighterList;
|
||||
i: Integer;
|
||||
begin
|
||||
HasSizeGrip := True;
|
||||
FClosingByApplyButton := False;
|
||||
// Assign linebreak values to their menu item tags, to write less code later
|
||||
menuWindowsLB.Tag := Integer(lbsWindows);
|
||||
menuUnixLB.Tag := Integer(lbsUnix);
|
||||
menuMacLB.Tag := Integer(lbsMac);
|
||||
menuWideLB.Tag := Integer(lbsWide);
|
||||
menuMixedLB.Tag := Integer(lbsMixed);
|
||||
|
||||
Highlighters := SynEditHighlighter.GetPlaceableHighlighters;
|
||||
for i:=0 to Highlighters.Count-1 do begin
|
||||
comboHighlighter.Items.Add(Highlighters[i].GetLanguageName);
|
||||
end;
|
||||
|
||||
FTableColumn := nil;
|
||||
|
||||
// Fix label position:
|
||||
lblTextLength.Top := tlbStandard.Top + (tlbStandard.Height-lblTextLength.Height) div 2;
|
||||
|
||||
// Define highlighters for which we have a reformatter
|
||||
FHighlighterFormatters := TStringList.Create;
|
||||
//FHighlighterFormatters.Add(TSynJSONSyn.ClassName);
|
||||
FHighlighterFormatters.Add(TSynSQLSyn.ClassName);
|
||||
FHighlighterFormatters.Add(TSynXMLSyn.ClassName);
|
||||
|
||||
MemoText.OnMouseWheel := MainForm.AnySynMemoMouseWheel;
|
||||
//MemoText.OnPaintTransient := MainForm.SynMemoQuery.OnPaintTransient;
|
||||
if AppSettings.ReadBool(asMemoEditorMaximized) then
|
||||
WindowState := wsMaximized;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
if WindowState <> wsMaximized then begin
|
||||
AppSettings.WriteIntDpiAware(asMemoEditorWidth, Self, Width);
|
||||
AppSettings.WriteIntDpiAware(asMemoEditorHeight, Self, Height);
|
||||
end;
|
||||
AppSettings.WriteBool(asMemoEditorMaximized, WindowState=wsMaximized);
|
||||
if btnWrap.Enabled then begin
|
||||
AppSettings.WriteBool(asMemoEditorWrap, btnWrap.Down);
|
||||
end;
|
||||
if Assigned(FTableColumn) and (comboHighlighter.Text <> AppSettings.GetDefaultString(asMemoEditorHighlighter)) then begin
|
||||
AppSettings.SessionPath := MainForm.GetRegKeyTable;
|
||||
AppSettings.WriteString(asMemoEditorHighlighter, comboHighlighter.Text, FTableColumn.Name);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.FormShow(Sender: TObject);
|
||||
var
|
||||
HighlighterName: String;
|
||||
begin
|
||||
// Restore form dimensions
|
||||
if WindowState <> wsMaximized then begin
|
||||
Width := AppSettings.ReadIntDpiAware(asMemoEditorWidth, Self);
|
||||
Height := AppSettings.ReadIntDpiAware(asMemoEditorHeight, Self);
|
||||
end;
|
||||
|
||||
if AppSettings.ReadBool(asMemoEditorWrap) and btnWrap.Enabled then begin
|
||||
btnWrap.Click;
|
||||
end;
|
||||
menuAlwaysFormatCode.Checked := AppSettings.ReadBool(asMemoEditorAlwaysFormatCode);
|
||||
|
||||
// Select previously used highlighter
|
||||
HighlighterName := AppSettings.GetDefaultString(asMemoEditorHighlighter);
|
||||
if Assigned(FTableColumn) then begin
|
||||
AppSettings.SessionPath := MainForm.GetRegKeyTable;
|
||||
HighlighterName := AppSettings.ReadString(asMemoEditorHighlighter, FTableColumn.Name, HighlighterName);
|
||||
end;
|
||||
|
||||
if MemoText.ReadOnly then begin
|
||||
MemoText.Color := clBtnFace;
|
||||
end;
|
||||
|
||||
comboHighlighter.ItemIndex := comboHighlighter.Items.IndexOf(HighlighterName);
|
||||
comboHighlighter.OnSelect(comboHighlighter);
|
||||
// Trigger change event, which is not fired when text is empty. See #132.
|
||||
TimerMemoChangeTimer(Self);
|
||||
MemoText.SetFocus;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.MemoTextKeyDown(Sender: TObject; var Key: Word; Shift:
|
||||
TShiftState);
|
||||
begin
|
||||
TimerMemoChange.Enabled := False;
|
||||
TimerMemoChange.Enabled := True;
|
||||
case Key of
|
||||
// Cancel active dialog by Escape
|
||||
VK_ESCAPE: begin
|
||||
btnCancelClick(Sender);
|
||||
end;
|
||||
// Apply changes and end editing by Ctrl + Enter
|
||||
VK_RETURN: if ssCtrl in Shift then btnApplyClick(Sender);
|
||||
Ord('a'), Ord('A'): if (ssCtrl in Shift) and (not (ssAlt in Shift)) then Mainform.actSelectAllExecute(Sender);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.MemoTextClick(Sender: TObject);
|
||||
begin
|
||||
TimerMemoChange.Enabled := False;
|
||||
TimerMemoChange.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.btnWrapClick(Sender: TObject);
|
||||
var
|
||||
WasModified: Boolean;
|
||||
begin
|
||||
Screen.Cursor := crHourglass;
|
||||
// Changing the scrollbars invoke the OnChange event. We avoid thinking the text was really modified.
|
||||
WasModified := Modified;
|
||||
if MemoText.ScrollBars = ssBoth then begin
|
||||
MemoText.ScrollBars := ssVertical;
|
||||
//MemoText.WordWrap := True;
|
||||
end else begin
|
||||
MemoText.ScrollBars := ssBoth;
|
||||
//MemoText.WordWrap := False;
|
||||
end;
|
||||
btnWrap.Down := MemoText.ScrollBars = ssVertical;
|
||||
Modified := WasModified;
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.comboHighlighterSelect(Sender: TObject);
|
||||
var
|
||||
Highlighters: TSynHighlighterList;
|
||||
i: Integer;
|
||||
SelStart, SelLength: Integer;
|
||||
begin
|
||||
// Code highlighter selected
|
||||
SelStart := MemoText.SelStart;
|
||||
SelLength := MemoText.SelEnd - MemoText.SelStart;
|
||||
MemoText.Highlighter := nil;
|
||||
FHighlighter.Free;
|
||||
Highlighters := SynEditHighlighter.GetPlaceableHighlighters;
|
||||
for i:=0 to Highlighters.Count-1 do begin
|
||||
if comboHighlighter.Text = Highlighters[i].GetLanguageName then begin
|
||||
FHighlighter := Highlighters[i].Create(Self);
|
||||
MemoText.Highlighter := FHighlighter;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
// In case the combobox is empty:
|
||||
if MemoText.Highlighter = nil then begin
|
||||
FHighlighter := TSynSQLSyn.Create(Self);
|
||||
MemoText.Highlighter := FHighlighter;
|
||||
end;
|
||||
|
||||
menuFormatCodeOnce.Enabled := FHighlighterFormatters.IndexOf(FHighlighter.ClassName) > -1;
|
||||
if menuAlwaysFormatCode.Checked and menuFormatCodeOnce.Enabled then begin
|
||||
menuFormatCodeOnce.OnClick(Sender);
|
||||
SelStart := 0;
|
||||
SelLength := 0;
|
||||
end;
|
||||
|
||||
// Load custom highlighter settings from ini file, if exists:
|
||||
MemoText.Highlighter.LoadFromFile(AppSettings.DirnameHighlighters + MemoText.Highlighter.LanguageName + '.ini');
|
||||
|
||||
MemoText.SelStart := SelStart;
|
||||
MemoText.SelEnd := SelStart + SelLength;
|
||||
end;
|
||||
|
||||
procedure TfrmTextEditor.btnLoadTextClick(Sender: TObject);
|
||||
var
|
||||
d: TExtFileOpenDialog;
|
||||
begin
|
||||
AppSettings.ResetPath;
|
||||
d := TExtFileOpenDialog.Create(Self);
|
||||
d.AddFileType('*.txt', _('Text files'));
|
||||
d.AddFileType('*.*', _('All files'));
|
||||
d.Encodings.Assign(MainForm.FileEncodings);
|
||||
d.EncodingIndex := AppSettings.ReadInt(asFileDialogEncoding, Self.Name);
|
||||
if d.Execute then try
|
||||
Screen.Cursor := crHourglass;
|
||||
MemoText.Text := ReadTextFile(d.FileName, MainForm.GetEncodingByName(d.Encodings[d.EncodingIndex]));
|
||||
if (FMaxLength > 0) and (Length(MemoText.Text) > FMaxLength) then
|
||||
MemoText.Text := copy(MemoText.Text, 0, FMaxLength);
|
||||
AppSettings.WriteInt(asFileDialogEncoding, d.EncodingIndex, Self.Name);
|
||||
finally
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
d.Free;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.btnCancelClick(Sender: TObject);
|
||||
begin
|
||||
FClosingByCancelButton := True;
|
||||
Close;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.menuAlwaysFormatCodeClick(Sender: TObject);
|
||||
begin
|
||||
// Change setting for "always reformat"
|
||||
AppSettings.WriteBool(asMemoEditorAlwaysFormatCode, menuAlwaysFormatCode.Checked);
|
||||
if menuAlwaysFormatCode.Checked and menuFormatCodeOnce.Enabled then begin
|
||||
menuFormatCodeOnce.OnClick(Sender);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.menuFormatCodeOnceClick(Sender: TObject);
|
||||
//var
|
||||
//JsonTmp: TJSONValue;
|
||||
//Xml: TXmlVerySimple;
|
||||
//XmlTmp: IXMLDocument;
|
||||
begin
|
||||
// Reformat code if possible
|
||||
try
|
||||
{if FHighlighter is TSynJSONSyn then begin
|
||||
JsonTmp := TJSONObject.ParseJSONValue(MemoText.Text);
|
||||
MemoText.Text := JsonTmp.Format;
|
||||
JsonTmp.Free;
|
||||
MemoText.SelStart := 0;
|
||||
MemoText.SelLength := 0;
|
||||
end
|
||||
else} if FHighlighter is TSynSQLSyn then begin
|
||||
// Prefer old internal formatter here, so the user does not run into request limits
|
||||
frmReformatter := TfrmReformatter.Create(Self);
|
||||
MemoText.Text := frmReformatter.FormatSqlInternal(MemoText.Text);
|
||||
MemoText.SelStart := 0;
|
||||
MemoText.SelEnd := 0;
|
||||
frmReformatter.Free;
|
||||
end
|
||||
{else if FHighlighter is TSynXMLSyn then begin
|
||||
XmlTmp := TXMLDocument.Create(nil);
|
||||
XmlTmp.LoadFromXML(MemoText.Text);
|
||||
MemoText.BeginUpdate;
|
||||
MemoText.Text := XMLDoc.FormatXMLData(MemoText.Text);
|
||||
MemoText.EndUpdate;
|
||||
Xml := TXmlVerySimple.Create;
|
||||
//Xml.Options := [doNodeAutoIndent, doParseProcessingInstr, doCaseInsensitive, doWriteBOM, doSimplifyTextNodes];
|
||||
Xml.Clear;
|
||||
Xml.Text := MemoText.Lines.Text.Trim;
|
||||
MemoText.BeginUpdate;
|
||||
MemoText.Lines.Text := Xml.Text;
|
||||
MemoText.EndUpdate;
|
||||
Xml.Free;
|
||||
MemoText.SelStart := 0;
|
||||
MemoText.SelLength := 0;
|
||||
end}
|
||||
else begin
|
||||
Beep;
|
||||
end;
|
||||
except
|
||||
on E:Exception do begin
|
||||
Beep;
|
||||
MainForm.LogSQL(f_('Error in code formatting: %s', [E.Message]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.FormClose(Sender: TObject; var Action: TCloseAction);
|
||||
begin
|
||||
if Modified then begin
|
||||
if FClosingByCancelButton then
|
||||
ModalResult := mrCancel
|
||||
else if FClosingByApplyButton then
|
||||
ModalResult := mrYes
|
||||
else
|
||||
ModalResult := MessageDialog(_('Apply modifications?'), mtConfirmation, [mbYes, mbNo]);
|
||||
end
|
||||
else
|
||||
ModalResult := mrCancel;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.btnApplyClick(Sender: TObject);
|
||||
begin
|
||||
FClosingByApplyButton := True;
|
||||
Close;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.MemoTextChange(Sender: TObject);
|
||||
begin
|
||||
Modified := True;
|
||||
TimerMemoChange.Enabled := False;
|
||||
TimerMemoChange.Enabled := True;
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmTextEditor.SetModified(NewVal: Boolean);
|
||||
begin
|
||||
// Enables or disables "apply" button, and resets SynEdit's modification marker in its gutter
|
||||
if FModified <> NewVal then begin
|
||||
FModified := NewVal;
|
||||
if not FModified then
|
||||
MemoText.Modified := False;
|
||||
btnApply.Enabled := FModified;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
Reference in New Issue
Block a user