source: trunk/src/gui/kernel/qclipboard_s60.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qclipboard.h"
43
44#ifndef QT_NO_CLIPBOARD
45
46#include "qapplication.h"
47#include "qbitmap.h"
48#include "qdatetime.h"
49#include "qbuffer.h"
50#include "qwidget.h"
51#include "qevent.h"
52#include "private/qcore_symbian_p.h"
53#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
54#include "txtclipboard.h"
55#endif
56#include "txtetext.h"
57#include <QtDebug>
58
59// Symbian's clipboard
60#include <baclipb.h>
61QT_BEGIN_NAMESPACE
62
63const TUid KQtCbDataStream = {0x2001B2DD};
64const TInt KPlainTextBegin = 0;
65
66class QClipboardData
67{
68public:
69 QClipboardData();
70 ~QClipboardData();
71
72 void setSource(QMimeData* s)
73 {
74 if (s == src)
75 return;
76 delete src;
77 src = s;
78 }
79 QMimeData* source()
80 { return src; }
81 bool connected()
82 { return connection; }
83 void clear();
84
85private:
86 QMimeData* src;
87 bool connection;
88};
89
90QClipboardData::QClipboardData():src(0),connection(true)
91{
92 clear();
93}
94
95QClipboardData::~QClipboardData()
96{
97 connection = false;
98 delete src;
99}
100
101void QClipboardData::clear()
102{
103 QMimeData* newSrc = new QMimeData;
104 delete src;
105 src = newSrc;
106}
107
108static QClipboardData *internalCbData = 0;
109
110static void cleanupClipboardData()
111{
112 delete internalCbData;
113 internalCbData = 0;
114}
115
116static QClipboardData *clipboardData()
117{
118 if (internalCbData == 0) {
119 internalCbData = new QClipboardData;
120 if (internalCbData)
121 {
122 if (!internalCbData->connected())
123 {
124 delete internalCbData;
125 internalCbData = 0;
126 }
127 else
128 {
129 qAddPostRoutine(cleanupClipboardData);
130 }
131 }
132 }
133 return internalCbData;
134}
135
136void writeToStreamLX(const QMimeData* aData, RWriteStream& aStream)
137{
138 // This function both leaves and throws exceptions. There must be no destructor
139 // dependencies between cleanup styles, and no cleanup stack dependencies on stacked objects.
140 QStringList headers = aData->formats();
141 aStream << TCardinality(headers.count());
142 for (QStringList::const_iterator iter= headers.constBegin();iter != headers.constEnd();iter++)
143 {
144 HBufC* stringData = TPtrC(reinterpret_cast<const TUint16*>((*iter).utf16())).AllocLC();
145 QByteArray ba = aData->data((*iter));
146 // mime type
147 aStream << TCardinality(stringData->Size());
148 aStream << *(stringData);
149 // mime data
150 aStream << TCardinality(ba.size());
151 aStream.WriteL(reinterpret_cast<const uchar*>(ba.constData()),ba.size());
152 CleanupStack::PopAndDestroy(stringData);
153 }
154}
155
156void writeToSymbianStoreLX(const QMimeData* aData, CClipboard* clipboard)
157{
158 // This function both leaves and throws exceptions. There must be no destructor
159 // dependencies between cleanup styles, and no cleanup stack dependencies on stacked objects.
160 if (aData->hasText()) {
161 CPlainText* text = CPlainText::NewL();
162 CleanupStack::PushL(text);
163
164 TPtrC textPtr(qt_QString2TPtrC(aData->text()));
165 text->InsertL(KPlainTextBegin, textPtr);
166 text->CopyToStoreL(clipboard->Store(), clipboard->StreamDictionary(),
167 KPlainTextBegin, textPtr.Length());
168 CleanupStack::PopAndDestroy(text);
169 }
170}
171
172void readSymbianStoreLX(QMimeData* aData, CClipboard* clipboard)
173{
174 // This function both leaves and throws exceptions. There must be no destructor
175 // dependencies between cleanup styles, and no cleanup stack dependencies on stacked objects.
176 CPlainText* text = CPlainText::NewL();
177 CleanupStack::PushL(text);
178 TInt dataLength = text->PasteFromStoreL(clipboard->Store(), clipboard->StreamDictionary(),
179 KPlainTextBegin);
180 if (dataLength == 0) {
181 User::Leave(KErrNotFound);
182 }
183 HBufC* hBuf = HBufC::NewL(dataLength);
184 TPtr buf = hBuf->Des();
185 text->Extract(buf, KPlainTextBegin, dataLength);
186
187 QString string = qt_TDesC2QString(buf);
188 CleanupStack::PopAndDestroy(text);
189
190 aData->setText(string);
191}
192
193void readFromStreamLX(QMimeData* aData,RReadStream& aStream)
194{
195 // This function both leaves and throws exceptions. There must be no destructor
196 // dependencies between cleanup styles, and no cleanup stack dependencies on stacked objects.
197 TCardinality mimeTypeCount;
198 aStream >> mimeTypeCount;
199 for (int i = 0; i< mimeTypeCount;i++)
200 {
201 // mime type
202 TCardinality mimeTypeSize;
203 aStream >> mimeTypeSize;
204 HBufC* mimeTypeBuf = HBufC::NewLC(aStream,mimeTypeSize);
205 QString mimeType = QString(reinterpret_cast<const QChar *>(mimeTypeBuf->Des().Ptr()),
206 mimeTypeBuf->Length());
207 CleanupStack::PopAndDestroy(mimeTypeBuf);
208 // mime data
209 TCardinality dataSize;
210 aStream >> dataSize;
211 QByteArray ba;
212 ba.reserve(dataSize);
213 aStream.ReadL(reinterpret_cast<uchar*>(ba.data_ptr()->data),dataSize);
214 ba.data_ptr()->size = dataSize;
215 aData->setData(mimeType,ba);
216 }
217}
218
219
220/*****************************************************************************
221 QClipboard member functions
222 *****************************************************************************/
223
224void QClipboard::clear(Mode mode)
225{
226 setText(QString(), mode);
227}
228const QMimeData* QClipboard::mimeData(Mode mode) const
229{
230 if (mode != Clipboard) return 0;
231 QClipboardData *d = clipboardData();
232 bool dataExists(false);
233 if (d)
234 {
235 TRAPD(err,{
236 RFs fs = qt_s60GetRFs();
237 CClipboard* cb = CClipboard::NewForReadingLC(fs);
238 Q_ASSERT(cb);
239 //stream for qt
240 RStoreReadStream stream;
241 TStreamId stid = (cb->StreamDictionary()).At(KQtCbDataStream);
242 if (stid != 0) {
243 stream.OpenLC(cb->Store(),stid);
244 QT_TRYCATCH_LEAVING(readFromStreamLX(d->source(),stream));
245 CleanupStack::PopAndDestroy(&stream);
246 dataExists = true;
247 }
248 else {
249 //symbian clipboard
250 RStoreReadStream symbianStream;
251 TStreamId symbianStId = (cb->StreamDictionary()).At(KClipboardUidTypePlainText);
252 if (symbianStId != 0) {
253 symbianStream.OpenLC(cb->Store(), symbianStId);
254 QT_TRYCATCH_LEAVING(readSymbianStoreLX(d->source(), cb));
255 CleanupStack::PopAndDestroy(&symbianStream);
256 dataExists = true;
257 }
258 }
259 CleanupStack::PopAndDestroy(cb);
260 });
261 if (err != KErrNone){
262 qDebug()<< "clipboard is empty/err: " << err;
263 }
264
265 if (dataExists) {
266 return d->source();
267 }
268 }
269 return 0;
270}
271
272
273void QClipboard::setMimeData(QMimeData* src, Mode mode)
274{
275 if (mode != Clipboard) return;
276 QClipboardData *d = clipboardData();
277 if (d)
278 {
279 TRAPD(err,{
280 RFs fs = qt_s60GetRFs();
281 CClipboard* cb = CClipboard::NewForWritingLC(fs);
282 //stream for qt
283 RStoreWriteStream stream;
284 TStreamId stid = stream.CreateLC(cb->Store());
285 QT_TRYCATCH_LEAVING(writeToStreamLX(src,stream));
286 d->setSource(src);
287 stream.CommitL();
288 (cb->StreamDictionary()).AssignL(KQtCbDataStream,stid);
289 cb->CommitL();
290
291 //stream for symbian
292 RStoreWriteStream symbianStream;
293 TStreamId symbianStId = symbianStream.CreateLC(cb->Store());
294 QT_TRYCATCH_LEAVING(writeToSymbianStoreLX(src, cb));
295 (cb->StreamDictionary()).AssignL(KClipboardUidTypePlainText, symbianStId);
296 cb->CommitL();
297 CleanupStack::PopAndDestroy(3,cb);
298 });
299 if (err != KErrNone){
300 qDebug()<< "clipboard write err :" << err;
301 }
302 }
303 emitChanged(QClipboard::Clipboard);
304}
305
306bool QClipboard::supportsMode(Mode mode) const
307{
308 return (mode == Clipboard);
309}
310
311bool QClipboard::ownsMode(Mode mode) const
312{
313 if (mode == Clipboard)
314 qWarning("QClipboard::ownsClipboard: UNIMPLEMENTED!");
315 return false;
316}
317
318bool QClipboard::event(QEvent * /* e */)
319{
320 return true;
321}
322
323void QClipboard::connectNotify( const char * )
324{
325}
326
327void QClipboard::ownerDestroyed()
328{
329}
330QT_END_NAMESPACE
331#endif // QT_NO_CLIPBOARD
Note: See TracBrowser for help on using the repository browser.