Merge branch 'master' into mart/okularActive

This commit is contained in:
Marco Martin 2012-10-01 13:26:34 +02:00
commit 5bcf1e8f35
131 changed files with 2591 additions and 1276 deletions

View file

@ -121,7 +121,7 @@ ENDIF(APPLE)
target_link_libraries(okularcore ${OKULAR_IOKIT} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBRARY} ${KDE4_KJSAPI_LIBRARY} ${MATH_LIB} ${KDE4_THREADWEAVER_LIBRARY} )
set_target_properties(okularcore PROPERTIES VERSION 1.8.0 SOVERSION 1 )
set_target_properties(okularcore PROPERTIES VERSION 2.0.0 SOVERSION 2 )
install(TARGETS okularcore ${INSTALL_TARGETS_DEFAULT_ARGS} )
@ -170,6 +170,7 @@ set(okularpart_SRCS
ui/searchwidget.cpp
ui/sidebar.cpp
ui/side_reviews.cpp
ui/snapshottaker.cpp
ui/thumbnaillist.cpp
ui/toc.cpp
ui/tocmodel.cpp

1
TODO
View file

@ -102,7 +102,6 @@ More items (first items will enter 'In progress list' first):
-> add okular manual in PDF format loaded on the first startup or on menu->help->manual
this visually explains basic usage, mouse buttons functions & more..
-> ADD: click over image allows "save image" [60% done (activerect of type image)]
-> zoom: fit text (with configurable margin)
-> bookview: 3d opengl widget for viewing the document as a real book (turning pages, etc..)
-> wallet: use asynchronous interface (to prevent ui-blocking)
-> restore a location from a given url (like http:/someurl?stringForViewport) (BR99240)

View file

@ -1 +1 @@
okular v0.14.80
okular v0.15.70

View file

@ -39,6 +39,7 @@ inline KAboutData okularAboutData( const char* name, const char* iname )
about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
about.addCredit(ki18n("Eugene Trounev"), ki18n("Annotations artwork"), "eugene.trounev@gmail.com");
about.addCredit(ki18n("Jiri Baum - NICTA"), ki18n("Table selection tool"), "jiri@baum.com.au");
about.addCredit(ki18n("Fabio D'Urso"), ki18n("Annotation improvements"), "fabiodurso@hotmail.it");
return about;
}

View file

@ -97,17 +97,34 @@ int main()
}
" HAVE_POPPLER_0_20)
check_cxx_source_compiles("
#include <poppler-qt4.h>
#include <poppler-annotation.h>
int main()
{
Poppler::MovieObject *movie = 0;
movie->showPosterImage();
const Poppler::Annotation::AdditionalActionType type = Poppler::Annotation::PageOpeningAction;
return 0;
}
" HAVE_POPPLER_0_22)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
if (HAVE_POPPLER_0_20)
if (HAVE_POPPLER_0_22)
set(popplerVersionMessage "0.22")
elseif (HAVE_POPPLER_0_20)
set(popplerVersionMessage "0.20")
elseif (HAVE_POPPLER_0_16)
set(popplerVersionMessage "0.16")
elseif (HAVE_POPPLER_0_12_1)
set(popplerVersionMessage "0.12.1")
else (HAVE_POPPLER_0_20)
else (HAVE_POPPLER_0_22)
set(popplerVersionMessage "0.5.4")
endif (HAVE_POPPLER_0_20)
endif (HAVE_POPPLER_0_22)
if (NOT Poppler_FIND_QUIETLY)
message(STATUS "Found Poppler-Qt4: ${POPPLER_LIBRARY}, (>= ${popplerVersionMessage})")
endif (NOT Poppler_FIND_QUIETLY)

View file

@ -61,10 +61,71 @@
<item>
<widget class="QCheckBox" name="kcfg_DisplayDocumentTitle">
<property name="text">
<string>Display document title in title bar</string>
<string>Display document title in title bar if available</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>When not displaying document title:</string>
</property>
</widget>
</item>
<item>
<widget class="KButtonGroup" name="kcfg_DisplayDocumentNameOrPath">
<property name="styleSheet">
<string notr="true">KButtonGroup {border:0; }</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="current" stdset="0">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="radioFileName">
<property name="text">
<string>Display file name only</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioFilePath">
<property name="text">
<string>Display full file path</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
</layout>
</item>
</layout>
</item>
<item>
@ -313,6 +374,12 @@ For files which were opened before the previous zoom is applied.</string>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KButtonGroup</class>
<extends>QGroupBox</extends>
<header>kbuttongroup.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KIntSpinBox</class>
<extends>QSpinBox</extends>

View file

@ -52,13 +52,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_EnableThreading">
<property name="text">
<string>Enable &amp;background generation</string>
</property>
</widget>
</item>
</layout>
</item>
<item>

View file

@ -65,9 +65,6 @@
<entry key="EnableCompositing" type="Bool" >
<default>true</default>
</entry>
<entry key="EnableThreading" type="Bool" >
<default>true</default>
</entry>
<entry key="TextAntialias" type="Enum" >
<default>Enabled</default>
<choices>
@ -167,6 +164,13 @@
<entry key="DisplayDocumentTitle" type="Bool" >
<default>true</default>
</entry>
<entry key="DisplayDocumentNameOrPath" type="Enum" >
<default>Name</default>
<choices>
<choice name="Name" />
<choice name="Path" />
</choices>
</entry>
<entry key="UseKTTSD" type="Bool" />
<entry key="WatchFile" type="Bool" >
<default>true</default>

View file

@ -15,6 +15,7 @@
#include <QtGui/QColor>
// local includes
#include "action.h"
#include "document.h"
#include "document_p.h"
#include "movie.h"
@ -849,18 +850,18 @@ void Annotation::store( QDomNode & annNode, QDomDocument & document ) const
}
}
void AnnotationPrivate::annotationTransform( const QMatrix &matrix )
void AnnotationPrivate::annotationTransform( const QTransform &matrix )
{
resetTransformation();
transform( matrix );
}
void AnnotationPrivate::transform( const QMatrix &matrix )
void AnnotationPrivate::transform( const QTransform &matrix )
{
m_transformedBoundary.transform( matrix );
}
void AnnotationPrivate::baseTransform( const QMatrix &matrix )
void AnnotationPrivate::baseTransform( const QTransform &matrix )
{
m_boundary.transform( matrix );
}
@ -893,13 +894,13 @@ class Okular::TextAnnotationPrivate : public Okular::AnnotationPrivate
public:
TextAnnotationPrivate()
: AnnotationPrivate(), m_textType( TextAnnotation::Linked ),
m_textIcon( "Note" ), m_inplaceAlign( 0 ),
m_textIcon( "Comment" ), m_inplaceAlign( 0 ),
m_inplaceIntent( TextAnnotation::Unknown )
{
}
virtual void transform( const QMatrix &matrix );
virtual void baseTransform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
virtual void baseTransform( const QTransform &matrix );
virtual void resetTransformation();
virtual void translate( const NormalizedPoint &coord );
virtual bool openDialogAfterCreation() const;
@ -1098,7 +1099,7 @@ void TextAnnotation::store( QDomNode & node, QDomDocument & document ) const
// store the optional attributes
if ( d->m_textType != Linked )
textElement.setAttribute( "type", (int)d->m_textType );
if ( d->m_textIcon != "Comment" )
if ( !d->m_textIcon.isEmpty() )
textElement.setAttribute( "icon", d->m_textIcon );
if ( d->m_textFont != QApplication::font() )
textElement.setAttribute( "font", d->m_textFont.toString() );
@ -1130,7 +1131,7 @@ void TextAnnotation::store( QDomNode & node, QDomDocument & document ) const
}
}
void TextAnnotationPrivate::transform( const QMatrix &matrix )
void TextAnnotationPrivate::transform( const QTransform &matrix )
{
AnnotationPrivate::transform( matrix );
@ -1139,7 +1140,7 @@ void TextAnnotationPrivate::transform( const QMatrix &matrix )
}
}
void TextAnnotationPrivate::baseTransform( const QMatrix &matrix )
void TextAnnotationPrivate::baseTransform( const QTransform &matrix )
{
AnnotationPrivate::baseTransform( matrix );
@ -1190,8 +1191,8 @@ class Okular::LineAnnotationPrivate : public Okular::AnnotationPrivate
{
}
virtual void transform( const QMatrix &matrix );
virtual void baseTransform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
virtual void baseTransform( const QTransform &matrix );
virtual void resetTransformation();
virtual void translate( const NormalizedPoint &coord );
@ -1434,7 +1435,7 @@ void LineAnnotation::store( QDomNode & node, QDomDocument & document ) const
}
}
void LineAnnotationPrivate::transform( const QMatrix &matrix )
void LineAnnotationPrivate::transform( const QTransform &matrix )
{
AnnotationPrivate::transform( matrix );
@ -1443,7 +1444,7 @@ void LineAnnotationPrivate::transform( const QMatrix &matrix )
it.next().transform( matrix );
}
void LineAnnotationPrivate::baseTransform( const QMatrix &matrix )
void LineAnnotationPrivate::baseTransform( const QTransform &matrix )
{
AnnotationPrivate::baseTransform( matrix );
@ -1546,18 +1547,6 @@ QColor GeomAnnotation::geometricalInnerColor() const
return d->m_geomInnerColor;
}
void GeomAnnotation::setGeometricalPointWidth( int width )
{
Q_D( GeomAnnotation );
d->m_style.setWidth( width );
}
int GeomAnnotation::geometricalPointWidth() const
{
Q_D( const GeomAnnotation );
return static_cast< int >( d->m_style.width() );
}
Annotation::SubType GeomAnnotation::subType() const
{
return AGeom;
@ -1674,7 +1663,7 @@ double HighlightAnnotation::Quad::feather() const
return d->m_feather;
}
void HighlightAnnotation::Quad::transform( const QMatrix &matrix )
void HighlightAnnotation::Quad::transform( const QTransform &matrix )
{
for ( int i = 0; i < 4; ++i ) {
d->m_transformedPoints[ i ] = d->m_points[ i ];
@ -1691,8 +1680,8 @@ class Okular::HighlightAnnotationPrivate : public Okular::AnnotationPrivate
{
}
virtual void transform( const QMatrix &matrix );
virtual void baseTransform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
virtual void baseTransform( const QTransform &matrix );
HighlightAnnotation::HighlightType m_highlightType;
QList< HighlightAnnotation::Quad > m_highlightQuads;
@ -1737,7 +1726,7 @@ HighlightAnnotation::HighlightAnnotation( const QDomNode & node )
q.setCapEnd( qe.hasAttribute( "end" ) );
q.setFeather( qe.attribute( "feather", "0.1" ).toDouble() );
q.transform( QMatrix() );
q.transform( QTransform() );
d->m_highlightQuads.append( q );
}
@ -1812,7 +1801,7 @@ Annotation::SubType HighlightAnnotation::subType() const
return AHighlight;
}
void HighlightAnnotationPrivate::transform( const QMatrix &matrix )
void HighlightAnnotationPrivate::transform( const QTransform &matrix )
{
AnnotationPrivate::transform( matrix );
@ -1821,7 +1810,7 @@ void HighlightAnnotationPrivate::transform( const QMatrix &matrix )
it.next().transform( matrix );
}
void HighlightAnnotationPrivate::baseTransform( const QMatrix &matrix )
void HighlightAnnotationPrivate::baseTransform( const QTransform &matrix )
{
AnnotationPrivate::baseTransform( matrix );
@ -1916,8 +1905,8 @@ class Okular::InkAnnotationPrivate : public Okular::AnnotationPrivate
{
}
virtual void transform( const QMatrix &matrix );
virtual void baseTransform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
virtual void baseTransform( const QTransform &matrix );
virtual void resetTransformation();
virtual void translate( const NormalizedPoint &coord );
@ -2041,7 +2030,7 @@ void InkAnnotation::store( QDomNode & node, QDomDocument & document ) const
}
}
void InkAnnotationPrivate::transform( const QMatrix &matrix )
void InkAnnotationPrivate::transform( const QTransform &matrix )
{
AnnotationPrivate::transform( matrix );
@ -2053,7 +2042,7 @@ void InkAnnotationPrivate::transform( const QMatrix &matrix )
}
}
void InkAnnotationPrivate::baseTransform( const QMatrix &matrix )
void InkAnnotationPrivate::baseTransform( const QTransform &matrix )
{
AnnotationPrivate::baseTransform( matrix );
@ -2423,3 +2412,149 @@ void MovieAnnotation::setMovie( Movie *movie )
Q_D( MovieAnnotation );
d->movie = movie;
}
/** ScreenAnnotation [Annotation] */
class Okular::ScreenAnnotationPrivate : public Okular::AnnotationPrivate
{
public:
~ScreenAnnotationPrivate();
QMap< Okular::Annotation::AdditionalActionType, Okular::Action* > m_additionalActions;
};
ScreenAnnotationPrivate::~ScreenAnnotationPrivate()
{
qDeleteAll( m_additionalActions );
}
ScreenAnnotation::ScreenAnnotation()
: Annotation( *new ScreenAnnotationPrivate() )
{
}
ScreenAnnotation::ScreenAnnotation( const QDomNode & node )
: Annotation( *new ScreenAnnotationPrivate(), node )
{
// loop through the whole children looking for a 'screen' element
QDomNode subNode = node.firstChild();
while( subNode.isElement() )
{
QDomElement e = subNode.toElement();
subNode = subNode.nextSibling();
if ( e.tagName() != "screen" )
continue;
// loading complete
break;
}
}
ScreenAnnotation::~ScreenAnnotation()
{
}
void ScreenAnnotation::store( QDomNode & node, QDomDocument & document ) const
{
// recurse to parent objects storing properties
Annotation::store( node, document );
// create [screen] element
QDomElement movieElement = document.createElement( "screen" );
node.appendChild( movieElement );
}
Annotation::SubType ScreenAnnotation::subType() const
{
return AScreen;
}
void ScreenAnnotation::setAdditionalAction( AdditionalActionType type, Action *action )
{
Q_D( ScreenAnnotation );
if ( d->m_additionalActions.contains( type ) )
delete d->m_additionalActions.value( type );
d->m_additionalActions.insert( type, action );
}
Action* ScreenAnnotation::additionalAction( AdditionalActionType type ) const
{
Q_D( const ScreenAnnotation );
if ( !d->m_additionalActions.contains( type ) )
return 0;
else
return d->m_additionalActions.value( type );
}
/** WidgetAnnotation [Annotation] */
class Okular::WidgetAnnotationPrivate : public Okular::AnnotationPrivate
{
public:
~WidgetAnnotationPrivate();
QMap< Okular::Annotation::AdditionalActionType, Okular::Action* > m_additionalActions;
};
WidgetAnnotationPrivate::~WidgetAnnotationPrivate()
{
qDeleteAll( m_additionalActions );
}
WidgetAnnotation::WidgetAnnotation()
: Annotation( *new WidgetAnnotationPrivate() )
{
}
WidgetAnnotation::WidgetAnnotation( const QDomNode & node )
: Annotation( *new WidgetAnnotationPrivate(), node )
{
// loop through the whole children looking for a 'widget' element
QDomNode subNode = node.firstChild();
while( subNode.isElement() )
{
QDomElement e = subNode.toElement();
subNode = subNode.nextSibling();
if ( e.tagName() != "widget" )
continue;
// loading complete
break;
}
}
WidgetAnnotation::~WidgetAnnotation()
{
}
void WidgetAnnotation::store( QDomNode & node, QDomDocument & document ) const
{
// recurse to parent objects storing properties
Annotation::store( node, document );
// create [widget] element
QDomElement movieElement = document.createElement( "widget" );
node.appendChild( movieElement );
}
Annotation::SubType WidgetAnnotation::subType() const
{
return AWidget;
}
void WidgetAnnotation::setAdditionalAction( AdditionalActionType type, Action *action )
{
Q_D( WidgetAnnotation );
if ( d->m_additionalActions.contains( type ) )
delete d->m_additionalActions.value( type );
d->m_additionalActions.insert( type, action );
}
Action* WidgetAnnotation::additionalAction( AdditionalActionType type ) const
{
Q_D( const WidgetAnnotation );
if ( !d->m_additionalActions.contains( type ) )
return 0;
else
return d->m_additionalActions.value( type );
}

View file

@ -23,6 +23,7 @@
namespace Okular {
class Action;
class Annotation;
class AnnotationObjectRect;
class AnnotationPrivate;
@ -42,6 +43,8 @@ class CaretAnnotationPrivate;
class FileAttachmentAnnotationPrivate;
class SoundAnnotationPrivate;
class MovieAnnotationPrivate;
class ScreenAnnotationPrivate;
class WidgetAnnotationPrivate;
/**
* @short Helper class for (recursive) annotation retrieval/storage.
@ -83,9 +86,6 @@ class OKULAR_EXPORT AnnotationUtils
*
* An Annotation is an object (text note, highlight, sound, popup window, ..)
* contained by a Page in the document.
*
* For current state in relations to pdf embedded annotations:
* @see generator_pdf/README.Annotations
*/
class OKULAR_EXPORT Annotation
{
@ -112,6 +112,8 @@ class OKULAR_EXPORT Annotation
AFileAttachment = 9, ///< A file attachment annotation
ASound = 10, ///< A sound annotation
AMovie = 11, ///< A movie annotation
AScreen = 12, ///< A screen annotation
AWidget = 13, ///< A widget annotation
A_BASE = 0 ///< The annotation base class
};
@ -177,6 +179,17 @@ class OKULAR_EXPORT Annotation
Completed = 64 ///< Has been completed
};
/**
* Describes the type of additional actions.
*
* @since 0.16 (KDE 4.10)
*/
enum AdditionalActionType
{
PageOpening, ///< Performed when the page containing the annotation is opened.
PageClosing ///< Performed when the page containing the annotation is closed.
};
/**
* A function to be called when the annotation is destroyed.
*
@ -1050,16 +1063,6 @@ class OKULAR_EXPORT GeomAnnotation : public Annotation
*/
QColor geometricalInnerColor() const;
/**
* Sets the point @p width of the geometrical annotation.
*/
KDE_DEPRECATED void setGeometricalPointWidth( int width );
/**
* Returns the point width of the geometrical annotation.
*/
KDE_DEPRECATED int geometricalPointWidth() const;
/**
* Returns the sub type of the geometrical annotation.
*/
@ -1191,7 +1194,7 @@ class OKULAR_EXPORT HighlightAnnotation : public Annotation
* Transforms the quad coordinates with the transformation defined
* by @p matrix.
*/
void transform( const QMatrix &matrix );
void transform( const QTransform &matrix );
private:
class Private;
@ -1524,6 +1527,117 @@ class OKULAR_EXPORT MovieAnnotation : public Annotation
Q_DISABLE_COPY( MovieAnnotation )
};
/**
* \short Screen annotation.
*
* The screen annotation specifies a region of a page upon which media clips
* may be played. It also serves as an object from which actions can be triggered.
*
* @since 0.16 (KDE 4.10)
*/
class OKULAR_EXPORT ScreenAnnotation : public Annotation
{
public:
/**
* Creates a new screen annotation.
*/
ScreenAnnotation();
/**
* Creates a new screen annotation from the xml @p description
*/
ScreenAnnotation( const QDomNode &description );
/**
* Destroys the screen annotation.
*/
virtual ~ScreenAnnotation();
/**
* Returns the sub type of the screen annotation.
*/
SubType subType() const;
/**
* Stores the screen annotation as xml in @p document
* under the given @p parentNode.
*/
void store( QDomNode &parentNode, QDomDocument &document ) const;
/**
* Sets the additional @p action of the given @p type.
*
* @since 0.16 (KDE 4.10)
*/
void setAdditionalAction( AdditionalActionType type, Action *action );
/**
* Returns the additional action of the given @p type or @c 0 if no action has been defined.
*
* @since 0.16 (KDE 4.10)
*/
Action* additionalAction( AdditionalActionType type ) const;
private:
Q_DECLARE_PRIVATE( ScreenAnnotation )
Q_DISABLE_COPY( ScreenAnnotation )
};
/**
* \short Widget annotation.
*
* The widget annotation represents a widget on a page.
*
* @since 0.16 (KDE 4.10)
*/
class OKULAR_EXPORT WidgetAnnotation : public Annotation
{
public:
/**
* Creates a new widget annotation.
*/
WidgetAnnotation();
/**
* Creates a new widget annotation from the xml @p description
*/
WidgetAnnotation( const QDomNode &description );
/**
* Destroys the widget annotation.
*/
virtual ~WidgetAnnotation();
/**
* Returns the sub type of the widget annotation.
*/
SubType subType() const;
/**
* Stores the widget annotation as xml in @p document
* under the given @p parentNode.
*/
void store( QDomNode &parentNode, QDomDocument &document ) const;
/**
* Sets the additional @p action of the given @p type.
*
* @since 0.16 (KDE 4.10)
*/
void setAdditionalAction( AdditionalActionType type, Action *action );
/**
* Returns the additional action of the given @p type or @c 0 if no action has been defined.
*
* @since 0.16 (KDE 4.10)
*/
Action* additionalAction( AdditionalActionType type ) const;
private:
Q_DECLARE_PRIVATE( WidgetAnnotation )
Q_DISABLE_COPY( WidgetAnnotation )
};
}
#endif

View file

@ -19,7 +19,7 @@
#include <QtCore/QVariant>
#include <QtGui/QColor>
class QMatrix;
class QTransform;
namespace Okular {
@ -36,10 +36,10 @@ class AnnotationPrivate
* Transforms the annotation coordinates with the transformation
* defined by @p matrix.
*/
void annotationTransform( const QMatrix &matrix );
void annotationTransform( const QTransform &matrix );
virtual void transform( const QMatrix &matrix );
virtual void baseTransform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
virtual void baseTransform( const QTransform &matrix );
virtual void resetTransformation();
virtual void translate( const NormalizedPoint &coord );
virtual bool openDialogAfterCreation() const;

View file

@ -40,7 +40,7 @@ NormalizedPoint& NormalizedPoint::operator=( const NormalizedPoint & p )
return *this;
}
void NormalizedPoint::transform( const QMatrix &matrix )
void NormalizedPoint::transform( const QTransform &matrix )
{
qreal tmp_x = (qreal)x;
qreal tmp_y = (qreal)y;
@ -190,7 +190,7 @@ QRect NormalizedRect::roundedGeometry( int xScale, int yScale ) const
return QRect( l, t, r - l + 1, b - t + 1 );
}
void NormalizedRect::transform( const QMatrix &matrix )
void NormalizedRect::transform( const QTransform &matrix )
{
QRectF rect( left, top, right - left, bottom - top );
rect = matrix.mapRect( rect );
@ -305,7 +305,7 @@ bool ObjectRect::contains( double x, double y, double, double ) const
return m_transformedPath.contains( QPointF( x, y ) );
}
void ObjectRect::transform( const QMatrix &matrix )
void ObjectRect::transform( const QTransform &matrix )
{
m_transformedPath = matrix.map( m_path );
}
@ -385,7 +385,7 @@ AnnotationObjectRect::~AnnotationObjectRect()
m_object = 0;
}
void AnnotationObjectRect::transform( const QMatrix &matrix )
void AnnotationObjectRect::transform( const QTransform &matrix )
{
m_annotation->d_func()->annotationTransform( matrix );
}

View file

@ -13,6 +13,7 @@
#include <QtCore/QList>
#include <QtGui/QColor>
#include <QtGui/QPainterPath>
#include <QtGui/QTransform>
#include <kdebug.h>
#include "global.h"
@ -69,7 +70,7 @@ class OKULAR_EXPORT NormalizedPoint
/**
* Transforms the normalized point with the operations defined by @p matrix.
*/
void transform( const QMatrix &matrix );
void transform( const QTransform &matrix );
/**
* The normalized x coordinate.
@ -206,7 +207,7 @@ class OKULAR_EXPORT NormalizedRect
/**
* Transforms the normalized rectangle with the operations defined by @p matrix.
*/
void transform( const QMatrix &matrix );
void transform( const QTransform &matrix );
/**
* Returns true if the point pt is located to the bottom of the rectangle
@ -370,7 +371,7 @@ class OKULAR_EXPORT ObjectRect
/**
* Transforms the object rectangle with the operations defined by @p matrix.
*/
virtual void transform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
/**
* Returns the square of the distance between the object and the point @p x, @p y
@ -425,7 +426,7 @@ class OKULAR_EXPORT AnnotationObjectRect : public ObjectRect
/**
* Transforms the annotation object rectangle with the operations defined by @p matrix.
*/
virtual void transform( const QMatrix &matrix );
virtual void transform( const QTransform &matrix );
private:
Annotation * m_annotation;
@ -576,7 +577,7 @@ template <class NormalizedShape, class Shape> class RegularArea : public QList<
/**
* Transforms the regular area with the operations defined by @p matrix.
*/
void transform( const QMatrix &matrix );
void transform( const QTransform &matrix );
};
template <class NormalizedShape, class Shape>
@ -808,7 +809,7 @@ QList<Shape> RegularArea<NormalizedShape, Shape>::geometry( int xScale, int ySca
}
template <class NormalizedShape, class Shape>
void RegularArea<NormalizedShape, Shape>::transform( const QMatrix &matrix )
void RegularArea<NormalizedShape, Shape>::transform( const QTransform &matrix )
{
if ( !this )
return;

View file

@ -73,29 +73,12 @@ static inline bool documentViewportFuzzyCompare( const DocumentViewport &vp1, co
return true;
}
static inline bool documentViewportLessThan( const DocumentViewport &vp1, const DocumentViewport &vp2 )
{
if ( vp1.pageNumber != vp2.pageNumber )
return vp1.pageNumber < vp2.pageNumber;
if ( !vp1.rePos.enabled && vp2.rePos.enabled )
return true;
if ( !vp2.rePos.enabled )
return false;
if ( vp1.rePos.normalizedY != vp2.rePos.normalizedY )
return vp1.rePos.normalizedY < vp2.rePos.normalizedY;
return vp1.rePos.normalizedX < vp2.rePos.normalizedX;
}
static inline bool bookmarkLessThan( const KBookmark &b1, const KBookmark &b2 )
{
DocumentViewport vp1( b1.url().htmlRef() );
DocumentViewport vp2( b2.url().htmlRef() );
return documentViewportLessThan( vp1, vp2 );
return vp1 < vp2;
}
static inline bool okularBookmarkActionLessThan( QAction * a1, QAction * a2 )
@ -103,7 +86,7 @@ static inline bool okularBookmarkActionLessThan( QAction * a1, QAction * a2 )
DocumentViewport vp1( static_cast< OkularBookmarkAction * >( a1 )->htmlRef() );
DocumentViewport vp2( static_cast< OkularBookmarkAction * >( a2 )->htmlRef() );
return documentViewportLessThan( vp1, vp2 );
return vp1 < vp2;
}
class BookmarkManager::Private : public KBookmarkOwner
@ -724,7 +707,7 @@ KBookmark BookmarkManager::nextBookmark( const DocumentViewport &viewport) const
foreach ( const KBookmark &bm, bmarks )
{
DocumentViewport vp( bm.url().htmlRef() );
if ( documentViewportLessThan( viewport, vp ) )
if ( viewport < vp )
{
bookmark = bm;
break;
@ -744,7 +727,7 @@ KBookmark BookmarkManager::previousBookmark( const DocumentViewport &viewport )
{
KBookmark bm = *(it-1);
DocumentViewport vp( bm.url().htmlRef() );
if ( documentViewportLessThan( vp, viewport ) )
if ( vp < viewport )
{
bookmark = bm;
break;

View file

@ -11,6 +11,7 @@
#include "document.h"
#include "document_p.h"
#include <limits.h>
#ifdef Q_OS_WIN
#define _WIN32_WINNT 0x0500
#include <windows.h>
@ -173,11 +174,12 @@ QString DocumentPrivate::localizedSize(const QSizeF &size) const
}
}
void DocumentPrivate::cleanupPixmapMemory( qulonglong /*sure? bytesOffset*/ )
qulonglong DocumentPrivate::calculateMemoryToFree()
{
// [MEM] choose memory parameters based on configuration profile
qulonglong clipValue = 0;
qulonglong memoryToFree = 0;
switch ( Settings::memoryLevel() )
{
case Settings::EnumMemoryLevel::Low:
@ -201,7 +203,9 @@ void DocumentPrivate::cleanupPixmapMemory( qulonglong /*sure? bytesOffset*/ )
break;
case Settings::EnumMemoryLevel::Greedy:
{
const qulonglong memoryLimit = qMax(getFreeMemory(), getTotalMemory() / 2);
qulonglong freeSwap;
qulonglong freeMemory = getFreeMemory( &freeSwap );
const qulonglong memoryLimit = qMin( qMax( freeMemory, getTotalMemory()/2 ), freeMemory+freeSwap );
if (m_allocatedPixmapsTotalMemory > memoryLimit) clipValue = (m_allocatedPixmapsTotalMemory - memoryLimit) / 2;
}
break;
@ -210,33 +214,80 @@ void DocumentPrivate::cleanupPixmapMemory( qulonglong /*sure? bytesOffset*/ )
if ( clipValue > memoryToFree )
memoryToFree = clipValue;
return memoryToFree;
}
void DocumentPrivate::cleanupPixmapMemory()
{
cleanupPixmapMemory( calculateMemoryToFree() );
}
void DocumentPrivate::cleanupPixmapMemory( qulonglong memoryToFree )
{
if ( memoryToFree > 0 )
{
// [MEM] free memory starting from older pixmaps
int pagesFreed = 0;
QLinkedList< AllocatedPixmap * >::iterator pIt = m_allocatedPixmapsFifo.begin();
QLinkedList< AllocatedPixmap * >::iterator pEnd = m_allocatedPixmapsFifo.end();
while ( (pIt != pEnd) && (memoryToFree > 0) )
while ( memoryToFree > 0 )
{
AllocatedPixmap * p = *pIt;
if ( m_observers.value( p->id )->canUnloadPixmap( p->page ) )
{
// update internal variables
pIt = m_allocatedPixmapsFifo.erase( pIt );
m_allocatedPixmapsTotalMemory -= p->memory;
AllocatedPixmap * p = searchLowestPriorityUnloadablePixmap( true );
if ( !p ) // No pixmap to remove
break;
kDebug().nospace() << "Evicting cache pixmap id=" << p->id << " page=" << p->page;
// m_allocatedPixmapsTotalMemory can't underflow because we always add or remove
// the memory used by the AllocatedPixmap so at most it can reach zero
m_allocatedPixmapsTotalMemory -= p->memory;
// Make sure memoryToFree does not underflow
if ( p->memory > memoryToFree )
memoryToFree = 0;
else
memoryToFree -= p->memory;
pagesFreed++;
// delete pixmap
m_pagesVector.at( p->page )->deletePixmap( p->id );
// delete allocation descriptor
delete p;
} else
++pIt;
pagesFreed++;
// delete pixmap
m_pagesVector.at( p->page )->deletePixmap( p->id );
// delete allocation descriptor
delete p;
}
//p--rintf("freeMemory A:[%d -%d = %d] \n", m_allocatedPixmapsFifo.count() + pagesFreed, pagesFreed, m_allocatedPixmapsFifo.count() );
//p--rintf("freeMemory A:[%d -%d = %d] \n", m_allocatedPixmaps.count() + pagesFreed, pagesFreed, m_allocatedPixmaps.count() );
}
}
/* Returns the next pixmap to evict from cache, or NULL if no suitable pixmap
* is found. If thenRemoveIt is set, the pixmap is removed from
* m_allocatedPixmaps before returning it */
AllocatedPixmap * DocumentPrivate::searchLowestPriorityUnloadablePixmap( bool thenRemoveIt )
{
QLinkedList< AllocatedPixmap * >::iterator pIt = m_allocatedPixmaps.begin();
QLinkedList< AllocatedPixmap * >::iterator pEnd = m_allocatedPixmaps.end();
QLinkedList< AllocatedPixmap * >::iterator farthestPixmap = pEnd;
const int currentViewportPage = (*m_viewportIterator).pageNumber;
/* Find the pixmap that is farthest from the current viewport */
int maxDistance = -1;
while ( pIt != pEnd )
{
const AllocatedPixmap * p = *pIt;
const int distance = qAbs( p->page - currentViewportPage );
if ( maxDistance < distance && m_observers.value( p->id )->canUnloadPixmap( p->page ) )
{
maxDistance = distance;
farthestPixmap = pIt;
}
++pIt;
}
/* No pixmap to remove */
if ( farthestPixmap == pEnd )
return 0;
AllocatedPixmap * selectedPixmap = *farthestPixmap;
if ( thenRemoveIt )
m_allocatedPixmaps.erase( farthestPixmap );
return selectedPixmap;
}
qulonglong DocumentPrivate::getTotalMemory()
{
static qulonglong cachedValue = 0;
@ -249,10 +300,8 @@ qulonglong DocumentPrivate::getTotalMemory()
if ( !memFile.open( QIODevice::ReadOnly ) )
return (cachedValue = 134217728);
// read /proc/meminfo and sum up the contents of 'MemFree', 'Buffers'
// and 'Cached' fields. consider swapped memory as used memory.
QTextStream readStream( &memFile );
while ( true )
while ( true )
{
QString entry = readStream.readLine();
if ( entry.isNull() ) break;
@ -275,13 +324,23 @@ qulonglong DocumentPrivate::getTotalMemory()
return (cachedValue = 134217728);
}
qulonglong DocumentPrivate::getFreeMemory()
qulonglong DocumentPrivate::getFreeMemory( qulonglong *freeSwap )
{
static QTime lastUpdate = QTime::currentTime().addSecs(-3);
static qulonglong cachedValue = 0;
static qulonglong cachedFreeSwap = 0;
if ( qAbs( lastUpdate.secsTo( QTime::currentTime() ) ) <= 2 )
{
if (freeSwap)
*freeSwap = cachedFreeSwap;
return cachedValue;
}
/* Initialize the returned free swap value to 0. It is overwritten if the
* actual value is available */
if (freeSwap)
*freeSwap = 0;
#if defined(Q_OS_LINUX)
// if /proc/meminfo doesn't exist, return MEMORY FULL
@ -294,22 +353,46 @@ qulonglong DocumentPrivate::getFreeMemory()
qulonglong memoryFree = 0;
QString entry;
QTextStream readStream( &memFile );
static const int nElems = 5;
QString names[nElems] = { "MemFree:", "Buffers:", "Cached:", "SwapFree:", "SwapTotal:" };
qulonglong values[nElems] = { 0, 0, 0, 0, 0 };
bool foundValues[nElems] = { false, false, false, false, false };
while ( true )
{
entry = readStream.readLine();
if ( entry.isNull() ) break;
if ( entry.startsWith( "MemFree:" ) ||
entry.startsWith( "Buffers:" ) ||
entry.startsWith( "Cached:" ) ||
entry.startsWith( "SwapFree:" ) )
memoryFree += entry.section( ' ', -2, -2 ).toULongLong();
if ( entry.startsWith( "SwapTotal:" ) )
memoryFree -= entry.section( ' ', -2, -2 ).toULongLong();
for ( int i = 0; i < nElems; ++i )
{
if ( entry.startsWith( names[i] ) )
{
values[i] = entry.section( ' ', -2, -2 ).toULongLong( &foundValues[i] );
}
}
}
memFile.close();
bool found = true;
for ( int i = 0; found && i < nElems; ++i )
found = found && foundValues[i];
if ( found )
{
/* MemFree + Buffers + Cached - SwapUsed =
* = MemFree + Buffers + Cached - (SwapTotal - SwapFree) =
* = MemFree + Buffers + Cached + SwapFree - SwapTotal */
memoryFree = values[0] + values[1] + values[2] + values[3];
if ( values[4] > memoryFree )
memoryFree = 0;
else
memoryFree -= values[4];
}
else
{
return 0;
}
lastUpdate = QTime::currentTime();
if (freeSwap)
*freeSwap = ( cachedFreeSwap = (Q_UINT64_C(1024) * values[3]) );
return ( cachedValue = (Q_UINT64_C(1024) * memoryFree) );
#elif defined(Q_OS_FREEBSD)
qulonglong cache, inact, free, psize;
@ -338,6 +421,8 @@ qulonglong DocumentPrivate::getFreeMemory()
lastUpdate = QTime::currentTime();
if (freeSwap)
*freeSwap = ( cachedFreeSwap = stat.ullAvailPageFile );
return ( cachedValue = stat.ullAvailPhys );
#else
// tell the memory is full.. will act as in LOW profile
@ -777,15 +862,16 @@ void DocumentPrivate::warnLimitedAnnotSupport()
return;
m_showWarningLimitedAnnotSupport = false; // Show the warning once
if ( canAddAnnotationsNatively() )
if ( m_annotationsNeedSaveAs )
{
// Show only if there are external annotations (we follow the usual XML path otherwise)
if ( m_containsExternalAnnotations )
KMessageBox::sorry( m_parent->widget(), i18n("Your changes will not be saved automatically. Use File -> Save As... or your changes will be lost") );
// Shown if the user is editing annotations in a file whose metadata is
// not stored locally (.okular archives belong to this category)
KMessageBox::information( m_parent->widget(), i18n("Your annotation changes will not be saved automatically. Use File -> Save As...\nor your changes will be lost once the document is closed"), QString(), "annotNeedSaveAs" );
}
else
else if ( !canAddAnnotationsNatively() )
{
KMessageBox::information( m_parent->widget(), i18n("You can save the annotated document using File -> Export As -> Document Archive"), QString(), "annotExportAsArchive" );
// If the generator doesn't support native annotations
KMessageBox::information( m_parent->widget(), i18n("Your annotations are saved internally by Okular.\nYou can export the annotated document using File -> Export As -> Document Archive"), QString(), "annotExportAsArchive" );
}
}
@ -810,8 +896,14 @@ void DocumentPrivate::saveDocumentInfo() const
QDomElement pageList = doc.createElement( "pageList" );
root.appendChild( pageList );
PageItems saveWhat = AllPageItems;
if ( canAddAnnotationsNatively() && m_containsExternalAnnotations )
saveWhat &= ~AnnotationPageItems; // Don't save local annotations in this case
if ( m_annotationsNeedSaveAs )
{
/* In this case, if the user makes a modification, he's requested to
* save to a new document. Therefore, if there are existing local
* annotations, we save them back unmodified in the original
* document's metadata, so that it appears that it was not changed */
saveWhat |= OriginalAnnotationPageItems;
}
// <page list><page number='x'>.... </page> save pages that hold data
QVector< Page * >::const_iterator pIt = m_pagesVector.constBegin(), pEnd = m_pagesVector.constEnd();
for ( ; pIt != pEnd; ++pIt )
@ -880,8 +972,22 @@ void DocumentPrivate::slotTimedMemoryCheck()
cleanupPixmapMemory();
}
void DocumentPrivate::sendGeneratorRequest()
void DocumentPrivate::sendGeneratorPixmapRequest()
{
/* If the pixmap cache will have to be cleaned in order to make room for the
* next request, get the distance from the current viewport of the page
* whose pixmap will be removed. We will ignore preload requests for pages
* that are at the same distance or farther */
const qulonglong memoryToFree = calculateMemoryToFree();
const int currentViewportPage = (*m_viewportIterator).pageNumber;
int maxDistance = INT_MAX; // Default: No maximum
if ( memoryToFree )
{
AllocatedPixmap *pixmapToReplace = searchLowestPriorityUnloadablePixmap();
if ( pixmapToReplace )
maxDistance = qAbs( pixmapToReplace->page - currentViewportPage );
}
// find a request
PixmapRequest * request = 0;
m_pixmapRequestsMutex.lock();
@ -909,8 +1015,16 @@ void DocumentPrivate::sendGeneratorRequest()
}
delete r;
}
else if ( !r->d->mForce && r->d->isPreload() && qAbs( r->pageNumber() - currentViewportPage ) >= maxDistance )
{
m_pixmapRequestsStack.pop_back();
//kDebug() << "Ignoring request that doesn't fit in cache";
delete r;
}
else
{
request = r;
}
}
// if no request found (or already generated), return
@ -923,7 +1037,7 @@ void DocumentPrivate::sendGeneratorRequest()
// [MEM] preventive memory freeing
qulonglong pixmapBytes = 4 * request->width() * request->height();
if ( pixmapBytes > (1024 * 1024) )
cleanupPixmapMemory( pixmapBytes );
cleanupPixmapMemory( memoryToFree /* previously calculated value */ );
// submit the request to the generator
if ( m_generator->canGeneratePixmap() )
@ -945,7 +1059,7 @@ void DocumentPrivate::sendGeneratorRequest()
{
m_pixmapRequestsMutex.unlock();
// pino (7/4/2006): set the polling interval from 10 to 30
QTimer::singleShot( 30, m_parent, SLOT(sendGeneratorRequest()) );
QTimer::singleShot( 30, m_parent, SLOT(sendGeneratorPixmapRequest()) );
}
}
@ -1008,11 +1122,8 @@ void DocumentPrivate::slotGeneratorConfigChanged( const QString& )
}
// [MEM] remove allocation descriptors
QLinkedList< AllocatedPixmap * >::const_iterator aIt = m_allocatedPixmapsFifo.constBegin();
QLinkedList< AllocatedPixmap * >::const_iterator aEnd = m_allocatedPixmapsFifo.constEnd();
for ( ; aIt != aEnd; ++aIt )
delete *aIt;
m_allocatedPixmapsFifo.clear();
qDeleteAll( m_allocatedPixmaps );
m_allocatedPixmaps.clear();
m_allocatedPixmapsTotalMemory = 0;
// send reload signals to observers
@ -1021,7 +1132,7 @@ void DocumentPrivate::slotGeneratorConfigChanged( const QString& )
// free memory if in 'low' profile
if ( Settings::memoryLevel() == Settings::EnumMemoryLevel::Low &&
!m_allocatedPixmapsFifo.isEmpty() && !m_pagesVector.isEmpty() )
!m_allocatedPixmaps.isEmpty() && !m_pagesVector.isEmpty() )
cleanupPixmapMemory();
}
@ -1057,66 +1168,73 @@ void DocumentPrivate::_o_configChanged()
}
}
void DocumentPrivate::doContinueNextMatchSearch(void *pagesToNotifySet, void * theMatch, int currentPage, int searchID, const QString & text, int theCaseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages)
void DocumentPrivate::doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct)
{
RegularAreaRect * match = static_cast<RegularAreaRect *>(theMatch);
Qt::CaseSensitivity caseSensitivity = static_cast<Qt::CaseSensitivity>(theCaseSensitivity);
QSet< int > *pagesToNotify = static_cast< QSet< int > * >( pagesToNotifySet );
RunningSearch *search = m_searches.value(searchID);
DoContinueDirectionMatchSearchStruct *searchStruct = static_cast<DoContinueDirectionMatchSearchStruct *>(doContinueDirectionMatchSearchStruct);
RunningSearch *search = m_searches.value(searchStruct->searchID);
if ((m_searchCancelled && !match) || !search)
if ((m_searchCancelled && !searchStruct->match) || !search)
{
// if the user cancelled but he just got a match, give him the match!
QApplication::restoreOverrideCursor();
if (search) search->isCurrentlySearching = false;
emit m_parent->searchFinished( searchID, Document::SearchCancelled );
delete pagesToNotify;
emit m_parent->searchFinished( searchStruct->searchID, Document::SearchCancelled );
delete searchStruct->pagesToNotify;
delete searchStruct;
return;
}
bool doContinue = false;
// if no match found, loop through the whole doc, starting from currentPage
if ( !match )
if ( !searchStruct->match )
{
int pageCount = m_pagesVector.count();
if (donePages < pageCount)
const int pageCount = m_pagesVector.count();
if (searchStruct->pagesDone < pageCount)
{
bool doContinue = true;
if ( currentPage >= pageCount )
doContinue = true;
if ( searchStruct->currentPage >= pageCount || searchStruct->currentPage < 0 )
{
if ( noDialogs || KMessageBox::questionYesNo(m_parent->widget(), i18n("End of document reached.\nContinue from the beginning?"), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::Yes )
currentPage = 0;
const QString question = searchStruct->forward ? i18n("End of document reached.\nContinue from the beginning?") : i18n("Beginning of document reached.\nContinue from the bottom?");
if ( searchStruct->noDialogs || KMessageBox::questionYesNo(m_parent->widget(), question, QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::Yes )
searchStruct->currentPage = searchStruct->forward ? 0 : pageCount - 1;
else
doContinue = false;
}
if (doContinue)
{
// get page
Page * page = m_pagesVector[ currentPage ];
// request search page if needed
if ( !page->hasTextPage() )
m_parent->requestTextPage( page->number() );
// if found a match on the current page, end the loop
match = page->findText( searchID, text, FromTop, caseSensitivity );
if ( !match )
{
currentPage++;
donePages++;
}
else
{
donePages = 1;
}
QMetaObject::invokeMethod(m_parent, "doContinueNextMatchSearch", Qt::QueuedConnection, Q_ARG(void *, pagesToNotifySet), Q_ARG(void *, match), Q_ARG(int, currentPage), Q_ARG(int, searchID), Q_ARG(QString, text), Q_ARG(int, caseSensitivity), Q_ARG(bool, moveViewport), Q_ARG(QColor, color), Q_ARG(bool, noDialogs), Q_ARG(int, donePages));
return;
}
}
}
doProcessSearchMatch( match, search, pagesToNotify, currentPage, searchID, moveViewport, color );
if (doContinue)
{
// get page
Page * page = m_pagesVector[ searchStruct->currentPage ];
// request search page if needed
if ( !page->hasTextPage() )
m_parent->requestTextPage( page->number() );
// if found a match on the current page, end the loop
searchStruct->match = page->findText( searchStruct->searchID, searchStruct->text, searchStruct->forward ? FromTop : FromBottom, searchStruct->caseSensitivity );
if ( !searchStruct->match )
{
if (searchStruct->forward) searchStruct->currentPage++;
else searchStruct->currentPage--;
searchStruct->pagesDone++;
}
else
{
searchStruct->pagesDone = 1;
}
// Both of the previous if branches need to call doContinueDirectionMatchSearch
QMetaObject::invokeMethod(m_parent, "doContinueDirectionMatchSearch", Qt::QueuedConnection, Q_ARG(void *, searchStruct));
}
else
{
doProcessSearchMatch( searchStruct->match, search, searchStruct->pagesToNotify, searchStruct->currentPage, searchStruct->searchID, searchStruct->moveViewport, searchStruct->color );
delete searchStruct;
}
}
void DocumentPrivate::doProcessSearchMatch( RegularAreaRect *match, RunningSearch *search, QSet< int > *pagesToNotify, int currentPage, int searchID, bool moveViewport, const QColor & color )
@ -1169,69 +1287,6 @@ void DocumentPrivate::doProcessSearchMatch( RegularAreaRect *match, RunningSearc
delete pagesToNotify;
}
void DocumentPrivate::doContinuePrevMatchSearch(void *pagesToNotifySet, void * theMatch, int currentPage, int searchID, const QString & text, int theCaseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages)
{
RegularAreaRect * match = static_cast<RegularAreaRect *>(theMatch);
Qt::CaseSensitivity caseSensitivity = static_cast<Qt::CaseSensitivity>(theCaseSensitivity);
QSet< int > *pagesToNotify = static_cast< QSet< int > * >( pagesToNotifySet );
RunningSearch *search = m_searches.value(searchID);
if ((m_searchCancelled && !match) || !search)
{
// if the user cancelled but he just got a match, give him the match!
QApplication::restoreOverrideCursor();
if (search) search->isCurrentlySearching = false;
emit m_parent->searchFinished( searchID, Document::SearchCancelled );
delete pagesToNotify;
return;
}
// if no match found, loop through the whole doc, starting from currentPage
if ( !match )
{
int pageCount = m_pagesVector.count();
if (donePages < pageCount)
{
bool doContinue = true;
if ( currentPage < 0 )
{
if ( noDialogs || KMessageBox::questionYesNo(m_parent->widget(), i18n("Beginning of document reached.\nContinue from the bottom?"), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::Yes )
currentPage = pageCount - 1;
else
doContinue = false;
}
if (doContinue)
{
// get page
Page * page = m_pagesVector[ currentPage ];
// request search page if needed
if ( !page->hasTextPage() )
m_parent->requestTextPage( page->number() );
// if found a match on the current page, end the loop
match = page->findText( searchID, text, FromBottom, caseSensitivity );
if ( !match )
{
currentPage--;
donePages++;
}
else
{
donePages = 1;
}
QMetaObject::invokeMethod(m_parent, "doContinuePrevMatchSearch", Qt::QueuedConnection, Q_ARG(void *, pagesToNotifySet), Q_ARG(void *, match), Q_ARG(int, currentPage), Q_ARG(int, searchID), Q_ARG(QString, text), Q_ARG(int, caseSensitivity), Q_ARG(bool, moveViewport), Q_ARG(QColor, color), Q_ARG(bool, noDialogs), Q_ARG(int, donePages));
return;
}
}
}
doProcessSearchMatch( match, search, pagesToNotify, currentPage, searchID, moveViewport, color );
}
void DocumentPrivate::doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QString & text, int theCaseSensitivity, const QColor & color)
{
QMap< Page *, QVector<RegularAreaRect *> > *pageMatches = static_cast< QMap< Page *, QVector<RegularAreaRect *> > * >(pageMatchesMap);
@ -1678,24 +1733,32 @@ bool Document::openDocument( const QString & docFile, const KUrl& url, const KMi
}
d->m_generatorName = offer->name();
d->m_containsExternalAnnotations = false;
d->m_showWarningLimitedAnnotSupport = true;
bool containsExternalAnnotations = false;
foreach ( Page * p, d->m_pagesVector )
{
p->d->m_doc = d;
if ( !p->annotations().empty() )
d->m_containsExternalAnnotations = true;
containsExternalAnnotations = true;
}
// Be quiet while restoring local annotations
d->m_showWarningLimitedAnnotSupport = false;
d->m_annotationsNeedSaveAs = false;
// 2. load Additional Data (bookmarks, local annotations and metadata) about the document
if ( d->m_archiveData )
{
d->loadDocumentInfo( d->m_archiveData->metadataFileName );
d->m_annotationsNeedSaveAs = true;
}
else
{
d->loadDocumentInfo();
d->m_annotationsNeedSaveAs = ( d->canAddAnnotationsNatively() && containsExternalAnnotations );
}
d->m_showWarningLimitedAnnotSupport = true;
d->m_bookmarkManager->setUrl( d->m_url );
// 3. setup observers inernal lists and data
@ -1863,11 +1926,8 @@ void Document::closeDocument()
d->m_pagesVector.clear();
// clear 'memory allocation' descriptors
QLinkedList< AllocatedPixmap * >::const_iterator aIt = d->m_allocatedPixmapsFifo.constBegin();
QLinkedList< AllocatedPixmap * >::const_iterator aEnd = d->m_allocatedPixmapsFifo.constEnd();
for ( ; aIt != aEnd; ++aIt )
delete *aIt;
d->m_allocatedPixmapsFifo.clear();
qDeleteAll( d->m_allocatedPixmaps );
d->m_allocatedPixmaps.clear();
// clear 'running searches' descriptors
QMap< int, RunningSearch * >::const_iterator rIt = d->m_searches.constBegin();
@ -1925,14 +1985,14 @@ void Document::removeObserver( DocumentObserver * pObserver )
(*it)->deletePixmap( observerId );
// [MEM] free observer's allocation descriptors
QLinkedList< AllocatedPixmap * >::iterator aIt = d->m_allocatedPixmapsFifo.begin();
QLinkedList< AllocatedPixmap * >::iterator aEnd = d->m_allocatedPixmapsFifo.end();
QLinkedList< AllocatedPixmap * >::iterator aIt = d->m_allocatedPixmaps.begin();
QLinkedList< AllocatedPixmap * >::iterator aEnd = d->m_allocatedPixmaps.end();
while ( aIt != aEnd )
{
AllocatedPixmap * p = *aIt;
if ( p->id == observerId )
{
aIt = d->m_allocatedPixmapsFifo.erase( aIt );
aIt = d->m_allocatedPixmaps.erase( aIt );
delete p;
}
else
@ -1963,11 +2023,8 @@ void Document::reparseConfig()
}
// [MEM] remove allocation descriptors
QLinkedList< AllocatedPixmap * >::const_iterator aIt = d->m_allocatedPixmapsFifo.constBegin();
QLinkedList< AllocatedPixmap * >::const_iterator aEnd = d->m_allocatedPixmapsFifo.constEnd();
for ( ; aIt != aEnd; ++aIt )
delete *aIt;
d->m_allocatedPixmapsFifo.clear();
qDeleteAll( d->m_allocatedPixmaps );
d->m_allocatedPixmaps.clear();
d->m_allocatedPixmapsTotalMemory = 0;
// send reload signals to observers
@ -1976,7 +2033,7 @@ void Document::reparseConfig()
// free memory if in 'low' profile
if ( Settings::memoryLevel() == Settings::EnumMemoryLevel::Low &&
!d->m_allocatedPixmapsFifo.isEmpty() && !d->m_pagesVector.isEmpty() )
!d->m_allocatedPixmaps.isEmpty() && !d->m_pagesVector.isEmpty() )
d->cleanupPixmapMemory();
}
@ -2138,6 +2195,9 @@ KUrl Document::currentDocument() const
bool Document::isAllowed( Permission action ) const
{
if ( action == Okular::AllowNotes && !d->m_annotationEditingEnabled )
return false;
#if !OKULAR_FORCE_DRM
if ( KAuthorized::authorize( "skip_drm" ) && !Okular::Settings::obeyDRM() )
return true;
@ -2297,7 +2357,6 @@ void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests,
}
// 2. [ADD TO STACK] add requests to stack
bool threadingDisabled = !Settings::enableThreading();
QLinkedList< PixmapRequest * >::const_iterator rIt = requests.constBegin(), rEnd = requests.constEnd();
for ( ; rIt != rEnd; ++rIt )
{
@ -2316,9 +2375,6 @@ void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests,
if ( !request->asynchronous() )
request->d->mPriority = 0;
if ( request->asynchronous() && threadingDisabled )
request->d->mAsynchronous = false;
// add request to the 'stack' at the right place
if ( !request->priority() )
// add priority zero requests to the top of the stack
@ -2338,9 +2394,9 @@ void Document::requestPixmaps( const QLinkedList< PixmapRequest * > & requests,
// 3. [START FIRST GENERATION] if <NO>generator is ready, start a new generation,
// or else (if gen is running) it will be started when the new contents will
//come from generator (in requestDone())</NO>
// all handling of requests put into sendGeneratorRequest
// all handling of requests put into sendGeneratorPixmapRequest
// if ( generator->canRequestPixmap() )
d->sendGeneratorRequest();
d->sendGeneratorPixmapRequest();
}
void Document::requestTextPage( uint page )
@ -2354,6 +2410,16 @@ void Document::requestTextPage( uint page )
d->m_generator->generateTextPage( kp );
}
void DocumentPrivate::notifyAnnotationChanges( int page )
{
int flags = DocumentObserver::Annotations;
if ( m_annotationsNeedSaveAs )
flags |= DocumentObserver::NeedSaveAs;
foreachObserverD( notifyPageChanged( page, flags ) );
}
void Document::addPageAnnotation( int page, Annotation * annotation )
{
Okular::SaveInterface * iface = qobject_cast< Okular::SaveInterface * >( d->m_generator );
@ -2376,7 +2442,7 @@ void Document::addPageAnnotation( int page, Annotation * annotation )
proxy->notifyAddition( annotation, page );
// notify observers about the change
foreachObserver( notifyPageChanged( page, DocumentObserver::Annotations ) );
d->notifyAnnotationChanges( page );
if ( annotation->flags() & Annotation::ExternallyDrawn )
{
@ -2432,7 +2498,7 @@ void Document::modifyPageAnnotation( int page, Annotation * annotation, bool app
proxy->notifyModification( annotation, page, appearanceChanged );
// notify observers about the change
foreachObserver( notifyPageChanged( page, DocumentObserver::Annotations ) );
d->notifyAnnotationChanges( page );
if ( appearanceChanged && (annotation->flags() & Annotation::ExternallyDrawn) )
{
@ -2507,7 +2573,7 @@ void Document::removePageAnnotation( int page, Annotation * annotation )
kp->removeAnnotation( annotation ); // Also destroys the object
// in case of success, notify observers about the change
foreachObserver( notifyPageChanged( page, DocumentObserver::Annotations ) );
d->notifyAnnotationChanges( page );
if ( isExternallyDrawn )
{
@ -2555,7 +2621,7 @@ void Document::removePageAnnotations( int page, const QList< Annotation * > &ann
if ( changed )
{
// in case we removed even only one annotation, notify observers about the change
foreachObserver( notifyPageChanged( page, DocumentObserver::Annotations ) );
d->notifyAnnotationChanges( page );
if ( refreshNeeded )
{
@ -2662,6 +2728,8 @@ void Document::setViewport( const DocumentViewport & viewport, int excludeId, bo
//if ( viewport == oldViewport )
// kDebug(OkularDebug) << "setViewport with the same viewport.";
const int oldPageNumber = oldViewport.pageNumber;
// set internal viewport taking care of history
if ( oldViewport.pageNumber == viewport.pageNumber || !oldViewport.isValid() )
{
@ -2681,31 +2749,19 @@ void Document::setViewport( const DocumentViewport & viewport, int excludeId, bo
d->m_viewportIterator = d->m_viewportHistory.insert( d->m_viewportHistory.end(), viewport );
}
const int currentViewportPage = (*d->m_viewportIterator).pageNumber;
const bool currentPageChanged = (oldPageNumber != currentViewportPage);
// notify change to all other (different from id) observers
QMap< int, DocumentObserver * >::const_iterator it = d->m_observers.constBegin(), end = d->m_observers.constEnd();
for ( ; it != end ; ++ it )
{
if ( it.key() != excludeId )
(*it)->notifyViewportChanged( smoothMove );
// [MEM] raise position of currently viewed page in allocation queue
if ( d->m_allocatedPixmapsFifo.count() > 1 )
{
const int page = viewport.pageNumber;
QLinkedList< AllocatedPixmap * > viewportPixmaps;
QLinkedList< AllocatedPixmap * >::iterator aIt = d->m_allocatedPixmapsFifo.begin();
QLinkedList< AllocatedPixmap * >::iterator aEnd = d->m_allocatedPixmapsFifo.end();
while ( aIt != aEnd )
{
if ( (*aIt)->page == page )
{
viewportPixmaps.append( *aIt );
aIt = d->m_allocatedPixmapsFifo.erase( aIt );
continue;
}
++aIt;
}
if ( !viewportPixmaps.isEmpty() )
d->m_allocatedPixmapsFifo += viewportPixmaps;
if ( currentPageChanged )
(*it)->notifyCurrentPageChanged( oldPageNumber, currentViewportPage );
}
}
@ -2825,37 +2881,14 @@ void Document::searchText( int searchID, const QString & text, bool fromStart, Q
QMetaObject::invokeMethod(this, "doContinueAllDocumentSearch", Qt::QueuedConnection, Q_ARG(void *, pagesToNotify), Q_ARG(void *, pageMatches), Q_ARG(int, 0), Q_ARG(int, searchID), Q_ARG(QString, text), Q_ARG(int, caseSensitivity), Q_ARG(QColor, color));
}
// 2. NEXTMATCH - find next matching item (or start from top)
else if ( type == NextMatch )
{
// find out from where to start/resume search from
int viewportPage = (*d->m_viewportIterator).pageNumber;
int currentPage = fromStart ? 0 : ((s->continueOnPage != -1) ? s->continueOnPage : viewportPage);
Page * lastPage = fromStart ? 0 : d->m_pagesVector[ currentPage ];
int pagesDone = 0;
// continue checking last TextPage first (if it is the current page)
RegularAreaRect * match = 0;
if ( lastPage && lastPage->number() == s->continueOnPage )
{
if ( newText )
match = lastPage->findText( searchID, text, FromTop, caseSensitivity );
else
match = lastPage->findText( searchID, text, NextResult, caseSensitivity, &s->continueOnMatch );
if ( !match )
{
currentPage++;
pagesDone++;
}
}
QMetaObject::invokeMethod(this, "doContinueNextMatchSearch", Qt::QueuedConnection, Q_ARG(void *, pagesToNotify), Q_ARG(void *, match), Q_ARG(int, currentPage), Q_ARG(int, searchID), Q_ARG(QString, text), Q_ARG(int, caseSensitivity), Q_ARG(bool, moveViewport), Q_ARG(QColor, color), Q_ARG(bool, noDialogs), Q_ARG(int, pagesDone));
}
// 3. PREVMATCH - find previous matching item (or start from bottom)
else if ( type == PreviousMatch )
else if ( type == NextMatch || type == PreviousMatch )
{
// find out from where to start/resume search from
int viewportPage = (*d->m_viewportIterator).pageNumber;
int currentPage = fromStart ? d->m_pagesVector.count() - 1 : ((s->continueOnPage != -1) ? s->continueOnPage : viewportPage);
const bool forward = type == NextMatch;
const int viewportPage = (*d->m_viewportIterator).pageNumber;
const int fromStartSearchPage = forward ? 0 : d->m_pagesVector.count() - 1;
int currentPage = fromStart ? fromStartSearchPage : ((s->continueOnPage != -1) ? s->continueOnPage : viewportPage);
Page * lastPage = fromStart ? 0 : d->m_pagesVector[ currentPage ];
int pagesDone = 0;
@ -2864,17 +2897,31 @@ void Document::searchText( int searchID, const QString & text, bool fromStart, Q
if ( lastPage && lastPage->number() == s->continueOnPage )
{
if ( newText )
match = lastPage->findText( searchID, text, FromBottom, caseSensitivity );
match = lastPage->findText( searchID, text, forward ? FromTop : FromBottom, caseSensitivity );
else
match = lastPage->findText( searchID, text, PreviousResult, caseSensitivity, &s->continueOnMatch );
match = lastPage->findText( searchID, text, forward ? NextResult : PreviousResult, caseSensitivity, &s->continueOnMatch );
if ( !match )
{
currentPage--;
if (forward) currentPage++;
else currentPage--;
pagesDone++;
}
}
DoContinueDirectionMatchSearchStruct *searchStruct = new DoContinueDirectionMatchSearchStruct();
searchStruct->forward = forward;
searchStruct->pagesToNotify = pagesToNotify;
searchStruct->match = match;
searchStruct->currentPage = currentPage;
searchStruct->searchID = searchID;
searchStruct->text = text;
searchStruct->caseSensitivity = caseSensitivity;
searchStruct->moveViewport = moveViewport;
searchStruct->color = color;
searchStruct->noDialogs = noDialogs;
searchStruct->pagesDone = pagesDone;
QMetaObject::invokeMethod(this, "doContinuePrevMatchSearch", Qt::QueuedConnection, Q_ARG(void *, pagesToNotify), Q_ARG(void *, match), Q_ARG(int, currentPage), Q_ARG(int, searchID), Q_ARG(QString, text), Q_ARG(int, caseSensitivity), Q_ARG(bool, moveViewport), Q_ARG(QColor, color), Q_ARG(bool, noDialogs), Q_ARG(int, pagesDone));
QMetaObject::invokeMethod(this, "doContinueDirectionMatchSearch", Qt::QueuedConnection, Q_ARG(void *, searchStruct));
}
// 4. GOOGLE* - process all document marking pages
else if ( type == GoogleAll || type == GoogleAny )
@ -3451,6 +3498,23 @@ bool Document::canSaveChanges() const
return saveIface->supportsOption( SaveInterface::SaveChanges );
}
bool Document::canSaveChanges( SaveCapability cap ) const
{
switch ( cap )
{
case SaveFormsCapability:
/* Assume that if the generator supports saving, forms can be saved.
* We have no means to actually query the generator at the moment
* TODO: Add some method to query the generator in SaveInterface */
return canSaveChanges();
case SaveAnnotationsCapability:
return d->canAddAnnotationsNatively();
}
return false;
}
bool Document::saveChanges( const QString &fileName )
{
QString errorText;
@ -3597,6 +3661,7 @@ bool Document::openDocumentArchive( const QString & docFile, const KUrl & url )
const KMimeType::Ptr docMime = KMimeType::findByPath( tempFileName, 0, true /* local file */ );
d->m_archiveData = archiveData.get();
d->m_archivedFileName = documentFileName;
bool ret = openDocument( tempFileName, url, docMime );
if ( ret )
@ -3616,7 +3681,9 @@ bool Document::saveDocumentArchive( const QString &fileName )
if ( !d->m_generator )
return false;
QString docFileName = d->m_url.fileName();
/* If we opened an archive, use the name of original file (eg foo.pdf)
* instead of the archive's one (eg foo.okular) */
QString docFileName = d->m_archiveData ? d->m_archivedFileName : d->m_url.fileName();
if ( docFileName == QLatin1String( "-" ) )
return false;
@ -3717,6 +3784,12 @@ QPrinter::Orientation Document::orientation() const
return (landscape > portrait) ? QPrinter::Landscape : QPrinter::Portrait;
}
void Document::setAnnotationEditingEnabled( bool enable )
{
d->m_annotationEditingEnabled = enable;
foreachObserver( notifySetup( d->m_pagesVector, 0 ) );
}
void DocumentPrivate::requestDone( PixmapRequest * req )
{
if ( !req )
@ -3739,13 +3812,13 @@ void DocumentPrivate::requestDone( PixmapRequest * req )
#endif
// [MEM] 1.1 find and remove a previous entry for the same page and id
QLinkedList< AllocatedPixmap * >::iterator aIt = m_allocatedPixmapsFifo.begin();
QLinkedList< AllocatedPixmap * >::iterator aEnd = m_allocatedPixmapsFifo.end();
QLinkedList< AllocatedPixmap * >::iterator aIt = m_allocatedPixmaps.begin();
QLinkedList< AllocatedPixmap * >::iterator aEnd = m_allocatedPixmaps.end();
for ( ; aIt != aEnd; ++aIt )
if ( (*aIt)->page == req->pageNumber() && (*aIt)->id == req->id() )
{
AllocatedPixmap * p = *aIt;
m_allocatedPixmapsFifo.erase( aIt );
m_allocatedPixmaps.erase( aIt );
m_allocatedPixmapsTotalMemory -= p->memory;
delete p;
break;
@ -3757,7 +3830,7 @@ void DocumentPrivate::requestDone( PixmapRequest * req )
// [MEM] 1.2 append memory allocation descriptor to the FIFO
qulonglong memoryBytes = 4 * req->width() * req->height();
AllocatedPixmap * memoryPage = new AllocatedPixmap( req->id(), req->pageNumber(), memoryBytes );
m_allocatedPixmapsFifo.append( memoryPage );
m_allocatedPixmaps.append( memoryPage );
m_allocatedPixmapsTotalMemory += memoryBytes;
// 2. notify an observer that its pixmap changed
@ -3779,7 +3852,7 @@ void DocumentPrivate::requestDone( PixmapRequest * req )
bool hasPixmaps = !m_pixmapRequestsStack.isEmpty();
m_pixmapRequestsMutex.unlock();
if ( hasPixmaps )
sendGeneratorRequest();
sendGeneratorPixmapRequest();
}
void DocumentPrivate::setPageBoundingBox( int page, const NormalizedRect& boundingBox )
@ -3892,11 +3965,8 @@ void Document::setPageSize( const PageSize &size )
for ( ; pIt != pEnd; ++pIt )
(*pIt)->d->changeSize( size );
// clear 'memory allocation' descriptors
QLinkedList< AllocatedPixmap * >::const_iterator aIt = d->m_allocatedPixmapsFifo.constBegin();
QLinkedList< AllocatedPixmap * >::const_iterator aEnd = d->m_allocatedPixmapsFifo.constEnd();
for ( ; aIt != aEnd; ++aIt )
delete *aIt;
d->m_allocatedPixmapsFifo.clear();
qDeleteAll( d->m_allocatedPixmaps );
d->m_allocatedPixmaps.clear();
d->m_allocatedPixmapsTotalMemory = 0;
// notify the generator that the current page size has changed
d->m_generator->pageSizeChanged( size, d->m_pageSize );
@ -4019,6 +4089,25 @@ bool DocumentViewport::operator==( const DocumentViewport & vp ) const
return true;
}
bool DocumentViewport::operator<( const DocumentViewport & vp ) const
{
// TODO: Check autoFit and Position
if ( pageNumber != vp.pageNumber )
return pageNumber < vp.pageNumber;
if ( !rePos.enabled && vp.rePos.enabled )
return true;
if ( !vp.rePos.enabled )
return false;
if ( rePos.normalizedY != vp.rePos.normalizedY )
return rePos.normalizedY < vp.rePos.normalizedY;
return rePos.normalizedX < vp.rePos.normalizedX;
}
/** DocumentInfo **/

View file

@ -561,10 +561,34 @@ class OKULAR_EXPORT Document : public QObject
*/
const KComponentData* componentData() const;
/**
* Saving capabilities. Their availability varies according to the
* underlying generator and/or the document type.
*
* @see canSaveChanges (SaveCapability)
* @since 0.15 (KDE 4.9)
*/
enum SaveCapability
{
SaveFormsCapability = 1, ///< Can save form changes
SaveAnnotationsCapability = 2 ///< Can save annotation changes
};
/**
* Returns whether it's possible to save a given category of changes to
* another document.
*
* @since 0.15 (KDE 4.9)
*/
bool canSaveChanges( SaveCapability cap ) const;
/**
* Returns whether the changes to the document (modified annotations,
* values in form fields, etc) can be saved to another document.
*
* Equivalent to the logical OR of canSaveChanges(SaveCapability) for
* each capability.
*
* @since 0.7 (KDE 4.1)
*/
bool canSaveChanges() const;
@ -642,6 +666,14 @@ class OKULAR_EXPORT Document : public QObject
*/
QPrinter::Orientation orientation() const;
/**
* Control annotation editing (creation, modification and removal),
* which is enabled by default.
*
* @since 0.15 (KDE 4.9)
*/
void setAnnotationEditingEnabled( bool enable );
public Q_SLOTS:
/**
@ -779,7 +811,7 @@ class OKULAR_EXPORT Document : public QObject
Q_PRIVATE_SLOT( d, void saveDocumentInfo() const )
Q_PRIVATE_SLOT( d, void slotTimedMemoryCheck() )
Q_PRIVATE_SLOT( d, void sendGeneratorRequest() )
Q_PRIVATE_SLOT( d, void sendGeneratorPixmapRequest() )
Q_PRIVATE_SLOT( d, void rotationFinished( int page, Okular::Page *okularPage ) )
Q_PRIVATE_SLOT( d, void fontReadingProgress( int page ) )
Q_PRIVATE_SLOT( d, void fontReadingGotFont( const Okular::FontInfo& font ) )
@ -788,8 +820,7 @@ class OKULAR_EXPORT Document : public QObject
Q_PRIVATE_SLOT( d, void _o_configChanged() )
// search thread simulators
Q_PRIVATE_SLOT( d, void doContinueNextMatchSearch(void *pagesToNotifySet, void * match, int currentPage, int searchID, const QString & text, int caseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages) )
Q_PRIVATE_SLOT( d, void doContinuePrevMatchSearch(void *pagesToNotifySet, void * match, int currentPage, int searchID, const QString & text, int caseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages) )
Q_PRIVATE_SLOT( d, void doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct) )
Q_PRIVATE_SLOT( d, void doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QString & text, int caseSensitivity, const QColor & color) )
Q_PRIVATE_SLOT( d, void doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QStringList & words, int caseSensitivity, const QColor & color, bool matchAll) )
};
@ -829,6 +860,7 @@ class OKULAR_EXPORT DocumentViewport
* @internal
*/
bool operator==( const DocumentViewport &other ) const;
bool operator<( const DocumentViewport &other ) const;
/**
* The number of the page nearest the center of the viewport.

View file

@ -63,6 +63,21 @@ namespace Okular {
class FontExtractionThread;
struct DoContinueDirectionMatchSearchStruct
{
bool forward;
QSet< int > *pagesToNotify;
RegularAreaRect *match;
int currentPage;
int searchID;
QString text;
Qt::CaseSensitivity caseSensitivity;
bool moveViewport;
QColor color;
bool noDialogs;
int pagesDone;
};
class DocumentPrivate
{
public:
@ -86,6 +101,7 @@ class DocumentPrivate
m_archiveData( 0 ),
m_fontsCached( false ),
m_documentInfo( 0 ),
m_annotationEditingEnabled ( true ),
m_annotationBeingMoved( false )
{
calculateMaxTextPages();
@ -94,10 +110,13 @@ class DocumentPrivate
// private methods
QString pagesSizeString() const;
QString localizedSize(const QSizeF &size) const;
void cleanupPixmapMemory( qulonglong bytesOffset = 0 );
qulonglong calculateMemoryToFree();
void cleanupPixmapMemory();
void cleanupPixmapMemory( qulonglong memoryToFree );
AllocatedPixmap * searchLowestPriorityUnloadablePixmap( bool thenRemoveIt = false );
void calculateMaxTextPages();
qulonglong getTotalMemory();
qulonglong getFreeMemory();
qulonglong getFreeMemory( qulonglong *freeSwap = 0 );
void loadDocumentInfo();
void loadDocumentInfo( const QString &fileName );
void loadViewsInfo( View *view, const QDomElement &e );
@ -115,6 +134,7 @@ class DocumentPrivate
bool openDocumentInternal( const KService::Ptr& offer, bool isstdin, const QString& docFile, const QByteArray& filedata );
bool savePageDocumentInfo( KTemporaryFile *infoFile, int what ) const;
DocumentViewport nextDocumentViewport() const;
void notifyAnnotationChanges( int page );
bool canAddAnnotationsNatively() const;
bool canModifyExternalAnnotations() const;
bool canRemoveExternalAnnotations() const;
@ -123,15 +143,14 @@ class DocumentPrivate
// private slots
void saveDocumentInfo() const;
void slotTimedMemoryCheck();
void sendGeneratorRequest();
void sendGeneratorPixmapRequest();
void rotationFinished( int page, Okular::Page *okularPage );
void fontReadingProgress( int page );
void fontReadingGotFont( const Okular::FontInfo& font );
void slotGeneratorConfigChanged( const QString& );
void refreshPixmaps( int );
void _o_configChanged();
void doContinueNextMatchSearch(void *pagesToNotifySet, void * match, int currentPage, int searchID, const QString & text, int caseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages);
void doContinuePrevMatchSearch(void *pagesToNotifySet, void * theMatch, int currentPage, int searchID, const QString & text, int theCaseSensitivity, bool moveViewport, const QColor & color, bool noDialogs, int donePages);
void doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct);
void doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QString & text, int caseSensitivity, const QColor & color);
void doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QStringList & words, int caseSensitivity, const QColor & color, bool matchAll);
@ -184,7 +203,7 @@ class DocumentPrivate
QLinkedList< PixmapRequest * > m_pixmapRequestsStack;
QLinkedList< PixmapRequest * > m_executingPixmapRequests;
QMutex m_pixmapRequestsMutex;
QLinkedList< AllocatedPixmap * > m_allocatedPixmapsFifo;
QLinkedList< AllocatedPixmap * > m_allocatedPixmaps;
qulonglong m_allocatedPixmapsTotalMemory;
QList< int > m_allocatedTextPagesFifo;
int m_maxAllocatedTextPages;
@ -225,6 +244,7 @@ class DocumentPrivate
Scripter *m_scripter;
ArchiveData *m_archiveData;
QString m_archivedFileName;
QPointer< FontExtractionThread > m_fontThread;
bool m_fontsCached;
@ -233,11 +253,14 @@ class DocumentPrivate
QSet< View * > m_views;
bool m_annotationEditingEnabled;
bool m_annotationsNeedSaveAs;
bool m_annotationBeingMoved; // is an annotation currently being moved?
bool m_containsExternalAnnotations; // set on opening and never changed
bool m_showWarningLimitedAnnotSupport;
};
}
#endif
/* kate: replace-tabs on; indent-width 4; */

View file

@ -33,13 +33,6 @@
using namespace Okular;
// Deprecated overload for binary compatibility
int FilePrinter::printFile( QPrinter &printer, const QString file, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange )
{
return printFile( printer, file, QPrinter::Portrait, fileDeletePolicy, pageSelectPolicy, pageRange );
}
int FilePrinter::printFile( QPrinter &printer, const QString file,
QPrinter::Orientation documentOrientation, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange )
@ -49,24 +42,6 @@ int FilePrinter::printFile( QPrinter &printer, const QString file,
documentOrientation );
}
// Deprecated function kept for binary compatibility
// This is deprecated because it cannot support different original orientations
// for each document in the list.
int FilePrinter::printFiles( QPrinter &printer, const QStringList &fileList, FileDeletePolicy fileDeletePolicy )
{
FilePrinter fp;
return fp.doPrintFiles( printer, fileList, fileDeletePolicy, FilePrinter::ApplicationSelectsPages, QString(),
QPrinter::Portrait );
}
// Deprecated overload for binary compatibility
int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange )
{
return doPrintFiles( printer, fileList, fileDeletePolicy, pageSelectPolicy, pageRange,
QPrinter::Portrait );
}
int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, const QString &pageRange,
QPrinter::Orientation documentOrientation )
@ -380,15 +355,6 @@ Generator::PrintError FilePrinter::printError( int c )
// Deprecated overload for binary compatibility
QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
const QString &pageRange, const QString &version )
{
return printArguments( printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions,
pageRange, version, QPrinter::Portrait );
}
QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
const QString &pageRange, const QString &version,
@ -516,12 +482,6 @@ QStringList FilePrinter::pages( QPrinter &printer, PageSelectPolicy pageSelectPo
return QStringList(); // AllPages
}
// Deprecated overload for binary compatibility
QStringList FilePrinter::cupsOptions( QPrinter &printer )
{
return cupsOptions( printer, QPrinter::Portrait );
}
QStringList FilePrinter::cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation )
{
QStringList optionList;
@ -635,12 +595,6 @@ QString FilePrinter::mediaPaperSource( QPrinter &printer )
}
}
// Deprecated overload for binary compatibility
QStringList FilePrinter::optionOrientation( QPrinter &printer )
{
return optionOrientation( printer, QPrinter::Portrait );
}
QStringList FilePrinter::optionOrientation( QPrinter &printer, QPrinter::Orientation documentOrientation )
{
// portrait and landscape options rotate the document according to the document orientation

View file

@ -18,9 +18,6 @@
#include <QtCore/QString>
#include <QtGui/QPrinter>
// For KDE_DEPRECATED
#include <kdemacros.h>
#include "okular_export.h"
#include "generator.h"
@ -84,60 +81,6 @@ public:
PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages,
const QString &pageRange = QString() );
/** Print a file using the settings in QPrinter (compatibility overload)
*
* Only supports CUPS and LPR on *NIX. Page Range only supported in CUPS.
* Most settings unsupported by LPR, some settings unsupported by CUPS.
*
* @param printer the print settings to use
* @param file the file to print
* @param fileDeletePolicy if the application or system deletes the file
* @param pageSelectPolicy if the application or system selects the pages to print
* @param pageRange page range to print if SystemSlectsPages and user chooses Selection in Print Dialog
*
* @returns Returns exit code:
* -9 if lpr not found
* -8 if empty file name
* -7 if unable to find file
* -6 if invalid printer state
* -5 if print to file copy failed
* -2 if the KProcess could not be started
* -1 if the KProcess crashed
* otherwise the KProcess exit code
*
* @deprecated Use the overload which takes the documentOrientation instead.
*/
static KDE_DEPRECATED int printFile( QPrinter &printer, const QString file,
FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles,
PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages,
const QString &pageRange = QString() );
/** Print a list of files using the settings in QPrinter
*
* Only supports CUPS and LPR on *NIX.
* Most settings unsupported by LPR, some settings unsupported by CUPS.
*
* @param printer the print settings to use
* @param fileList the files to print
* @param fileDeletePolicy if the application or system deletes the file
*
* @returns Returns exit code:
* -9 if lpr not found
* -8 if empty file list
* -7 if unable to find a file
* -6 if invalid printer state
* -5 if print to file copy failed
* -2 if the KProcess could not be started
* -1 if the KProcess crashed
* otherwise the KProcess exit code
*
* @deprecated Use printFile instead, passing the documentOrientation for each file.
*/
static KDE_DEPRECATED int printFiles( QPrinter &printer, const QStringList &fileList,
FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles );
/** Return the list of pages selected by the user in the Print Dialog
*
* @param printer the print settings to use
@ -209,17 +152,11 @@ protected:
bool detectCupsService();
bool detectCupsConfig();
KDE_DEPRECATED int doPrintFiles( QPrinter &printer, const QStringList fileList,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange );
int doPrintFiles( QPrinter &printer, const QStringList fileList,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange,
QPrinter::Orientation documentOrientation );
KDE_DEPRECATED QStringList printArguments( QPrinter &printer,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
bool useCupsOptions, const QString &pageRange, const QString &version );
QStringList printArguments( QPrinter &printer,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
bool useCupsOptions, const QString &pageRange, const QString &version,
@ -233,12 +170,10 @@ protected:
QStringList pages( QPrinter &printer, PageSelectPolicy pageSelectPolicy,
const QString &pageRange, bool useCupsOptions, const QString &version );
KDE_DEPRECATED QStringList cupsOptions( QPrinter &printer );
QStringList cupsOptions( QPrinter &printer, QPrinter::Orientation documentOrientation );
QStringList optionMedia( QPrinter &printer );
QString mediaPageSize( QPrinter &printer );
QString mediaPaperSource( QPrinter &printer );
KDE_DEPRECATED QStringList optionOrientation( QPrinter &printer );
QStringList optionOrientation( QPrinter &printer, QPrinter::Orientation documentOrientation );
QStringList optionDoubleSidedPrinting( QPrinter &printer );
QStringList optionPageOrder( QPrinter &printer );

View file

@ -10,6 +10,7 @@
#include "generator.h"
#include "generator_p.h"
#include "observer.h"
#include <qeventloop.h>
#include <QtGui/QPrinter>
@ -102,9 +103,9 @@ void GeneratorPrivate::pixmapGenerationFinished()
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( img ) ) );
const int pageNumber = request->page()->number();
q->signalPixmapRequestDone( request );
if ( mPixmapGenerationThread->calcBoundingBox() )
q->updatePageBoundingBox( pageNumber, mPixmapGenerationThread->boundingBox() );
q->signalPixmapRequestDone( request );
}
void GeneratorPrivate::textpageGenerationFinished()
@ -254,7 +255,6 @@ bool Generator::canGenerateTextPage() const
void Generator::generateTextPage( Page *page )
{
Q_D( Generator );
TextPage *tp = textPage( page );
page->setTextPage( tp );
signalTextGenerationDone( page, tp );
@ -478,6 +478,19 @@ void PixmapRequestPrivate::swap()
qSwap( mWidth, mHeight );
}
bool PixmapRequestPrivate::isPreload() const
{
switch ( mPriority )
{
case PAGEVIEW_PRELOAD_PRIO:
case THUMBNAILS_PRELOAD_PRIO:
case PRESENTATION_PRELOAD_PRIO:
return true;
default:
return false;
}
}
class Okular::ExportFormatPrivate : public QSharedData
{
public:

View file

@ -70,6 +70,7 @@ class PixmapRequestPrivate
{
public:
void swap();
bool isPreload() const;
int mId;
int mPageNumber;

View file

@ -12,6 +12,7 @@
// qt/kde includes
#include <qdir.h>
#include <qimage.h>
#include <qstring.h>
#include <qtemporaryfile.h>
@ -30,7 +31,8 @@ class Movie::Private
m_playMode( PlayOnce ),
m_tmp( 0 ),
m_showControls( false ),
m_autoPlay( false )
m_autoPlay( false ),
m_showPosterImage( false )
{
}
@ -39,8 +41,10 @@ class Movie::Private
Rotation m_rotation;
PlayMode m_playMode;
QTemporaryFile *m_tmp;
QImage m_posterImage;
bool m_showControls : 1;
bool m_autoPlay : 1;
bool m_showPosterImage : 1;
};
Movie::Movie( const QString& fileName )
@ -58,7 +62,7 @@ Movie::Movie( const QString& fileName, const QByteArray &data )
* GStreamer backend). Storing the data in a temporary file works fine
* though, not to mention, it releases much needed memory. (gamaral)
*/
d->m_tmp = new QTemporaryFile( QString( "%1/okrXXXXXX_%2" ).arg( QDir::tempPath() ).arg( fileName ) );
d->m_tmp = new QTemporaryFile( QString( "%1/okrXXXXXX" ).arg( QDir::tempPath() ) );
if ( d->m_tmp->open() ) {
d->m_tmp->write( data );
d->m_tmp->flush();
@ -130,3 +134,22 @@ bool Movie::autoPlay() const
return d->m_autoPlay;
}
void Movie::setShowPosterImage( bool show )
{
d->m_showPosterImage = show;
}
bool Movie::showPosterImage() const
{
return d->m_showPosterImage;
}
void Movie::setPosterImage( const QImage &image )
{
d->m_posterImage = image;
}
QImage Movie::posterImage() const
{
return d->m_posterImage;
}

View file

@ -16,6 +16,8 @@
#include <QtCore/QSize>
class QImage;
namespace Okular {
/**
@ -107,6 +109,34 @@ class OKULAR_EXPORT Movie
*/
bool autoPlay() const;
/**
* Sets whether to show a poster image.
*
* @since 4.10
*/
void setShowPosterImage( bool show );
/**
* Whether to show a poster image.
*
* @since 4.10
*/
bool showPosterImage() const;
/**
* Sets the poster image.
*
* @since 4.10
*/
void setPosterImage( const QImage &image );
/**
* Returns the poster image.
*
* @since 4.10
*/
QImage posterImage() const;
private:
class Private;
Private* const d;

View file

@ -48,3 +48,7 @@ bool DocumentObserver::canUnloadPixmap( int ) const
{
return true;
}
void DocumentObserver::notifyCurrentPageChanged( int, int )
{
}

View file

@ -72,8 +72,9 @@ class OKULAR_EXPORT DocumentObserver
Bookmark = 2, ///< Bookmarks has been changed
Highlights = 4, ///< Highlighting information has been changed
TextSelection = 8, ///< Text selection has been changed
Annotations = 16, ///< Annotations has been changed
BoundingBox = 32 ///< Bounding boxes have been changed
Annotations = 16, ///< Annotations have been changed
BoundingBox = 32, ///< Bounding boxes have been changed
NeedSaveAs = 64 ///< Set along with Annotations when Save As is needed or annotation changes will be lost @since 0.15 (KDE 4.9)
};
/**
@ -129,6 +130,16 @@ class OKULAR_EXPORT DocumentObserver
*/
virtual bool canUnloadPixmap( int page ) const;
/**
* This method is called after the current page of the document has been entered.
*
* @param previous The number of the previous page (is @c -1 for the initial page change).
* @param current The number of the current page.
*
* @since 0.16 (KDE 4.10)
*/
virtual void notifyCurrentPageChanged( int previous, int current );
private:
class Private;
const Private* d;

View file

@ -16,7 +16,7 @@ Comment[en_GB]=File format backend for Okular
Comment[es]=Motor de formatos de archivos para Okular
Comment[et]=Okulari failivormingu taustaprogramm
Comment[eu]=Okular-en fitxategi-formatuaren motorra
Comment[fi]=Tiedostomuodot-taustaosa Okular-lukijalle
Comment[fi]=Tiedostomuototaustaosa Okularille
Comment[fr]=Interface du format de fichier d'Okular
Comment[ga]=Inneall formáide comhaid le haghaidh Okular
Comment[gl]=Infraestrutura dun formato de ficheiro para Okular

View file

@ -102,9 +102,9 @@ void PagePrivate::imageRotationDone( RotationJob * job )
}
}
QMatrix PagePrivate::rotationMatrix() const
QTransform PagePrivate::rotationMatrix() const
{
QMatrix matrix;
QTransform matrix;
matrix.rotate( (int)m_rotation * 90 );
switch ( m_rotation )
@ -369,7 +369,7 @@ void PagePrivate::rotateAt( Rotation orientation )
/**
* Rotate the object rects on the page.
*/
const QMatrix matrix = rotationMatrix();
const QTransform matrix = rotationMatrix();
QLinkedList< ObjectRect * >::const_iterator objectIt = m_page->m_rects.begin(), end = m_page->m_rects.end();
for ( ; objectIt != end; ++objectIt )
(*objectIt)->transform( matrix );
@ -405,6 +405,19 @@ const ObjectRect * Page::objectRect( ObjectRect::ObjectType type, double x, doub
return 0;
}
QLinkedList< const ObjectRect * > Page::objectRects( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const
{
QLinkedList< const ObjectRect * > result;
QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
for ( ; it != end; ++it )
if ( ( (*it)->objectType() == type ) && (*it)->contains( x, y, xScale, yScale ) )
result.append( *it );
return result;
}
const ObjectRect* Page::nearestObjectRect( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale, double * distance ) const
{
ObjectRect * res = 0;
@ -506,7 +519,7 @@ void Page::setObjectRects( const QLinkedList< ObjectRect * > & rects )
/**
* Rotate the object rects of the page.
*/
const QMatrix matrix = d->rotationMatrix();
const QTransform matrix = d->rotationMatrix();
QLinkedList< ObjectRect * >::const_iterator objectIt = rects.begin(), end = rects.end();
for ( ; objectIt != end; ++objectIt )
@ -588,7 +601,7 @@ void Page::addAnnotation( Annotation * annotation )
AnnotationObjectRect *rect = new AnnotationObjectRect( annotation );
// Rotate the annotation on the page.
const QMatrix matrix = d->rotationMatrix();
const QTransform matrix = d->rotationMatrix();
annotation->d_ptr->baseTransform( matrix.inverted() );
annotation->d_ptr->annotationTransform( matrix );
@ -736,6 +749,9 @@ void PagePrivate::restoreLocalContents( const QDomNode & pageNode )
QTime time;
time.start();
#endif
// Clone annotationList as root node in restoredLocalAnnotationList
const QDomNode clonedNode = restoredLocalAnnotationList.importNode( childElement, true );
restoredLocalAnnotationList.appendChild( clonedNode );
// iterate over all annotations
QDomNode annotationNode = childElement.firstChild();
@ -803,10 +819,6 @@ void PagePrivate::restoreLocalContents( const QDomNode & pageNode )
void PagePrivate::saveLocalContents( QDomNode & parentNode, QDomDocument & document, PageItems what ) const
{
// only add a node if there is some stuff to write into
if ( m_page->m_annotations.isEmpty() && formfields.isEmpty() )
return;
// create the page node and set the 'number' attribute
QDomElement pageElement = document.createElement( "page" );
pageElement.setAttribute( "number", m_number );
@ -825,7 +837,17 @@ void PagePrivate::saveLocalContents( QDomNode & parentNode, QDomDocument & docum
#endif
// add annotations info if has got any
if ( ( what & AnnotationPageItems ) && !m_page->m_annotations.isEmpty() )
if ( ( what & AnnotationPageItems ) && ( what & OriginalAnnotationPageItems ) )
{
const QDomElement savedDocRoot = restoredLocalAnnotationList.documentElement();
if ( !savedDocRoot.isNull() )
{
// Import and append node in target document
const QDomNode importedNode = document.importNode( savedDocRoot, true );
pageElement.appendChild( importedNode );
}
}
else if ( ( what & AnnotationPageItems ) && !m_page->m_annotations.isEmpty() )
{
// create the annotationList
QDomElement annotListElement = document.createElement( "annotationList" );

View file

@ -223,6 +223,12 @@ class OKULAR_EXPORT Page
*/
const ObjectRect * objectRect( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const;
/**
* Returns all object rects of the given @p type which are at point (@p x, @p y) at scale (@p xScale, @p yScale).
* @since 0.16 (KDE 4.10)
*/
QLinkedList< const ObjectRect * > objectRects( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const;
/**
* Returns the object rect of the given @p type which is nearest to the point (@p x, @p y) at scale (@p xScale, @p yScale).
*

View file

@ -14,16 +14,15 @@
// qt/kde includes
#include <qlinkedlist.h>
#include <qmap.h>
#include <qmatrix.h>
#include <qtransform.h>
#include <qstring.h>
#include <qdom.h>
// local includes
#include "global.h"
#include "area.h"
class QColor;
class QDomDocument;
class QDomNode;
namespace Okular {
@ -43,7 +42,11 @@ enum PageItem
None = 0,
AnnotationPageItems = 0x01,
FormFieldPageItems = 0x02,
AllPageItems = 0xff
AllPageItems = 0xff,
/* If set along with AnnotationPageItems, tells saveLocalContents to save
* the original annotations (if any) instead of the modified ones */
OriginalAnnotationPageItems = 0x100
};
Q_DECLARE_FLAGS(PageItems, PageItem)
@ -54,7 +57,7 @@ class PagePrivate
~PagePrivate();
void imageRotationDone( RotationJob * job );
QMatrix rotationMatrix() const;
QTransform rotationMatrix() const;
/**
* Loads the local contents (e.g. annotations) of the page.
@ -125,6 +128,7 @@ class PagePrivate
QString m_label;
bool m_isBoundingBoxKnown : 1;
QDomDocument restoredLocalAnnotationList; // <annotationList>...</annotationList>
};
}

View file

@ -9,7 +9,7 @@
#include "rotationjob_p.h"
#include <QtGui/QMatrix>
#include <QtGui/QTransform>
using namespace Okular;
@ -50,14 +50,14 @@ void RotationJob::run()
return;
}
QMatrix matrix = rotationMatrix( mOldRotation, mNewRotation );
QTransform matrix = rotationMatrix( mOldRotation, mNewRotation );
mRotatedImage = mImage.transformed( matrix );
}
QMatrix RotationJob::rotationMatrix( Rotation from, Rotation to )
QTransform RotationJob::rotationMatrix( Rotation from, Rotation to )
{
QMatrix matrix;
QTransform matrix;
if ( from == Rotation0 ) {
if ( to == Rotation90 )

View file

@ -11,7 +11,7 @@
#define _OKULAR_ROTATIONJOB_P_H_
#include <QtGui/QImage>
#include <QtGui/QMatrix>
#include <QtGui/QTransform>
#include <threadweaver/Job.h>
@ -35,7 +35,7 @@ class RotationJob : public ThreadWeaver::Job
int id() const;
PagePrivate * page() const;
static QMatrix rotationMatrix( Rotation from, Rotation to );
static QTransform rotationMatrix( Rotation from, Rotation to );
protected:
virtual void run();

View file

@ -174,7 +174,7 @@ class TinyTextEntity
: QString::fromRawData( d.data, length );
}
inline NormalizedRect transformedArea( const QMatrix &matrix ) const
inline NormalizedRect transformedArea( const QTransform &matrix ) const
{
NormalizedRect transformed_area = area;
transformed_area.transform( matrix );
@ -215,7 +215,7 @@ NormalizedRect* TextEntity::area() const
return m_area;
}
NormalizedRect TextEntity::transformedArea(const QMatrix &matrix) const
NormalizedRect TextEntity::transformedArea(const QTransform &matrix) const
{
NormalizedRect transformed_area = *m_area;
transformed_area.transform( matrix );
@ -359,7 +359,7 @@ RegularAreaRect * TextPage::textArea ( TextSelection * sel) const
*/
RegularAreaRect * ret= new RegularAreaRect;
const QMatrix matrix = d->m_page ? d->m_page->rotationMatrix() : QMatrix();
const QTransform matrix = d->m_page ? d->m_page->rotationMatrix() : QTransform();
#if 0
int it = -1;
int itB = -1;
@ -840,7 +840,7 @@ RegularAreaRect* TextPagePrivate::findTextInternalForward( int searchID, const Q
const TextList::ConstIterator &start,
const TextList::ConstIterator &end )
{
const QMatrix matrix = m_page ? m_page->rotationMatrix() : QMatrix();
const QTransform matrix = m_page ? m_page->rotationMatrix() : QTransform();
RegularAreaRect* ret=new RegularAreaRect;
@ -863,7 +863,6 @@ RegularAreaRect* TextPagePrivate::findTextInternalForward( int searchID, const Q
{
curEntity = *it;
const QString &str = curEntity->text();
kDebug() << str;
if ( !offsetMoved && ( it == start ) )
{
if ( m_searchPoints.contains( searchID ) )
@ -956,7 +955,7 @@ RegularAreaRect* TextPagePrivate::findTextInternalBackward( int searchID, const
const TextList::ConstIterator &start,
const TextList::ConstIterator &end )
{
const QMatrix matrix = m_page ? m_page->rotationMatrix() : QMatrix();
const QTransform matrix = m_page ? m_page->rotationMatrix() : QTransform();
RegularAreaRect* ret=new RegularAreaRect;

View file

@ -16,7 +16,7 @@
#include "okular_export.h"
#include "global.h"
class QMatrix;
class QTransform;
namespace Okular {
@ -70,7 +70,7 @@ class OKULAR_EXPORT TextEntity
/**
* Returns the transformed area of the text entity.
*/
NormalizedRect transformedArea(const QMatrix &matrix) const;
NormalizedRect transformedArea(const QTransform &matrix) const;
private:
QString m_text;

View file

@ -14,7 +14,7 @@
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QPair>
#include <QtGui/QMatrix>
#include <QtGui/QTransform>
class SearchPoint;
class TinyTextEntity;

View file

@ -10,10 +10,10 @@
#ifndef _OKULAR_VERSION_H_
#define _OKULAR_VERSION_H_
#define OKULAR_VERSION_STRING "0.14.80"
#define OKULAR_VERSION_STRING "0.15.70"
#define OKULAR_VERSION_MAJOR 0
#define OKULAR_VERSION_MINOR 14
#define OKULAR_VERSION_RELEASE 80
#define OKULAR_VERSION_MINOR 15
#define OKULAR_VERSION_RELEASE 70
#define OKULAR_MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c))
#define OKULAR_VERSION \

BIN
doc/bookmark-management.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
doc/configure-editor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -1,6 +1,7 @@
<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
<!ENTITY kappname "&okular;">
<!ENTITY latex "L<superscript>A</superscript>T<subscript>E</subscript>X">
<!ENTITY package "kdegraphics">
<!ENTITY kpdf "<application>KPDF</application>">
<!ENTITY PDF "<acronym>PDF</acronym>">
@ -36,8 +37,8 @@ Context menu actions like Rename Bookmarks etc)
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>
<legalnotice>&FDLNotice;</legalnotice>
<date>2010-10-05</date>
<releaseinfo>0.11.80 (&kde; 4.6)</releaseinfo>
<date>2012-09-09</date>
<releaseinfo>0.15.70 (&kde; 4.10)</releaseinfo>
<!-- Abstract about this handbook -->
<abstract>
<para>&okular; is a &kde; universal document viewer based on &kpdf; code.</para>
@ -67,9 +68,9 @@ Context menu actions like Rename Bookmarks etc)
improved presentation support and annotation support.
</para>
<para>
&okular; supports a lot of different formats like PDF, Postscript, Tiff, CHM, DjVU, Images (png, jpg, &etc;)
&okular; supports a lot of different formats like PDF, Postscript, Tiff, CHM, DjVU, Images (png, jpg, &etc;)
XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub and Fax.
For all supported formats and their features see <ulink url="http://okular.kde.org/formats.php">
For all supported formats and their features see <ulink url="http://okular.kde.org/formats.php">
&okular; Document Format Handlers</ulink>.
</para>
<screenshot>
@ -106,8 +107,8 @@ Context menu actions like Rename Bookmarks etc)
the <menuchoice><guimenu>File</guimenu><guisubmenu>Open Recent</guisubmenu></menuchoice> menu.
</para>
<para>&okular; is the default &kde; application for PDF and Postscript files, launched when you click with the
&LMB; on such a file type in the filemanager. If you want to open any file whose format is supported by &okular;
use <menuchoice><guimenu>Open with...</guimenu><guimenuitem>&okular;</guimenuitem> </menuchoice> from context
&LMB; on such a file type in the filemanager. If you want to open any file whose format is supported by &okular;
use <menuchoice><guimenu>Open with...</guimenu><guimenuitem>&okular;</guimenuitem> </menuchoice> from context
menu in the filemanager.
</para>
<para>
@ -123,7 +124,7 @@ Presentation mode: add Up (previous page) and Down (next page) keys
Add a 'Find Previous' entry
-->
<para>
There are multiple ways of scrolling the viewing area. One is to use the
There are multiple ways of scrolling the viewing area. One is to use the
<keycap>Up Arrow</keycap> and <keycap>Down Arrow</keycap> keys. You may also use
the scrollbar, your mousewheel or the <keycap>Page Up</keycap> and <keycap>Page Down</keycap>
keys.
@ -135,8 +136,8 @@ Add a 'Find Previous' entry
</guimenuitem></menuchoice>.
</para>
<para>If you want to read a document with several pages use the automatic scrolling feature of &okular;.
Start automatic scrolling with <keycombo action="simul">&Shift;<keysym>Down Arrow</keysym></keycombo> or
<keycombo action="simul">&Shift;<keysym>Up Arrow</keysym></keycombo>. Then use these keys to increase and
Start automatic scrolling with <keycombo action="simul">&Shift;<keysym>Down Arrow</keysym></keycombo> or
<keycombo action="simul">&Shift;<keysym>Up Arrow</keysym></keycombo>. Then use these keys to increase and
decrease the scrolling speed. You can start or stop automatic scrolling temporarily by pressing the &Shift; key;
pressing any other key deactivates this feature.
</para>
@ -163,15 +164,15 @@ Add a 'Find Previous' entry
</listitem>
<listitem>
<para>
If the document has bookmarks, enable the <guilabel>Bookmarks</guilabel> view
If the document has bookmarks, enable the <guilabel>Bookmarks</guilabel> view
and click them to go to the associated page.
If bookmarks are not only shown for the current document, you can quickly
If bookmarks are not only shown for the current document, you can quickly
switch to bookmarks in all recently opened files.
</para>
</listitem>
<listitem>
<para>
If the document has annotations, enable the <guilabel>Reviews</guilabel> view
If the document has annotations, enable the <guilabel>Reviews</guilabel> view
and click the annotations or select them with the <keycap>Up Arrow</keycap> and <keycap>Down Arrow</keycap> keys and press <keycap>Return</keycap> to go to the associated page.
</para>
</listitem>
@ -190,9 +191,9 @@ Add a 'Find Previous' entry
<itemizedlist>
<listitem>
<para>
You can go to the beginning of the document using
You can go to the beginning of the document using
<keycombo action="simul">&Ctrl;<keycap>Home</keycap></keycombo> or
using
using
<menuchoice>
<guimenu>Go</guimenu>
<guimenuitem>Beginning of the document</guimenuitem>
@ -201,9 +202,9 @@ Add a 'Find Previous' entry
</listitem>
<listitem>
<para>
You can go to the end of the document using
You can go to the end of the document using
<keycombo action="simul">&Ctrl;<keycap>End</keycap></keycombo> or
using
using
<menuchoice>
<guimenu>Go</guimenu>
<guimenuitem>End of the document</guimenuitem>
@ -214,7 +215,7 @@ Add a 'Find Previous' entry
<para>
You can go forward in the document using <keycap>Space</keycap> or <keycap>Page Down</keycap>.
To go to the next page of the document use the <guibutton>Next Page</guibutton> Toolbar
button or
button or
<menuchoice>
<guimenu>Go</guimenu>
<guimenuitem>Next Page</guimenuitem>
@ -225,7 +226,7 @@ Add a 'Find Previous' entry
<para>
You can go back in the document using &Backspace; or <keycap>Page Up</keycap>.
To go to the previous page of the document use <guibutton>Previous Page</guibutton> Toolbar
button or
button or
<menuchoice>
<guimenu>Go</guimenu>
<guimenuitem>Previous Page</guimenuitem>
@ -241,7 +242,7 @@ Add a 'Find Previous' entry
enabled in
<menuchoice><guimenu>View</guimenu><guimenuitem>Presentation</guimenuitem></menuchoice>.
It shows the document on a page per page basis. The pages are shown with
zoom to page, that means all the page is visible.
zoom to page, that means all the page is visible.
</para>
<note>
<para>
@ -277,12 +278,12 @@ Add a 'Find Previous' entry
<para>
You can also draw on the current page with a pencil. Click on the
<guilabel>Toggle Drawing Mode</guilabel> icon in the top bar to enable or disable the possibility
of draw in the presentation mode. The drawings are cleared automatically when leaving the presentation
of draw in the presentation mode. The drawings are cleared automatically when leaving the presentation
mode, switching to another page, or manually selecting the <guilabel>Erase Drawings</guilabel> icon in the top bar.
</para>
<para>
The presentation mode has support for more than one screen in a multi-monitor configuration.
With more than one screen a new button will appear in the top bar, with the icon of a screen:
The presentation mode has support for more than one screen in a multi-monitor configuration.
With more than one screen a new button will appear in the top bar, with the icon of a screen:
this is a drop down box that allows you to move the presentation to any of the other available screens.
</para>
<para>
@ -290,6 +291,42 @@ Add a 'Find Previous' entry
description in the chapter <link linkend="configpresentation">Configuring &okular;</link>.
</para>
</sect1>
<sect1 id="inverse_search">
<title>Inverse Search between &latex; Editors and &okular;</title>
<para>Inverse search is a very useful feature when you are writing a &latex; document yourself. If everything is set up properly, you can
click into &okular;'s window with the <mousebutton>left</mousebutton> mouse button while pressing &Shift;. After that editor loads the &latex; source file and jumps to
the proper paragraph.</para>
<para>Inverse search cannot work unless:</para>
<itemizedlist>
<listitem><para>The source file has been compiled successfully.</para></listitem>
<listitem><para>&okular; knows which editor you would like to use.</para></listitem>
</itemizedlist>
<para>With this feature of &okular;, a left mouse click while pressing &Shift; in the &DVI; or &PDF; document will
result in editor opening the corresponding &latex; document and attempt to go to the
corresponding line. Remember to tell &okular; to use proper editor, in &okular;'s
menu item <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure Okular...</guimenuitem></menuchoice>
(on the page <guimenuitem>Editor</guimenuitem>).</para>
<para>For more details on editor configuration please refer to the <link linkend="configeditor">corresponding section of this manual</link>.</para>
<screenshot>
<screeninfo>Configuring &okular;</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="configure-editor.png" format="PNG" />
</imageobject>
<textobject>
<phrase>Configuring editor in &okular;</phrase>
</textobject>
<caption><para>Configuring editor in &okular;</para></caption>
</mediaobject>
</screenshot>
</sect1>
</chapter>
<chapter id="advanced">
@ -298,7 +335,7 @@ Add a 'Find Previous' entry
<title>Embedded Files</title>
<para>
If the current document has some files embedded in it, when you open it a yellow bar
will appear above the page view to notify you about the embedded files.
will appear above the page view to notify you about the embedded files.
</para>
<screenshot>
<screeninfo>The embedded files bar</screeninfo>
@ -322,7 +359,7 @@ Add a 'Find Previous' entry
<title>Forms</title>
<para>
If the current document has forms, when you open it a bar
will appear above the page view where you can enable the forms.
will appear above the page view where you can enable the forms.
</para>
<screenshot>
<screeninfo>The forms bar</screeninfo>
@ -361,7 +398,7 @@ Add a 'Find Previous' entry
</mediaobject>
</screenshot>
<para>&okular; has two different kind of annotations:</para>
<para>Text annotations like <guilabel>Yellow Highlighter</guilabel> and <guilabel>Black Underlining</guilabel>
<para>Text annotations like <guilabel>Yellow Highlighter</guilabel> and <guilabel>Black Underlining</guilabel>
for files with text like &eg; PDF.</para>
<para>Graphic annotations like <guilabel>Note</guilabel>, <guilabel>Inline Note</guilabel>, <guilabel>Green Freehand Line</guilabel>, <guilabel>Straight Yellow Line</guilabel>, <guilabel>Blue Polygon</guilabel>, <guilabel>Stamp</guilabel> and <guilabel>Cyan Ellipse</guilabel> for all formats supported by &okular;.</para>
<para>Using the context menu either in the <guilabel>Reviews</guilabel> view of the navigation panel or in the main window you can open a <guilabel>Pop up Note</guilabel> for any kind of annotation and add or edit comments.</para>
@ -369,6 +406,20 @@ Add a 'Find Previous' entry
<para>
Since &kde; 4.2, &okular; has the "document archiving" feature. This is an &okular;-specific format for carrying the document plus various metadata related to it (currently only annotations). You can save a "document archive" from the open document by choosing <menuchoice><guimenu>File</guimenu><guisubmenu>Export As</guisubmenu><guimenuitem>Document Archive</guimenuitem></menuchoice>. To open an &okular; document archive, just open it with &okular; as it would be &eg; a &PDF; document.
</para>
<para>
Since &okular; 0.15 you can <emphasis>also</emphasis> save annotations directly into PDF files. This feature is only available if &okular; has been built with version 0.20 or later of <ulink url="http://poppler.freedesktop.org/">Poppler rendering library</ulink>. You can use <menuchoice><guimenu>File</guimenu> <guimenuitem>Save As...</guimenuitem></menuchoice> to save the copy of &PDF; file with annotations.
</para>
<note>
<para>
It is not possible to save annotations into &PDF; file if original file was encrypted and &okular; uses Poppler libraries of version which is lower than 0.22.
</para>
</note>
<note>
<para>
If you open a &PDF; with existing annotations, your annotation changes are not automatically saved in the internal local data folder, and you need to save the modified document (using <menuchoice><guimenu>File</guimenu><guimenuitem>Save As...</guimenuitem></menuchoice>) before closing it. Should you forget to do this &okular; will show confirmation window that allows you to save the document.
</para>
</note>
<note>
<para>
Due to DRM limitations (typically with &PDF; documents), adding, editing some properties
@ -406,7 +457,7 @@ Add a 'Find Previous' entry
</para>
<note>
<para>Using stamps a single click just places a square stamp (useful for icons).
To add a rectangular stamp you can click with the &LMB; and hold to place the top-left point,
To add a rectangular stamp you can click with the &LMB; and hold to place the top-left point,
then drag to place the bottom-right one.</para>
</note>
</sect2>
@ -446,7 +497,7 @@ Add a 'Find Previous' entry
</mediaobject>
</screenshot>
<para>
To move an annotation, hold down the &Ctrl; key, move the mouse pointer on it and
To move an annotation, hold down the &Ctrl; key, move the mouse pointer on it and
then start dragging with the &LMB;.
</para>
<note>
@ -457,8 +508,50 @@ Add a 'Find Previous' entry
</note>
</sect2>
</sect1>
<sect1 id="bookmark-management">
<title>Bookmark Management</title>
<para>
&okular; has a very flexible bookmark system. &okular; saves the position on the page in bookmark and allows you to define more than one bookmark per page.
</para>
<para>
To manage bookmarks in &okular; you can use <guilabel>Bookmarks</guilabel> view from <guilabel>Navigation Panel</guilabel>, <link linkend="menubookmarks">Bookmarks menu</link> or context menu of document view (click with &RMB; to open it).
</para>
<sect2 id="bookmarks-view">
<title>Bookmarks view</title>
<para>
To open <guilabel>Bookmarks</guilabel> view click on <guilabel>Bookmarks</guilabel> item on the <guilabel>Navigation Panel</guilabel>. If the <guilabel>Navigation Panel</guilabel> is not shown, use <menuchoice><shortcut><keycap>F7</keycap></shortcut> <guimenu>Settings</guimenu><guimenuitem>Show Navigation Panel</guimenuitem>
</menuchoice> main menu item to make it visible.
</para>
<screenshot>
<screeninfo>Bookmark view context menu</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="bookmark-management.png" format="PNG" />
</imageobject>
<textobject>
<phrase>Bookmark view context menu</phrase>
</textobject>
</mediaobject>
</screenshot>
<para>
The filter bar at the top of <guilabel>Bookmarks</guilabel> view can be used to filter the content of bookmark list pane according to the text in the box.
</para>
<para>
The list pane permits to view the bookmark list in a tree-like fashion: each document in the list can be <quote>expanded</quote> or <quote>collapsed</quote> by clicking on the <guiicon>&lt;</guiicon> or <guiicon>v</guiicon> icon next to it.
</para>
<para>
Click on <inlinemediaobject><imageobject><imagedata fileref="rating.png" format="PNG"/></imageobject></inlinemediaobject> icon below the list to show only the bookmarks from the current document.
</para>
<para>
Right-click menu of document item can be used to open document, rename its item or remove it from the list. Remember that the removal of a document item leads to the removal of all bookmarks in the corresponding document.
</para>
<para>
Right-click menus of individual bookmark items allow you to go to the bookmark, rename or remove it.
</para>
</sect2>
</sect1>
</chapter>
<chapter id="primary-menu-items">
<title>The Menubar</title>
@ -493,7 +586,7 @@ Add a 'Find Previous' entry
<para>
<action>Open</action> a file which was used previously from a
submenu. If a file is currently being displayed it
will be closed. For more information, see the section about
will be closed. For more information, see the section about
<link linkend="opening">Opening Files</link>.
</para>
</listitem>
@ -534,7 +627,7 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Save</action> the currently open file under a different name using the document backend. With the &PDF; backend (Poppler >= 0.8 required) it is possible to save the document with the changed values of the form fields. <!--Only useful for pdf? what happens with other formats/backends?--></para>
<para><action>Save</action> the currently open file under a different name using the document backend. With the &PDF; backend (Poppler >= 0.8 required) it is possible to save the document with the changed values of the form fields.<!--Only useful for pdf? what happens with other formats/backends?--> It can be possible (provided that the data were not secured using DRM) to save annotations with &PDF; files (Poppler >= 0.22 required).</para>
</listitem>
</varlistentry>
@ -546,7 +639,7 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Save</action> a copy of the currently open file under a different name
<para><action>Save</action> a copy of the currently open file under a different name
without using the current document backend.</para>
</listitem>
</varlistentry>
@ -578,7 +671,7 @@ Add a 'Find Previous' entry
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
@ -662,7 +755,7 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Copy</action> the currently selected text in
<para><action>Copy</action> the currently selected text in
<guibutton>Text Selection</guibutton> mode to the clipboard.</para>
</listitem>
</varlistentry>
@ -678,7 +771,7 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Selects</action> all the text (if the document provides it). This works only in
<para><action>Selects</action> all the text (if the document provides it). This works only in
<guibutton>Text Selection</guibutton> mode.</para>
</listitem>
</varlistentry>
@ -728,7 +821,7 @@ Add a 'Find Previous' entry
</varlistentry>
</variablelist>
</sect1>
<sect1 id="menuview">
<title>The View Menu</title>
<variablelist>
@ -821,7 +914,7 @@ Add a 'Find Previous' entry
<listitem>
<para>This submenu makes you choose the view mode for the pages. The possible
options are: <guimenuitem>Single Page</guimenuitem> (only one page per row),
<guimenuitem>Facing Pages</guimenuitem> (two pages per row, in a book style),
<guimenuitem>Facing Pages</guimenuitem> (two pages per row, in a book style),
<guimenuitem>Facing Pages (Center First Page)</guimenuitem> and
<guimenuitem>Overview</guimenuitem> (the number of columns is the one
specified in the <link linkend="configure">&okular; settings</link>).</para>
@ -1008,7 +1101,20 @@ Add a 'Find Previous' entry
</term>
<listitem>
<para>
<action>Add or remove a bookmark for the current page</action>.
<action>Add or remove a bookmark for the current position</action>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<guimenu>Bookmarks</guimenu>
<guimenuitem>Rename Bookmark</guimenuitem>
</menuchoice>
</term>
<listitem>
<para>
<action>Rename a bookmark for the current position</action>.
</para>
</listitem>
</varlistentry>
@ -1020,8 +1126,8 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Go to the previous bookmarked page</action>, or do nothing if there
are no bookmarked pages prior to the current one.</para>
<para><action>Go to the previous bookmark</action>, or do nothing if there
are no bookmarks prior to the current one.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1032,8 +1138,8 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para><action>Go to the next bookmarked page</action>, or do nothing if there
are no bookmarked pages after the current one.</para>
<para><action>Go to the next bookmark</action>, or do nothing if there
are no bookmarks after the current one.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1044,9 +1150,9 @@ Add a 'Find Previous' entry
</menuchoice>
</term>
<listitem>
<para>This is an always disabled action that appears in this menu only if the current document has
no bookmarks. Otherwise a list of all bookmarked pages is displayed here. Clicking on these bookmarks
allows you to go directly to the associated pages.</para>
<para>This is an always disabled action that appears in this menu only if the current document has
no bookmarks. Otherwise a list of all bookmarks is displayed here. Clicking on these bookmarks
allows you to go directly to the associated position.</para>
</listitem>
</varlistentry>
</variablelist>
@ -1159,9 +1265,9 @@ Add a 'Find Previous' entry
</term>
<listitem>
<para><action>Toggle the Menubar display</action> on and off. Once
hidden it can be made visible using the shortcut
hidden it can be made visible using the shortcut
<keycombo action="simul">&Ctrl;<keycap>M</keycap></keycombo> again.
If the menubar is hidden, the context menu opened with a right mouse button
If the menubar is hidden, the context menu opened with a right mouse button
click anywhere in the view area has an extra entry <guimenuitem>Show Menubar</guimenuitem>.</para>
</listitem>
</varlistentry>
@ -1188,6 +1294,17 @@ Add a 'Find Previous' entry
<para><action>Toggle the navigation panel</action> on and off.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<guimenu>Settings</guimenu>
<guimenuitem>Show Page Bar</guimenuitem>
</menuchoice>
</term>
<listitem>
<para><action>Toggle the page bar</action> at the bottom of document area on and off to save vertical place in &okular; window.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
@ -1252,14 +1369,14 @@ Add a 'Find Previous' entry
window.</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1 id="menuhelp">
<title>The Help Menu</title>
&help.menu.documentation;
</sect1>
</chapter>
<chapter id="configure">
<title>Configuring &okular;</title>
@ -1332,6 +1449,21 @@ Add a 'Find Previous' entry
load, &etc;.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Display document title in title bar if available</guilabel></term>
<listitem>
<para>Whether to show the current document title in the title bar of &okular; window. If no metadata for title
found in the document or this item is unchecked &okular; shows filename of the document.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>When not displaying document title</guilabel></term>
<listitem>
<para>You can choose any of two options, <guilabel>Display file name only</guilabel> or <guilabel>Display full file path</guilabel>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Obey DRM limitations</guilabel></term>
<listitem>
@ -1368,7 +1500,15 @@ Add a 'Find Previous' entry
<term><guilabel>Overview columns</guilabel></term>
<listitem>
<para>
This options represent the number of columns to use in the overview mode.
This option represents the number of columns to use in the overview mode.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Page Up/Down overlap</guilabel></term>
<listitem>
<para>
Here you can define the percentage of the current viewing area that should be visible after pressing <keycap>Page Up</keycap>/<keycap>Page Down</keycap> keys.
</para>
</listitem>
</varlistentry>
@ -1414,7 +1554,7 @@ Add a 'Find Previous' entry
<varlistentry>
<term><guilabel>Change Dark &amp; Light Colors</guilabel></term>
<listitem>
<para><action>Changes</action> the dark and light color to your preference, that means
<para><action>Changes</action> the dark and light color to your preference, that means
black will not be rendered as black but as the selected dark color and white
will not be rendered as white but as the selected light color.</para>
</listitem>
@ -1440,21 +1580,14 @@ Add a 'Find Previous' entry
outline or opaque fill styles and increase speed on selections.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Enable background generation</guilabel></term>
<listitem>
<para>Use a background thread to generate the pages. By disabling
this option the user interface will become less reactive (will be blocked
if necessary), but pages will be displayed a bit faster.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Memory Usage</guilabel></term>
<listitem>
<para>&okular; can achieve best performance by tuning the memory usage, based on your system and your tastes.
The more memory you let it to use, the faster the program will behave. The Default profile is good
for every system, but you can prevent &okular; from using more memory than necessary by selecting the Low
profile, or let it get the most out of your system using Aggressive.</para>
profile, or let it get the most out of your system using Aggressive. Use Greedy profile to preload all
pages without risk of system memory overfull (only 50% of total memory or free memory will be used).</para>
</listitem>
</varlistentry>
</variablelist>
@ -1505,6 +1638,12 @@ Add a 'Find Previous' entry
<para>Whether to show a summary page at the beginning of the presentation with the title, author and number of pages of the document.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Enable transitions</guilabel></term>
<listitem>
<para>Use this checkbox to enable or disable transition effects between pages.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Default transition</guilabel></term>
<listitem>
@ -1515,7 +1654,7 @@ Add a 'Find Previous' entry
<varlistentry>
<term><guilabel>Placement</guilabel></term>
<listitem>
<para>In this section you can select the <guilabel>Screen</guilabel> used to display the presentation.</para>
<para>In this section you can select the <guilabel>Screen</guilabel> used to display the presentation.</para>
<para><guilabel>Current Screen</guilabel> is same screen of the &okular; window that starts the presentation mode.</para>
<para><guilabel>Default Screen</guilabel> is the screen marked as default in the xinerama configuration.</para>
<para><guilabel>Screen 0</guilabel>, <guilabel>Screen 1</guilabel> &etc; are the available screens.</para>
@ -1541,15 +1680,38 @@ Add a 'Find Previous' entry
<varlistentry>
<term><guilabel>Editor</guilabel></term>
<listitem>
<para>Choose the editor you want to launch when &okular; wants to open a source file.
This is the case when the document has references to the various points (usually row and column number) of sources it was generated from. The &DVI; format supports natively the addition of the information about the sources the LaTeX document was generated from. A similar system exists for &PDF; documents, called <acronym>pdfsync</acronym>, which stores these extra information in an external file named after the &PDF; file itself (for example <filename>mydocument.pdfsync</filename> for <filename>mydocument.pdf</filename>).
<para>Choose the editor you want to launch when &okular; wants to open a source file.
This is the case when the document has references to the various points (usually row and column number) of sources it was generated from. The &DVI; format supports natively the addition of the information about the sources the LaTeX document was generated from. A similar system exists for &PDF; documents, called <acronym>pdfsync</acronym>, which stores these extra information in an external file named after the &PDF; file itself (for example <filename>mydocument.pdfsync</filename> for <filename>mydocument.pdf</filename>).
</para>
<para>
&okular; ships with preconfigured settings for the following editors: <ulink url="http://kate-editor.org/">&kate;</ulink>, <ulink url="http://kile.sourceforge.net/">Kile</ulink>, <ulink url="http://www.scintilla.org/SciTE.html">SciTE</ulink>, <ulink url="http://www.gnu.org/software/emacs/">Emacs client</ulink>, and <ulink url="http://www.lyx.org/">LyX client</ulink>.
</para>
<note>
<para>
To use inverse search in <application>Kile</application>, you have to compile your &latex; file with the <guilabel>Modern</guilabel> configuration.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Command</guilabel></term>
<listitem>
<para>This is the command and its parameters to invoke the selected editor with the source file of the actual document.</para>
<para>This field will be filled automatically if you use one of the preconfigured editors. Otherwise, please choose <guimenuitem>Custom Text Editor</guimenuitem> in <guilabel>Editor</guilabel> drop-down list and refer to the documentation on your favorite editor to find the proper command.
</para>
<para>You can use the following placeholders:</para>
<itemizedlist>
<listitem>
<para>%f - the file name</para>
</listitem>
<listitem>
<para>%l - the line of the file to be reached</para>
</listitem>
<listitem>
<para>%c - the column of the file to be reached</para>
</listitem>
</itemizedlist>
<para>If %f is not specified, then the document name is appended to the specified command.</para>
</listitem>
</varlistentry>
</variablelist>
@ -1557,18 +1719,18 @@ Add a 'Find Previous' entry
</chapter>
<chapter id="credits">
<title>Credits and License</title>
<itemizedlist>
<title>Program Copyright:</title>
<listitem><para>Albert Astals Cid<email>aacid@kde.org</email> </para></listitem>
<listitem><para>Pino Toscano <email>pino@kde.org</email> Current maintainer</para></listitem>
<listitem><para>Enrico Ros<email>eros.kde@email.it</email> &kpdf; developer</para></listitem>
<listitem><para>Albert Astals Cid <email>aacid@kde.org</email> Current maintainer</para></listitem>
<listitem><para>Pino Toscano <email>pino@kde.org</email></para></listitem>
<listitem><para>Enrico Ros <email>eros.kde@email.it</email> &kpdf; developer</para></listitem>
</itemizedlist>
<itemizedlist>
<title>Documentation Copyright:</title>
<listitem><para>Albert Astals Cid<email>aacid@kde.org</email> Author</para></listitem>
<listitem><para>Titus Laska<email>titus.laska@gmx.de</email> Some updates and additions</para></listitem>
<listitem><para>Albert Astals Cid <email>aacid@kde.org</email> Author</para></listitem>
<listitem><para>Titus Laska <email>titus.laska@gmx.de</email> Some updates and additions</para></listitem>
<listitem><para>Pino Toscano <email>pino@kde.org</email></para></listitem>
</itemizedlist>
<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
@ -1593,7 +1755,7 @@ Add a 'Find Previous' entry
&install.compile.documentation;
</sect1>
</appendix>
&documentation.index;
&documentation.index;
</book>

BIN
doc/rating.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

View file

@ -22,7 +22,7 @@ Description[eo]=Kio-sklavo por montri la WinHelp dosierojn
Description[es]=Un «kioslave» para mostrar archivos WinHelp
Description[et]=KIO-moodul WinHelp-failide näitamiseks
Description[eu]=WinHelp fitxategiak bistaratzeko kioslave bat
Description[fi]=Kioslave WinHelp-tiedostojen näyttämiseksi
Description[fi]=WinHelp-tiedostoja näyttävä kioslave
Description[fr]=Module d'entrées / sorties pour l'affichage des fichiers d'aide Win Help
Description[ga]=Sclábhaí KIO a thaispeánann comhaid WinHelp
Description[gl]=Un kioslave para mostrar ficheiros WinHelp

View file

@ -75,7 +75,7 @@ Comment[en_GB]=Windows HTMLHelp backend for Okular
Comment[es]=Motor de archivos de ayuda en HTML de Windows para Okular
Comment[et]=Okulari Windowsi HTMLHelp-failide taustaprogramm
Comment[eu]=Okular-en Windows HTMLHelp motorra
Comment[fi]=Windows HTMLHelp -taustaosa Okular-lukijalle
Comment[fi]=Windows HTMLHelp -taustaosa Okularille
Comment[fr]=Interface d'Okular pour les fichiers d'aide Windows HTMLHelp
Comment[ga]=Inneall HTMLHelp Windows le haghaidh Okular
Comment[gl]=Infraestrutura de ficheiros Windows HTMLHelp para Okular

View file

@ -143,7 +143,9 @@ X-KDE-Keywords[ga]=chm
X-KDE-Keywords[hu]=chm
X-KDE-Keywords[it]=chm
X-KDE-Keywords[kk]=chm
X-KDE-Keywords[km]=chm
X-KDE-Keywords[ko]=chm
X-KDE-Keywords[lv]=chm
X-KDE-Keywords[nb]=chm
X-KDE-Keywords[nds]=CHM
X-KDE-Keywords[nl]=chm
@ -159,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=chm,ЦХМ
X-KDE-Keywords[sr@ijekavianlatin]=chm,CHM
X-KDE-Keywords[sr@latin]=chm,CHM
X-KDE-Keywords[sv]=chm
X-KDE-Keywords[tr]=chm
X-KDE-Keywords[uk]=chm
X-KDE-Keywords[x-test]=xxchmxx
X-KDE-Keywords[zh_CN]=chm

View file

@ -16,7 +16,7 @@ Name[eo]=ComicBook
Name[es]=Comic Book
Name[et]=Koomiks
Name[eu]=Komikia
Name[fi]=Sarjakuva
Name[fi]=Comic Book
Name[fr]=« Comic Book »
Name[ga]=Comic Book
Name[gl]=Libro de banda deseñada
@ -74,7 +74,7 @@ Comment[en_GB]=Comic book backend for Okular
Comment[es]=Motor de libros de Comic para Okular
Comment[et]=Okulari koomiksite taustaprogramm
Comment[eu]=Okular-en komiki motorra
Comment[fi]=Sarjakuvat-taustaosa Okular-ohjelmalle
Comment[fi]=Comic book -taustaosa Okularille
Comment[fr]=Interface d'Okular pour les bandes dessinés
Comment[ga]=Inneall Comic Book le haghaidh Okular
Comment[gl]=Infraestruturas de banda deseñada para Okular

View file

@ -137,13 +137,15 @@ X-KDE-Keywords[de]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[el]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[es]=cbr, cbz, cbt, libro de cómic
X-KDE-Keywords[et]=cbr, cbz, cbt, Comic Book, koomiks
X-KDE-Keywords[fi]=cbr, cbz, cbt, Sarjakuva
X-KDE-Keywords[fi]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[fr]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[ga]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[hu]=cbr, cbz, cbt, Képregény
X-KDE-Keywords[it]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[kk]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[km]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[ko]=cbr, cbz, cbt, Comic Book,
X-KDE-Keywords[lv]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[nb]=cbr, cbz, cbt, tegneserie
X-KDE-Keywords[nds]=cbr, cbz, cbt, Comicbook
X-KDE-Keywords[nl]=cbr, cbz, cbt, Stripverhaal
@ -159,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=cbr, cbz, cbt, Comic Book,комикбук
X-KDE-Keywords[sr@ijekavianlatin]=cbr, cbz, cbt, Comic Book,ComicBook
X-KDE-Keywords[sr@latin]=cbr, cbz, cbt, Comic Book,ComicBook
X-KDE-Keywords[sv]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[tr]=cbr, cbz, cbt, Comic Book
X-KDE-Keywords[uk]=cbr,cbz,cbt,Comic Book,комікс
X-KDE-Keywords[x-test]=xxcbr, cbz, cbt, Comic Bookxx
X-KDE-Keywords[zh_CN]=cbr, cbz, cbt, Comic Book,,,

View file

@ -76,7 +76,7 @@ Comment[en_GB]=DjVu backend for Okular
Comment[es]=Motor DjVu para Okular
Comment[et]=Okulari DjVu taustaprogramm
Comment[eu]=Okular-en DjVu motorra
Comment[fi]=DjVu-taustaosa Okular-lukijalle
Comment[fi]=DjVu-taustaosa Okularille
Comment[fr]=Interface d'Okular pour DjVu
Comment[ga]=Inneall DjVu le haghaidh Okular
Comment[gl]=Infraestrutura de DjVu para Okular

View file

@ -143,7 +143,9 @@ X-KDE-Keywords[ga]=djvu
X-KDE-Keywords[hu]=djvu
X-KDE-Keywords[it]=djvu
X-KDE-Keywords[kk]=djvu
X-KDE-Keywords[km]=djvu
X-KDE-Keywords[ko]=djvu
X-KDE-Keywords[lv]=djvu
X-KDE-Keywords[nb]=djvu
X-KDE-Keywords[nds]=DjVu
X-KDE-Keywords[nl]=djvu
@ -159,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=djvu,ДјВу
X-KDE-Keywords[sr@ijekavianlatin]=djvu,DjVu
X-KDE-Keywords[sr@latin]=djvu,DjVu
X-KDE-Keywords[sv]=djvu
X-KDE-Keywords[tr]=djvu
X-KDE-Keywords[ug]=djvu
X-KDE-Keywords[uk]=djvu
X-KDE-Keywords[x-test]=xxdjvuxx

View file

@ -25,7 +25,7 @@
TeXFont_PFB::TeXFont_PFB(TeXFontDefinition *parent, fontEncoding *enc, double slant)
: TeXFont(parent)
: TeXFont(parent), face(0)
{
#ifdef DEBUG_PFB
if (enc != 0)

View file

@ -76,7 +76,7 @@ Comment[en_GB]=DVI backend for Okular
Comment[es]=Motor DVI para Okular
Comment[et]=Okulari DVI taustaprogramm
Comment[eu]=Okular-en DVI motorra
Comment[fi]=DVI-taustaosa Okular-lukijalle
Comment[fi]=DVI-taustaosa Okularille
Comment[fr]=Interface d'Okular pour le DVI
Comment[ga]=Inneall DVI le haghaidh Okular
Comment[gl]=Infraestrutura de DVI para Okular

View file

@ -143,7 +143,9 @@ X-KDE-Keywords[ga]=dvi
X-KDE-Keywords[hu]=dvi
X-KDE-Keywords[it]=dvi
X-KDE-Keywords[kk]=dvi
X-KDE-Keywords[km]=dvi
X-KDE-Keywords[ko]=dvi
X-KDE-Keywords[lv]=dvi
X-KDE-Keywords[nb]=dvi
X-KDE-Keywords[nds]=DVI
X-KDE-Keywords[nl]=dvi
@ -159,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=dvi,ДВИ
X-KDE-Keywords[sr@ijekavianlatin]=dvi,DVI
X-KDE-Keywords[sr@latin]=dvi,DVI
X-KDE-Keywords[sv]=dvi
X-KDE-Keywords[tr]=dvi
X-KDE-Keywords[ug]=dvi
X-KDE-Keywords[uk]=dvi
X-KDE-Keywords[x-test]=xxdvixx

View file

@ -188,7 +188,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if (mSectionMap.contains(link)) {
block = mSectionMap.value(link);
} else { // load missing resource
char *data;
char *data = 0;
int size = epub_get_data(mTextDocument->getEpub(), clink, &data);
if (data) {
_cursor->insertBlock();

View file

@ -19,7 +19,7 @@ static KAboutData createAboutData()
"okular_epub",
"okular_epub",
ki18n("EPub Backend"),
"0.2",
"0.2.1",
ki18n("An EPub backend"),
KAboutData::License_GPL,
ki18n("© 2008 Ely Levy")

View file

@ -9,7 +9,7 @@ Name[ca]=Document EPub
Name[ca@valencia]=Document EPub
Name[cs]=EPub dokument
Name[da]=EPub-dokument
Name[de]=EPub-Dokument
Name[de]=EPUB-Dokument
Name[el]=Έγγραφο EPub
Name[en_GB]=EPub document
Name[es]=Documento EPub
@ -65,13 +65,13 @@ Comment[ca]=Dorsal d'EPub per a l'Okular
Comment[ca@valencia]=Dorsal d'EPub per a l'Okular
Comment[cs]=Implementace Epub pro Okular
Comment[da]=EPub-motor til Okular
Comment[de]=Anzeigemodul für EPub in Okular
Comment[de]=Anzeigemodul für EPUB in Okular
Comment[el]=Σύστημα υποστήριξης EPub για το Okular
Comment[en_GB]=EPub backend for Okular
Comment[es]=Motor EPub para Okular
Comment[et]=Okulari EPubi taustaprogramm
Comment[eu]=Okular-en EPub motorra
Comment[fi]=EPub-taustaosa Okular-lukijalle
Comment[fi]=EPub-taustaosa Okularille
Comment[fr]=Interface d'Okular pour EPub
Comment[ga]=Inneall EPub le haghaidh Okular
Comment[gl]=Infraestrutura de EPub para Okular

View file

@ -143,7 +143,9 @@ X-KDE-Keywords[ga]=epub, ríomhleabhar, r-leabhar
X-KDE-Keywords[hu]=epub, e-book
X-KDE-Keywords[it]=epub, e-book
X-KDE-Keywords[kk]=epub, e-book
X-KDE-Keywords[km]=epub, e-book
X-KDE-Keywords[ko]=epub, e-book,,
X-KDE-Keywords[lv]=epub, e-book, e-grāmata
X-KDE-Keywords[nb]=epub, e-bok
X-KDE-Keywords[nds]=epub, e-book
X-KDE-Keywords[nl]=epub, e-book
@ -159,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=epub, e-book,ЕПУБ,е‑књига
X-KDE-Keywords[sr@ijekavianlatin]=epub, e-book,EPUB,eknjiga
X-KDE-Keywords[sr@latin]=epub, e-book,EPUB,eknjiga
X-KDE-Keywords[sv]=epub, e-bok
X-KDE-Keywords[tr]=epub, e-book
X-KDE-Keywords[uk]=epub,e-book,електронна,книга
X-KDE-Keywords[x-test]=xxepub, e-bookxx
X-KDE-Keywords[zh_CN]=epub, e-book,

View file

@ -71,7 +71,7 @@ Comment[en_GB]=G3/G4 Fax backend for Okular
Comment[es]=Motor de fax G3/G4 para Okular
Comment[et]=Okulari G3/G4 faksi taustaprogramm
Comment[eu]=Okular-en G3/G4 faxaren motorra
Comment[fi]=G3/G4-Faksitaustaosa Okular-lukijalle
Comment[fi]=G3/G4-faksitaustaosa Okularille
Comment[fr]=Interface d'Okular pour les fax de type G3/G4
Comment[ga]=Inneall facsála G3/G4 le haghaidh Okular
Comment[gl]=Infraestrutura de fax G3/G4 para Okular

View file

@ -67,7 +67,7 @@ QTextDocument* Converter::convert( const QString &fileName )
Document fbDocument( fileName );
if ( !fbDocument.open() ) {
emit error( fbDocument.lastErrorString(), -1 );
return false;
return 0;
}
mTextDocument = new QTextDocument;
@ -97,7 +97,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( documentElement.tagName() != QLatin1String( "FictionBook" ) ) {
emit error( i18n( "Document is not a valid FictionBook" ), -1 );
delete mCursor;
return false;
return 0;
}
/**
@ -108,7 +108,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( element.tagName() == QLatin1String( "binary" ) ) {
if ( !convertBinary( element ) ) {
delete mCursor;
return false;
return 0;
}
}
@ -123,7 +123,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( element.tagName() == QLatin1String( "description" ) ) {
if ( !convertDescription( element ) ) {
delete mCursor;
return false;
return 0;
}
} else if ( element.tagName() == QLatin1String( "body" ) ) {
if ( !mTitleInfo->mCoverPage.isNull() ) {
@ -165,7 +165,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( !convertBody( element ) ) {
delete mCursor;
return false;
return 0;
}
}

View file

@ -20,7 +20,7 @@ static KAboutData createAboutData()
"okular_fictionbook",
"okular_fictionbook",
ki18n( "Fiction Book Backend" ),
"0.1.4",
"0.1.5",
ki18n( "A renderer for FictionBook eBooks" ),
KAboutData::License_GPL,
ki18n( "© 2007-2008 Tobias Koenig" )

View file

@ -73,7 +73,7 @@ Comment[en_GB]=FictionBook backend for Okular
Comment[es]=Motor FictionBook para Okular
Comment[et]=Okulari FictionBooki taustaprogramm
Comment[eu]=Okular-en fikzio-libururen motorra
Comment[fi]=FictionBook-taustaosa Okular-lukijalle
Comment[fi]=FictionBook-taustaosa Okularille
Comment[fr]=Interface d'Okular pour « FictionBook »
Comment[ga]=Inneall FictionBook le haghaidh Okular
Comment[gl]=Infraestrutura FictionBook para Okular

View file

@ -131,6 +131,7 @@ X-KDE-Keywords[ar]=FictionBook, e-book, fb2
X-KDE-Keywords[bg]=FictionBook, e-book, fb2
X-KDE-Keywords[ca]=FictionBook, e-book, fb2
X-KDE-Keywords[ca@valencia]=FictionBook, e-book, fb2
X-KDE-Keywords[cs]=FictionBook, e-book, fb2
X-KDE-Keywords[da]=FictionBook,e-book,fb2
X-KDE-Keywords[de]=FictionBook, e-book, fb2
X-KDE-Keywords[el]=FictionBook, e-book, fb2
@ -142,7 +143,9 @@ X-KDE-Keywords[ga]=FictionBook, r-leabhar, ríomhleabhar, fb2
X-KDE-Keywords[hu]=FictionBook, e-book, fb2
X-KDE-Keywords[it]=FictionBook, e-book, fb2
X-KDE-Keywords[kk]=FictionBook, e-book, fb2
X-KDE-Keywords[km]=FictionBook, e-book, fb2
X-KDE-Keywords[ko]=FictionBook, e-book, fb2
X-KDE-Keywords[lv]=FictionBook, e-book, fb2, e-grāmata
X-KDE-Keywords[nb]=FictionBook, e-bok, fb2
X-KDE-Keywords[nds]=FictionBook, e-book, fb2
X-KDE-Keywords[nl]=Fictieboek, e-book, fb2
@ -158,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=FictionBook, e-book, fb2,фикшнбук,е‑књ
X-KDE-Keywords[sr@ijekavianlatin]=FictionBook, e-book, fb2,FictionBook,eknjiga
X-KDE-Keywords[sr@latin]=FictionBook, e-book, fb2,FictionBook,eknjiga
X-KDE-Keywords[sv]=FictionBook, e-bok, fb2
X-KDE-Keywords[tr]=FictionBook, e-book, fb2
X-KDE-Keywords[uk]=FictionBook,fb2,електронна,книга
X-KDE-Keywords[x-test]=xxFictionBook, e-book, fb2xx
X-KDE-Keywords[zh_CN]=FictionBook, e-book, fb2,,

View file

@ -76,7 +76,7 @@ Comment[en_GB]=Image backend for Okular
Comment[es]=Motor de imágenes para Okular
Comment[et]=Okulari piltide taustaprogramm
Comment[eu]=Okular-en irudi motorra
Comment[fi]=Kuvataustaosta Okular-lukijalle
Comment[fi]=Kuvataustaosta Okularille
Comment[fr]=Interface d'Okular pour les images
Comment[ga]=Inneall íomhánna le haghaidh Okular
Comment[gl]=Infraestrutura de imaxes para Okular

View file

@ -96,7 +96,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( !document.setContent( &source, &reader, &errorMsg ) ) {
emit error( i18n( "Invalid XML document: %1", errorMsg ), -1 );
delete mCursor;
return false;
return 0;
}
mStyleInformation = new StyleInformation();
@ -109,7 +109,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( !styleParser.parse() ) {
emit error( i18n( "Unable to read style information" ), -1 );
delete mCursor;
return false;
return 0;
}
/**
@ -156,7 +156,7 @@ QTextDocument* Converter::convert( const QString &fileName )
if ( !convertBody( element ) ) {
emit error( i18n( "Unable to convert document content" ), -1 );
delete mCursor;
return false;
return 0;
}
}

View file

@ -20,7 +20,7 @@ static KAboutData createAboutData()
"okular_ooo",
"okular_ooo",
ki18n( "OpenOffice Document Backend" ),
"0.2.2",
"0.2.3",
ki18n( "A renderer for OpenOffice text documents" ),
KAboutData::License_GPL,
ki18n( "© 2006-2008 Tobias Koenig" )

View file

@ -16,7 +16,7 @@ Name[eo]=OpenDocument formato
Name[es]=Formato OpenDocument
Name[et]=OpenDocumenti vorming
Name[eu]=OpenDocument formatua
Name[fi]=OpenDocument -muoto
Name[fi]=OpenDocument-muoto
Name[fr]=Format OpenDocument
Name[ga]=Formáid OpenDocument
Name[gl]=Formato OpenDocument
@ -75,7 +75,7 @@ Comment[en_GB]=OpenDocument backend for Okular
Comment[es]=Motor OpenDocument para Okular
Comment[et]=Okulari OpenDocumenti taustaprogramm
Comment[eu]=Okular-en OpenDocument motorra
Comment[fi]=OpenDocument-taustaosa Okular-lukijalle
Comment[fi]=OpenDocument-taustaosa Okularille
Comment[fr]=Interface d'Okular pour le format OpenDocument
Comment[ga]=Inneall OpenDocument le haghaidh Okular
Comment[gl]=Infraestrutura de OpenDocument para Okular

View file

@ -131,20 +131,15 @@ const Okular::DocumentInfo* PluckerGenerator::generateDocumentInfo()
return &mDocumentInfo;
}
bool PluckerGenerator::canGeneratePixmap() const
{
return true;
}
void PluckerGenerator::generatePixmap( Okular::PixmapRequest * request )
QImage PluckerGenerator::image( Okular::PixmapRequest *request )
{
const QSizeF size = mPages[ request->pageNumber() ]->size();
QPixmap *pixmap = new QPixmap( request->width(), request->height() );
pixmap->fill( Qt::white );
QImage image( request->width(), request->height(), QImage::Format_ARGB32_Premultiplied );
image.fill( Qt::white );
QPainter p;
p.begin( pixmap );
p.begin( &image );
qreal width = request->width();
qreal height = request->height();
@ -153,9 +148,6 @@ void PluckerGenerator::generatePixmap( Okular::PixmapRequest * request )
mPages[ request->pageNumber() ]->drawContents( &p );
p.end();
request->page()->setPixmap( request->id(), pixmap );
if ( !mLinkAdded.contains( request->pageNumber() ) ) {
QLinkedList<Okular::ObjectRect*> objects;
for ( int i = 0; i < mLinks.count(); ++i ) {
@ -176,7 +168,7 @@ void PluckerGenerator::generatePixmap( Okular::PixmapRequest * request )
mLinkAdded.insert( request->pageNumber() );
}
signalPixmapRequestDone( request );
return image;
}
Okular::ExportFormat::List PluckerGenerator::exportFormats() const

View file

@ -32,9 +32,9 @@ class PluckerGenerator : public Okular::Generator
// [INHERITED] document information
const Okular::DocumentInfo * generateDocumentInfo();
bool canGeneratePixmap() const;
void generatePixmap( Okular::PixmapRequest *request );
// [INHERITED] perform actions on document / pages
QImage image( Okular::PixmapRequest *request );
// [INHERITED] text exporting
Okular::ExportFormat::List exportFormats() const;

View file

@ -75,7 +75,7 @@ Comment[en_GB]=Plucker backend for Okular
Comment[es]=Motor Plucker para Okular
Comment[et]=Okulari Pluckeri taustaprogramm
Comment[eu]=Okular-en Plucker motorra
Comment[fi]=Plucker-taustaosa Okular-lukijalle
Comment[fi]=Plucker-taustaosa Okularille
Comment[fr]=Interface d'Okular pour les fichiers Plucker
Comment[ga]=Inneall Plucker le haghaidh Okular
Comment[gl]=Infraestrutura de Plucker para Okular

View file

@ -131,6 +131,7 @@ X-KDE-Keywords[ar]=plucker
X-KDE-Keywords[bg]=plucker
X-KDE-Keywords[ca]=plucker
X-KDE-Keywords[ca@valencia]=plucker
X-KDE-Keywords[cs]=plucker
X-KDE-Keywords[da]=plucker
X-KDE-Keywords[de]=plucker
X-KDE-Keywords[el]=plucker
@ -142,7 +143,9 @@ X-KDE-Keywords[ga]=plucker
X-KDE-Keywords[hu]=plucker
X-KDE-Keywords[it]=plucker
X-KDE-Keywords[kk]=plucker
X-KDE-Keywords[km]=plucker
X-KDE-Keywords[ko]=plucker
X-KDE-Keywords[lv]=plucker
X-KDE-Keywords[nb]=plucker
X-KDE-Keywords[nds]=Plucker
X-KDE-Keywords[nl]=plucker
@ -158,6 +161,7 @@ X-KDE-Keywords[sr@ijekavian]=plucker,Плакер
X-KDE-Keywords[sr@ijekavianlatin]=plucker,Plucker
X-KDE-Keywords[sr@latin]=plucker,Plucker
X-KDE-Keywords[sv]=plucker
X-KDE-Keywords[tr]=plucker
X-KDE-Keywords[uk]=plucker
X-KDE-Keywords[x-test]=xxpluckerxx
X-KDE-Keywords[zh_CN]=plucker

View file

@ -1,161 +0,0 @@
Summary: PDF 1.6 Annotations specs and okular support.
Author: Enrico Ros - KPDF project - 2005
okular team - 2006
** Relations to okular:
okular tries to support ALL annotations and ALL parameters in PDF specs. If
this can't be done, we must support at least the most common ones and the
most common parameters.
Current Data Structure status:
complete:
[markup], popup, text, freetext, line, polygon, polyline, highlight,
underline, squiggly, strikeout, stamp, ink
partial:
base{P,AP,AS,A,AA,StructPar,OC}, geom{RD}
missing:
link (handled in another way), caret, {fileattachment, sound, movie},
screen, widget, {printermark, trapnet, watermark}, 3d
** Notes on parsing in relation to okular:
Different Data Structures:
To adapt the 'plain' pdf storage to okular data structures we use a couple
of queues to store cross-dependant objects for each page and then adapt
objects to our DSs resolving crossdeps at the end of the loops.
** PDF file structure (annotations section):
COMMON FIELDS (note: '*' is required)
Type name 'Annot'
*Subtype name [Text...3D]
\ see second table (below)
*Rect rectangle norma rect
Contents text string alternate text / description
P dictionary page reference (mandatory for Screen)
NM text string unique name
M date or string last modify date
F integer flags (default:0)
\ OR-ed flags: Invisible(0), Hidden(1), Print(2), NoZoom(3), NoRotate(4),
\NoView(5), ReadOnly(6), Locked(7), ToggleNoView(8)
BS dictionary border styles (also style for: Line,Square,Circle,Ink)
\ Type (name='Border'), W (number), S (name), D (array)
BE dictionary border effect (only for square, circle, and polygon)
\ S (name (effect[S:no effect,C: cloudy])), I (number (intensity(0..2))
AP dictionary visual representation (handler should provide own impl)
\ renderable data to be used with composition algorithm 8.1 (in pdf spec)
AS name visual state (indexes an AP representation)
Border array pre-BS: x-corner-rad, y-corner-rad, width [,dash array]
C array color (3 components in range [0..1])
A dictionary action (NA on link, specialized on Movie)
\ 'LinkAction' to extract those and use internal handler instead of external one
AA dictionary additional actions for events (used by Widget only)
StructPar. integer annotation's key in the structural tree(not used)
OC dictionary optional content properties (custom visi-check)
MARKUP -additional- fields (see 'X' marks in the Subtype table):
Markup annotations have an associated pop-up window that may contain text.
If the popup id is given, that popup is used for displaying text, otherwise a
popup is created on annotation opening but the popup is rendered 'in place'
with the annotation and can not be moved without moving the annotation.
T text string titlebar text (creator name by convention)
Popup dictionary indirect refrence to pupup annot for editing text
CA number opacity (def: 1.0)
RC text string/eam rich text displayed if opened (overrides Contents)
CreationD. date creation date
IRT dictionary reference to the ann this is 'in reply to' (if RT)
Subj text string short subject addressed
RT name 'R':in reply 'Group':grouped (if IRT)
IT name annotation intent (specialized for certail types)
[annotation states? pg 585]
CUSTOM FIELDS (for each subType) (X: is markup):
Popup . no gfx only a parent (inherits Contents,M,C,T)
Parent dictionary indirect reference to parent (from wich Mark. are inh)
Open boolean initially displayed opened (def:false)
Text X a 'sticky note' attached to a point in document
Open boolean default:false
Name name icon[Comment,Key,Note,Help,NewParagraph,Paragraph,Insert]
[M]State text string if RT,IRT,StateModel are set
[M]StateM. text string if RT,IRT,State are set
FreeText X like Text but the text is always visible
*DA string appearance string (AP takes precedence)
Q integer 0(Left-justified) 1(Centered) 2(Right-justified)
RC text string/eam rich text string (overrides Contents)
DS text string default text string
CL array 2 or 3 {x,y} couples for callout line
[M]IT name not present,FreeTextCallout,FreeTextTypeWriter
Line X a single straight line on the page (has popup note)
*L array 4 numbers (2 x,y couples)
BS dictionary width and dash pattern to be used in drawing the line
LE array 2 names (start and end styles) (def:None,None)
\ values [Square,Circle,Diamond,OpenArrow,ClosedArrow,None,
Butt,ROpenArrow,RClosedArrow,Slash]
IC array interior color (3 components in range [0..1])
LL number leader line fwd (if LLE) in points
LLE number leader line bk (if LL) in points
Cap boolean has caption (RC or Contents) (def:false)
[M]IT name not present,LineArrow,LineDimension
Polygon X closed polygon on the page
PolyLine X polygon without first and last vtx closed
*Vertices array n*{x,y} pairs of all line vertices
LE array 2 names (start and end styles) (def:None,None)
BS dictionary width and dash pattern
IC array interior color (3 components in range [0..1])
BE dictionary border effect
IT name not present,PolygonCloud
Square X rect or ellipse on the page (has popup note) the square
Circle X or circle have 18pt border are inscribed into rect
BS dictionary line width and dash pattern
IC array interior color (3 components in range [0..1])
BE dictionary border effect
RD rectangle negative border offsets (4 positive coords)
Highlight X
Underline X appears as highlights, underlines, strikeouts. has
Squiggly X popup text of associated note)
StrikeOut X
*QuadPo. array array of ccw quadrilats (8 x n numbers) (AP takes prec)
Caret X visual symbol that indicates the presence of text
RD rectangle rect displacement from effective rect to annotation one
Sy name 'P':paragraph symbol, 'None':no symbol(defaulr)
Stamp X displays text or graphics intended to look as rubber stamps
Name name [Approved,Experimental,NotApproved,AsIs,Expired,
NotForPublicRelease,Confidential,Final,Sold,Departmental,
ForComment,TopSecret,Draft,ForPublicRelease]
Ink X freehand ?scribble? composed of one or more disjoint paths
*InkList array array or arrays of {x,y} userspace couples
BS dictionary line width and dash pattern
UNUSED / INCOMPLETE:
Link . hypertext link to a location in document or action
Dest arr,nam,str if A not present
H name N(none) I(invert) O(outline) P(sunken)
PA dictionary URI action
QuadPoints array array of quadrilaterals (8 x n numbers)
FileAttachment X reference to file (typically embedded)
*FS file file associated
Name name icon [Graph,PushPin,Paperclip,Tag]
Sound X like Text but contains sound
*Sound stream sound to be played when annot is activated
Name name icon [Speaker,Mic,_more_]
Movie . contains animated graphics and sound
Movie dictionary the movie to be played when annot is actived
A boolean whether and how to play the movie (def:true)
Screen . specifies a region of a page on which play media clips
Widget . appearance of the fields for user interaction
PrinterMark . a graphic symbol used to assist production personnel
TrapNet . add color marks along colour boundaries to avoid artifacts
Watermark . graphics to be printed at a fixed size and position on a page
3D . the mean by which 3D artwork is represented in a document

View file

@ -310,6 +310,13 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( Poppler::Annotation *
break;
}
#ifdef HAVE_POPPLER_0_22
case Poppler::Annotation::AWidget:
{
annotation = new Okular::WidgetAnnotation();
break;
}
#endif
#ifdef HAVE_POPPLER_0_20
case Poppler::Annotation::AScreen:
{
@ -350,12 +357,16 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( Poppler::Annotation *
}
if ( annotation )
{
// the Contents field might have lines separated by \r
QString contents = ann->contents();
contents.replace( QLatin1Char( '\r' ), QLatin1Char( '\n' ) );
annotation->setAuthor( ann->author() );
annotation->setContents( ann->contents() );
annotation->setContents( contents );
annotation->setUniqueName( ann->uniqueName() );
annotation->setModificationDate( ann->modificationDate() );
annotation->setCreationDate( ann->creationDate() );
annotation->setFlags( ann->flags() );
annotation->setFlags( ann->flags() | Okular::Annotation::External );
annotation->setBoundingRectangle( Okular::NormalizedRect::fromQRectF( ann->boundary() ) );
if (externallyDrawn)
@ -378,6 +389,27 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( Poppler::Annotation *
}
}
if ( annotation->subType() == Okular::Annotation::AText )
{
Okular::TextAnnotation * txtann = static_cast<Okular::TextAnnotation*>( annotation );
if ( txtann->textType() == Okular::TextAnnotation::InPlace )
{
#ifndef HAVE_POPPLER_0_20
// Poppler before 0.20 returns the inplaceText in contents
txtann->setInplaceText( txtann->contents() );
#endif
}
else if ( txtann->textType() == Okular::TextAnnotation::Linked )
{
Poppler::TextAnnotation * ppl_txtann = static_cast<Poppler::TextAnnotation*>( ann );
// Poppler and Okular assume a different default icon name in XML
// We re-read it via getter, which always tells the right one
txtann->setTextIcon( ppl_txtann->textIcon() );
}
}
// TODO clone style
// TODO clone window
// TODO clone revisions

View file

@ -6,3 +6,6 @@
/* Defined if we have the 0.20 version of the Poppler library */
#cmakedefine HAVE_POPPLER_0_20 1
/* Defined if we have the 0.22 version of the Poppler library */
#cmakedefine HAVE_POPPLER_0_22 1

View file

@ -82,7 +82,7 @@ class PDFOptionsPage : public QWidget
layout->addWidget(m_forceRaster);
layout->addStretch(1);
#ifndef HAVE_POPPLER_0_20
#if defined(Q_WS_WIN) || !defined(HAVE_POPPLER_0_20)
m_printAnnots->setVisible( false );
#endif
setPrintAnnots( true ); // Default value
@ -180,6 +180,10 @@ Okular::Movie* createMovieFromPopplerMovie( const Poppler::MovieObject *popplerM
movie->setShowControls( popplerMovie->showControls() );
movie->setPlayMode( (Okular::Movie::PlayMode)popplerMovie->playMode() );
movie->setAutoPlay( false ); // will be triggered by external MovieAnnotation
#ifdef HAVE_POPPLER_0_22
movie->setShowPosterImage( popplerMovie->showPosterImage() );
movie->setPosterImage( popplerMovie->posterImage() );
#endif
return movie;
}
@ -358,7 +362,7 @@ static KAboutData createAboutData()
"okular_poppler",
"okular_poppler",
ki18n( "PDF Backend" ),
"0.5",
"0.6.2",
ki18n( "A PDF file renderer" ),
KAboutData::License_GPL,
ki18n( "© 2005-2008 Albert Astals Cid" )
@ -649,8 +653,10 @@ const Okular::DocumentInfo * PDFGenerator::generateDocumentInfo()
docInfo.set( Okular::DocumentInfo::ModificationDate,
KGlobal::locale()->formatDateTime( pdfdoc->date("ModDate"), KLocale::LongDate, true ) );
docInfo.set( "format", i18nc( "PDF v. <version>", "PDF v. %1",
QString::number( pdfdoc->pdfVersion() ) ), i18n( "Format" ) );
int major, minor;
pdfdoc->getPdfVersion(&major, &minor);
docInfo.set( "format", i18nc( "PDF v. <version>", "PDF v. %1.%2",
major, minor ), i18n( "Format" ) );
docInfo.set( "encryption", pdfdoc->isEncrypted() ? i18n( "Encrypted" ) : i18n( "Unencrypted" ),
i18n("Security") );
docInfo.set( "optimization", pdfdoc->isLinearized() ? i18n( "Yes" ) : i18n( "No" ),
@ -939,6 +945,23 @@ void PDFGenerator::resolveMovieLinkReferences( Okular::Page *page )
resolveMovieLinkReference( const_cast<Okular::Action*>( page->pageAction( Okular::Page::Opening ) ), page );
resolveMovieLinkReference( const_cast<Okular::Action*>( page->pageAction( Okular::Page::Closing ) ), page );
foreach ( Okular::Annotation *annotation, page->annotations() )
{
if ( annotation->subType() == Okular::Annotation::AScreen )
{
Okular::ScreenAnnotation *screenAnnotation = static_cast<Okular::ScreenAnnotation*>( annotation );
resolveMovieLinkReference( screenAnnotation->additionalAction( Okular::Annotation::PageOpening ), page );
resolveMovieLinkReference( screenAnnotation->additionalAction( Okular::Annotation::PageClosing ), page );
}
if ( annotation->subType() == Okular::Annotation::AWidget )
{
Okular::WidgetAnnotation *widgetAnnotation = static_cast<Okular::WidgetAnnotation*>( annotation );
resolveMovieLinkReference( widgetAnnotation->additionalAction( Okular::Annotation::PageOpening ), page );
resolveMovieLinkReference( widgetAnnotation->additionalAction( Okular::Annotation::PageClosing ), page );
}
}
foreach ( Okular::FormField *field, page->formFields() )
resolveMovieLinkReference( field->activationAction(), page );
}
@ -1238,7 +1261,7 @@ bool PDFGenerator::exportTo( const QString &fileName, const Okular::ExportFormat
Poppler::Page *pp = pdfdoc->page(i);
if (pp)
{
text = pp->text(QRect());
text = pp->text(QRect()).normalized(QString::NormalizationForm_KC);
}
userMutex()->unlock();
ts << text;
@ -1364,52 +1387,47 @@ void PDFGenerator::addAnnotations( Poppler::Page * popplerPage, Okular::Page * p
foreach(Poppler::Annotation *a, popplerAnnotations)
{
//a->window.width = (int)(page->width() * a->window.width);
//a->window.height = (int)(page->height() * a->window.height);
//a->window.width = a->window.width < 200 ? 200 : a->window.width;
// a->window.height = a->window.height < 120 ? 120 : a->window.height;
// resize annotation's geometry to an icon
// TODO okular geom.right = geom.left + 22.0 / page->width();
// TODO okular geom.bottom = geom.top + 22.0 / page->height();
/*
QString szanno;
QTextStream(&szanno)<<"PopplerAnnotation={author:"<<a->author
<<", contents:"<<a->contents
<<", uniqueName:"<<a->uniqueName
<<", modifyDate:"<<a->modifyDate.toString("hh:mm:ss, dd.MM.yyyy")
<<", creationDate:"<<a->creationDate.toString("hh:mm:ss, dd.MM.yyyy")
<<", flags:"<<a->flags
<<", boundary:"<<a->boundary.left()<<","<<a->boundary.top()<<","<<a->boundary.right()<<","<<a->boundary.bottom()
<<", style.color:"<<a->style.color.name()
<<", style.opacity:"<<a->style.opacity
<<", style.width:"<<a->style.width
<<", style.LineStyle:"<<a->style.style
<<", style.xyCorners:"<<a->style.xCorners<<","<<a->style.yCorners
<<", style.marks:"<<a->style.marks
<<", style.spaces:"<<a->style.spaces
<<", style.LineEffect:"<<a->style.effect
<<", style.effectIntensity:"<<a->style.effectIntensity
<<", window.flags:"<<a->window.flags
<<", window.topLeft:"<<(a->window.topLeft.x())
<<","<<(a->window.topLeft.y())
<<", window.width,height:"<<a->window.width<<","<<a->window.height
<<", window.title:"<<a->window.title
<<", window.summary:"<<a->window.summary
<<", window.text:"<<a->window.text;
kDebug(PDFDebug) << "astario: " << szanno; */
//TODO add annotations after poppler write feather is full suported
bool doDelete = true;
Okular::Annotation * newann = createAnnotationFromPopplerAnnotation( a, &doDelete );
if (newann)
{
// the Contents field has lines separated by \r
QString contents = newann->contents();
contents.replace( QLatin1Char( '\r' ), QLatin1Char( '\n' ) );
newann->setContents( contents );
// explicitly mark as external
newann->setFlags( newann->flags() | Okular::Annotation::External );
page->addAnnotation(newann);
#ifdef HAVE_POPPLER_0_22
if ( a->subType() == Poppler::Annotation::AScreen )
{
/*
// TODO: (tokoe) This has been disabled for the moment, since we return MovieAnnotation objects
// for AScreen annotations, which will lead to a crash down here.
Poppler::ScreenAnnotation *annotScreen = static_cast<Poppler::ScreenAnnotation*>( a );
Okular::ScreenAnnotation *screenAnnotation = static_cast<Okular::ScreenAnnotation*>( newann );
const Poppler::Link *pageOpeningLink = annotScreen->additionalAction( Poppler::Annotation::PageOpeningAction );
if ( pageOpeningLink )
screenAnnotation->setAdditionalAction( Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) );
const Poppler::Link *pageClosingLink = annotScreen->additionalAction( Poppler::Annotation::PageClosingAction );
if ( pageClosingLink )
screenAnnotation->setAdditionalAction( Okular::Annotation::PageClosing, createLinkFromPopplerLink( pageClosingLink ) );
*/
}
if ( a->subType() == Poppler::Annotation::AWidget )
{
Poppler::WidgetAnnotation *annotWidget = static_cast<Poppler::WidgetAnnotation*>( a );
Okular::WidgetAnnotation *widgetAnnotation = static_cast<Okular::WidgetAnnotation*>( newann );
const Poppler::Link *pageOpeningLink = annotWidget->additionalAction( Poppler::Annotation::PageOpeningAction );
if ( pageOpeningLink )
widgetAnnotation->setAdditionalAction( Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) );
const Poppler::Link *pageClosingLink = annotWidget->additionalAction( Poppler::Annotation::PageClosingAction );
if ( pageClosingLink )
widgetAnnotation->setAdditionalAction( Okular::Annotation::PageClosing, createLinkFromPopplerLink( pageClosingLink ) );
}
#endif
if ( !doDelete )
annotationsHash.insert( newann, a );
}
@ -1672,7 +1690,7 @@ const Okular::SourceReference * PDFGenerator::dynamicSourceReference( int pageNr
}
const char *name = synctex_scanner_get_name( synctex_scanner, synctex_node_tag( node ) );
Okular::SourceReference * sourceRef = new Okular::SourceReference( name, line, col );
Okular::SourceReference * sourceRef = new Okular::SourceReference( QString::fromLocal8Bit( name ), line, col );
return sourceRef;
}
}
@ -1755,9 +1773,13 @@ bool PDFGenerator::supportsOption( SaveOption option ) const
{
case SaveChanges:
{
// Saving files with /Encrypt is not supported before Poppler 0.22
#ifndef HAVE_POPPLER_0_22
QMutexLocker locker( userMutex() );
// Saving files with /Encrypt is not supported
return pdfdoc->isEncrypted() ? false : true;
#else
return true;
#endif
}
default: ;
}
@ -1780,7 +1802,10 @@ bool PDFGenerator::save( const QString &fileName, SaveOptions options, QString *
switch (pdfConv->lastError())
{
case Poppler::BaseConverter::NotSupportedInputFileError:
#ifndef HAVE_POPPLER_0_22
// This can only happen with Poppler before 0.22
*errorText = i18n("Saving files with /Encrypt is not supported.");
#endif
break;
case Poppler::BaseConverter::NoError:

View file

@ -75,7 +75,7 @@ Comment[en_GB]=PDF backend for Okular using poppler
Comment[es]=Motor PDF para Okular que usa Poppler
Comment[et]=Okulari PDF-i taustaprogramm poppleri vahendusel
Comment[eu]=Okular-en PDF motorra poppler erabiliz
Comment[fi]=Poppler-kirjastoa käyttävä PDF-taustaosa Okular-lukijalle
Comment[fi]=Poppler-kirjastoa käyttävä PDF-taustaosa Okularille
Comment[fr]=Interface d'Okular pour les PDF (utilise poppler)
Comment[ga]=Inneall PDF a úsáideann poppler le haghaidh Okular
Comment[gl]=Infraestrutura de PDF mediante poppler para Okular

View file

@ -142,7 +142,9 @@ X-KDE-Keywords[ga]=PDF, Portable Document Format
X-KDE-Keywords[hu]=PDF, Portable Document Format
X-KDE-Keywords[it]=PDF, Portable Document Format, formato per documenti portabile
X-KDE-Keywords[kk]=PDF, Portable Document Format
X-KDE-Keywords[km]=PDF, Portable Document Format
X-KDE-Keywords[ko]=PDF, Portable Document Format
X-KDE-Keywords[lv]=PDF, Portable Document formāts
X-KDE-Keywords[nb]=PDF, Portabelt Dokument Format
X-KDE-Keywords[nds]=PDF, Porteerbor Dokmentformaat
X-KDE-Keywords[nl]=PDF, Portable Document Format
@ -158,6 +160,7 @@ X-KDE-Keywords[sr@ijekavian]=PDF, Portable Document Format,ПДФ
X-KDE-Keywords[sr@ijekavianlatin]=PDF, Portable Document Format,PDF
X-KDE-Keywords[sr@latin]=PDF, Portable Document Format,PDF
X-KDE-Keywords[sv]=PDF, Portabelt dokumentformat
X-KDE-Keywords[tr]=PDF, Taşınabilir Belge Biçimi
X-KDE-Keywords[uk]=PDF,Portable Document Format,пдф
X-KDE-Keywords[x-test]=xxPDF, Portable Document Formatxx
X-KDE-Keywords[zh_CN]=PDF, Portable Document Format,

View file

@ -39,7 +39,7 @@ static KAboutData createAboutData()
"okular_ghostview",
"okular_ghostview",
ki18n( "PS Backend" ),
"0.1.5",
"0.1.6",
ki18n( "A PostScript file renderer." ),
KAboutData::License_GPL,
ki18n( "© 2007-2008 Albert Astals Cid" ),

View file

@ -75,7 +75,7 @@ Comment[en_GB]=Ghostscript PS/PDF backend for Okular
Comment[es]=Motor PS/PDF de Ghostscript para Okular
Comment[et]=Okulari Ghostscript PS/PDF-i taustaprogramm
Comment[eu]=Okular-en Ghostscript PS/PDF motorra
Comment[fi]=Ghostscript-pohjainen PS/PDF-taustaosa ohjelmaa Okular varten
Comment[fi]=Ghostscript-pohjainen PS/PDF-taustaosa Okularille
Comment[fr]=Interface d'Okular pour les fichiers Ghostscript PS/PDF
Comment[ga]=Inneall PS/PDF Ghostscript le haghaidh Okular
Comment[gl]=Infraestrutura Ghostscript PS/PDF para Okular

View file

@ -70,6 +70,13 @@ void GSRendererThread::run()
spectre_page_render(req.spectrePage, m_renderContext, &data, &row_length);
// Qt needs the missing alpha of QImage::Format_RGB32 to be 0xff
if (data[3] != 0xff)
{
for (int i = 3; i < row_length * wantedHeight; i += 4)
data[i] = 0xff;
}
QImage img;
if (row_length == wantedWidth * 4)
{
@ -86,7 +93,7 @@ void GSRendererThread::run()
{
case Okular::Rotation90:
{
QMatrix m;
QTransform m;
m.rotate(90);
img = img.transformed( m );
break;
@ -94,14 +101,14 @@ void GSRendererThread::run()
case Okular::Rotation180:
{
QMatrix m;
QTransform m;
m.rotate(180);
img = img.transformed( m );
break;
}
case Okular::Rotation270:
{
QMatrix m;
QTransform m;
m.rotate(270);
img = img.transformed( m );
}

View file

@ -15,7 +15,7 @@ Name[en_GB]=Okular TIFF Library
Name[es]=Biblioteca TIFF de Okular
Name[et]=Okulari TIFF-i teek
Name[eu]=Okular TIFF liburutegia
Name[fi]=Okular TIFF-kirjasto
Name[fi]=TIFF-kirjasto Okularille
Name[fr]=Librairie d'Okular pour le format TIFF
Name[ga]=Leabharlann TIFF Okular
Name[gl]=Biblioteca TIFF de Okular
@ -71,7 +71,7 @@ Comment[en_GB]=TIFF backend for Okular
Comment[es]=Motor TIFF para Okular
Comment[et]=Okulari TIFF-i taustaprogramm
Comment[eu]=Okular-en TIFF motorra
Comment[fi]=TIFF-taustaosa ohjelmaa Okular varten
Comment[fi]=TIFF-taustaosa Okularille
Comment[fr]=Interface d'Okular pour les fichiers TIFF
Comment[ga]=Inneall TIFF le haghaidh Okular
Comment[gl]=Infraestrutura de TIFF para Okular

View file

@ -393,18 +393,18 @@ static QPainterPath parseAbbreviatedPathData( const QString &data)
/**
Parse a "Matrix" attribute string
\param csv the comma separated list of values
\return the QMatrix corresponding to the affine transform
\return the QTransform corresponding to the affine transform
given in the attribute
\see XPS specification 7.4.1
*/
static QMatrix attsToMatrix( const QString &csv )
static QTransform attsToMatrix( const QString &csv )
{
QStringList values = csv.split( ',' );
if ( values.count() != 6 ) {
return QMatrix(); // that is an identity matrix - no effect
return QTransform(); // that is an identity matrix - no effect
}
return QMatrix( values.at(0).toDouble(), values.at(1).toDouble(),
return QTransform( values.at(0).toDouble(), values.at(1).toDouble(),
values.at(2).toDouble(), values.at(3).toDouble(),
values.at(4).toDouble(), values.at(5).toDouble() );
}
@ -440,12 +440,12 @@ static QPen parseRscRefColorForPen( const QString &data )
/**
\return Matrix specified by given data or by referenced dictionary
*/
static QMatrix parseRscRefMatrix( const QString &data )
static QTransform parseRscRefMatrix( const QString &data )
{
if (data[0] == '{') {
//TODO
kDebug(XpsDebug) << "Reference" << data;
return QMatrix();
return QTransform();
} else {
return attsToMatrix( data );
}
@ -878,7 +878,7 @@ void XpsHandler::processGlyph( XpsRenderNode &node )
//RenderTransform
att = node.attributes.value("RenderTransform");
if (!att.isEmpty()) {
m_painter->setWorldMatrix( parseRscRefMatrix( att ), true);
m_painter->setWorldTransform( parseRscRefMatrix( att ), true);
}
// Clip
@ -984,27 +984,27 @@ void XpsHandler::processImageBrush( XpsRenderNode &node )
QImage image = m_page->loadImageFromFile( node.attributes.value( "ImageSource" ) );
// Matrix which can transform [0, 0, 1, 1] rectangle to given viewbox
QMatrix viewboxMatrix = QMatrix( viewbox.width() * image.physicalDpiX() / 96, 0, 0, viewbox.height() * image.physicalDpiY() / 96, viewbox.x(), viewbox.y() );
QTransform viewboxMatrix = QTransform( viewbox.width() * image.physicalDpiX() / 96, 0, 0, viewbox.height() * image.physicalDpiY() / 96, viewbox.x(), viewbox.y() );
// Matrix which can transform [0, 0, 1, 1] rectangle to given viewport
//TODO Take ViewPort into account
QMatrix viewportMatrix;
QTransform viewportMatrix;
att = node.attributes.value( "Transform" );
if ( att.isEmpty() ) {
QVariant data = node.getChildData( "ImageBrush.Transform" );
if (data.canConvert<QMatrix>()) {
viewportMatrix = data.value<QMatrix>();
if (data.canConvert<QTransform>()) {
viewportMatrix = data.value<QTransform>();
} else {
viewportMatrix = QMatrix();
viewportMatrix = QTransform();
}
} else {
viewportMatrix = parseRscRefMatrix( att );
}
viewportMatrix = viewportMatrix * QMatrix( viewport.width(), 0, 0, viewport.height(), viewport.x(), viewport.y() );
viewportMatrix = viewportMatrix * QTransform( viewport.width(), 0, 0, viewport.height(), viewport.x(), viewport.y() );
brush = QBrush( image );
brush.setMatrix( viewboxMatrix.inverted() * viewportMatrix );
brush.setTransform( viewboxMatrix.inverted() * viewportMatrix );
node.data = qVariantFromValue( brush );
}
@ -1135,10 +1135,10 @@ void XpsHandler::processPath( XpsRenderNode &node )
// RenderTransform
att = node.attributes.value( "RenderTransform" );
if (! att.isEmpty() ) {
m_painter->setWorldMatrix( parseRscRefMatrix( att ), true );
m_painter->setWorldTransform( parseRscRefMatrix( att ), true );
}
if ( !pathdata->transform.isIdentity() ) {
m_painter->setWorldMatrix( pathdata->transform, true );
m_painter->setWorldTransform( pathdata->transform, true );
}
Q_FOREACH ( XpsPathFigure *figure, pathdata->paths ) {
@ -1292,7 +1292,7 @@ void XpsHandler::processStartElement( XpsRenderNode &node )
m_painter->save();
QString att = node.attributes.value( "RenderTransform" );
if ( !att.isEmpty() ) {
m_painter->setWorldMatrix( parseRscRefMatrix( att ), true );
m_painter->setWorldTransform( parseRscRefMatrix( att ), true );
}
att = node.attributes.value( "Opacity" );
if ( !att.isEmpty() ) {
@ -1316,11 +1316,11 @@ void XpsHandler::processEndElement( XpsRenderNode &node )
processPath( node );
} else if (node.name == "MatrixTransform") {
//TODO Ignoring x:key
node.data = qVariantFromValue( QMatrix( attsToMatrix( node.attributes.value( "Matrix" ) ) ) );
node.data = qVariantFromValue( QTransform( attsToMatrix( node.attributes.value( "Matrix" ) ) ) );
} else if ((node.name == "Canvas.RenderTransform") || (node.name == "Glyphs.RenderTransform") || (node.name == "Path.RenderTransform")) {
QVariant data = node.getRequiredChildData( "MatrixTransform" );
if (data.canConvert<QMatrix>()) {
m_painter->setWorldMatrix( data.value<QMatrix>(), true );
if (data.canConvert<QTransform>()) {
m_painter->setWorldTransform( data.value<QTransform>(), true );
}
} else if (node.name == "Canvas") {
m_painter->restore();
@ -1461,7 +1461,7 @@ bool XpsPage::renderToPainter( QPainter *painter )
{
XpsHandler handler( this );
handler.m_painter = painter;
handler.m_painter->setWorldMatrix(QMatrix().scale((qreal)painter->device()->width() / size().width(), (qreal)painter->device()->height() / size().height()));
handler.m_painter->setWorldTransform(QTransform().scale((qreal)painter->device()->width() / size().width(), (qreal)painter->device()->height() / size().height()));
QXmlSimpleReader parser;
parser.setContentHandler( &handler );
parser.setErrorHandler( &handler );
@ -1617,9 +1617,9 @@ Okular::TextPage* XpsPage::textPage()
QXmlStreamReader xml;
xml.addData( readFileOrDirectoryParts( pageFile ) );
QMatrix matrix = QMatrix();
QStack<QMatrix> matrices;
matrices.push( QMatrix() );
QTransform matrix = QTransform();
QStack<QTransform> matrices;
matrices.push( QTransform() );
bool useMatrix = false;
QXmlStreamAttributes glyphsAtts;

View file

@ -76,8 +76,8 @@ struct XpsGradient
Types of data in XpsRenderNode::data. Name of each type consist of Xps and
name of xml element which data it holds
*/
typedef QMatrix XpsMatrixTransform;
typedef QMatrix XpsRenderTransform;
typedef QTransform XpsMatrixTransform;
typedef QTransform XpsRenderTransform;
typedef QBrush XpsFill;
struct XpsPathFigure
{

View file

@ -15,7 +15,7 @@ Name[en_GB]=Okular XPS Plugin
Name[es]=Complemento XPS de Okular
Name[et]=Okulari XPS-i plugin
Name[eu]=Okular-en XPS plugina
Name[fi]=XPS-liitännäinen ohjelmaa Okular varten
Name[fi]=XPS-liitännäinen Okularille
Name[fr]=Module externe XPS pour Okular
Name[ga]=Breiseán XPS Okular
Name[gl]=Extensión XPS para Okular
@ -71,7 +71,7 @@ Comment[en_GB]=XPS backend for Okular
Comment[es]=Motor XPS para Okular
Comment[et]=Okulari XPS-i taustaprogramm
Comment[eu]=Okular-en XPS motorra
Comment[fi]=XPS-taustaosa ohjelmaa Okular varten
Comment[fi]=XPS-taustaosa Okularille
Comment[fr]=Interface d'Okular pour les fichiers XPS
Comment[ga]=Inneall XPS le haghaidh Okular
Comment[gl]=Infraestrutura de XPS para Okular

View file

@ -142,7 +142,9 @@ X-KDE-Keywords[ga]=XPS
X-KDE-Keywords[hu]=XPS
X-KDE-Keywords[it]=XPS
X-KDE-Keywords[kk]=XPS
X-KDE-Keywords[km]=XPS
X-KDE-Keywords[ko]=XPS
X-KDE-Keywords[lv]=XPS
X-KDE-Keywords[nb]=XPS
X-KDE-Keywords[nds]=XPS
X-KDE-Keywords[nl]=XPS
@ -158,6 +160,7 @@ X-KDE-Keywords[sr@ijekavian]=XPS,ИксПС
X-KDE-Keywords[sr@ijekavianlatin]=XPS,XPS
X-KDE-Keywords[sr@latin]=XPS,XPS
X-KDE-Keywords[sv]=XPS
X-KDE-Keywords[tr]=XPS
X-KDE-Keywords[uk]=XPS
X-KDE-Keywords[x-test]=xxXPSxx
X-KDE-Keywords[zh_CN]=mXPS

View file

@ -58,7 +58,7 @@ Name[uk]=Okular
Name[x-test]=xxOkularxx
Name[zh_CN]=Okular
Name[zh_TW]=_Okular
X-KDE-ServiceTypes=KParts/ReadOnlyPart
X-KDE-ServiceTypes=KParts/ReadOnlyPart,KParts/ReadWritePart
X-KDE-Library=okularpart
Type=Service
MimeType=application/vnd.kde.okular-archive;

View file

@ -1,5 +1,5 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="okular_part_viewermode" version="1">
<kpartgui name="okular_part_viewermode" version="2">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
@ -24,7 +24,6 @@
<Action name="view_zoom_out" group="viewer_menu_merge"/>
<Action name="view_fit_to_width" group="viewer_menu_merge"/>
<Action name="view_fit_to_page" group="viewer_menu_merge"/>
<Action name="zoom_fit_rect" group="viewer_menu_merge"/>
<Separator group="viewer_menu_merge"/>
<Action name="view_continuous" group="viewer_menu_merge"/>
<Action name="view_render_mode" group="viewer_menu_merge"/>

185
part.cpp
View file

@ -86,6 +86,7 @@
#include "conf/preferencesdialog.h"
#include "settings.h"
#include "core/action.h"
#include "core/annotations.h"
#include "core/bookmarkmanager.h"
#include "core/document.h"
#include "core/generator.h"
@ -151,8 +152,25 @@ class FileKeeper
std::FILE * m_handle;
};
K_PLUGIN_FACTORY( okularPartFactory, registerPlugin< Okular::Part >(); )
K_EXPORT_PLUGIN( okularPartFactory( okularAboutData( "okular", I18N_NOOP( "Okular" ) ) ) )
Okular::PartFactory::PartFactory()
: KPluginFactory(okularAboutData( "okular", I18N_NOOP( "Okular" ) ))
{
}
Okular::PartFactory::~PartFactory()
{
}
QObject *Okular::PartFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword)
{
Q_UNUSED ( keyword );
Okular::Part *object = new Okular::Part( parentWidget, parent, args, componentData() );
object->setReadWrite( QLatin1String(iface) == QLatin1String("KParts::ReadWritePart") );
return object;
}
K_EXPORT_PLUGIN( Okular::PartFactory() )
static QAction* actionForExportFormat( const Okular::ExportFormat& format, QObject *parent = 0 )
{
@ -259,13 +277,16 @@ static bool keepFileOpen()
}
#endif
int Okular::Part::numberOfParts = 0;
namespace Okular
{
Part::Part(QWidget *parentWidget,
QObject *parent,
const QVariantList &args )
: KParts::ReadOnlyPart(parent),
const QVariantList &args,
KComponentData componentData )
: KParts::ReadWritePart(parent),
m_tempfile( 0 ), m_fileWasRemoved( false ), m_showMenuBarAction( 0 ), m_showFullScreenAction( 0 ), m_actionsSearched( false ),
m_cliPresentation(false), m_embedMode(detectEmbedMode(parentWidget, parent, args)), m_generatorGuiClient(0), m_keeper( 0 )
{
@ -283,8 +304,13 @@ m_cliPresentation(false), m_embedMode(detectEmbedMode(parentWidget, parent, args
}
}
Okular::Settings::instance( configFileName );
QDBusConnection::sessionBus().registerObject("/okular", this, QDBusConnection::ExportScriptableSlots);
numberOfParts++;
if (numberOfParts == 1) {
QDBusConnection::sessionBus().registerObject("/okular", this, QDBusConnection::ExportScriptableSlots);
} else {
QDBusConnection::sessionBus().registerObject(QString("/okular%1").arg(numberOfParts), this, QDBusConnection::ExportScriptableSlots);
}
// connect the started signal to tell the job the mimetypes we like,
// and get some more information from it
@ -300,7 +326,7 @@ m_cliPresentation(false), m_embedMode(detectEmbedMode(parentWidget, parent, args
new OkularLiveConnectExtension( this );
// we need an instance
setComponentData(okularPartFactory::componentData());
setComponentData( componentData );
GuiUtils::addIconLoader( iconLoader() );
@ -421,6 +447,7 @@ m_cliPresentation(false), m_embedMode(detectEmbedMode(parentWidget, parent, args
connect( m_findBar, SIGNAL(forwardKeyPressEvent(QKeyEvent*)), m_pageView, SLOT(externalKeyPressEvent(QKeyEvent*)));
connect( m_miniBar, SIGNAL(forwardKeyPressEvent(QKeyEvent*)), m_pageView, SLOT(externalKeyPressEvent(QKeyEvent*)));
connect( m_pageView, SIGNAL(escPressed()), m_findBar, SLOT(resetSearch()) );
connect( m_pageNumberTool, SIGNAL(forwardKeyPressEvent(QKeyEvent*)), m_pageView, SLOT(externalKeyPressEvent(QKeyEvent*)));
connect( m_reviewsWidget, SIGNAL(openAnnotationWindow(Okular::Annotation*,int)),
@ -764,14 +791,17 @@ void Part::setupActions()
ac->addAction( "switch_blackscreen_mode", blackscreenAction );
blackscreenAction->setShortcut( QKeySequence( Qt::Key_B ) );
blackscreenAction->setIcon( KIcon( "view-presentation" ) );
blackscreenAction->setEnabled( false );
KToggleAction *drawingAction = new KToggleAction( i18n( "Toggle Drawing Mode" ), ac );
ac->addAction( "presentation_drawing_mode", drawingAction );
drawingAction->setIcon( KIcon( "draw-freehand" ) );
drawingAction->setEnabled( false );
KAction *eraseDrawingAction = new KAction( i18n( "Erase Drawings" ), ac );
ac->addAction( "presentation_erase_drawings", eraseDrawingAction );
eraseDrawingAction->setIcon( KIcon( "draw-eraser" ) );
eraseDrawingAction->setEnabled( false );
}
Part::~Part()
@ -780,7 +810,7 @@ Part::~Part()
m_document->removeObserver( this );
if ( m_document->isOpened() )
Part::closeUrl();
Part::closeUrl( false );
delete m_toc;
delete m_pageView;
@ -968,7 +998,7 @@ void Part::setWindowTitleFromDocument()
{
// If 'DocumentTitle' should be used, check if the document has one. If
// either case is false, use the file name.
QString title = realUrl().fileName();
QString title = Okular::Settings::displayDocumentNameOrPath() == Okular::Settings::EnumDisplayDocumentNameOrPath::Path ? realUrl().pathOrUrl() : realUrl().fileName();
if ( Okular::Settings::displayDocumentTitle() )
{
@ -1015,6 +1045,7 @@ void Part::notifySetup( const QVector< Okular::Page * > & /*pages*/, int setupFl
rebuildBookmarkMenu();
updateAboutBackendAction();
m_findBar->resetSearch();
m_searchWidget->setEnabled( m_document->supportsSearching() );
}
@ -1025,6 +1056,9 @@ void Part::notifyViewportChanged( bool /*smoothMove*/ )
void Part::notifyPageChanged( int page, int flags )
{
if ( flags & Okular::DocumentObserver::NeedSaveAs )
setModified();
if ( !(flags & Okular::DocumentObserver::Bookmark ) )
return;
@ -1154,20 +1188,27 @@ bool Part::openFile()
mime = KMimeType::findByPath( fileNameToOpen );
}
bool ok = false;
isDocumentArchive = false;
if ( uncompressOk )
{
if ( mime->is( "application/vnd.kde.okular-archive" ) )
{
ok = m_document->openDocumentArchive( fileNameToOpen, url() );
isDocumentArchive = true;
}
else
{
ok = m_document->openDocument( fileNameToOpen, url(), mime );
}
}
bool canSearch = m_document->supportsSearching();
// update one-time actions
emit enableCloseAction( ok );
m_find->setEnabled( ok && canSearch );
m_findNext->setEnabled( ok && canSearch );
m_findPrev->setEnabled( ok && canSearch );
if( m_saveAs ) m_saveAs->setEnabled( ok && m_document->canSaveChanges() );
if( m_saveAs ) m_saveAs->setEnabled( ok && (m_document->canSaveChanges() || isDocumentArchive) );
if( m_saveCopyAs ) m_saveCopyAs->setEnabled( ok );
emit enablePrintAction( ok && m_document->printingSupport() != Okular::Document::NoPrinting );
m_printPreview->setEnabled( ok && m_document->printingSupport() != Okular::Document::NoPrinting );
@ -1214,6 +1255,7 @@ bool Part::openFile()
// if can't open document, update windows so they display blank contents
m_pageView->viewport()->update();
m_thumbnailList->update();
setUrl( KUrl() );
return false;
}
@ -1258,6 +1300,10 @@ bool Part::openFile()
bool Part::openUrl(const KUrl &_url)
{
// Close current document if any
if ( !closeUrl() )
return false;
KUrl url( _url );
if ( url.hasHTMLRef() )
{
@ -1281,7 +1327,7 @@ bool Part::openUrl(const KUrl &_url)
}
// this calls in sequence the 'closeUrl' and 'openFile' methods
bool openOk = KParts::ReadOnlyPart::openUrl( url );
bool openOk = KParts::ReadWritePart::openUrl( url );
if ( openOk )
{
@ -1297,9 +1343,36 @@ bool Part::openUrl(const KUrl &_url)
return openOk;
}
bool Part::closeUrl()
bool Part::queryClose()
{
if ( !isReadWrite() || !isModified() )
return true;
const int res = KMessageBox::warningYesNoCancel( widget(),
i18n( "Do you want to save your annotation changes or discard them?" ),
i18n( "Close Document" ),
KStandardGuiItem::saveAs(),
KStandardGuiItem::discard() );
switch ( res )
{
case KMessageBox::Yes: // Save as
slotSaveFileAs();
return !isModified(); // Only allow closing if file was really saved
case KMessageBox::No: // Discard
return true;
default: // Cancel
return false;
}
}
bool Part::closeUrl(bool promptToSave)
{
if ( promptToSave && !queryClose() )
return false;
setModified( false );
if (!m_temporaryLocalFile.isNull() && m_temporaryLocalFile != localFilePath())
{
QFile::remove( m_temporaryLocalFile );
@ -1307,6 +1380,7 @@ bool Part::closeUrl()
}
slotHidePresentation();
emit enableCloseAction( false );
m_find->setEnabled( false );
m_findNext->setEnabled( false );
m_findPrev->setEnabled( false );
@ -1358,17 +1432,22 @@ bool Part::closeUrl()
#ifdef OKULAR_KEEP_FILE_OPEN
m_keeper->close();
#endif
bool r = KParts::ReadOnlyPart::closeUrl();
bool r = KParts::ReadWritePart::closeUrl();
setUrl(KUrl());
return r;
}
bool Part::closeUrl()
{
return closeUrl( true );
}
void Part::guiActivateEvent(KParts::GUIActivateEvent *event)
{
updateViewActions();
KParts::ReadOnlyPart::guiActivateEvent(event);
KParts::ReadWritePart::guiActivateEvent(event);
}
void Part::close()
@ -1473,7 +1552,12 @@ void Part::slotDoFileDirty()
}
// close and (try to) reopen the document
if ( KParts::ReadOnlyPart::openUrl( url() ) )
KUrl oldUrl = url();
if ( !closeUrl() )
return;
if ( KParts::ReadWritePart::openUrl( oldUrl ) )
{
// on successful opening, restore the previous viewport
if ( m_viewportDirty.pageNumber >= (int) m_document->pages() )
@ -1864,30 +1948,79 @@ void Part::slotFindPrev()
m_findBar->findPrev();
}
bool Part::saveFile()
{
kDebug() << "Okular part doesn't support saving the file in the location from which it was opened";
return false;
}
void Part::slotSaveFileAs()
{
if ( m_embedMode == PrintPreviewMode )
return;
/* Show a warning before saving if the generator can't save annotations,
* unless we are going to save a .okular archive. */
if ( !isDocumentArchive && !m_document->canSaveChanges( Document::SaveAnnotationsCapability ) )
{
/* Search local annotations */
bool containsLocalAnnotations = false;
const int pagecount = m_document->pages();
for ( int pageno = 0; pageno < pagecount; ++pageno )
{
const Okular::Page *page = m_document->page( pageno );
foreach ( const Okular::Annotation *ann, page->annotations() )
{
if ( !(ann->flags() & Okular::Annotation::External) )
{
containsLocalAnnotations = true;
break;
}
}
if ( containsLocalAnnotations )
break;
}
/* Don't show it if there are no local annotations */
if ( containsLocalAnnotations )
{
int res = KMessageBox::warningContinueCancel( widget(), "Your annotations will not be exported.\nYou can export the annotated document using File -> Export As -> Document Archive" );
if ( res != KMessageBox::Continue )
return; // Canceled
}
}
KUrl saveUrl = KFileDialog::getSaveUrl( KUrl("kfiledialog:///okular/" + url().fileName()),
QString(), widget(), QString(),
KFileDialog::ConfirmOverwrite );
if ( !saveUrl.isValid() || saveUrl.isEmpty() )
return;
saveAs( saveUrl );
}
bool Part::saveAs( const KUrl & saveUrl )
{
KTemporaryFile tf;
QString fileName;
if ( !tf.open() )
{
KMessageBox::information( widget(), i18n("Could not open the temporary file for saving." ) );
return;
return false;
}
fileName = tf.fileName();
tf.close();
QString errorText;
if ( !m_document->saveChanges( fileName, &errorText ) )
bool saved;
if ( isDocumentArchive )
saved = m_document->saveDocumentArchive( fileName );
else
saved = m_document->saveChanges( fileName, &errorText );
if ( !saved )
{
if (errorText.isEmpty())
{
@ -1897,12 +2030,18 @@ void Part::slotSaveFileAs()
{
KMessageBox::information( widget(), i18n("File could not be saved in '%1'. %2", fileName, errorText ) );
}
return;
return false;
}
KIO::Job *copyJob = KIO::file_copy( fileName, saveUrl, -1, KIO::Overwrite );
if ( !KIO::NetAccess::synchronousRun( copyJob, widget() ) )
{
KMessageBox::information( widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", saveUrl.prettyUrl() ) );
return false;
}
setModified( false );
return true;
}
@ -2434,9 +2573,11 @@ void Part::unsetDummyMode()
// add back and next in history
m_historyBack = KStandardAction::documentBack( this, SLOT(slotHistoryBack()), actionCollection() );
m_historyBack->setWhatsThis( i18n( "Go to the place you were before" ) );
connect(m_pageView, SIGNAL(mouseBackButtonClick()), m_historyBack, SLOT(trigger()));
m_historyNext = KStandardAction::documentForward( this, SLOT(slotHistoryNext()), actionCollection());
m_historyNext->setWhatsThis( i18n( "Go to the place you were after" ) );
connect(m_pageView, SIGNAL(mouseForwardButtonClick()), m_historyNext, SLOT(trigger()));
m_pageView->setupActions( actionCollection() );
@ -2577,6 +2718,12 @@ void Part::updateAboutBackendAction()
}
}
void Part::setReadWrite(bool readwrite)
{
m_document->setAnnotationEditingEnabled( readwrite );
ReadWritePart::setReadWrite( readwrite );
}
} // namespace Okular
#include "part.moc"

31
part.h
View file

@ -17,6 +17,7 @@
#define _PART_H_
#include <kparts/part.h>
#include <kpluginfactory.h>
#include <qicon.h>
#include <qlist.h>
#include <qpointer.h>
@ -89,7 +90,7 @@ enum EmbedMode
* @author Wilco Greven <greven@kde.org>
* @version 0.2
*/
class Part : public KParts::ReadOnlyPart, public Okular::DocumentObserver, public KDocumentViewer, public Okular::ViewerInterface
class Part : public KParts::ReadWritePart, public Okular::DocumentObserver, public KDocumentViewer, public Okular::ViewerInterface
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.okular")
@ -104,7 +105,7 @@ class Part : public KParts::ReadOnlyPart, public Okular::DocumentObserver, publi
* which config file should be used by adding a string containing "ConfigFileName=<file name>"
* to 'args'.
**/
Part(QWidget* parentWidget, QObject* parent, const QVariantList& args);
Part(QWidget* parentWidget, QObject* parent, const QVariantList& args, KComponentData componentData);
// Destructor
~Part();
@ -149,13 +150,20 @@ class Part : public KParts::ReadOnlyPart, public Okular::DocumentObserver, publi
void enablePrintAction(bool enable);
void openSourceReference(const QString& absFileName, int line, int column);
void viewerMenuStateChange(bool enabled);
void enableCloseAction(bool enable);
protected:
// reimplemented from KParts::ReadOnlyPart
// reimplemented from KParts::ReadWritePart
bool openFile();
bool openUrl(const KUrl &url);
bool closeUrl();
void guiActivateEvent(KParts::GUIActivateEvent *event);
public:
bool saveFile();
bool queryClose();
bool closeUrl();
bool closeUrl(bool promptToSave);
void setReadWrite(bool readwrite);
bool saveAs(const KUrl & saveUrl);
protected slots:
// connected to actions
@ -223,12 +231,15 @@ class Part : public KParts::ReadOnlyPart, public Okular::DocumentObserver, publi
void updateAboutBackendAction();
void unsetDummyMode();
void slotRenameBookmark( const DocumentViewport &viewport );
static int numberOfParts;
KTemporaryFile *m_tempfile;
// the document
Okular::Document * m_document;
QString m_temporaryLocalFile;
bool isDocumentArchive;
// main widgets
Sidebar *m_sidebar;
@ -319,6 +330,18 @@ class Part : public KParts::ReadOnlyPart, public Okular::DocumentObserver, publi
void slotHandleActivatedSourceReference(const QString& absFileName, int line, int col, bool *handled);
};
class PartFactory : public KPluginFactory
{
Q_OBJECT
public:
PartFactory();
virtual ~PartFactory();
protected:
virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword);
};
}
#endif

View file

@ -1,5 +1,5 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="okular_part" version="32">
<kpartgui name="okular_part" version="33">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Action name="get_new_stuff" group="file_open"/>
@ -29,7 +29,6 @@
<Action name="view_zoom_out"/>
<Action name="view_fit_to_width"/>
<Action name="view_fit_to_page"/>
<Action name="zoom_fit_rect"/>
<Separator/>
<Action name="view_continuous"/>
<Action name="view_render_mode"/>

View file

@ -17,6 +17,7 @@
#include <kcmdlineargs.h>
#include <klocale.h>
#include <QtDBus/qdbusinterface.h>
#include <QTextStream>
#include "aboutdata.h"
#include "shellutils.h"
@ -26,13 +27,15 @@ static bool attachUniqueInstance(KCmdLineArgs* args)
return false;
QDBusInterface iface("org.kde.okular", "/okular", "org.kde.okular");
if (!iface.isValid())
QDBusInterface iface2("org.kde.okular", "/okularshell", "org.kde.okular");
if (!iface.isValid() || !iface2.isValid())
return false;
if (args->isSet("page"))
iface.call("openDocument", ShellUtils::urlFromArg(args->arg(0), ShellUtils::qfileExistFunc(), args->getOption("page")).url());
else
iface.call("openDocument", ShellUtils::urlFromArg(args->arg(0), ShellUtils::qfileExistFunc()).url());
iface2.call("tryRaise");
return true;
}
@ -72,6 +75,12 @@ int main(int argc, char** argv)
Shell* widget = new Shell(args);
widget->show();
}
else if (args->isSet( "unique" ) && args->count() > 1)
{
QTextStream stream(stderr);
stream << i18n( "Error: Can't open more than one document with the --unique switch" ) << endl;
return -1;
}
else
{
for (int i = 0; i < args->count(); ++i)

View file

@ -42,6 +42,7 @@
#include <ktoggleaction.h>
#include <ktogglefullscreenaction.h>
#include <kactioncollection.h>
#include <kwindowsystem.h>
// local includes
#include "kdocumentviewer.h"
@ -85,7 +86,7 @@ void Shell::init()
// now that the Part is loaded, we cast it to a Part to get
// our hands on it
m_part = factory->create< KParts::ReadOnlyPart >( this );
m_part = factory->create< KParts::ReadWritePart >( this );
if (m_part)
{
// then, setup our actions
@ -101,13 +102,19 @@ void Shell::init()
connect( this, SIGNAL(restoreDocument(KConfigGroup)),m_part, SLOT(restoreDocument(KConfigGroup)));
connect( this, SIGNAL(saveDocumentRestoreInfo(KConfigGroup&)), m_part, SLOT(saveDocumentRestoreInfo(KConfigGroup&)));
connect( m_part, SIGNAL(enablePrintAction(bool)), m_printAction, SLOT(setEnabled(bool)));
connect( m_part, SIGNAL(enableCloseAction(bool)), m_closeAction, SLOT(setEnabled(bool)));
readSettings();
if (m_args && m_args->isSet("unique") && m_args->count() == 1)
m_unique = false;
if (m_args && m_args->isSet("unique") && m_args->count() <= 1)
{
QDBusConnection::sessionBus().registerService("org.kde.okular");
m_unique = QDBusConnection::sessionBus().registerService("org.kde.okular");
if (!m_unique)
KMessageBox::information(this, i18n("There is already a unique Okular instance running. This instance won't be the unique one."));
}
QDBusConnection::sessionBus().registerObject("/okularshell", this, QDBusConnection::ExportScriptableSlots);
if (m_openUrl.isValid()) QTimer::singleShot(0, this, SLOT(delayedOpen()));
}
@ -117,10 +124,19 @@ void Shell::delayedOpen()
openUrl( m_openUrl );
}
void Shell::showOpenRecentMenu()
{
m_recent->menu()->popup(QCursor::pos());
}
Shell::~Shell()
{
if ( m_part ) writeSettings();
delete m_part;
if ( m_part )
{
writeSettings();
m_part->closeUrl( false );
}
m_part = 0; // It is deleted by the KPart/QObject machinery
if ( m_args )
m_args->clear();
}
@ -129,20 +145,40 @@ void Shell::openUrl( const KUrl & url )
{
if ( m_part )
{
if ( m_doc && m_args && m_args->isSet( "presentation" ) )
m_doc->startPresentation();
bool openOk = m_part->openUrl( url );
const bool isstdin = url.fileName( KUrl::ObeyTrailingSlash ) == QLatin1String( "-" );
if ( !isstdin )
if( !m_part->url().isEmpty() )
{
if ( openOk )
m_recent->addUrl( url );
if( m_unique )
{
KMessageBox::error(this, i18n("Can't open more than one document in the unique Okular instance."));
}
else
m_recent->removeUrl( url );
{
Shell* newShell = new Shell();
newShell->openUrl( url );
newShell->show();
}
}
else
{
if ( m_doc && m_args && m_args->isSet( "presentation" ) )
m_doc->startPresentation();
bool openOk = m_part->openUrl( url );
const bool isstdin = url.fileName( KUrl::ObeyTrailingSlash ) == QLatin1String( "-" );
if ( !isstdin )
{
if ( openOk )
m_recent->addUrl( url );
else
m_recent->removeUrl( url );
}
}
}
}
void Shell::closeUrl()
{
m_part->closeUrl();
}
void Shell::readSettings()
{
@ -178,12 +214,13 @@ void Shell::setupActions()
KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
m_recent = KStandardAction::openRecent( this, SLOT(openUrl(KUrl)), actionCollection() );
m_recent->setToolBarMode( KRecentFilesAction::MenuMode );
m_recent->setToolButtonPopupMode( QToolButton::DelayedPopup );
connect( m_recent, SIGNAL(triggered()), this, SLOT(fileOpen()) );
connect( m_recent, SIGNAL(triggered()), this, SLOT(showOpenRecentMenu()) );
m_recent->setToolTip( i18n("Click to open a file\nClick and hold to open a recent file") );
m_recent->setWhatsThis( i18n( "<b>Click</b> to open a file or <b>Click and hold</b> to select a recent file" ) );
m_printAction = KStandardAction::print( m_part, SLOT(slotPrint()), actionCollection() );
m_printAction->setEnabled( false );
m_closeAction = KStandardAction::close( this, SLOT(closeUrl()), actionCollection() );
m_closeAction->setEnabled( false );
KStandardAction::quit(this, SLOT(slotQuit()), actionCollection());
setStandardToolBarMenuEnabled(true);
@ -267,7 +304,9 @@ void Shell::fileOpen()
return;
KUrl url = dlg.selectedUrl();
if ( !url.isEmpty() )
{
openUrl( url );
}
}
void Shell::slotQuit()
@ -275,6 +314,14 @@ void Shell::slotQuit()
close();
}
void Shell::tryRaise()
{
if (m_unique)
{
KWindowSystem::forceActiveWindow( window()->effectiveWinId() );
}
}
// only called when starting the program
void Shell::setFullScreen( bool useFullScreen )
{
@ -331,6 +378,11 @@ QSize Shell::sizeHint() const
return QApplication::desktop()->availableGeometry( this ).size() * 0.75;
}
bool Shell::queryClose()
{
return m_part ? m_part->queryClose() : true;
}
#include "shell.moc"
/* kate: replace-tabs on; indent-width 4; */

View file

@ -18,6 +18,8 @@
#include <kparts/mainwindow.h>
#include <QtDBus/QtDBus>
class KCmdLineArgs;
class KRecentFilesAction;
class KToggleAction;
@ -36,6 +38,7 @@ class Part;
class Shell : public KParts::MainWindow
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.okular")
public:
/**
@ -51,6 +54,8 @@ public:
QSize sizeHint() const;
public slots:
void slotQuit();
Q_SCRIPTABLE Q_NOREPLY void tryRaise();
protected:
/**
@ -68,6 +73,7 @@ protected:
void readSettings();
void writeSettings();
void setFullScreen( bool );
bool queryClose();
void showEvent(QShowEvent *event);
@ -79,6 +85,8 @@ private slots:
void openUrl( const KUrl & url );
void delayedOpen();
void showOpenRecentMenu();
void closeUrl();
signals:
void restoreDocument(const KConfigGroup &group);
@ -92,15 +100,17 @@ private:
private:
KCmdLineArgs* m_args;
KParts::ReadOnlyPart* m_part;
KParts::ReadWritePart* m_part;
KDocumentViewer* m_doc;
KRecentFilesAction* m_recent;
QStringList m_fileformats;
bool m_fileformatsscanned;
KAction* m_printAction;
KAction* m_closeAction;
KToggleAction* m_fullScreenAction;
KToggleAction* m_showMenuBarAction;
bool m_menuBarWasShown, m_toolBarWasShown;
bool m_unique;
KUrl m_openUrl;
};

View file

@ -18,9 +18,11 @@
#include "core/document.h"
#include "guiutils.h"
AnnotationPopup::AnnotationPopup( Okular::Document *document,
Q_DECLARE_METATYPE( AnnotationPopup::AnnotPagePair )
AnnotationPopup::AnnotationPopup( Okular::Document *document, MenuMode mode,
QWidget *parent )
: mParent( parent ), mDocument( document )
: mParent( parent ), mDocument( document ), mMenuMode( mode )
{
}
@ -38,57 +40,114 @@ void AnnotationPopup::exec( const QPoint &point )
KMenu menu( mParent );
QAction *popoutWindow = 0;
QAction *deleteNote = 0;
QAction *showProperties = 0;
QAction *saveAttachment = 0;
QAction *action = 0;
Okular::FileAttachmentAnnotation *fileAttachAnnot = 0;
const bool onlyOne = mAnnotations.count() == 1;
const char *actionTypeId = "actionType";
menu.addTitle( i18np( "Annotation", "%1 Annotations", mAnnotations.count() ) );
popoutWindow = menu.addAction( KIcon( "comment" ), i18n( "&Open Pop-up Note" ) );
popoutWindow->setEnabled( onlyOne );
deleteNote = menu.addAction( KIcon( "list-remove" ), i18n( "&Delete" ) );
deleteNote->setEnabled( mDocument->isAllowed( Okular::AllowNotes ) );
const QString openId = QString::fromLatin1( "open" );
const QString deleteId = QString::fromLatin1( "delete" );
const QString deleteAllId = QString::fromLatin1( "deleteAll" );
const QString propertiesId = QString::fromLatin1( "properties" );
const QString saveId = QString::fromLatin1( "save" );
const AnnotPagePair &firstAnnotPagePair = mAnnotations.at(0);
foreach ( const AnnotPagePair& pair, mAnnotations )
if ( mMenuMode == SingleAnnotationMode )
{
if ( !mDocument->canRemovePageAnnotation(pair.annotation) )
deleteNote->setEnabled( false );
const bool onlyOne = (mAnnotations.count() == 1);
const AnnotPagePair &pair = mAnnotations.at(0);
menu.addTitle( i18np( "Annotation", "%1 Annotations", mAnnotations.count() ) );
action = menu.addAction( KIcon( "comment" ), i18n( "&Open Pop-up Note" ) );
action->setData( QVariant::fromValue( pair ) );
action->setEnabled( onlyOne );
action->setProperty( actionTypeId, openId );
action = menu.addAction( KIcon( "list-remove" ), i18n( "&Delete" ) );
action->setEnabled( mDocument->isAllowed( Okular::AllowNotes ) );
action->setProperty( actionTypeId, deleteAllId );
foreach ( const AnnotPagePair& pair, mAnnotations )
{
if ( !mDocument->canRemovePageAnnotation( pair.annotation ) )
action->setEnabled( false );
}
action = menu.addAction( KIcon( "configure" ), i18n( "&Properties" ) );
action->setData( QVariant::fromValue( pair ) );
action->setEnabled( onlyOne );
action->setProperty( actionTypeId, propertiesId );
if ( onlyOne && pair.annotation->subType() == Okular::Annotation::AFileAttachment )
{
menu.addSeparator();
fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", fileAttachAnnot->embeddedFile()->name() );
action = menu.addAction( KIcon( "document-save" ), saveText );
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, saveId );
}
}
showProperties = menu.addAction( KIcon( "configure" ), i18n( "&Properties" ) );
showProperties->setEnabled( onlyOne );
if ( onlyOne && firstAnnotPagePair.annotation->subType() == Okular::Annotation::AFileAttachment )
else
{
menu.addSeparator();
fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( firstAnnotPagePair.annotation );
const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", fileAttachAnnot->embeddedFile()->name() );
saveAttachment = menu.addAction( KIcon( "document-save" ), saveText );
foreach ( const AnnotPagePair& pair, mAnnotations )
{
menu.addTitle( GuiUtils::captionForAnnotation( pair.annotation ) );
action = menu.addAction( KIcon( "comment" ), i18n( "&Open Pop-up Note" ) );
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, openId );
action = menu.addAction( KIcon( "list-remove" ), i18n( "&Delete" ) );
action->setEnabled( mDocument->isAllowed( Okular::AllowNotes ) &&
mDocument->canRemovePageAnnotation( pair.annotation ) );
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, deleteId );
action = menu.addAction( KIcon( "configure" ), i18n( "&Properties" ) );
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, propertiesId );
if ( pair.annotation->subType() == Okular::Annotation::AFileAttachment )
{
menu.addSeparator();
fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", fileAttachAnnot->embeddedFile()->name() );
action = menu.addAction( KIcon( "document-save" ), saveText );
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, saveId );
}
}
}
QAction *choice = menu.exec( point.isNull() ? QCursor::pos() : point );
// check if the user really selected an action
if ( choice ) {
if ( choice == popoutWindow ) {
emit openAnnotationWindow( firstAnnotPagePair.annotation, firstAnnotPagePair.pageNumber );
} else if( choice == deleteNote ) {
const AnnotPagePair pair = choice->data().value<AnnotPagePair>();
const QString actionType = choice->property( actionTypeId ).toString();
if ( actionType == openId ) {
emit openAnnotationWindow( pair.annotation, pair.pageNumber );
} else if( actionType == deleteId ) {
if ( pair.pageNumber != -1 )
mDocument->removePageAnnotation( pair.pageNumber, pair.annotation );
} else if( actionType == deleteAllId ) {
Q_FOREACH ( const AnnotPagePair& pair, mAnnotations )
{
if ( pair.pageNumber != -1 )
mDocument->removePageAnnotation( pair.pageNumber, pair.annotation );
}
} else if( choice == showProperties ) {
if ( firstAnnotPagePair.pageNumber != -1 ) {
AnnotsPropertiesDialog propdialog( mParent, mDocument, firstAnnotPagePair.pageNumber, firstAnnotPagePair.annotation );
} else if( actionType == propertiesId ) {
if ( pair.pageNumber != -1 ) {
AnnotsPropertiesDialog propdialog( mParent, mDocument, pair.pageNumber, pair.annotation );
propdialog.exec();
}
} else if( choice == saveAttachment ) {
Q_ASSERT( fileAttachAnnot );
} else if( actionType == saveId ) {
const Okular::FileAttachmentAnnotation * fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
GuiUtils::saveEmbeddedFile( fileAttachAnnot->embeddedFile(), mParent );
}
}

View file

@ -25,8 +25,16 @@ class AnnotationPopup : public QObject
Q_OBJECT
public:
explicit AnnotationPopup( Okular::Document *document,
QWidget *parent = 0 );
/**
* Describes the structure of the popup menu.
*/
enum MenuMode
{
SingleAnnotationMode, ///< The menu shows only entries to manipulate a single annotation, or multiple annotations as a group.
MultiAnnotationMode ///< The menu shows entries to manipulate multiple annotations.
};
AnnotationPopup( Okular::Document *document, MenuMode mode, QWidget *parent = 0 );
void addAnnotation( Okular::Annotation* annotation, int pageNumber );
@ -35,9 +43,11 @@ class AnnotationPopup : public QObject
Q_SIGNALS:
void openAnnotationWindow( Okular::Annotation *annotation, int pageNumber );
private:
QWidget *mParent;
public:
struct AnnotPagePair {
AnnotPagePair() : annotation( 0 ), pageNumber( -1 )
{ }
AnnotPagePair( Okular::Annotation *a, int pn ) : annotation( a ), pageNumber( pn )
{ }
@ -50,8 +60,13 @@ class AnnotationPopup : public QObject
Okular::Annotation* annotation;
int pageNumber;
};
private:
QWidget *mParent;
QList< AnnotPagePair > mAnnotations;
Okular::Document *mDocument;
MenuMode mMenuMode;
};

View file

@ -50,6 +50,10 @@ AnnotatorEngine::~AnnotatorEngine()
{
}
SmoothPath::SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen )
: points ( points ), pen ( pen )
{
}
/** SmoothPathEngine */
SmoothPathEngine::SmoothPathEngine( const QDomElement & engineElement )
@ -112,12 +116,20 @@ QRect SmoothPathEngine::event( EventType type, Button button, double nX, double
}
void SmoothPathEngine::paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ )
{
// use engine's color for painting
const SmoothPath path( points, QPen(m_engineColor, 1) );
// draw the path
path.paint( painter, xScale, yScale );
}
void SmoothPath::paint( QPainter * painter, double xScale, double yScale ) const
{
// draw SmoothPaths with at least 2 points
if ( points.count() > 1 )
{
// use engine's color for painting
painter->setPen( QPen( m_engineColor, 1 ) );
painter->setPen( pen );
QLinkedList<Okular::NormalizedPoint>::const_iterator pIt = points.begin(), pEnd = points.end();
Okular::NormalizedPoint pA = *pIt;
@ -173,3 +185,17 @@ QList< Okular::Annotation* > SmoothPathEngine::end()
return QList< Okular::Annotation* >() << ann;
}
SmoothPath SmoothPathEngine::endSmoothPath()
{
m_creationCompleted = false;
double width = 1;
if ( m_annotElement.hasAttribute( "width" ) )
width = m_annotElement.attribute( "width" ).toDouble();
QColor color( m_annotElement.hasAttribute( "color" ) ?
m_annotElement.attribute( "color" ) : m_engineColor );
return SmoothPath( points, QPen(color, width) );
}

View file

@ -12,6 +12,7 @@
#include <qdom.h>
#include <qlinkedlist.h>
#include <qpen.h>
#include <qrect.h>
#include "core/area.h"
@ -64,6 +65,17 @@ class AnnotatorEngine
PageViewItem * m_item;
};
class SmoothPath
{
public:
SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen );
void paint( QPainter * painter, double xScale, double yScale ) const;
private:
const QLinkedList<Okular::NormalizedPoint> points;
const QPen pen;
};
/** @short SmoothPathEngine */
class SmoothPathEngine
: public AnnotatorEngine
@ -75,7 +87,9 @@ class SmoothPathEngine
void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ );
// These are two alternative ways to get the resulting path. Don't call them both!
QList< Okular::Annotation* > end();
SmoothPath endSmoothPath();
private:
// data

View file

@ -202,9 +202,6 @@ AnnotWindow::AnnotWindow( QWidget * parent, Okular::Annotation * annot, Okular::
if (!canEditAnnotation)
textEdit->setReadOnly(true);
m_latexRenderer = new GuiUtils::LatexRenderer();
emit containsLatex( GuiUtils::LatexRenderer::mightContainLatex( GuiUtils::contents( m_annot ) ) );
QVBoxLayout * mainlay = new QVBoxLayout( this );
mainlay->setMargin( 2 );
mainlay->setSpacing( 0 );
@ -217,6 +214,9 @@ AnnotWindow::AnnotWindow( QWidget * parent, Okular::Annotation * annot, Okular::
QSizeGrip * sb = new QSizeGrip( this );
lowerlay->addWidget( sb );
m_latexRenderer = new GuiUtils::LatexRenderer();
emit containsLatex( GuiUtils::LatexRenderer::mightContainLatex( GuiUtils::contents( m_annot ) ) );
m_title->setTitle( m_annot->window().summary() );
m_title->connectOptionButton( this, SLOT(slotOptionBtn()) );

View file

@ -62,9 +62,7 @@ class BookmarkItem : public QTreeWidgetItem
if ( other.type() == BookmarkItemType )
{
const BookmarkItem *cmp = static_cast< const BookmarkItem* >( &other );
const int v = m_viewport.pageNumber - cmp->m_viewport.pageNumber;
if ( v != 0 )
return v < 0;
return m_viewport < cmp->m_viewport;
}
return QTreeWidgetItem::operator<( other );
}
@ -229,7 +227,8 @@ void BookmarkList::slotChanged( QTreeWidgetItem * item )
FileItem* fItem = dynamic_cast<FileItem*>( item );
if ( fItem )
{
m_document->bookmarkManager()->renameBookmark( m_document->currentDocument(), fItem->text( 0 ) );
const KUrl url = fItem->data( 0, UrlRole ).value< KUrl >();
m_document->bookmarkManager()->renameBookmark( url, fItem->text( 0 ) );
m_document->bookmarkManager()->save();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more