mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Issue #24: Text selection and table selection bug
This commit is contained in:
@ -314,7 +314,7 @@ bool PDFTextLayout::isHoveringOverTextBlock(const QPointF& point) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor)
|
PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor, bool strictSelection)
|
||||||
{
|
{
|
||||||
PDFTextSelection selection;
|
PDFTextSelection selection;
|
||||||
|
|
||||||
@ -374,12 +374,12 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const
|
|||||||
QRectF boundingBoxPathBBRect = boundingBoxPath.controlPointRect();
|
QRectF boundingBoxPathBBRect = boundingBoxPath.controlPointRect();
|
||||||
|
|
||||||
// If start point is above the text block, move start point to the left.
|
// If start point is above the text block, move start point to the left.
|
||||||
if (boundingBoxPathBBRect.bottom() < pointA.y())
|
if (!strictSelection && boundingBoxPathBBRect.bottom() < pointA.y())
|
||||||
{
|
{
|
||||||
pointA.setX(boundingBoxPathBBRect.left());
|
pointA.setX(boundingBoxPathBBRect.left());
|
||||||
isTopPointAboveText = true;
|
isTopPointAboveText = true;
|
||||||
}
|
}
|
||||||
if (boundingBoxPathBBRect.top() > pointB.y())
|
if (!strictSelection && boundingBoxPathBBRect.top() > pointB.y())
|
||||||
{
|
{
|
||||||
pointB.setX(boundingBoxPathBBRect.right());
|
pointB.setX(boundingBoxPathBBRect.right());
|
||||||
isBottomPointBelowText = true;
|
isBottomPointBelowText = true;
|
||||||
@ -399,6 +399,16 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const
|
|||||||
for (size_t lineId = 0, linesCount = lines.size(); lineId < linesCount; ++lineId)
|
for (size_t lineId = 0, linesCount = lines.size(); lineId < linesCount; ++lineId)
|
||||||
{
|
{
|
||||||
const PDFTextLine& line = lines[lineId];
|
const PDFTextLine& line = lines[lineId];
|
||||||
|
QRectF lineBoundingRect = line.getBoundingBox().boundingRect();
|
||||||
|
|
||||||
|
// We skip lines, which are not in the range (pointB.y(), pointA.y),
|
||||||
|
// i.e. are above or below.
|
||||||
|
if (lineBoundingRect.bottom() < pointB.y() ||
|
||||||
|
lineBoundingRect.top() > pointA.y())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const TextCharacters& characters = line.getCharacters();
|
const TextCharacters& characters = line.getCharacters();
|
||||||
for (size_t characterId = 0, characterCount = characters.size(); characterId < characterCount; ++characterId)
|
for (size_t characterId = 0, characterCount = characters.size(); characterId < characterCount; ++characterId)
|
||||||
{
|
{
|
||||||
|
@ -368,7 +368,12 @@ public:
|
|||||||
/// \param point1 First point
|
/// \param point1 First point
|
||||||
/// \param point2 Second point
|
/// \param point2 Second point
|
||||||
/// \param selectionColor Selection color
|
/// \param selectionColor Selection color
|
||||||
PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor = Qt::yellow);
|
/// \param strictSelection If true, does not adjust horizontal range when above/below text block
|
||||||
|
PDFTextSelection createTextSelection(PDFInteger pageIndex,
|
||||||
|
const QPointF& point1,
|
||||||
|
const QPointF& point2,
|
||||||
|
QColor selectionColor = Qt::yellow,
|
||||||
|
bool strictSelection = false);
|
||||||
|
|
||||||
/// Returns string from text selection
|
/// Returns string from text selection
|
||||||
/// \param itBegin Iterator (begin range)
|
/// \param itBegin Iterator (begin range)
|
||||||
|
@ -1567,46 +1567,15 @@ void PDFSelectTableTool::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
|||||||
cell.row = rowIndex;
|
cell.row = rowIndex;
|
||||||
cell.column = columnIndex;
|
cell.column = columnIndex;
|
||||||
cell.rectangle = QRectF(left, top, width, height);
|
cell.rectangle = QRectF(left, top, width, height);
|
||||||
|
|
||||||
|
PDFTextSelection textSelection = m_textLayout.createTextSelection(m_pageIndex, cell.rectangle.topLeft(), cell.rectangle.bottomRight(), Qt::yellow, true);
|
||||||
|
cell.text = m_textLayout.getTextFromSelection(textSelection, m_pageIndex).trimmed();
|
||||||
|
cell.text = cell.text.remove(QChar('\n'));
|
||||||
|
|
||||||
tableCells.push_back(cell);
|
tableCells.push_back(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PDFTextBlocks& textBlocks = m_textLayout.getTextBlocks();
|
|
||||||
for (size_t i = 0; i < textBlocks.size(); ++i)
|
|
||||||
{
|
|
||||||
// Detect, if whole block can be in some text cell
|
|
||||||
const PDFTextBlock& textBlock = textBlocks[i];
|
|
||||||
QRectF textRect = textBlock.getBoundingBox().boundingRect();
|
|
||||||
auto itBlockCell = std::find_if(tableCells.begin(), tableCells.end(), [textRect](const auto& cell) { return cell.rectangle.contains(textRect); });
|
|
||||||
if (itBlockCell != tableCells.end())
|
|
||||||
{
|
|
||||||
// Jakub Melka: whole block is contained in the cell
|
|
||||||
PDFTextSelection blockSelection = m_textLayout.selectBlock(i, m_pageIndex, QColor());
|
|
||||||
QString text = m_textLayout.getTextFromSelection(blockSelection, m_pageIndex);
|
|
||||||
TableCell& cell = *itBlockCell;
|
|
||||||
cell.text = QString("%1 %2").arg(cell.text, text).trimmed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PDFTextLines& textLines = textBlock.getLines();
|
|
||||||
for (size_t j = 0; j < textLines.size(); ++j)
|
|
||||||
{
|
|
||||||
const PDFTextLine& textLine = textLines[j];
|
|
||||||
QRectF boundingRect = textLine.getBoundingBox().boundingRect();
|
|
||||||
|
|
||||||
auto itLineCell = std::find_if(tableCells.begin(), tableCells.end(), [boundingRect](const auto& cell) { return cell.rectangle.contains(boundingRect); });
|
|
||||||
if (itLineCell != tableCells.end())
|
|
||||||
{
|
|
||||||
// Jakub Melka: whole block is contained in the cell
|
|
||||||
PDFTextSelection blockSelection = m_textLayout.selectLineInBlock(i, j, m_pageIndex, QColor());
|
|
||||||
QString text = m_textLayout.getTextFromSelection(blockSelection, m_pageIndex);
|
|
||||||
TableCell& cell = *itLineCell;
|
|
||||||
cell.text = QString("%1 %2").arg(cell.text, text).trimmed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_isTransposed)
|
if (m_isTransposed)
|
||||||
{
|
{
|
||||||
auto comparator = [](const TableCell& left, const TableCell right)
|
auto comparator = [](const TableCell& left, const TableCell right)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
CURRENT:
|
CURRENT:
|
||||||
- Issue #21: Table selection tool
|
- Issue #21: Table selection tool
|
||||||
- Issue #22: Solve compilation warnings
|
- Issue #22: Solve compilation warnings
|
||||||
|
- Issue #24: Text selection and table selection algorithm improvement
|
||||||
|
|
||||||
V: 1.2.1 30.6.2022
|
V: 1.2.1 30.6.2022
|
||||||
- Issue #17: Public key security handler
|
- Issue #17: Public key security handler
|
||||||
|
Reference in New Issue
Block a user