mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-04-14 18:32:42 +02:00
Copying text to clipboard
This commit is contained in:
parent
12b2f44619
commit
0bc64494fd
@ -483,6 +483,33 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const
|
|||||||
return selection;
|
return selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PDFTextLayout::getTextFromSelection(PDFTextSelection::iterator itBegin, PDFTextSelection::iterator itEnd, PDFInteger pageIndex) const
|
||||||
|
{
|
||||||
|
QStringList text;
|
||||||
|
|
||||||
|
if (itBegin != itEnd)
|
||||||
|
{
|
||||||
|
PDFTextFlows flows = PDFTextFlow::createTextFlows(*this, PDFTextFlow::RemoveSoftHyphen, pageIndex);
|
||||||
|
Q_ASSERT(flows.size() < 2);
|
||||||
|
|
||||||
|
if (!flows.empty())
|
||||||
|
{
|
||||||
|
const PDFTextFlow& textFlow = flows.front();
|
||||||
|
for (auto it = itBegin; it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
text << textFlow.getText(it->start, it->end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PDFTextLayout::getTextFromSelection(const PDFTextSelection& selection, PDFInteger pageIndex) const
|
||||||
|
{
|
||||||
|
return getTextFromSelection(selection.begin(pageIndex), selection.end(pageIndex), pageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream& operator>>(QDataStream& stream, PDFTextLayout& layout)
|
QDataStream& operator>>(QDataStream& stream, PDFTextLayout& layout)
|
||||||
{
|
{
|
||||||
stream >> layout.m_characters;
|
stream >> layout.m_characters;
|
||||||
@ -1083,6 +1110,17 @@ PDFTextSelection::iterator PDFTextSelection::end(PDFInteger pageIndex) const
|
|||||||
return std::upper_bound(m_items.cbegin(), m_items.end(), item);
|
return std::upper_bound(m_items.cbegin(), m_items.end(), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFTextSelection::iterator PDFTextSelection::nextPageRange(iterator currentPageRange) const
|
||||||
|
{
|
||||||
|
auto it = currentPageRange;
|
||||||
|
while (it != m_items.cend() && it->start.pageIndex == currentPageRange->start.pageIndex)
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
PDFFindResults PDFTextFlow::find(const QString& text, Qt::CaseSensitivity caseSensitivity) const
|
PDFFindResults PDFTextFlow::find(const QString& text, Qt::CaseSensitivity caseSensitivity) const
|
||||||
{
|
{
|
||||||
PDFFindResults results;
|
PDFFindResults results;
|
||||||
@ -1133,6 +1171,21 @@ PDFFindResults PDFTextFlow::find(const QRegularExpression& expression) const
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PDFTextFlow::getText(const PDFCharacterPointer& begin, const PDFCharacterPointer& end) const
|
||||||
|
{
|
||||||
|
auto it = std::find(m_characterPointers.cbegin(), m_characterPointers.cend(), begin);
|
||||||
|
auto itEnd = std::find(m_characterPointers.cbegin(), m_characterPointers.cend(), end);
|
||||||
|
|
||||||
|
const std::size_t startIndex = std::distance(m_characterPointers.cbegin(), it);
|
||||||
|
const std::size_t endIndex = std::distance(m_characterPointers.cbegin(), itEnd);
|
||||||
|
if (startIndex <= endIndex)
|
||||||
|
{
|
||||||
|
return m_text.mid(int(startIndex), int(endIndex - startIndex + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
void PDFTextFlow::merge(const PDFTextFlow& next)
|
void PDFTextFlow::merge(const PDFTextFlow& next)
|
||||||
{
|
{
|
||||||
m_text += next.m_text;
|
m_text += next.m_text;
|
||||||
|
@ -238,9 +238,15 @@ public:
|
|||||||
/// Returns iterator to end of page range
|
/// Returns iterator to end of page range
|
||||||
iterator end(PDFInteger pageIndex) const;
|
iterator end(PDFInteger pageIndex) const;
|
||||||
|
|
||||||
|
/// Returns iterator to next page range
|
||||||
|
iterator nextPageRange(iterator currentPageRange) const;
|
||||||
|
|
||||||
/// Returns true, if text selection is empty
|
/// Returns true, if text selection is empty
|
||||||
bool isEmpty() const { return m_items.empty(); }
|
bool isEmpty() const { return m_items.empty(); }
|
||||||
|
|
||||||
|
iterator begin() const { return m_items.cbegin(); }
|
||||||
|
iterator end() const { return m_items.cend(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFTextSelectionColoredItems m_items;
|
PDFTextSelectionColoredItems m_items;
|
||||||
};
|
};
|
||||||
@ -288,6 +294,11 @@ public:
|
|||||||
/// \param expression Regular expression to be matched
|
/// \param expression Regular expression to be matched
|
||||||
PDFFindResults find(const QRegularExpression& expression) const;
|
PDFFindResults find(const QRegularExpression& expression) const;
|
||||||
|
|
||||||
|
/// Returns text form character pointers
|
||||||
|
/// \param begin Begin character
|
||||||
|
/// \param end End character
|
||||||
|
QString getText(const PDFCharacterPointer& begin, const PDFCharacterPointer& end) const;
|
||||||
|
|
||||||
/// Merge data from \p next flow (i.e. connect two consecutive flows)
|
/// Merge data from \p next flow (i.e. connect two consecutive flows)
|
||||||
void merge(const PDFTextFlow& next);
|
void merge(const PDFTextFlow& next);
|
||||||
|
|
||||||
@ -347,6 +358,17 @@ public:
|
|||||||
/// \param point2 Second point
|
/// \param point2 Second point
|
||||||
PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2);
|
PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2);
|
||||||
|
|
||||||
|
/// Returns string from text selection
|
||||||
|
/// \param itBegin Iterator (begin range)
|
||||||
|
/// \param itEnd Iterator (end range)
|
||||||
|
/// \param pageIndex Index of the page
|
||||||
|
QString getTextFromSelection(PDFTextSelection::iterator itBegin, PDFTextSelection::iterator itEnd, PDFInteger pageIndex) const;
|
||||||
|
|
||||||
|
/// Returns string from text selection
|
||||||
|
/// \param selection Text selection
|
||||||
|
/// \param pageIndex Index of the page
|
||||||
|
QString getTextFromSelection(const PDFTextSelection& selection, PDFInteger pageIndex) const;
|
||||||
|
|
||||||
friend QDataStream& operator<<(QDataStream& stream, const PDFTextLayout& layout);
|
friend QDataStream& operator<<(QDataStream& stream, const PDFTextLayout& layout);
|
||||||
friend QDataStream& operator>>(QDataStream& stream, PDFTextLayout& layout);
|
friend QDataStream& operator>>(QDataStream& stream, PDFTextLayout& layout);
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -602,7 +604,32 @@ void PDFSelectTextTool::updateCursor()
|
|||||||
|
|
||||||
void PDFSelectTextTool::onActionCopyText()
|
void PDFSelectTextTool::onActionCopyText()
|
||||||
{
|
{
|
||||||
|
if (isActive())
|
||||||
|
{
|
||||||
|
// Jakub Melka: we must obey document permissions
|
||||||
|
if (getDocument()->getStorage().getSecurityHandler()->isAllowed(PDFSecurityHandler::Permission::CopyContent))
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
auto it = m_textSelection.begin();
|
||||||
|
auto itEnd = m_textSelection.nextPageRange(it);
|
||||||
|
while (it != m_textSelection.end())
|
||||||
|
{
|
||||||
|
const PDFInteger pageIndex = it->start.pageIndex;
|
||||||
|
PDFTextLayout textLayout = getProxy()->getTextLayoutCompiler()->getTextLayoutLazy(pageIndex);
|
||||||
|
result << textLayout.getTextFromSelection(it, itEnd, pageIndex);
|
||||||
|
|
||||||
|
it = itEnd;
|
||||||
|
itEnd = m_textSelection.nextPageRange(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text = result.join("\n\n");
|
||||||
|
if (!text.isEmpty())
|
||||||
|
{
|
||||||
|
QApplication::clipboard()->setText(text, QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFSelectTextTool::onActionSelectAll()
|
void PDFSelectTextTool::onActionSelectAll()
|
||||||
|
@ -102,6 +102,7 @@ protected:
|
|||||||
virtual void setActiveImpl(bool active);
|
virtual void setActiveImpl(bool active);
|
||||||
virtual void updateActions();
|
virtual void updateActions();
|
||||||
|
|
||||||
|
const PDFDocument* getDocument() const { return m_document; }
|
||||||
PDFDrawWidgetProxy* getProxy() const { return m_proxy; }
|
PDFDrawWidgetProxy* getProxy() const { return m_proxy; }
|
||||||
|
|
||||||
inline void setCursor(QCursor cursor) { m_cursor = qMove(cursor); }
|
inline void setCursor(QCursor cursor) { m_cursor = qMove(cursor); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user