Cocoa: Support pasting rich text to Qt apps

Native Mac OS X apps uses Rtf as the rich text format
while Qt uses html. Add QMacPasteboardMimeRtfText
which supports converting from public.rtf to text/html
(but not the other way around, since we want to keep
posting our html as html).

The QMacInternalPasteboardMime API does not support
the concept of a one-way handler. Skip the Rtf handler
in QMacPasteboard::setMimeData().

Task-number: QTBUG-37188
Change-Id: Ibe29997a038bbb64da24b961e84a5f60133074e0
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
Morten Johan Sørvig 2014-03-20 22:05:59 +01:00 committed by The Qt Project
parent f1540a2966
commit d24ada47b4
2 changed files with 72 additions and 0 deletions

View File

@ -136,9 +136,76 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
return ret;
}
// This handler is special: It supports converting public.rtf top text/html,
// but not the other way around.
class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime {
public:
QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
QString mimeFor(QString flav);
bool canConvert(const QString &mime, QString flav);
QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
};
QString QMacPasteboardMimeRtfText::convertorName()
{
return QLatin1String("Rtf");
}
QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime)
{
if (mime == QLatin1String("text/html"))
return QLatin1String("public.rtf");
return QString();
}
QString QMacPasteboardMimeRtfText::mimeFor(QString flav)
{
if (flav == QLatin1String("public.rtf"))
return QLatin1String("text/html");
return QString();
}
bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav)
{
return flavorFor(mime) == flav;
}
QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
{
if (!canConvert(mimeType, flavor))
return QVariant();
if (data.count() > 1)
qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
// Convert Rtf to Html.
NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL];
NSError *error;
NSRange range = NSMakeRange(0,[string length]);
NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error];
[string release];
return QByteArray::fromNSData(htmldata);
}
QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor)
{
Q_UNUSED(mime);
Q_UNUSED(data);
Q_UNUSED(flavor);
qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported");
QList<QByteArray> ret;
return ret;
}
void QCocoaMimeTypes::initializeMimeTypes()
{
new QMacPasteboardMimeTiff;
new QMacPasteboardMimeRtfText;
}
QT_END_NAMESPACE

View File

@ -305,6 +305,11 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
QString mimeType = formats.at(f);
for (QList<QMacInternalPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
QMacInternalPasteboardMime *c = (*it);
// Hack: The Rtf handler converts incoming Rtf to Html. We do
// not want to convert outgoing Html to Rtf but instead keep
// posting it as Html. Skip the Rtf handler here.
if (c->convertorName() == QStringLiteral("Rtf"))
continue;
QString flavor(c->flavorFor(mimeType));
if (!flavor.isEmpty()) {
QVariant mimeData = static_cast<QMacMimeData*>(mime_src)->variantData(mimeType);