mirror of https://github.com/JakubMelka/PDF4QT.git
Finishing editation of text field - also 'Comb' functionality
This commit is contained in:
parent
691eaff6db
commit
713a7079f8
|
@ -1122,6 +1122,7 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||
parameters.annotation = annotation.annotation.data();
|
||||
parameters.formManager = m_formManager;
|
||||
parameters.key = std::make_pair(annotation.appearance, annotation.annotation->getAppearanceState());
|
||||
parameters.invertColors = m_features.testFlag(PDFRenderer::InvertColors);
|
||||
annotation.annotation->draw(parameters);
|
||||
|
||||
if (parameters.boundingRectangle.isValid())
|
||||
|
@ -1394,15 +1395,19 @@ void PDFWidgetAnnotationManager::keyReleaseEvent(QWidget* widget, QKeyEvent* eve
|
|||
void PDFWidgetAnnotationManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
|
||||
updateFromMouseEvent(event);
|
||||
}
|
||||
|
||||
void PDFWidgetAnnotationManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void PDFWidgetAnnotationManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
|
||||
updateFromMouseEvent(event);
|
||||
}
|
||||
|
@ -1410,7 +1415,6 @@ void PDFWidgetAnnotationManager::mouseReleaseEvent(QWidget* widget, QMouseEvent*
|
|||
void PDFWidgetAnnotationManager::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
|
||||
updateFromMouseEvent(event);
|
||||
}
|
||||
|
|
|
@ -458,6 +458,9 @@ struct AnnotationDrawParameters
|
|||
|
||||
/// Appeareance mode (normal/rollover/down, and appearance state)
|
||||
PDFAppeareanceStreams::Key key;
|
||||
|
||||
/// Invert colors?
|
||||
bool invertColors = false;
|
||||
};
|
||||
|
||||
/// Base class for all annotation types. Represents PDF annotation object.
|
||||
|
@ -1424,6 +1427,7 @@ public:
|
|||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void wheelEvent(QWidget* widget, QWheelEvent* event) override;
|
||||
|
|
|
@ -95,6 +95,11 @@ public:
|
|||
/// \param event Event
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) = 0;
|
||||
|
||||
/// Handles mouse double click event from widget
|
||||
/// \param widget Widget
|
||||
/// \param event Event
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) = 0;
|
||||
|
||||
/// Handles mouse release event from widget
|
||||
/// \param widget Widget
|
||||
/// \param event Event
|
||||
|
|
|
@ -384,6 +384,17 @@ void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
|
|||
event->accept();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
if (processEvent<QMouseEvent, &IDrawWidgetInputInterface::mouseDoubleClickEvent>(event))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
|
|
|
@ -142,6 +142,7 @@ protected:
|
|||
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||
virtual void keyReleaseEvent(QKeyEvent* event) override;
|
||||
virtual void mousePressEvent(QMouseEvent* event) override;
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
||||
virtual void wheelEvent(QWheelEvent* event) override;
|
||||
|
|
|
@ -866,7 +866,7 @@ void PDFFormManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|||
setFocusToEditor(info.editor);
|
||||
}
|
||||
|
||||
info.editor->mousePressEvent(widget, event);
|
||||
info.editor->mousePressEvent(widget, event, info.mousePosition);
|
||||
grabMouse(info, event);
|
||||
}
|
||||
else if (!isMouseGrabbed())
|
||||
|
@ -876,6 +876,30 @@ void PDFFormManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void PDFFormManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
if (!hasForm())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MouseEventInfo info = getMouseEventInfo(widget, event->pos());
|
||||
if (info.isValid())
|
||||
{
|
||||
Q_ASSERT(info.editor);
|
||||
info.editor->mouseDoubleClickEvent(widget, event, info.mousePosition);
|
||||
|
||||
// If mouse is grabbed, then event is accepted always (because
|
||||
// we get Press event, when we grabbed the mouse, then we will
|
||||
// wait for corresponding release event while all mouse move events
|
||||
// will be accepted, even if editor doesn't accept them.
|
||||
if (isMouseGrabbed())
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
if (!hasForm())
|
||||
|
@ -887,7 +911,7 @@ void PDFFormManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
|||
if (info.isValid())
|
||||
{
|
||||
Q_ASSERT(info.editor);
|
||||
info.editor->mouseReleaseEvent(widget, event);
|
||||
info.editor->mouseReleaseEvent(widget, event, info.mousePosition);
|
||||
ungrabMouse(info, event);
|
||||
}
|
||||
}
|
||||
|
@ -903,7 +927,7 @@ void PDFFormManager::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
|||
if (info.isValid())
|
||||
{
|
||||
Q_ASSERT(info.editor);
|
||||
info.editor->mouseMoveEvent(widget, event);
|
||||
info.editor->mouseMoveEvent(widget, event, info.mousePosition);
|
||||
|
||||
// If mouse is grabbed, then event is accepted always (because
|
||||
// we get Press event, when we grabbed the mouse, then we will
|
||||
|
@ -1172,22 +1196,32 @@ void PDFFormFieldWidgetEditor::keyReleaseEvent(QWidget* widget, QKeyEvent* event
|
|||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void PDFFormFieldWidgetEditor::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
||||
void PDFFormFieldWidgetEditor::mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(mousePagePosition);
|
||||
}
|
||||
|
||||
void PDFFormFieldWidgetEditor::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||
void PDFFormFieldWidgetEditor::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(mousePagePosition);
|
||||
}
|
||||
|
||||
void PDFFormFieldWidgetEditor::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
||||
void PDFFormFieldWidgetEditor::mouseReleaseEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(mousePagePosition);
|
||||
}
|
||||
|
||||
void PDFFormFieldWidgetEditor::mouseMoveEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(mousePagePosition);
|
||||
}
|
||||
|
||||
void PDFFormFieldWidgetEditor::setFocus(bool hasFocus)
|
||||
|
@ -1281,6 +1315,28 @@ PDFFormFieldAbstractButtonEditor::PDFFormFieldAbstractButtonEditor(PDFFormManage
|
|||
|
||||
}
|
||||
|
||||
void PDFFormFieldAbstractButtonEditor::shortcutOverrideEvent(QWidget* widget, QKeyEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_Down:
|
||||
{
|
||||
event->accept();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldAbstractButtonEditor::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
||||
{
|
||||
switch (event->key())
|
||||
|
@ -1326,9 +1382,10 @@ void PDFFormFieldAbstractButtonEditor::keyReleaseEvent(QWidget* widget, QKeyEven
|
|||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldAbstractButtonEditor::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
||||
void PDFFormFieldAbstractButtonEditor::mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(mousePagePosition);
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
|
@ -1464,6 +1521,46 @@ void PDFFormFieldTextBoxEditor::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldTextBoxEditor::mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
const int cursorPosition = m_textEdit.getCursorPositionFromWidgetPosition(mousePagePosition, m_hasFocus);
|
||||
m_textEdit.setCursorPosition(cursorPosition, event->modifiers() & Qt::ShiftModifier);
|
||||
|
||||
event->accept();
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldTextBoxEditor::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
const int cursorPosition = m_textEdit.getCursorPositionFromWidgetPosition(mousePagePosition, m_hasFocus);
|
||||
m_textEdit.setCursorPosition(cursorPosition, false);
|
||||
m_textEdit.setCursorPosition(m_textEdit.getCursorWordBackward(), false);
|
||||
m_textEdit.setCursorPosition(m_textEdit.getCursorWordForward(), true);
|
||||
|
||||
event->accept();
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldTextBoxEditor::mouseMoveEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
// We must test, if left mouse button is pressed while
|
||||
// we are moving the mouse - if yes, then select the text.
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
const int cursorPosition = m_textEdit.getCursorPositionFromWidgetPosition(mousePagePosition, m_hasFocus);
|
||||
m_textEdit.setCursorPosition(cursorPosition, true);
|
||||
|
||||
event->accept();
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldTextBoxEditor::draw(AnnotationDrawParameters& parameters) const
|
||||
{
|
||||
m_textEdit.draw(parameters, true);
|
||||
|
@ -1515,6 +1612,19 @@ void PDFTextEditPseudowidget::shortcutOverrideEvent(QWidget* widget, QKeyEvent*
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!event->text().isEmpty())
|
||||
{
|
||||
event->accept();
|
||||
for (const QChar& character : event->text())
|
||||
{
|
||||
if (!character.isPrint())
|
||||
{
|
||||
event->ignore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTextEditPseudowidget::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
||||
|
@ -1836,6 +1946,7 @@ void PDFTextEditPseudowidget::setAppearance(const PDFAnnotationDefaultAppearance
|
|||
QFont font(appearance.getFontName());
|
||||
font.setHintingPreference(QFont::PreferNoHinting);
|
||||
font.setPixelSize(qCeil(fontSize));
|
||||
font.setStyleStrategy(QFont::ForceOutline);
|
||||
m_textLayout.setFont(font);
|
||||
|
||||
QTextOption option = m_textLayout.textOption();
|
||||
|
@ -1956,56 +2067,232 @@ void PDFTextEditPseudowidget::performInsertText(const QString& text)
|
|||
updateTextLayout();
|
||||
}
|
||||
|
||||
QMatrix PDFTextEditPseudowidget::createTextBoxTransformMatrix(bool edit) const
|
||||
{
|
||||
QMatrix matrix;
|
||||
|
||||
matrix.translate(m_widgetRect.left(), m_widgetRect.bottom());
|
||||
matrix.scale(1.0, -1.0);
|
||||
|
||||
if (edit && !isComb() && m_textLayout.isValidCursorPosition(m_positionCursor))
|
||||
{
|
||||
// Jakub Melka: we must scroll the control, so cursor is always
|
||||
// visible in the widget area. If we are not editing, this not the
|
||||
// case, because we always show the text from the beginning.
|
||||
|
||||
const QTextLine line = m_textLayout.lineForTextPosition(m_positionCursor);
|
||||
if (line.isValid())
|
||||
{
|
||||
const qreal xCursorPosition = line.cursorToX(m_positionCursor);
|
||||
if (xCursorPosition >= m_widgetRect.width())
|
||||
{
|
||||
const qreal delta = xCursorPosition - m_widgetRect.width();
|
||||
matrix.translate(-delta, 0.0);
|
||||
}
|
||||
|
||||
// Check, if we aren't outside of y position
|
||||
const qreal lineSpacing = line.leadingIncluded() ? line.height() : line.leading() + line.height();
|
||||
const qreal lineBottom = lineSpacing * (line.lineNumber() + 1);
|
||||
|
||||
if (lineBottom >= m_widgetRect.height())
|
||||
{
|
||||
const qreal delta = lineBottom - m_widgetRect.height();
|
||||
matrix.translate(0.0, -delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<int> PDFTextEditPseudowidget::getCursorPositions() const
|
||||
{
|
||||
std::vector<int> result;
|
||||
result.reserve(m_editText.length());
|
||||
result.push_back(0);
|
||||
|
||||
int currentPos = 0;
|
||||
while (currentPos < m_editText.length())
|
||||
{
|
||||
currentPos = m_textLayout.nextCursorPosition(currentPos, QTextLayout::SkipCharacters);
|
||||
result.push_back(currentPos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PDFTextEditPseudowidget::draw(AnnotationDrawParameters& parameters, bool edit) const
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(parameters.painter);
|
||||
parameters.boundingRectangle = parameters.annotation->getRectangle();
|
||||
|
||||
QPainter* painter = parameters.painter;
|
||||
painter->translate(parameters.boundingRectangle.bottomLeft());
|
||||
painter->scale(1.0, -1.0);
|
||||
QPalette palette = QApplication::palette();
|
||||
|
||||
QVector<QTextLayout::FormatRange> selections;
|
||||
|
||||
QTextLayout::FormatRange defaultFormat;
|
||||
defaultFormat.start = getPositionStart();
|
||||
defaultFormat.length = getTextLength();
|
||||
defaultFormat.format.clearBackground();
|
||||
defaultFormat.format.setForeground(QBrush(m_textColor, Qt::SolidPattern));
|
||||
|
||||
// If we are editing, draw selections
|
||||
if (edit && isTextSelected())
|
||||
auto getAdjustedColor = [¶meters](QColor color)
|
||||
{
|
||||
QTextLayout::FormatRange before = defaultFormat;
|
||||
QTextLayout::FormatRange after = defaultFormat;
|
||||
if (parameters.invertColors)
|
||||
{
|
||||
return invertColor(color);
|
||||
}
|
||||
|
||||
before.start = getPositionStart();
|
||||
before.length = m_selectionStart;
|
||||
after.start = m_selectionEnd;
|
||||
after.length = getTextLength() - m_selectionEnd;
|
||||
return color;
|
||||
};
|
||||
|
||||
QPalette palette = QApplication::palette();
|
||||
QTextLayout::FormatRange selectedFormat = defaultFormat;
|
||||
selectedFormat.start = m_selectionStart;
|
||||
selectedFormat.length = getSelectionLength();
|
||||
selectedFormat.format.setForeground(palette.brush(QPalette::HighlightedText));
|
||||
selectedFormat.format.setBackground(palette.brush(QPalette::Highlight));
|
||||
QPainter* painter = parameters.painter;
|
||||
painter->setClipRect(parameters.boundingRectangle, Qt::IntersectClip);
|
||||
painter->setWorldMatrix(createTextBoxTransformMatrix(edit), true);
|
||||
painter->setPen(getAdjustedColor(Qt::black));
|
||||
|
||||
selections = { before, selectedFormat, after};
|
||||
if (isComb())
|
||||
{
|
||||
const qreal combCount = qMax(m_maxTextLength, 1);
|
||||
qreal combWidth = m_widgetRect.width() / combCount;
|
||||
QRectF combRect(0.0, 0.0, combWidth, m_widgetRect.height());
|
||||
painter->setFont(m_textLayout.font());
|
||||
|
||||
QColor textColor = getAdjustedColor(palette.color(QPalette::Text));
|
||||
QColor highlightTextColor = getAdjustedColor(palette.color(QPalette::HighlightedText));
|
||||
QColor highlightColor = getAdjustedColor(palette.color(QPalette::Highlight));
|
||||
|
||||
std::vector<int> positions = getCursorPositions();
|
||||
for (size_t i = 1; i < positions.size(); ++i)
|
||||
{
|
||||
if (positions[i - 1] >= m_selectionStart && positions[i] - 1 < m_selectionEnd)
|
||||
{
|
||||
// We are in text selection
|
||||
painter->fillRect(combRect, highlightColor);
|
||||
painter->setPen(highlightTextColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not in text selection
|
||||
painter->setPen(textColor);
|
||||
}
|
||||
|
||||
int length = positions[i] - positions[i - 1];
|
||||
QString text = m_displayText.mid(positions[i - 1], length);
|
||||
painter->drawText(combRect, Qt::AlignCenter, text);
|
||||
|
||||
// Draw the cursor?
|
||||
if (edit && m_positionCursor >= positions[i - 1] && m_positionCursor < positions[i])
|
||||
{
|
||||
QRectF cursorRect(combRect.left(), combRect.bottom() - 1, combRect.width(), 1);
|
||||
painter->fillRect(cursorRect, textColor);
|
||||
}
|
||||
|
||||
combRect.translate(combWidth, 0.0);
|
||||
}
|
||||
|
||||
// Draw the cursor onto next unfilled cell?
|
||||
if (edit && m_positionCursor == getPositionEnd())
|
||||
{
|
||||
QRectF cursorRect(combRect.left(), combRect.bottom() - 1, combRect.width(), 1);
|
||||
painter->fillRect(cursorRect, textColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selections.push_back(defaultFormat);
|
||||
QVector<QTextLayout::FormatRange> selections;
|
||||
|
||||
QTextLayout::FormatRange defaultFormat;
|
||||
defaultFormat.start = getPositionStart();
|
||||
defaultFormat.length = getTextLength();
|
||||
defaultFormat.format.clearBackground();
|
||||
defaultFormat.format.setForeground(QBrush(getAdjustedColor(m_textColor), Qt::SolidPattern));
|
||||
|
||||
// If we are editing, draw selections
|
||||
if (edit && isTextSelected())
|
||||
{
|
||||
QTextLayout::FormatRange before = defaultFormat;
|
||||
QTextLayout::FormatRange after = defaultFormat;
|
||||
|
||||
before.start = getPositionStart();
|
||||
before.length = m_selectionStart;
|
||||
after.start = m_selectionEnd;
|
||||
after.length = getTextLength() - m_selectionEnd;
|
||||
|
||||
QTextLayout::FormatRange selectedFormat = defaultFormat;
|
||||
selectedFormat.start = m_selectionStart;
|
||||
selectedFormat.length = getSelectionLength();
|
||||
selectedFormat.format.setForeground(QBrush(getAdjustedColor(palette.color(QPalette::HighlightedText)), Qt::SolidPattern));
|
||||
selectedFormat.format.setBackground(QBrush(getAdjustedColor(palette.color(QPalette::Highlight)), Qt::SolidPattern));
|
||||
|
||||
selections = { before, selectedFormat, after};
|
||||
}
|
||||
else
|
||||
{
|
||||
selections.push_back(defaultFormat);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
m_textLayout.draw(painter, QPointF(0.0, 0.0), selections, QRectF());
|
||||
|
||||
// If we are editing, also draw text
|
||||
if (edit)
|
||||
{
|
||||
m_textLayout.drawCursor(painter, QPointF(0.0, 0.0), m_positionCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw text
|
||||
m_textLayout.draw(painter, QPointF(0.0, 0.0), selections, QRectF(0, 0, parameters.boundingRectangle.width(), parameters.boundingRectangle.height()));
|
||||
int PDFTextEditPseudowidget::getCursorPositionFromWidgetPosition(const QPointF& point, bool edit) const
|
||||
{
|
||||
QMatrix textBoxSpaceToPageSpace = createTextBoxTransformMatrix(edit);
|
||||
QMatrix pageSpaceToTextBoxSpace = textBoxSpaceToPageSpace.inverted();
|
||||
|
||||
// If we are editing, also draw text
|
||||
if (edit)
|
||||
QPointF textBoxPoint = pageSpaceToTextBoxSpace.map(point);
|
||||
|
||||
if (isComb())
|
||||
{
|
||||
m_textLayout.drawCursor(painter, QPointF(0.0, 0.0), m_positionCursor);
|
||||
// If it is comb, then characters are spaced equidistantly
|
||||
const qreal x = qBound(0.0, textBoxPoint.x(), m_widgetRect.width());
|
||||
const size_t position = qFloor(x * qreal(m_maxTextLength) / qreal(m_widgetRect.width()));
|
||||
std::vector<int> positions = getCursorPositions();
|
||||
if (position < positions.size())
|
||||
{
|
||||
return positions[position];
|
||||
}
|
||||
|
||||
return positions.back();
|
||||
}
|
||||
else if (m_textLayout.lineCount() > 0)
|
||||
{
|
||||
QTextLine line;
|
||||
qreal yPos = 0.0;
|
||||
|
||||
// Find line under cursor
|
||||
for (int i = 0; i < m_textLayout.lineCount(); ++i)
|
||||
{
|
||||
QTextLine currentLine = m_textLayout.lineAt(i);
|
||||
const qreal lineSpacing = currentLine.leadingIncluded() ? currentLine.height() : currentLine.leading() + currentLine.height();
|
||||
const qreal yNextPos = yPos + lineSpacing;
|
||||
|
||||
if (textBoxPoint.y() >= yPos && textBoxPoint.y() < yNextPos)
|
||||
{
|
||||
line = currentLine;
|
||||
break;
|
||||
}
|
||||
|
||||
yPos = yNextPos;
|
||||
}
|
||||
|
||||
// If no line is found, select last line
|
||||
if (!line.isValid())
|
||||
{
|
||||
if (textBoxPoint.y() < 0.0)
|
||||
{
|
||||
line = m_textLayout.lineAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
line = m_textLayout.lineAt(m_textLayout.lineCount() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return line.xToCursor(textBoxPoint.x(), QTextLine::CursorBetweenCharacters);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDFTextEditPseudowidget::updateTextLayout()
|
||||
|
@ -2049,7 +2336,7 @@ void PDFTextEditPseudowidget::updateTextLayout()
|
|||
int length = 0;
|
||||
int currentPos = 0;
|
||||
|
||||
while (currentPos <= m_editText.length())
|
||||
while (currentPos < m_editText.length())
|
||||
{
|
||||
currentPos = m_textLayout.nextCursorPosition(currentPos, QTextLayout::SkipCharacters);
|
||||
++length;
|
||||
|
|
|
@ -517,6 +517,25 @@ public:
|
|||
/// \param parameters Parameters
|
||||
void draw(AnnotationDrawParameters& parameters, bool edit) const;
|
||||
|
||||
/// Returns valid cursor position retrieved from position in the widget.
|
||||
/// \param point Point in page coordinate space
|
||||
/// \param edit Are we using edit transformations?
|
||||
/// \returns Cursor position
|
||||
int getCursorPositionFromWidgetPosition(const QPointF& point, bool edit) const;
|
||||
|
||||
inline int getCursorForward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepForward(), mode); }
|
||||
inline int getCursorBackward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepBackward(), mode); }
|
||||
inline int getCursorCharacterForward() const { return getCursorForward(QTextLayout::SkipCharacters); }
|
||||
inline int getCursorCharacterBackward() const { return getCursorBackward(QTextLayout::SkipCharacters); }
|
||||
inline int getCursorWordForward() const { return getCursorForward(QTextLayout::SkipWords); }
|
||||
inline int getCursorWordBackward() const { return getCursorBackward(QTextLayout::SkipWords); }
|
||||
inline int getCursorDocumentStart() const { return (getSingleStepForward() > 0) ? getPositionStart() : getPositionEnd(); }
|
||||
inline int getCursorDocumentEnd() const { return (getSingleStepForward() > 0) ? getPositionEnd() : getPositionStart(); }
|
||||
inline int getCursorLineStart() const { return (getSingleStepForward() > 0) ? getCurrentLineTextStart() : getCurrentLineTextEnd(); }
|
||||
inline int getCursorLineEnd() const { return (getSingleStepForward() > 0) ? getCurrentLineTextEnd() : getCurrentLineTextStart(); }
|
||||
inline int getCursorNextLine() const { return getCurrentLineTextEnd(); }
|
||||
inline int getCursorPreviousLine() const { return getNextPrevCursorPosition(getCurrentLineTextStart(), -1, QTextLayout::SkipCharacters); }
|
||||
|
||||
private:
|
||||
/// This function does following things:
|
||||
/// 1) Clamps edit text to fit maximum length
|
||||
|
@ -551,18 +570,16 @@ private:
|
|||
/// Returns current line text end position
|
||||
int getCurrentLineTextEnd() const;
|
||||
|
||||
inline int getCursorForward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepForward(), mode); }
|
||||
inline int getCursorBackward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepBackward(), mode); }
|
||||
inline int getCursorCharacterForward() const { return getCursorForward(QTextLayout::SkipCharacters); }
|
||||
inline int getCursorCharacterBackward() const { return getCursorBackward(QTextLayout::SkipCharacters); }
|
||||
inline int getCursorWordForward() const { return getCursorForward(QTextLayout::SkipWords); }
|
||||
inline int getCursorWordBackward() const { return getCursorBackward(QTextLayout::SkipWords); }
|
||||
inline int getCursorDocumentStart() const { return (getSingleStepForward() > 0) ? getPositionStart() : getPositionEnd(); }
|
||||
inline int getCursorDocumentEnd() const { return (getSingleStepForward() > 0) ? getPositionEnd() : getPositionStart(); }
|
||||
inline int getCursorLineStart() const { return (getSingleStepForward() > 0) ? getCurrentLineTextStart() : getCurrentLineTextEnd(); }
|
||||
inline int getCursorLineEnd() const { return (getSingleStepForward() > 0) ? getCurrentLineTextEnd() : getCurrentLineTextStart(); }
|
||||
inline int getCursorNextLine() const { return getCurrentLineTextEnd(); }
|
||||
inline int getCursorPreviousLine() const { return getNextPrevCursorPosition(getCurrentLineTextStart(), -1, QTextLayout::SkipCharacters); }
|
||||
/// Creates text box transform matrix, which transforms from
|
||||
/// widget space to page space.
|
||||
/// \param edit Create matrix for text editing?
|
||||
QMatrix createTextBoxTransformMatrix(bool edit) const;
|
||||
|
||||
/// Returns vector of cursor positions (which may be not equal
|
||||
/// to edit string length, because edit string can contain surrogates,
|
||||
/// or graphemes, which are single glyphs, but represented by more
|
||||
/// 16-bit unicode codes).
|
||||
std::vector<int> getCursorPositions() const;
|
||||
|
||||
int getCursorLineUp() const;
|
||||
int getCursorLineDown() const;
|
||||
|
@ -607,9 +624,10 @@ public:
|
|||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event);
|
||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event);
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event);
|
||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event);
|
||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event);
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
|
||||
virtual bool isEditorDrawEnabled() const { return false; }
|
||||
|
||||
|
@ -647,9 +665,10 @@ public:
|
|||
explicit PDFFormFieldAbstractButtonEditor(PDFFormManager* formManager, PDFFormWidget formWidget, QObject* parent);
|
||||
virtual ~PDFFormFieldAbstractButtonEditor() = default;
|
||||
|
||||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition) override;
|
||||
|
||||
protected:
|
||||
virtual void click() = 0;
|
||||
|
@ -701,6 +720,9 @@ public:
|
|||
|
||||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||
|
||||
virtual bool isEditorDrawEnabled() const override { return m_hasFocus; }
|
||||
virtual void draw(AnnotationDrawParameters& parameters) const override;
|
||||
|
@ -870,6 +892,7 @@ public:
|
|||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
virtual void wheelEvent(QWidget* widget, QWheelEvent* event) override;
|
||||
|
|
|
@ -833,6 +833,12 @@ void PDFToolManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void PDFToolManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void PDFToolManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
|
|
@ -464,6 +464,11 @@ public:
|
|||
/// \param event Event
|
||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
|
||||
/// Handles mouse double click event from widget, over which tool operates
|
||||
/// \param widget Widget, over which tool operates
|
||||
/// \param event Event
|
||||
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
|
||||
|
||||
/// Handles mouse release event from widget, over which tool operates
|
||||
/// \param widget Widget, over which tool operates
|
||||
/// \param event Event
|
||||
|
|
Loading…
Reference in New Issue