diff --git a/components/codetools/ide/codystrconsts.pas b/components/codetools/ide/codystrconsts.pas index 28312f2bbf..2207db1288 100644 --- a/components/codetools/ide/codystrconsts.pas +++ b/components/codetools/ide/codystrconsts.pas @@ -86,6 +86,8 @@ resourcestring +'example:%sMyVar:=3;'; crsDeclareVariable3 = 'Declare variable "%s"'; crsAlreadyDefined = 'Already defined'; + crsInInterface = 'In interface'; + crsInImplementation = 'In implementation'; crsLocalVariableOf = 'Local variable of %s'; crsAlreadyDefinedAt = 'Already defined at %s'; crsPrivate = 'Private'; diff --git a/components/codetools/ide/codyutils.pas b/components/codetools/ide/codyutils.pas index 8744a721ea..e9d27302ea 100644 --- a/components/codetools/ide/codyutils.pas +++ b/components/codetools/ide/codyutils.pas @@ -30,7 +30,7 @@ unit CodyUtils; interface uses - Classes, SysUtils, Dialogs, Controls, LCLIntf, + Classes, SysUtils, Dialogs, Controls, LCLIntf, Clipbrd, LCLType, // IDEIntf IDEDialogs, LazIDEIntf, SrcEditorIntf, IDEHelpIntf, // codetools @@ -40,12 +40,56 @@ uses CodyStrConsts; type + + { TCodyClipboardData } + + TCodyClipboardData = class + public + AsText: string; + procedure WriteString(MemStream: TMemoryStream; const s: string); + function ReadString(MemStream: TMemoryStream): string; + procedure WriteToStream({%H-}MemStream: TMemoryStream); virtual; + procedure ReadFromStream({%H-}MemStream: TMemoryStream); virtual; + procedure Execute; virtual; + end; + TCodyClipboardFormat = class of TCodyClipboardData; + + { TCodyClipboardSrcData } + + TCodyClipboardSrcData = class(TCodyClipboardData) + public + SourceFilename: string; + SourceX: integer; + SourceY: integer; + procedure SetSourcePos(const SrcPos: TCodeXYPosition); + procedure WriteToStream(MemStream: TMemoryStream); override; + procedure ReadFromStream(MemStream: TMemoryStream); override; + end; + { TCody } TCody = class + private + FClipboardFormats: TFPList; + function GetClipboardFormats(Index: integer): TCodyClipboardFormat; public + constructor Create; + destructor Destroy; override; + procedure DecodeLoaded(Sender: TSourceLog; const Filename: string; var Source, DiskEncoding, MemEncoding: string); + + // clipboard + class function ClipboardFormatId: TClipboardFormat; + function CanReadFromClipboard(AClipboard: TClipboard): Boolean; + function ReadFromClipboard(AClipboard: TClipboard): boolean; + function WriteToClipboard(AClipboard: TClipboard; + Data: TCodyClipboardData): Boolean; + procedure RegisterClipboardFormat(ccFormat: TCodyClipboardFormat); + function FindClipboardFormat(aName: string): TCodyClipboardFormat; + function ClipboardFormatCount: integer; + property ClipboardFormats[Index: integer]: TCodyClipboardFormat + read GetClipboardFormats; end; var @@ -302,8 +346,107 @@ begin OpenURL(BasePath+Path); end; +{ TCodyClipboardSrcData } + +procedure TCodyClipboardSrcData.SetSourcePos(const SrcPos: TCodeXYPosition); +begin + SourceFilename:=SrcPos.Code.Filename; + SourceX:=SrcPos.X; + SourceY:=SrcPos.Y; +end; + +procedure TCodyClipboardSrcData.WriteToStream(MemStream: TMemoryStream); +begin + inherited WriteToStream(MemStream); + WriteString(MemStream,SourceFilename); + MemStream.Write(SourceX,4); + MemStream.Write(SourceY,4); +end; + +procedure TCodyClipboardSrcData.ReadFromStream(MemStream: TMemoryStream); +begin + inherited ReadFromStream(MemStream); + SourceFilename:=ReadString(MemStream); + MemStream.Read(SourceX,4); + MemStream.Read(SourceY,4); +end; + +{ TCodyClipboardData } + +procedure TCodyClipboardData.WriteString(MemStream: TMemoryStream; + const s: string); +var + b: byte; + l: Integer; +begin + if length(s)<255 then begin + b:=length(s); + MemStream.Write(b,1); + if b>0 then + MemStream.Write(s[1],b); + end else begin + b:=255; + MemStream.Write(b,1); + l:=length(s); + MemStream.Write(l,4); + MemStream.Write(s[1],l); + end; +end; + +function TCodyClipboardData.ReadString(MemStream: TMemoryStream): string; +var + b: byte; + l: integer; +begin + Result:=''; + b:=0; + if MemStream.Read(b,1)<>1 then exit; + if b<255 then begin + SetLength(Result,b); + if Result<>'' then + MemStream.Read(Result[1],b); + end else begin + l:=0; + MemStream.Read(l,4); + if l<=0 then exit; + SetLength(Result,l); + MemStream.Read(Result[1],l); + end; +end; + +procedure TCodyClipboardData.WriteToStream(MemStream: TMemoryStream); +begin + +end; + +procedure TCodyClipboardData.ReadFromStream(MemStream: TMemoryStream); +begin + +end; + +procedure TCodyClipboardData.Execute; +begin + raise Exception.Create('not implemented yet: '+ClassName+'.Execute'); +end; + { TCody } +function TCody.GetClipboardFormats(Index: integer): TCodyClipboardFormat; +begin + Result:=TCodyClipboardFormat(FClipboardFormats[Index]); +end; + +constructor TCody.Create; +begin + FClipboardFormats:=TFPList.Create; +end; + +destructor TCody.Destroy; +begin + FreeAndNil(FClipboardFormats); + inherited Destroy; +end; + procedure TCody.DecodeLoaded(Sender: TSourceLog; const Filename: string; var Source, DiskEncoding, MemEncoding: string); begin @@ -314,6 +457,102 @@ begin Source,DiskEncoding,MemEncoding); end; +class function TCody.ClipboardFormatId: TClipboardFormat; +const + CodyClipboardMimeType = 'Application/X-Laz-Cody'; +var + ID: TClipboardFormat = 0; +begin + if ID = 0 then + ID := ClipboardRegisterFormat(CodyClipboardMimeType); + Result := ID; +end; + +function TCody.CanReadFromClipboard(AClipboard: TClipboard): Boolean; +begin + Result := AClipboard.HasFormat(ClipboardFormatId); +end; + +function TCody.ReadFromClipboard(AClipboard: TClipboard): boolean; + + procedure InvalidStream; + begin + raise Exception.Create('The Cody clipboard data is invalid'); + end; + +var + MemStream: TMemoryStream; + ID: ShortString; + aFormat: TCodyClipboardFormat; + Data: TCodyClipboardData; +begin + Result:=false; + if not AClipboard.HasFormat(ClipboardFormatId) then exit; + Result:=true; + MemStream:=TMemoryStream.Create; + Data:=nil; + try + Result:=AClipboard.GetFormat(ClipboardFormatId,MemStream); + ID:=''; + if MemStream.Read(ID[0],1)<>1 then + InvalidStream; + if MemStream.Read(ID[1],ord(ID[0]))<>ord(ID[0]) then + InvalidStream; + aFormat:=FindClipboardFormat(ID); + if aFormat=nil then + InvalidStream; + Data:=aFormat.Create; + Data.ReadFromStream(MemStream); + Data.Execute; + finally + Data.Free; + MemStream.Free; + end; +end; + +function TCody.WriteToClipboard(AClipboard: TClipboard; Data: TCodyClipboardData + ): Boolean; +var + MemStream: TMemoryStream; + ID: ShortString; +begin + AClipboard.AsText:=Data.AsText; + if not AClipboard.HasFormat(CF_TEXT) then + raise Exception.Create('Write to clipboard failed'); + MemStream:=TMemoryStream.Create; + try + ID:=AClipboard.ClassName; + MemStream.Write(ID[0],length(ID)+1); + Data.WriteToStream(MemStream); + Result:=AClipboard.AddFormat(ClipboardFormatId,MemStream); + finally + MemStream.Free; + end; +end; + +procedure TCody.RegisterClipboardFormat(ccFormat: TCodyClipboardFormat); +begin + if FindClipboardFormat(ccFormat.ClassName)<>nil then + raise Exception.Create('cody clipboard format "'+ccFormat.ClassName+'" is already registered'); + FClipboardFormats.Add(ccFormat); +end; + +function TCody.FindClipboardFormat(aName: string): TCodyClipboardFormat; +var + i: Integer; +begin + for i:=0 to ClipboardFormatCount-1 do begin + Result:=ClipboardFormats[i]; + if SysUtils.CompareText(Result.ClassName,aName)=0 then exit; + end; + Result:=nil; +end; + +function TCody.ClipboardFormatCount: integer; +begin + Result:=FClipboardFormats.Count; +end; + initialization Cody:=TCody.Create; finalization diff --git a/components/codetools/ide/declarevardlg.pas b/components/codetools/ide/declarevardlg.pas index 7c3ffd2520..959355d03a 100644 --- a/components/codetools/ide/declarevardlg.pas +++ b/components/codetools/ide/declarevardlg.pas @@ -60,6 +60,18 @@ type constructor Create(const Context: TFindContext); end; + { TCodyClipboardDeclareVar } + + TCodyClipboardDeclareVar = class(TCodyClipboardSrcData) + public + VarName: string; + VarType: string; + TheUnitName: string; + procedure WriteToStream(MemStream: TMemoryStream); override; + procedure ReadFromStream(MemStream: TMemoryStream); override; + procedure Execute; override; + end; + { TCodyDeclareVarDialog } TCodyDeclareVarDialog = class(TForm) @@ -184,13 +196,38 @@ begin end; end; +{ TCodyClipboardDeclareVar } + +procedure TCodyClipboardDeclareVar.WriteToStream(MemStream: TMemoryStream); +begin + inherited WriteToStream(MemStream); + WriteString(MemStream,VarName); + WriteString(MemStream,VarType); + WriteString(MemStream,TheUnitName); +end; + +procedure TCodyClipboardDeclareVar.ReadFromStream(MemStream: TMemoryStream); +begin + inherited ReadFromStream(MemStream); + VarName:=ReadString(MemStream); + VarType:=ReadString(MemStream); + TheUnitName:=ReadString(MemStream); +end; + +procedure TCodyClipboardDeclareVar.Execute; +begin + inherited Execute; +end; + { TCodyDeclareVarTarget } constructor TCodyDeclareVarTarget.Create(const Context: TFindContext); begin Tool:=Context.Tool; - NodeDesc:=Context.Node.Desc; - Context.Tool.CleanPosToCaret(Context.Node.StartPos,NodeStartPos); + if Context.Node<>nil then begin + NodeDesc:=Context.Node.Desc; + Context.Tool.CleanPosToCaret(Context.Node.StartPos,NodeStartPos); + end; end; {$R *.lfm} @@ -300,12 +337,12 @@ begin AddClassTarget(Context,ctnClassPublished); end else if Context.Node.Desc=ctnImplementation then begin Target:=TCodyDeclareVarTarget.Create(Context); - Target.Caption:='In implementation'; + Target.Caption:=crsInImplementation; Targets.Add(Target); Node:=Context.Node.PriorBrother; if (Node<>nil) and (Node.Desc=ctnInterface) then begin Target:=TCodyDeclareVarTarget.Create(CreateFindContext(Context.Tool,Node)); - Target.Caption:='In interface'; + Target.Caption:=crsInInterface; Targets.Add(Target); end; end; @@ -322,6 +359,11 @@ begin exit; end; + // add target for clipboard + Target:=TCodyDeclareVarTarget.Create(CleanFindContext); + Target.Caption:='On clipboard'; + Targets.Add(Target); + Caption:=Format(crsDeclareVariable3, [Identifier]); TypeLabel.Caption:=crsType; TypeEdit.Text:=RecommendedType; @@ -340,6 +382,12 @@ begin NewType:=Trim(TypeEdit.Text); Target:=TCodyDeclareVarTarget(Targets[WhereRadioGroup.ItemIndex]); + if Target.Tool=nil then begin + // on clipboard + // ToDo + exit; + end; + OldChange:=LazarusIDE.OpenEditorsOnCodeToolChange; try OldSrcEdit:=SourceEditorManagerIntf.ActiveEditor; diff --git a/components/codetools/ide/languages/codystrconsts.it.po b/components/codetools/ide/languages/codystrconsts.it.po index 4685e7258c..e164a0e18a 100644 --- a/components/codetools/ide/languages/codystrconsts.it.po +++ b/components/codetools/ide/languages/codystrconsts.it.po @@ -214,6 +214,14 @@ msgstr "Gbyte" msgid "&Help" msgstr "" +#: codystrconsts.crsinimplementation +msgid "In implementation" +msgstr "" + +#: codystrconsts.crsininterface +msgid "In interface" +msgstr "" + #: codystrconsts.crsinsertfileatcursor msgid "Insert file at cursor ..." msgstr "" diff --git a/components/codetools/ide/languages/codystrconsts.po b/components/codetools/ide/languages/codystrconsts.po index c024bc1947..875e37db09 100644 --- a/components/codetools/ide/languages/codystrconsts.po +++ b/components/codetools/ide/languages/codystrconsts.po @@ -205,6 +205,14 @@ msgstr "" msgid "&Help" msgstr "" +#: codystrconsts.crsinimplementation +msgid "In implementation" +msgstr "" + +#: codystrconsts.crsininterface +msgid "In interface" +msgstr "" + #: codystrconsts.crsinsertfileatcursor msgid "Insert file at cursor ..." msgstr "" diff --git a/components/codetools/ide/languages/codystrconsts.pt_BR.po b/components/codetools/ide/languages/codystrconsts.pt_BR.po index 4d490a6706..1bff4b74ba 100644 --- a/components/codetools/ide/languages/codystrconsts.pt_BR.po +++ b/components/codetools/ide/languages/codystrconsts.pt_BR.po @@ -213,6 +213,14 @@ msgstr "Gbytes" msgid "&Help" msgstr "" +#: codystrconsts.crsinimplementation +msgid "In implementation" +msgstr "" + +#: codystrconsts.crsininterface +msgid "In interface" +msgstr "" + #: codystrconsts.crsinsertfileatcursor msgid "Insert file at cursor ..." msgstr "Inserir arquivo na posição do cursor ..." diff --git a/components/codetools/ide/languages/codystrconsts.ru.po b/components/codetools/ide/languages/codystrconsts.ru.po index f07bb56bdf..470c7877a6 100644 --- a/components/codetools/ide/languages/codystrconsts.ru.po +++ b/components/codetools/ide/languages/codystrconsts.ru.po @@ -213,6 +213,14 @@ msgstr "ГБ" msgid "&Help" msgstr "&Справка" +#: codystrconsts.crsinimplementation +msgid "In implementation" +msgstr "" + +#: codystrconsts.crsininterface +msgid "In interface" +msgstr "" + #: codystrconsts.crsinsertfileatcursor msgid "Insert file at cursor ..." msgstr "Вставить содержимое файла в месте расположения курсора ..."