Changeset 326 for trunk/src/gui/kernel/qclipboard_pm.cpp
- Timestamp:
- Nov 19, 2009, 2:44:19 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qclipboard_pm.cpp
r324 r326 92 92 if (!WinOpenClipbrd(NULLHANDLE)) { 93 93 #ifndef QT_NO_DEBUG 94 qWarning("QClipboardWatcher: WinOpenClipbrd failed with 0x%lX",95 WinGetLastError(NULLHANDLE));94 qWarning("QClipboardWatcher::peekData: WinOpenClipbrd " 95 "failed with 0x%lX", WinGetLastError(NULLHANDLE)); 96 96 #endif 97 97 return; … … 168 168 ~QClipboardData(); 169 169 170 void setSource(QMimeData *s) 170 void setSource(QMimeData *s); 171 172 void setAsClipboardViewer(); 173 bool ownsClipboard(); 174 void renderAllFormats(bool isDelayed); 175 176 static QClipboardData *instance() 171 177 { 172 if (s == src) 173 return; 174 delete src; 175 src = s; 176 } 177 178 QMimeData *source() 178 if (instancePtr == 0) { 179 instancePtr = new QClipboardData; 180 } 181 Q_ASSERT(instancePtr); 182 return instancePtr; 183 } 184 185 static void deleteInstance() 179 186 { 180 return src; 181 } 182 187 delete instancePtr; 188 instancePtr = 0; 189 } 190 191 private: 192 bool openClipboard(); 193 void closeClipboard(); 183 194 bool setClipboard(QPMMime *converter, ULONG format, bool isDelayed); 195 void renderFormat(ULONG format); 184 196 185 197 MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2); 186 198 187 private:188 199 QMimeData *src; 200 QList<QPMMime::Match> matches; 201 HWND prevClipboardViewer; 202 203 bool ignore_WM_DESTROYCLIPBOARD; 204 205 static QClipboardData *instancePtr; 189 206 }; 190 207 191 QClipboardData::QClipboardData() : src(0) 208 // static 209 QClipboardData *QClipboardData::instancePtr = 0; 210 211 QClipboardData::QClipboardData() 212 : src(0), prevClipboardViewer(NULLHANDLE) 213 , ignore_WM_DESTROYCLIPBOARD(false) 192 214 { 193 215 } … … 195 217 QClipboardData::~QClipboardData() 196 218 { 219 renderAllFormats(false); 220 setSource(0); 221 222 // make sure we are not the clipboard viewer any more 223 if (hwnd() == WinQueryClipbrdViewer(NULLHANDLE)) 224 WinSetClipbrdViewer(NULLHANDLE, prevClipboardViewer); 225 } 226 227 void QClipboardData::setSource(QMimeData *s) 228 { 229 if (s == src) 230 return; 197 231 delete src; 232 src = s; 233 234 // build the list of all mime <-> cf matches 235 matches.clear(); 236 if (src) 237 matches = QPMMime::allConvertersFromMimeData(src); 238 } 239 240 void QClipboardData::setAsClipboardViewer() 241 { 242 HWND clipboardViewer = WinQueryClipbrdViewer(NULLHANDLE); 243 if (hwnd() != clipboardViewer) { 244 prevClipboardViewer = clipboardViewer; 245 BOOL ok = WinSetClipbrdViewer(NULLHANDLE, hwnd()); 246 Q_UNUSED(ok); 247 #ifndef QT_NO_DEBUG 248 if (!ok) 249 qWarning("QClipboardData::setAsClipboardViewer: WinSetClipbrdViewer " 250 " failed with 0x%lX", WinGetLastError(NULLHANDLE)); 251 #endif 252 } 253 } 254 255 bool QClipboardData::ownsClipboard() 256 { 257 return src && hwnd() == WinQueryClipbrdOwner(NULLHANDLE); 258 } 259 260 bool QClipboardData::openClipboard() 261 { 262 if (!WinOpenClipbrd(NULLHANDLE)) { 263 #ifndef QT_NO_DEBUG 264 qWarning("QClipboardData::openClipboard: WinOpenClipbrd " 265 "failed with 0x%lX", WinGetLastError(NULLHANDLE)); 266 #endif 267 return false; 268 } 269 return true; 270 } 271 272 void QClipboardData::closeClipboard() 273 { 274 WinCloseClipbrd(NULLHANDLE); 198 275 } 199 276 … … 223 300 #ifdef QCLIPBOARD_DEBUG 224 301 qDebug("QClipboardData::setClipboard: convert to CF 0x%lX, flags 0x%lX," 225 "data 0x%lX, ok %d", format, flags, data, ok);302 "data 0x%lX, delayed %d, ok %d", format, flags, data, isDelayed, ok); 226 303 #endif 227 304 … … 229 306 } 230 307 308 void QClipboardData::renderFormat(ULONG format) 309 { 310 #ifdef QCLIPBOARD_DEBUG 311 qDebug("QClipboardData::renderFormat: CF 0x%lX", format); 312 #endif 313 314 if (!src) 315 return; 316 317 if (!openClipboard()) 318 return; 319 320 foreach(QPMMime::Match match, matches) { 321 if (match.format == format) { 322 setClipboard(match.converter, match.format, false); 323 break; 324 } 325 } 326 327 closeClipboard(); 328 } 329 330 void QClipboardData::renderAllFormats(bool isDelayed) 331 { 332 #ifdef QCLIPBOARD_DEBUG 333 qDebug() << "QClipboardData::renderAllFormats: isDelayed" << isDelayed; 334 #endif 335 336 if (!openClipboard()) 337 return; 338 339 // delete the clipboard contents before we render everything to make sure 340 // nothing is left there from another owner 341 ignore_WM_DESTROYCLIPBOARD = true; 342 BOOL ok = WinEmptyClipbrd(NULLHANDLE); 343 ignore_WM_DESTROYCLIPBOARD = false; 344 if (!ok) { 345 #ifndef QT_NO_DEBUG 346 qWarning("QClipboardData::renderAllFormats: WinEmptyClipbrd " 347 "failed with 0x%lX", WinGetLastError(NULLHANDLE)); 348 #endif 349 return; 350 } 351 352 if (src) { 353 #ifdef QCLIPBOARD_DEBUG 354 qDebug() << "QClipboardData::renderAllFormats: mimes" << src->formats(); 355 #endif 356 foreach(QPMMime::Match match, matches) 357 setClipboard(match.converter, match.format, isDelayed); 358 } 359 360 closeClipboard(); 361 } 362 231 363 MRESULT QClipboardData::message(ULONG msg, MPARAM mp1, MPARAM mp2) 232 364 { 233 return 0; 234 } 235 236 static QClipboardData *ptrClipboardData = 0; 237 238 static QClipboardData *clipboardData() 239 { 240 if (ptrClipboardData == 0) { 241 ptrClipboardData = new QClipboardData; 242 } 243 return ptrClipboardData; 244 } 245 246 static void cleanupClipboardData() 247 { 248 delete ptrClipboardData; 249 ptrClipboardData = 0; 365 #ifdef QCLIPBOARD_DEBUG 366 qDebug("QClipboardData::message: msg %08lX, mp1 %p, mp2 %p", 367 msg, mp1, mp2); 368 #endif 369 370 switch (msg) { 371 372 case WM_DRAWCLIPBOARD: { 373 // ask QClipboard to emit changed() signals 374 QClipboardEvent e(reinterpret_cast<QEventPrivate *>(1)); 375 qt_sendSpontaneousEvent(QApplication::clipboard(), &e); 376 377 if (hwnd() != WinQueryClipbrdOwner(NULLHANDLE) && src) { 378 // we no longer the clipboard, clean up the clipboard object 379 setSource(0); 380 } 381 // PM doesn't inform the previous clipboard viewer if another 382 // app changes it (nor does it support viewer chains in some other 383 // way). The best we can do is to propagate the message to the 384 // previous clipboard viewer ourselves (though there is no guarantee 385 // that all non-Qt apps will do the same). 386 if (prevClipboardViewer) { 387 // propagate the message to the previous clipboard viewer 388 BOOL ok = WinPostMsg(prevClipboardViewer, msg, mp1, mp2); 389 if (!ok) 390 prevClipboardViewer = NULLHANDLE; 391 } 392 break; 393 } 394 395 case WM_DESTROYCLIPBOARD: 396 if (!ignore_WM_DESTROYCLIPBOARD) 397 setSource(0); 398 break; 399 400 case WM_RENDERFMT: 401 renderFormat((ULONG)mp1); 402 break; 403 404 case WM_RENDERALLFMTS: 405 renderAllFormats(false); 406 break; 407 408 default: 409 break; 410 } 411 412 return (MRESULT)TRUE; 250 413 } 251 414 252 415 //////////////////////////////////////////////////////////////////////////////// 253 416 254 static bool ignore_WM_DESTROYCLIPBOARD = FALSE;255 256 417 QClipboard::~QClipboard() 257 418 { 258 cleanupClipboardData();419 QClipboardData::deleteInstance(); 259 420 } 260 421 261 422 void QClipboard::setMimeData(QMimeData *src, Mode mode) 262 423 { 424 #ifdef QCLIPBOARD_DEBUG 425 qDebug() << "QClipboard::setMimeData: src" << src << "mode" << mode; 426 #endif 427 263 428 if (mode != Clipboard) { 264 429 delete src; … … 266 431 } 267 432 268 if (!WinOpenClipbrd(NULLHANDLE)) { 269 #ifndef QT_NO_DEBUG 270 qWarning("QClipboard::setMimeData: WinOpenClipbrd failed with 0x%lX", 271 WinGetLastError(NULLHANDLE)); 272 #endif 273 delete src; 274 return; 275 } 276 277 QClipboardData *d = clipboardData(); 433 QClipboardData *d = QClipboardData::instance(); 278 434 d->setSource(src); 279 280 ignore_WM_DESTROYCLIPBOARD = TRUE;281 BOOL ok = WinEmptyClipbrd(NULLHANDLE);282 ignore_WM_DESTROYCLIPBOARD = FALSE;283 #ifndef QT_NO_DEBUG284 if (!ok)285 qWarning("QClipboard::setMimeData: WinEmptyClipbrd failed with 0x%lX",286 WinGetLastError(NULLHANDLE));287 #else288 Q_UNUSED(ok);289 #endif290 435 291 436 if (!src) … … 295 440 QCoreApplication::instance()->d_func()->in_exec; 296 441 297 QStringList formats = src->formats(); 298 foreach(QString mime, formats) { 299 #ifdef QCLIPBOARD_DEBUG 300 qDebug() << "QClipboard::setMimeData: src mime" << mime; 301 #endif 302 QList<QPMMime::Match> matches = QPMMime::allConvertersFromMimeData(src); 303 foreach(QPMMime::Match match, matches) { 304 d->setClipboard(match.converter, match.format, !runsEventLoop); 305 } 306 } 307 308 WinCloseClipbrd(NULLHANDLE); 442 d->renderAllFormats(runsEventLoop); 309 443 } 310 444 311 445 void QClipboard::clear(Mode mode) 312 446 { 313 // @todo implement447 setMimeData(0, Clipboard); 314 448 } 315 449 316 450 bool QClipboard::event(QEvent *e) 317 451 { 318 // @todo implement 319 return false; 452 if (e->type() != QEvent::Clipboard) 453 return QObject::event(e); 454 455 if (!((QClipboardEvent*)e)->data()) { 456 // this is sent by QApplication to render all formats at app shut down 457 QClipboardData::instance()->renderAllFormats(false); 458 } else { 459 // this is sent by QClipboardData to notify about clipboard data change 460 emitChanged(QClipboard::Clipboard); 461 } 462 463 return true; 320 464 } 321 465 322 466 void QClipboard::connectNotify(const char *signal) 323 467 { 324 // @todo implement 468 if (qstrcmp(signal, SIGNAL(dataChanged())) == 0) { 469 // ensure we are up and running (by instantiating QClipboardData and 470 // setting it as the clipboard viewer to receive notifications on 471 // clipboard contents chages) but block signals so the dataChange signal 472 // is not emitted while being connected to. 473 bool blocked = blockSignals(true); 474 QClipboardData::instance()->setAsClipboardViewer(); 475 blockSignals(blocked); 476 } 325 477 } 326 478 … … 338 490 bool QClipboard::ownsMode(Mode mode) const 339 491 { 340 // @todo implement 492 if (mode == Clipboard) { 493 return QClipboardData::instance()->ownsClipboard(); 494 } 341 495 return false; 342 496 } … … 344 498 void QClipboard::ownerDestroyed() 345 499 { 500 // not used 346 501 } 347 502
Note:
See TracChangeset
for help on using the changeset viewer.