diff --git a/core/area.h b/core/area.h index bae16e9f5..aac8aa413 100644 --- a/core/area.h +++ b/core/area.h @@ -1,999 +1,999 @@ /*************************************************************************** * Copyright (C) 2004-05 by Enrico Ros * * Copyright (C) 2005 by Piotr Szymanski * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_AREA_H_ #define _OKULAR_AREA_H_ #include #include #include #include #include #include #include "global.h" #include "okularcore_export.h" class QPolygonF; class QRect; namespace Okular { class Annotation; class Action; class NormalizedShape; /** * NormalizedPoint is a helper class which stores the coordinates * of a normalized point. * * @par Normalized Coordinate System * @parblock * Normalized means that the coordinates are always between 0 and 1, * unless the point shall be outside of the reference area. * * The reference area is a rectangle, and all normalized points * with coordinates of 0 or 1 describe its edges. * * This allows to locate things on a reference area without knowing its * (current or future) actual size. When the reference area is resized, * all things which are described in normalized coordinates keep their * proportional position on the area. * @endparblock * * @par Transformation to and from Normalized Coordinates * @parblock * To transform normalized coordinates to coordinates on the reference area, * just multiply them with the size of the reference area. * * To get normalized coordinates from a point on the reference area, * just divide its coordinates with the size of the reference area. * * Many methods have parameters @c xScale and @c yScale, * these are equal to the size of the reference area. * @endparblock * * @par Normalized Coordinate System Applied to Pages * @parblock * Okular uses a normalized coordinate system mainly to describe * positions on pages. * This is useful because pages can be shown in different sizes (zoom), * but all objects shall keep their proportional position on the page. * * Okular maps from page to normalized coordinates as follows: * * Left edge of the page: x = 0 * * Right edge of the page: x = 1 * * Top edge of the page: y = 0 * * Bottom edge of the page: y = 1 * @endparblock * * @par Example: Draw a Point on a Page * @parblock * The point is given in normalized coordinates (0.5, 0.3). * * If you want to draw it on a 800x600 page, * just multiply the x coordinate (0.5) with the page width (800), * and the y coordinate (0.3) with the page height (600). * So, the point will be drawn on the page at (400, 180). * * That allows you to zoom the page by just multiplying the normalized points with the * zoomed page size. * @endparblock * * @par Example: Select Text on a Page using Mouse Events * @parblock - * The positon of all glyphs and words is stored in normalized coordinates. + * The position of all glyphs and words is stored in normalized coordinates. * (This is what TextPage actually does.) * Mouse press and release events are given in page coordinates (400, 180) and (600, 450), * while the page has a size of 800x600. * * If you want to search all text between the mouse click and release event, * you need their normalized coordinates. * Just divide the x coordinates (400 and 600) by the page width (800), * and the y coordinates (180 and 450) by the page height (600). * So, you have to search for all glyphs between (0.5, 0.3) and (0.75, 0.75). * * That allows you to process all glyphs and words without * having to keep any of their positions in sync with the page. * @endparblock * * @par Geometric operations * @parblock * NormalizedPoint supports basic geometric operations. * * You can transform it with a QTransform matrix. * * With the size of the reference area, you can calculate the squared * absolute distance to another NormalizedPoint or a line of two NormalizedPoints. * * NormalizedRect provides additional geometric operations for rectangles. * @endparblock * * @see NormalizedRect */ class OKULARCORE_EXPORT NormalizedPoint { public: /** * Creates a normalized point at (0, 0). */ NormalizedPoint(); /** * Creates a new normalized point with the normalized coordinates (@p x, @p y ). */ NormalizedPoint( double x, double y ); /** * Creates a new normalized point from an absolute point (@p x, @p y) * on a reference area of size @p xScale x @p yScale. */ NormalizedPoint( int x, int y, int xScale, int yScale ); /** * @internal */ NormalizedPoint& operator=( const NormalizedPoint& ); NormalizedPoint( const NormalizedPoint& ); ~NormalizedPoint(); /** * Transforms the normalized point with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); /** * Returns squared distance to normalized point (@p x, @p y) * on a reference area of size @p xScale x @p yScale. * @since 0.17 (KDE 4.11) */ double distanceSqr( double x, double y, double xScale, double yScale ) const; /** * Returns squared distance of the normalized point (@p x, @p y) * to the line segment from @p start to @p end * on a reference area of size @p xScale x @p yScale. * @since 0.17 (KDE 4.11) */ static double distanceSqr( double x, double y, double xScale, double yScale, const NormalizedPoint& start, const NormalizedPoint& end ); /** * The normalized x coordinate. */ double x; /** * The normalized y coordinate. */ double y; }; /** * A NormalizedRect is a rectangle which can be defined by two NormalizedPoints. * * It describes a rectangular area on a reference area of undefined size. * For more information about the normalized coordinate system, see NormalizedPoint. * * In Okular, NormalizedRect can be used e. g. to describe bounding boxes of TextEntity objects, * and the highlight area of text selections. * * If you need to describe an area which consists of multiple rectangles, * you can use RegularAreaRect instead. * * @see NormalizedPoint, RegularAreaRect, TextEntity */ class OKULARCORE_EXPORT NormalizedRect { public: /** * Creates a null normalized rectangle. * @see isNull() */ NormalizedRect(); /** * Creates a normalized rectangle with the normalized coordinates * @p left, @p top, @p right, @p bottom. * * If you need the x, y, width and height coordinates use the * following formulas: * * @li x = left * @li y = top * @li width = right - left * @li height = bottom - top * * @note * The coordinates for @p left and @p top should be lower than * @p right and @p bottom, respectively. * At negative width or height the behaviour of some operations is undefined. */ NormalizedRect( double left, double top, double right, double bottom ); /** * Creates a normalized rectangle from the given @p rectangle * on a reference area of size @p xScale x @p yScale. * * @note * The rectangle should have positive width and height. * You can use e. g. QRect::normalize() to ensure this. * At negative width or height the behaviour of some operations is undefined. */ NormalizedRect( const QRect &rectangle, double xScale, double yScale ); /** * @internal */ NormalizedRect( const NormalizedRect& ); /** * @internal */ NormalizedRect& operator=( const NormalizedRect &other ); ~NormalizedRect(); /** * Build a normalized rect from a QRectF, which already has normalized coordinates. */ static NormalizedRect fromQRectF( const QRectF &rect ); /** * Returns whether this normalized rectangle is a null normalized rect. */ bool isNull() const; /** * Returns whether the normalized rectangle contains the normalized point * (@p x, @p y). */ bool contains( double x, double y ) const; /** * Returns whether the normalized rectangle intersects the @p other normalized * rectangle. */ bool intersects( const NormalizedRect &other ) const; /** * This is an overloaded member function, provided for convenience. It behaves essentially * like the above function. */ bool intersects( const NormalizedRect *other ) const; /** * Returns whether the normalized rectangle intersects an other normalized * rectangle, which is defined by @p left, @p top, @p right and @p bottom. */ bool intersects( double left, double top, double right, double bottom ) const; /** * Returns the rectangle mapped to a reference area of @p xScale x @p yScale. */ QRect geometry( int xScale, int yScale ) const; /** * Same functionality as geometry, but the output is now rounded before typecasting to int * * @since 0.14 (KDE 4.8) */ QRect roundedGeometry( int xScale, int yScale ) const; /** * Returns the normalized bounding rectangle of the normalized rectangle * combined with the @p other normalized rectangle. */ NormalizedRect operator|( const NormalizedRect &other ) const; /** * Sets the normalized rectangle to the normalized bounding rectangle * of itself combined with the @p other normalized rectangle. */ NormalizedRect& operator|=( const NormalizedRect &other ); /** * Returns the intersection of this normalized rectangle with the specified * @p other. If the rects do not intersect then the result is a null rectangle. * * @since 0.7 (KDE 4.1) */ NormalizedRect operator&( const NormalizedRect &other ) const; /** * Returns whether the normalized rectangle is equal to the @p other * normalized rectangle. */ bool operator==( const NormalizedRect &other ) const; /** * Returns the center of the rectangle * @since 0.10 (KDE 4.4) */ NormalizedPoint center() const; /** * Transforms the normalized rectangle with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); /** * Returns true if the point @p pt is located below the bottom of the rectangle * @since 0.14 (KDE 4.8) */ bool isBottom(const NormalizedPoint& pt) const { return bottom < pt.y; } /** * Returns true if the point @p pt is located above the top of the rectangle * @since 0.14 (KDE 4.8) */ bool isTop(const NormalizedPoint& pt) const { return top > pt.y; } /** * Returns true if the point @p pt is located below the top of the rectangle * @since 0.14 (KDE 4.8) */ bool isBottomOrLevel(const NormalizedPoint& pt) const { return top < pt.y; } /** * Returns true if the point @p pt is located above the bottom of the rectangle * @since 0.14 (KDE 4.8) */ bool isTopOrLevel(const NormalizedPoint& pt) const { return bottom > pt.y; } /** * Returns true if the point @p pt is located to the right of the left edge of the rectangle * @since 0.14 (KDE 4.8) */ bool isLeft(const NormalizedPoint& pt) const { return left < pt.x; } /** * Returns true if the point @p pt is located to the left of the right edge of the rectangle * @since 0.14 (KDE 4.8) */ bool isRight(const NormalizedPoint& pt) const { return right > pt.x; } /** * Returns the squared distance of the normalized point (@p x, @p y) * to the closest edge, or 0 if the point is within the rectangle; * using a reference area of size @p xScale x @p yScale * @since 0.17 (KDE 4.11) */ double distanceSqr(double x, double y, double xScale, double yScale) const { double distX = 0; if ( x < left ) distX = left - x; else if ( x > right ) distX = x - right; double distY = 0; if ( top > y ) distY = top - y; else if (bottom < y) distY = y - bottom; return pow( distX * xScale, 2 ) + pow( distY * yScale, 2 ); } /// @since 1.4 double width() const { return right - left; } /// @since 1.4 double height() const { return bottom - top; } /** * The normalized left coordinate. */ double left; /** * The normalized top coordinate. */ double top; /** * The normalized right coordinate. */ double right; /** * The normalized bottom coordinate. */ double bottom; }; //KDE_DUMMY_QHASH_FUNCTION(NormalizedRect) /** * @short An area with normalized coordinates that contains a reference to an object. * * These areas ("rects") contain a pointer to a document object * (such as a hyperlink, an action, or something like that). * The pointer is read and stored as 'void pointer' so cast is * performed by accessors based on the value returned by objectType(). Objects * are reparented to this class. * * Type / Class correspondence tab: * - Action : class Action: description of an action * - Image : class Image : description of an image (n/a) * - Annotation: class Annotation: description of an annotation * * For more information about the normalized coordinate system, see NormalizedPoint. * * @see NormalizedPoint */ class OKULARCORE_EXPORT ObjectRect { public: /** * Describes the type of storable object. */ enum ObjectType { Action, ///< An action Image, ///< An image OAnnotation, ///< An annotation SourceRef ///< A source reference }; /** * Creates a new object rectangle. * * @param left The left coordinate of the rectangle. * @param top The top coordinate of the rectangle. * @param right The right coordinate of the rectangle. * @param bottom The bottom coordinate of the rectangle. * @param ellipse If true the rectangle describes an ellipse. * @param type The type of the storable object @see ObjectType. * @param object The pointer to the storable object. */ ObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object ); /** * This is an overloaded member function, provided for convenience. */ ObjectRect( const NormalizedRect &rect, bool ellipse, ObjectType type, void *object ); /** * This is an overloaded member function, provided for convenience. */ ObjectRect( const QPolygonF &poly, ObjectType type, void *object ); /** * Destroys the object rectangle. */ virtual ~ObjectRect(); /** * Returns the object type of the object rectangle. * @see ObjectType */ ObjectType objectType() const; /** * Returns the storable object of the object rectangle. */ const void *object() const; /** * Returns the region that is covered by the object rectangle. */ const QPainterPath ®ion() const; /** * Returns the bounding rect of the object rectangle for the * scaling factor @p xScale and @p yScale. */ virtual QRect boundingRect( double xScale, double yScale ) const; /** * Returns whether the object rectangle contains the point with absolute coordinates * (@p x, @p y) at a page size of @p xScale x @p yScale. */ virtual bool contains( double x, double y, double xScale, double yScale ) const; /** * Transforms the object rectangle with the operations defined by @p matrix. */ virtual void transform( const QTransform &matrix ); /** * Returns the squared distance between the object * and the point with * normalized coordinates (@p x, @p y) * at a page size of @p xScale x @p yScale. * * @since 0.8.2 (KDE 4.2.2) */ // FIXME this should most probably be a virtual method double distanceSqr( double x, double y, double xScale, double yScale ) const; protected: ObjectType m_objectType; void * m_object; QPainterPath m_path; QPainterPath m_transformedPath; }; /** * This class describes the object rectangle for an annotation. */ class OKULARCORE_EXPORT AnnotationObjectRect : public ObjectRect { public: /** * Creates a new annotation object rectangle with the * given @p annotation. */ explicit AnnotationObjectRect( Annotation *annotation ); /** * Destroys the annotation object rectangle. */ virtual ~AnnotationObjectRect(); /** * Returns the annotation object of the annotation object rectangle. */ Annotation *annotation() const; /** * Returns the bounding rect of the annotation object rectangle for the * scaling factor @p xScale and @p yScale. */ QRect boundingRect( double xScale, double yScale ) const override; /** * Returns whether the annotation object rectangle contains the point @p x, @p y for the * scaling factor @p xScale and @p yScale. */ bool contains( double x, double y, double xScale, double yScale ) const override; /** * Transforms the annotation object rectangle with the operations defined by @p matrix. */ void transform( const QTransform &matrix ) override; private: Annotation * m_annotation; }; /** * This class describes the object rectangle for a source reference. */ class OKULARCORE_EXPORT SourceRefObjectRect : public ObjectRect { friend class ObjectRect; public: /** * Creates a new source reference object rectangle. * * @param point The point of the source reference. * @param reference The storable source reference object. */ SourceRefObjectRect( const NormalizedPoint& point, void *reference ); /** * Returns the bounding rect of the source reference object rectangle for the * scaling factor @p xScale and @p yScale. */ QRect boundingRect( double xScale, double yScale ) const override; /** * Returns whether the source reference object rectangle contains the point @p x, @p y for the * scaling factor @p xScale and @p yScale. */ bool contains( double x, double y, double xScale, double yScale ) const override; private: NormalizedPoint m_point; }; /** * This class is an object rect that doesn't own the given pointer, i.e. won't delete it on destruction * @since 1.7 */ class OKULARCORE_EXPORT NonOwningObjectRect : public ObjectRect { public: NonOwningObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object ); ~NonOwningObjectRect(); }; /// @cond PRIVATE /** @internal */ /** @internal */ template T* givePtr( T& t ) { return &t; } /** @internal */ template T& deref( T& t ) { return t; } /// @endcond /** * @short An area with normalized coordinates, consisting of NormalizedShape objects. * * This is a template class to describe an area which consists of * multiple shapes of the same type, intersecting or non-intersecting. * The coordinates are normalized, and can be mapped to a reference area of defined size. * For more information about the normalized coordinate system, see NormalizedPoint. * * Class NormalizedShape \b must have the following functions/operators defined: * - bool contains( double, double ), whether it contains the given NormalizedPoint * - bool intersects( NormalizedShape ) * - bool isNull() * - Shape geometry( int, int ), which maps to the reference area * - operator|=( NormalizedShape ), which unites two NormalizedShape's * * @see RegularAreaRect, NormalizedPoint */ template class RegularArea : public QList { public: /** * Returns whether this area contains the normalized point (@p x, @p y). */ bool contains( double x, double y ) const; /** * Returns whether this area contains a NormalizedShape object that equals @p shape. * * @note * The original NormalizedShape objects can be lost if simplify() was called. */ bool contains( const NormalizedShape& shape ) const; /** * Returns whether this area intersects with the given @p area. */ bool intersects( const RegularArea *area ) const; /** * Returns whether the regular area intersects with the given @p shape. */ bool intersects( const NormalizedShape& shape ) const; /** * Appends the given @p area to this area. */ void appendArea( const RegularArea *area ); /** * Appends the given @p shape to this area. */ void appendShape( const NormalizedShape& shape, MergeSide side = MergeAll ); /** * Simplifies this regular area by merging its intersecting subareas. * This might change the effective geometry of this area. */ void simplify(); /** * Returns whether the regular area is a null area. */ bool isNull() const; /** * Returns the subareas of this regular area * mapped to a reference area of size @p xScale x @p yScale, * then translated by @p dx and @p dy. */ QList geometry( int xScale, int yScale, int dx = 0, int dy = 0 ) const; /** * Transforms the regular area with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); }; template void RegularArea::simplify() { #ifdef DEBUG_REGULARAREA int prev_end = this->count(); #endif int end = this->count() - 1, x = 0; for ( int i = 0; i < end; ++i ) { if ( givePtr( (*this)[x] )->intersects( deref( (*this)[i+1] ) ) ) { deref((*this)[x]) |= deref((*this)[i+1]); this->removeAt( i + 1 ); --end; --i; } else { x=i+1; } } #ifdef DEBUG_REGULARAREA qCDebug(OkularCoreDebug) << "from" << prev_end << "to" << this->count(); #endif } template bool RegularArea::isNull() const { if ( this->isEmpty() ) return true; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( !givePtr( *it )->isNull() ) return false; return true; } template bool RegularArea::intersects( const NormalizedShape& rect ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( !givePtr( *it )->isNull() && givePtr( *it )->intersects( rect ) ) return true; return false; } template bool RegularArea::intersects( const RegularArea *area ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) { typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); for ( ; areaIt != areaItEnd; ++areaIt ) { if ( !( *it ).isNull() && ( *it ).intersects( *areaIt ) ) return true; } } return false; } template void RegularArea::appendArea( const RegularArea *area ) { typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); for ( ; areaIt != areaItEnd; ++areaIt ) this->append( *areaIt ); } template void RegularArea::appendShape( const NormalizedShape& shape, MergeSide side ) { int size = this->count(); // if the list is empty, adds the shape normally if ( size == 0 ) { this->append( shape ); } else { bool intersection = false; NormalizedShape& last = (*this)[size - 1]; #define O_LAST givePtr( last ) # define O_LAST_R O_LAST->right # define O_LAST_L O_LAST->left # define O_LAST_T O_LAST->top # define O_LAST_B O_LAST->bottom #define O_NEW givePtr( shape ) # define O_NEW_R O_NEW->right # define O_NEW_L O_NEW->left # define O_NEW_T O_NEW->top # define O_NEW_B O_NEW->bottom switch ( side ) { case MergeRight: intersection = ( O_LAST_R >= O_NEW_L ) && ( O_LAST_L <= O_NEW_R ) && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); break; case MergeBottom: intersection = ( O_LAST_B >= O_NEW_T ) && ( O_LAST_T <= O_NEW_B ) && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); break; case MergeLeft: intersection = ( O_LAST_L <= O_NEW_R ) && ( O_LAST_R >= O_NEW_L ) && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); break; case MergeTop: intersection = ( O_LAST_T <= O_NEW_B ) && ( O_LAST_B >= O_NEW_T ) && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); break; case MergeAll: intersection = O_LAST->intersects( shape ); break; } #undef O_LAST # undef O_LAST_R # undef O_LAST_L # undef O_LAST_T # undef O_LAST_B #undef O_NEW # undef O_NEW_R # undef O_NEW_L # undef O_NEW_T # undef O_NEW_B // if the new shape intersects with the last shape in the list, then // merge it with that and delete the shape if ( intersection ) { deref((*this)[size - 1]) |= deref( shape ); } else this->append( shape ); } } template bool RegularArea::contains( double x, double y ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( ( *it ).contains( x, y ) ) return true; return false; } template bool RegularArea::contains( const NormalizedShape& shape ) const { if ( this->isEmpty() ) return false; return QList::contains( shape ); } template QList RegularArea::geometry( int xScale, int yScale, int dx, int dy ) const { if ( this->isEmpty() ) return QList(); QList ret; Shape t; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) { t = givePtr( *it )->geometry( xScale, yScale ); t.translate( dx, dy ); ret.append( t ); } return ret; } template void RegularArea::transform( const QTransform &matrix ) { if ( this->isEmpty() ) return; for ( int i = 0; i < this->count(); ++i ) givePtr( (*this)[i] )->transform( matrix ); } /** * This is a list of NormalizedRect, to describe an area consisting of * multiple rectangles using normalized coordinates. * * This area can be mapped to a reference area, resulting in a list of QRects. * For more information about the normalized coordinate system, see NormalizedPoint. * * Okular uses this area e. g. to describe a text highlight area, * which consists of multiple, intersecting or non-intersecting rectangles. * * @see NormalizedRect, NormalizedPoint */ class OKULARCORE_EXPORT RegularAreaRect : public RegularArea< NormalizedRect, QRect > { public: RegularAreaRect(); RegularAreaRect( const RegularAreaRect& rar ); ~RegularAreaRect(); RegularAreaRect& operator=( const RegularAreaRect& rar ); private: class Private; Private * const d; }; /** * This class stores the geometry of a highlighting area in normalized coordinates, * together with highlighting specific information. */ class HighlightAreaRect : public RegularAreaRect { public: /** * Creates a new highlight area rect with the coordinates of * the given @p area. */ explicit HighlightAreaRect( const RegularAreaRect *area = nullptr ); /** * The search ID of the highlight owner. */ int s_id; /** * The color of the highlight. */ QColor color; }; } uint qHash(const Okular::NormalizedRect& r, uint seed = 0); #ifndef QT_NO_DEBUG_STREAM /** * Debug operator for normalized @p point. */ OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedPoint &point ); /** * Debug operator for normalized @p rect. */ OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedRect &rect ); #endif #endif diff --git a/core/script/event.cpp b/core/script/event.cpp index f4c55eab7..3efc6c341 100644 --- a/core/script/event.cpp +++ b/core/script/event.cpp @@ -1,267 +1,267 @@ /*************************************************************************** * Copyright (C) 2018 by Intevation GmbH * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include #include "event_p.h" #include "../form.h" using namespace Okular; class Event::Private { public: Private( EventType eventType ): m_target( nullptr ), m_targetPage( nullptr ), m_source( nullptr ), m_sourcePage( nullptr ), m_eventType( eventType ), m_returnCode( false ), m_shiftModifier( false ) { } void *m_target; Page *m_targetPage; FormField *m_source; Page *m_sourcePage; EventType m_eventType; QString m_targetName; QVariant m_value; bool m_returnCode; bool m_shiftModifier; }; Event::Event(): d( new Private( UnknownEvent ) ) { } Event::Event( EventType eventType ): d( new Private( eventType ) ) { } Event::EventType Event::eventType() const { return d->m_eventType; } QString Event::name() const { switch ( d->m_eventType ) { case ( FieldCalculate ): return QStringLiteral( "Calculate" ); case ( FieldFormat ): return QStringLiteral( "Format" ); case ( FieldKeystroke ): - return QStringLiteral( "Keystroke" ); + return QStringLiteral( "Keystroke" ); case ( FieldFocus ): return QStringLiteral( "Focus" ); case ( FieldValidate ): return QStringLiteral( "Validate" ); case ( UnknownEvent ): default: return QStringLiteral( "Unknown" ); } } QString Event::type() const { switch ( d->m_eventType ) { case ( FieldCalculate ): case ( FieldFormat ): case ( FieldKeystroke ): case ( FieldFocus ): case ( FieldValidate ): return QStringLiteral( "Field" ); case ( UnknownEvent ): default: return QStringLiteral( "Unknown" ); } } QString Event::targetName() const { if ( !d->m_targetName.isNull() ) { return d->m_targetName; } return QStringLiteral( "JavaScript for: " ) + type() + name(); } void Event::setTargetName( const QString &val ) { d->m_targetName = val; } FormField *Event::source() const { return d->m_source; } void Event::setSource( FormField *val ) { d->m_source = val; } Page *Event::sourcePage() const { return d->m_sourcePage; } void Event::setSourcePage( Page *val ) { d->m_sourcePage = val; } void *Event::target() const { return d->m_target; } void Event::setTarget( void *target ) { d->m_target = target; } Page *Event::targetPage() const { return d->m_targetPage; } void Event::setTargetPage( Page *val ) { d->m_targetPage = val; } QVariant Event::value() const { return d->m_value; } void Event::setValue( const QVariant &val ) { d->m_value = val; } bool Event::returnCode() const { return d->m_returnCode; } void Event::setReturnCode( bool returnCode ) { d->m_returnCode = returnCode; } bool Event::shiftModifier() const { return d->m_shiftModifier; } void Event::setShiftModifier( bool shiftModifier ) { d->m_shiftModifier = shiftModifier; } // static std::shared_ptr Event::createFormCalculateEvent( FormField *target, Page *targetPage, FormField *source, Page *sourcePage, const QString &targetName ) { std::shared_ptr ret( new Event( Event::FieldCalculate ) ); ret->setSource( source ); ret->setSourcePage( sourcePage ); ret->setTarget( target ); ret->setTargetPage( targetPage ); ret->setTargetName( targetName ); FormFieldText *fft = dynamic_cast< FormFieldText * >(target); if ( fft ) { ret->setValue( QVariant( fft->text() ) ); } return ret; } // static std::shared_ptr Event::createFormatEvent( FormField *target, Page *targetPage, const QString &targetName ) { std::shared_ptr ret( new Event( Event::FieldFormat ) ); ret->setTarget( target ); ret->setTargetPage( targetPage ); ret->setTargetName( targetName ); FormFieldText *fft = dynamic_cast< FormFieldText * >(target); if ( fft ) { ret->setValue( QVariant( fft->text() ) ); } return ret; } // static std::shared_ptr Event::createKeystrokeEvent( FormField *target, Page *targetPage ) { std::shared_ptr ret( new Event( Event::FieldKeystroke ) ); ret->setTarget( target ); ret->setTargetPage( targetPage ); FormFieldText *fft = dynamic_cast< FormFieldText * >(target); if ( fft ) { ret->setReturnCode( true ); ret->setValue( QVariant( fft->text() ) ); } return ret; } std::shared_ptr Event::createFormFocusEvent( FormField *target, Page *targetPage, const QString &targetName ) { std::shared_ptr ret( new Event( Event::FieldFocus ) ); ret->setTarget( target ); ret->setTargetPage( targetPage ); ret->setTargetName( targetName ); ret->setShiftModifier( QApplication::keyboardModifiers() & Qt::ShiftModifier ); FormFieldText *fft = dynamic_cast< FormFieldText * >(target); if ( fft ) { ret->setValue( QVariant( fft->text() ) ); } return ret; } std::shared_ptr Event::createFormValidateEvent( FormField *target, Page *targetPage, const QString &targetName ) { std::shared_ptr ret( new Event( Event::FieldValidate ) ); ret->setTarget( target ); ret->setTargetPage( targetPage ); ret->setTargetName( targetName ); ret->setShiftModifier( QApplication::keyboardModifiers() & Qt::ShiftModifier ); FormFieldText *fft = dynamic_cast< FormFieldText * >(target); if ( fft ) { ret->setValue( QVariant( fft->text() ) ); ret->setReturnCode( true ); } return ret; -} \ No newline at end of file +} diff --git a/core/script/event_p.h b/core/script/event_p.h index 5e59766c4..420518e4c 100644 --- a/core/script/event_p.h +++ b/core/script/event_p.h @@ -1,132 +1,132 @@ /*************************************************************************** * Copyright (C) 2018 by Intevation GmbH * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef OKULAR_SCRIPT_EVENT_P_H #define OKULAR_SCRIPT_EVENT_P_H #include #include #include namespace Okular { class FormField; class Page; /** * @short A JavaScript Event Object data container. * * Object to represet a JavaScript Event Object as described in the * Acrobat JavaScript Scripting Reference. * * The implementation is currently limited. To implement support * for a new event create the according data fields / getters * and setters and update the handling in kjs_event * accordingly. * * See Acrobat JavaScript Scripting Reference for the meaning * the fields and add getter / setter according for the * event you wish to implement. */ class Event { private: Event(); public: enum EventType { UnknownEvent, /// < Unknown AppInit, /// < Not implemented. BatchExec, /// < Not implemented. BookmarkMouseUp, /// < Not implemented. ConsoleExec, /// < Not implemented. DocDidPrint, /// < Not implemented. DocDidSave, /// < Not implemented. DocOpen, /// < Not implemented. DocWillClose, /// < Not implemented. DocWillPrint, /// < Not implemented. DocWillSave, /// < Not implemented. ExternalExec, /// < Not implemented. FieldBlur, /// < Not implemented. FieldCalculate, /// < This event is defined in a field re-calculation. FieldFocus, /// < This event is defined when the field gains or loses focus. FieldFormat, /// < When a format action is executed FieldKeystroke, /// < Checks if the entered value is valid. FieldMouseDown, /// < Not implemented. FieldMouseEnter, /// < Not implemented. FieldMouseExit, /// < Not implemented. FieldMouseUp, /// < Not implemented. - /* Validates the field after every change is commited + /* Validates the field after every change is committed * (clicked outside or tabbed to another field). * The enter event is not handled */ FieldValidate, LinkMouseUp, /// < Not implemented. MenuExec, /// < Not implemented. PageOpen, /// < Not implemented. PageClose, /// < Not implemented. }; explicit Event(EventType type); /** One of the defined EventTypes */ EventType eventType() const; QString name() const; QString type() const; QString targetName() const; void setTargetName( const QString &val ); Page *targetPage() const; void setTargetPage( Page *val ); FormField *source() const; void setSource( FormField *val ); Page *sourcePage() const; void setSourcePage( Page *val ); void *target() const; void setTarget( void *target ); QVariant value() const; void setValue(const QVariant &val); bool returnCode() const; void setReturnCode(bool returnCode); // Checks if the shift key was down when creating the event. bool shiftModifier() const; void setShiftModifier(bool shiftModifier); static std::shared_ptr createFormCalculateEvent( FormField *target, Page *targetPage, FormField *source = nullptr, Page *sourcePage = nullptr, const QString &targetName = QString() ); static std::shared_ptr createFormatEvent( FormField *target, Page *targetPage, const QString &targetName = QString() ); static std::shared_ptr createKeystrokeEvent( FormField *target, Page *targetPage ); static std::shared_ptr createFormFocusEvent( FormField *target, Page *targetPage, const QString &targetName = QString() ); static std::shared_ptr createFormValidateEvent( FormField *target, Page *targetPage, const QString &targetName = QString() ); private: class Private; std::shared_ptr d; Q_DISABLE_COPY( Event ) }; } // namespace Okular #endif //OKULAR_SCRIPT_EVENT_P_H diff --git a/core/signatureutils.h b/core/signatureutils.h index c102c2555..a301b8a10 100644 --- a/core/signatureutils.h +++ b/core/signatureutils.h @@ -1,277 +1,277 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef OKULAR_SIGNATUREUTILS_H #define OKULAR_SIGNATUREUTILS_H #include "okularcore_export.h" #include #include #include #include #include namespace Okular { class CertificateInfoPrivate; class SignatureInfoPrivate; /** * @short A helper class to store information about x509 certificate */ class OKULARCORE_EXPORT CertificateInfo { public: /** * The algorithm of public key. */ enum PublicKeyType { RsaKey, DsaKey, EcKey, OtherKey }; /** * Certificate key usage extensions. */ enum KeyUsageExtension { KuDigitalSignature = 0x80, KuNonRepudiation = 0x40, KuKeyEncipherment = 0x20, KuDataEncipherment = 0x10, KuKeyAgreement = 0x08, KuKeyCertSign = 0x04, KuClrSign = 0x02, KuEncipherOnly = 0x01, KuNone = 0x00 }; Q_DECLARE_FLAGS( KeyUsageExtensions, KeyUsageExtension ) /** * Predefined keys for elements in an entity's distinguished name. */ enum EntityInfoKey { CommonName, DistinguishedName, EmailAddress, Organization, }; /** * Destructor */ virtual ~CertificateInfo(); /** * Returns true if certificate has no contents; otherwise returns false. */ virtual bool isNull() const; /** * The certificate version string. */ virtual int version() const; /** * The certificate serial number. */ virtual QByteArray serialNumber() const; /** * Information about the issuer. */ virtual QString issuerInfo(EntityInfoKey key) const; /** * Information about the subject */ virtual QString subjectInfo(EntityInfoKey key) const; /** * The date-time when certificate becomes valid. */ virtual QDateTime validityStart() const; /** * The date-time when certificate expires. */ virtual QDateTime validityEnd() const; /** * The uses allowed for the certificate. */ virtual KeyUsageExtensions keyUsageExtensions() const; /** * The public key value. */ virtual QByteArray publicKey() const; /** * The public key type. */ virtual PublicKeyType publicKeyType() const; /** * The strength of public key in bits. */ virtual int publicKeyStrength() const; /** * Returns true if certificate is self-signed otherwise returns false. */ virtual bool isSelfSigned() const; /** * The DER encoded certificate. */ virtual QByteArray certificateData() const; protected: friend class SignatureInfo; CertificateInfo(); private: Q_DISABLE_COPY( CertificateInfo ) }; /** * @short A helper class to store information about digital signature */ class OKULARCORE_EXPORT SignatureInfo { public: /** * The verification result of the signature. */ enum SignatureStatus { SignatureStatusUnknown, ///< The signature status is unknown for some reason. SignatureValid, ///< The signature is cryptographically valid. SignatureInvalid, ///< The signature is cryptographically invalid. SignatureDigestMismatch, ///< The document content was changed after the signature was applied. SignatureDecodingError, ///< The signature CMS/PKCS7 structure is malformed. SignatureGenericError, ///< The signature could not be verified. SignatureNotFound, ///< The requested signature is not present in the document. SignatureNotVerified ///< The signature is not yet verified. }; /** * The verification result of the certificate. */ enum CertificateStatus { CertificateStatusUnknown, ///< The certificate status is unknown for some reason. CertificateTrusted, ///< The certificate is considered trusted. CertificateUntrustedIssuer, ///< The issuer of this certificate has been marked as untrusted by the user. CertificateUnknownIssuer, ///< The certificate trust chain has not finished in a trusted root certificate. CertificateRevoked, ///< The certificate was revoked by the issuing certificate authority. CertificateExpired, ///< The signing time is outside the validity bounds of this certificate. CertificateGenericError, ///< The certificate could not be verified. CertificateNotVerified ///< The certificate is not yet verified. }; /** * The hash algorithm of the signature */ enum HashAlgorithm { HashAlgorithmUnknown, HashAlgorithmMd2, HashAlgorithmMd5, HashAlgorithmSha1, HashAlgorithmSha256, HashAlgorithmSha384, HashAlgorithmSha512, HashAlgorithmSha224 }; /** * Destructor. */ virtual ~SignatureInfo(); /** * The signature status of the signature. */ virtual SignatureStatus signatureStatus() const; /** * The certificate status of the signature. */ virtual CertificateStatus certificateStatus() const; /** * The signer subject common name associated with the signature. */ virtual QString signerName() const; /** * The signer subject distinguished name associated with the signature. */ virtual QString signerSubjectDN() const; /** * Get signing location. */ virtual QString location() const; /** * Get signing reason. */ virtual QString reason() const; /** - * The the hash algorithm used for the signature. + * The hash algorithm used for the signature. */ virtual HashAlgorithm hashAlgorithm() const; /** * The signing time associated with the signature. */ virtual QDateTime signingTime() const; /** * Get the signature binary data. */ virtual QByteArray signature() const; /** * Get the bounds of the ranges of the document which are signed. */ virtual QList signedRangeBounds() const; /** * Checks whether the signature authenticates the total document * except for the signature itself. */ virtual bool signsTotalDocument() const; /** * Get certificate details. */ virtual const CertificateInfo &certificateInfo() const; protected: SignatureInfo(); private: Q_DISABLE_COPY( SignatureInfo ) }; } #endif