NS_IMETHODIMP nsClipboard::SetNativeClipboardData( nsITransferable *aTransferable, QClipboard::Mode clipboardMode ) { if (nullptr == aTransferable) { NS_WARNING("nsClipboard::SetNativeClipboardData(): no transferable!"); return NS_ERROR_FAILURE; } // get flavor list that includes all flavors that can be written (including // ones obtained through conversion) nsCOMPtr<nsISupportsArray> flavorList; nsresult rv = aTransferable->FlavorsTransferableCanExport( getter_AddRefs(flavorList) ); if (NS_FAILED(rv)) { NS_WARNING("nsClipboard::SetNativeClipboardData(): no FlavorsTransferable !"); return NS_ERROR_FAILURE; } QClipboard *cb = QGuiApplication::clipboard(); QMimeData *mimeData = new QMimeData; uint32_t flavorCount = 0; flavorList->Count(&flavorCount); bool imageAdded = false; for (uint32_t i = 0; i < flavorCount; ++i) { nsCOMPtr<nsISupports> genericFlavor; flavorList->GetElementAt(i,getter_AddRefs(genericFlavor)); nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor)); if (currentFlavor) { // flavorStr is the mime type nsXPIDLCString flavorStr; currentFlavor->ToString(getter_Copies(flavorStr)); // Clip is the data which will be sent to the clipboard nsCOMPtr<nsISupports> clip; // len is the length of the data uint32_t len; // Unicode text? if (!strcmp(flavorStr.get(), kUnicodeMime)) { rv = aTransferable->GetTransferData(flavorStr,getter_AddRefs(clip),&len); nsCOMPtr<nsISupportsString> wideString; wideString = do_QueryInterface(clip); if (!wideString || NS_FAILED(rv)) continue; nsAutoString utf16string; wideString->GetData(utf16string); QString str = QString::fromUtf16((const ushort*)utf16string.get()); // Add text to the mimeData mimeData->setText(str); } // html? else if (!strcmp(flavorStr.get(), kHTMLMime)) { rv = aTransferable->GetTransferData(flavorStr,getter_AddRefs(clip),&len); nsCOMPtr<nsISupportsString> wideString; wideString = do_QueryInterface(clip); if (!wideString || NS_FAILED(rv)) continue; nsAutoString utf16string; wideString->GetData(utf16string); QString str = QString::fromUtf16((const ushort*)utf16string.get()); // Add html to the mimeData mimeData->setHtml(str); } // image? else if (!imageAdded // image is added only once to the clipboard && (!strcmp(flavorStr.get(), kNativeImageMime) || !strcmp(flavorStr.get(), kPNGImageMime) || !strcmp(flavorStr.get(), kJPEGImageMime) || !strcmp(flavorStr.get(), kJPGImageMime) || !strcmp(flavorStr.get(), kGIFImageMime)) ) { // Look through our transfer data for the image static const char* const imageMimeTypes[] = { kNativeImageMime, kPNGImageMime, kJPEGImageMime, kJPGImageMime, kGIFImageMime }; nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive; for (uint32_t i = 0; !ptrPrimitive && i < ArrayLength(imageMimeTypes); i++) { aTransferable->GetTransferData(imageMimeTypes[i], getter_AddRefs(clip), &len); ptrPrimitive = do_QueryInterface(clip); } if (!ptrPrimitive) continue; nsCOMPtr<nsISupports> primitiveData; ptrPrimitive->GetData(getter_AddRefs(primitiveData)); nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData)); if (!image) // Not getting an image for an image mime type!? continue; RefPtr<SourceSurface> surface = image->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); if (!surface) continue; RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface(); if (!dataSurface) continue; DataSourceSurface::MappedSurface map; if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) continue; QImage qImage(map.mData, dataSurface->GetSize().width, dataSurface->GetSize().height, map.mStride, _moz2dformat_to_qformat(dataSurface->GetFormat())); dataSurface->Unmap(); // Add image to the mimeData mimeData->setImageData(qImage); imageAdded = true; } // Other flavors, adding data to clipboard "as is" else { rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(clip), &len); // nothing found? if (!clip || NS_FAILED(rv)) continue; void *primitive_data = nullptr; nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr.get(), clip, &primitive_data, len); if (primitive_data) { QByteArray data ((const char *)primitive_data, len); // Add data to the mimeData mimeData->setData(flavorStr.get(), data); free(primitive_data); } } } } // If we have some mime data, add it to the clipboard if(!mimeData->formats().isEmpty()) cb->setMimeData(mimeData, clipboardMode); else delete mimeData; return NS_OK; }