Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-84662

Drag/drop of "text/plain" does not work, QMimeData::text() returns an empty string

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: P2: Important P2: Important
    • 5.15.1
    • 5.15.0, 5.15
    • GUI: Drag and Drop
    • None
    • Qt 5.15.0, openSUSE Leap 15.1
    • Linux/X11
    • 5826a7ad921930393c84b790123f493e26d0685c (qt/qtbase/5.15)

      Drag/drop of "text/plain" does not work, QMimeData::text() returns an empty string. The bug came in with the fix for QTBUG-54786, Qt 5.13.0 (despite the fix itself seems correct). Reason: QMimeDataPrivate::retrieveTypedData does not reliably return QVariant::isNull(), if the MIME type does not match, e.g. in the following case:

      #if QT_CONFIG(textcodec)
              case QMetaType::QString: {
                  const QByteArray ba = data.toByteArray();
                  QTextCodec *codec = QTextCodec::codecForName("utf-8");
                  if (format == QLatin1String("text/html"))
                      codec = QTextCodec::codecForHtml(ba, codec);
                  return codec->toUnicode(ba);
              }
      #endif // textcodec
      

      Suggested (but unreviewed) fix QMimeDataPrivate::retrieveTypedData(take the branch #if FIXED):

          #if FIXED
      
          // Text data requested: fallback to URL data if available
          if (data.isNull() && format == QLatin1String("text/plain")) {
              data = retrieveTypedData(textUriListLiteral(), QMetaType::QVariantList);
              if (data.isNull())
                  return data;
              if (data.userType() == QMetaType::QUrl) {
                  data = QVariant(data.toUrl().toDisplayString());
              } else if (data.userType() == QMetaType::QVariantList) {
                  QString text;
                  int numUrls = 0;
                  const QList<QVariant> list = data.toList();
                  for (int i = 0; i < list.size(); ++i) {
                      if (list.at(i).userType() == QMetaType::QUrl) {
                          text += list.at(i).toUrl().toDisplayString() + QLatin1Char('\n');
                          ++numUrls;
                      }
                  }
                  if (numUrls == 1)
                      text.chop(1); // no final '\n' if there's only one URL
                  data = QVariant(text);
              }
          }
      
          if (data.userType() == type || data.isNull())
              return data;
      
          #else
      
          // Text data requested: fallback to URL data if available
          if (format == QLatin1String("text/plain") && !data.isValid()) {
              data = retrieveTypedData(textUriListLiteral(), QMetaType::QVariantList);
              if (data.userType() == QMetaType::QUrl) {
                  data = QVariant(data.toUrl().toDisplayString());
              } else if (data.userType() == QMetaType::QVariantList) {
                  QString text;
                  int numUrls = 0;
                  const QList<QVariant> list = data.toList();
                  for (int i = 0; i < list.size(); ++i) {
                      if (list.at(i).userType() == QMetaType::QUrl) {
                          text += list.at(i).toUrl().toDisplayString() + QLatin1Char('\n');
                          ++numUrls;
                      }
                  }
                  if (numUrls == 1)
                      text.chop(1); // no final '\n' if there's only one URL
                  data = QVariant(text);
              }
          }
      
          if (data.userType() == type || !data.isValid())
              return data;
      
          #endif
      

      The bug can be reproduced with the attached application "app". This app shows a QLineEdit at the top and a QTextEdit at the bottom. Start two instances of that app, type an arbitrary text into the QLineEdit of the first instance and try to drag the text to the edits of the second instance. On drop the target QLineEdit receives an empty string. The target QTextEdit does not accept the drop at all, because QTextEdit refuses empty strings.

       

        For Gerrit Dashboard: QTBUG-84662
        # Subject Branch Project Status CR V

            liaqi Liang Qi
            wschenke Winfried Schenke
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes