mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Finishing editation of text field - also 'Comb' functionality
This commit is contained in:
@ -1122,6 +1122,7 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
parameters.annotation = annotation.annotation.data();
|
parameters.annotation = annotation.annotation.data();
|
||||||
parameters.formManager = m_formManager;
|
parameters.formManager = m_formManager;
|
||||||
parameters.key = std::make_pair(annotation.appearance, annotation.annotation->getAppearanceState());
|
parameters.key = std::make_pair(annotation.appearance, annotation.annotation->getAppearanceState());
|
||||||
|
parameters.invertColors = m_features.testFlag(PDFRenderer::InvertColors);
|
||||||
annotation.annotation->draw(parameters);
|
annotation.annotation->draw(parameters);
|
||||||
|
|
||||||
if (parameters.boundingRectangle.isValid())
|
if (parameters.boundingRectangle.isValid())
|
||||||
@ -1394,15 +1395,19 @@ void PDFWidgetAnnotationManager::keyReleaseEvent(QWidget* widget, QKeyEvent* eve
|
|||||||
void PDFWidgetAnnotationManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
void PDFWidgetAnnotationManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
Q_UNUSED(event);
|
|
||||||
|
|
||||||
updateFromMouseEvent(event);
|
updateFromMouseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFWidgetAnnotationManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(widget);
|
||||||
|
Q_UNUSED(event);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFWidgetAnnotationManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
void PDFWidgetAnnotationManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
Q_UNUSED(event);
|
|
||||||
|
|
||||||
updateFromMouseEvent(event);
|
updateFromMouseEvent(event);
|
||||||
}
|
}
|
||||||
@ -1410,7 +1415,6 @@ void PDFWidgetAnnotationManager::mouseReleaseEvent(QWidget* widget, QMouseEvent*
|
|||||||
void PDFWidgetAnnotationManager::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
void PDFWidgetAnnotationManager::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
Q_UNUSED(event);
|
|
||||||
|
|
||||||
updateFromMouseEvent(event);
|
updateFromMouseEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -458,6 +458,9 @@ struct AnnotationDrawParameters
|
|||||||
|
|
||||||
/// Appeareance mode (normal/rollover/down, and appearance state)
|
/// Appeareance mode (normal/rollover/down, and appearance state)
|
||||||
PDFAppeareanceStreams::Key key;
|
PDFAppeareanceStreams::Key key;
|
||||||
|
|
||||||
|
/// Invert colors?
|
||||||
|
bool invertColors = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for all annotation types. Represents PDF annotation object.
|
/// 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 keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyReleaseEvent(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) override;
|
||||||
|
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void wheelEvent(QWidget* widget, QWheelEvent* event) override;
|
virtual void wheelEvent(QWidget* widget, QWheelEvent* event) override;
|
||||||
|
@ -95,6 +95,11 @@ public:
|
|||||||
/// \param event Event
|
/// \param event Event
|
||||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) = 0;
|
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
|
/// Handles mouse release event from widget
|
||||||
/// \param widget Widget
|
/// \param widget Widget
|
||||||
/// \param event Event
|
/// \param event Event
|
||||||
|
@ -384,6 +384,17 @@ void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
|
|||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BaseWidget>
|
||||||
|
void PDFDrawWidgetBase<BaseWidget>::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
event->ignore();
|
||||||
|
|
||||||
|
if (processEvent<QMouseEvent, &IDrawWidgetInputInterface::mouseDoubleClickEvent>(event))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BaseWidget>
|
template<typename BaseWidget>
|
||||||
void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
|
void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
|
@ -142,6 +142,7 @@ protected:
|
|||||||
virtual void keyPressEvent(QKeyEvent* event) override;
|
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||||
virtual void keyReleaseEvent(QKeyEvent* event) override;
|
virtual void keyReleaseEvent(QKeyEvent* event) override;
|
||||||
virtual void mousePressEvent(QMouseEvent* event) override;
|
virtual void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
virtual void wheelEvent(QWheelEvent* event) override;
|
virtual void wheelEvent(QWheelEvent* event) override;
|
||||||
|
@ -866,7 +866,7 @@ void PDFFormManager::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|||||||
setFocusToEditor(info.editor);
|
setFocusToEditor(info.editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.editor->mousePressEvent(widget, event);
|
info.editor->mousePressEvent(widget, event, info.mousePosition);
|
||||||
grabMouse(info, event);
|
grabMouse(info, event);
|
||||||
}
|
}
|
||||||
else if (!isMouseGrabbed())
|
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)
|
void PDFFormManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
if (!hasForm())
|
if (!hasForm())
|
||||||
@ -887,7 +911,7 @@ void PDFFormManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
|||||||
if (info.isValid())
|
if (info.isValid())
|
||||||
{
|
{
|
||||||
Q_ASSERT(info.editor);
|
Q_ASSERT(info.editor);
|
||||||
info.editor->mouseReleaseEvent(widget, event);
|
info.editor->mouseReleaseEvent(widget, event, info.mousePosition);
|
||||||
ungrabMouse(info, event);
|
ungrabMouse(info, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -903,7 +927,7 @@ void PDFFormManager::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
|||||||
if (info.isValid())
|
if (info.isValid())
|
||||||
{
|
{
|
||||||
Q_ASSERT(info.editor);
|
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
|
// If mouse is grabbed, then event is accepted always (because
|
||||||
// we get Press event, when we grabbed the mouse, then we will
|
// 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);
|
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(widget);
|
||||||
Q_UNUSED(event);
|
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(widget);
|
||||||
Q_UNUSED(event);
|
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(widget);
|
||||||
Q_UNUSED(event);
|
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)
|
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)
|
void PDFFormFieldAbstractButtonEditor::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
||||||
{
|
{
|
||||||
switch (event->key())
|
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(widget);
|
||||||
|
Q_UNUSED(mousePagePosition);
|
||||||
|
|
||||||
if (event->button() == Qt::LeftButton)
|
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
|
void PDFFormFieldTextBoxEditor::draw(AnnotationDrawParameters& parameters) const
|
||||||
{
|
{
|
||||||
m_textEdit.draw(parameters, true);
|
m_textEdit.draw(parameters, true);
|
||||||
@ -1515,6 +1612,19 @@ void PDFTextEditPseudowidget::shortcutOverrideEvent(QWidget* widget, QKeyEvent*
|
|||||||
default:
|
default:
|
||||||
break;
|
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)
|
void PDFTextEditPseudowidget::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
||||||
@ -1836,6 +1946,7 @@ void PDFTextEditPseudowidget::setAppearance(const PDFAnnotationDefaultAppearance
|
|||||||
QFont font(appearance.getFontName());
|
QFont font(appearance.getFontName());
|
||||||
font.setHintingPreference(QFont::PreferNoHinting);
|
font.setHintingPreference(QFont::PreferNoHinting);
|
||||||
font.setPixelSize(qCeil(fontSize));
|
font.setPixelSize(qCeil(fontSize));
|
||||||
|
font.setStyleStrategy(QFont::ForceOutline);
|
||||||
m_textLayout.setFont(font);
|
m_textLayout.setFont(font);
|
||||||
|
|
||||||
QTextOption option = m_textLayout.textOption();
|
QTextOption option = m_textLayout.textOption();
|
||||||
@ -1956,22 +2067,138 @@ void PDFTextEditPseudowidget::performInsertText(const QString& text)
|
|||||||
updateTextLayout();
|
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
|
void PDFTextEditPseudowidget::draw(AnnotationDrawParameters& parameters, bool edit) const
|
||||||
{
|
{
|
||||||
pdf::PDFPainterStateGuard guard(parameters.painter);
|
pdf::PDFPainterStateGuard guard(parameters.painter);
|
||||||
parameters.boundingRectangle = parameters.annotation->getRectangle();
|
parameters.boundingRectangle = parameters.annotation->getRectangle();
|
||||||
|
|
||||||
QPainter* painter = parameters.painter;
|
QPalette palette = QApplication::palette();
|
||||||
painter->translate(parameters.boundingRectangle.bottomLeft());
|
|
||||||
painter->scale(1.0, -1.0);
|
|
||||||
|
|
||||||
|
auto getAdjustedColor = [¶meters](QColor color)
|
||||||
|
{
|
||||||
|
if (parameters.invertColors)
|
||||||
|
{
|
||||||
|
return invertColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
};
|
||||||
|
|
||||||
|
QPainter* painter = parameters.painter;
|
||||||
|
painter->setClipRect(parameters.boundingRectangle, Qt::IntersectClip);
|
||||||
|
painter->setWorldMatrix(createTextBoxTransformMatrix(edit), true);
|
||||||
|
painter->setPen(getAdjustedColor(Qt::black));
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
QVector<QTextLayout::FormatRange> selections;
|
QVector<QTextLayout::FormatRange> selections;
|
||||||
|
|
||||||
QTextLayout::FormatRange defaultFormat;
|
QTextLayout::FormatRange defaultFormat;
|
||||||
defaultFormat.start = getPositionStart();
|
defaultFormat.start = getPositionStart();
|
||||||
defaultFormat.length = getTextLength();
|
defaultFormat.length = getTextLength();
|
||||||
defaultFormat.format.clearBackground();
|
defaultFormat.format.clearBackground();
|
||||||
defaultFormat.format.setForeground(QBrush(m_textColor, Qt::SolidPattern));
|
defaultFormat.format.setForeground(QBrush(getAdjustedColor(m_textColor), Qt::SolidPattern));
|
||||||
|
|
||||||
// If we are editing, draw selections
|
// If we are editing, draw selections
|
||||||
if (edit && isTextSelected())
|
if (edit && isTextSelected())
|
||||||
@ -1984,12 +2211,11 @@ void PDFTextEditPseudowidget::draw(AnnotationDrawParameters& parameters, bool ed
|
|||||||
after.start = m_selectionEnd;
|
after.start = m_selectionEnd;
|
||||||
after.length = getTextLength() - m_selectionEnd;
|
after.length = getTextLength() - m_selectionEnd;
|
||||||
|
|
||||||
QPalette palette = QApplication::palette();
|
|
||||||
QTextLayout::FormatRange selectedFormat = defaultFormat;
|
QTextLayout::FormatRange selectedFormat = defaultFormat;
|
||||||
selectedFormat.start = m_selectionStart;
|
selectedFormat.start = m_selectionStart;
|
||||||
selectedFormat.length = getSelectionLength();
|
selectedFormat.length = getSelectionLength();
|
||||||
selectedFormat.format.setForeground(palette.brush(QPalette::HighlightedText));
|
selectedFormat.format.setForeground(QBrush(getAdjustedColor(palette.color(QPalette::HighlightedText)), Qt::SolidPattern));
|
||||||
selectedFormat.format.setBackground(palette.brush(QPalette::Highlight));
|
selectedFormat.format.setBackground(QBrush(getAdjustedColor(palette.color(QPalette::Highlight)), Qt::SolidPattern));
|
||||||
|
|
||||||
selections = { before, selectedFormat, after};
|
selections = { before, selectedFormat, after};
|
||||||
}
|
}
|
||||||
@ -1999,13 +2225,74 @@ void PDFTextEditPseudowidget::draw(AnnotationDrawParameters& parameters, bool ed
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw text
|
// Draw text
|
||||||
m_textLayout.draw(painter, QPointF(0.0, 0.0), selections, QRectF(0, 0, parameters.boundingRectangle.width(), parameters.boundingRectangle.height()));
|
m_textLayout.draw(painter, QPointF(0.0, 0.0), selections, QRectF());
|
||||||
|
|
||||||
// If we are editing, also draw text
|
// If we are editing, also draw text
|
||||||
if (edit)
|
if (edit)
|
||||||
{
|
{
|
||||||
m_textLayout.drawCursor(painter, QPointF(0.0, 0.0), m_positionCursor);
|
m_textLayout.drawCursor(painter, QPointF(0.0, 0.0), m_positionCursor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFTextEditPseudowidget::getCursorPositionFromWidgetPosition(const QPointF& point, bool edit) const
|
||||||
|
{
|
||||||
|
QMatrix textBoxSpaceToPageSpace = createTextBoxTransformMatrix(edit);
|
||||||
|
QMatrix pageSpaceToTextBoxSpace = textBoxSpaceToPageSpace.inverted();
|
||||||
|
|
||||||
|
QPointF textBoxPoint = pageSpaceToTextBoxSpace.map(point);
|
||||||
|
|
||||||
|
if (isComb())
|
||||||
|
{
|
||||||
|
// 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()
|
void PDFTextEditPseudowidget::updateTextLayout()
|
||||||
@ -2049,7 +2336,7 @@ void PDFTextEditPseudowidget::updateTextLayout()
|
|||||||
int length = 0;
|
int length = 0;
|
||||||
int currentPos = 0;
|
int currentPos = 0;
|
||||||
|
|
||||||
while (currentPos <= m_editText.length())
|
while (currentPos < m_editText.length())
|
||||||
{
|
{
|
||||||
currentPos = m_textLayout.nextCursorPosition(currentPos, QTextLayout::SkipCharacters);
|
currentPos = m_textLayout.nextCursorPosition(currentPos, QTextLayout::SkipCharacters);
|
||||||
++length;
|
++length;
|
||||||
|
@ -517,6 +517,25 @@ public:
|
|||||||
/// \param parameters Parameters
|
/// \param parameters Parameters
|
||||||
void draw(AnnotationDrawParameters& parameters, bool edit) const;
|
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:
|
private:
|
||||||
/// This function does following things:
|
/// This function does following things:
|
||||||
/// 1) Clamps edit text to fit maximum length
|
/// 1) Clamps edit text to fit maximum length
|
||||||
@ -551,18 +570,16 @@ private:
|
|||||||
/// Returns current line text end position
|
/// Returns current line text end position
|
||||||
int getCurrentLineTextEnd() const;
|
int getCurrentLineTextEnd() const;
|
||||||
|
|
||||||
inline int getCursorForward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepForward(), mode); }
|
/// Creates text box transform matrix, which transforms from
|
||||||
inline int getCursorBackward(QTextLayout::CursorMode mode) const { return getNextPrevCursorPosition(getSingleStepBackward(), mode); }
|
/// widget space to page space.
|
||||||
inline int getCursorCharacterForward() const { return getCursorForward(QTextLayout::SkipCharacters); }
|
/// \param edit Create matrix for text editing?
|
||||||
inline int getCursorCharacterBackward() const { return getCursorBackward(QTextLayout::SkipCharacters); }
|
QMatrix createTextBoxTransformMatrix(bool edit) const;
|
||||||
inline int getCursorWordForward() const { return getCursorForward(QTextLayout::SkipWords); }
|
|
||||||
inline int getCursorWordBackward() const { return getCursorBackward(QTextLayout::SkipWords); }
|
/// Returns vector of cursor positions (which may be not equal
|
||||||
inline int getCursorDocumentStart() const { return (getSingleStepForward() > 0) ? getPositionStart() : getPositionEnd(); }
|
/// to edit string length, because edit string can contain surrogates,
|
||||||
inline int getCursorDocumentEnd() const { return (getSingleStepForward() > 0) ? getPositionEnd() : getPositionStart(); }
|
/// or graphemes, which are single glyphs, but represented by more
|
||||||
inline int getCursorLineStart() const { return (getSingleStepForward() > 0) ? getCurrentLineTextStart() : getCurrentLineTextEnd(); }
|
/// 16-bit unicode codes).
|
||||||
inline int getCursorLineEnd() const { return (getSingleStepForward() > 0) ? getCurrentLineTextEnd() : getCurrentLineTextStart(); }
|
std::vector<int> getCursorPositions() const;
|
||||||
inline int getCursorNextLine() const { return getCurrentLineTextEnd(); }
|
|
||||||
inline int getCursorPreviousLine() const { return getNextPrevCursorPosition(getCurrentLineTextStart(), -1, QTextLayout::SkipCharacters); }
|
|
||||||
|
|
||||||
int getCursorLineUp() const;
|
int getCursorLineUp() const;
|
||||||
int getCursorLineDown() const;
|
int getCursorLineDown() const;
|
||||||
@ -607,9 +624,10 @@ public:
|
|||||||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event);
|
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event);
|
||||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event);
|
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event);
|
||||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event);
|
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event);
|
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event, const QPointF& mousePagePosition);
|
||||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event);
|
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; }
|
virtual bool isEditorDrawEnabled() const { return false; }
|
||||||
|
|
||||||
@ -647,9 +665,10 @@ public:
|
|||||||
explicit PDFFormFieldAbstractButtonEditor(PDFFormManager* formManager, PDFFormWidget formWidget, QObject* parent);
|
explicit PDFFormFieldAbstractButtonEditor(PDFFormManager* formManager, PDFFormWidget formWidget, QObject* parent);
|
||||||
virtual ~PDFFormFieldAbstractButtonEditor() = default;
|
virtual ~PDFFormFieldAbstractButtonEditor() = default;
|
||||||
|
|
||||||
|
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyReleaseEvent(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:
|
protected:
|
||||||
virtual void click() = 0;
|
virtual void click() = 0;
|
||||||
@ -701,6 +720,9 @@ public:
|
|||||||
|
|
||||||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
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 bool isEditorDrawEnabled() const override { return m_hasFocus; }
|
||||||
virtual void draw(AnnotationDrawParameters& parameters) const override;
|
virtual void draw(AnnotationDrawParameters& parameters) const override;
|
||||||
@ -870,6 +892,7 @@ public:
|
|||||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyReleaseEvent(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) override;
|
||||||
|
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
|
||||||
virtual void wheelEvent(QWidget* widget, QWheelEvent* 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)
|
void PDFToolManager::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
||||||
{
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
@ -464,6 +464,11 @@ public:
|
|||||||
/// \param event Event
|
/// \param event Event
|
||||||
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
|
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
|
/// Handles mouse release event from widget, over which tool operates
|
||||||
/// \param widget Widget, over which tool operates
|
/// \param widget Widget, over which tool operates
|
||||||
/// \param event Event
|
/// \param event Event
|
||||||
|
Reference in New Issue
Block a user