mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-31 07:56:05 +02:00
Initial version of missing properties fixer.
git-svn-id: trunk@23801 -
This commit is contained in:
parent
611903515a
commit
722da95ece
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2211,6 +2211,8 @@ converter/convertdelphi.pas svneol=native#text/plain
|
||||
converter/convertsettings.lfm svneol=native#text/plain
|
||||
converter/convertsettings.pas svneol=native#text/plain
|
||||
converter/lazxmlforms.pas svneol=native#text/plain
|
||||
converter/missingpropertiesdlg.lfm svneol=native#text/plain
|
||||
converter/missingpropertiesdlg.pas svneol=native#text/plain
|
||||
converter/missingunits.lfm svneol=native#text/plain
|
||||
converter/missingunits.pas svneol=native#text/plain
|
||||
debian/README.Debian svneol=native#text/plain
|
||||
|
741
converter/missingpropertiesdlg.lfm
Normal file
741
converter/missingpropertiesdlg.lfm
Normal file
@ -0,0 +1,741 @@
|
||||
object FixLFMDialog: TFixLFMDialog
|
||||
Left = 337
|
||||
Height = 580
|
||||
Top = 150
|
||||
Width = 749
|
||||
ActiveControl = LFMSynEdit
|
||||
Caption = 'Repair LFM file'
|
||||
ClientHeight = 580
|
||||
ClientWidth = 749
|
||||
OnCreate = CheckLFMDialogCreate
|
||||
LCLVersion = '0.9.29'
|
||||
object NoteLabel: TLabel
|
||||
Left = 0
|
||||
Height = 16
|
||||
Top = 0
|
||||
Width = 749
|
||||
Align = alTop
|
||||
Caption = 'NoteLabel'
|
||||
ParentColor = False
|
||||
WordWrap = True
|
||||
end
|
||||
object LFMGroupBox: TGroupBox
|
||||
Left = 0
|
||||
Height = 412
|
||||
Top = 16
|
||||
Width = 408
|
||||
Align = alLeft
|
||||
Caption = 'LFM file'
|
||||
ClientHeight = 390
|
||||
ClientWidth = 398
|
||||
TabOrder = 0
|
||||
inline LFMSynEdit: TSynEdit
|
||||
Left = 0
|
||||
Height = 390
|
||||
Top = 0
|
||||
Width = 398
|
||||
Align = alClient
|
||||
Font.Height = -15
|
||||
Font.Name = 'courier'
|
||||
Font.Pitch = fpFixed
|
||||
Font.Quality = fqNonAntialiased
|
||||
ParentColor = False
|
||||
ParentFont = False
|
||||
TabOrder = 0
|
||||
Gutter.Width = 59
|
||||
Gutter.MouseActions = <
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 13
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbRight
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdUp
|
||||
Command = 12
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end>
|
||||
Highlighter = SynLFMSyn1
|
||||
Keystrokes = <
|
||||
item
|
||||
Command = ecUp
|
||||
ShortCut = 38
|
||||
end
|
||||
item
|
||||
Command = ecSelUp
|
||||
ShortCut = 8230
|
||||
end
|
||||
item
|
||||
Command = ecScrollUp
|
||||
ShortCut = 16422
|
||||
end
|
||||
item
|
||||
Command = ecDown
|
||||
ShortCut = 40
|
||||
end
|
||||
item
|
||||
Command = ecSelDown
|
||||
ShortCut = 8232
|
||||
end
|
||||
item
|
||||
Command = ecScrollDown
|
||||
ShortCut = 16424
|
||||
end
|
||||
item
|
||||
Command = ecLeft
|
||||
ShortCut = 37
|
||||
end
|
||||
item
|
||||
Command = ecSelLeft
|
||||
ShortCut = 8229
|
||||
end
|
||||
item
|
||||
Command = ecWordLeft
|
||||
ShortCut = 16421
|
||||
end
|
||||
item
|
||||
Command = ecSelWordLeft
|
||||
ShortCut = 24613
|
||||
end
|
||||
item
|
||||
Command = ecRight
|
||||
ShortCut = 39
|
||||
end
|
||||
item
|
||||
Command = ecSelRight
|
||||
ShortCut = 8231
|
||||
end
|
||||
item
|
||||
Command = ecWordRight
|
||||
ShortCut = 16423
|
||||
end
|
||||
item
|
||||
Command = ecSelWordRight
|
||||
ShortCut = 24615
|
||||
end
|
||||
item
|
||||
Command = ecPageDown
|
||||
ShortCut = 34
|
||||
end
|
||||
item
|
||||
Command = ecSelPageDown
|
||||
ShortCut = 8226
|
||||
end
|
||||
item
|
||||
Command = ecPageBottom
|
||||
ShortCut = 16418
|
||||
end
|
||||
item
|
||||
Command = ecSelPageBottom
|
||||
ShortCut = 24610
|
||||
end
|
||||
item
|
||||
Command = ecPageUp
|
||||
ShortCut = 33
|
||||
end
|
||||
item
|
||||
Command = ecSelPageUp
|
||||
ShortCut = 8225
|
||||
end
|
||||
item
|
||||
Command = ecPageTop
|
||||
ShortCut = 16417
|
||||
end
|
||||
item
|
||||
Command = ecSelPageTop
|
||||
ShortCut = 24609
|
||||
end
|
||||
item
|
||||
Command = ecLineStart
|
||||
ShortCut = 36
|
||||
end
|
||||
item
|
||||
Command = ecSelLineStart
|
||||
ShortCut = 8228
|
||||
end
|
||||
item
|
||||
Command = ecEditorTop
|
||||
ShortCut = 16420
|
||||
end
|
||||
item
|
||||
Command = ecSelEditorTop
|
||||
ShortCut = 24612
|
||||
end
|
||||
item
|
||||
Command = ecLineEnd
|
||||
ShortCut = 35
|
||||
end
|
||||
item
|
||||
Command = ecSelLineEnd
|
||||
ShortCut = 8227
|
||||
end
|
||||
item
|
||||
Command = ecEditorBottom
|
||||
ShortCut = 16419
|
||||
end
|
||||
item
|
||||
Command = ecSelEditorBottom
|
||||
ShortCut = 24611
|
||||
end
|
||||
item
|
||||
Command = ecToggleMode
|
||||
ShortCut = 45
|
||||
end
|
||||
item
|
||||
Command = ecCopy
|
||||
ShortCut = 16429
|
||||
end
|
||||
item
|
||||
Command = ecPaste
|
||||
ShortCut = 8237
|
||||
end
|
||||
item
|
||||
Command = ecDeleteChar
|
||||
ShortCut = 46
|
||||
end
|
||||
item
|
||||
Command = ecCut
|
||||
ShortCut = 8238
|
||||
end
|
||||
item
|
||||
Command = ecDeleteLastChar
|
||||
ShortCut = 8
|
||||
end
|
||||
item
|
||||
Command = ecDeleteLastChar
|
||||
ShortCut = 8200
|
||||
end
|
||||
item
|
||||
Command = ecDeleteLastWord
|
||||
ShortCut = 16392
|
||||
end
|
||||
item
|
||||
Command = ecUndo
|
||||
ShortCut = 32776
|
||||
end
|
||||
item
|
||||
Command = ecRedo
|
||||
ShortCut = 40968
|
||||
end
|
||||
item
|
||||
Command = ecLineBreak
|
||||
ShortCut = 13
|
||||
end
|
||||
item
|
||||
Command = ecSelectAll
|
||||
ShortCut = 16449
|
||||
end
|
||||
item
|
||||
Command = ecCopy
|
||||
ShortCut = 16451
|
||||
end
|
||||
item
|
||||
Command = ecBlockIndent
|
||||
ShortCut = 24649
|
||||
end
|
||||
item
|
||||
Command = ecLineBreak
|
||||
ShortCut = 16461
|
||||
end
|
||||
item
|
||||
Command = ecInsertLine
|
||||
ShortCut = 16462
|
||||
end
|
||||
item
|
||||
Command = ecDeleteWord
|
||||
ShortCut = 16468
|
||||
end
|
||||
item
|
||||
Command = ecBlockUnindent
|
||||
ShortCut = 24661
|
||||
end
|
||||
item
|
||||
Command = ecPaste
|
||||
ShortCut = 16470
|
||||
end
|
||||
item
|
||||
Command = ecCut
|
||||
ShortCut = 16472
|
||||
end
|
||||
item
|
||||
Command = ecDeleteLine
|
||||
ShortCut = 16473
|
||||
end
|
||||
item
|
||||
Command = ecDeleteEOL
|
||||
ShortCut = 24665
|
||||
end
|
||||
item
|
||||
Command = ecUndo
|
||||
ShortCut = 16474
|
||||
end
|
||||
item
|
||||
Command = ecRedo
|
||||
ShortCut = 24666
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker0
|
||||
ShortCut = 16432
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker1
|
||||
ShortCut = 16433
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker2
|
||||
ShortCut = 16434
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker3
|
||||
ShortCut = 16435
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker4
|
||||
ShortCut = 16436
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker5
|
||||
ShortCut = 16437
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker6
|
||||
ShortCut = 16438
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker7
|
||||
ShortCut = 16439
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker8
|
||||
ShortCut = 16440
|
||||
end
|
||||
item
|
||||
Command = ecGotoMarker9
|
||||
ShortCut = 16441
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker0
|
||||
ShortCut = 24624
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker1
|
||||
ShortCut = 24625
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker2
|
||||
ShortCut = 24626
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker3
|
||||
ShortCut = 24627
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker4
|
||||
ShortCut = 24628
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker5
|
||||
ShortCut = 24629
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker6
|
||||
ShortCut = 24630
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker7
|
||||
ShortCut = 24631
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker8
|
||||
ShortCut = 24632
|
||||
end
|
||||
item
|
||||
Command = ecSetMarker9
|
||||
ShortCut = 24633
|
||||
end
|
||||
item
|
||||
Command = ecNormalSelect
|
||||
ShortCut = 24654
|
||||
end
|
||||
item
|
||||
Command = ecColumnSelect
|
||||
ShortCut = 24643
|
||||
end
|
||||
item
|
||||
Command = ecLineSelect
|
||||
ShortCut = 24652
|
||||
end
|
||||
item
|
||||
Command = ecTab
|
||||
ShortCut = 9
|
||||
end
|
||||
item
|
||||
Command = ecShiftTab
|
||||
ShortCut = 8201
|
||||
end
|
||||
item
|
||||
Command = ecMatchBracket
|
||||
ShortCut = 24642
|
||||
end>
|
||||
MouseActions = <
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = [ssShift, ssAlt]
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 1
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = [ssShift]
|
||||
ShiftMask = [ssShift, ssAlt]
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 1
|
||||
MoveCaret = True
|
||||
Option = 1
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = [ssAlt]
|
||||
ShiftMask = [ssShift, ssAlt]
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 3
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = [ssShift, ssAlt]
|
||||
ShiftMask = [ssShift, ssAlt]
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 3
|
||||
MoveCaret = True
|
||||
Option = 1
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbRight
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdUp
|
||||
Command = 12
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccDouble
|
||||
ClickDir = cdDown
|
||||
Command = 6
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccTriple
|
||||
ClickDir = cdDown
|
||||
Command = 7
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccQuad
|
||||
ClickDir = cdDown
|
||||
Command = 8
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbMiddle
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 10
|
||||
MoveCaret = True
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = [ssCtrl]
|
||||
ShiftMask = [ssShift, ssAlt, ssCtrl]
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdUp
|
||||
Command = 11
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end>
|
||||
MouseSelActions = <
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdDown
|
||||
Command = 9
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end>
|
||||
Lines.Strings = (
|
||||
'LFMSynEdit'
|
||||
)
|
||||
BracketHighlightStyle = sbhsBoth
|
||||
OnSpecialLineMarkup = LFMSynEditSpecialLineMarkup
|
||||
inline TSynGutterPartList
|
||||
object TSynGutterMarks
|
||||
Width = 23
|
||||
end
|
||||
object TSynGutterLineNumber
|
||||
Width = 19
|
||||
MouseActions = <>
|
||||
MarkupInfo.Background = clBtnFace
|
||||
MarkupInfo.Foreground = clNone
|
||||
DigitCount = 2
|
||||
ShowOnlyLineNumbersMultiplesOf = 1
|
||||
ZeroStart = False
|
||||
LeadingZeros = False
|
||||
end
|
||||
object TSynGutterChanges
|
||||
Width = 4
|
||||
ModifiedColor = 59900
|
||||
SavedColor = clGreen
|
||||
end
|
||||
object TSynGutterSeparator
|
||||
Width = 2
|
||||
end
|
||||
object TSynGutterCodeFolding
|
||||
MouseActions = <
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbRight
|
||||
ClickCount = ccSingle
|
||||
ClickDir = cdUp
|
||||
Command = 16
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = [ssShift]
|
||||
Button = mbMiddle
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 14
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = [ssShift]
|
||||
ShiftMask = [ssShift]
|
||||
Button = mbMiddle
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 14
|
||||
MoveCaret = False
|
||||
Option = 1
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 0
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end>
|
||||
MarkupInfo.Background = clNone
|
||||
MarkupInfo.Foreground = clGray
|
||||
MouseActionsExpanded = <
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = []
|
||||
Button = mbLeft
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 14
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end>
|
||||
MouseActionsCollapsed = <
|
||||
item
|
||||
Shift = [ssCtrl]
|
||||
ShiftMask = [ssCtrl]
|
||||
Button = mbLeft
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 15
|
||||
MoveCaret = False
|
||||
Option = 0
|
||||
Priority = 0
|
||||
end
|
||||
item
|
||||
Shift = []
|
||||
ShiftMask = [ssCtrl]
|
||||
Button = mbLeft
|
||||
ClickCount = ccAny
|
||||
ClickDir = cdDown
|
||||
Command = 15
|
||||
MoveCaret = False
|
||||
Option = 1
|
||||
Priority = 0
|
||||
end>
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
object ErrorsGroupBox: TGroupBox
|
||||
Left = 0
|
||||
Height = 104
|
||||
Top = 428
|
||||
Width = 749
|
||||
Align = alBottom
|
||||
Caption = 'Errors'
|
||||
ClientHeight = 82
|
||||
ClientWidth = 739
|
||||
TabOrder = 1
|
||||
object ErrorsListBox: TListBox
|
||||
Left = 0
|
||||
Height = 82
|
||||
Top = 0
|
||||
Width = 739
|
||||
Align = alClient
|
||||
ItemHeight = 0
|
||||
OnClick = ErrorsListBoxClick
|
||||
TabOrder = 0
|
||||
end
|
||||
end
|
||||
object BtnPanel: TPanel
|
||||
Left = 0
|
||||
Height = 48
|
||||
Top = 532
|
||||
Width = 749
|
||||
Align = alBottom
|
||||
AutoSize = True
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 48
|
||||
ClientWidth = 749
|
||||
TabOrder = 2
|
||||
object CancelButton: TBitBtn
|
||||
Left = 662
|
||||
Height = 36
|
||||
Top = 6
|
||||
Width = 81
|
||||
Align = alRight
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 6
|
||||
Cancel = True
|
||||
Caption = 'Cancel'
|
||||
Kind = bkCancel
|
||||
ModalResult = 2
|
||||
NumGlyphs = 0
|
||||
TabOrder = 0
|
||||
end
|
||||
object RemoveAllButton: TBitBtn
|
||||
Left = 6
|
||||
Height = 25
|
||||
Top = 6
|
||||
Width = 175
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'Remove all invalid properties'
|
||||
NumGlyphs = 0
|
||||
OnClick = RemoveAllButtonClick
|
||||
TabOrder = 1
|
||||
end
|
||||
object ReplaceAllButton: TBitBtn
|
||||
AnchorSideLeft.Control = RemoveAllButton
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
Left = 192
|
||||
Height = 25
|
||||
Top = 6
|
||||
Width = 137
|
||||
AutoSize = True
|
||||
BorderSpacing.Left = 11
|
||||
Caption = 'Replace all properties'
|
||||
OnClick = ReplaceAllButtonClick
|
||||
TabOrder = 2
|
||||
Visible = False
|
||||
end
|
||||
end
|
||||
object PropertyReplaceGroupBox: TGroupBox
|
||||
Left = 413
|
||||
Height = 412
|
||||
Top = 16
|
||||
Width = 336
|
||||
Align = alClient
|
||||
Caption = 'Properties to replace'
|
||||
ClientHeight = 390
|
||||
ClientWidth = 326
|
||||
TabOrder = 3
|
||||
object PropertyReplaceGrid: TStringGrid
|
||||
Left = 0
|
||||
Height = 390
|
||||
Top = 0
|
||||
Width = 326
|
||||
Align = alClient
|
||||
ColCount = 3
|
||||
Columns = <
|
||||
item
|
||||
Title.Caption = 'Delphi Property'
|
||||
end
|
||||
item
|
||||
Title.Caption = 'New Property'
|
||||
end>
|
||||
TabOrder = 0
|
||||
end
|
||||
end
|
||||
object Splitter1: TSplitter
|
||||
Left = 408
|
||||
Height = 412
|
||||
Top = 16
|
||||
Width = 5
|
||||
end
|
||||
object SynLFMSyn1: TSynLFMSyn
|
||||
DefaultFilter = 'Lazarus Form Files (*.lfm)|*.lfm'
|
||||
Enabled = False
|
||||
left = 129
|
||||
top = 104
|
||||
end
|
||||
end
|
576
converter/missingpropertiesdlg.pas
Normal file
576
converter/missingpropertiesdlg.pas
Normal file
@ -0,0 +1,576 @@
|
||||
{ $Id$ }
|
||||
{
|
||||
/***************************************************************************
|
||||
checklfmdlg.pas
|
||||
---------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* This source is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This code is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* A copy of the GNU General Public License is available on the World *
|
||||
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
||||
* obtain it by writing to the Free Software Foundation, *
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
* *
|
||||
***************************************************************************
|
||||
}
|
||||
unit MissingPropertiesDlg;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
// FCL+LCL
|
||||
Classes, SysUtils, Math, TypInfo, LCLProc, Forms, Controls, LResources,
|
||||
Graphics, Dialogs, Buttons, StdCtrls,
|
||||
// components
|
||||
SynHighlighterLFM, SynEdit, BasicCodeTools, CodeCache, CodeToolManager,
|
||||
SynEditMiscClasses, LFMTrees,
|
||||
// IDE
|
||||
PropEdits, IDEDialogs, ComponentReg, PackageIntf, IDEWindowIntf,
|
||||
CustomFormEditor, LazarusIDEStrConsts, OutputFilter, IDEProcs, IDEOptionDefs,
|
||||
EditorOptions, ExtCtrls, Grids, JITForms, PropEditUtils;
|
||||
|
||||
type
|
||||
|
||||
{ TLfmFixer }
|
||||
|
||||
TLfmFixer = class
|
||||
private
|
||||
fPascalBuffer: TCodeBuffer;
|
||||
fLfmBuffer: TCodeBuffer;
|
||||
fOnOutput: TOnAddFilteredLine;
|
||||
fRootMustBeClassInIntf: boolean;
|
||||
fObjectsMustExists: boolean;
|
||||
fLfmTree: TLFMTree;
|
||||
procedure WriteUnitError(Code: TCodeBuffer; x, Y: integer;
|
||||
const ErrorMessage: string);
|
||||
procedure WriteCodeToolsError;
|
||||
procedure WriteLFMErrors;
|
||||
function FixMissingComponentClasses: TModalResult;
|
||||
function CheckUnit: boolean;
|
||||
function ShowRepairLFMWizard: TModalResult;
|
||||
|
||||
public
|
||||
constructor Create(APascalBuffer, ALfmBuffer: TCodeBuffer;
|
||||
const AOnOutput: TOnAddFilteredLine);
|
||||
destructor Destroy; override;
|
||||
function Repair: TModalResult;
|
||||
public
|
||||
property PascalBuffer: TCodeBuffer read fPascalBuffer;
|
||||
property LfmBuffer: TCodeBuffer read fLfmBuffer;
|
||||
property OnOutput: TOnAddFilteredLine read fOnOutput;
|
||||
property RootMustBeClassInIntf: boolean read fRootMustBeClassInIntf
|
||||
write fRootMustBeClassInIntf;
|
||||
property ObjectsMustExists: boolean read fObjectsMustExists
|
||||
write fObjectsMustExists;
|
||||
end;
|
||||
|
||||
|
||||
{ TFixLFMDialog }
|
||||
|
||||
TFixLFMDialog = class(TForm)
|
||||
ReplaceAllButton: TBitBtn;
|
||||
CancelButton: TBitBtn;
|
||||
ErrorsGroupBox: TGroupBox;
|
||||
ErrorsListBox: TListBox;
|
||||
PropertyReplaceGroupBox: TGroupBox;
|
||||
NoteLabel: TLabel;
|
||||
LFMGroupBox: TGroupBox;
|
||||
LFMSynEdit: TSynEdit;
|
||||
BtnPanel: TPanel;
|
||||
RemoveAllButton: TBitBtn;
|
||||
Splitter1: TSplitter;
|
||||
PropertyReplaceGrid: TStringGrid;
|
||||
SynLFMSyn1: TSynLFMSyn;
|
||||
procedure ErrorsListBoxClick(Sender: TObject);
|
||||
procedure LFMSynEditSpecialLineMarkup(Sender: TObject; Line: integer;
|
||||
var Special: boolean; AMarkup: TSynSelectedColor);
|
||||
procedure RemoveAllButtonClick(Sender: TObject);
|
||||
procedure CheckLFMDialogCREATE(Sender: TObject);
|
||||
procedure ReplaceAllButtonClick(Sender: TObject);
|
||||
private
|
||||
fLFMSource: TCodeBuffer;
|
||||
fLFMTree: TLFMTree;
|
||||
procedure SetLFMSource(const AValue: TCodeBuffer);
|
||||
procedure SetLFMTree(const AValue: TLFMTree);
|
||||
procedure SetupComponents;
|
||||
function FindListBoxError: TLFMError;
|
||||
procedure JumpToError(LFMError: TLFMError);
|
||||
procedure FindNiceNodeBounds(LFMNode: TLFMTreeNode;
|
||||
var StartPos, EndPos: integer);
|
||||
procedure AddReplacement(LFMChangeList: TList; StartPos, EndPos: integer;
|
||||
const NewText: string);
|
||||
function ApplyReplacements(LFMChangeList: TList): boolean;
|
||||
public
|
||||
procedure LoadLFM;
|
||||
procedure FillErrorsListBox;
|
||||
function AutomaticFixIsPossible: boolean;
|
||||
property LFMTree: TLFMTree read fLFMTree write SetLFMTree;
|
||||
property LFMSource: TCodeBuffer read fLFMSource write SetLFMSource;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
type
|
||||
TLFMChangeEntry = class
|
||||
public
|
||||
StartPos, EndPos: integer;
|
||||
NewText: string;
|
||||
end;
|
||||
|
||||
{ TLfmFixer }
|
||||
|
||||
constructor TLfmFixer.Create(APascalBuffer, ALfmBuffer: TCodeBuffer;
|
||||
const AOnOutput: TOnAddFilteredLine);
|
||||
begin
|
||||
fPascalBuffer:=APascalBuffer;
|
||||
fLfmBuffer:=ALfmBuffer;
|
||||
fOnOutput:=AOnOutput;
|
||||
fRootMustBeClassInIntf:=true;
|
||||
fObjectsMustExists:=true;
|
||||
end;
|
||||
|
||||
destructor TLfmFixer.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TLfmFixer.Repair: TModalResult;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
if not CheckUnit then begin
|
||||
exit;
|
||||
end;
|
||||
if CodeToolBoss.CheckLFM(fPascalBuffer,fLfmBuffer,fLfmTree,
|
||||
fRootMustBeClassInIntf,fObjectsMustExists)
|
||||
then begin
|
||||
Result:=mrOk;
|
||||
exit;
|
||||
end;
|
||||
Result:=FixMissingComponentClasses;
|
||||
if Result in [mrAbort,mrOk] then begin
|
||||
exit;
|
||||
end;
|
||||
WriteLFMErrors;
|
||||
Result:=ShowRepairLFMWizard;
|
||||
end;
|
||||
|
||||
procedure TLfmFixer.WriteUnitError(Code: TCodeBuffer; x, Y: integer;
|
||||
const ErrorMessage: string);
|
||||
var
|
||||
Dir: String;
|
||||
Filename: String;
|
||||
Msg: String;
|
||||
begin
|
||||
if not Assigned(fOnOutput) then exit;
|
||||
if Code=nil then
|
||||
Code:=fPascalBuffer;
|
||||
Dir:=ExtractFilePath(Code.Filename);
|
||||
Filename:=ExtractFilename(Code.Filename);
|
||||
Msg:=Filename
|
||||
+'('+IntToStr(Y)+','+IntToStr(X)+')'
|
||||
+' Error: '
|
||||
+ErrorMessage;
|
||||
fOnOutput(Msg,Dir,-1,nil);
|
||||
end;
|
||||
|
||||
procedure TLfmFixer.WriteCodeToolsError;
|
||||
begin
|
||||
WriteUnitError(CodeToolBoss.ErrorCode,CodeToolBoss.ErrorColumn,
|
||||
CodeToolBoss.ErrorLine,CodeToolBoss.ErrorMessage);
|
||||
end;
|
||||
|
||||
procedure TLfmFixer.WriteLFMErrors;
|
||||
var
|
||||
CurError: TLFMError;
|
||||
Dir: String;
|
||||
Msg: String;
|
||||
Filename: String;
|
||||
begin
|
||||
if not Assigned(fOnOutput) then exit;
|
||||
CurError:=fLfmTree.FirstError;
|
||||
Dir:=ExtractFilePath(fLfmBuffer.Filename);
|
||||
Filename:=ExtractFilename(fLfmBuffer.Filename);
|
||||
while CurError<>nil do begin
|
||||
Msg:=Filename
|
||||
+'('+IntToStr(CurError.Caret.Y)+','+IntToStr(CurError.Caret.X)+')'
|
||||
+' Error: '
|
||||
+CurError.ErrorMessage;
|
||||
fOnOutput(Msg,Dir,-1,nil);
|
||||
CurError:=CurError.NextError;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLfmFixer.FixMissingComponentClasses: TModalResult;
|
||||
// returns true, if after adding units to uses section all errors are fixed
|
||||
var
|
||||
CurError: TLFMError;
|
||||
MissingObjectTypes: TStringList;
|
||||
TypeName: String;
|
||||
RegComp: TRegisteredComponent;
|
||||
i: Integer;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
MissingObjectTypes:=TStringList.Create;
|
||||
try
|
||||
// collect all missing object types
|
||||
CurError:=fLfmTree.FirstError;
|
||||
while CurError<>nil do begin
|
||||
if CurError.IsMissingObjectType then begin
|
||||
TypeName:=(CurError.Node as TLFMObjectNode).TypeName;
|
||||
if MissingObjectTypes.IndexOf(TypeName)<0 then
|
||||
MissingObjectTypes.Add(TypeName);
|
||||
end;
|
||||
CurError:=CurError.NextError;
|
||||
end;
|
||||
// FixMissingComponentClasses Missing object types in unit.
|
||||
|
||||
// keep all object types with a registered component class
|
||||
for i:=MissingObjectTypes.Count-1 downto 0 do begin
|
||||
RegComp:=IDEComponentPalette.FindComponent(MissingObjectTypes[i]);
|
||||
if (RegComp=nil) or (RegComp.GetUnitName='') then
|
||||
MissingObjectTypes.Delete(i);
|
||||
end;
|
||||
if MissingObjectTypes.Count=0 then exit;
|
||||
//FixMissingComponentClasses Missing object types, but luckily found in IDE.
|
||||
|
||||
// there are missing object types with registered component classes
|
||||
Result:=PackageEditingInterface.AddUnitDependenciesForComponentClasses(
|
||||
fPascalBuffer.Filename,MissingObjectTypes);
|
||||
if Result<>mrOk then begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
// check LFM again
|
||||
if CodeToolBoss.CheckLFM(fPascalBuffer,fLfmBuffer,fLfmTree,
|
||||
fRootMustBeClassInIntf,fObjectsMustExists)
|
||||
then begin
|
||||
Result:=mrOk;
|
||||
end else begin
|
||||
Result:=mrCancel;
|
||||
end;
|
||||
finally
|
||||
MissingObjectTypes.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLfmFixer.CheckUnit: boolean;
|
||||
var
|
||||
NewCode: TCodeBuffer;
|
||||
NewX, NewY, NewTopLine: integer;
|
||||
ErrorMsg: string;
|
||||
MissingUnits: TStrings;
|
||||
s: String;
|
||||
begin
|
||||
Result:=false;
|
||||
// check syntax
|
||||
if not CodeToolBoss.CheckSyntax(fPascalBuffer,NewCode,NewX,NewY,NewTopLine,ErrorMsg)
|
||||
then begin
|
||||
WriteUnitError(NewCode,NewX,NewY,ErrorMsg);
|
||||
exit;
|
||||
end;
|
||||
// check used units
|
||||
MissingUnits:=nil;
|
||||
try
|
||||
if not CodeToolBoss.FindMissingUnits(fPascalBuffer,MissingUnits,false,
|
||||
false)
|
||||
then begin
|
||||
WriteCodeToolsError;
|
||||
exit;
|
||||
end;
|
||||
if (MissingUnits<>nil) and (MissingUnits.Count>0) then begin
|
||||
s:=StringListToText(MissingUnits,',');
|
||||
WriteUnitError(fPascalBuffer,1,1,'Units not found: '+s);
|
||||
exit;
|
||||
end;
|
||||
finally
|
||||
MissingUnits.Free;
|
||||
end;
|
||||
if NewTopLine=0 then ;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TLfmFixer.ShowRepairLFMWizard: TModalResult;
|
||||
var
|
||||
FixLFMDialog: TFixLFMDialog;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
FixLFMDialog:=TFixLFMDialog.Create(nil);
|
||||
FixLFMDialog.LFMTree:=fLfmTree;
|
||||
FixLFMDialog.LFMSource:=fLfmBuffer;
|
||||
FixLFMDialog.LoadLFM;
|
||||
Result:=FixLFMDialog.ShowModal;
|
||||
FixLFMDialog.Free;
|
||||
end;
|
||||
|
||||
|
||||
{ TFixLFMDialog }
|
||||
|
||||
procedure TFixLFMDialog.ReplaceAllButtonClick(Sender: TObject);
|
||||
begin
|
||||
;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.RemoveAllButtonClick(Sender: TObject);
|
||||
var
|
||||
CurError: TLFMError;
|
||||
DeleteNode: TLFMTreeNode;
|
||||
StartPos, EndPos: integer;
|
||||
Replacements: TList;
|
||||
i: integer;
|
||||
begin
|
||||
Replacements:=TList.Create;
|
||||
try
|
||||
// automatically delete each error location
|
||||
CurError:=LFMTree.LastError;
|
||||
while CurError<>nil do begin
|
||||
DeleteNode:=CurError.FindContextNode;
|
||||
if (DeleteNode<>nil) and (DeleteNode.Parent<>nil) then begin
|
||||
FindNiceNodeBounds(DeleteNode,StartPos,EndPos);
|
||||
AddReplacement(Replacements,StartPos,EndPos,'');
|
||||
end;
|
||||
CurError:=CurError.PrevError;
|
||||
end;
|
||||
|
||||
if ApplyReplacements(Replacements) then
|
||||
ModalResult:=mrOk;
|
||||
finally
|
||||
for i := 0 to Replacements.Count - 1 do
|
||||
TObject(Replacements[i]).Free;
|
||||
Replacements.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.ErrorsListBoxClick(Sender: TObject);
|
||||
begin
|
||||
JumpToError(FindListBoxError);
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.LFMSynEditSpecialLineMarkup(Sender: TObject;
|
||||
Line: integer; var Special: boolean; AMarkup: TSynSelectedColor);
|
||||
var
|
||||
CurError: TLFMError;
|
||||
begin
|
||||
CurError:=LFMTree.FindErrorAtLine(Line);
|
||||
if CurError = nil then Exit;
|
||||
|
||||
Special := True;
|
||||
EditorOpts.SetMarkupColor(SynLFMSyn1, ahaErrorLine, AMarkup);
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.CheckLFMDialogCREATE(Sender: TObject);
|
||||
begin
|
||||
Caption:=lisFixLFMFile;
|
||||
Position:=poScreenCenter;
|
||||
IDEDialogLayoutList.ApplyLayout(Self,600,400);
|
||||
SetupComponents;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.SetLFMSource(const AValue: TCodeBuffer);
|
||||
begin
|
||||
if fLFMSource=AValue then exit;
|
||||
fLFMSource:=AValue;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.SetLFMTree(const AValue: TLFMTree);
|
||||
begin
|
||||
if fLFMTree=AValue then exit;
|
||||
fLFMTree:=AValue;
|
||||
RemoveAllButton.Enabled:=AutomaticFixIsPossible;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.SetupComponents;
|
||||
const // Will be moved to LazarusIDEStrConsts
|
||||
lisReplaceAllProperties = 'Replace all properties';
|
||||
begin
|
||||
NoteLabel.Caption:=lisTheLFMLazarusFormFileContainsInvalidPropertiesThis;
|
||||
ErrorsGroupBox.Caption:=lisErrors;
|
||||
LFMGroupBox.Caption:=lisLFMFile;
|
||||
RemoveAllButton.Caption:=lisRemoveAllInvalidProperties;
|
||||
RemoveAllButton.LoadGlyphFromLazarusResource('laz_delete');
|
||||
ReplaceAllButton.Caption:=lisReplaceAllProperties;
|
||||
ReplaceAllButton.LoadGlyphFromLazarusResource('laz_refresh');
|
||||
EditorOpts.GetHighlighterSettings(SynLFMSyn1);
|
||||
EditorOpts.GetSynEditSettings(LFMSynEdit);
|
||||
end;
|
||||
|
||||
function TFixLFMDialog.FindListBoxError: TLFMError;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
i:=ErrorsListBox.ItemIndex;
|
||||
if (i<0) or (i>=ErrorsListBox.Items.Count) then exit;
|
||||
Result:=LFMTree.FirstError;
|
||||
while Result<>nil do begin
|
||||
if i=0 then exit;
|
||||
Result:=Result.NextError;
|
||||
dec(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.JumpToError(LFMError: TLFMError);
|
||||
begin
|
||||
if LFMError=nil then exit;
|
||||
LFMSynEdit.CaretXY:=LFMError.Caret;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.FindNiceNodeBounds(LFMNode: TLFMTreeNode;
|
||||
var StartPos, EndPos: integer);
|
||||
var
|
||||
Src: String;
|
||||
begin
|
||||
Src:=LFMSource.Source;
|
||||
StartPos:=FindLineEndOrCodeInFrontOfPosition(Src,LFMNode.StartPos,1,false,true);
|
||||
EndPos:=FindLineEndOrCodeInFrontOfPosition(Src,LFMNode.EndPos,1,false,true);
|
||||
EndPos:=FindLineEndOrCodeAfterPosition(Src,EndPos,length(Src),false);
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.AddReplacement(LFMChangeList: TList;
|
||||
StartPos, EndPos: integer; const NewText: string);
|
||||
var
|
||||
Entry: TLFMChangeEntry;
|
||||
NewEntry: TLFMChangeEntry;
|
||||
i: Integer;
|
||||
begin
|
||||
if StartPos>EndPos then
|
||||
RaiseException('TCheckLFMDialog.AddReplaceMent StartPos>EndPos');
|
||||
|
||||
// check for intersection
|
||||
for i:=0 to LFMChangeList.Count-1 do begin
|
||||
Entry:=TLFMChangeEntry(LFMChangeList[i]);
|
||||
if ((Entry.StartPos<EndPos) and (Entry.EndPos>StartPos)) then begin
|
||||
// New and Entry intersects
|
||||
if (Entry.NewText='') and (NewText='') then begin
|
||||
// both are deletes => combine
|
||||
StartPos:=Min(StartPos,Entry.StartPos);
|
||||
EndPos:=Max(EndPos,Entry.EndPos);
|
||||
end else begin
|
||||
// not allowed
|
||||
RaiseException('TCheckLFMDialog.AddReplaceMent invalid Intersection');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// combine deletions
|
||||
if NewText='' then begin
|
||||
for i:=LFMChangeList.Count-1 downto 0 do begin
|
||||
Entry:=TLFMChangeEntry(LFMChangeList[i]);
|
||||
if ((Entry.StartPos<EndPos) and (Entry.EndPos>StartPos)) then begin
|
||||
// New and Entry intersects
|
||||
// -> remove Entry
|
||||
LFMChangeList.Delete(i);
|
||||
Entry.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// insert new entry
|
||||
NewEntry:=TLFMChangeEntry.Create;
|
||||
NewEntry.NewText:=NewText;
|
||||
NewEntry.StartPos:=StartPos;
|
||||
NewEntry.EndPos:=EndPos;
|
||||
if LFMChangeList.Count=0 then begin
|
||||
LFMChangeList.Add(NewEntry);
|
||||
end else begin
|
||||
for i:=0 to LFMChangeList.Count-1 do begin
|
||||
Entry:=TLFMChangeEntry(LFMChangeList[i]);
|
||||
if EndPos<=Entry.StartPos then begin
|
||||
// insert in front
|
||||
LFMChangeList.Insert(i,NewEntry);
|
||||
break;
|
||||
end else if i=LFMChangeList.Count-1 then begin
|
||||
// insert behind
|
||||
LFMChangeList.Add(NewEntry);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFixLFMDialog.ApplyReplacements(LFMChangeList: TList): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
Entry: TLFMChangeEntry;
|
||||
begin
|
||||
Result:=false;
|
||||
for i:=LFMChangeList.Count-1 downto 0 do begin
|
||||
Entry:=TLFMChangeEntry(LFMChangeList[i]);
|
||||
// DebugLn('TCheckLFMDialog.ApplyReplacements A ',IntToStr(i),' ',
|
||||
// IntToStr(Entry.StartPos),',',IntToStr(Entry.EndPos),
|
||||
// ' "',copy(LFMSource.Source,Entry.StartPos,Entry.EndPos-Entry.StartPos),'" -> "',Entry.NewText,'"');
|
||||
LFMSource.Replace(Entry.StartPos,Entry.EndPos-Entry.StartPos,Entry.NewText);
|
||||
end;
|
||||
//writeln(LFMSource.Source);
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.LoadLFM;
|
||||
begin
|
||||
LFMSynEdit.Lines.Text:=LFMSource.Source;
|
||||
FillErrorsListBox;
|
||||
end;
|
||||
|
||||
procedure TFixLFMDialog.FillErrorsListBox;
|
||||
var
|
||||
CurError: TLFMError;
|
||||
Filename: String;
|
||||
Msg: String;
|
||||
begin
|
||||
ErrorsListBox.Items.BeginUpdate;
|
||||
ErrorsListBox.Items.Clear;
|
||||
if LFMTree<>nil then begin
|
||||
Filename:=ExtractFileName(LFMSource.Filename);
|
||||
CurError:=LFMTree.FirstError;
|
||||
while CurError<>nil do begin
|
||||
Msg:=Filename
|
||||
+'('+IntToStr(CurError.Caret.Y)+','+IntToStr(CurError.Caret.X)+')'
|
||||
+' Error: '
|
||||
+CurError.ErrorMessage;
|
||||
ErrorsListBox.Items.Add(Msg);
|
||||
CurError:=CurError.NextError;
|
||||
end;
|
||||
end;
|
||||
ErrorsListBox.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
function TFixLFMDialog.AutomaticFixIsPossible: boolean;
|
||||
var
|
||||
CurError: TLFMError;
|
||||
begin
|
||||
Result:=true;
|
||||
CurError:=LFMTree.FirstError;
|
||||
while CurError<>nil do begin
|
||||
if CurError.ErrorType in [lfmeNoError,lfmeIdentifierNotFound,
|
||||
lfmeObjectNameMissing,lfmeObjectIncompatible,lfmePropertyNameMissing,
|
||||
lfmePropertyHasNoSubProperties,lfmeIdentifierNotPublished]
|
||||
then begin
|
||||
// these things can be fixed automatically
|
||||
end else begin
|
||||
// these not
|
||||
Result:=false;
|
||||
exit;
|
||||
end;
|
||||
CurError:=CurError.NextError;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user