Qt: Fixed all clipboard operations ,no more clipboard problems with copy-paste from other apps into ide editor.

git-svn-id: trunk@14958 -
This commit is contained in:
zeljko 2008-04-25 08:52:42 +00:00
parent f703ada675
commit a47d7719f1

View File

@ -33,7 +33,7 @@ uses
// Free Pascal // Free Pascal
Classes, SysUtils, Types, Classes, SysUtils, Types,
// LCL // LCL
LCLType, LCLIntf, Menus, LCLProc, Graphics; LCLType, LCLIntf, Menus, LCLProc, Graphics, ClipBrd;
type type
// forward declarations // forward declarations
@ -406,13 +406,13 @@ type
TQtClipboard = class(TQtObject) TQtClipboard = class(TQtObject)
private private
{$IFNDEF MSWINDOWS} // {$IFNDEF MSWINDOWS}
FClipChanged: Boolean;
FClipCounter: Integer;
FClipDataChangedHook: QClipboard_hookH; FClipDataChangedHook: QClipboard_hookH;
{$ENDIF} // {$ENDIF}
FClipChanged: Boolean;
FClipBoardFormats: TStringList; FClipBoardFormats: TStringList;
FOnClipBoardRequest: TClipboardRequestEvent; FOnClipBoardRequest: TClipboardRequestEvent;
function IsClipboardChanged: Boolean;
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override; destructor Destroy; override;
@ -2527,10 +2527,6 @@ end;
constructor TQtClipboard.Create; constructor TQtClipboard.Create;
begin begin
inherited Create; inherited Create;
{$IFNDEF MSWINDOWS}
FClipChanged := True;
FClipCounter := 0;
{$ENDIF}
FOnClipBoardRequest := nil; FOnClipBoardRequest := nil;
FClipBoardFormats := TStringList.Create; FClipBoardFormats := TStringList.Create;
FClipBoardFormats.Add('foo'); // 0 is reserved FClipBoardFormats.Add('foo'); // 0 is reserved
@ -2546,28 +2542,50 @@ begin
end; end;
procedure TQtClipboard.AttachEvents; procedure TQtClipboard.AttachEvents;
{$IFNDEF MSWINDOWS}
var var
Method: TMethod; Method: TMethod;
{$ENDIF}
begin begin
inherited AttachEvents; inherited AttachEvents;
{$IFNDEF MSWINDOWS}
FClipDataChangedHook := QClipboard_hook_create(TheObject); FClipDataChangedHook := QClipboard_hook_create(TheObject);
QClipboard_dataChanged_Event(Method) := @signalDataChanged; QClipboard_dataChanged_Event(Method) := @signalDataChanged;
QClipboard_hook_hook_dataChanged(FClipDataChangedHook, Method); QClipboard_hook_hook_dataChanged(FClipDataChangedHook, Method);
{$ENDIF}
end; end;
procedure TQtClipboard.signalDataChanged; cdecl; procedure TQtClipboard.signalDataChanged; cdecl;
begin begin
{$IFNDEF MSWINDOWS}
{$IFDEF VERBOSE_QT_CLIPBOARD} {$IFDEF VERBOSE_QT_CLIPBOARD}
writeln('signalDataChanged()'); writeln('signalDataChanged()');
{$ENDIF} {$ENDIF}
FClipChanged := True; FClipChanged := IsClipboardChanged;
inc(FClipCounter); end;
{$ENDIF}
function TQtClipboard.IsClipboardChanged: Boolean;
var
ClipBord: TClipboard;
AMimeData: QMimeDataH;
Str: WideString;
Str2: WideString;
P: PChar;
begin
Result := False;
AMimeData := getMimeData(QClipboardClipboard);
if (AMimeData <> nil) and
(QMimeData_hasText(AMimeData) or QMimeData_hasHtml(AMimeData) or
QMimeData_hasURLS(AMimeData)) then
begin
QMimeData_text(AMimeData, @Str);
Str := UTF8Encode(Str);
{we must check for null terminator}
if Copy(Str, length(Str), 1) = #0 then
Str2 := Clipbrd.Clipboard.AsText + #0
else
Str2 := Clipbrd.Clipboard.AsText;
Result := Str <> Str2;
if Result then
Clipbrd.Clipboard.AsText := Str;
end;
end; end;
function TQtClipboard.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; function TQtClipboard.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
@ -2577,23 +2595,13 @@ begin
if QEvent_type(Event) = QEventClipboard then if QEvent_type(Event) = QEventClipboard then
begin begin
{$IFDEF MSWINDOWS}
Result := True;
{$ELSE}
Result := FClipChanged; Result := FClipChanged;
{$IFDEF VERBOSE_QT_CLIPBOARD}
writeln('TQtClipboard.EventFilter() RESULT=',Result);
{$ENDIF}
if FClipCounter > 0 then
dec(FClipCounter);
FClipChanged := FClipCounter > 0;
{$ENDIF}
QEvent_accept(Event);
// Clipboard is changed, but we have no ability at moment to pass that info // Clipboard is changed, but we have no ability at moment to pass that info
// to LCL since LCL has no support for that event // to LCL since LCL has no support for that event
// so we are using signalDataChanged() to pass changes to Clipbrd.Clipboard
if FClipChanged then
FClipChanged := False;
QEvent_accept(Event);
end; end;
EndEventProcessing; EndEventProcessing;
end; end;
@ -2677,10 +2685,7 @@ begin
try try
Count := QStringList_size(QtList); Count := QStringList_size(QtList);
{$IFNDEF MSWINDOWS} GetMem(List, Count * SizeOf(TClipboardFormat));
if Count > 0 then
{$ENDIF}
GetMem(List, Count * SizeOf(TClipboardFormat));
for i := 0 to Count - 1 do for i := 0 to Count - 1 do
begin begin
@ -2719,7 +2724,11 @@ function TQtClipboard.GetOwnerShip(ClipboardType: TClipboardType;
MimeType := FormatToMimeType(Formats[I]); MimeType := FormatToMimeType(Formats[I]);
FOnClipBoardRequest(Formats[I], DataStream); FOnClipBoardRequest(Formats[I], DataStream);
Data := QByteArray_create(PAnsiChar(DataStream.Memory), DataStream.Size); {TODO: check if this is correct on darwin (win32,linux are OK!),
seem that data stream always puts an extra #0
which confuses clip operations. If you remove this -1
then we'll get a mess !!!}
Data := QByteArray_create(PAnsiChar(DataStream.Memory), DataStream.Size - 1);
QMimeData_setData(MimeData, @MimeType, Data); QMimeData_setData(MimeData, @MimeType, Data);
QByteArray_destroy(Data); QByteArray_destroy(Data);
end; end;
@ -2741,10 +2750,6 @@ begin
{ clear OnClipBoardRequest to prevent destroying the LCL clipboard, { clear OnClipBoardRequest to prevent destroying the LCL clipboard,
when emptying the clipboard} when emptying the clipboard}
FOnClipBoardRequest := nil; FOnClipBoardRequest := nil;
{Clipboard is cleared each time when setMimeData is called !}
{$IFNDEF MSWINDOWS}
Clear(ClipbBoardTypeToQtClipboard[ClipBoardType]);
{$ENDIF}
FOnClipBoardRequest := OnRequestProc; FOnClipBoardRequest := OnRequestProc;
PutOnClipBoard; PutOnClipBoard;
Result := True; Result := True;