From 181b086f99803fd0003b9e6ce8ef58f3ae45a462 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= <thorbjorn.lindeijer@nokia.com>
Date: Fri, 5 Mar 2010 11:50:37 +0100
Subject: [PATCH] Added syntax highlighted code to clipboard as HTML when
 copying

The generated HTML is not the prettiest HTML in the universe, but it
does the job. When copying code from Qt Creator to Microsoft Office or
OpenOffice.org, the syntax highlighting is now preserved. The code also
pastes as preformatted text.

Reviewed-by: mae
Task-number: QTCREATORBUG-727
---
 dist/changes-2.0.0                        |  2 +
 src/plugins/texteditor/basetexteditor.cpp | 47 ++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/dist/changes-2.0.0 b/dist/changes-2.0.0
index e49cf5c2025..2bcc710c068 100644
--- a/dist/changes-2.0.0
+++ b/dist/changes-2.0.0
@@ -30,6 +30,8 @@ Editing
    * Open with "System Editor"
    * Fixed missing semicolon after } when creating unnamed enumeration
    * Fixed auto indent for C style coments
+   * Copying text from the editor now supports HTML mime type, preserving
+     the syntax highlighting.
 
 C++ Support
    * Recognize *.cu as C files
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 5f23328526c..7bcca16b848 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -69,6 +69,7 @@
 #include <QtGui/QStyle>
 #include <QtGui/QSyntaxHighlighter>
 #include <QtGui/QTextCursor>
+#include <QtGui/QTextDocumentFragment>
 #include <QtGui/QTextBlock>
 #include <QtGui/QTextLayout>
 #include <QtGui/QToolBar>
@@ -5327,13 +5328,57 @@ QMimeData *BaseTextEditor::createMimeDataFromSelection() const
         mimeData->setData(QLatin1String("application/vnd.nokia.qtcreator.vblocktext"), text.toUtf8());
         mimeData->setText(text); // for exchangeability
         return mimeData;
-    } else if (textCursor().hasSelection()){
+    } else if (textCursor().hasSelection()) {
         QTextCursor cursor = textCursor();
         QMimeData *mimeData = new QMimeData;
+
+        // Copy the selected text as plain text
         QString text = cursor.selectedText();
         convertToPlainText(text);
         mimeData->setText(text);
 
+        // Copy the selected text as HTML
+        {
+            // Create a new document from the selected text document fragment
+            QTextDocument *tempDocument = new QTextDocument;
+            QTextCursor tempCursor(tempDocument);
+            tempCursor.insertFragment(cursor.selection());
+
+            // Apply the additional formats set by the syntax highlighter
+            QTextBlock start = document()->findBlock(cursor.selectionStart());
+            QTextBlock end = document()->findBlock(cursor.selectionEnd());
+            end = end.next();
+
+            const int selectionStart = cursor.selectionStart();
+            const int endOfDocument = tempDocument->characterCount() - 1;
+            for (QTextBlock current = start; current.isValid() && current != end; current = current.next()) {
+                const QTextLayout *layout = current.layout();
+                foreach (const QTextLayout::FormatRange &range, layout->additionalFormats()) {
+                    const int start = current.position() + range.start - selectionStart;
+                    const int end = start + range.length;
+                    if (end <= 0 || start >= endOfDocument)
+                        continue;
+                    tempCursor.setPosition(qMax(start, 0));
+                    tempCursor.setPosition(qMin(end, endOfDocument), QTextCursor::KeepAnchor);
+                    tempCursor.setCharFormat(range.format);
+                }
+            }
+
+            // Reset the user states since they are not interesting
+            for (QTextBlock block = tempDocument->begin(); block.isValid(); block = block.next())
+                block.setUserState(-1);
+
+            // Make sure the text appears pre-formatted
+            tempCursor.setPosition(0);
+            tempCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+            QTextBlockFormat blockFormat = tempCursor.blockFormat();
+            blockFormat.setNonBreakableLines(true);
+            tempCursor.setBlockFormat(blockFormat);
+
+            mimeData->setHtml(tempCursor.selection().toHtml());
+            delete tempDocument;
+        }
+
         /*
           Try to figure out whether we are copying an entire block, and store the complete block
           including indentation in the qtcreator.blocktext mimetype.
-- 
GitLab