mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 10:39:18 +02:00
cocoa: move clipboard (cocoa-pasteboard) related implementation into a separate unit. Update the behaviour of ClipboardGetFormats function to return the actual information from the pasteboard. #34121
git-svn-id: trunk@58695 -
This commit is contained in:
parent
db95c32b36
commit
aa9cfe7f1a
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -8884,6 +8884,7 @@ lcl/interfaces/cocoa/cocoawinapih.inc svneol=native#text/pascal
|
|||||||
lcl/interfaces/cocoa/cocoawindows.pas svneol=native#text/plain
|
lcl/interfaces/cocoa/cocoawindows.pas svneol=native#text/plain
|
||||||
lcl/interfaces/cocoa/cocoawsbuttons.pp svneol=native#text/pascal
|
lcl/interfaces/cocoa/cocoawsbuttons.pp svneol=native#text/pascal
|
||||||
lcl/interfaces/cocoa/cocoawschecklst.pas svneol=native#text/plain
|
lcl/interfaces/cocoa/cocoawschecklst.pas svneol=native#text/plain
|
||||||
|
lcl/interfaces/cocoa/cocoawsclipboard.pas svneol=native#text/plain
|
||||||
lcl/interfaces/cocoa/cocoawscomctrls.pas svneol=native#text/plain
|
lcl/interfaces/cocoa/cocoawscomctrls.pas svneol=native#text/plain
|
||||||
lcl/interfaces/cocoa/cocoawscommon.pas svneol=native#text/plain
|
lcl/interfaces/cocoa/cocoawscommon.pas svneol=native#text/plain
|
||||||
lcl/interfaces/cocoa/cocoawsdatepicker.pas svneol=native#text/plain
|
lcl/interfaces/cocoa/cocoawsdatepicker.pas svneol=native#text/plain
|
||||||
|
@ -28,8 +28,6 @@ interface
|
|||||||
uses
|
uses
|
||||||
// rtl+ftl
|
// rtl+ftl
|
||||||
Types, Classes, SysUtils, Math, contnrs,
|
Types, Classes, SysUtils, Math, contnrs,
|
||||||
// fcl-image
|
|
||||||
fpreadpng, fpwritepng, fpimage, fpreadbmp, fpwritebmp,
|
|
||||||
// carbon bindings
|
// carbon bindings
|
||||||
MacOSAll,
|
MacOSAll,
|
||||||
// interfacebase
|
// interfacebase
|
||||||
@ -37,6 +35,7 @@ uses
|
|||||||
// private
|
// private
|
||||||
CocoaAll, CocoaPrivate, CocoaUtils, CocoaGDIObjects,
|
CocoaAll, CocoaPrivate, CocoaUtils, CocoaGDIObjects,
|
||||||
cocoa_extra, CocoaWSMenus, CocoaWSForms, CocoaWindows, CocoaScrollers,
|
cocoa_extra, CocoaWSMenus, CocoaWSForms, CocoaWindows, CocoaScrollers,
|
||||||
|
CocoaWSClipboard,
|
||||||
// LCL
|
// LCL
|
||||||
LCLStrConsts, LMessages, LCLMessageGlue, LCLProc, LCLIntf, LCLType,
|
LCLStrConsts, LMessages, LCLMessageGlue, LCLProc, LCLIntf, LCLType,
|
||||||
Controls, Forms, Themes, Menus,
|
Controls, Forms, Themes, Menus,
|
||||||
@ -52,20 +51,6 @@ type
|
|||||||
class function newWithFunc(afunc: TWSTimerProc): TCocoaTimerObject; message 'newWithFunc:';
|
class function newWithFunc(afunc: TWSTimerProc): TCocoaTimerObject; message 'newWithFunc:';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCocoaClipboardDataType = (ccdtText,
|
|
||||||
ccdtCocoaStandard, // Formats supported natively by Mac OS X
|
|
||||||
ccdtBitmap, // BMPs need conversion to PNG to work with other Mac OS X apps
|
|
||||||
ccdtNonStandard { Formats that will only work in LCL apps } );
|
|
||||||
|
|
||||||
TCocoaClipboardData = class(TObject) // TClipboardFormat is a reference to a TClipboardData
|
|
||||||
public
|
|
||||||
MimeType: string;
|
|
||||||
CocoaFormat: NSString; // utilized for ccdtCocoaStandard and ccdtNonStandard
|
|
||||||
DataType: TCocoaClipboardDataType;
|
|
||||||
constructor Create(AMimeType: string; ACocoaFormat: NSString; ADataType: TCocoaClipboardDataType);
|
|
||||||
destructor Destroy; override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TAppDelegate = objcclass(NSObject, NSApplicationDelegateProtocol)
|
TAppDelegate = objcclass(NSObject, NSApplicationDelegateProtocol)
|
||||||
procedure application_openFiles(sender: NSApplication; filenames: NSArray);
|
procedure application_openFiles(sender: NSApplication; filenames: NSArray);
|
||||||
procedure applicationDidHide(notification: NSNotification);
|
procedure applicationDidHide(notification: NSNotification);
|
||||||
@ -86,13 +71,6 @@ type
|
|||||||
function nextEventMatchingMask_untilDate_inMode_dequeue(mask: NSUInteger; expiration: NSDate; mode: NSString; deqFlag: Boolean): NSEvent; override;
|
function nextEventMatchingMask_untilDate_inMode_dequeue(mask: NSUInteger; expiration: NSDate; mode: NSString; deqFlag: Boolean): NSEvent; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCocoaPasteboardsRef = record
|
|
||||||
pasteboard : NSPasteboard;
|
|
||||||
changeCount: NSInteger;
|
|
||||||
dataProc : TClipboardRequestEvent;
|
|
||||||
isOwned : Boolean;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TCocoaWidgetSet }
|
{ TCocoaWidgetSet }
|
||||||
|
|
||||||
TCocoaWidgetSet = class(TWidgetSet)
|
TCocoaWidgetSet = class(TWidgetSet)
|
||||||
@ -121,18 +99,11 @@ type
|
|||||||
|
|
||||||
// Sandboxing
|
// Sandboxing
|
||||||
SandboxingOn: Boolean;
|
SandboxingOn: Boolean;
|
||||||
|
fClipboard: TCocoaWSClipboard;
|
||||||
|
|
||||||
// Clipboard
|
// Clipboard
|
||||||
PrimarySelection: NSPasteboard;
|
|
||||||
SecondarySelection: NSPasteboard;
|
|
||||||
ClipboardFormats: TFPObjectList; // of TCocoaClipboardData
|
|
||||||
ClipboardChangeCount: NSInteger;
|
|
||||||
Pasteboards: array [TClipboardType] of TCocoaPasteboardsRef;
|
|
||||||
|
|
||||||
procedure InitClipboard();
|
|
||||||
procedure FreeClipboard();
|
|
||||||
procedure SyncClipboard();
|
procedure SyncClipboard();
|
||||||
function GetClipboardDataForFormat(AFormat: TClipboardFormat): TCocoaClipboardData;
|
|
||||||
|
|
||||||
function PromptUser(const DialogCaption, DialogMessage: String;
|
function PromptUser(const DialogCaption, DialogMessage: String;
|
||||||
DialogType: longint; Buttons: PLongint; ButtonCount, DefaultIndex,
|
DialogType: longint; Buttons: PLongint; ButtonCount, DefaultIndex,
|
||||||
|
@ -149,54 +149,9 @@ begin
|
|||||||
Result := (WindowHandle <> 0) and (DC <> 0) and TCocoaContext(DC).isDesignDC;
|
Result := (WindowHandle <> 0) and (DC <> 0) and TCocoaContext(DC).isDesignDC;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaWidgetSet.InitClipboard;
|
|
||||||
var
|
|
||||||
t : TClipboardType;
|
|
||||||
begin
|
|
||||||
PrimarySelection := NSPasteboard.pasteboardWithUniqueName();
|
|
||||||
SecondarySelection := NSPasteboard.pasteboardWithUniqueName();
|
|
||||||
ClipboardFormats := TFPObjectList.Create(True);
|
|
||||||
|
|
||||||
Pasteboards[ctPrimarySelection].pasteboard := PrimarySelection;
|
|
||||||
Pasteboards[ctSecondarySelection].pasteboard := SecondarySelection;
|
|
||||||
Pasteboards[ctClipboard].pasteboard := NSPasteboard.generalPasteboard;
|
|
||||||
|
|
||||||
for t := Low(TClipboardType) to High(TClipboardType) do
|
|
||||||
if Assigned(Pasteboards[t].pasteboard) then
|
|
||||||
Pasteboards[t].changeCount := Pasteboards[t].pasteboard.changeCount;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCocoaWidgetSet.FreeClipboard;
|
|
||||||
begin
|
|
||||||
PrimarySelection.releaseGlobally();
|
|
||||||
SecondarySelection.releaseGlobally();
|
|
||||||
ClipboardFormats.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCocoaWidgetSet.SyncClipboard();
|
procedure TCocoaWidgetSet.SyncClipboard();
|
||||||
var
|
|
||||||
ct : TClipboardType;
|
|
||||||
pb : NSPasteboard;
|
|
||||||
begin
|
begin
|
||||||
for ct := low(TClipboardType) to high(TClipboardType) do begin
|
fClipboard.Sync;
|
||||||
if not Pasteboards[ct].isOwned then Continue;
|
|
||||||
|
|
||||||
pb := Pasteboards[ct].pasteboard;
|
|
||||||
if not Assigned(pb) then Continue;
|
|
||||||
|
|
||||||
if (pb.changeCount <> Pasteboards[ct].changeCount) then
|
|
||||||
begin
|
|
||||||
Pasteboards[ct].isOwned:=false;
|
|
||||||
if Assigned(Pasteboards[ct].dataProc) then
|
|
||||||
// notifying about the loss of ownership
|
|
||||||
Pasteboards[ct].dataProc(0, nil);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCocoaWidgetSet.GetClipboardDataForFormat(AFormat: TClipboardFormat): TCocoaClipboardData;
|
|
||||||
begin
|
|
||||||
Result := TCocoaClipboardData(AFormat);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
@ -170,7 +170,7 @@ begin
|
|||||||
|
|
||||||
InitStockItems;
|
InitStockItems;
|
||||||
|
|
||||||
InitClipboard(); // must be here otherwise clipboard calls before Application.Initialize crash
|
fClipboard := TCocoaWSClipboard.Create; // must be here otherwise clipboard calls before Application.Initialize crash
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -193,7 +193,7 @@ begin
|
|||||||
|
|
||||||
FreeSysColorBrushes;
|
FreeSysColorBrushes;
|
||||||
|
|
||||||
FreeClipboard();
|
fClipboard.Free;
|
||||||
|
|
||||||
// The CocoaCaret is based WidgetSet timer.
|
// The CocoaCaret is based WidgetSet timer.
|
||||||
// The GlobalCaret is freed in finalization section, which is called
|
// The GlobalCaret is freed in finalization section, which is called
|
||||||
@ -612,20 +612,6 @@ begin
|
|||||||
Result.func:=afunc;
|
Result.func:=afunc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaClipboardData }
|
|
||||||
|
|
||||||
constructor TCocoaClipboardData.Create(AMimeType: string; ACocoaFormat: NSString; ADataType: TCocoaClipboardDataType);
|
|
||||||
begin
|
|
||||||
MimeType := AMimeType;
|
|
||||||
CocoaFormat := ACocoaFormat;
|
|
||||||
DataType := ADataType;
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TCocoaClipboardData.Destroy;
|
|
||||||
begin
|
|
||||||
CocoaFormat.release;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TAppDelegate.application_openFiles(sender: NSApplication; filenames: NSArray);
|
procedure TAppDelegate.application_openFiles(sender: NSApplication; filenames: NSArray);
|
||||||
var
|
var
|
||||||
lFiles: array of string;
|
lFiles: array of string;
|
||||||
|
@ -141,16 +141,11 @@ end;
|
|||||||
Returns: The corresponding mime type as string
|
Returns: The corresponding mime type as string
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function TCocoaWidgetSet.ClipboardFormatToMimeType(FormatID: TClipboardFormat): string;
|
function TCocoaWidgetSet.ClipboardFormatToMimeType(FormatID: TClipboardFormat): string;
|
||||||
var
|
|
||||||
lFormat: TCocoaClipboardData;
|
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerboseClipboard}
|
{$IFDEF VerboseClipboard}
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardFormatToMimeType FormatID: ' + DbgS(FormatID));
|
DebugLn('TCocoaWidgetSet.ClipboardFormatToMimeType FormatID: ' + DbgS(FormatID));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
Result := fClipboard.FormatToMimeType(FormatID);
|
||||||
lFormat := GetClipboardDataForFormat(FormatID);
|
|
||||||
if lFormat = nil then Exit;
|
|
||||||
Result := lFormat.MimeType;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -163,84 +158,12 @@ end;
|
|||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function TCocoaWidgetSet.ClipboardGetData(ClipboardType: TClipboardType;
|
function TCocoaWidgetSet.ClipboardGetData(ClipboardType: TClipboardType;
|
||||||
FormatID: TClipboardFormat; Stream: TStream): boolean;
|
FormatID: TClipboardFormat; Stream: TStream): boolean;
|
||||||
var
|
|
||||||
pasteboard: NSPasteboard;
|
|
||||||
lFormat: TCocoaClipboardData;
|
|
||||||
lNSStr: NSString;
|
|
||||||
// for text
|
|
||||||
lStr: String;
|
|
||||||
// for standard
|
|
||||||
lNSData: NSData;
|
|
||||||
lNSbytes: PByte;
|
|
||||||
i: Integer;
|
|
||||||
// for bitmap
|
|
||||||
image: TFPCustomImage;
|
|
||||||
lTmpStream: TMemoryStream;
|
|
||||||
reader: TFPCustomImageReader;
|
|
||||||
writer: TFPCustomImageWriter;
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
|
||||||
{$IFDEF VerboseClipboard}
|
{$IFDEF VerboseClipboard}
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardGetData ClipboardType=' +
|
DebugLn('TCocoaWidgetSet.ClipboardGetData ClipboardType=' +
|
||||||
ClipboardTypeName[ClipboardType] + ' FormatID: ' + DbgS(FormatID));
|
ClipboardTypeName[ClipboardType] + ' FormatID: ' + DbgS(FormatID));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
Result := fClipboard.GetData(ClipboardType, FormatID, Stream);
|
||||||
case ClipboardType of
|
|
||||||
ctPrimarySelection: pasteboard := PrimarySelection;
|
|
||||||
ctSecondarySelection: pasteboard := SecondarySelection;
|
|
||||||
ctClipboard: pasteboard := NSPasteboard.generalPasteboard;
|
|
||||||
end;
|
|
||||||
|
|
||||||
lFormat := GetClipboardDataForFormat(FormatID);
|
|
||||||
if lFormat = nil then Exit;
|
|
||||||
|
|
||||||
case lFormat.DataType of
|
|
||||||
ccdtText:
|
|
||||||
begin
|
|
||||||
lNSStr := pasteboard.stringForType(lFormat.CocoaFormat);
|
|
||||||
if lNSStr = nil then Exit;
|
|
||||||
lStr := NSStringToString(lNSStr);
|
|
||||||
Stream.Write(lStr[1], Length(lStr));
|
|
||||||
{$IFDEF VerboseClipboard}
|
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardGetData IsText Result=' + lStr);
|
|
||||||
{$ENDIF}
|
|
||||||
end;
|
|
||||||
ccdtCocoaStandard, ccdtNonStandard:
|
|
||||||
begin
|
|
||||||
lNSData := pasteboard.dataForType(lFormat.CocoaFormat);
|
|
||||||
if lNSData = nil then Exit;
|
|
||||||
lNSbytes := lNSData.bytes;
|
|
||||||
for i := 0 to lNSData.length-1 do
|
|
||||||
Stream.WriteByte(lNSbytes[i]);
|
|
||||||
end;
|
|
||||||
// In Cocoa images are stored as PNG, convert to BMP for LCL app usage
|
|
||||||
ccdtBitmap:
|
|
||||||
begin
|
|
||||||
lNSData := pasteboard.dataForType(lFormat.CocoaFormat);
|
|
||||||
if lNSData = nil then Exit;
|
|
||||||
lNSbytes := lNSData.bytes;
|
|
||||||
|
|
||||||
Image := TFPMemoryImage.Create(10, 10);
|
|
||||||
Reader := TFPReaderPNG.Create;
|
|
||||||
Writer := TFPWriterBMP.Create;
|
|
||||||
lTmpStream := TMemoryStream.Create;
|
|
||||||
try
|
|
||||||
for i := 0 to lNSData.length-1 do
|
|
||||||
lTmpStream.WriteByte(lNSbytes[i]);
|
|
||||||
lTmpStream.Position := 0;
|
|
||||||
|
|
||||||
Image.LoadFromStream(lTmpStream, Reader);
|
|
||||||
Image.SaveToStream(Stream, Writer);
|
|
||||||
finally
|
|
||||||
Image.Free;
|
|
||||||
Reader.Free;
|
|
||||||
Writer.Free;
|
|
||||||
lTmpStream.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := True;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -251,28 +174,23 @@ end;
|
|||||||
(you must free it yourself)
|
(you must free it yourself)
|
||||||
Returns: If the function succeeds
|
Returns: If the function succeeds
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
|
|
||||||
function TCocoaWidgetSet.ClipboardGetFormats(ClipboardType: TClipboardType;
|
function TCocoaWidgetSet.ClipboardGetFormats(ClipboardType: TClipboardType;
|
||||||
var Count: integer; var List: PClipboardFormat): boolean;
|
var Count: integer; var List: PClipboardFormat): boolean;
|
||||||
var
|
var
|
||||||
ListDataSize, ListCount: Integer;
|
fmt: TDynClipboardFormatArray;
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
|
||||||
{$IFDEF VerboseClipboard}
|
{$IFDEF VerboseClipboard}
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardGetFormats ClipboardType' +
|
DebugLn('TCocoaWidgetSet.ClipboardGetFormats ClipboardType' +
|
||||||
ClipboardTypeName[ClipboardType]);
|
ClipboardTypeName[ClipboardType]);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
fmt := nil;
|
||||||
ListCount := Min(ClipboardFormats.Count, Count);
|
Result := fClipboard.GetFormats(ClipboardType, Count, fmt);
|
||||||
ListDataSize := SizeOf(Pointer) * ListCount;
|
if Count > 0 then begin
|
||||||
List := GetMem(ListDataSize);
|
GetMem(List, Count * sizeof(TClipboardFormat));
|
||||||
|
Move(fmt[0], List^, Count * sizeof(TClipboardFormat));
|
||||||
for i := 0 to ListCount - 1 do
|
end else
|
||||||
begin
|
List := nil;
|
||||||
List[i] := PtrUInt(ClipboardFormats.Items[i]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := True;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -295,116 +213,12 @@ end;
|
|||||||
function TCocoaWidgetSet.ClipboardGetOwnerShip(ClipboardType: TClipboardType;
|
function TCocoaWidgetSet.ClipboardGetOwnerShip(ClipboardType: TClipboardType;
|
||||||
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
|
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
|
||||||
Formats: PClipboardFormat): boolean;
|
Formats: PClipboardFormat): boolean;
|
||||||
var
|
|
||||||
pasteboard: NSPasteboard;
|
|
||||||
i: Integer;
|
|
||||||
lCurFormat: TCocoaClipboardData;
|
|
||||||
DataStream: TMemoryStream;
|
|
||||||
FormatToOwn: NSString;
|
|
||||||
FormatToOwnArray: NSArray;
|
|
||||||
// text format
|
|
||||||
lText: string;
|
|
||||||
lNSText: NSString;
|
|
||||||
// non-text
|
|
||||||
lNSData: NSData;
|
|
||||||
// for bitmap
|
|
||||||
image: TFPCustomImage;
|
|
||||||
lTmpStream: TMemoryStream;
|
|
||||||
reader: TFPCustomImageReader;
|
|
||||||
writer: TFPCustomImageWriter;
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
|
||||||
{$IFDEF VerboseClipboard}
|
{$IFDEF VerboseClipboard}
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardGetOwnerShip ClipboardType=' +
|
DebugLn('TCocoaWidgetSet.ClipboardGetOwnerShip ClipboardType=' +
|
||||||
ClipboardTypeName[ClipboardType] + ' FormatCount: ' + DbgS(FormatCount));
|
ClipboardTypeName[ClipboardType] + ' FormatCount: ' + DbgS(FormatCount));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
Result := fClipboard.GetOwnership(ClipboardType, OnRequestProc, FormatCount, Formats);
|
||||||
case ClipboardType of
|
|
||||||
ctPrimarySelection: pasteboard := PrimarySelection;
|
|
||||||
ctSecondarySelection: pasteboard := SecondarySelection;
|
|
||||||
ctClipboard: pasteboard := NSPasteboard.generalPasteboard;
|
|
||||||
end;
|
|
||||||
|
|
||||||
DataStream := TMemoryStream.Create;
|
|
||||||
try
|
|
||||||
FormatToOwnArray := nil;
|
|
||||||
if FormatCount>0 then
|
|
||||||
begin
|
|
||||||
FormatToOwnArray := NSArray(NSMutableArray.array_);
|
|
||||||
for i := 0 to FormatCount-1 do
|
|
||||||
begin
|
|
||||||
lCurFormat := TCocoaClipboardData(Formats[i]);
|
|
||||||
if lCurFormat = nil then Continue;
|
|
||||||
FormatToOwn := lCurFormat.CocoaFormat;
|
|
||||||
NSMutableArray(FormatToOwnArray).addObject(FormatToOwn);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Assigned(FormatToOwnArray) and (FormatToOwnArray.count>0) then
|
|
||||||
pasteboard.declareTypes_owner(FormatToOwnArray, nil);
|
|
||||||
|
|
||||||
for i := 0 to FormatCount-1 do
|
|
||||||
begin
|
|
||||||
lCurFormat := TCocoaClipboardData(Formats[i]);
|
|
||||||
if lCurFormat = nil then Continue;
|
|
||||||
DataStream.Position := 0;
|
|
||||||
DataStream.Size := 0;
|
|
||||||
OnRequestProc(Formats[i], DataStream);
|
|
||||||
|
|
||||||
case lCurFormat.DataType of
|
|
||||||
ccdtText:
|
|
||||||
begin
|
|
||||||
DataStream.Position := 0;
|
|
||||||
SetLength(lText, DataStream.Size);
|
|
||||||
DataStream.Read(lText[1], DataStream.Size);
|
|
||||||
lNSText := NSStringUtf8(lText);
|
|
||||||
|
|
||||||
pasteboard.setString_forType(lNSText, lCurFormat.CocoaFormat);
|
|
||||||
end;
|
|
||||||
ccdtCocoaStandard, ccdtNonStandard:
|
|
||||||
begin
|
|
||||||
DataStream.Position := 0;
|
|
||||||
lNSData := NSData.dataWithBytes_length(DataStream.Memory, DataStream.Size);
|
|
||||||
|
|
||||||
pasteboard.setData_forType(lNSData, lCurFormat.CocoaFormat);
|
|
||||||
end;
|
|
||||||
ccdtBitmap:
|
|
||||||
begin
|
|
||||||
Image := TFPMemoryImage.Create(10, 10);
|
|
||||||
Reader := TFPReaderBMP.Create;
|
|
||||||
Writer := TFPWriterPNG.Create;
|
|
||||||
lTmpStream := TMemoryStream.Create;
|
|
||||||
try
|
|
||||||
DataStream.Position := 0;
|
|
||||||
Image.LoadFromStream(DataStream, Reader);
|
|
||||||
Image.SaveToStream(lTmpStream, Writer);
|
|
||||||
lTmpStream.Position := 0;
|
|
||||||
lNSData := NSData.dataWithBytes_length(lTmpStream.Memory, lTmpStream.Size);
|
|
||||||
pasteboard.setData_forType(lNSData, lCurFormat.CocoaFormat);
|
|
||||||
finally
|
|
||||||
Image.Free;
|
|
||||||
Reader.Free;
|
|
||||||
Writer.Free;
|
|
||||||
lTmpStream.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
DataStream.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Pasteboards[ClipboardType].pasteboard:=pasteboard;
|
|
||||||
Pasteboards[ClipboardType].dataProc:=OnRequestProc;
|
|
||||||
if Assigned(pasteboard) then
|
|
||||||
begin
|
|
||||||
Pasteboards[ClipboardType].changeCount:=pasteboard.changeCount;
|
|
||||||
Pasteboards[ClipboardType].isOwned:=true;
|
|
||||||
end else
|
|
||||||
Pasteboards[ClipboardType].isOwned:=false;
|
|
||||||
|
|
||||||
|
|
||||||
Result := True;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -414,64 +228,8 @@ end;
|
|||||||
Returns: The registered Format identifier (TClipboardFormat)
|
Returns: The registered Format identifier (TClipboardFormat)
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function TCocoaWidgetSet.ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat;
|
function TCocoaWidgetSet.ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
lCurData: TCocoaClipboardData;
|
|
||||||
lNSStr: NSString = nil;
|
|
||||||
lDataType: TCocoaClipboardDataType;
|
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := fClipboard.RegisterFormat(AMimeType);
|
||||||
|
|
||||||
// Check first if it was already registered
|
|
||||||
for i := 0 to ClipboardFormats.Count-1 do
|
|
||||||
begin
|
|
||||||
lCurData := TCocoaClipboardData(ClipboardFormats.Items[i]);
|
|
||||||
if lCurData.MimeType = AMimeType then
|
|
||||||
begin
|
|
||||||
Result := TClipboardFormat(lCurData);
|
|
||||||
{$IFDEF VerboseClipboard}
|
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=' + AMimeType
|
|
||||||
+ ' Result='+DbgS(Result));
|
|
||||||
{$ENDIF}
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// if none was found, we need to register it
|
|
||||||
|
|
||||||
lDataType := ccdtNonStandard;
|
|
||||||
// See PredefinedClipboardMimeTypes for the most common mime-types
|
|
||||||
case AMimeType of
|
|
||||||
'text/plain':
|
|
||||||
begin
|
|
||||||
//hack: the name of constants is a hack
|
|
||||||
// should be replaced with either weaklinking
|
|
||||||
// or dynamic loading (dlsym)
|
|
||||||
lNSStr := NSSTR('public.utf8-plain-text'); // NSPasteboardTypeString; // commented out for OSX < 10.6 see #33672
|
|
||||||
lDataType := ccdtText;
|
|
||||||
end;
|
|
||||||
'image/png':
|
|
||||||
begin
|
|
||||||
lNSStr := NSSTR('public.png'); // NSPasteboardTypePNG
|
|
||||||
lDataType := ccdtCocoaStandard;
|
|
||||||
end;
|
|
||||||
'image/bmp':
|
|
||||||
begin
|
|
||||||
lNSStr := NSSTR('public.png'); // NSPasteboardTypePNG
|
|
||||||
lDataType := ccdtBitmap;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
lNSStr := NSStringUtf8(AMimeType);
|
|
||||||
lDataType := ccdtNonStandard;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if lNSStr <> nil then
|
|
||||||
begin
|
|
||||||
lCurData := TCocoaClipboardData.Create(AMimeType, lNSStr, lDataType);
|
|
||||||
ClipboardFormats.Add(lCurData);
|
|
||||||
Result := TClipboardFormat(lCurData);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{$IFDEF VerboseClipboard}
|
{$IFDEF VerboseClipboard}
|
||||||
DebugLn('TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=' + AMimeType
|
DebugLn('TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=' + AMimeType
|
||||||
+ ' Result='+DbgS(Result));
|
+ ' Result='+DbgS(Result));
|
||||||
|
444
lcl/interfaces/cocoa/cocoawsclipboard.pas
Normal file
444
lcl/interfaces/cocoa/cocoawsclipboard.pas
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
unit CocoaWSClipboard;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$modeswitch objectivec2}
|
||||||
|
|
||||||
|
uses
|
||||||
|
CocoaAll, Classes, SysUtils, contnrs
|
||||||
|
// fcl-image
|
||||||
|
,fpreadpng, fpwritepng, fpimage, fpreadbmp, fpwritebmp
|
||||||
|
,LCLType
|
||||||
|
,CocoaUtils;
|
||||||
|
|
||||||
|
type
|
||||||
|
TCocoaClipboardDataType = (ccdtText,
|
||||||
|
ccdtCocoaStandard, // Formats supported natively by Mac OS X
|
||||||
|
ccdtBitmap, // BMPs need conversion to PNG to work with other Mac OS X apps
|
||||||
|
ccdtNonStandard { Formats that will only work in LCL apps } );
|
||||||
|
|
||||||
|
TCocoaClipboardData = class(TObject) // TClipboardFormat is a reference to a TClipboardData
|
||||||
|
public
|
||||||
|
MimeType: string;
|
||||||
|
CocoaFormat: NSString; // utilized for ccdtCocoaStandard and ccdtNonStandard
|
||||||
|
DataType: TCocoaClipboardDataType;
|
||||||
|
constructor Create(AMimeType: string; ACocoaFormat: NSString; ADataType: TCocoaClipboardDataType);
|
||||||
|
destructor Destroy; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TCocoaPasteboardsRef = record
|
||||||
|
pasteboard : NSPasteboard;
|
||||||
|
changeCount: NSInteger;
|
||||||
|
dataProc : TClipboardRequestEvent;
|
||||||
|
isOwned : Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TDynClipboardFormatArray = array of TClipboardFormat;
|
||||||
|
|
||||||
|
{ TCocoaWSClipboard }
|
||||||
|
|
||||||
|
TCocoaWSClipboard = class(TObject)
|
||||||
|
public
|
||||||
|
PrimarySelection: NSPasteboard;
|
||||||
|
SecondarySelection: NSPasteboard;
|
||||||
|
ClipboardFormats: TFPObjectList; // of TCocoaClipboardData
|
||||||
|
Pasteboards: array [TClipboardType] of TCocoaPasteboardsRef;
|
||||||
|
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Sync;
|
||||||
|
|
||||||
|
function FormatToMimeType(FormatID: TClipboardFormat): string;
|
||||||
|
function GetData(ClipboardType: TClipboardType;
|
||||||
|
FormatID: TClipboardFormat; Stream: TStream): boolean;
|
||||||
|
function GetFormats(ClipboardType: TClipboardType;
|
||||||
|
var Count: integer; var List: TDynClipboardFormatArray): boolean;
|
||||||
|
function GetOwnership(ClipboardType: TClipboardType;
|
||||||
|
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
|
||||||
|
Formats: PClipboardFormat): boolean;
|
||||||
|
function RegisterFormat(const AMimeType: string): TClipboardFormat;
|
||||||
|
|
||||||
|
function GetClipboardDataForFormat(AFormat: TClipboardFormat): TCocoaClipboardData;
|
||||||
|
function RegisterCocoaType(AType: NSString): TClipboardFormat;
|
||||||
|
function CocoaTypeToMimeType(AType: NSString): string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
// these constants are available starting MacOSX 10.6
|
||||||
|
// thus for earlier systems must be redeclared
|
||||||
|
_NSPasteboardTypeString : NSString = nil;
|
||||||
|
_NSPasteboardTypePNG : NSString = nil;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure InitConst;
|
||||||
|
begin
|
||||||
|
_NSPasteboardTypeString := NSSTR('public.utf8-plain-text');
|
||||||
|
_NSPasteboardTypePNG := NSSTR('public.png');
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCocoaWSClipboard }
|
||||||
|
|
||||||
|
constructor TCocoaWSClipboard.Create;
|
||||||
|
var
|
||||||
|
t : TClipboardType;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
PrimarySelection := NSPasteboard.pasteboardWithUniqueName();
|
||||||
|
SecondarySelection := NSPasteboard.pasteboardWithUniqueName();
|
||||||
|
ClipboardFormats := TFPObjectList.Create(True);
|
||||||
|
|
||||||
|
Pasteboards[ctPrimarySelection].pasteboard := PrimarySelection;
|
||||||
|
Pasteboards[ctSecondarySelection].pasteboard := SecondarySelection;
|
||||||
|
Pasteboards[ctClipboard].pasteboard := NSPasteboard.generalPasteboard;
|
||||||
|
|
||||||
|
for t := Low(TClipboardType) to High(TClipboardType) do
|
||||||
|
if Assigned(Pasteboards[t].pasteboard) then
|
||||||
|
Pasteboards[t].changeCount := Pasteboards[t].pasteboard.changeCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCocoaWSClipboard.Destroy;
|
||||||
|
begin
|
||||||
|
PrimarySelection.releaseGlobally();
|
||||||
|
SecondarySelection.releaseGlobally();
|
||||||
|
ClipboardFormats.Free;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaWSClipboard.Sync;
|
||||||
|
var
|
||||||
|
ct : TClipboardType;
|
||||||
|
pb : NSPasteboard;
|
||||||
|
begin
|
||||||
|
for ct := low(TClipboardType) to high(TClipboardType) do begin
|
||||||
|
if not Pasteboards[ct].isOwned then Continue;
|
||||||
|
|
||||||
|
pb := Pasteboards[ct].pasteboard;
|
||||||
|
if not Assigned(pb) then Continue;
|
||||||
|
|
||||||
|
if (pb.changeCount <> Pasteboards[ct].changeCount) then
|
||||||
|
begin
|
||||||
|
Pasteboards[ct].isOwned:=false;
|
||||||
|
if Assigned(Pasteboards[ct].dataProc) then
|
||||||
|
// notifying about the loss of ownership
|
||||||
|
Pasteboards[ct].dataProc(0, nil);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.FormatToMimeType(FormatID: TClipboardFormat
|
||||||
|
): string;
|
||||||
|
var
|
||||||
|
lFormat: TCocoaClipboardData;
|
||||||
|
begin
|
||||||
|
lFormat := GetClipboardDataForFormat(FormatID);
|
||||||
|
if lFormat = nil then Exit;
|
||||||
|
Result := lFormat.MimeType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.GetClipboardDataForFormat(AFormat: TClipboardFormat
|
||||||
|
): TCocoaClipboardData;
|
||||||
|
begin
|
||||||
|
Result := TCocoaClipboardData(AFormat);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.GetData(ClipboardType: TClipboardType;
|
||||||
|
FormatID: TClipboardFormat; Stream: TStream): boolean;
|
||||||
|
var
|
||||||
|
pasteboard: NSPasteboard;
|
||||||
|
lFormat: TCocoaClipboardData;
|
||||||
|
lNSStr: NSString;
|
||||||
|
// for text
|
||||||
|
lStr: String;
|
||||||
|
// for standard
|
||||||
|
lNSData: NSData;
|
||||||
|
lNSbytes: PByte;
|
||||||
|
i: Integer;
|
||||||
|
// for bitmap
|
||||||
|
image: TFPCustomImage;
|
||||||
|
lTmpStream: TMemoryStream;
|
||||||
|
reader: TFPCustomImageReader;
|
||||||
|
writer: TFPCustomImageWriter;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
pasteboard := Pasteboards[ClipboardType].pasteboard;
|
||||||
|
|
||||||
|
lFormat := GetClipboardDataForFormat(FormatID);
|
||||||
|
if lFormat = nil then Exit;
|
||||||
|
|
||||||
|
case lFormat.DataType of
|
||||||
|
ccdtText:
|
||||||
|
begin
|
||||||
|
lNSStr := pasteboard.stringForType(lFormat.CocoaFormat);
|
||||||
|
if lNSStr = nil then Exit;
|
||||||
|
lStr := NSStringToString(lNSStr);
|
||||||
|
Stream.Write(lStr[1], Length(lStr));
|
||||||
|
{$IFDEF VerboseClipboard}
|
||||||
|
DebugLn('TCocoaWidgetSet.ClipboardGetData IsText Result=' + lStr);
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
ccdtCocoaStandard, ccdtNonStandard:
|
||||||
|
begin
|
||||||
|
lNSData := pasteboard.dataForType(lFormat.CocoaFormat);
|
||||||
|
if lNSData = nil then Exit;
|
||||||
|
lNSbytes := lNSData.bytes;
|
||||||
|
for i := 0 to lNSData.length-1 do
|
||||||
|
Stream.WriteByte(lNSbytes[i]);
|
||||||
|
end;
|
||||||
|
// In Cocoa images are stored as PNG, convert to BMP for LCL app usage
|
||||||
|
ccdtBitmap:
|
||||||
|
begin
|
||||||
|
lNSData := pasteboard.dataForType(lFormat.CocoaFormat);
|
||||||
|
if lNSData = nil then Exit;
|
||||||
|
lNSbytes := lNSData.bytes;
|
||||||
|
|
||||||
|
Image := TFPMemoryImage.Create(10, 10);
|
||||||
|
Reader := TFPReaderPNG.Create;
|
||||||
|
Writer := TFPWriterBMP.Create;
|
||||||
|
lTmpStream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
for i := 0 to lNSData.length-1 do
|
||||||
|
lTmpStream.WriteByte(lNSbytes[i]);
|
||||||
|
lTmpStream.Position := 0;
|
||||||
|
|
||||||
|
Image.LoadFromStream(lTmpStream, Reader);
|
||||||
|
Image.SaveToStream(Stream, Writer);
|
||||||
|
finally
|
||||||
|
Image.Free;
|
||||||
|
Reader.Free;
|
||||||
|
Writer.Free;
|
||||||
|
lTmpStream.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.GetFormats(ClipboardType: TClipboardType;
|
||||||
|
var Count: integer; var List: TDynClipboardFormatArray): boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
pb : NSPasteboard;
|
||||||
|
tp : NSString;
|
||||||
|
begin
|
||||||
|
pb := Pasteboards[ClipboardType].pasteboard;
|
||||||
|
if not Assigned(pb) then begin
|
||||||
|
Result := false;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
i := 0;
|
||||||
|
SetLength(List, pb.types.count);
|
||||||
|
for tp in pb.types do
|
||||||
|
begin
|
||||||
|
List[i]:=RegisterCocoaType(tp);
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Count := i;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.GetOwnership(ClipboardType: TClipboardType;
|
||||||
|
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
|
||||||
|
Formats: PClipboardFormat): boolean;
|
||||||
|
var
|
||||||
|
pasteboard: NSPasteboard;
|
||||||
|
i: Integer;
|
||||||
|
lCurFormat: TCocoaClipboardData;
|
||||||
|
DataStream: TMemoryStream;
|
||||||
|
FormatToOwn: NSString;
|
||||||
|
FormatToOwnArray: NSArray;
|
||||||
|
// text format
|
||||||
|
lText: string;
|
||||||
|
lNSText: NSString;
|
||||||
|
// non-text
|
||||||
|
lNSData: NSData;
|
||||||
|
// for bitmap
|
||||||
|
image: TFPCustomImage;
|
||||||
|
lTmpStream: TMemoryStream;
|
||||||
|
reader: TFPCustomImageReader;
|
||||||
|
writer: TFPCustomImageWriter;
|
||||||
|
begin
|
||||||
|
pasteboard := Pasteboards[ClipboardType].pasteboard;
|
||||||
|
|
||||||
|
DataStream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
FormatToOwnArray := nil;
|
||||||
|
if FormatCount>0 then
|
||||||
|
begin
|
||||||
|
FormatToOwnArray := NSArray(NSMutableArray.array_);
|
||||||
|
for i := 0 to FormatCount-1 do
|
||||||
|
begin
|
||||||
|
lCurFormat := TCocoaClipboardData(Formats[i]);
|
||||||
|
if lCurFormat = nil then Continue;
|
||||||
|
FormatToOwn := lCurFormat.CocoaFormat;
|
||||||
|
NSMutableArray(FormatToOwnArray).addObject(FormatToOwn);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(FormatToOwnArray) and (FormatToOwnArray.count>0) then
|
||||||
|
pasteboard.declareTypes_owner(FormatToOwnArray, nil);
|
||||||
|
|
||||||
|
for i := 0 to FormatCount-1 do
|
||||||
|
begin
|
||||||
|
lCurFormat := TCocoaClipboardData(Formats[i]);
|
||||||
|
if lCurFormat = nil then Continue;
|
||||||
|
DataStream.Position := 0;
|
||||||
|
DataStream.Size := 0;
|
||||||
|
OnRequestProc(Formats[i], DataStream);
|
||||||
|
|
||||||
|
case lCurFormat.DataType of
|
||||||
|
ccdtText:
|
||||||
|
begin
|
||||||
|
DataStream.Position := 0;
|
||||||
|
SetLength(lText, DataStream.Size);
|
||||||
|
DataStream.Read(lText[1], DataStream.Size);
|
||||||
|
lNSText := NSStringUtf8(lText);
|
||||||
|
|
||||||
|
pasteboard.setString_forType(lNSText, lCurFormat.CocoaFormat);
|
||||||
|
end;
|
||||||
|
ccdtCocoaStandard, ccdtNonStandard:
|
||||||
|
begin
|
||||||
|
DataStream.Position := 0;
|
||||||
|
lNSData := NSData.dataWithBytes_length(DataStream.Memory, DataStream.Size);
|
||||||
|
|
||||||
|
pasteboard.setData_forType(lNSData, lCurFormat.CocoaFormat);
|
||||||
|
end;
|
||||||
|
ccdtBitmap:
|
||||||
|
begin
|
||||||
|
Image := TFPMemoryImage.Create(10, 10);
|
||||||
|
Reader := TFPReaderBMP.Create;
|
||||||
|
Writer := TFPWriterPNG.Create;
|
||||||
|
lTmpStream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
DataStream.Position := 0;
|
||||||
|
Image.LoadFromStream(DataStream, Reader);
|
||||||
|
Image.SaveToStream(lTmpStream, Writer);
|
||||||
|
lTmpStream.Position := 0;
|
||||||
|
lNSData := NSData.dataWithBytes_length(lTmpStream.Memory, lTmpStream.Size);
|
||||||
|
pasteboard.setData_forType(lNSData, lCurFormat.CocoaFormat);
|
||||||
|
finally
|
||||||
|
Image.Free;
|
||||||
|
Reader.Free;
|
||||||
|
Writer.Free;
|
||||||
|
lTmpStream.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
DataStream.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Pasteboards[ClipboardType].pasteboard:=pasteboard;
|
||||||
|
Pasteboards[ClipboardType].dataProc:=OnRequestProc;
|
||||||
|
if Assigned(pasteboard) then
|
||||||
|
begin
|
||||||
|
Pasteboards[ClipboardType].changeCount:=pasteboard.changeCount;
|
||||||
|
Pasteboards[ClipboardType].isOwned:=true;
|
||||||
|
end else
|
||||||
|
Pasteboards[ClipboardType].isOwned:=false;
|
||||||
|
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.RegisterFormat(const AMimeType: string
|
||||||
|
): TClipboardFormat;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
lCurData: TCocoaClipboardData;
|
||||||
|
lNSStr: NSString = nil;
|
||||||
|
lDataType: TCocoaClipboardDataType;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
|
||||||
|
// Check first if it was already registered
|
||||||
|
for i := 0 to ClipboardFormats.Count-1 do
|
||||||
|
begin
|
||||||
|
lCurData := TCocoaClipboardData(ClipboardFormats.Items[i]);
|
||||||
|
if lCurData.MimeType = AMimeType then
|
||||||
|
begin
|
||||||
|
Result := TClipboardFormat(lCurData);
|
||||||
|
{$IFDEF VerboseClipboard}
|
||||||
|
DebugLn('TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=' + AMimeType
|
||||||
|
+ ' Result='+DbgS(Result));
|
||||||
|
{$ENDIF}
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// if none was found, we need to register it
|
||||||
|
|
||||||
|
lDataType := ccdtNonStandard;
|
||||||
|
// See PredefinedClipboardMimeTypes for the most common mime-types
|
||||||
|
case AMimeType of
|
||||||
|
'text/plain':
|
||||||
|
begin
|
||||||
|
//hack: the name of constants is a hack
|
||||||
|
// should be replaced with either weaklinking
|
||||||
|
// or dynamic loading (dlsym)
|
||||||
|
lNSStr := NSSTR('public.utf8-plain-text'); // NSPasteboardTypeString; // commented out for OSX < 10.6 see #33672
|
||||||
|
lDataType := ccdtText;
|
||||||
|
end;
|
||||||
|
'image/png':
|
||||||
|
begin
|
||||||
|
lNSStr := NSSTR('public.png'); // NSPasteboardTypePNG
|
||||||
|
lDataType := ccdtCocoaStandard;
|
||||||
|
end;
|
||||||
|
'image/bmp':
|
||||||
|
begin
|
||||||
|
lNSStr := NSSTR('public.png'); // NSPasteboardTypePNG
|
||||||
|
lDataType := ccdtBitmap;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
lNSStr := NSStringUtf8(AMimeType);
|
||||||
|
lDataType := ccdtNonStandard;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if lNSStr <> nil then
|
||||||
|
begin
|
||||||
|
lCurData := TCocoaClipboardData.Create(AMimeType, lNSStr, lDataType);
|
||||||
|
ClipboardFormats.Add(lCurData);
|
||||||
|
Result := TClipboardFormat(lCurData);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.RegisterCocoaType(AType: NSString): TClipboardFormat;
|
||||||
|
begin
|
||||||
|
Result := RegisterFormat( CocoaTypeToMimeType(AType) );
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaWSClipboard.CocoaTypeToMimeType(AType: NSString): string;
|
||||||
|
begin
|
||||||
|
// "default" types must be mapped to a default LCL mime-type
|
||||||
|
if AType.isEqualToString(_NSPasteboardTypeString) then
|
||||||
|
Result := 'text/plan'
|
||||||
|
else
|
||||||
|
Result := NSStringToString(AType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCocoaClipboardData }
|
||||||
|
|
||||||
|
constructor TCocoaClipboardData.Create(AMimeType: string; ACocoaFormat: NSString; ADataType: TCocoaClipboardDataType);
|
||||||
|
begin
|
||||||
|
MimeType := AMimeType;
|
||||||
|
CocoaFormat := ACocoaFormat;
|
||||||
|
DataType := ADataType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCocoaClipboardData.Destroy;
|
||||||
|
begin
|
||||||
|
CocoaFormat.release;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
initialization
|
||||||
|
InitConst;
|
||||||
|
|
||||||
|
end.
|
@ -129,7 +129,7 @@ end;"/>
|
|||||||
<License Value="modified LGPL-2
|
<License Value="modified LGPL-2
|
||||||
"/>
|
"/>
|
||||||
<Version Major="1" Minor="9"/>
|
<Version Major="1" Minor="9"/>
|
||||||
<Files Count="483">
|
<Files Count="484">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="carbon/agl.pp"/>
|
<Filename Value="carbon/agl.pp"/>
|
||||||
<AddToUsesPkgSection Value="False"/>
|
<AddToUsesPkgSection Value="False"/>
|
||||||
@ -2391,6 +2391,11 @@ end;"/>
|
|||||||
<AddToUsesPkgSection Value="False"/>
|
<AddToUsesPkgSection Value="False"/>
|
||||||
<UnitName Value="CocoaScrollers"/>
|
<UnitName Value="CocoaScrollers"/>
|
||||||
</Item483>
|
</Item483>
|
||||||
|
<Item484>
|
||||||
|
<Filename Value="cocoa/cocoawsclipboard.pas"/>
|
||||||
|
<AddToUsesPkgSection Value="False"/>
|
||||||
|
<UnitName Value="cocoawsclipboard"/>
|
||||||
|
</Item484>
|
||||||
</Files>
|
</Files>
|
||||||
<LazDoc Paths="../../docs/xml/lcl"/>
|
<LazDoc Paths="../../docs/xml/lcl"/>
|
||||||
<i18n>
|
<i18n>
|
||||||
|
Loading…
Reference in New Issue
Block a user