Finishing of outline, zoom actions

This commit is contained in:
Jakub Melka
2019-12-01 13:02:25 +01:00
parent 5954b7f409
commit 939a011ca6
14 changed files with 786 additions and 11 deletions

View File

@@ -202,6 +202,8 @@ SUFFIX = d
qt_libraries.files = $$[QT_INSTALL_BINS]/Qt?Widgets$${SUFFIX}.dll \
$$[QT_INSTALL_BINS]/Qt?Gui$${SUFFIX}.dll \
$$[QT_INSTALL_BINS]/Qt?Core$${SUFFIX}.dll
$$[QT_INSTALL_BINS]/Qt?Core$${SUFFIX}.dll \
$$[QT_INSTALL_BINS]/Qt?WinExtras$${SUFFIX}.dll \
$$[QT_INSTALL_BINS]/Qt?Svg$${SUFFIX}.dll
qt_libraries.path = $$DESTDIR/install
INSTALLS += qt_libraries

View File

@@ -327,7 +327,7 @@ PDFDestination PDFDestination::parse(const PDFDocument* document, PDFObject obje
const PDFArray* array = object.getArray();
if (array->getCount() < 2)
{
throw PDFException(PDFTranslationContext::tr("Invalid destination - array has invalid size."));
return result;
}
PDFDocumentDataLoaderDecorator loader(document);
@@ -344,7 +344,7 @@ PDFDestination PDFDestination::parse(const PDFDocument* document, PDFObject obje
}
else
{
throw PDFException(PDFTranslationContext::tr("Invalid destination - invalid page reference."));
return result;
}
QByteArray name = loader.readName(array->getItem(1));
@@ -352,11 +352,11 @@ PDFDestination PDFDestination::parse(const PDFDocument* document, PDFObject obje
size_t currentIndex = 2;
auto readNumber = [&]()
{
if (currentIndex >= array->getCount())
if (currentIndex < array->getCount())
{
throw PDFException(PDFTranslationContext::tr("Invalid destination - array has invalid size."));
return loader.readNumber(array->getItem(currentIndex++), 0.0);
}
return loader.readNumber(array->getItem(currentIndex++), 0.0);
return 0.0;
};
if (name == "XYZ")
@@ -404,7 +404,7 @@ PDFDestination PDFDestination::parse(const PDFDocument* document, PDFObject obje
}
else
{
throw PDFException(PDFTranslationContext::tr("Invalid destination - unknown type."));
return result;
}
}

View File

@@ -86,7 +86,7 @@ public:
PDFInteger getPageIndex() const { return m_pageIndex; }
/// Parses the destination from the object. If object contains invalid destination,
/// then exception is thrown. If object is empty, empty destination is returned.
/// then empty destination is returned. If object is empty, empty destination is returned.
/// \param document Document
/// \param object Destination object
static PDFDestination parse(const PDFDocument* document, PDFObject object);

View File

@@ -143,6 +143,7 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume
{
object = object.getDictionary()->get("D");
}
return PDFDestination::parse(document, qMove(object));
};

View File

@@ -114,6 +114,25 @@ PDFDrawSpaceController::LayoutItem PDFDrawSpaceController::getLayoutItemForPage(
return result;
}
QSizeF PDFDrawSpaceController::getReferenceBoundingBox() const
{
QRectF rect;
for (const LayoutItem& item : m_layoutItems)
{
QRectF pageRect = item.pageRectMM;
pageRect.translate(0, -pageRect.top());
rect = rect.united(pageRect);
}
if (rect.isValid())
{
rect.adjust(0, 0, m_horizontalSpacingMM, m_verticalSpacingMM);
}
return rect.size();
}
void PDFDrawSpaceController::recalculate()
{
if (!m_document)
@@ -697,6 +716,24 @@ void PDFDrawWidgetProxy::performOperation(Operation operation)
break;
}
case ZoomFit:
{
zoom(getZoomHint(ZoomHint::Fit));
break;
}
case ZoomFitWidth:
{
zoom(getZoomHint(ZoomHint::FitWidth));
break;
}
case ZoomFitHeight:
{
zoom(getZoomHint(ZoomHint::FitHeight));
break;
}
default:
{
Q_ASSERT(false);
@@ -734,6 +771,38 @@ void PDFDrawWidgetProxy::zoom(PDFReal zoom)
}
}
PDFReal PDFDrawWidgetProxy::getZoomHint(ZoomHint hint) const
{
QSizeF referenceSize = m_controller->getReferenceBoundingBox();
if (referenceSize.isValid())
{
const PDFReal ratio = 0.95;
const PDFReal widthMM = m_widget->widthMM() * ratio;
const PDFReal heightMM = m_widget->heightMM() * ratio;
const PDFReal widthHint = widthMM / referenceSize.width();
const PDFReal heightHint = heightMM / referenceSize.height();
switch (hint)
{
case ZoomHint::Fit:
return qMin(widthHint, heightHint);
case ZoomHint::FitWidth:
return widthHint;
case ZoomHint::FitHeight:
return heightHint;
default:
break;
}
}
// Return default 100% zoom
return 1.0;
}
void PDFDrawWidgetProxy::goToPage(PDFInteger pageIndex)
{
PDFDrawSpaceController::LayoutItem layoutItem = m_controller->getLayoutItemForPage(pageIndex);

View File

@@ -105,6 +105,11 @@ public:
/// Returns optional content activity
const PDFOptionalContentActivity* getOptionalContentActivity() const { return m_optionalContentActivity; }
/// Returns reference bounding box for correct calculation of zoom fit/fit vertical/fit horizontal.
/// If zoom is set in a way to display this bounding box on a screen, then it is assured that
/// any page on the screen will fit this bounding box, regardless of mode (single/two columns, etc.).
QSizeF getReferenceBoundingBox() const;
signals:
void drawSpaceChanged();
void repaintNeeded();
@@ -175,6 +180,9 @@ public:
{
ZoomIn,
ZoomOut,
ZoomFit,
ZoomFitWidth,
ZoomFitHeight,
NavigateDocumentStart,
NavigateDocumentEnd,
NavigateNextPage,
@@ -197,6 +205,18 @@ public:
/// \param zoom New zoom
void zoom(PDFReal zoom);
enum class ZoomHint
{
Fit,
FitWidth,
FitHeight
};
/// Calculates zoom using given hint (i.e. to fill whole space, fill vertical,
/// or fill horizontal).
/// \param hint Zoom hint type
PDFReal getZoomHint(ZoomHint hint) const;
/// Go to the specified page
/// \param pageIndex Page to scroll to
void goToPage(PDFInteger pageIndex);

View File

@@ -176,6 +176,7 @@ template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::keyPressEvent(QKeyEvent* event)
{
QScrollBar* verticalScrollbar = m_widget->getVerticalScrollbar();
event->ignore();
// Vertical navigation
if (verticalScrollbar->isVisible())
@@ -195,11 +196,10 @@ void PDFDrawWidgetBase<BaseWidget>::keyPressEvent(QKeyEvent* event)
if (event->matches(keyToOperation.first))
{
m_widget->getDrawWidgetProxy()->performOperation(keyToOperation.second);
event->accept();
}
}
}
event->accept();
}
template<typename BaseWidget>