]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt4/GuiClipboard.C
Fix bug 2138: copy and paste should preserve formatting between different
[features.git] / src / frontends / qt4 / GuiClipboard.C
index 235a72986ced3f637abaf171a363ba3387d28dcd..0f770319e5cc04198528b7a1d28b960475e55904 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <QApplication>
 #include <QClipboard>
+#include <QMimeData>
 #include <QString>
 
 #include "support/lstrings.h"
@@ -26,15 +27,50 @@ using lyx::support::internalLineEnding;
 using lyx::support::externalLineEnding;
 
 using std::endl;
+using std::string;
+
+
+namespace {
+
+char const * const mime_type = "application/x-lyx";
+
+}
+
 
 namespace lyx {
 namespace frontend {
 
-docstring const GuiClipboard::get() const
+string const GuiClipboard::getAsLyX() const
 {
+       lyxerr[Debug::ACTION] << "GuiClipboard::getAsLyX(): `";
+       // We don't convert encodings here since the encoding of the
+       // clipboard contents is specified in the data itself
+       QMimeData const * source =
+               qApp->clipboard()->mimeData(QClipboard::Clipboard);
+       if (!source) {
+               lyxerr[Debug::ACTION] << "' (no QMimeData)" << endl;
+               return string();
+       }
+       if (source->hasFormat(mime_type)) {
+               // data from ourself or some other LyX instance
+               QByteArray const ar = source->data(mime_type);
+               string const s(ar.data(), ar.count());
+               if (lyxerr.debugging(Debug::ACTION))
+                       lyxerr[Debug::ACTION] << s << "'" << endl;
+               return s;
+       }
+       lyxerr[Debug::ACTION] << "'" << endl;
+       return string();
+}
+
+
+docstring const GuiClipboard::getAsText() const
+{
+       // text data from other applications
        QString const str = qApp->clipboard()->text(QClipboard::Clipboard);
-       lyxerr[Debug::ACTION] << "GuiClipboard::get: " << fromqstr(str)
-                             << endl;
+       if (lyxerr.debugging(Debug::ACTION))
+               lyxerr[Debug::ACTION] << "GuiClipboard::getAsText(): `"
+                                     << fromqstr(str) << "'" << endl;
        if (str.isNull())
                return docstring();
 
@@ -42,12 +78,31 @@ docstring const GuiClipboard::get() const
 }
 
 
-void GuiClipboard::put(docstring const & str)
+void GuiClipboard::put(string const & lyx, docstring const & text)
 {
-       lyxerr[Debug::ACTION] << "GuiClipboard::put: " << lyx::to_utf8(str) << endl;
+       if (lyxerr.debugging(Debug::ACTION))
+               lyxerr[Debug::ACTION] << "GuiClipboard::put(`" << lyx << "' `"
+                                     << to_utf8(text) << "')" << endl;
+       // We don't convert the encoding of lyx since the encoding of the
+       // clipboard contents is specified in the data itself
+       QMimeData * data = new QMimeData;
+       if (!lyx.empty()) {
+               QByteArray const qlyx(lyx.c_str(), lyx.size());
+               data->setData(mime_type, qlyx);
+       }
+       // Don't test for text.empty() since we want to be able to clear the
+       // clipboard.
+       QString const qtext = toqstr(text);
+       data->setText(qtext);
+       qApp->clipboard()->setMimeData(data, QClipboard::Clipboard);
+}
+
 
-       qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
-                                  QClipboard::Clipboard);
+bool GuiClipboard::hasLyXContents() const
+{
+       QMimeData const * const source =
+               qApp->clipboard()->mimeData(QClipboard::Clipboard);
+       return source && source->hasFormat(mime_type);
 }