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:
mattias 2007-08-03 22:38:11 +00:00
parent 80a0bfee01
commit 3b69506329
16 changed files with 796 additions and 89 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -1025,8 +1025,6 @@ var
child: TDOMNode;
begin
Result := nil;
if index < 0 then
exit;
child := node.FirstChild;
while Assigned(child) do
begin

View File

@ -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

View File

@ -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.

View File

@ -218,6 +218,7 @@ begin
TextConverterToolClasses.RegisterClass(TRemoveEmptyTypeVarConstSections);
TextConverterToolClasses.RegisterClass(TReplaceImplicitTypes);
TextConverterToolClasses.RegisterClass(TFixArrayOfParameterType);
TextConverterToolClasses.RegisterClass(TRemoveRedefinitionsInUnit);
end;
{ TH2PasDialog }

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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);