File indexing completed on 2024-04-14 03:55:09

0001 /*
0002     SPDX-FileCopyrightText: 2009 Milian Wolff <mail@milianw.de>
0003     SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
0004     SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org>
0005     SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org>
0006     SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #include "exporter.h"
0012 #include "abstractexporter.h"
0013 #include "htmlexporter.h"
0014 
0015 #include <ktexteditor/document.h>
0016 #include <ktexteditor/view.h>
0017 
0018 #include <KLocalizedString>
0019 
0020 #include <QApplication>
0021 #include <QClipboard>
0022 #include <QFileDialog>
0023 #include <QMimeData>
0024 
0025 void KateExporter::exportToClipboard()
0026 {
0027     if (!m_view->selection()) {
0028         return;
0029     }
0030 
0031     QMimeData *data = new QMimeData();
0032 
0033     QString s;
0034     QTextStream output(&s, QIODevice::WriteOnly);
0035     exportData(true, output);
0036 
0037     data->setHtml(s);
0038     data->setText(s);
0039 
0040     QApplication::clipboard()->setMimeData(data);
0041 }
0042 
0043 void KateExporter::exportToFile(const QString &file)
0044 {
0045     QFile savefile(file);
0046     if (!savefile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
0047         return;
0048     }
0049 
0050     QTextStream outputStream(&savefile);
0051     exportData(false, outputStream);
0052 }
0053 
0054 void KateExporter::exportData(const bool useSelection, QTextStream &output)
0055 {
0056     const KTextEditor::Range range = useSelection ? m_view->selectionRange() : m_view->document()->documentRange();
0057     const bool blockwise = useSelection ? m_view->blockSelection() : false;
0058 
0059     if ((blockwise || range.onSingleLine()) && (range.start().column() > range.end().column())) {
0060         return;
0061     }
0062 
0063     /// TODO: add more exporters
0064     std::unique_ptr<AbstractExporter> exporter = std::make_unique<HTMLExporter>(m_view, output, !useSelection);
0065 
0066     const KTextEditor::Attribute::Ptr noAttrib(nullptr);
0067 
0068     for (int i = range.start().line(); (i <= range.end().line()) && (i < m_view->document()->lines()); ++i) {
0069         const QString &line = m_view->document()->line(i);
0070 
0071         const QList<KTextEditor::AttributeBlock> attribs = m_view->lineAttributes(i);
0072 
0073         int lineStart = 0;
0074         int remainingChars = line.length();
0075         if (blockwise || range.onSingleLine()) {
0076             lineStart = range.start().column();
0077             remainingChars = range.columnWidth();
0078         } else if (i == range.start().line()) {
0079             lineStart = range.start().column();
0080         } else if (i == range.end().line()) {
0081             remainingChars = range.end().column();
0082         }
0083 
0084         int handledUntil = lineStart;
0085 
0086         for (const KTextEditor::AttributeBlock &block : attribs) {
0087             // honor (block-) selections
0088             if (block.start + block.length <= lineStart) {
0089                 continue;
0090             } else if (block.start >= lineStart + remainingChars) {
0091                 break;
0092             }
0093             int start = qMax(block.start, lineStart);
0094             if (start > handledUntil) {
0095                 exporter->exportText(line.mid(handledUntil, start - handledUntil), noAttrib);
0096             }
0097             int length = qMin(block.length, remainingChars);
0098             exporter->exportText(line.mid(start, length), block.attribute);
0099             handledUntil = start + length;
0100         }
0101 
0102         if (handledUntil < lineStart + remainingChars) {
0103             exporter->exportText(line.mid(handledUntil, remainingChars), noAttrib);
0104         }
0105 
0106         exporter->closeLine(i == range.end().line());
0107     }
0108 
0109     output.flush();
0110 }