mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-04 05:47:19 +01:00
gtk2 intf: added focus events for combobox, ideintf: textconverter now supports codetool buffers, h2pas wiz: added tool to remove redfinitions, reduced warnings
git-svn-id: trunk@11733 -
This commit is contained in:
parent
80a0bfee01
commit
3b69506329
@ -39,8 +39,8 @@
|
||||
ToDo:
|
||||
-add code for index properties (TList, TFPList, array of, Pointer array)
|
||||
TList:
|
||||
property Items[Index: integer]: AType accesstlist;
|
||||
-> creates
|
||||
property Items[Index: integer]: AType;
|
||||
-> creates via dialog
|
||||
property Items[Index: integer]: Type2 read GetItems write SetItems;
|
||||
private FItems: TList;
|
||||
private function GetItems(Index: integer): Type2;
|
||||
@ -108,7 +108,7 @@ type
|
||||
const VariableName: string; var VariableType: string;
|
||||
IsMethod: boolean; NewLocation: TNewVarLocation
|
||||
): boolean;
|
||||
|
||||
|
||||
{ TCodeCompletionCodeTool }
|
||||
|
||||
TCodeCompletionCodeTool = class(TMethodJumpingCodeTool)
|
||||
@ -188,6 +188,15 @@ type
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
function AddPublishedVariable(const UpperClassName,VarName, VarType: string;
|
||||
SourceChangeCache: TSourceChangeCache): boolean; override;
|
||||
function GetRedefinitionNodeText(Node: TCodeTreeNode): string;
|
||||
function FindRedefinitions(out TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
WithEnums: boolean): boolean;
|
||||
function RemoveRedefinitions(TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
function FindAliasDefinitions(out TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
OnlyWrongType: boolean): boolean;
|
||||
function FixAliasDefinitions(TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
|
||||
// custom class completion
|
||||
function InitClassCompletion(const UpperClassName: string;
|
||||
@ -1102,6 +1111,307 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.GetRedefinitionNodeText(Node: TCodeTreeNode
|
||||
): string;
|
||||
begin
|
||||
case Node.Desc of
|
||||
ctnProcedure:
|
||||
Result:=ExtractProcHead(Node,[phpInUpperCase,phpWithoutSemicolon]);
|
||||
ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition,ctnEnumIdentifier:
|
||||
Result:=ExtractDefinitionName(Node);
|
||||
else
|
||||
Result:='';
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.FindRedefinitions(
|
||||
out TreeOfCodeTreeNodeExt: TAVLTree; WithEnums: boolean): boolean;
|
||||
var
|
||||
AllNodes: TAVLTree;
|
||||
|
||||
procedure AddRedefinition(Redefinition, Definition: TCodeTreeNode;
|
||||
const NodeText: string);
|
||||
var
|
||||
NodeExt: TCodeTreeNodeExtension;
|
||||
begin
|
||||
DebugLn(['AddRedefinition ',NodeText,' Redefined=',CleanPosToStr(Redefinition.StartPos),' Definition=',CleanPosToStr(Definition.StartPos)]);
|
||||
if TreeOfCodeTreeNodeExt=nil then
|
||||
TreeOfCodeTreeNodeExt:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||
NodeExt:=NodeExtMemManager.NewNode;
|
||||
NodeExt.Node:=Redefinition;
|
||||
NodeExt.Data:=Definition;
|
||||
NodeExt.Txt:=NodeText;
|
||||
TreeOfCodeTreeNodeExt.Add(NodeExt);
|
||||
end;
|
||||
|
||||
procedure AddDefinition(Node: TCodeTreeNode; const NodeText: string);
|
||||
var
|
||||
NodeExt: TCodeTreeNodeExtension;
|
||||
begin
|
||||
NodeExt:=NodeExtMemManager.NewNode;
|
||||
NodeExt.Node:=Node;
|
||||
NodeExt.Txt:=NodeText;
|
||||
AllNodes.Add(NodeExt);
|
||||
end;
|
||||
|
||||
var
|
||||
Node: TCodeTreeNode;
|
||||
NodeText: String;
|
||||
AVLNode: TAVLTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
BuildTree(true);
|
||||
|
||||
AllNodes:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||
try
|
||||
Node:=Tree.Root;
|
||||
while Node<>nil do begin
|
||||
case Node.Desc of
|
||||
ctnImplementation, ctnInitialization, ctnFinalization,
|
||||
ctnBeginBlock, ctnAsmBlock:
|
||||
// skip implementation
|
||||
break;
|
||||
ctnVarDefinition, ctnTypeDefinition, ctnConstDefinition, ctnProcedure,
|
||||
ctnEnumIdentifier:
|
||||
begin
|
||||
NodeText:=GetRedefinitionNodeText(Node);
|
||||
AVLNode:=FindCodeTreeNodeExtAVLNode(AllNodes,NodeText);
|
||||
if AVLNode<>nil then begin
|
||||
AddRedefinition(Node,TCodeTreeNodeExtension(AVLNode.Data).Node,NodeText);
|
||||
end else begin
|
||||
AddDefinition(Node,NodeText);
|
||||
end;
|
||||
if WithEnums
|
||||
and (Node.FirstChild<>nil)
|
||||
and (Node.FirstChild.Desc=ctnEnumerationType) then
|
||||
Node:=Node.FirstChild
|
||||
else
|
||||
Node:=Node.NextSkipChilds;
|
||||
end;
|
||||
else
|
||||
Node:=Node.Next;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
AllNodes.FreeAndClear;
|
||||
AllNodes.Free;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.RemoveRedefinitions(
|
||||
TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var
|
||||
AVLNode: TAVLTreeNode;
|
||||
NodesToDo: TAVLTree;
|
||||
Node: TCodeTreeNode;
|
||||
StartNode: TCodeTreeNode;
|
||||
EndNode: TCodeTreeNode;
|
||||
IsListStart: Boolean;
|
||||
IsListEnd: Boolean;
|
||||
StartPos: LongInt;
|
||||
EndPos: LongInt;
|
||||
begin
|
||||
Result:=false;
|
||||
if SourceChangeCache=nil then exit;
|
||||
if (TreeOfCodeTreeNodeExt=nil) or (TreeOfCodeTreeNodeExt.Count=0) then exit;
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
|
||||
NodesToDo:=TAVLTree.Create;
|
||||
try
|
||||
// put the nodes to remove into the NodesToDo
|
||||
AVLNode:=TreeOfCodeTreeNodeExt.FindLowest;
|
||||
while AVLNode<>nil do begin
|
||||
NodesToDo.Add(TCodeTreeNodeExtension(AVLNode.Data).Node);
|
||||
AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
|
||||
end;
|
||||
|
||||
// delete all redefinitions
|
||||
while NodesToDo.Count>0 do begin
|
||||
// find a block of redefinitions
|
||||
StartNode:=TCodeTreeNode(NodesToDo.Root.Data);
|
||||
EndNode:=StartNode;
|
||||
while (StartNode.PriorBrother<>nil)
|
||||
and (NodesToDo.Find(StartNode.PriorBrother)<>nil) do
|
||||
StartNode:=StartNode.PriorBrother;
|
||||
while (EndNode.NextBrother<>nil)
|
||||
and (NodesToDo.Find(EndNode.NextBrother)<>nil) do
|
||||
EndNode:=EndNode.NextBrother;
|
||||
|
||||
// check if a whole section is deleted
|
||||
if (StartNode.PriorBrother=nil) and (EndNode.PriorBrother=nil)
|
||||
and (StartNode.Parent<>nil)
|
||||
and (StartNode.Parent.Desc in AllDefinitionSections) then begin
|
||||
StartNode:=StartNode.Parent;
|
||||
EndNode:=StartNode;
|
||||
end;
|
||||
|
||||
// compute nice code positions to delete
|
||||
StartPos:=FindLineEndOrCodeInFrontOfPosition(StartNode.StartPos);
|
||||
EndPos:=FindLineEndOrCodeAfterPosition(EndNode.EndPos);
|
||||
|
||||
// check list of definitions
|
||||
if EndNode.Desc in AllIdentifierDefinitions then begin
|
||||
// check list definition. For example:
|
||||
// delete, delete: char; -> delete whole
|
||||
// a,delete, delete: char; -> a: char;
|
||||
// delete,delete,c: char; -> c: char;
|
||||
// a,delete,delete,c: char; -> a,c:char;
|
||||
IsListStart:=(StartNode.PriorBrother<>nil)
|
||||
and (StartNode.PriorBrother.FirstChild<>nil);
|
||||
IsListEnd:=(EndNode.FirstChild<>nil);
|
||||
if IsListStart and IsListEnd then begin
|
||||
// case 1: delete, delete: char; -> delete whole
|
||||
end else begin
|
||||
// case 2-4: keep type
|
||||
// get start position of first deleting identifier
|
||||
StartPos:=StartNode.StartPos;
|
||||
// get end position of last deleting identifier
|
||||
EndPos:=EndNode.StartPos+GetIdentLen(@Src[EndNode.StartPos]);
|
||||
if IsListEnd then begin
|
||||
// case 2: a,delete, delete: char; -> a: char;
|
||||
// delete comma in front of start too
|
||||
MoveCursorToCleanPos(StartNode.PriorBrother.StartPos);
|
||||
ReadNextAtom; // read identifier
|
||||
ReadNextAtom; // read comma
|
||||
StartPos:=CurPos.StartPos;
|
||||
end else begin
|
||||
// case 3,4
|
||||
// delete comma behind end too
|
||||
MoveCursorToCleanPos(EndNode.StartPos);
|
||||
ReadNextAtom; // read identifier
|
||||
ReadNextAtom; // read comma
|
||||
EndPos:=CurPos.StartPos;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// replace
|
||||
DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions deleting:']);
|
||||
debugln('"',copy(Src,StartPos,EndPos-StartPos),'"');
|
||||
|
||||
if not SourceChangeCache.Replace(gtNone,gtNone,StartPos,EndPos,'') then
|
||||
exit;
|
||||
|
||||
// remove nodes from NodesToDo
|
||||
Node:=StartNode;
|
||||
repeat
|
||||
NodesToDo.Remove(Node);
|
||||
if Node=EndNode then break;
|
||||
Node:=Node.Next;
|
||||
until false;
|
||||
end;
|
||||
finally
|
||||
NodesToDo.Free;
|
||||
end;
|
||||
|
||||
Result:=SourceChangeCache.Apply;
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.FindAliasDefinitions(out
|
||||
TreeOfCodeTreeNodeExt: TAVLTree; OnlyWrongType: boolean): boolean;
|
||||
var
|
||||
NodeExt: TCodeTreeNodeExtension;
|
||||
AllNodes: TAVLTree;
|
||||
Node: TCodeTreeNode;
|
||||
NodeText: String;
|
||||
AVLNode: TAVLTreeNode;
|
||||
ReferingNode: TCodeTreeNode;
|
||||
ReferingNodeText: String;
|
||||
WrongType: Boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
BuildTree(true);
|
||||
|
||||
AllNodes:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||
try
|
||||
Node:=Tree.Root;
|
||||
while Node<>nil do begin
|
||||
case Node.Desc of
|
||||
ctnImplementation, ctnInitialization, ctnFinalization,
|
||||
ctnBeginBlock, ctnAsmBlock:
|
||||
// skip implementation
|
||||
break;
|
||||
ctnTypeDefinition, ctnConstDefinition:
|
||||
begin
|
||||
if OnlyWrongType then begin
|
||||
// remember the definition
|
||||
NodeText:=GetRedefinitionNodeText(Node);
|
||||
AVLNode:=FindCodeTreeNodeExtAVLNode(AllNodes,NodeText);
|
||||
if AVLNode=nil then begin
|
||||
// add new node
|
||||
NodeExt:=NodeExtMemManager.NewNode;
|
||||
NodeExt.Node:=Node;
|
||||
NodeExt.Txt:=NodeText;
|
||||
AllNodes.Add(NodeExt);
|
||||
end else begin
|
||||
// update node
|
||||
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
|
||||
NodeExt.Node:=Node;
|
||||
end;
|
||||
end;
|
||||
|
||||
// check if definition is an alias
|
||||
// Example: const A = B;
|
||||
if (Node.Parent<>nil)
|
||||
and (Node.Parent.Desc in [ctnConstSection,ctnTypeSection])
|
||||
and (Node.FirstChild<>nil)
|
||||
and (Node.FirstChild.Desc=ctnIdentifier) then begin
|
||||
// this is a const or type alias
|
||||
DebugLn(['TCodeCompletionCodeTool.FindAliasDefinitions Alias: ',ExtractNode(Node,[])]);
|
||||
WrongType:=false;
|
||||
ReferingNode:=nil;
|
||||
if OnlyWrongType then begin
|
||||
ReferingNodeText:=GetIdentifier(@Src[Node.FirstChild.StartPos]);
|
||||
AVLNode:=FindCodeTreeNodeExtAVLNode(AllNodes,ReferingNodeText);
|
||||
if (AVLNode<>nil) then begin
|
||||
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
|
||||
ReferingNode:=NodeExt.Node;
|
||||
if ReferingNode.Desc<>Node.Desc then begin
|
||||
// this alias has wrong type
|
||||
WrongType:=true;
|
||||
DebugLn(['TCodeCompletionCodeTool.FindAliasDefinitions Wrong: ',ReferingNode.DescAsString,'<>',Node.DescAsString]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (not WrongType) or OnlyWrongType then begin
|
||||
// add alias
|
||||
if TreeOfCodeTreeNodeExt=nil then
|
||||
TreeOfCodeTreeNodeExt:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||
NodeExt:=NodeExtMemManager.NewNode;
|
||||
NodeExt.Node:=Node;
|
||||
NodeExt.Txt:=GetRedefinitionNodeText(Node);
|
||||
NodeExt.Data:=ReferingNode;
|
||||
TreeOfCodeTreeNodeExt.Add(NodeExt);
|
||||
end;
|
||||
end;
|
||||
|
||||
Node:=Node.NextSkipChilds;
|
||||
end;
|
||||
ctnProcedure:
|
||||
Node:=Node.NextSkipChilds;
|
||||
else
|
||||
Node:=Node.Next;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
AllNodes.FreeAndClear;
|
||||
AllNodes.Free;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.FixAliasDefinitions(
|
||||
TreeOfCodeTreeNodeExt: TAVLTree; SourceChangeCache: TSourceChangeCache
|
||||
): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.InitClassCompletion(
|
||||
const UpperClassName: string;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
@ -1829,7 +2139,7 @@ begin
|
||||
Indent:=GetLineIndent(Src,InsertNode.StartPos);
|
||||
if InsertBehind then begin
|
||||
// insert behind InsertNode
|
||||
InsertPos:=FindFirstLineEndAfterInCode(InsertNode.EndPos);
|
||||
InsertPos:=FindLineEndOrCodeAfterPosition(InsertNode.EndPos);
|
||||
end else begin
|
||||
// insert in front of InsertNode
|
||||
InsertPos:=InsertNode.StartPos;
|
||||
@ -1838,7 +2148,7 @@ begin
|
||||
// insert as first variable/proc
|
||||
Indent:=GetLineIndent(Src,ClassSectionNode.StartPos)
|
||||
+ASourceChangeCache.BeautifyCodeOptions.Indent;
|
||||
InsertPos:=FindFirstLineEndAfterInCode(ClassSectionNode.StartPos);
|
||||
InsertPos:=FindLineEndOrCodeAfterPosition(ClassSectionNode.StartPos);
|
||||
end;
|
||||
end;
|
||||
CurCode:=ANodeExt.ExtTxt1;
|
||||
|
||||
@ -406,6 +406,18 @@ type
|
||||
function CompleteCode(Code: TCodeBuffer; X,Y,TopLine: integer;
|
||||
out NewCode: TCodeBuffer;
|
||||
out NewX, NewY, NewTopLine: integer): boolean;
|
||||
function FindRedefinitions(Code: TCodeBuffer;
|
||||
out TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
WithEnums: boolean): boolean;
|
||||
function RemoveRedefinitions(Code: TCodeBuffer;
|
||||
TreeOfCodeTreeNodeExt: TAVLTree): boolean;
|
||||
function RemoveAllRedefinitions(Code: TCodeBuffer): boolean;
|
||||
function FindAliasDefinitions(Code: TCodeBuffer;
|
||||
out TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
OnlyWrongType: boolean): boolean;
|
||||
function FixAliasDefinitions(Code: TCodeBuffer;
|
||||
TreeOfCodeTreeNodeExt: TAVLTree): boolean;
|
||||
function FixAllAliasDefinitions(Code: TCodeBuffer): boolean;
|
||||
|
||||
// custom class completion
|
||||
function InitClassCompletion(Code: TCodeBuffer;
|
||||
@ -2699,6 +2711,127 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.FindRedefinitions(Code: TCodeBuffer; out
|
||||
TreeOfCodeTreeNodeExt: TAVLTree; WithEnums: boolean): boolean;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.FindRedefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.FindRedefinitions(TreeOfCodeTreeNodeExt,WithEnums);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.RemoveRedefinitions(Code: TCodeBuffer;
|
||||
TreeOfCodeTreeNodeExt: TAVLTree): boolean;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.RemoveRedefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.RemoveRedefinitions(TreeOfCodeTreeNodeExt,
|
||||
SourceChangeCache);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.RemoveAllRedefinitions(Code: TCodeBuffer): boolean;
|
||||
var
|
||||
TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.RemoveAllRedefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
try
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.FindRedefinitions(TreeOfCodeTreeNodeExt,false);
|
||||
if not Result then exit;
|
||||
Result:=FCurCodeTool.RemoveRedefinitions(TreeOfCodeTreeNodeExt,
|
||||
SourceChangeCache);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
finally
|
||||
if TreeOfCodeTreeNodeExt<>nil then begin
|
||||
TreeOfCodeTreeNodeExt.FreeAndClear;
|
||||
TreeOfCodeTreeNodeExt.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.FindAliasDefinitions(Code: TCodeBuffer; out
|
||||
TreeOfCodeTreeNodeExt: TAVLTree; OnlyWrongType: boolean): boolean;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.FindAliasDefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.FindAliasDefinitions(TreeOfCodeTreeNodeExt,
|
||||
OnlyWrongType);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.FixAliasDefinitions(Code: TCodeBuffer;
|
||||
TreeOfCodeTreeNodeExt: TAVLTree): boolean;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.FixAliasDefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.FixAliasDefinitions(TreeOfCodeTreeNodeExt,
|
||||
SourceChangeCache);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.FixAllAliasDefinitions(Code: TCodeBuffer): boolean;
|
||||
var
|
||||
TreeOfCodeTreeNodeExt: TAVLTree;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeToolManager.FixAllAliasDefinitions A ',Code.Filename);
|
||||
{$ENDIF}
|
||||
Result:=false;
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
try
|
||||
TreeOfCodeTreeNodeExt:=nil;
|
||||
if not InitCurCodeTool(Code) then exit;
|
||||
try
|
||||
Result:=FCurCodeTool.FindAliasDefinitions(TreeOfCodeTreeNodeExt,true);
|
||||
if not Result then exit;
|
||||
Result:=FCurCodeTool.FixAliasDefinitions(TreeOfCodeTreeNodeExt,
|
||||
SourceChangeCache);
|
||||
except
|
||||
on e: Exception do Result:=HandleException(e);
|
||||
end;
|
||||
finally
|
||||
if TreeOfCodeTreeNodeExt<>nil then begin
|
||||
TreeOfCodeTreeNodeExt.FreeAndClear;
|
||||
TreeOfCodeTreeNodeExt.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCodeToolManager.InitClassCompletion(Code: TCodeBuffer;
|
||||
const UpperClassName: string; out CodeTool: TCodeTool): boolean;
|
||||
begin
|
||||
|
||||
@ -238,6 +238,9 @@ type
|
||||
procedure WriteDebugReport(WithChilds: boolean);
|
||||
end;
|
||||
|
||||
|
||||
{ TCodeTreeNodeExtension }
|
||||
|
||||
TCodeTreeNodeExtension = class
|
||||
public
|
||||
Node: TCodeTreeNode;
|
||||
@ -249,12 +252,13 @@ type
|
||||
Next: TCodeTreeNodeExtension;
|
||||
procedure Clear;
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function ConsistencyCheck: integer; // 0 = ok
|
||||
procedure WriteDebugReport;
|
||||
end;
|
||||
|
||||
// memory system for TCodeTreeNode(s)
|
||||
|
||||
{ TCodeTreeNodeMemManager - memory system for TCodeTreeNode(s) }
|
||||
|
||||
TCodeTreeNodeMemManager = class(TCodeToolMemManager)
|
||||
protected
|
||||
procedure FreeFirstItem; override;
|
||||
@ -263,7 +267,9 @@ type
|
||||
function NewNode: TCodeTreeNode;
|
||||
end;
|
||||
|
||||
// memory system for TCodeTreeNodeExtension(s)
|
||||
|
||||
{ TCodeTreeNodeExtMemManager - memory system for TCodeTreeNodeExtension(s) }
|
||||
|
||||
TCodeTreeNodeExtMemManager = class(TCodeToolMemManager)
|
||||
protected
|
||||
procedure FreeFirstItem; override;
|
||||
@ -783,11 +789,6 @@ begin
|
||||
Position:=-1;
|
||||
end;
|
||||
|
||||
destructor TCodeTreeNodeExtension.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TCodeTreeNodeExtension.ConsistencyCheck: integer;
|
||||
// 0 = ok
|
||||
begin
|
||||
|
||||
@ -204,7 +204,6 @@ type
|
||||
function FindLineEndOrCodeInFrontOfPosition(StartPos: integer): integer;
|
||||
function FindLineEndOrCodeInFrontOfPosition(StartPos: integer;
|
||||
StopAtDirectives: boolean): integer;
|
||||
function FindFirstLineEndAfterInCode(StartPos: integer): integer;
|
||||
|
||||
function UpdateNeeded(OnlyInterfaceNeeded: boolean): boolean;
|
||||
procedure BeginParsing(DeleteNodes, OnlyInterfaceNeeded: boolean); virtual;
|
||||
@ -1805,7 +1804,7 @@ var NewPos: integer;
|
||||
begin
|
||||
if Src='' then
|
||||
RaiseSrcEmpty;
|
||||
NewPos:=PtrInt(ACleanPos)-PtrInt(@Src[1])+1;
|
||||
NewPos:=PtrInt(PtrUInt(ACleanPos))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>SrcLen) then
|
||||
RaiseNotInSrc;
|
||||
MoveCursorToCleanPos(NewPos);
|
||||
@ -1852,7 +1851,7 @@ var NewPos: integer;
|
||||
begin
|
||||
Result:=false;
|
||||
if Src='' then exit;
|
||||
NewPos:=PtrInt(ACleanPos)-PtrInt(@Src[1])+1;
|
||||
NewPos:=PtrInt(PtrUInt(ACleanPos))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>SrcLen) then exit;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2282,23 +2281,6 @@ begin
|
||||
StartPos,LinkStart,Scanner.NestedComments,StopAtDirectives);
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.FindFirstLineEndAfterInCode(StartPos: integer
|
||||
): integer;
|
||||
{ Searches a line end or code break in the cleaned source after StartPos.
|
||||
It will skip any line ends in comments.
|
||||
}
|
||||
var
|
||||
LinkIndex, LinkEnd: integer;
|
||||
begin
|
||||
LinkIndex:=Scanner.LinkIndexAtCleanPos(StartPos);
|
||||
LinkEnd:=Scanner.LinkCleanedEndPos(LinkIndex);
|
||||
if LinkEnd>StartPos then
|
||||
Result:=BasicCodeTools.FindFirstLineEndAfterInCode(Src,
|
||||
StartPos,LinkEnd-1,Scanner.NestedComments)
|
||||
else
|
||||
Result:=StartPos;
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.ClearIgnoreErrorAfter;
|
||||
begin
|
||||
IgnoreErrorAfter:=CodePosition(0,nil);
|
||||
@ -2555,7 +2537,7 @@ var NewPos: integer;
|
||||
begin
|
||||
Result:=false;
|
||||
if Src='' then exit;
|
||||
NewPos:=PtrInt(p)-PtrInt(@Src[1])+1;
|
||||
NewPos:=PtrInt(PtrUInt(p))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>length(Src)) then exit;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2583,7 +2565,7 @@ var NewPos: integer;
|
||||
begin
|
||||
if Src='' then
|
||||
RaiseSrcEmpty;
|
||||
NewPos:=PtrInt(APos)-PtrInt(@Src[1])+1;
|
||||
NewPos:=PtrInt(PtrUInt(APos))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>length(Src)) then
|
||||
RaiseNotInSrc;
|
||||
MoveCursorToPos(NewPos);
|
||||
|
||||
@ -1025,8 +1025,6 @@ var
|
||||
child: TDOMNode;
|
||||
begin
|
||||
Result := nil;
|
||||
if index < 0 then
|
||||
exit;
|
||||
child := node.FirstChild;
|
||||
while Assigned(child) do
|
||||
begin
|
||||
|
||||
@ -1463,7 +1463,7 @@ begin
|
||||
if OldPosition.StartPos>0 then begin
|
||||
OldPosition.StartPos:=FindLineEndOrCodeInFrontOfPosition(
|
||||
OldPosition.StartPos);
|
||||
OldPosition.EndPos:=FindFirstLineEndAfterInCode(OldPosition.EndPos);
|
||||
OldPosition.EndPos:=FindLineEndOrCodeAfterPosition(OldPosition.EndPos);
|
||||
if not SourceChangeCache.Replace(gtNone,gtNone,
|
||||
OldPosition.StartPos,OldPosition.EndPos,'') then exit;
|
||||
end;
|
||||
@ -2172,7 +2172,7 @@ begin
|
||||
end else begin
|
||||
// it exists -> replace it
|
||||
FromPos:=FindLineEndOrCodeInFrontOfPosition(OldPosition.StartPos);
|
||||
ToPos:=FindFirstLineEndAfterInCode(OldPosition.EndPos);
|
||||
ToPos:=FindLineEndOrCodeAfterPosition(OldPosition.EndPos);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
SourceChangeCache.Replace(gtNewLine,gtNewLine,FromPos,ToPos,
|
||||
SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
|
||||
@ -2191,7 +2191,7 @@ begin
|
||||
if FindCreateFormStatement(-1,'*',UpperVarName,Position)=-1 then
|
||||
exit;
|
||||
FromPos:=FindLineEndOrCodeInFrontOfPosition(Position.StartPos);
|
||||
ToPos:=FindFirstLineEndAfterInCode(Position.EndPos);
|
||||
ToPos:=FindLineEndOrCodeAfterPosition(Position.EndPos);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,'');
|
||||
Result:=SourceChangeCache.Apply;
|
||||
@ -2226,7 +2226,7 @@ begin
|
||||
end else begin
|
||||
// replace
|
||||
FromPos:=FindLineEndOrCodeInFrontOfPosition(OldPosition.StartPos);
|
||||
ToPos:=FindFirstLineEndAfterInCode(OldPosition.EndPos);
|
||||
ToPos:=FindLineEndOrCodeAfterPosition(OldPosition.EndPos);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
SourceChangeCache.Replace(gtNewLine,gtNewLine,FromPos,ToPos,
|
||||
SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
|
||||
@ -2296,7 +2296,7 @@ begin
|
||||
StatementPos.StartPos:= FindLineEndOrCodeInFrontOfPosition(StatementPos.StartPos);
|
||||
if InsertPos < 1 then InsertPos:= StatementPos.StartPos;
|
||||
|
||||
StatementPos.EndPos:= FindFirstLineEndAfterInCode(StatementPos.EndPos);
|
||||
StatementPos.EndPos:= FindLineEndOrCodeAfterPosition(StatementPos.EndPos);
|
||||
|
||||
SourceChangeCache.Replace(gtNone,gtNone, StatementPos.StartPos, StatementPos.EndPos, '');
|
||||
until false;
|
||||
@ -2454,7 +2454,7 @@ begin
|
||||
if StringConstStartPos=0 then ;
|
||||
// -> delete whole line
|
||||
FromPos:=FindLineEndOrCodeInFrontOfPosition(StartPos);
|
||||
ToPos:=FindFirstLineEndAfterInCode(EndPos);
|
||||
ToPos:=FindLineEndOrCodeAfterPosition(EndPos);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
if not SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,'') then exit;
|
||||
if not SourceChangeCache.Apply then exit;
|
||||
@ -3825,7 +3825,7 @@ begin
|
||||
NearestNode:=CursorTool.FindNearestIdentifierNode(CursorPos,IdentTree);
|
||||
if NearestNode=nil then exit;
|
||||
// convert node to cleanpos
|
||||
NearestCleanPos:=PtrInt(NearestNode.Data)-PtrInt(@SectionTool.Src[1])+1;
|
||||
NearestCleanPos:=PtrUInt(NearestNode.Data)-PtrUInt(@SectionTool.Src[1])+1;
|
||||
// convert cleanpos to caret
|
||||
CleanPosToCaret(NearestCleanPos,NearestPos);
|
||||
finally
|
||||
@ -4046,7 +4046,7 @@ begin
|
||||
// variable definition has the form 'VarName: VarType;'
|
||||
// -> delete whole line
|
||||
FromPos:=FindLineEndOrCodeInFrontOfPosition(VarNode.StartPos);
|
||||
ToPos:=FindFirstLineEndAfterInCode(VarNode.EndPos);
|
||||
ToPos:=FindLineEndOrCodeAfterPosition(VarNode.EndPos);
|
||||
end else begin
|
||||
// variable definition has the form 'VarName, NextVarName: VarType;'
|
||||
// -> delete only 'VarName, '
|
||||
@ -4233,7 +4233,7 @@ var
|
||||
PropInfo:=PPropInfo(PByte(@TypeData^.UnitName)+Length(TypeData^.UnitName)+1);
|
||||
// read property count
|
||||
CurCount:=PWord(PropInfo)^;
|
||||
inc(PtrInt(PropInfo),SizeOf(Word));
|
||||
inc(PtrUInt(PropInfo),SizeOf(Word));
|
||||
//debugln(' UnitName=',TypeData^.UnitName,' Type=',TypeInfo^.Name,' CurPropCount=',dbgs(CurCount));
|
||||
// read properties
|
||||
while CurCount>0 do begin
|
||||
|
||||
@ -26,7 +26,7 @@ uses
|
||||
Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage,
|
||||
Forms, Controls, Dialogs, FileUtil, FileProcs, AvgLvlTree,
|
||||
// CodeTools
|
||||
KeywordFuncLists, BasicCodeTools,
|
||||
KeywordFuncLists, BasicCodeTools, CodeCache, CodeToolManager,
|
||||
// IDEIntf
|
||||
TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf,
|
||||
IDEMsgIntf, IDETextConverter;
|
||||
@ -41,6 +41,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TRemoveEmptyCMacrosTool - Remove empty C macros}
|
||||
|
||||
TRemoveEmptyCMacrosTool = class(TCustomTextConverterTool)
|
||||
@ -49,6 +50,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TReplaceEdgedBracketPairWithStar - Replace [] with * }
|
||||
|
||||
TReplaceEdgedBracketPairWithStar = class(TCustomTextReplaceTool)
|
||||
@ -57,6 +59,7 @@ type
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
end;
|
||||
|
||||
|
||||
{ TReplace0PointerWithNULL -
|
||||
Replace macro values 0 pointer like (char *)0 with NULL }
|
||||
|
||||
@ -65,6 +68,7 @@ type
|
||||
class function ClassDescription: string; override;
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TReplaceUnitFilenameWithUnitName -
|
||||
Replace "unit filename;" with "unit name;" }
|
||||
@ -75,6 +79,7 @@ type
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
end;
|
||||
|
||||
|
||||
{ TRemoveSystemTypes -
|
||||
Remove type redefinitons like PLongint }
|
||||
|
||||
@ -84,6 +89,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TRemoveRedefinedPointerTypes - Remove redefined pointer types }
|
||||
|
||||
TRemoveRedefinedPointerTypes = class(TCustomTextConverterTool)
|
||||
@ -92,6 +98,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TRemoveEmptyTypeVarConstSections - Remove empty type/var/const sections }
|
||||
|
||||
TRemoveEmptyTypeVarConstSections = class(TCustomTextConverterTool)
|
||||
@ -100,6 +107,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TReplaceImplicitTypes -
|
||||
Search implicit types in parameters and add types for them
|
||||
For example:
|
||||
@ -142,6 +150,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
function CodeToIdentifier(const Code: string): string;
|
||||
end;
|
||||
|
||||
|
||||
{ TFixArrayOfParameterType - Replace "array of )" with "array of const)" }
|
||||
|
||||
@ -151,8 +160,33 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TRemoveRedefinitionsInUnit
|
||||
Removes redefinitions of types, variables, constants and resourcestrings }
|
||||
|
||||
TRemoveRedefinitionsInUnit = class(TCustomTextConverterTool)
|
||||
public
|
||||
class function ClassDescription: string; override;
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ TFixAliasDefinitionsInUnit
|
||||
NOT COMPLETE YET
|
||||
|
||||
Checks all alias definitions of the form
|
||||
const LeftSide = RightSide;
|
||||
looks up RightSide in the unit and if RightSide is a type or var, changes
|
||||
the section accordingly }
|
||||
|
||||
TFixAliasDefinitionsInUnit = class(TCustomTextConverterTool)
|
||||
public
|
||||
class function ClassDescription: string; override;
|
||||
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||
end;
|
||||
|
||||
|
||||
{ Proposal:
|
||||
- A tool to collect the content of several units into one
|
||||
- A tool to remove redefinitions
|
||||
- A tool to fix "constant A=B;" to type A=B; or functions
|
||||
- A tool to reorder a unit to fix forward definitions
|
||||
@ -605,13 +639,14 @@ end;
|
||||
function TH2PasFile.IsEqual(AFile: TH2PasFile): boolean;
|
||||
begin
|
||||
Result:=(CompareFilenames(Filename,AFile.Filename)=0)
|
||||
and (Enabled=AFile.Enabled);
|
||||
and (Enabled=AFile.Enabled)
|
||||
and (Merge=AFile.Merge);
|
||||
end;
|
||||
|
||||
procedure TH2PasFile.Load(Config: TConfigStorage);
|
||||
begin
|
||||
FEnabled:=Config.GetValue('Enabled/Value',true);
|
||||
FMerge:=Config.GetValue('Merge/Value',false);
|
||||
FMerge:=Config.GetValue('Merge/Value',true);
|
||||
FFilename:=Config.GetValue('Filename/Value','');
|
||||
if Project<>nil then
|
||||
FFilename:=Project.NormalizeFilename(FFilename);
|
||||
@ -1353,6 +1388,9 @@ begin
|
||||
AddNewTextConverterTool(FPostH2PasTools,TRemoveEmptyTypeVarConstSections);
|
||||
AddNewTextConverterTool(FPostH2PasTools,TReplaceImplicitTypes);
|
||||
AddNewTextConverterTool(FPostH2PasTools,TFixArrayOfParameterType);
|
||||
// the above tools fixed the syntax
|
||||
// now improve the declarations
|
||||
AddNewTextConverterTool(FPostH2PasTools,TRemoveRedefinitionsInUnit);
|
||||
end;
|
||||
|
||||
function TH2PasProject.SearchIncludedCHeaderFile(aFile: TH2PasFile;
|
||||
@ -1787,7 +1825,7 @@ begin
|
||||
CheckedFiles:=TFPList.Create;
|
||||
AddIncludedByFiles(IncludedByFiles,CurFile);
|
||||
if IncludedByFiles.Count>1 then begin
|
||||
// this merged file is included by more than unit
|
||||
// this merged file is included by more than one unit
|
||||
Warning:=Warning
|
||||
+'Warning: the file "'+Project.ShortenFilename(CurFile.Filename)+'"'#13
|
||||
+'will be merged into multiple files:'#13;
|
||||
@ -3085,4 +3123,53 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TRemoveRedefinitionsInUnit }
|
||||
|
||||
class function TRemoveRedefinitionsInUnit.ClassDescription: string;
|
||||
begin
|
||||
Result:='Remove redefinitions in pascal unit';
|
||||
end;
|
||||
|
||||
function TRemoveRedefinitionsInUnit.Execute(aText: TIDETextConverter
|
||||
): TModalResult;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
if (not FilenameIsPascalUnit(aText.Filename)) then begin
|
||||
DebugLn(['TRemoveRedefinitionsInUnit.Execute file is not pascal: ',aText.Filename]);
|
||||
exit(mrOk);// ignore
|
||||
end;
|
||||
if not CodeToolBoss.RemoveAllRedefinitions(TCodeBuffer(aText.CodeBuffer)) then begin
|
||||
DebugLn(['TRemoveRedefinitionsInUnit.Execute RemoveAllRedefinitions failed ',CodeToolBoss.ErrorMessage]);
|
||||
exit;
|
||||
end;
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
{ TFixAliasDefinitionsInUnit }
|
||||
|
||||
class function TFixAliasDefinitionsInUnit.ClassDescription: string;
|
||||
begin
|
||||
Result:='Fixes section type of alias definitions in pascal unit'#13
|
||||
+'Checks all alias definitions of the form'#13
|
||||
+'const LeftSide = RightSide;'#13
|
||||
+'looks up RightSide in the unit and if RightSide is a type or var, changes'
|
||||
+' the section accordingly';
|
||||
end;
|
||||
|
||||
function TFixAliasDefinitionsInUnit.Execute(aText: TIDETextConverter
|
||||
): TModalResult;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
if (not FilenameIsPascalUnit(aText.Filename)) then begin
|
||||
DebugLn(['TRemoveRedefinitionsInUnit.Execute file is not pascal: ',aText.Filename]);
|
||||
exit(mrOk);// ignore
|
||||
end;
|
||||
// ToDo: finish codetools FixAllAliasDefinitions
|
||||
if not CodeToolBoss.FixAllAliasDefinitions(TCodeBuffer(aText.CodeBuffer)) then begin
|
||||
DebugLn(['TRemoveRedefinitionsInUnit.Execute FixAllAliasDefinitions failed ',CodeToolBoss.ErrorMessage]);
|
||||
exit;
|
||||
end;
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -218,6 +218,7 @@ begin
|
||||
TextConverterToolClasses.RegisterClass(TRemoveEmptyTypeVarConstSections);
|
||||
TextConverterToolClasses.RegisterClass(TReplaceImplicitTypes);
|
||||
TextConverterToolClasses.RegisterClass(TFixArrayOfParameterType);
|
||||
TextConverterToolClasses.RegisterClass(TRemoveRedefinitionsInUnit);
|
||||
end;
|
||||
|
||||
{ TH2PasDialog }
|
||||
|
||||
@ -120,7 +120,7 @@ end;
|
||||
|
||||
function TSynEditRegexSearch.GetLength(aIndex: integer): integer;
|
||||
begin
|
||||
Result := PtrInt( fLengths[ aIndex ] );
|
||||
Result := PtrInt(PtrUInt( fLengths[ aIndex ] ));
|
||||
end;
|
||||
|
||||
function TSynEditRegexSearch.GetPattern: string;
|
||||
@ -130,7 +130,7 @@ end;
|
||||
|
||||
function TSynEditRegexSearch.GetResult(aIndex: integer): integer;
|
||||
begin
|
||||
Result := PtrInt( fPositions[ aIndex ] );
|
||||
Result := PtrInt( PtrUint(fPositions[ aIndex ]) );
|
||||
end;
|
||||
|
||||
function TSynEditRegexSearch.GetResultCount: integer;
|
||||
|
||||
@ -3067,7 +3067,7 @@ function TBaseCallStack.GetStackEntry(const AIndex: Integer): TCallStackEntry;
|
||||
var
|
||||
idx: PtrInt;
|
||||
begin
|
||||
idx := PtrInt(FEntryIndex[AIndex]);
|
||||
idx := PtrInt(PtrUInt(FEntryIndex[AIndex]));
|
||||
if idx = -1
|
||||
then begin
|
||||
// not created yet
|
||||
|
||||
@ -48,8 +48,20 @@ type
|
||||
TLazTextConverterToolClasses = class(TTextConverterToolClasses)
|
||||
protected
|
||||
function GetTempFilename: string; override;
|
||||
function SupportsType(aTextType: TTextConverterType): boolean; override;
|
||||
function LoadFromFile(Converter: TIDETextConverter; const AFilename: string;
|
||||
UpdateFromDisk, Revert: Boolean): Boolean; override;
|
||||
function SaveCodeBufferToFile(Converter: TIDETextConverter;
|
||||
const AFilename: string): Boolean; override;
|
||||
function GetCodeBufferSource(Converter: TIDETextConverter;
|
||||
out Source: string): boolean; override;
|
||||
function CreateCodeBuffer(Converter: TIDETextConverter;
|
||||
const Filename, NewSource: string;
|
||||
out CodeBuffer: Pointer): boolean; override;
|
||||
function LoadCodeBufferFromFile(Converter: TIDETextConverter;
|
||||
const Filename: string;
|
||||
UpdateFromDisk, Revert: Boolean;
|
||||
out CodeBuffer: Pointer): boolean; override;
|
||||
end;
|
||||
|
||||
procedure SetupTextConverters;
|
||||
@ -599,6 +611,7 @@ function TLazTextConverterToolClasses.LoadFromFile(
|
||||
var
|
||||
TheFilename: String;
|
||||
CodeBuf: TCodeBuffer;
|
||||
TargetCodeBuffer: TCodeBuffer;
|
||||
begin
|
||||
TheFilename:=CleanAndExpandFilename(AFilename);
|
||||
CodeBuf:=CodeToolBoss.FindFile(TheFilename);
|
||||
@ -622,10 +635,59 @@ begin
|
||||
Result:=SaveStringToFile(Converter.Filename,CodeBuf.Source,[])=mrOk;
|
||||
tctStrings:
|
||||
CodeBuf.AssignTo(Converter.Strings,true);
|
||||
tctCodeBuffer:
|
||||
begin
|
||||
if Converter.CodeBuffer=nil then
|
||||
Converter.CodeBuffer:=CodeBuf
|
||||
else begin
|
||||
TargetCodeBuffer:=(TObject(Converter.CodeBuffer) as TCodeBuffer);
|
||||
if TargetCodeBuffer<>CodeBuf then
|
||||
TargetCodeBuffer.Source:=CodeBuf.Source;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLazTextConverterToolClasses.SaveCodeBufferToFile(
|
||||
Converter: TIDETextConverter; const AFilename: string): Boolean;
|
||||
begin
|
||||
Result:=(TObject(Converter.CodeBuffer) as TCodeBuffer).SaveToFile(AFilename);
|
||||
end;
|
||||
|
||||
function TLazTextConverterToolClasses.GetCodeBufferSource(
|
||||
Converter: TIDETextConverter; out Source: string): boolean;
|
||||
begin
|
||||
Result:=true;
|
||||
Source:=(TObject(Converter.CodeBuffer) as TCodeBuffer).Source;
|
||||
end;
|
||||
|
||||
function TLazTextConverterToolClasses.CreateCodeBuffer(
|
||||
Converter: TIDETextConverter; const Filename, NewSource: string; out
|
||||
CodeBuffer: Pointer): boolean;
|
||||
begin
|
||||
CodeBuffer:=CodeToolBoss.CreateFile(Filename);
|
||||
if CodeBuffer<>nil then begin
|
||||
TCodeBuffer(CodeBuffer).Source:=NewSource;
|
||||
Result:=true;
|
||||
end else
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
function TLazTextConverterToolClasses.LoadCodeBufferFromFile(
|
||||
Converter: TIDETextConverter; const Filename: string;
|
||||
UpdateFromDisk, Revert: Boolean; out CodeBuffer: Pointer): boolean;
|
||||
begin
|
||||
CodeBuffer:=CodeToolBoss.LoadFile(Filename,UpdateFromDisk,Revert);
|
||||
Result:=CodeBuffer<>nil;
|
||||
end;
|
||||
|
||||
function TLazTextConverterToolClasses.SupportsType(aTextType: TTextConverterType
|
||||
): boolean;
|
||||
begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
initialization
|
||||
REException:=ERegExpr;
|
||||
REMatchesFunction:=@SynREMatches;
|
||||
|
||||
@ -27,7 +27,7 @@ unit IDETextConverter;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, Controls, Forms, FileUtil, SrcEditorIntf,
|
||||
Classes, SysUtils, TypInfo, LCLProc, Controls, Forms, FileUtil, SrcEditorIntf,
|
||||
PropEdits;
|
||||
|
||||
type
|
||||
@ -36,13 +36,14 @@ type
|
||||
TTextConverterType = (
|
||||
tctSource,
|
||||
tctFile,
|
||||
tctStrings
|
||||
tctStrings,
|
||||
tctCodeBuffer // TCodeBuffer
|
||||
);
|
||||
|
||||
{ TIDETextConverter
|
||||
A component to hold a Text and tools to change the Text.
|
||||
For example to do several find and replace operations on the text.
|
||||
The Text can be a file, a string or TStrings.
|
||||
The Text can be a file, a string, TStrings or a TCodeBuffer.
|
||||
The Text is converted on the fly, whenever someone reads/write one of the
|
||||
formats.
|
||||
The tools are decendants of TCustomTextConverterTool. }
|
||||
@ -51,16 +52,20 @@ type
|
||||
private
|
||||
FFilename: string;
|
||||
FSource: string;
|
||||
FCodeBuffer: Pointer;
|
||||
FStrings: TStrings;
|
||||
FCurrentType: TTextConverterType;
|
||||
FFileIsTemporary: boolean;
|
||||
FStringsIsTemporary: Boolean;
|
||||
procedure CreateTempFilename;
|
||||
function GetCodeBuffer: Pointer;
|
||||
function GetFilename: string;
|
||||
function GetSource: string;
|
||||
function GetStrings: TStrings;
|
||||
procedure RemoveStrings;
|
||||
procedure SaveToFile(const NewFilename: string);
|
||||
procedure ResetStrings;
|
||||
procedure ResetFile;
|
||||
procedure ConvertToFile(const NewFilename: string);
|
||||
procedure SetCodeBuffer(const AValue: Pointer);
|
||||
procedure SetFilename(const AValue: string);
|
||||
procedure SetSource(const AValue: string);
|
||||
procedure SetStrings(const AValue: TStrings);
|
||||
@ -73,6 +78,8 @@ type
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Clear;
|
||||
procedure CheckType(aTextType: TTextConverterType);
|
||||
function SupportsType(aTextType: TTextConverterType): boolean; virtual;
|
||||
function Execute(ToolList: TComponent): TModalResult;// run the tools
|
||||
function LoadFromFile(const AFilename: string;
|
||||
UseIDECache: Boolean = true;
|
||||
@ -82,8 +89,10 @@ type
|
||||
procedure InitWithFilename(const AFilename: string);
|
||||
procedure InitWithSource(const ASource: string);
|
||||
procedure InitWithStrings(const aStrings: TStrings);
|
||||
procedure InitWithCodeBuffers(const aBuffer: Pointer);
|
||||
property CurrentType: TTextConverterType read FCurrentType write SetCurrentType;
|
||||
property Source: string read GetSource write SetSource;
|
||||
property CodeBuffer: Pointer read GetCodeBuffer write SetCodeBuffer;
|
||||
property Filename: string read GetFilename write SetFilename;
|
||||
property Strings: TStrings read GetStrings write SetStrings;
|
||||
property FileIsTemporary: boolean read FFileIsTemporary write SetFileIsTemporary;
|
||||
@ -98,6 +107,7 @@ type
|
||||
FCaption: string;
|
||||
FDescription: string;
|
||||
FEnabled: boolean;
|
||||
function IsCaptionStored: boolean;
|
||||
procedure SetCaption(const AValue: string);
|
||||
procedure SetDescription(const AValue: string);
|
||||
public
|
||||
@ -107,7 +117,7 @@ type
|
||||
function Execute(aText: TIDETextConverter): TModalResult; virtual; abstract;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
published
|
||||
property Caption: string read FCaption write SetCaption;
|
||||
property Caption: string read FCaption write SetCaption stored IsCaptionStored;
|
||||
property Description: string read FDescription write SetDescription;
|
||||
property Enabled: boolean read FEnabled write FEnabled default True;
|
||||
end;
|
||||
@ -172,9 +182,22 @@ type
|
||||
var ComponentClass: TComponentClass);
|
||||
property Items[Index: integer]: TCustomTextConverterToolClass read GetItems; default;
|
||||
property Count: integer read GetCount;
|
||||
|
||||
function SupportsType(aTextType: TTextConverterType): boolean; virtual; abstract;
|
||||
function GetTempFilename: string; virtual; abstract;
|
||||
function LoadFromFile(Converter: TIDETextConverter; const AFilename: string;
|
||||
UpdateFromDisk, Revert: Boolean): Boolean; virtual; abstract;
|
||||
function SaveCodeBufferToFile(Converter: TIDETextConverter;
|
||||
const AFilename: string): Boolean; virtual; abstract;
|
||||
function GetCodeBufferSource(Converter: TIDETextConverter;
|
||||
out Source: string): boolean; virtual; abstract;
|
||||
function CreateCodeBuffer(Converter: TIDETextConverter;
|
||||
const Filename, NewSource: string;
|
||||
out CodeBuffer: Pointer): boolean; virtual; abstract;
|
||||
function LoadCodeBufferFromFile(Converter: TIDETextConverter;
|
||||
const Filename: string;
|
||||
UpdateFromDisk, Revert: Boolean;
|
||||
out CodeBuffer: Pointer): boolean; virtual; abstract;
|
||||
end;
|
||||
|
||||
var
|
||||
@ -309,7 +332,7 @@ end;
|
||||
|
||||
procedure TIDETextConverter.SetFilename(const AValue: string);
|
||||
begin
|
||||
SaveToFile(AValue);
|
||||
ConvertToFile(AValue);
|
||||
end;
|
||||
|
||||
function TIDETextConverter.GetFilename: string;
|
||||
@ -330,7 +353,7 @@ begin
|
||||
Result:=FStrings;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.RemoveStrings;
|
||||
procedure TIDETextConverter.ResetStrings;
|
||||
begin
|
||||
if StringsIsTemporary then
|
||||
FStrings.Free;
|
||||
@ -338,20 +361,29 @@ begin
|
||||
FStringsIsTemporary:=false;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.ResetFile;
|
||||
begin
|
||||
if FileIsTemporary then begin
|
||||
DeleteFile(FFilename);
|
||||
// do not change FFileIsTemporary, so that File > Source > File sequences
|
||||
// keep the file temporary.
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SetSource(const AValue: string);
|
||||
begin
|
||||
FCurrentType:=tctSource;
|
||||
RemoveStrings;
|
||||
ResetStrings;
|
||||
ResetFile;
|
||||
FSource:=AValue;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SetStrings(const AValue: TStrings);
|
||||
begin
|
||||
FCurrentType:=tctStrings;
|
||||
if (AValue<>FStrings) and StringsIsTemporary then
|
||||
FreeAndNil(FStrings);
|
||||
ResetFile;
|
||||
ResetStrings;
|
||||
FStrings:=AValue;
|
||||
FStringsIsTemporary:=false;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SetCurrentType(const AValue: TTextConverterType);
|
||||
@ -359,6 +391,7 @@ var
|
||||
fs: TFileStream;
|
||||
begin
|
||||
if FCurrentType=AValue then exit;
|
||||
CheckType(AValue);
|
||||
//DebugLn(['TIDETextConverter.SetCurrentType ',ord(FCurrentType),' ',ord(AValue)]);
|
||||
case AValue of
|
||||
tctSource:
|
||||
@ -369,7 +402,7 @@ begin
|
||||
tctStrings:
|
||||
if FStrings<>nil then begin
|
||||
FSource:=FStrings.Text;
|
||||
RemoveStrings;
|
||||
ResetStrings;
|
||||
end;
|
||||
tctFile:
|
||||
if FileExists(FFilename) then begin
|
||||
@ -380,12 +413,16 @@ begin
|
||||
finally
|
||||
fs.Free;
|
||||
end;
|
||||
if FileIsTemporary then begin
|
||||
DeleteFile(FFilename);
|
||||
end;
|
||||
ResetFile;
|
||||
end;
|
||||
tctCodeBuffer:
|
||||
begin
|
||||
TextConverterToolClasses.GetCodeBufferSource(Self,FSource);
|
||||
FCodeBuffer:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
tctStrings:
|
||||
// convert to TStrings
|
||||
begin
|
||||
@ -402,12 +439,18 @@ begin
|
||||
tctFile:
|
||||
if FileExists(FFilename) then begin
|
||||
FStrings.LoadFromFile(FFilename);
|
||||
if FileIsTemporary then begin
|
||||
DeleteFile(FFilename);
|
||||
end;
|
||||
ResetFile;
|
||||
end;
|
||||
tctCodeBuffer:
|
||||
begin
|
||||
TextConverterToolClasses.GetCodeBufferSource(Self,FSource);
|
||||
FStrings.Text:=FSource;
|
||||
FSource:='';
|
||||
FCodeBuffer:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
tctFile:
|
||||
// convert to File
|
||||
begin
|
||||
@ -431,7 +474,41 @@ begin
|
||||
tctStrings:
|
||||
if FStrings<>nil then begin
|
||||
FStrings.SaveToFile(FFilename);
|
||||
RemoveStrings;
|
||||
ResetStrings;
|
||||
end;
|
||||
tctCodeBuffer:
|
||||
begin
|
||||
TextConverterToolClasses.SaveCodeBufferToFile(Self,FFilename);
|
||||
FCodeBuffer:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
tctCodeBuffer:
|
||||
// convert to CodeBuffer
|
||||
begin
|
||||
// keep old Filename, so that a Filename, Source, Filename combination
|
||||
// uses the same Filename
|
||||
if FFilename='' then
|
||||
CreateTempFilename;
|
||||
case FCurrentType of
|
||||
tctSource:
|
||||
begin
|
||||
TextConverterToolClasses.CreateCodeBuffer(Self,FFilename,FSource,
|
||||
FCodeBuffer);
|
||||
FSource:='';
|
||||
end;
|
||||
tctStrings:
|
||||
begin
|
||||
TextConverterToolClasses.CreateCodeBuffer(Self,FFilename,
|
||||
FStrings.Text,FCodeBuffer);
|
||||
ResetStrings;
|
||||
end;
|
||||
tctFile:
|
||||
begin
|
||||
TextConverterToolClasses.LoadCodeBufferFromFile(Self,FFilename,
|
||||
true,true,FCodeBuffer);
|
||||
ResetFile;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -445,7 +522,7 @@ begin
|
||||
FFileIsTemporary:=AValue;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SaveToFile(const NewFilename: string);
|
||||
procedure TIDETextConverter.ConvertToFile(const NewFilename: string);
|
||||
var
|
||||
fs: TFileStream;
|
||||
TrimmedFilename: String;
|
||||
@ -469,19 +546,38 @@ begin
|
||||
tctStrings:
|
||||
begin
|
||||
fStrings.SaveToFile(TrimmedFilename);
|
||||
RemoveStrings;
|
||||
ResetStrings;
|
||||
end;
|
||||
tctCodeBuffer:
|
||||
begin
|
||||
TextConverterToolClasses.SaveCodeBufferToFile(Self,NewFilename);
|
||||
FCodeBuffer:=nil;
|
||||
end;
|
||||
end;
|
||||
FCurrentType:=tctFile;
|
||||
FFilename:=TrimmedFilename;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SetCodeBuffer(const AValue: Pointer);
|
||||
begin
|
||||
CheckType(tctCodeBuffer);
|
||||
FCurrentType:=tctCodeBuffer;
|
||||
ResetStrings;
|
||||
FCodeBuffer:=AValue;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.CreateTempFilename;
|
||||
begin
|
||||
FFilename:=GetTempFilename;
|
||||
FFileIsTemporary:=true;
|
||||
end;
|
||||
|
||||
function TIDETextConverter.GetCodeBuffer: Pointer;
|
||||
begin
|
||||
CurrentType:=tctCodeBuffer;
|
||||
Result:=FCodeBuffer;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.SetStringsIsTemporary(const AValue: Boolean);
|
||||
begin
|
||||
if FStringsIsTemporary=AValue then exit;
|
||||
@ -504,7 +600,8 @@ end;
|
||||
|
||||
destructor TIDETextConverter.Destroy;
|
||||
begin
|
||||
RemoveStrings;
|
||||
ResetFile;
|
||||
ResetStrings;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -512,10 +609,31 @@ procedure TIDETextConverter.Clear;
|
||||
begin
|
||||
FFilename:='';
|
||||
FSource:='';
|
||||
RemoveStrings;
|
||||
FCodeBuffer:=nil;
|
||||
ResetStrings;
|
||||
FCurrentType:=tctSource;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.CheckType(aTextType: TTextConverterType);
|
||||
|
||||
procedure RaiseNotSupported;
|
||||
begin
|
||||
raise Exception.Create('TIDETextConverter.CheckType:'
|
||||
+' type not supported '+GetEnumName(TypeInfo(TTextConverterType),ord(aTextType)));
|
||||
end;
|
||||
|
||||
begin
|
||||
if not SupportsType(aTextType) then RaiseNotSupported;
|
||||
end;
|
||||
|
||||
function TIDETextConverter.SupportsType(aTextType: TTextConverterType
|
||||
): boolean;
|
||||
begin
|
||||
Result:=(aTextType in [tctSource,tctFile,tctStrings])
|
||||
or ((TextConverterToolClasses<>nil)
|
||||
and (TextConverterToolClasses.SupportsType(aTextType)));
|
||||
end;
|
||||
|
||||
function TIDETextConverter.Execute(ToolList: TComponent): TModalResult;
|
||||
var
|
||||
i: Integer;
|
||||
@ -594,6 +712,14 @@ begin
|
||||
FStrings:=aStrings;
|
||||
end;
|
||||
|
||||
procedure TIDETextConverter.InitWithCodeBuffers(const aBuffer: Pointer);
|
||||
begin
|
||||
CheckType(tctCodeBuffer);
|
||||
Clear;
|
||||
FCurrentType:=tctCodeBuffer;
|
||||
FCodeBuffer:=aBuffer;
|
||||
end;
|
||||
|
||||
{ TCustomTextConverterTool }
|
||||
|
||||
procedure TCustomTextConverterTool.SetCaption(const AValue: string);
|
||||
@ -602,6 +728,11 @@ begin
|
||||
FCaption:=AValue;
|
||||
end;
|
||||
|
||||
function TCustomTextConverterTool.IsCaptionStored: boolean;
|
||||
begin
|
||||
Result:=Caption<>FirstLineOfClassDescription;
|
||||
end;
|
||||
|
||||
procedure TCustomTextConverterTool.SetDescription(const AValue: string);
|
||||
begin
|
||||
if FDescription=AValue then exit;
|
||||
|
||||
@ -813,6 +813,7 @@ begin
|
||||
EventTrace('killfocusCB', data);
|
||||
{$ENDIF}
|
||||
if (Widget=nil) or (Event=nil) then ;
|
||||
//DebugLn('GTKKillFocusCB ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget));
|
||||
{$IFDEF VerboseFocus}
|
||||
write('GTKillFocusCB Widget=',DbgS(Widget),' Event^.theIn=',Event^.theIn);
|
||||
LCLObject:=TObject(data);
|
||||
@ -862,6 +863,7 @@ begin
|
||||
{$IFDEF EventTrace}
|
||||
EventTrace('killfocusCBAfter', data);
|
||||
{$ENDIF}
|
||||
//DebugLn('GTKKillFocusCBAfter ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget));
|
||||
{$IFDEF VerboseFocus}
|
||||
write('GTKillFocusCBAfter Widget=',DbgS(Widget),' Event^.theIn=',Event^.theIn);
|
||||
LCLObject:=TObject(data);
|
||||
|
||||
@ -515,7 +515,7 @@ begin
|
||||
then begin
|
||||
p:=nil;
|
||||
gdk_window_get_user_data(AWindow,p);
|
||||
if GtkWidgetIsA(PGTKWidget(p),GTKAPIWidget_GetType) then begin
|
||||
if GtkWidgetIsA(PGTKWidget(p),gtk_widget_get_type) then begin
|
||||
Widget:=PGTKWidget(p);
|
||||
Result:=Result+'<Widget['+GetWidgetDebugReport(Widget)+']>';
|
||||
end else begin
|
||||
|
||||
@ -418,6 +418,7 @@ procedure TGTK2WidgetSet.SetCallbackEx(const AMsg: LongInt;
|
||||
|
||||
procedure ConnectFocusEvents(const AnObject: PGTKObject);
|
||||
begin
|
||||
//DebugLn(['ConnectFocusEvents ',GetWidgetDebugReport(PGtkWidget(AnObject))]);
|
||||
ConnectSenderSignal(AnObject, 'focus-in-event', @gtk2FocusCB);
|
||||
ConnectSenderSignalAfter(AnObject, 'focus-in-event', @gtk2FocusCBAfter);
|
||||
ConnectSenderSignal(AnObject, 'focus-out-event', @gtk2KillFocusCB);
|
||||
@ -460,12 +461,7 @@ begin
|
||||
case AMsg of
|
||||
LM_FOCUS :
|
||||
begin
|
||||
if (ALCLObject is TCustomComboBox) then begin
|
||||
ConnectFocusEvents(PgtkObject(PgtkCombo(gObject)^.entry));
|
||||
ConnectFocusEvents(PgtkObject(PgtkCombo(gObject)^.list));
|
||||
end else begin
|
||||
ConnectFocusEvents(gCore);
|
||||
end;
|
||||
ConnectFocusEvents(gCore);
|
||||
end;
|
||||
|
||||
LM_CHAR,
|
||||
|
||||
@ -42,7 +42,8 @@ uses
|
||||
|
||||
type
|
||||
|
||||
{ !!! Both are used: TGtkComboBoxEntry and TGtkComboBox, but not the old TGtkCombo !!! }
|
||||
{ !!! Both are used: TGtkComboBoxEntry (with entry) and TGtkComboBox (without entry),
|
||||
but not the old TGtkCombo !!! }
|
||||
|
||||
PGtkComboBoxPrivate = ^TGtkComboBoxPrivate;
|
||||
TGtkComboBoxPrivate = record
|
||||
@ -95,7 +96,8 @@ type
|
||||
end;
|
||||
|
||||
{ TGtk2WSCustomComboBox }
|
||||
{ !!! Both are used: TGtkComboBoxEntry and TGtkComboBox, but not the old TGtkCombo !!! }
|
||||
{ !!! Both are used: TGtkComboBoxEntry (with entry) and TGtkComboBox (without entry),
|
||||
but not the old TGtkCombo !!! }
|
||||
|
||||
TGtk2WSCustomComboBox = class(TGtkWSCustomComboBox)
|
||||
private
|
||||
@ -900,7 +902,8 @@ begin
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONUP, InputObject, AWinControl);
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEWHEEL, InputObject, AWinControl);
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_PAINT, InputObject, AWinControl);
|
||||
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_FOCUS, InputObject, AWinControl);
|
||||
|
||||
// And now the same for the Button in the combo
|
||||
if AButton<>nil then begin
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEENTER, AButton, AWinControl);
|
||||
@ -915,6 +918,7 @@ begin
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONUP, AButton, AWinControl);
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEWHEEL, AButton, AWinControl);
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_PAINT, AButton, AWinControl);
|
||||
Gtk2WidgetSet.SetCallbackDirect(LM_FOCUS, AButton, AWinControl);
|
||||
end;
|
||||
|
||||
// if we are a GtkComboBoxEntry
|
||||
@ -924,7 +928,7 @@ begin
|
||||
|
||||
if APrivate^.popup_widget<>nil then begin
|
||||
g_signal_connect(APrivate^.popup_widget, 'show', TGCallback(@GtkPopupShowCB), AWidgetInfo);
|
||||
g_signal_connect(APrivate^.popup_widget, 'hide', TGCallback(@GtkPopupHideCB), AWidgetInfo);
|
||||
g_signal_connect_after(APrivate^.popup_widget, 'hide', TGCallback(@GtkPopupHideCB), AWidgetInfo);
|
||||
end;
|
||||
//g_signal_connect(ComboWidget, 'popup-shown', TGCallback(@GtkPopupShowCB), AWidgetInfo);
|
||||
g_object_set_data(G_OBJECT(AWidget), 'Menu', APrivate^.popup_widget);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user