mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-28 17:37:46 +01:00
Combo box finishing, some bugfixing
This commit is contained in:
parent
7e02bdde1e
commit
ba188426c2
@ -96,6 +96,23 @@ public:
|
||||
virtual void reportRenderErrorOnce(RenderErrorType type, QString message) = 0;
|
||||
};
|
||||
|
||||
/// Dummy class for reporting render errors
|
||||
class PDFRenderErrorReporterDummy : public PDFRenderErrorReporter
|
||||
{
|
||||
public:
|
||||
virtual void reportRenderError(RenderErrorType type, QString message) override
|
||||
{
|
||||
Q_UNUSED(type);
|
||||
Q_UNUSED(message);
|
||||
}
|
||||
|
||||
virtual void reportRenderErrorOnce(RenderErrorType type, QString message) override
|
||||
{
|
||||
Q_UNUSED(type);
|
||||
Q_UNUSED(message);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFEXCEPTION_H
|
||||
|
@ -125,6 +125,8 @@ public:
|
||||
inline int getCursorPreviousLine() const { return getNextPrevCursorPosition(getCurrentLineTextStart(), -1, QTextLayout::SkipCharacters); }
|
||||
|
||||
const QRectF& getWidgetRect() const { return m_widgetRect; }
|
||||
QFont getFont() const { return m_textLayout.font(); }
|
||||
QColor getFontColor() const { return m_textColor; }
|
||||
|
||||
private:
|
||||
/// This function does following things:
|
||||
@ -335,6 +337,9 @@ public:
|
||||
/// \param index Index, from which we want to get valid one
|
||||
int getValidIndex(int index) const;
|
||||
|
||||
/// Returns true, if index is valid
|
||||
bool isValidIndex(int index) const { return index == getValidIndex(index); }
|
||||
|
||||
/// Returns number of rows in the viewport
|
||||
int getViewportRowCount() const { return qFloor(m_widgetRect.height() / m_lineSpacing); }
|
||||
|
||||
@ -348,6 +353,30 @@ public:
|
||||
/// \param modifiers Keyboard modifiers
|
||||
void setCurrentItem(int index, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
/// Returns text of selected item text. If no item is selected,
|
||||
/// or multiple items are selected, then empty string is returned.
|
||||
/// \returns Selected text
|
||||
QString getSelectedItemText() const;
|
||||
|
||||
/// Returns true, if single item is selected
|
||||
bool isSingleItemSelected() const { return m_selection.size() == 1; }
|
||||
|
||||
/// Returns index of option, in the list box option list.
|
||||
/// If option is not found, then -1 is returned.
|
||||
/// \param option Option
|
||||
int findOption(const QString& option) const;
|
||||
|
||||
/// Sets widget appearance, such as font, font size, color, text alignment,
|
||||
/// and rectangle, in which widget resides on page (in page coordinates)
|
||||
/// \param font Font
|
||||
/// \param fontColor Font color
|
||||
/// \param textAlignment Text alignment
|
||||
/// \param rect Widget rectangle in page coordinates
|
||||
/// \param options Options selectable by list box
|
||||
/// \param topIndex Index of first visible item
|
||||
void initialize(QFont font, QColor fontColor, Qt::Alignment textAlignment, QRectF rect,
|
||||
const Options& options, int topIndex, std::set<int> selection);
|
||||
|
||||
private:
|
||||
int getStartItemIndex() const { return 0; }
|
||||
int getEndItemIndex() const { return m_options.empty() ? 0 : int(m_options.size() - 1); }
|
||||
@ -421,6 +450,12 @@ protected:
|
||||
private:
|
||||
static PDFFormField::FieldFlags getTextEditFlags(PDFFormField::FieldFlags flags);
|
||||
|
||||
/// Updates list box selection based on current text. If current text
|
||||
/// corresponds to some item in the list box, then item is selected
|
||||
/// and scrolled to. If text is not found in the text box, then
|
||||
/// selection is cleared.
|
||||
void updateListBoxSelection();
|
||||
|
||||
PDFTextEditPseudowidget m_textEdit;
|
||||
PDFListBoxPseudowidget m_listBox;
|
||||
QRectF m_listBoxPopupRectangle;
|
||||
@ -1948,7 +1983,12 @@ PDFFormFieldComboBoxEditor::PDFFormFieldComboBoxEditor(PDFFormManager* formManag
|
||||
m_listBox(formWidget.getParent()->getFlags()),
|
||||
m_listBoxVisible(false)
|
||||
{
|
||||
const int listBoxItems = 7;
|
||||
const PDFFormFieldChoice* parentField = dynamic_cast<const PDFFormFieldChoice*>(m_formWidget.getParent());
|
||||
Q_ASSERT(parentField);
|
||||
|
||||
initializeTextEdit(&m_textEdit);
|
||||
|
||||
const int listBoxItems = qMin(7, int(parentField->getOptions().size()));
|
||||
QRectF comboBoxRectangle = m_formManager->getWidgetRectangle(m_formWidget);
|
||||
QRectF listBoxPopupRectangle = comboBoxRectangle;
|
||||
listBoxPopupRectangle.translate(0, -comboBoxRectangle.height() * (listBoxItems));
|
||||
@ -1956,8 +1996,6 @@ PDFFormFieldComboBoxEditor::PDFFormFieldComboBoxEditor(PDFFormManager* formManag
|
||||
m_listBoxPopupRectangle = listBoxPopupRectangle;
|
||||
m_dropDownButtonRectangle = comboBoxRectangle;
|
||||
m_dropDownButtonRectangle.setLeft(m_dropDownButtonRectangle.right() - m_dropDownButtonRectangle.height());
|
||||
|
||||
initializeTextEdit(&m_textEdit);
|
||||
initializeListBox(&m_listBox);
|
||||
}
|
||||
|
||||
@ -1979,22 +2017,38 @@ void PDFFormFieldComboBoxEditor::keyPressEvent(QWidget* widget, QKeyEvent* event
|
||||
|
||||
if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return))
|
||||
{
|
||||
// Commit the editor
|
||||
m_formManager->setFocusToEditor(nullptr);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
// If popup list box is shown, then use text and hide it,
|
||||
// otherwise close the editor.
|
||||
if (m_listBoxVisible)
|
||||
{
|
||||
if (m_listBox.isSingleItemSelected())
|
||||
{
|
||||
m_textEdit.setText(m_listBox.getSelectedItemText());
|
||||
}
|
||||
m_listBoxVisible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_formManager->setFocusToEditor(nullptr);
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Escape)
|
||||
event->accept();
|
||||
}
|
||||
else if (event->key() == Qt::Key_Escape)
|
||||
{
|
||||
// Cancel the editor
|
||||
reloadValue();
|
||||
m_formManager->setFocusToEditor(nullptr);
|
||||
// If popup list box is shown, hide it, if not, cancel the editing
|
||||
if (m_listBoxVisible)
|
||||
{
|
||||
m_listBoxVisible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reloadValue();
|
||||
m_formManager->setFocusToEditor(nullptr);
|
||||
}
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_hasFocus || !m_listBoxVisible)
|
||||
else if (!m_listBoxVisible)
|
||||
{
|
||||
m_textEdit.keyPressEvent(widget, event);
|
||||
}
|
||||
@ -2018,23 +2072,11 @@ void PDFFormFieldComboBoxEditor::mousePressEvent(QWidget* widget, QMouseEvent* e
|
||||
if (m_listBoxVisible)
|
||||
{
|
||||
const int index = m_listBox.getIndexFromWidgetPosition(mousePagePosition);
|
||||
m_listBox.setCurrentItem(index, event->modifiers());
|
||||
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
if (m_listBox.isSingleItemSelected())
|
||||
{
|
||||
std::set<int> selection = m_listBox.getSelection();
|
||||
if (selection.count(index))
|
||||
{
|
||||
selection.erase(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection.insert(index);
|
||||
}
|
||||
m_listBox.setSelection(qMove(selection), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_listBox.setCurrentItem(index, event->modifiers());
|
||||
m_textEdit.setText(m_listBox.getSelectedItemText());
|
||||
}
|
||||
|
||||
m_listBoxVisible = false;
|
||||
@ -2045,6 +2087,7 @@ void PDFFormFieldComboBoxEditor::mousePressEvent(QWidget* widget, QMouseEvent* e
|
||||
if (m_dropDownButtonRectangle.contains(mousePagePosition))
|
||||
{
|
||||
m_listBoxVisible = true;
|
||||
updateListBoxSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2060,19 +2103,37 @@ void PDFFormFieldComboBoxEditor::mousePressEvent(QWidget* widget, QMouseEvent* e
|
||||
|
||||
void PDFFormFieldComboBoxEditor::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 PDFFormFieldComboBoxEditor::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 && !m_listBoxVisible)
|
||||
{
|
||||
const int cursorPosition = m_textEdit.getCursorPositionFromWidgetPosition(mousePagePosition, m_hasFocus);
|
||||
m_textEdit.setCursorPosition(cursorPosition, true);
|
||||
|
||||
event->accept();
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldComboBoxEditor::wheelEvent(QWidget* widget, QWheelEvent* event, const QPointF& mousePagePosition)
|
||||
{
|
||||
Q_UNUSED(mousePagePosition);
|
||||
|
||||
if (m_hasFocus && m_listBoxVisible)
|
||||
if (m_listBoxVisible)
|
||||
{
|
||||
if (event->angleDelta().y() < 0)
|
||||
{
|
||||
@ -2088,6 +2149,23 @@ void PDFFormFieldComboBoxEditor::wheelEvent(QWidget* widget, QWheelEvent* event,
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldComboBoxEditor::updateListBoxSelection()
|
||||
{
|
||||
QString text = m_textEdit.getText();
|
||||
|
||||
const int index = m_listBox.findOption(text);
|
||||
if (m_listBox.isValidIndex(index))
|
||||
{
|
||||
m_listBox.setSelection({ index }, true);
|
||||
m_listBox.scrollTo(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_listBox.setTopItemIndex(0);
|
||||
m_listBox.setSelection({ }, true);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFormFieldComboBoxEditor::reloadValue()
|
||||
{
|
||||
const PDFFormFieldChoice* parentField = dynamic_cast<const PDFFormFieldChoice*>(m_formWidget.getParent());
|
||||
@ -2097,9 +2175,6 @@ void PDFFormFieldComboBoxEditor::reloadValue()
|
||||
m_textEdit.setText(loader.readTextString(m_formWidget.getParent()->getValue(), QString()));
|
||||
|
||||
m_listBoxVisible = false;
|
||||
|
||||
m_listBox.setTopItemIndex(0);
|
||||
m_listBox.setSelection({ }, true);
|
||||
}
|
||||
|
||||
void PDFFormFieldComboBoxEditor::draw(AnnotationDrawParameters& parameters, bool edit) const
|
||||
@ -2178,12 +2253,7 @@ void PDFFormFieldComboBoxEditor::initializeListBox(PDFListBoxPseudowidget* listB
|
||||
Q_ASSERT(parentField);
|
||||
|
||||
// Initialize popup list box
|
||||
listBox->setAppearance(PDFAnnotationDefaultAppearance::parse(m_formManager->getForm()->getDefaultAppearance().value_or(QByteArray())),
|
||||
m_formManager->getForm()->getDefaultAlignment(),
|
||||
m_listBoxPopupRectangle,
|
||||
parentField->getOptions(),
|
||||
0,
|
||||
{ });
|
||||
listBox->initialize(m_textEdit.getFont(), m_textEdit.getFontColor(), m_formManager->getForm()->getDefaultAlignment(), m_listBoxPopupRectangle, parentField->getOptions(), 0, { });
|
||||
}
|
||||
|
||||
void PDFFormFieldComboBoxEditor::setFocusImpl(bool focused)
|
||||
@ -3395,6 +3465,28 @@ void PDFListBoxPseudowidget::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void PDFListBoxPseudowidget::initialize(QFont font, QColor fontColor, Qt::Alignment textAlignment, QRectF rect,
|
||||
const Options& options, int topIndex, std::set<int> selection)
|
||||
{
|
||||
m_font = font;
|
||||
|
||||
QFontMetricsF fontMetrics(m_font);
|
||||
m_lineSpacing = fontMetrics.lineSpacing();
|
||||
|
||||
m_textColor = fontColor;
|
||||
if (!m_textColor.isValid())
|
||||
{
|
||||
m_textColor = Qt::black;
|
||||
}
|
||||
|
||||
m_textAlignment = textAlignment;
|
||||
m_widgetRect = rect;
|
||||
m_options = options;
|
||||
m_topIndex = getValidIndex(topIndex);
|
||||
m_selection = qMove(selection);
|
||||
m_currentIndex = m_topIndex;
|
||||
}
|
||||
|
||||
void PDFListBoxPseudowidget::setAppearance(const PDFAnnotationDefaultAppearance& appearance,
|
||||
Qt::Alignment textAlignment,
|
||||
QRectF rect,
|
||||
@ -3409,27 +3501,14 @@ void PDFListBoxPseudowidget::setAppearance(const PDFAnnotationDefaultAppearance&
|
||||
fontSize = qMax(rect.height() / qMax<qreal>(options.size(), 1), qreal(12.0));
|
||||
}
|
||||
|
||||
QColor fontColor = appearance.getFontColor();
|
||||
|
||||
QFont font(appearance.getFontName());
|
||||
font.setHintingPreference(QFont::PreferNoHinting);
|
||||
font.setPixelSize(qCeil(fontSize));
|
||||
font.setStyleStrategy(QFont::ForceOutline);
|
||||
m_font = font;
|
||||
|
||||
QFontMetricsF fontMetrics(font);
|
||||
m_lineSpacing = fontMetrics.lineSpacing();
|
||||
|
||||
m_textColor = appearance.getFontColor();
|
||||
if (!m_textColor.isValid())
|
||||
{
|
||||
m_textColor = Qt::black;
|
||||
}
|
||||
|
||||
m_textAlignment = textAlignment;
|
||||
m_widgetRect = rect;
|
||||
m_options = options;
|
||||
m_topIndex = getValidIndex(topIndex);
|
||||
m_selection = qMove(selection);
|
||||
m_currentIndex = m_topIndex;
|
||||
initialize(font, fontColor, textAlignment, rect, options, topIndex, qMove(selection));
|
||||
}
|
||||
|
||||
QMatrix PDFListBoxPseudowidget::createListBoxTransformMatrix() const
|
||||
@ -3590,6 +3669,28 @@ void PDFListBoxPseudowidget::setCurrentItem(int index, Qt::KeyboardModifiers mod
|
||||
scrollTo(m_currentIndex);
|
||||
}
|
||||
|
||||
QString PDFListBoxPseudowidget::getSelectedItemText() const
|
||||
{
|
||||
if (m_selection.size() == 1)
|
||||
{
|
||||
const int selectedIndex = *m_selection.begin();
|
||||
return m_options[selectedIndex].userString;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
int PDFListBoxPseudowidget::findOption(const QString& option) const
|
||||
{
|
||||
auto it = std::find_if(m_options.cbegin(), m_options.cend(), [&option](const auto& currentOption) { return currentOption.userString == option; });
|
||||
if (it != m_options.cend())
|
||||
{
|
||||
return static_cast<int>(std::distance(m_options.cbegin(), it));
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool PDFListBoxPseudowidget::hasContinuousSelection() const
|
||||
{
|
||||
if (m_selection.empty())
|
||||
|
@ -290,7 +290,8 @@ void PDFDocumentPropertiesDialog::initializeFonts(const pdf::PDFDocument* docume
|
||||
{
|
||||
if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, document))
|
||||
{
|
||||
pdf::PDFRealizedFontPointer realizedFont = pdf::PDFRealizedFont::createRealizedFont(font, 8.0, nullptr);
|
||||
pdf::PDFRenderErrorReporterDummy dummyReporter;
|
||||
pdf::PDFRealizedFontPointer realizedFont = pdf::PDFRealizedFont::createRealizedFont(font, 8.0, &dummyReporter);
|
||||
if (realizedFont)
|
||||
{
|
||||
const pdf::FontType fontType = font->getFontType();
|
||||
|
Loading…
x
Reference in New Issue
Block a user