mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-02 14:14:10 +00:00
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor (like the ones acroread and kviewshell have) it doesnt intersect the selection area with words under it, no, it does a lot more, including work on cursors and searching for the text area closest to the given cursor - 2. rotation support, change the orientation of the documents if you need too :) - 3. the kfaxview backend works beautifully, porting kviewshell backends is damn easy ! djvu and dvi will be next! - 4. Hardware Blending of selection rectangles! We now use XRender instead of KImageEffect, makes a damn faster blend! - 5. Overview mode - as seen in Kviewshell, but quite a bit extended, the kviewshell is only one state, while we support it in both continous and non-continous form - BTW. I coded all those features myself, (apart from kfaxview backend library) it is an impressive bit right? but oKular cant be run by only one person, join in on the fun! i can introduce you into the code just mail niedakh@gmail.com svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
This commit is contained in:
parent
efd05b1ea5
commit
4387e1489e
|
@ -8,149 +8,80 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>351</width>
|
||||
<height>416</height>
|
||||
<width>340</width>
|
||||
<height>554</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="caption">
|
||||
<string>DlgGeneral</string>
|
||||
</property>
|
||||
<spacer>
|
||||
<property name="name">
|
||||
<cstring>spacer3</cstring>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>510</y>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
</spacer>
|
||||
<spacer>
|
||||
<property name="name">
|
||||
<cstring>spacer4</cstring>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<y>180</y>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</spacer>
|
||||
<widget class="QLayoutWidget">
|
||||
<property name="name">
|
||||
<cstring>layout7</cstring>
|
||||
<cstring>layout13</cstring>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<width>348</width>
|
||||
<height>408</height>
|
||||
<y>0</y>
|
||||
<width>295</width>
|
||||
<height>501</height>
|
||||
</rect>
|
||||
</property>
|
||||
<grid>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QGroupBox" row="2" column="0">
|
||||
<property name="name">
|
||||
<cstring>groupBox2_2</cstring>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Temporary DEBUG Options</string>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_DebugDrawBoundaries</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DebugDrawBoundaries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_DebugDrawAnnotationRect</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DebugDrawAnnotationRect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
<widget class="QGroupBox" row="1" column="0">
|
||||
<property name="name">
|
||||
<cstring>groupBox3</cstring>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Program Features</string>
|
||||
</property>
|
||||
<grid>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QLayoutWidget" row="0" column="1">
|
||||
<property name="name">
|
||||
<cstring>layout3_2_2</cstring>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QLabel">
|
||||
<property name="name">
|
||||
<cstring>pixmapLabel1_2_2</cstring>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy>
|
||||
<hsizetype>0</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>"exec", 32</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
<spacer>
|
||||
<property name="name">
|
||||
<cstring>spacerV1_2</cstring>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</vbox>
|
||||
</widget>
|
||||
<widget class="QLayoutWidget" row="0" column="0">
|
||||
<property name="name">
|
||||
<cstring>layout5</cstring>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ObeyDRM</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Obey DRM limitations</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_WatchFile</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Watch file</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ChooseGenerators</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show generator selection dialog</string>
|
||||
</property>
|
||||
<property name="accel">
|
||||
<string></string>
|
||||
</property>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
</grid>
|
||||
</widget>
|
||||
<widget class="QGroupBox" row="0" column="0">
|
||||
<widget class="QGroupBox">
|
||||
<property name="name">
|
||||
<cstring>groupBox2</cstring>
|
||||
</property>
|
||||
|
@ -176,6 +107,9 @@
|
|||
<property name="text">
|
||||
<string>Show scroll&bars</string>
|
||||
</property>
|
||||
<property name="accel">
|
||||
<string>Alt+B</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
|
@ -262,33 +196,216 @@
|
|||
</widget>
|
||||
</hbox>
|
||||
</widget>
|
||||
</grid>
|
||||
<widget class="QGroupBox">
|
||||
<property name="name">
|
||||
<cstring>groupBox3</cstring>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Program Features</string>
|
||||
</property>
|
||||
<grid>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QLayoutWidget" row="0" column="1">
|
||||
<property name="name">
|
||||
<cstring>layout3_2_2</cstring>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QLabel">
|
||||
<property name="name">
|
||||
<cstring>pixmapLabel1_2_2</cstring>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy>
|
||||
<hsizetype>0</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>"exec", 32</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
<spacer>
|
||||
<property name="name">
|
||||
<cstring>spacerV1_2</cstring>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</vbox>
|
||||
</widget>
|
||||
<widget class="QLayoutWidget" row="0" column="0">
|
||||
<property name="name">
|
||||
<cstring>layout5</cstring>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ObeyDRM</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Obey DRM limitations</string>
|
||||
</property>
|
||||
<property name="accel">
|
||||
<string>Alt+O</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_WatchFile</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Watch file</string>
|
||||
</property>
|
||||
<property name="accel">
|
||||
<string>Alt+W</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ChooseGenerators</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show generator selection dialog</string>
|
||||
</property>
|
||||
<property name="accel">
|
||||
<string></string>
|
||||
</property>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
</grid>
|
||||
</widget>
|
||||
<widget class="QGroupBox">
|
||||
<property name="name">
|
||||
<cstring>groupBox2_2_2</cstring>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Rendering options</string>
|
||||
</property>
|
||||
<widget class="QLayoutWidget">
|
||||
<property name="name">
|
||||
<cstring>layout12</cstring>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>230</width>
|
||||
<height>58</height>
|
||||
</rect>
|
||||
</property>
|
||||
<grid>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QLabel" row="1" column="0">
|
||||
<property name="name">
|
||||
<cstring>columnLabel</cstring>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy>
|
||||
<hsizetype>4</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Overview columns:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" row="0" column="0">
|
||||
<property name="name">
|
||||
<cstring>rowLabel</cstring>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy>
|
||||
<hsizetype>4</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Overview rows:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" row="1" column="1">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ViewColumns</cstring>
|
||||
</property>
|
||||
<property name="maxValue">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="minValue">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" row="0" column="1">
|
||||
<property name="name">
|
||||
<cstring>kcfg_ViewRows</cstring>
|
||||
</property>
|
||||
<property name="maxValue">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minValue">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</grid>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox">
|
||||
<property name="name">
|
||||
<cstring>groupBox2_2</cstring>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Temporary DEBUG Options</string>
|
||||
</property>
|
||||
<vbox>
|
||||
<property name="name">
|
||||
<cstring>unnamed</cstring>
|
||||
</property>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_DebugDrawBoundaries</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DebugDrawBoundaries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
<cstring>kcfg_DebugDrawAnnotationRect</cstring>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DebugDrawAnnotationRect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
<spacer>
|
||||
<property name="name">
|
||||
<cstring>spacer3</cstring>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>410</y>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
<includes>
|
||||
<include location="global" impldecl="in implementation">kdialog.h</include>
|
||||
|
|
|
@ -184,6 +184,11 @@
|
|||
<min>1</min>
|
||||
<max>8</max>
|
||||
</entry>
|
||||
<entry key="ViewRows" type="UInt" >
|
||||
<default>1</default>
|
||||
<min>1</min>
|
||||
<max>5</max>
|
||||
</entry>
|
||||
<entry key="ViewContinuous" type="Bool" >
|
||||
<default>true</default>
|
||||
</entry>
|
||||
|
|
|
@ -145,10 +145,10 @@ Annotation::Annotation( const QDomNode & annNode )
|
|||
// parse boundary
|
||||
if ( ee.tagName() == "boundary" )
|
||||
{
|
||||
boundary.left = ee.attribute( "l" ).toDouble();
|
||||
boundary.top = ee.attribute( "t" ).toDouble();
|
||||
boundary.right = ee.attribute( "r" ).toDouble();
|
||||
boundary.bottom = ee.attribute( "b" ).toDouble();
|
||||
boundary=NormalizedRect(ee.attribute( "l" ).toDouble(),
|
||||
ee.attribute( "t" ).toDouble(),
|
||||
ee.attribute( "r" ).toDouble(),
|
||||
ee.attribute( "b" ).toDouble());
|
||||
}
|
||||
// parse penStyle if not default
|
||||
else if ( ee.tagName() == "penStyle" )
|
||||
|
|
|
@ -37,7 +37,7 @@ NormalizedRect::NormalizedRect( const QRect & r, double xScale, double yScale )
|
|||
|
||||
bool NormalizedRect::isNull() const
|
||||
{
|
||||
return left == 0 && top == 0 && right == 0 && bottom == 0;
|
||||
return left == 0 && top== 0 && right == 0 && bottom == 0;
|
||||
}
|
||||
|
||||
bool NormalizedRect::contains( double x, double y ) const
|
||||
|
@ -60,6 +60,28 @@ bool NormalizedRect::intersects( double l, double t, double r, double b ) const
|
|||
return (l <= right) && (r >= left) && (t <= bottom) && (b >= top);
|
||||
}
|
||||
|
||||
NormalizedRect NormalizedRect::operator| (const NormalizedRect & r) const
|
||||
{
|
||||
NormalizedRect ret;
|
||||
// todo !
|
||||
ret.left=QMIN(left,r.left);
|
||||
ret.top=QMIN(top,r.top);
|
||||
ret.bottom=QMAX(bottom,r.bottom);
|
||||
ret.right=QMAX(right,r.right);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NormalizedRect& NormalizedRect::operator|= (const NormalizedRect & r)
|
||||
{
|
||||
return ((*this) = (*this) | r );
|
||||
}
|
||||
/*
|
||||
kdbgstream& operator << (kdbgstream& str , const NormalizedRect &r)
|
||||
{
|
||||
str << "[" <<r.left() << "," << r.top() << "] x "<< "[" <<r.right() << "," << r.bottom() << "]";
|
||||
return str;
|
||||
}*/
|
||||
|
||||
QRect NormalizedRect::geometry( int xScale, int yScale ) const
|
||||
{
|
||||
int l = (int)( left * xScale ),
|
||||
|
|
59
core/area.h
59
core/area.h
|
@ -11,6 +11,7 @@
|
|||
#define _KPDF_AREA_H_
|
||||
#include <qvaluelist.h>
|
||||
#include <qcolor.h>
|
||||
#include <kdebug.h>
|
||||
class QRect;
|
||||
class KPDFLink;
|
||||
|
||||
|
@ -44,8 +45,11 @@ class NormalizedRect
|
|||
bool intersects( double l, double t, double r, double b ) const;
|
||||
bool intersects( const NormalizedRect * r ) const;
|
||||
QRect geometry( int xScale, int yScale ) const;
|
||||
NormalizedRect operator| (const NormalizedRect & r) const;
|
||||
NormalizedRect& operator|= (const NormalizedRect & r);
|
||||
};
|
||||
|
||||
// kdbgstream& operator << (kdbgstream &, const NormalizedRect &);
|
||||
|
||||
/**
|
||||
* @short NormalizedRect that contains a reference to an object.
|
||||
|
@ -98,6 +102,7 @@ struct HighlightRect : public NormalizedRect
|
|||
* intersects(NormalizedShape)
|
||||
* isNull()
|
||||
* geometry(int,int)
|
||||
* operator | and |= which unite two NormalizedShapes
|
||||
*/
|
||||
|
||||
template <class NormalizedShape, class Shape> class RegularArea :
|
||||
|
@ -109,13 +114,43 @@ public QValueList<NormalizedShape*>
|
|||
// RegularArea<NormalizedShape,Shape> (NormalizedShape* x) { QValueList(x) ; } ;
|
||||
// class Iterator : public QValueListIterator<NormalizedShape*> {};
|
||||
bool contains( double x, double y ) const;
|
||||
bool contains( NormalizedShape * ) const;
|
||||
bool intersects (const RegularArea<NormalizedShape,Shape> * area) const;
|
||||
bool intersects (const NormalizedShape * shape) const;
|
||||
void appendArea (const RegularArea<NormalizedShape,Shape> *area);
|
||||
void simplify ();
|
||||
bool isNull() const;
|
||||
QValueList<Shape>* geometry( int xScale, int yScale ) const;
|
||||
QValueList<Shape>* geometry( int xScale, int yScale, int dx=0,int dy=0 ) const;
|
||||
};
|
||||
|
||||
template <class NormalizedShape, class Shape>
|
||||
void RegularArea<NormalizedShape, Shape>::simplify()
|
||||
{
|
||||
int end=this->count(),i=0,x=0;
|
||||
QValueList <NormalizedShape*> m_remove;
|
||||
for (;i<end;i++)
|
||||
{
|
||||
if ( i < (end-1) )
|
||||
{
|
||||
if ( (*this)[x]->intersects( (*this)[i+1] ) )
|
||||
{
|
||||
*((*this)[x]) |= *((*this)[i+1]);
|
||||
m_remove.append( (*this)[i+1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
x=i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_remove.isEmpty())
|
||||
{
|
||||
this->remove( m_remove.last() );
|
||||
m_remove.pop_back();
|
||||
}
|
||||
kdDebug() << "from " << end << " to " << this->count() << endl;
|
||||
}
|
||||
|
||||
template <class NormalizedShape, class Shape>
|
||||
bool RegularArea<NormalizedShape, Shape>::isNull() const
|
||||
{
|
||||
|
@ -204,9 +239,21 @@ bool RegularArea<NormalizedShape, Shape>::contains (double x, double y) const
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class NormalizedShape, class Shape>
|
||||
bool RegularArea<NormalizedShape, Shape>::contains (NormalizedShape * shape) const
|
||||
{
|
||||
if (!this)
|
||||
return false;
|
||||
if (this->isEmpty())
|
||||
return false;
|
||||
|
||||
const QValueList<NormalizedShape*> * const lista=dynamic_cast<const QValueList<NormalizedShape*> * const >(this);
|
||||
return lista->contains(shape);
|
||||
}
|
||||
|
||||
template <class NormalizedShape, class Shape>
|
||||
QValueList<Shape> *
|
||||
RegularArea<NormalizedShape, Shape>::geometry( int xScale, int yScale ) const
|
||||
RegularArea<NormalizedShape, Shape>::geometry( int xScale, int yScale, int dx, int dy ) const
|
||||
{
|
||||
if (!this)
|
||||
return false;
|
||||
|
@ -214,11 +261,13 @@ RegularArea<NormalizedShape, Shape>::geometry( int xScale, int yScale ) const
|
|||
return 0;
|
||||
|
||||
ConstIterator i;
|
||||
QValueList<Shape>* ret=0;
|
||||
|
||||
QValueList<Shape>* ret=new QValueList<Shape>;
|
||||
Shape t;
|
||||
for (i=this->begin();i!=this->end();++i)
|
||||
{
|
||||
ret.append((*i)->geometry(xScale,yScale));
|
||||
t=(*i)->geometry(xScale,yScale);
|
||||
t.moveBy(dx,dy);
|
||||
ret->append(t);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -526,6 +526,16 @@ bool KPDFDocument::supportsRotation() const
|
|||
return generator ? generator->supportsRotation() : false;
|
||||
}
|
||||
|
||||
bool KPDFDocument::supportsPaperSizes() const
|
||||
{
|
||||
return generator ? generator->supportsPaperSizes() : false;
|
||||
}
|
||||
|
||||
QStringList KPDFDocument::paperSizes() const
|
||||
{
|
||||
return generator ? generator->paperSizes() : QStringList();
|
||||
}
|
||||
|
||||
bool KPDFDocument::historyAtBegin() const
|
||||
{
|
||||
return d->viewportIterator == d->viewportHistory.begin();
|
||||
|
@ -575,6 +585,7 @@ void KPDFDocument::requestPixmaps( const QValueList< PixmapRequest * > & request
|
|||
{
|
||||
// set the 'page field' (see PixmapRequest) and check if it is valid
|
||||
PixmapRequest * request = *rIt;
|
||||
kdWarning() << "request id=" << request->id << " " <<request->width << "x" << request->height << "@" << request->pageNumber << endl;
|
||||
if ( !(request->page = pages_vector[ request->pageNumber ]) )
|
||||
{
|
||||
// skip requests referencing an invalid page (must not happen)
|
||||
|
@ -1294,6 +1305,7 @@ void KPDFDocument::sendGeneratorRequest()
|
|||
// submit the request to the generator
|
||||
if ( generator->canGeneratePixmap( request->async ) )
|
||||
{
|
||||
kdWarning() << "sending request id=" << request->id << " " <<request->width << "x" << request->height << "@" << request->pageNumber << " async == " << request->async << endl;
|
||||
d->pixmapRequestsStack.remove ( request );
|
||||
generator->generatePixmap ( request );
|
||||
}
|
||||
|
@ -1593,14 +1605,27 @@ void KPDFDocument::slotTimedMemoryCheck()
|
|||
|
||||
void KPDFDocument::slotOrientation( int orientation )
|
||||
{
|
||||
if (generator->supportsRotation())
|
||||
if ( generator->supportsRotation() )
|
||||
{
|
||||
generator->setOrientation(pages_vector,orientation);
|
||||
foreachObserver( notifySetup( pages_vector, true ) );
|
||||
foreachObserver( notifyContentsCleared (DocumentObserver::Pixmap | DocumentObserver::Highlights | DocumentObserver::Annotations));
|
||||
// foreachObserver( notifyViewportChanged( false /*disables smoothMove*/ ));
|
||||
// foreachObserver( notifyPageChanged( ) );
|
||||
kdDebug() << "Oreint: " << orientation << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void KPDFDocument::slotPaperSizes( int newsize )
|
||||
{
|
||||
if (generator->supportsPaperSizes())
|
||||
{
|
||||
generator->setPaperSize(pages_vector,newsize);
|
||||
foreachObserver( notifySetup( pages_vector, true ) );
|
||||
kdDebug() << "PaperSize no: " << newsize << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/** DocumentViewport **/
|
||||
|
||||
DocumentViewport::DocumentViewport( int n )
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <qobject.h>
|
||||
#include <qvaluevector.h>
|
||||
#include <qstring.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qdom.h>
|
||||
#include <qdict.h>
|
||||
#include <kmimetype.h>
|
||||
|
@ -86,6 +87,8 @@ class KPDFDocument : public QObject
|
|||
bool isAllowed( int /*Document::Permisison(s)*/ ) const;
|
||||
bool supportsSearching() const;
|
||||
bool supportsRotation() const;
|
||||
bool supportsPaperSizes() const;
|
||||
QStringList paperSizes() const;
|
||||
// might be useful later
|
||||
// bool hasFonts() const;
|
||||
bool historyAtBegin() const;
|
||||
|
@ -122,6 +125,7 @@ class KPDFDocument : public QObject
|
|||
|
||||
public slots:
|
||||
void slotOrientation( int orientation );
|
||||
void slotPaperSizes( int );
|
||||
|
||||
signals:
|
||||
void close();
|
||||
|
|
|
@ -85,6 +85,9 @@ class Generator : public QObject
|
|||
// rotation
|
||||
virtual bool supportsRotation() { return false; };
|
||||
virtual void setOrientation(QValueVector<KPDFPage*> & /*pagesVector*/, int /*orientation*/) { ; };
|
||||
virtual bool supportsPaperSizes () { return false; }
|
||||
virtual QStringList paperSizes () { return QStringList(); }
|
||||
virtual void setPaperSize (QValueVector<KPDFPage*> & /*pagesVector*/, int /*newsize*/) { ; }
|
||||
|
||||
// internal search and gettext
|
||||
virtual RegularAreaRect * findText( const QString & /*text*/, SearchDir /*dir*/, const bool /*strictCase*/,
|
||||
|
|
56
core/misc.h
Normal file
56
core/misc.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef _KPDF_MISC_H_
|
||||
#define _KPDF_MISC_H_
|
||||
#include "area.h"
|
||||
|
||||
/**
|
||||
@short Wrapper around the information needed to generate the selection area
|
||||
There are two assumptions inside this class:
|
||||
1. the start never changes, one instance of this class is used for one selection,
|
||||
therefore the start of the selection will not change, only end and direction of
|
||||
the selection will change.
|
||||
|
||||
By direction we mean the direction in which the end moves in relation to the start,
|
||||
forward selection is when end is after the start, backward when its before.
|
||||
2. The following changes might appear during selection:
|
||||
a. the end moves without changing the direction (it can move up and down but not past the start):
|
||||
only itE will be updated
|
||||
b. the end moves with changing the direction then itB becomes itE if the previous direction was forward
|
||||
or itE becomes itB
|
||||
3. Internally it that is related to the start cursor is always at it[0] while it related to end is it[1],
|
||||
transition between meanings (itB/itE) is done with dir modifier;
|
||||
*/
|
||||
class TextSelection
|
||||
{
|
||||
public:
|
||||
TextSelection (NormalizedPoint &a, NormalizedPoint &b)
|
||||
{
|
||||
if (b.y-a.y<0 || (b.y-a.y==0 && b.x-a.x <0))
|
||||
direction=1;
|
||||
else
|
||||
direction=0;
|
||||
cur[0]=a,cur[1]=b;
|
||||
it[direction%2]=-1,it[(direction+1)%2]=-1;
|
||||
};
|
||||
void end (NormalizedPoint & p)
|
||||
{
|
||||
// changing direction as in 2b , assuming the bool->int conversion is correct
|
||||
int dir1=direction;
|
||||
direction = (p.y-cur[0].y<0 || (p.y-cur[0].y==0 && p.x-cur[0].x <0));
|
||||
if (direction!=dir1)
|
||||
kdDebug() << "changing direction in selection\n";
|
||||
cur[1]=p;
|
||||
}
|
||||
void itE (int p) { it[(direction+1)%2]=p; }
|
||||
void itB (int p) { it[(direction)%2]=p; }
|
||||
int dir () { return direction; }
|
||||
const NormalizedPoint * start() {return &cur[direction%2];};
|
||||
const NormalizedPoint * end() {return &cur[(direction+1)%2];};
|
||||
int itB() {return it[direction%2];}
|
||||
int itE() {return it[(direction+1)%2];}
|
||||
private:
|
||||
int direction;
|
||||
int it[2];
|
||||
NormalizedPoint cur[2];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
// temp includes
|
||||
#include <sys/time.h>
|
||||
|
||||
class TextSelection;
|
||||
|
||||
/** class KPDFPage **/
|
||||
|
||||
|
@ -75,6 +75,13 @@ bool KPDFPage::hasBookmark() const
|
|||
return m_bookmarked;
|
||||
}
|
||||
|
||||
RegularAreaRect * KPDFPage::getTextArea ( TextSelection * sel ) const
|
||||
{
|
||||
if (m_text)
|
||||
return m_text->getTextArea (sel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool KPDFPage::hasObjectRect( double x, double y ) const
|
||||
{
|
||||
if ( m_rects.count() < 1 )
|
||||
|
|
|
@ -21,7 +21,7 @@ class QDomDocument;
|
|||
class KPDFPageTransition;
|
||||
class Annotation;
|
||||
class KPDFTextPage;
|
||||
|
||||
class TextSelection;
|
||||
// didnt work with forward declarations
|
||||
#include "area.h"
|
||||
#include "textpage.h"
|
||||
|
@ -34,6 +34,7 @@ class HighlightAreaRect;
|
|||
class ObjectRect;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @short Collector for all the data belonging to a page.
|
||||
*
|
||||
|
@ -68,6 +69,7 @@ class KPDFPage
|
|||
|
||||
RegularAreaRect * findText( const QString & text, SearchDir dir, bool strictCase, const RegularAreaRect * lastRect=0) const;
|
||||
QString * getText( const RegularAreaRect * rect ) const;
|
||||
RegularAreaRect * getTextArea ( TextSelection * ) const;
|
||||
// const ObjectRect * getObjectRect( double x, double y ) const;
|
||||
const ObjectRect * getObjectRect( ObjectRect::ObjectType type, double x, double y ) const;
|
||||
//const Annotation * getAnnotation( double x, double y ) const;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
***************************************************************************/
|
||||
#include "textpage.h"
|
||||
#include "area.h"
|
||||
#include "misc.h"
|
||||
#include <kdebug.h>
|
||||
|
||||
KPDFTextPage::~KPDFTextPage()
|
||||
|
@ -19,6 +20,122 @@ KPDFTextPage::~KPDFTextPage()
|
|||
}
|
||||
}
|
||||
|
||||
RegularAreaRect * KPDFTextPage::getTextArea ( TextSelection * sel) const
|
||||
{
|
||||
/**
|
||||
It works like this:
|
||||
There are two cursors, we need to select all the text between them. The coordinates are normalised, leftTop is (0,0)
|
||||
rightBottom is (1,1), so for cursors start (sx,sy) and end (ex,ey) we start with finding text rectangles under those
|
||||
points, if not we search for the first that is to the right to it in the same baseline, if none found, then we search
|
||||
for the first rectangle with a baseline under the cursor, having two points that are the best rectangles to both
|
||||
of the cursors: (rx,ry)x(tx,ty) for start and (ux,uy)x(vx,vy) for end, we do a
|
||||
1. (rx,ry)x(1,ty)
|
||||
2. (0,ty)x(1,uy)
|
||||
3. (0,uy)x(vx,vy)
|
||||
|
||||
To find the closest rectangle to cursor (cx,cy) we search for a rectangle that either contains the cursor
|
||||
or that has a left border >= cx and bottom border >= cy.
|
||||
*/
|
||||
RegularAreaRect * ret= new RegularAreaRect;
|
||||
int it=-1,itB=-1,itE=-1;
|
||||
// if (sel->itB==-1)
|
||||
|
||||
// ending cursor is higher then start cursor, we need to find positions in reverse
|
||||
NormalizedRect *tmp=0,*start=0,*end=0;
|
||||
const NormalizedPoint * startC=sel->start();
|
||||
const NormalizedPoint * endC=sel->end();
|
||||
if (sel->dir() == 1 || (sel->itB()==-1 && sel->dir()==0))
|
||||
{
|
||||
kdWarning() << "running first loop\n";
|
||||
for (it=0;it<m_words.count();it++)
|
||||
{
|
||||
tmp=m_words[it]->area;
|
||||
if (tmp->contains(startC->x,startC->y)
|
||||
|| ( tmp->top <= startC->y && tmp->bottom >= startC->y && tmp->left >= startC->x )
|
||||
|| ( tmp->top >= startC->y))
|
||||
{
|
||||
/// we have found the (rx,ry)x(tx,ty)
|
||||
itB=it;
|
||||
kdWarning() << "start is " << itB << " count is " << m_words.count() << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
sel->itB(itB);
|
||||
}
|
||||
itB=sel->itB();
|
||||
kdWarning() << "direction is " << sel->dir() << endl;
|
||||
kdWarning() << "reloaded start is " << itB << " against " << sel->itB() << endl;
|
||||
if (sel->dir() == 0 || (sel->itE() == -1 && sel->dir()==1))
|
||||
{
|
||||
kdWarning() << "running second loop\n";
|
||||
for (it=m_words.count()-1; it>=itB;it--)
|
||||
{
|
||||
tmp=m_words[it]->area;
|
||||
if (tmp->contains(endC->x,endC->y)
|
||||
|| ( tmp->top <= endC->y && tmp->bottom >= endC->y && tmp->right <= endC->x )
|
||||
|| ( tmp->bottom <= endC->y))
|
||||
{
|
||||
/// we have found the (ux,uy)x(vx,vy)
|
||||
itE=it;
|
||||
kdWarning() << "ending is " << itE << " count is " << m_words.count() << endl;
|
||||
kdWarning () << "conditions " << tmp->contains(endC->x,endC->y) << " "
|
||||
<< ( tmp->top <= endC->y && tmp->bottom >= endC->y && tmp->right <= endC->x ) << " " <<
|
||||
( tmp->top >= endC->y) << endl;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
sel->itE(itE);
|
||||
}
|
||||
kdWarning() << "reloaded ending is " << itE << " against " << sel->itE() << endl;
|
||||
|
||||
if (sel->itB()!=-1 && sel->itE()!=-1)
|
||||
{
|
||||
start=m_words[sel->itB()]->area;
|
||||
end=m_words[sel->itE()]->area;
|
||||
|
||||
NormalizedRect first,second,third;/*
|
||||
first.right=1;
|
||||
/// if (rx,ry)x(1,ty) intersects the end cursor, there is only one line
|
||||
bool sameBaseline=end->intersects(first);
|
||||
kdWarning() << "sameBaseline : " << sameBaseline << endl;
|
||||
if (sameBaseline)
|
||||
{
|
||||
first=*start;
|
||||
first.right=end->right;
|
||||
first.bottom=end->bottom;
|
||||
for (it=QMIN(sel->itB(),sel->itE()); it<=QMAX(sel->itB(),sel->itE());it++)
|
||||
{
|
||||
tmp=m_words[it]->area;
|
||||
if (tmp->intersects(&first))
|
||||
ret->append(tmp);
|
||||
}
|
||||
}
|
||||
else*/
|
||||
/// finding out if there are more then one baseline between them is a hard and discussable task
|
||||
/// we will create a rectangle (rx,0)x(tx,1) and will check how many times does it intersect the
|
||||
/// areas, if more than one -> we have a three or over line selection
|
||||
// {
|
||||
first=*start;
|
||||
second.top=start->bottom;
|
||||
first.right=second.right=1;
|
||||
third=*end;
|
||||
third.left=second.left=0;
|
||||
second.bottom=end->top;
|
||||
for (it=QMIN(sel->itB(),sel->itE()); it<=QMAX(sel->itB(),sel->itE());it++)
|
||||
{
|
||||
tmp=m_words[it]->area;
|
||||
if (tmp->intersects(&first) || tmp->intersects(&second) || tmp->intersects(&third))
|
||||
ret->append(tmp);
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
ret->simplify();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
RegularAreaRect* KPDFTextPage::findText(const QString &query, SearchDir & direct,
|
||||
|
@ -173,36 +290,13 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
|
|||
queryLeft-=min;
|
||||
}
|
||||
}
|
||||
if (haveMatch && queryLeft==0 && j==query.length())
|
||||
|
||||
if (haveMatch && queryLeft==0 && j==query.length())
|
||||
{
|
||||
// RegularAreaRect::ConstIterator i=ret->begin(), end=ret->end;
|
||||
int end=ret->count(),i=0,x=0;
|
||||
QValueList <NormalizedRect*> m_remove;
|
||||
for (;i<end;i++)
|
||||
{
|
||||
if ( i < (end-1) )
|
||||
{
|
||||
if ( (*ret)[x]->intersects( (*ret)[i+1] ) )
|
||||
{
|
||||
(*ret)[x]->left=(QMIN((*ret)[x]->left,(*ret)[i+1]->left));
|
||||
(*ret)[x]->top=(QMIN((*ret)[x]->top,(*ret)[i+1]->top));
|
||||
(*ret)[x]->bottom=(QMAX((*ret)[x]->bottom,(*ret)[i+1]->bottom));
|
||||
(*ret)[x]->right=(QMAX((*ret)[x]->right,(*ret)[i+1]->right));
|
||||
m_remove.append( (*ret)[i+1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
x=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_remove.isEmpty())
|
||||
{
|
||||
ret->remove( m_remove.last() );
|
||||
m_remove.pop_back();
|
||||
}
|
||||
ret->simplify();
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -220,6 +314,7 @@ QString * KPDFTextPage::getText(const RegularAreaRect *area)
|
|||
// provide the string FIXME?: newline handling
|
||||
if (area->intersects((*it)->area))
|
||||
{
|
||||
// kdDebug()<< "[" << (*it)->area->left << "," << (*it)->area->top << "]x["<< (*it)->area->right << "," << (*it)->area->bottom << "]\n";
|
||||
*ret += ((*it)->txt);
|
||||
last=*it;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <qvaluelist.h>
|
||||
#include <qstringlist.h>
|
||||
#include "area.h"
|
||||
class TextSelection;
|
||||
|
||||
/*! @enum SearchDir
|
||||
* The enum holding the direction of searching.
|
||||
|
@ -52,8 +53,7 @@ struct KPDFTextEntity
|
|||
//
|
||||
QString txt;
|
||||
NormalizedRect* area;
|
||||
int rotation;
|
||||
KPDFTextEntity(QString text, NormalizedRect* ar, int rot) : txt(text), rotation(rot)
|
||||
KPDFTextEntity(QString text, NormalizedRect* ar) : txt(text)
|
||||
{ area=ar; };
|
||||
~KPDFTextEntity() { delete area; };
|
||||
};
|
||||
|
@ -63,10 +63,11 @@ class KPDFTextPage {
|
|||
RegularAreaRect* findText(const QString &query, SearchDir & direct,
|
||||
const bool &strictCase, const RegularAreaRect *area);
|
||||
QString * getText(const RegularAreaRect *rect);
|
||||
RegularAreaRect * getTextArea ( TextSelection* ) const;
|
||||
KPDFTextPage(QValueList<KPDFTextEntity*> words) : m_words(words) {};
|
||||
KPDFTextPage() : m_words() {};
|
||||
void append(QString txt, NormalizedRect* area, int rot)
|
||||
{ m_words.append(new KPDFTextEntity(txt,area,rot) ); };
|
||||
void append(QString txt, NormalizedRect* area)
|
||||
{ m_words.append(new KPDFTextEntity(txt,area) ); };
|
||||
~KPDFTextPage();
|
||||
private:
|
||||
RegularAreaRect * findTextInternal(const QString &query, bool forward,
|
||||
|
@ -74,4 +75,6 @@ class KPDFTextPage {
|
|||
QValueList<KPDFTextEntity*> m_words;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <klocale.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qpainter.h>
|
||||
#include <qpaintdevice.h>
|
||||
|
||||
#include "faxrenderer.h"
|
||||
#include "core/page.h"
|
||||
|
@ -33,7 +34,7 @@ KPDF_EXPORT_PLUGIN(FaxRenderer)
|
|||
FaxRenderer::FaxRenderer(KPDFDocument * doc)
|
||||
: Generator( doc )
|
||||
{
|
||||
;
|
||||
kdWarning() << "fax generator has landed" <<endl;
|
||||
}
|
||||
|
||||
void FaxRenderer::generatePixmap( PixmapRequest * request )
|
||||
|
@ -49,9 +50,10 @@ void FaxRenderer::generatePixmap( PixmapRequest * request )
|
|||
|
||||
// Wait for all access to this documentRenderer to finish
|
||||
|
||||
QPixmap* pix = new QPixmap();
|
||||
QPixmap* pix = new QPixmap(request->width,request->height);
|
||||
pix->fill();
|
||||
QPainter p(pix);
|
||||
QImage img = fax.page(request->pageNumber-1);
|
||||
QImage img = fax.page(request->pageNumber).smoothScale(request->width,request->height);
|
||||
p.drawImage( 0,0, img, 0,0,img.width(),img.height());
|
||||
/*
|
||||
SimplePageSize psize = pageSizes[page->getPageNumber() - 1];
|
||||
|
@ -94,12 +96,12 @@ bool FaxRenderer::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
#endif
|
||||
|
||||
// Wait for all access to this documentRenderer to finish
|
||||
mutex.lock();
|
||||
// mutex.lock();
|
||||
|
||||
// Now we assume that the file is fine and load the file into the
|
||||
// fax member. We abort on error and give an error message.
|
||||
bool ok = fax.loadImage(fileName);
|
||||
|
||||
kdWarning(1000) << "fax " << fileName << " loaded ok: " << ok <<endl;
|
||||
// It can happen that fax.loadImage() returns with 'ok == true', but
|
||||
// still the file could NOT be loaded. This happens, e.g. for TIFF
|
||||
// file that do NOT contain FAX, but other image formats. We handle
|
||||
|
@ -119,7 +121,7 @@ bool FaxRenderer::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
temp=i18n("Error while opening file: %1.").arg(fax.errorString());
|
||||
emit error (temp,-1);
|
||||
}
|
||||
mutex.unlock();
|
||||
// mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -131,8 +133,7 @@ bool FaxRenderer::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
{
|
||||
QSize pageSize = fax.page_size(pg);
|
||||
// how about rotation?
|
||||
pagesVector[pg] = new KPDFPage(pg, pageSize.width(), pageSize.height(),0);
|
||||
/*
|
||||
|
||||
QPoint dpi = fax.page_dpi(pg);
|
||||
double dpix = dpi.x();
|
||||
double dpiy = dpi.y();
|
||||
|
@ -141,14 +142,12 @@ bool FaxRenderer::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
kdError() << "File invalid resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << ". This information will be ignored and 75 DPI assumed." << endl;
|
||||
dpix = dpiy = 75.0;
|
||||
}
|
||||
|
||||
w.setLength_in_inch(pageSize.width() / dpix);
|
||||
h.setLength_in_inch(pageSize.height() / dpiy);
|
||||
pageSizes[pg].setPageSize(w, h);*/
|
||||
pagesVector[pg] = new KPDFPage(pg, QPaintDevice::x11AppDpiX () * pageSize.width() / dpix,
|
||||
QPaintDevice::x11AppDpiX () * pageSize.height()/dpiy,0);
|
||||
}
|
||||
|
||||
// the return value 'true' indicates that this operation was not successful.
|
||||
mutex.unlock();
|
||||
// mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@ Comment=Fax backend for oKular
|
|||
ServiceTypes=oKular/Generator
|
||||
MimeType=image/fax-g3;image/tiff;
|
||||
X-KDE-Library=libokularGenerator_fax.la
|
||||
X-KDE-Priority=1
|
||||
X-KDE-Priority=4
|
||||
X-KDE-oKularAPIVersion=1
|
||||
X-KDE-oKularHasInternalSettings=false
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <qfile.h>
|
||||
#include <qpainter.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qsize.h>
|
||||
#include <qtoolbox.h>
|
||||
|
||||
|
@ -182,8 +183,8 @@ bool GSGenerator::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
if( !pixGenerator )
|
||||
{
|
||||
pixGenerator = new GSInterpreterLib ();
|
||||
connect (pixGenerator, SIGNAL (Finished(const QImage* img)),
|
||||
this, SLOT(slotPixmapGenerated (const QImage* img)));
|
||||
connect (pixGenerator, SIGNAL (Finished(const QImage*)),
|
||||
this, SLOT(slotPixmapGenerated (const QImage*)));
|
||||
|
||||
if ( GSSettings::messages() )
|
||||
{
|
||||
|
@ -216,17 +217,22 @@ bool GSGenerator::loadDocument( const QString & fileName, QValueVector< KPDFPage
|
|||
|
||||
void GSGenerator::slotPixmapGenerated(const QImage* img)
|
||||
{
|
||||
QPixmap *pix=new QPixmap(m_sRequest->width, m_asRequest->height);
|
||||
QPainter p(pix);
|
||||
syncLock.unlock();
|
||||
kdWarning() << "SlotSyncGenerated! - finished m_sRequest id=" << m_sRequest->id << " " <<m_sRequest->width << "x" << m_sRequest->height << "@" << m_sRequest->pageNumber << " async == " << m_sRequest->async << endl;
|
||||
QPixmap * rPix;
|
||||
rPix = new QPixmap(img->size());
|
||||
rPix->fill();
|
||||
QPainter p(rPix);
|
||||
p.drawImage(0,0,*img,0,0,img->width(),img->height());
|
||||
docLock.unlock();
|
||||
m_sRequest->page->setPixmap( m_sRequest->id, pix );
|
||||
p.end();
|
||||
m_sRequest->page->setPixmap( m_sRequest->id, rPix );
|
||||
signalRequestDone( m_sRequest );
|
||||
}
|
||||
|
||||
void GSGenerator::slotAsyncPixmapGenerated(QPixmap * pix)
|
||||
{
|
||||
docLock.unlock();
|
||||
kdWarning() << "SlotASyncGenerated!\n";
|
||||
m_asRequest->page->setPixmap( m_asRequest->id, pix );
|
||||
signalRequestDone( m_asRequest );
|
||||
}
|
||||
|
@ -324,6 +330,7 @@ bool GSGenerator::initInterpreter()
|
|||
{
|
||||
if( pixGenerator->start() && internalDoc->dsc()->isStructured() )
|
||||
{
|
||||
|
||||
// this 0 is ok here, we will not be getting a PAGE anwser from those
|
||||
pixGenerator->run ( internalDoc->file() , internalDoc->prolog(), false);
|
||||
pixGenerator->unlock();
|
||||
|
@ -344,51 +351,69 @@ bool GSGenerator::loadDocumentWithDSC( QString & name, QValueVector< KPDFPage *
|
|||
|
||||
void GSGenerator::generatePixmap( PixmapRequest * req )
|
||||
{
|
||||
|
||||
kdDebug() << req << endl;
|
||||
kdWarning() << "receiving req id=" << req->id << " " <<req->width << "x" << req->height << "@" << req->pageNumber << " async == " << req->async << endl;
|
||||
int pgNo=req->pageNumber;
|
||||
if ( req->async )
|
||||
if ( false )
|
||||
{
|
||||
docLock.lock();
|
||||
return ;
|
||||
m_asRequest=req;
|
||||
kdWarning() << "setOrientation\n";
|
||||
asyncGenerator->setOrientation(rotation (internalDoc->orientation(pgNo)));
|
||||
// asyncGenerator->setBoundingBox( internalDoc->boundingBox(i));
|
||||
kdWarning() << "setSize\n";
|
||||
asyncGenerator->setSize(req->width ,req->height);
|
||||
kdWarning() << "setMedia\n";
|
||||
asyncGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( pgNo )) );
|
||||
kdWarning() << "setMagnify\n";
|
||||
asyncGenerator->setMagnify(QMAX(static_cast<double>(req->width)/req->page->width() ,
|
||||
static_cast<double>(req->height)/req->page->height()));
|
||||
GSInterpreterLib::Position u=internalDoc->pagePos(pgNo);
|
||||
kdDebug() << "Page pos is " << pgNo << ":"<< u.first << "/" << u.second << endl;
|
||||
// kdWarning () << "Page pos is " << pgNo << ":"<< u.first << "/" << u.second << endl;
|
||||
if (!asyncGenerator->running())
|
||||
{
|
||||
if ( internalDoc->dsc()->isStructured() )
|
||||
{
|
||||
kdWarning() << "setStructure\n";
|
||||
asyncGenerator->setStructure( internalDoc->prolog() , internalDoc->setup() );
|
||||
kdDebug () << "sending init" << endl;
|
||||
}
|
||||
asyncGenerator->start();
|
||||
if (!asyncGenerator->running())
|
||||
{
|
||||
kdWarning() << "start after structure\n";
|
||||
asyncGenerator->startInterpreter();
|
||||
}
|
||||
}
|
||||
kdWarning() << "run pagepos\n";
|
||||
asyncGenerator->run (internalDoc->pagePos(pgNo));
|
||||
return;
|
||||
}
|
||||
m_sRequest=req;
|
||||
pixGenerator->setOrientation(rotation (internalDoc->orientation(pgNo)));
|
||||
// pixGenerator->setBoundingBox( internalDoc->boundingBox(i));
|
||||
pixGenerator->setSize(req->width ,req->height);
|
||||
pixGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( pgNo )) );
|
||||
pixGenerator->setMagnify(QMAX(static_cast<double>(req->width)/req->page->width() ,
|
||||
static_cast<double>(req->height)/req->page->height()));
|
||||
|
||||
if (!pixGenerator->running())
|
||||
else
|
||||
{
|
||||
syncLock.lock();
|
||||
disconnect (pixGenerator, SIGNAL (Finished(const QImage*)),
|
||||
this, SLOT(slotPixmapGenerated (const QImage*)));
|
||||
m_sRequest=req;
|
||||
pixGenerator->setOrientation(rotation (internalDoc->orientation(pgNo)));
|
||||
// pixGenerator->setBoundingBox( internalDoc->boundingBox(i));
|
||||
pixGenerator->setSize(req->width ,req->height);
|
||||
pixGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( pgNo )) );
|
||||
pixGenerator->setMagnify(QMAX(static_cast<double>(req->width)/req->page->width() ,
|
||||
static_cast<double>(req->height)/req->page->height()));
|
||||
if (!pixGenerator->running())
|
||||
{
|
||||
initInterpreter();
|
||||
pixGenerator->run ( internalDoc->file() , internalDoc->pagePos(pgNo));
|
||||
}
|
||||
connect (pixGenerator, SIGNAL (Finished(const QImage*)),
|
||||
this, SLOT(slotPixmapGenerated (const QImage*)));
|
||||
pixGenerator->run ( internalDoc->file() , internalDoc->pagePos(pgNo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GSGenerator::canGeneratePixmap( bool async )
|
||||
{
|
||||
if (async) return ! docLock.locked();
|
||||
return ( pixGenerator ) ? pixGenerator->ready() : true;
|
||||
// kdWarning () << "ready Async/Sync " << (! docLock.locked()) << "/ " << (( pixGenerator ) ? !syncLock.locked() : true) << " asking for async: " << async << endl;
|
||||
// if (async) return false;
|
||||
return ( pixGenerator ) ? ! syncLock.locked() : true;
|
||||
}
|
||||
|
||||
const DocumentInfo * GSGenerator::generateDocumentInfo()
|
||||
|
|
|
@ -94,6 +94,7 @@ class GSGenerator : public Generator
|
|||
int angle( CDSC_ORIENTATION_ENUM orientation );
|
||||
CDSC_ORIENTATION_ENUM orientation( int rot );
|
||||
QMutex docLock;
|
||||
QMutex syncLock;
|
||||
bool m_asyncBusy;
|
||||
|
||||
// pixmap requests
|
||||
|
|
|
@ -184,7 +184,7 @@ bool GSInterpreterCMD::stop(bool async)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSInterpreterCMD::start()
|
||||
bool GSInterpreterCMD::startInterpreter()
|
||||
{
|
||||
kdDebug(4655) << "start()" << endl;
|
||||
if ( m_process && m_process->isRunning() )
|
||||
|
@ -335,6 +335,7 @@ bool GSInterpreterCMD::run( GSInterpreterLib::Position pos)
|
|||
}
|
||||
// the pixmap to which the generated image will be copied
|
||||
m_pixmap = new QPixmap (m_width, m_height);
|
||||
m_pixmap -> fill();
|
||||
|
||||
m_info.pos=pos;
|
||||
m_info.sync=true;
|
||||
|
@ -389,12 +390,17 @@ void GSInterpreterCMD::run()
|
|||
}
|
||||
}
|
||||
|
||||
#include <qdialog.h>
|
||||
#include <qpainter.h>
|
||||
|
||||
void GSInterpreterCMD::customEvent( QCustomEvent * e )
|
||||
{
|
||||
if (e->type() == GS_DATAREADY_ID )
|
||||
{
|
||||
kdDebug(4655) << "emitting signal" << endl;
|
||||
emit Finished(m_pixmap);
|
||||
QPixmap *pix=takePixmap();
|
||||
|
||||
emit Finished(pix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class GSInterpreterCMD : public QObject , public QThread
|
|||
GSInterpreterCMD( const QString & fileName);
|
||||
~GSInterpreterCMD();
|
||||
QPixmap* takePixmap();
|
||||
bool start();
|
||||
bool startInterpreter();
|
||||
bool stop(bool async=true);
|
||||
bool ready() { return !interpreterLock.locked() ; } ;
|
||||
bool running ();
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
|
||||
// #include <qdialog.h>
|
||||
|
||||
GSInterpreterLib *interpreter;
|
||||
int mem;
|
||||
|
@ -35,12 +35,17 @@ FILE * f;
|
|||
|
||||
void PixHandler::slotPixmap(const QImage* img)
|
||||
{
|
||||
QPixmap *pix=new QPixmap(img->size(), img->depth());
|
||||
kdDebug() << "Handles: " << pix->handle() << " " << pData.handle <<endl;
|
||||
QPainter p;
|
||||
p.begin(pix);
|
||||
p.drawImage(0,0,*img, 0,0,img->width(),img->height());
|
||||
p.end();
|
||||
QPixmap *pix=new QPixmap();
|
||||
kdWarning() << "img size/depth " << img->size() << "/" <<img->depth() << endl;
|
||||
bool done=pix->convertFromImage(*img);
|
||||
kdWarning () << "Conversion from qimage " << done << endl;
|
||||
// QDialog t;
|
||||
// t.resize(pix->width(),pix->height());
|
||||
// t.setBackgroundPixmap(*pix);
|
||||
// t.update();
|
||||
// t.exec();
|
||||
|
||||
|
||||
XCopyArea
|
||||
(qt_xdisplay(),
|
||||
pix->handle(),
|
||||
|
@ -62,7 +67,7 @@ void process()
|
|||
{
|
||||
|
||||
read ( mem, &pData, sizeof(pData) );
|
||||
if ( !interpreter->running() )
|
||||
if ( ! ( interpreter->running() ) )
|
||||
interpreter->start(false);
|
||||
|
||||
// kdDebug() << "Processing: " << pData.sync << endl;
|
||||
|
@ -76,6 +81,7 @@ void process()
|
|||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
KApplication app(argc,argv,QCString("kpdflibgsasyncgenerator"));
|
||||
// Order of argv: fileName, msgQueueId, media type, magnify, orientation
|
||||
|
||||
for (int i=0;i<argc;i++)
|
||||
|
@ -89,10 +95,12 @@ int main (int argc, char* argv[])
|
|||
interpreter->setSize ( QString(argv[7]).toInt(), QString(argv[8]).toInt() );
|
||||
interpreter->setPlatformFonts ( QString(argv[9]).toInt() !=0 );
|
||||
interpreter->setAABits(QString(argv[10]).toInt(), QString(argv[11]).toInt() );
|
||||
KApplication app(argc,argv,QCString("kpdflibgsasyncgenerator"));
|
||||
interpreter->setProgressive(false);
|
||||
interpreter->start(false);
|
||||
|
||||
PixHandler pxHandler;
|
||||
|
||||
QObject::connect(interpreter,SIGNAL(Finished(const QImage* img)),&pxHandler,SLOT(slotPixmap(const QImage* img)));
|
||||
QObject::connect(interpreter,SIGNAL(Finished(const QImage* )),&pxHandler,SLOT(slotPixmap(const QImage* )));
|
||||
|
||||
int request;
|
||||
anwser = open( argv[3] , O_RDWR );
|
||||
|
|
|
@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../.. -I$(srcdir)/xpdf -I$(srcdir)/xpdf/goo -I$(srcdir)/x
|
|||
|
||||
libokularGenerator_xpdf_la_LIBADD = $(top_builddir)/kpdf/core/liboKularcore.la $(top_builddir)/kpdf/conf/liboKularconf.la \
|
||||
$(top_builddir)/kpdf/generators/xpdf/xpdf/xpdf/libxpdf.la \
|
||||
$(LIB_KDEPRINT) $(LIB_KDEUI)
|
||||
$(LIB_KDEPRINT) $(LIB_KDEUI) -lm
|
||||
libokularGenerator_xpdf_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
|
||||
libokularGenerator_xpdf_la_SOURCES = generator_pdf.cpp gp_outputdev.cpp
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <qapplication.h>
|
||||
#include <qpaintdevicemetrics.h>
|
||||
#include <qregexp.h>
|
||||
#include <qpoint.h>
|
||||
#include <kapplication.h>
|
||||
#include <klocale.h>
|
||||
#include <kpassdlg.h>
|
||||
|
@ -204,16 +205,19 @@ void PDFGenerator::loadPages(QValueVector<KPDFPage*> &pagesVector, int rotation,
|
|||
{
|
||||
// TODO XPDF 3.01 check
|
||||
// KPDFTextDev td;
|
||||
int count=pagesVector.count();
|
||||
int count=pagesVector.count(),w=0,h=0;
|
||||
for ( int i = 0; i < count ; i++ )
|
||||
{
|
||||
// get xpdf page
|
||||
Page * p = pdfdoc->getCatalog()->getPage( i + 1 );
|
||||
|
||||
w=pdfdoc->getPageCropWidth(i+1);
|
||||
h=pdfdoc->getPageCropHeight(i+1);
|
||||
if (rotation==-1)
|
||||
rotation=pdfdoc->getPageRotate(i+1)/90;
|
||||
if (rotation%2==1)
|
||||
qSwap(w,h);
|
||||
// init a kpdfpage, add transition and annotations informations
|
||||
KPDFPage * page = new KPDFPage( i, pdfdoc->getPageCropWidth(i+1),
|
||||
pdfdoc->getPageCropHeight(i+1),
|
||||
(rotation==-1) ? pdfdoc->getPageRotate(i+1) : 0 );
|
||||
KPDFPage * page = new KPDFPage( i, w, h, rotation );
|
||||
addTransition( p, page );
|
||||
if ( true ) //TODO real check
|
||||
addAnnotations( p, page );
|
||||
|
@ -239,11 +243,11 @@ TextPage * PDFGenerator::fastTextPage (KPDFPage * page)
|
|||
// fetch ourselves a textpage
|
||||
TextOutputDev td(NULL, gTrue, gFalse, gFalse);
|
||||
docLock.lock();
|
||||
pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation(), false, true, false );
|
||||
pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation()*90, false, true, false );
|
||||
// ..and attach it to the page
|
||||
TextPage *p=td.takeText();
|
||||
if (prefersInternalSearching())
|
||||
page->setSearchPage( abstractTextPage(p, page->height(), page->width()) );
|
||||
page->setSearchPage( abstractTextPage(p, page->height(), page->width(),page->rotation()) );
|
||||
docLock.unlock();
|
||||
return p;
|
||||
}
|
||||
|
@ -252,15 +256,11 @@ QString * PDFGenerator::getText( const RegularAreaRect * area, KPDFPage * page
|
|||
{
|
||||
TextPage* textPage=fastTextPage (page);
|
||||
|
||||
int left,right,bottom,top;
|
||||
// int left,right,bottom,top;
|
||||
QString * text = new QString;
|
||||
// when using internal stuff we just have
|
||||
NormalizedRect * rect = area->first();
|
||||
left = (int)( rect->left * page->width() );
|
||||
top = (int)( rect->top * page->height() );
|
||||
right = (int)( rect->right * page->width() );
|
||||
bottom = (int)( rect->bottom * page->height() );
|
||||
*text= textPage->getText( left, top, right, bottom )->getCString();
|
||||
QRect rect = area->first()->geometry(page->width(),page->height());
|
||||
*text= textPage->getText( rect.left(), rect.top(), rect.right(), rect.bottom() )->getCString();
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ void PDFGenerator::generatePixmap( PixmapRequest * request )
|
|||
// note: thread safety is set on 'false' for the GUI (this) thread
|
||||
kpdfOutputDev->setParams( request->width, request->height, genObjectRects, genObjectRects, false );
|
||||
// TODO: check if this should not get a rotation parameter
|
||||
pdfdoc->displayPage( kpdfOutputDev, page->number() + 1, fakeDpiX, fakeDpiY, page->rotation(),
|
||||
pdfdoc->displayPage( kpdfOutputDev, page->number() + 1, fakeDpiX, fakeDpiY, page->rotation()*90,
|
||||
false, true, genObjectRects );
|
||||
|
||||
// 2. Take data from outputdev and attach it to the Page
|
||||
|
@ -510,7 +510,7 @@ void PDFGenerator::generatePixmap( PixmapRequest * request )
|
|||
if ( genTextPage )
|
||||
{
|
||||
TextOutputDev td(NULL, gTrue, gFalse, gFalse);
|
||||
page->setSearchPage( abstractTextPage(td.takeText(), page->height(), page->width()) );
|
||||
page->setSearchPage( abstractTextPage(td.takeText(), page->height(), page->width(),page->rotation()) );
|
||||
}
|
||||
// update ready state
|
||||
ready = true;
|
||||
|
@ -529,9 +529,9 @@ void PDFGenerator::generateSyncTextPage( KPDFPage * page )
|
|||
// build a TextPage...
|
||||
TextOutputDev td(NULL, gTrue, gFalse, gFalse);
|
||||
docLock.lock();
|
||||
pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation(), false, true, false );
|
||||
pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation()*90, false, true, false );
|
||||
// ..and attach it to the page
|
||||
page->setSearchPage( abstractTextPage(td.takeText(), page->height(), page->width()) );
|
||||
page->setSearchPage( abstractTextPage(td.takeText(), page->height(), page->width(),page->rotation()) );
|
||||
docLock.unlock();
|
||||
}
|
||||
|
||||
|
@ -672,43 +672,36 @@ static QString unicodeToQString(const Unicode* u, int len) {
|
|||
}
|
||||
|
||||
inline void append (KPDFTextPage* ktp,
|
||||
QString s, double l, double b, double r, double t, double rot)
|
||||
QString s, double l, double b, double r, double t)
|
||||
{
|
||||
// kdWarning() << "text: " << s << " at (" << l << "," << t << ")x(" << r <<","<<b<<")" << endl;
|
||||
ktp->append( s ,
|
||||
new NormalizedRect(
|
||||
l,
|
||||
b,
|
||||
r,
|
||||
t
|
||||
),
|
||||
static_cast<int>(rot));
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, double width)
|
||||
{
|
||||
KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, double width,int rot)
|
||||
{
|
||||
KPDFTextPage* ktp=new KPDFTextPage;
|
||||
TextWordList *list = tp->makeWordList(true);
|
||||
TextWord * word, *next;
|
||||
int wordCount=list->getLength();
|
||||
kdWarning() << "getting text page in generator pdf - rotation: " << rot << endl;
|
||||
int charCount=0;
|
||||
int i,j,rot;
|
||||
QString s,t;
|
||||
int i,j;
|
||||
QString s;
|
||||
NormalizedRect * wordRect = new NormalizedRect;
|
||||
for (i=0;i<wordCount;i++)
|
||||
{
|
||||
word=list->get(i);
|
||||
word->getBBox(&wordRect->left,&wordRect->bottom,&wordRect->right,&wordRect->top);
|
||||
charCount=word->getLength();
|
||||
rot=word->getRotation();
|
||||
next=word->nextWord();
|
||||
|
||||
if ( word->hasSpaceAfter() == gTrue && next )
|
||||
t=" ";
|
||||
else if ( !next )
|
||||
t="\n";
|
||||
else
|
||||
t="";
|
||||
switch (rot)
|
||||
{
|
||||
case 0:
|
||||
|
@ -717,15 +710,23 @@ KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, doubl
|
|||
for (j=0;j<charCount;j++)
|
||||
{
|
||||
s=unicodeToQString( word->getChar(j),1);
|
||||
append(ktp, s+t,
|
||||
append(ktp, (j==charCount-1 && !next ) ? (s + "\n") : s,
|
||||
// this letters boundary
|
||||
word->getEdge(j)/width,
|
||||
wordRect->bottom/height,
|
||||
// next letters boundary
|
||||
word->getEdge(j+1)/width,
|
||||
wordRect->top/height,
|
||||
rot);
|
||||
wordRect->top/height);
|
||||
}
|
||||
|
||||
if ( word->hasSpaceAfter() == gTrue && next )
|
||||
append(ktp, " ",
|
||||
// this letters boundary
|
||||
word->getEdge(charCount)/width,
|
||||
wordRect->bottom/height,
|
||||
// next letters boundary
|
||||
next->getEdge(0)/width,
|
||||
wordRect->top/height);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -734,13 +735,21 @@ KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, doubl
|
|||
for (j=0;j<charCount;j++)
|
||||
{
|
||||
s=unicodeToQString( word->getChar(j),1);
|
||||
append(ktp, s+t,
|
||||
append(ktp, (j==charCount-1 && !next ) ? (s + "\n") : s,
|
||||
wordRect->left/width,
|
||||
word->getEdge(j)/height,
|
||||
wordRect->right/width,
|
||||
word->getEdge(j+1)/height,
|
||||
rot);
|
||||
word->getEdge(j+1)/height);
|
||||
}
|
||||
|
||||
if ( word->hasSpaceAfter() == gTrue && next )
|
||||
append(ktp, " ",
|
||||
// this letters boundary
|
||||
wordRect->left/width,
|
||||
word->getEdge(charCount)/height,
|
||||
// next letters boundary
|
||||
wordRect->right/width,
|
||||
next->getEdge(0)/height);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -748,27 +757,44 @@ KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, doubl
|
|||
for (j=0;j<charCount;j++)
|
||||
{
|
||||
s=unicodeToQString( word->getChar(j),1);
|
||||
append(ktp, s+t,
|
||||
append(ktp, (j==charCount-1 && !next ) ? (s + "\n") : s,
|
||||
word->getEdge(j+1)/width,
|
||||
wordRect->bottom/height,
|
||||
word->getEdge(j)/width,
|
||||
wordRect->top/height,
|
||||
rot);
|
||||
wordRect->top/height);
|
||||
|
||||
}
|
||||
|
||||
if ( word->hasSpaceAfter() == gTrue && next )
|
||||
append(ktp, " ",
|
||||
// this letters boundary
|
||||
next->getEdge(0)/width,
|
||||
wordRect->bottom/height,
|
||||
// next letters boundary
|
||||
word->getEdge(charCount)/width,
|
||||
wordRect->top/height);
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (j=0;j<charCount;j++)
|
||||
{
|
||||
s=unicodeToQString( word->getChar(j),1);
|
||||
append(ktp, s+t,
|
||||
append(ktp, (j==charCount-1 && !next ) ? (s + "\n") : s,
|
||||
wordRect->left/width,
|
||||
word->getEdge(j+1)/height,
|
||||
wordRect->right/width,
|
||||
word->getEdge(j)/height,
|
||||
rot);
|
||||
word->getEdge(j)/height);
|
||||
}
|
||||
|
||||
if ( word->hasSpaceAfter() == gTrue && next )
|
||||
append(ktp, " ",
|
||||
// this letters boundary
|
||||
wordRect->left/width,
|
||||
next->getEdge(0)/height,
|
||||
// next letters boundary
|
||||
wordRect->right/width,
|
||||
word->getEdge(charCount)/height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2084,7 +2110,7 @@ void PDFGenerator::customEvent( QCustomEvent * event )
|
|||
delete outImage;
|
||||
if ( outTextPage )
|
||||
request->page->setSearchPage( abstractTextPage( outTextPage ,
|
||||
request->page->height(), request->page->width()));
|
||||
request->page->height(), request->page->width(),request->page->rotation()));
|
||||
if ( !outRects.isEmpty() )
|
||||
request->page->setObjectRects( outRects );
|
||||
|
||||
|
@ -2229,7 +2255,7 @@ void PDFPixmapGeneratorThread::run()
|
|||
d->generator->kpdfOutputDev->setParams( width, height,
|
||||
genObjectRects, genObjectRects, TRUE /*thread safety*/ );
|
||||
d->generator->pdfdoc->displayPage( d->generator->kpdfOutputDev, page->number() + 1,
|
||||
fakeDpiX, fakeDpiY, d->currentRequest->rotation , false,true, genObjectRects );
|
||||
fakeDpiX, fakeDpiY, d->currentRequest->rotation*90 , false,true, genObjectRects );
|
||||
|
||||
// 2. grab data from the OutputDev and store it locally (note takeIMAGE)
|
||||
#ifndef NDEBUG
|
||||
|
@ -2245,7 +2271,7 @@ void PDFPixmapGeneratorThread::run()
|
|||
if ( genTextPage )
|
||||
{
|
||||
TextOutputDev td(NULL, gTrue, gFalse, gFalse);
|
||||
d->generator->pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation(), false, true, false );
|
||||
d->generator->pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation()*90, false, true, false );
|
||||
// ..and attach it to the page
|
||||
d->m_textPage = td.takeText();
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ class PDFGenerator : public Generator
|
|||
// fetch the transition information and add it to the page
|
||||
void addTransition( Page * xpdfPage, KPDFPage * page );
|
||||
|
||||
static KPDFTextPage * abstractTextPage(TextPage *tp, double height, double width);
|
||||
static KPDFTextPage * abstractTextPage(TextPage *tp, double height, double width, int rot);
|
||||
TextPage * fastTextPage (KPDFPage * page);
|
||||
|
||||
// (async related) receive data from the generator thread
|
||||
|
|
1
part.h
1
part.h
|
@ -170,6 +170,7 @@ private:
|
|||
KToggleAction* m_showMenuBarAction;
|
||||
KToggleAction* m_showLeftPanel;
|
||||
KToggleAction* m_showFullScreenAction;
|
||||
|
||||
bool m_actionsSearched;
|
||||
bool m_searchStarted;
|
||||
BrowserExtension *m_bExtension;
|
||||
|
|
5
part.rc
5
part.rc
|
@ -24,7 +24,10 @@
|
|||
<Action name="zoom_fit_rect"/>
|
||||
<Separator/>
|
||||
<Action name="view_continuous"/>
|
||||
<Action name="view_twopages"/>
|
||||
<Action name="view_render_mode"/>
|
||||
<Separator/>
|
||||
<Action name="view_orientation"/>
|
||||
<Action name="view_papersizes"/>
|
||||
</Menu>
|
||||
<Menu name="go"><text>&Go</text>
|
||||
<Action name="previous_page"/>
|
||||
|
|
413
ui/pageview.cpp
413
ui/pageview.cpp
|
@ -16,6 +16,10 @@
|
|||
* (at your option) any later version. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
// qt/kde includes
|
||||
#include <qcursor.h>
|
||||
#include <qpainter.h>
|
||||
|
@ -50,6 +54,7 @@
|
|||
#include "pageviewannotator.h"
|
||||
#include "core/document.h"
|
||||
#include "core/page.h"
|
||||
#include "core/misc.h"
|
||||
#include "core/link.h"
|
||||
#include "core/generator.h"
|
||||
#include "conf/settings.h"
|
||||
|
@ -74,13 +79,19 @@ public:
|
|||
PageView::MouseMode mouseMode;
|
||||
QPoint mouseGrabPos;
|
||||
QPoint mousePressPos;
|
||||
QPoint mouseSelectPos;
|
||||
bool mouseMidZooming;
|
||||
int mouseMidLastY;
|
||||
bool mouseSelecting;
|
||||
QRect mouseSelectionRect;
|
||||
QColor mouseSelectionColor;
|
||||
bool mouseTextSelecting;
|
||||
bool mouseTextSelectionPainted;
|
||||
QValueList<QRect>* mouseTextSelectionRect;
|
||||
QColor mouseTextSelectionColor;
|
||||
TextSelection * mouseTextSelectionInfo;
|
||||
bool mouseOnRect;
|
||||
|
||||
|
||||
// type ahead find
|
||||
bool typeAheadActive;
|
||||
QString typeAheadString;
|
||||
|
@ -104,6 +115,7 @@ public:
|
|||
|
||||
// actions
|
||||
KSelectAction * aOrientation;
|
||||
KSelectAction * aPaperSizes;
|
||||
KToggleAction * aMouseNormal;
|
||||
KToggleAction * aMouseSelect;
|
||||
KToggleAction * aToggleAnnotator;
|
||||
|
@ -111,7 +123,7 @@ public:
|
|||
KToggleAction * aZoomFitWidth;
|
||||
KToggleAction * aZoomFitPage;
|
||||
KToggleAction * aZoomFitText;
|
||||
KToggleAction * aViewTwoPages;
|
||||
KSelectAction * aRenderMode;
|
||||
KToggleAction * aViewContinuous;
|
||||
KAction * aPrevAction;
|
||||
};
|
||||
|
@ -135,11 +147,13 @@ PageView::PageView( QWidget *parent, KPDFDocument *document )
|
|||
d = new PageViewPrivate();
|
||||
d->document = document;
|
||||
d->aOrientation = 0;
|
||||
d->aRenderMode = 0;
|
||||
d->zoomMode = (PageView::ZoomMode) KpdfSettings::zoomMode();
|
||||
d->zoomFactor = KpdfSettings::zoomFactor();
|
||||
d->mouseMode = MouseNormal;
|
||||
d->mouseMidZooming = false;
|
||||
d->mouseSelecting = false;
|
||||
d->mouseTextSelecting = false;
|
||||
d->mouseOnRect = false;
|
||||
d->typeAheadActive = false;
|
||||
d->findTimeoutTimer = 0;
|
||||
|
@ -154,6 +168,10 @@ PageView::PageView( QWidget *parent, KPDFDocument *document )
|
|||
d->blockPixmapsRequest = false;
|
||||
d->messageWindow = new PageViewMessage(this);
|
||||
d->aPrevAction = 0;
|
||||
d->mouseTextSelectionRect=0;
|
||||
d->mouseTextSelectionInfo=0;
|
||||
d->mouseTextSelectionPainted=0;
|
||||
d->aPaperSizes=0;
|
||||
|
||||
// widget setup: setup focus, accept drops and track mouse
|
||||
viewport()->setFocusProxy( this );
|
||||
|
@ -187,8 +205,8 @@ PageView::~PageView()
|
|||
|
||||
void PageView::setupActions( KActionCollection * ac )
|
||||
{
|
||||
d->aOrientation=new KSelectAction( i18n( "&Orientation" ), 0, this, 0, ac, "orientation_menu" );
|
||||
|
||||
d->aOrientation=new KSelectAction( i18n( "&Orientation" ), 0, this, 0, ac, "view_orientation" );
|
||||
d->aPaperSizes=new KSelectAction( i18n( "&Paper sizes" ), 0, this, 0, ac, "view_papersizes" );
|
||||
QStringList orientations;
|
||||
orientations.append( i18n( "Portrait" ) );
|
||||
orientations.append( i18n( "Landscape" ) );
|
||||
|
@ -198,8 +216,14 @@ void PageView::setupActions( KActionCollection * ac )
|
|||
|
||||
connect( d->aOrientation , SIGNAL( activated( int ) ),
|
||||
d->document , SLOT( slotOrientation( int ) ) );
|
||||
connect( d->aPaperSizes , SIGNAL( activated( int ) ),
|
||||
d->document , SLOT( slotPaperSizes( int ) ) );
|
||||
|
||||
d->aOrientation->setEnabled(d->document->supportsRotation());
|
||||
bool paperSizes=d->document->supportsPaperSizes();
|
||||
d->aPaperSizes->setEnabled(paperSizes);
|
||||
if (paperSizes)
|
||||
d->aPaperSizes->setItems(d->document->paperSizes());
|
||||
|
||||
// Zoom actions ( higher scales takes lots of memory! )
|
||||
d->aZoom = new KSelectAction( i18n( "Zoom" ), "viewmag", 0, this, SLOT( slotZoom() ), ac, "zoom_to" );
|
||||
|
@ -223,9 +247,15 @@ void PageView::setupActions( KActionCollection * ac )
|
|||
connect( d->aZoomFitText, SIGNAL( toggled( bool ) ), SLOT( slotFitToTextToggled( bool ) ) );
|
||||
|
||||
// View-Layout actions
|
||||
d->aViewTwoPages = new KToggleAction( i18n("&Two Pages"), "view_left_right", 0, ac, "view_twopages" );
|
||||
connect( d->aViewTwoPages, SIGNAL( toggled( bool ) ), SLOT( slotTwoPagesToggled( bool ) ) );
|
||||
d->aViewTwoPages->setChecked( KpdfSettings::viewColumns() > 1 );
|
||||
QStringList renderModes;
|
||||
renderModes.append( i18n( "Single" ) );
|
||||
renderModes.append( i18n( "Facing" ) );
|
||||
renderModes.append( i18n( "Overview" ) );
|
||||
|
||||
d->aRenderMode = new KSelectAction( i18n("&Render Mode"), "view_left_right", 0, ac, "view_render_mode" );
|
||||
connect( d->aRenderMode, SIGNAL( activated( int ) ), SLOT( slotRenderMode( int ) ) );
|
||||
d->aRenderMode->setItems( renderModes );
|
||||
d->aRenderMode->setCurrentItem( KpdfSettings::renderMode() );
|
||||
|
||||
d->aViewContinuous = new KToggleAction( i18n("&Continuous"), "view_text", 0, ac, "view_continuous" );
|
||||
connect( d->aViewContinuous, SIGNAL( toggled( bool ) ), SLOT( slotContinuousToggled( bool ) ) );
|
||||
|
@ -256,18 +286,18 @@ void PageView::setupActions( KActionCollection * ac )
|
|||
|
||||
bool PageView::canFitPageWidth()
|
||||
{
|
||||
return KpdfSettings::viewColumns() != 1 || d->zoomMode != ZoomFitWidth;
|
||||
return KpdfSettings::renderMode() != 0 || d->zoomMode != ZoomFitWidth;
|
||||
}
|
||||
|
||||
void PageView::fitPageWidth( int page )
|
||||
{
|
||||
// zoom: Fit Width, columns: 1. setActions + relayout + setPage + update
|
||||
d->zoomMode = ZoomFitWidth;
|
||||
KpdfSettings::setViewColumns( 1 );
|
||||
KpdfSettings::setRenderMode( 0 );
|
||||
d->aZoomFitWidth->setChecked( true );
|
||||
d->aZoomFitPage->setChecked( false );
|
||||
d->aZoomFitText->setChecked( false );
|
||||
d->aViewTwoPages->setChecked( false );
|
||||
d->aRenderMode->setCurrentItem( 0 );
|
||||
viewport()->setUpdatesEnabled( false );
|
||||
slotRelayoutPages();
|
||||
viewport()->setUpdatesEnabled( true );
|
||||
|
@ -309,7 +339,7 @@ void PageView::notifySetup( const QValueVector< KPDFPage * > & pageSet, bool doc
|
|||
if ( !documentChanged )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// delete all widgets (one for each page in pageSet)
|
||||
QValueVector< PageViewItem * >::iterator dIt = d->items.begin(), dEnd = d->items.end();
|
||||
for ( ; dIt != dEnd; ++dIt )
|
||||
|
@ -320,7 +350,12 @@ void PageView::notifySetup( const QValueVector< KPDFPage * > & pageSet, bool doc
|
|||
// create children widgets
|
||||
QValueVector< KPDFPage * >::const_iterator setIt = pageSet.begin(), setEnd = pageSet.end();
|
||||
for ( ; setIt != setEnd; ++setIt )
|
||||
{
|
||||
d->items.push_back( new PageViewItem( *setIt ) );
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdDebug() << "geom for " << d->items.last()->pageNumber() << " is " << d->items.last()->geometry() << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// invalidate layout so relayout/repaint will happen on next viewport change
|
||||
if ( pageSet.count() > 0 )
|
||||
|
@ -329,7 +364,7 @@ void PageView::notifySetup( const QValueVector< KPDFPage * > & pageSet, bool doc
|
|||
// Need slotRelayoutPages() here instead of d->dirtyLayout = true
|
||||
// because opening a pdf from another pdf will not trigger a viewportchange
|
||||
// so pages are never relayouted
|
||||
QTimer::singleShot(0, this, SLOT(slotRelayoutPages()));
|
||||
QTimer::singleShot(0, this, SLOT(slotRelayoutPages())); // was used
|
||||
else
|
||||
{
|
||||
// update the mouse cursor when closing because we may have close through a link and
|
||||
|
@ -347,6 +382,10 @@ void PageView::notifySetup( const QValueVector< KPDFPage * > & pageSet, bool doc
|
|||
PageViewMessage::Info, 4000 );
|
||||
|
||||
d->aOrientation->setEnabled(d->document->supportsRotation());
|
||||
bool paperSizes=d->document->supportsPaperSizes();
|
||||
d->aPaperSizes->setEnabled(paperSizes);
|
||||
if (paperSizes)
|
||||
d->aPaperSizes->setItems(d->document->paperSizes());
|
||||
}
|
||||
|
||||
void PageView::notifyViewportChanged( bool smoothMove )
|
||||
|
@ -374,7 +413,9 @@ void PageView::notifyViewportChanged( bool smoothMove )
|
|||
d->blockViewport = false;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdDebug() << "document viewport changed\n";
|
||||
#endif
|
||||
// relayout in "Single Pages" mode or if a relayout is pending
|
||||
d->blockPixmapsRequest = true;
|
||||
if ( !KpdfSettings::viewContinuous() || d->dirtyLayout )
|
||||
|
@ -542,7 +583,8 @@ if ( d->document->handleEvent( pe ) )
|
|||
}
|
||||
|
||||
// note: this check will take care of all things requiring alpha blending (not only selection)
|
||||
bool wantCompositing = !selectionRect.isNull() && contentsRect.intersects( selectionRect );
|
||||
bool wantCompositing = ( !selectionRect.isNull() && contentsRect.intersects( selectionRect ) )
|
||||
|| d->mouseTextSelecting;
|
||||
|
||||
if ( wantCompositing && KpdfSettings::enableCompositing() )
|
||||
{
|
||||
|
@ -551,9 +593,18 @@ if ( d->document->handleEvent( pe ) )
|
|||
QPainter pixmapPainter( &doubleBuffer );
|
||||
pixmapPainter.translate( -contentsRect.left(), -contentsRect.top() );
|
||||
|
||||
// calculate the color
|
||||
XRenderColor col;
|
||||
float alpha=0.2f;
|
||||
QColor blCol=selBlendColor.dark(140);
|
||||
col.red=( (blCol.red() << 8) | blCol.red() ) * alpha;
|
||||
col.green=( (blCol.green() << 8) | blCol.green() )*alpha;
|
||||
col.blue=( (blCol.blue() << 8) | blCol.blue())*alpha;
|
||||
col.alpha=alpha*0xffff;
|
||||
|
||||
// 1) Layer 0: paint items and clear bg on unpainted rects
|
||||
drawDocumentOnPainter( contentsRect, &pixmapPainter );
|
||||
// 2) Layer 1: paint (blend) transparent selection
|
||||
// 2) Layer 1a: paint (blend) transparent selection
|
||||
if ( !selectionRect.isNull() && selectionRect.intersects( contentsRect ) &&
|
||||
!selectionRectInternal.contains( contentsRect ) )
|
||||
{
|
||||
|
@ -567,14 +618,55 @@ if ( d->document->handleEvent( pe ) )
|
|||
blendRect.left() - contentsRect.left(), blendRect.top() - contentsRect.top(),
|
||||
blendRect.width(), blendRect.height() );
|
||||
// blend selBlendColor into the background pixmap
|
||||
QImage blendedImage = blendedPixmap.convertToImage();
|
||||
KImageEffect::blend( selBlendColor.dark(140), blendedImage, 0.2 );
|
||||
// QImage blendedImage = blendedPixmap.convertToImage();
|
||||
// KImageEffect::blend( selBlendColor.dark(140), blendedImage, 0.2 );
|
||||
XRenderFillRectangle(x11Display(), PictOpOver, blendedPixmap.x11RenderHandle(), &col,
|
||||
0,0, blendRect.width(), blendRect.height());
|
||||
// copy the blended pixmap back to its place
|
||||
pixmapPainter.drawPixmap( blendRect.left(), blendRect.top(), blendedImage );
|
||||
pixmapPainter.drawPixmap( blendRect.left(), blendRect.top(), blendedPixmap );
|
||||
}
|
||||
// draw border (red if the selection is too small)
|
||||
pixmapPainter.setPen( selBlendColor );
|
||||
pixmapPainter.drawRect( selectionRect );
|
||||
}
|
||||
if ( d->mouseTextSelecting )
|
||||
{
|
||||
QRect blendRect;
|
||||
QValueList<QRect>::iterator it=d->mouseTextSelectionRect->begin(),
|
||||
end=d->mouseTextSelectionRect->end();
|
||||
XRenderColor col;
|
||||
float alpha=0.2f;
|
||||
QColor blCol=d->mouseTextSelectionColor.dark(140);
|
||||
col.red=( (blCol.red() << 8) | blCol.red() ) * alpha;
|
||||
col.green=( (blCol.green() << 8) | blCol.green() )*alpha;
|
||||
col.blue=( (blCol.blue() << 8) | blCol.blue())*alpha;
|
||||
col.alpha=alpha*0xffff;
|
||||
|
||||
for (;it!=end;++it)
|
||||
{
|
||||
if (! ((*it).intersects( contentsRect )))
|
||||
continue;
|
||||
blendRect = (*it).intersect(contentsRect);
|
||||
QPixmap blendedPixmap( blendRect.width(), blendRect.height() );
|
||||
copyBlt( &blendedPixmap, 0,0, &doubleBuffer,
|
||||
blendRect.left() - contentsRect.left(), blendRect.top() - contentsRect.top(),
|
||||
blendRect.width(), blendRect.height() );
|
||||
// blend selBlendColor into the background pixmap
|
||||
// QImage blendedImage = blendedPixmap.convertToImage();
|
||||
XRenderFillRectangle(x11Display(), PictOpOver, blendedPixmap.x11RenderHandle(), &col,
|
||||
0,0, blendRect.width(), blendRect.height());
|
||||
|
||||
// KImageEffect::blend( d->mouseTextSelectionColor.dark(140), blendedImage, 0.2 );
|
||||
|
||||
// copy the blended pixmap back to its place
|
||||
pixmapPainter.drawPixmap( blendRect.left(), blendRect.top(), blendedPixmap );
|
||||
|
||||
// draw border (red if the selection is too small)
|
||||
pixmapPainter.setPen( d->mouseTextSelectionColor );
|
||||
pixmapPainter.drawRect( selectionRect );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// 3) Layer 1: give annotator painting control
|
||||
if ( d->annotator && d->annotator->routePaints( contentsRect ) )
|
||||
|
@ -735,7 +827,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
case Key_Up:
|
||||
case Key_PageUp:
|
||||
// if in single page mode and at the top of the screen, go to previous page
|
||||
// if in single page mode and at the top of the screen, go to \ page
|
||||
if ( KpdfSettings::viewContinuous() || verticalScrollBar()->value() > verticalScrollBar()->minValue() )
|
||||
{
|
||||
if ( e->key() == Key_Up )
|
||||
|
@ -747,7 +839,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
// more optimized than document->setPrevPage and then move view to bottom
|
||||
DocumentViewport newViewport = d->document->viewport();
|
||||
newViewport.pageNumber -= KpdfSettings::viewColumns();
|
||||
newViewport.pageNumber -= viewColumns();
|
||||
if ( newViewport.pageNumber < 0 )
|
||||
newViewport.pageNumber = 0;
|
||||
newViewport.rePos.enabled = true;
|
||||
|
@ -769,7 +861,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
// more optimized than document->setNextPage and then move view to top
|
||||
DocumentViewport newViewport = d->document->viewport();
|
||||
newViewport.pageNumber += d->document->currentPage() ? KpdfSettings::viewColumns() : 1;
|
||||
newViewport.pageNumber += d->document->currentPage() ? viewColumns() : 1;
|
||||
if ( newViewport.pageNumber >= (int)d->items.count() )
|
||||
newViewport.pageNumber = d->items.count() - 1;
|
||||
newViewport.rePos.enabled = true;
|
||||
|
@ -897,16 +989,49 @@ if (d->document->handleEvent( e ) )
|
|||
}
|
||||
else if ( rightButton && !d->mousePressPos.isNull() )
|
||||
{
|
||||
// if mouse moves 5 px away from the press point, switch to 'selection'
|
||||
int deltaX = d->mousePressPos.x() - e->globalPos().x(),
|
||||
deltaY = d->mousePressPos.y() - e->globalPos().y();
|
||||
if ( deltaX > 5 || deltaX < -5 || deltaY > 5 || deltaY < -5 )
|
||||
// if mouse moves 5 px away from the press point, do 'textselection'
|
||||
int deltaX = e->x() - d->mouseSelectPos.x(),
|
||||
deltaY = e->y() - d->mouseSelectPos.y();
|
||||
if ( d->document->supportsSearching() && ( deltaX > 5 || deltaX < -5 || deltaY > 5 || deltaY < -5 ) )
|
||||
{
|
||||
d->aPrevAction = d->aMouseNormal;
|
||||
d->aMouseSelect->activate();
|
||||
QColor selColor = palette().active().highlight().light( 120 );
|
||||
selectionStart( e->x() + deltaX, e->y() + deltaY, selColor, false );
|
||||
selectionEndPoint( e->x(), e->y() );
|
||||
PageViewItem * currentItem = d->items[ QMAX( 0, (int)d->document->currentPage() ) ];
|
||||
// PageViewItem* item=pickItemOnPoint(e->x(),e->y());
|
||||
const KPDFPage * kpdfPage = currentItem->page();
|
||||
// build a proper rectangle (make sure left/top is to the left of right/bottom)
|
||||
// QRect rect (d->mouseSelectPos,e->pos());
|
||||
// rect=rect.normalize();
|
||||
//
|
||||
QRect vRect = currentItem->geometry();
|
||||
// kdDebug() << "viewport " << vRect << endl;
|
||||
// kdDebug() << "selection (UN) " << rect << endl;
|
||||
// // move selection area over to relevant viewport
|
||||
// rect.moveBy(-vRect.left(),-vRect.top());
|
||||
// kdDebug() << "selection (MV) " << rect << endl;
|
||||
// clip to viewport
|
||||
// rect &= vRect;
|
||||
// kdDebug() << "selection (CL) " << rect << endl;
|
||||
// FIXME: width and height are greater by 1 then the selection.
|
||||
// rect.addCoords(1,1,-1,-1);
|
||||
|
||||
if ( !kpdfPage->hasSearchPage() )
|
||||
d->document->requestTextPage( kpdfPage->number() );
|
||||
NormalizedPoint startCursor(d->mouseSelectPos.x()-vRect.left(),d->mouseSelectPos.y()-vRect.top(),
|
||||
vRect.width(), vRect.height());
|
||||
NormalizedPoint endCursor(e->x()-vRect.left(),e->y()-vRect.top(),vRect.width(), vRect.height());
|
||||
|
||||
if ( ! d->mouseTextSelectionInfo )
|
||||
d->mouseTextSelectionInfo=new TextSelection(startCursor,endCursor);
|
||||
else
|
||||
d->mouseTextSelectionInfo->end(endCursor);
|
||||
RegularAreaRect * selectionArea=kpdfPage->getTextArea(d->mouseTextSelectionInfo);
|
||||
kdWarning () << "text areas: " << selectionArea->count() << endl;
|
||||
if ( selectionArea->count() > 0 )
|
||||
{
|
||||
QColor selColor = palette().active().highlight();
|
||||
textSelection(selectionArea->geometry(vRect.width(),vRect.height(),vRect.left(),vRect.top())
|
||||
,selColor);
|
||||
}
|
||||
delete selectionArea;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -920,7 +1045,8 @@ if (d->document->handleEvent( e ) )
|
|||
case MouseZoom:
|
||||
case MouseSelect:
|
||||
// set second corner of selection
|
||||
if ( d->mouseSelecting && (leftButton || d->aPrevAction) )
|
||||
// TODO: does this condition make sense?
|
||||
if ( d->mouseSelecting || (d->mouseSelecting && d->aPrevAction) )
|
||||
selectionEndPoint( e->x(), e->y() );
|
||||
break;
|
||||
}
|
||||
|
@ -929,7 +1055,7 @@ if (d->document->handleEvent( e ) )
|
|||
|
||||
void PageView::contentsMousePressEvent( QMouseEvent * e )
|
||||
{
|
||||
if (d->document->handleEvent( e ) )
|
||||
if ( d->document->handleEvent( e ) )
|
||||
{
|
||||
// don't perform any mouse action when no document is shown
|
||||
if ( d->items.isEmpty() )
|
||||
|
@ -969,6 +1095,11 @@ if (d->document->handleEvent( e ) )
|
|||
// handle mode dependant mouse press actions
|
||||
bool leftButton = e->button() & LeftButton,
|
||||
rightButton = e->button() & RightButton;
|
||||
|
||||
// Not sure we should erase the selection when clicking with left.
|
||||
// if ( !(rightButton && d->mouseMode==MouseNormal) && d->mouseTextSelectionPainted )
|
||||
// textSelectionClear();
|
||||
|
||||
switch ( d->mouseMode )
|
||||
{
|
||||
case MouseNormal: // drag start / click / link following
|
||||
|
@ -978,6 +1109,8 @@ if (d->document->handleEvent( e ) )
|
|||
if ( !d->mouseOnRect )
|
||||
setCursor( sizeAllCursor );
|
||||
}
|
||||
else if (rightButton)
|
||||
d->mouseSelectPos=e->pos() ; // just check
|
||||
break;
|
||||
|
||||
case MouseZoom: // set first corner of the zoom rect
|
||||
|
@ -988,11 +1121,11 @@ if (d->document->handleEvent( e ) )
|
|||
break;
|
||||
|
||||
case MouseSelect: // set first corner of the selection rect
|
||||
if ( leftButton )
|
||||
{
|
||||
// if ( leftButton )
|
||||
// {
|
||||
QColor selColor = palette().active().highlight().light( 120 );
|
||||
selectionStart( e->x(), e->y(), selColor, false );
|
||||
}
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1078,6 +1211,15 @@ if (d->document->handleEvent( e ) )
|
|||
}
|
||||
else if ( rightButton )
|
||||
{
|
||||
if ( d->mouseTextSelecting )
|
||||
{
|
||||
d->mouseTextSelecting = false;
|
||||
delete d->mouseTextSelectionInfo;
|
||||
d->mouseTextSelectionInfo=0;
|
||||
textSelectionClear();
|
||||
// textSelectionToClipboard();
|
||||
}
|
||||
else
|
||||
// right click (if not within 5 px of the press point, the mode
|
||||
// had been already changed to 'Selection' instead of 'Normal')
|
||||
emit rightClick( pageItem ? pageItem->page() : 0, e->globalPos() );
|
||||
|
@ -1148,7 +1290,7 @@ if (d->document->handleEvent( e ) )
|
|||
QString* selectedText=0;
|
||||
if (d->document->supportsSearching())
|
||||
{
|
||||
|
||||
|
||||
// grab text in selection by extracting it from all intersected pages
|
||||
RegularAreaRect * rects=new RegularAreaRect;
|
||||
const KPDFPage * kpdfPage=0;
|
||||
|
@ -1161,6 +1303,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
// request the textpage if there isn't one
|
||||
kpdfPage= item->page();
|
||||
kdWarning() << "checking if page " << item->pageNumber() << " has text " << kpdfPage->hasSearchPage() << endl;
|
||||
if ( !kpdfPage->hasSearchPage() )
|
||||
d->document->requestTextPage( kpdfPage->number() );
|
||||
// grab text in the rect that intersects itemRect
|
||||
|
@ -1314,7 +1457,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
// more optimized than document->setNextPage and then move view to top
|
||||
DocumentViewport newViewport = d->document->viewport();
|
||||
newViewport.pageNumber += d->document->currentPage() ? KpdfSettings::viewColumns() : 1;
|
||||
newViewport.pageNumber += d->document->currentPage() ? viewColumns() : 1;
|
||||
if ( newViewport.pageNumber >= (int)d->items.count() )
|
||||
newViewport.pageNumber = d->items.count() - 1;
|
||||
newViewport.rePos.enabled = true;
|
||||
|
@ -1329,7 +1472,7 @@ if (d->document->handleEvent( e ) )
|
|||
{
|
||||
// more optimized than document->setPrevPage and then move view to bottom
|
||||
DocumentViewport newViewport = d->document->viewport();
|
||||
newViewport.pageNumber -= KpdfSettings::viewColumns();
|
||||
newViewport.pageNumber -= viewColumns();
|
||||
if ( newViewport.pageNumber < 0 )
|
||||
newViewport.pageNumber = 0;
|
||||
newViewport.rePos.enabled = true;
|
||||
|
@ -1493,6 +1636,50 @@ PageViewItem * PageView::pickItemOnPoint( int x, int y )
|
|||
return item;
|
||||
}
|
||||
|
||||
void PageView::textSelection( QValueList<QRect> * area, const QColor & color )
|
||||
{
|
||||
setCursor( Qt::IbeamCursor );
|
||||
QValueList<QRect> toUpdate;
|
||||
if ( d->mouseTextSelectionRect && d->mouseTextSelectionRect )
|
||||
{
|
||||
toUpdate+=*(d->mouseTextSelectionRect);
|
||||
delete d->mouseTextSelectionRect;
|
||||
d->mouseTextSelectionRect=0;
|
||||
}
|
||||
|
||||
if (area)
|
||||
toUpdate+=*(area);
|
||||
|
||||
d->mouseTextSelecting = true;
|
||||
d->mouseTextSelectionRect = area;
|
||||
d->mouseTextSelectionColor = color;
|
||||
// ensures page doesn't scroll
|
||||
if ( d->autoScrollTimer )
|
||||
{
|
||||
d->scrollIncrement = 0;
|
||||
d->autoScrollTimer->stop();
|
||||
}
|
||||
QValueList<QRect>::Iterator it=toUpdate.begin(), end=toUpdate.end();
|
||||
for (;it!=end;++it)
|
||||
{
|
||||
updateContents( *it );
|
||||
}
|
||||
d->mouseTextSelectionPainted=true;
|
||||
}
|
||||
|
||||
void PageView::textSelectionClear()
|
||||
{
|
||||
setCursor( Qt::ArrowCursor );
|
||||
QValueList<QRect>::iterator it=d->mouseTextSelectionRect->begin(),
|
||||
end=d->mouseTextSelectionRect->end();
|
||||
for (;it!=end;++it)
|
||||
{
|
||||
updateContents( *it );
|
||||
}
|
||||
delete d->mouseTextSelectionRect;
|
||||
d->mouseTextSelectionRect=0;
|
||||
}
|
||||
|
||||
void PageView::selectionStart( int x, int y, const QColor & color, bool /*aboveAll*/ )
|
||||
{
|
||||
d->mouseSelecting = true;
|
||||
|
@ -1624,7 +1811,7 @@ void PageView::updateZoomText()
|
|||
|
||||
// add items that describe fit actions
|
||||
QStringList translated;
|
||||
translated << i18n("Fit Width") << i18n("Fit Page"); // << i18n("Fit Text");
|
||||
translated << i18n("Fit Width") << i18n("Fit Page") /*<< i18n("Fit Text")*/;
|
||||
|
||||
// add percent items
|
||||
QString double_oh( "00" );
|
||||
|
@ -1684,9 +1871,24 @@ void PageView::updateCursor( const QPoint &p )
|
|||
}
|
||||
}
|
||||
|
||||
int PageView::viewColumns()
|
||||
{
|
||||
int nr=KpdfSettings::renderMode();
|
||||
if (nr<2)
|
||||
return nr+1;
|
||||
return KpdfSettings::viewColumns();
|
||||
}
|
||||
|
||||
int PageView::viewRows()
|
||||
{
|
||||
if (KpdfSettings::renderMode()<2)
|
||||
return 1;
|
||||
return KpdfSettings::viewRows();
|
||||
}
|
||||
|
||||
//BEGIN private SLOTS
|
||||
void PageView::slotRelayoutPages()
|
||||
// called by: notifySetup, viewportResizeEvent, slotTwoPagesToggled, slotContinuousToggled, updateZoom
|
||||
// called by: notifySetup, viewportResizeEvent, slotRenderMode, slotContinuousToggled, updateZoom
|
||||
{
|
||||
// set an empty container if we have no pages
|
||||
int pageCount = d->items.count();
|
||||
|
@ -1714,7 +1916,7 @@ void PageView::slotRelayoutPages()
|
|||
QRect viewportRect( contentsX(), contentsY(), viewportWidth, viewportHeight );
|
||||
|
||||
// handle the 'center first page in row' stuff
|
||||
int nCols = KpdfSettings::viewColumns();
|
||||
int nCols = viewColumns();
|
||||
bool centerFirstPage = KpdfSettings::centerFirstPageInRow() && nCols > 1;
|
||||
|
||||
// set all items geometry and resize contents. handle 'continuous' and 'single' modes separately
|
||||
|
@ -1725,8 +1927,15 @@ void PageView::slotRelayoutPages()
|
|||
pageCount += nCols - 1;
|
||||
// Here we find out column's width and row's height to compute a table
|
||||
// so we can place widgets 'centered in virtual cells'.
|
||||
int nRows = (int)ceil( (float)pageCount / (float)nCols ),
|
||||
* colWidth = new int[ nCols ],
|
||||
int nRows;
|
||||
|
||||
// if ( KpdfSettings::renderMode() < 2 )
|
||||
nRows = (int)ceil( (float)pageCount / (float)nCols );
|
||||
// nRows=(int)ceil( (float)pageCount / (float) KpdfSettings::viewRows() );
|
||||
// else
|
||||
// nRows = KpdfSettings::viewRows();
|
||||
|
||||
int * colWidth = new int[ nCols ],
|
||||
* rowHeight = new int[ nRows ],
|
||||
cIdx = 0,
|
||||
rIdx = 0;
|
||||
|
@ -1799,6 +2008,9 @@ void PageView::slotRelayoutPages()
|
|||
insertX = 0;
|
||||
insertY += rHeight;
|
||||
}
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdWarning() << "updating size for pageno " << item->pageNumber() << " to " << item->geometry() << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
delete [] colWidth;
|
||||
|
@ -1807,31 +2019,51 @@ void PageView::slotRelayoutPages()
|
|||
else // viewContinuous is FALSE
|
||||
{
|
||||
PageViewItem * currentItem = d->items[ QMAX( 0, (int)d->document->currentPage() ) ];
|
||||
|
||||
int nRows=viewRows();
|
||||
|
||||
// handle the 'centering on first row' stuff
|
||||
if ( centerFirstPage && d->document->currentPage() < 1 )
|
||||
nCols = 1;
|
||||
// setup varialbles for a 1(row) x N(columns) grid
|
||||
if ( centerFirstPage && d->document->currentPage() < 1 && KpdfSettings::renderMode() == 1 )
|
||||
nCols = 1, nRows=1;
|
||||
|
||||
// setup varialbles for a M(row) x N(columns) grid
|
||||
int * colWidth = new int[ nCols ],
|
||||
cIdx = 0;
|
||||
fullHeight = viewportHeight;
|
||||
|
||||
int * rowHeight = new int[ nRows ],
|
||||
rIdx = 0;
|
||||
|
||||
for ( int i = 0; i < nCols; i++ )
|
||||
colWidth[ i ] = viewportWidth / nCols;
|
||||
|
||||
for ( int i = 0; i < nRows; i++ )
|
||||
rowHeight[ i ] = viewportHeight / nRows;
|
||||
|
||||
// 1) find out maximum area extension for the pages
|
||||
bool wasCurrent = false;
|
||||
for ( iIt = d->items.begin(); iIt != iEnd; ++iIt )
|
||||
{
|
||||
PageViewItem * item = *iIt;
|
||||
if ( item == currentItem || (cIdx > 0 && cIdx < nCols) )
|
||||
if ( rIdx >= 0 && rIdx < nRows )
|
||||
{
|
||||
// update internal page size (leaving a little margin in case of Fit* modes)
|
||||
updateItemSize( item, colWidth[ cIdx ] - 6, viewportHeight - 12 );
|
||||
// find row's maximum height and column's max width
|
||||
if ( item->width() + 6 > colWidth[ cIdx ] )
|
||||
colWidth[ cIdx ] = item->width() + 6;
|
||||
if ( item->height() + 12 > fullHeight )
|
||||
fullHeight = item->height() + 12;
|
||||
cIdx++;
|
||||
if ( item == currentItem )
|
||||
wasCurrent=true;
|
||||
if ( wasCurrent && cIdx >= 0 && cIdx < nCols )
|
||||
{
|
||||
// update internal page size (leaving a little margin in case of Fit* modes)
|
||||
updateItemSize( item, colWidth[ cIdx ] - 6, rowHeight[ rIdx ] - 12 );
|
||||
// find row's maximum height and column's max width
|
||||
if ( item->width() + 6 > colWidth[ cIdx ] )
|
||||
colWidth[ cIdx ] = item->width() + 6;
|
||||
if ( item->height() + 12 > rowHeight[ rIdx ] )
|
||||
rowHeight[ rIdx ] = item->height() + 12;
|
||||
cIdx++;
|
||||
}
|
||||
if( cIdx>=nCols )
|
||||
{
|
||||
rIdx++;
|
||||
cIdx=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1839,25 +2071,47 @@ void PageView::slotRelayoutPages()
|
|||
for ( int i = 0; i < nCols; i++ )
|
||||
fullWidth += colWidth[ i ];
|
||||
|
||||
for ( int i = 0; i < nRows; i++ )
|
||||
fullHeight += rowHeight[ i ];
|
||||
|
||||
// 3) hide all widgets except the displayable ones and dispose those
|
||||
int insertX = 0;
|
||||
int insertY = 0;
|
||||
cIdx = 0;
|
||||
rIdx = 0;
|
||||
wasCurrent=false;
|
||||
for ( iIt = d->items.begin(); iIt != iEnd; ++iIt )
|
||||
{
|
||||
PageViewItem * item = *iIt;
|
||||
if ( item == currentItem || (cIdx > 0 && cIdx < nCols) )
|
||||
if ( rIdx >= 0 && rIdx < nRows )
|
||||
{
|
||||
// center widget inside 'cells'
|
||||
item->moveTo( insertX + (colWidth[ cIdx ] - item->width()) / 2,
|
||||
(fullHeight - item->height()) / 2 );
|
||||
// advance col index
|
||||
insertX += colWidth[ cIdx ];
|
||||
cIdx++;
|
||||
} else
|
||||
item->setGeometry( 0, 0, -1, -1 );
|
||||
if ( item == currentItem )
|
||||
wasCurrent=true;
|
||||
if ( wasCurrent && cIdx >= 0 && cIdx < nCols )
|
||||
{
|
||||
// center widget inside 'cells'
|
||||
item->moveTo( insertX + (colWidth[ cIdx ] - item->width()) / 2,
|
||||
insertY + ( rowHeight[ rIdx ] - item->height() ) / 2 );
|
||||
// advance col index
|
||||
insertX += colWidth[ cIdx ];
|
||||
cIdx++;
|
||||
} else
|
||||
item->setGeometry( 0, 0, -1, -1 );
|
||||
|
||||
if( cIdx>=nCols)
|
||||
{
|
||||
insertY += rowHeight[ rIdx ];
|
||||
rIdx++;
|
||||
insertX = 0;
|
||||
cIdx=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
item->setGeometry( 0, 0, -1, -1 );
|
||||
}
|
||||
|
||||
delete [] colWidth;
|
||||
delete [] rowHeight;
|
||||
}
|
||||
|
||||
// 3) reset dirty state
|
||||
|
@ -1929,17 +2183,26 @@ void PageView::slotRequestVisiblePixmaps( int newLeft, int newTop )
|
|||
for ( ; iIt != iEnd; ++iIt )
|
||||
{
|
||||
PageViewItem * i = *iIt;
|
||||
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdWarning() << "checking page " << i->pageNumber() << endl;
|
||||
kdWarning() << "viewportRect is " << viewportRect << ", page item is " << i->geometry() << " intersect : " << viewportRect.intersects( i->geometry() ) << endl;
|
||||
#endif
|
||||
// if the item doesn't intersect the viewport, skip it
|
||||
if ( !viewportRect.intersects( i->geometry() ) )
|
||||
continue;
|
||||
|
||||
// add the item to the 'visible list'
|
||||
d->visibleItems.push_back( i );
|
||||
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdWarning() << "checking for pixmap for page " << i->pageNumber() << " = " << i->page()->hasPixmap( PAGEVIEW_ID, i->width(), i->height() ) << "\n";
|
||||
#endif
|
||||
kdWarning() << "checking for text for page " << i->pageNumber() << " = " << i->page()->hasSearchPage() << "\n";
|
||||
// if the item has not the right pixmap, add a request for it
|
||||
if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->width(), i->height() ) )
|
||||
{
|
||||
#ifdef PAGEVIEW_DEBUG
|
||||
kdWarning() << "rerequesting visible pixmaps for page " << i->pageNumber() << " !\n";
|
||||
#endif
|
||||
PixmapRequest * p = new PixmapRequest(
|
||||
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), i->rotation(), PAGEVIEW_PRIO, true );
|
||||
requestedPixmaps.push_back( p );
|
||||
|
@ -1995,8 +2258,9 @@ void PageView::slotRequestVisiblePixmaps( int newLeft, int newTop )
|
|||
|
||||
// send requests to the document
|
||||
if ( !requestedPixmaps.isEmpty() )
|
||||
{
|
||||
d->document->requestPixmaps( requestedPixmaps );
|
||||
|
||||
}
|
||||
// if this functions was invoked by viewport events, send update to document
|
||||
if ( isEvent && nearPageNumber != -1 )
|
||||
{
|
||||
|
@ -2102,12 +2366,17 @@ void PageView::slotFitToTextToggled( bool on )
|
|||
if ( on ) updateZoom( ZoomFitText );
|
||||
}
|
||||
|
||||
void PageView::slotTwoPagesToggled( bool on )
|
||||
void PageView::slotRenderMode( int nr )
|
||||
{
|
||||
uint newColumns = on ? 2 : 1;
|
||||
if ( KpdfSettings::viewColumns() != newColumns )
|
||||
uint newColumns;
|
||||
if (nr<2)
|
||||
newColumns = nr+1;
|
||||
else
|
||||
newColumns = KpdfSettings::viewColumns();
|
||||
|
||||
if ( KpdfSettings::renderMode() != nr )
|
||||
{
|
||||
KpdfSettings::setViewColumns( newColumns );
|
||||
KpdfSettings::setRenderMode( nr );
|
||||
KpdfSettings::writeConfig();
|
||||
if ( d->document->pages() > 0 )
|
||||
slotRelayoutPages();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <qscrollview.h>
|
||||
#include <qvaluevector.h>
|
||||
#include <qvaluelist.h>
|
||||
#include "ui/pageviewutils.h"
|
||||
#include "core/observer.h"
|
||||
|
||||
|
@ -116,8 +117,12 @@ class PageView : public QScrollView, public DocumentObserver
|
|||
void updateZoom( ZoomMode newZm );
|
||||
// update the text on the label using global zoom value or current page's one
|
||||
void updateZoomText();
|
||||
void textSelection( QValueList<QRect> * , const QColor & );
|
||||
void textSelectionClear();
|
||||
// updates cursor
|
||||
void updateCursor( const QPoint &p );
|
||||
int viewColumns();
|
||||
int viewRows();
|
||||
|
||||
// don't want to expose classes in here
|
||||
class PageViewPrivate * d;
|
||||
|
@ -141,7 +146,7 @@ class PageView : public QScrollView, public DocumentObserver
|
|||
void slotFitToWidthToggled( bool );
|
||||
void slotFitToPageToggled( bool );
|
||||
void slotFitToTextToggled( bool );
|
||||
void slotTwoPagesToggled( bool );
|
||||
void slotRenderMode( int );
|
||||
void slotContinuousToggled( bool );
|
||||
void slotSetMouseNormal();
|
||||
void slotSetMouseZoom();
|
||||
|
|
|
@ -86,8 +86,10 @@ class SmoothPathEngine : public AnnotatorEngine
|
|||
// start operation
|
||||
if ( type == Press && points.isEmpty() )
|
||||
{
|
||||
totalRect.left = totalRect.right = lastPoint.x = nX;
|
||||
totalRect.top = totalRect.bottom = lastPoint.y = nY;
|
||||
lastPoint.x = nX;
|
||||
lastPoint.y = nY;
|
||||
totalRect.left = totalRect.right = lastPoint.x;
|
||||
totalRect.top = totalRect.bottom = lastPoint.y;
|
||||
points.append( lastPoint );
|
||||
}
|
||||
// add a point to the path
|
||||
|
@ -248,10 +250,10 @@ class PickPointEngine : public AnnotatorEngine
|
|||
// update variables and extents (zoom invariant rect)
|
||||
point.x = nX;
|
||||
point.y = nY;
|
||||
rect.left = nX - (16.0 / (double)xScale);
|
||||
rect.right = nX + (17.0 / (double)xScale);
|
||||
rect.top = nY - (16.0 / (double)yScale);
|
||||
rect.bottom = nY + (17.0 / (double)yScale);
|
||||
rect.left = nX - (16.0 / (double)xScale) ;
|
||||
rect.right = nX + (17.0 / (double)xScale) ;
|
||||
rect.top = nY - (16.0 / (double)yScale) ;
|
||||
rect.bottom = nY + (17.0 / (double)yScale) ;
|
||||
return rect.geometry( (int)xScale, (int)yScale );
|
||||
}
|
||||
|
||||
|
@ -296,8 +298,10 @@ class TwoPointsEngine : public AnnotatorEngine
|
|||
if ( type == Press && points.isEmpty() )
|
||||
{
|
||||
NormalizedPoint newPoint;
|
||||
rect.left = rect.right = newPoint.x = nX;
|
||||
rect.top = rect.bottom = newPoint.y = nY;
|
||||
newPoint.x = nX;
|
||||
newPoint.y = nY;
|
||||
rect.left = rect.right =newPoint.x;
|
||||
rect.top = rect.bottom =newPoint.y;
|
||||
points.append( newPoint );
|
||||
return QRect();
|
||||
}
|
||||
|
@ -366,7 +370,7 @@ PageViewAnnotator::PageViewAnnotator( PageView * parent, KPDFDocument * storage
|
|||
m_toolBar( 0 ), m_engine( 0 ), m_lastToolID( -1 ), m_lockedItem( 0 )
|
||||
{
|
||||
// load the tools from the 'xml tools definition' file. store the tree internally.
|
||||
QFile infoFile( locate("data", "kpdf/tools.xml") );
|
||||
QFile infoFile( locate("data", "oKular/tools.xml") );
|
||||
if ( infoFile.exists() && infoFile.open( IO_ReadOnly ) )
|
||||
{
|
||||
QDomDocument doc( "annotatingTools" );
|
||||
|
|
Loading…
Reference in a new issue