Commit a12cc5e5 authored by Enrico Ros's avatar Enrico Ros

Getting ready for HEAD merge of parts of the stuff.

pageviewtoolbox.cpp/.h: Removed.
PageViewToolBar (was PageViewToolbox): Moved def/impl inside the
  pageviewutils.c/.h files. Uses eventfilter to get notified when the
  anchorWidget changes in size. Cleaned up code.
Annotations: added empty code.
PageView: removed some code. fixed rmb popup menu hidden if no document
  was opened.
Updated TODO.

svn path=/branches/kpdf_annotations/kdegraphics/kpdf/; revision=393302
parent b2ed18c6
......@@ -48,6 +48,7 @@ More items (first items will enter 'In progress list' first):
-> text selection in wordprocessor style (very hard, not impossible)
-> zoom: fit text (with configurable margin)
-> bookview: 3d opengl widget for viewing the document as a real book (turning pages, etc..)
-> wallet: use asynchronous interface (to prevent ui-blocking)
-> open gzipped (.pdf.gz?) files
-> kspeech TTS interface. speech {document(missing) / page(missing) / selection(done)}
-> automatic online dictionaries / translators (BR80338)
......@@ -74,6 +75,7 @@ More items (first items will enter 'In progress list' first):
-> cleanup code and update README.png
Done (newest features come first):
-> FIX: rmb when no doc displayed to restore menu
-> ADD: google-like search on thumbnails
-> ADD: use kde wallet for storing passwords of protected files
-> The branch 'kpdf_annotations' was created at this point. [2005-Feb-12]
......
......@@ -62,7 +62,7 @@
<default>true</default>
</entry>
<entry key="SplitterSizes" type="IntList" />
<entry key="EditToolboxPlacement" type="Int" >
<entry key="EditToolBarPlacement" type="Int" >
<default>0</default>
</entry>
</group>
......
......@@ -29,13 +29,161 @@ Annotation::~Annotation()
{
}
/*
void mousePressEvent( double x, double y, Qt::ButtonState b );
void mouseMoveEvent( double x, double y, Qt::ButtonState b );
void mouseReleaseEvent( double x, double y, Qt::ButtonState b );
bool mouseEvent( MouseEvent e, double x, double y, Qt::ButtonState b );
void overlayPaint( QPainter * painter );
void finalPaint( QPixmap * pixmap, MouseState mouseState );
void overlayPaint( QPainter * )
void finalPaint( QPixmap *, MouseState )
*/
/** Text **/
TextAnnotation::TextAnnotation( Type type )
: Annotation(), m_type( type )
{
}
QString TextAnnotation::usageTip() const
{
if ( m_type == InPlace )
return i18n( "A..." );
//else m_type == Popup
return i18n( "B..." );
}
bool TextAnnotation::mouseEvent( MouseEvent, double, double, Qt::ButtonState )
{
return false;
}
void TextAnnotation::paintOverlay( QPainter *, int, int, const QRect & )
{
}
void TextAnnotation::paintFinal( QImage &, int, int, const QRect & )
{
}
/** Line **/
LineAnnotation::LineAnnotation( Type type )
: Annotation(), m_type( type )
{
}
QString LineAnnotation::usageTip() const
{
return i18n( "Draw a line between A and Br" );
}
bool LineAnnotation::mouseEvent( MouseEvent, double, double, Qt::ButtonState )
{
return false;
}
void LineAnnotation::paintOverlay( QPainter *, int, int, const QRect & )
{
}
void LineAnnotation::paintFinal( QImage &, int, int, const QRect & )
{
}
/** Path **/
PathAnnotation::PathAnnotation( Type type )
: Annotation(), m_type( type )
{
}
QString PathAnnotation::usageTip() const
{
if ( m_type == Ink )
return i18n( "Use the mouse as an ink pen." );
//else if m_type == Poly
return i18n( "Press --describe me--." );
}
bool PathAnnotation::mouseEvent( MouseEvent e, double x, double y, Qt::ButtonState b )
{
// only process events if left button pressed
if ( b != Qt::LeftButton )
return false;
// start operation
if ( e == MousePress && m_state == NewBorn )
{
FloatPoint newPoint;
left = right = newPoint.x = x;
top = bottom = newPoint.y = y;
m_points.append( newPoint );
m_state = Creating;
return false;
}
// add a point to the path, TODO inline redundancy suppression
else if ( e == MouseMove && m_state == Creating )
{
double dist = hypot( x - m_points.last().x, y - m_points.last().y );
if ( dist < 0.02 )
return false;
left = QMIN( left, x );
top = QMIN( y, top );
right = QMAX( x, right );
bottom = QMAX( y, bottom );
FloatPoint newPoint;
newPoint.x = x;
newPoint.y = y;
m_points.append( newPoint );
return true;
}
// terminate precess
else if ( e == MouseRelease && m_state == Creating )
{
if ( m_points.count() > 2 )
m_state = Opened;
else
m_state = NewBorn;
return false;
}
// nothing change -> don't update gfx
return false;
}
void PathAnnotation::paintOverlay( QPainter * painter, int xScale, int yScale, const QRect & limits )
{
// draw annotations whith at least 2 points
if ( m_points.count() < 2 )
return;
// use basecolor
painter->setPen( QPen(m_baseColor, 3) );
// perform a rought paint drawing meanline only
//const QRect myRect = geometry( xScale, yScale );
QValueList<FloatPoint>::iterator pIt = m_points.begin(), pEnd = m_points.end();
FloatPoint pA = *pIt;
++pIt;
for ( ; pIt != pEnd; ++pIt )
{
FloatPoint pB = *pIt;
painter->drawLine( (int)(pA.x * (double)xScale), (int)(pA.y * (double)yScale),
(int)(pB.x * (double)xScale), (int)(pB.y * (double)yScale) );
pA = pB;
}
}
void PathAnnotation::paintFinal( QImage & /*backImage*/, int /*xScale*/, int /*yScale*/, const QRect & /*limits*/ )
{
// use m_type for painting
}
/** Highlight **/
HighlightAnnotation::HighlightAnnotation( Type type )
: Annotation(), m_type( type )
{
......@@ -110,9 +258,6 @@ void HighlightAnnotation::paintOverlay( QPainter * painter, int xScale, int ySca
for ( ; pIt != pEnd; ++pIt )
{
FloatPoint pB = *pIt;
// painter->setPen( QPen(Qt::black, 2) );
// painter->drawLine( (int)(pA.x * (double)xScale)+1, (int)(pA.y * (double)yScale)+1,
// (int)(pB.x * (double)xScale)+1, (int)(pB.y * (double)yScale)+1 );
painter->drawLine( (int)(pA.x * (double)xScale), (int)(pA.y * (double)yScale),
(int)(pB.x * (double)xScale), (int)(pB.y * (double)yScale) );
pA = pB;
......
......@@ -70,33 +70,64 @@ class Annotation : public NormalizedRect
QDateTime m_creationDate;
};
struct FloatPoint {
double x, y;
};
class TextAnnotation : public Annotation
{
public:
enum Type { InPlace, Popup };
TextAnnotation( Type type );
// [Annotation] inherited methods
QString usageTip() const;
bool mouseEvent( MouseEvent e, double x, double y, Qt::ButtonState b );
void paintOverlay( QPainter * painter, int xScale, int yScale, const QRect & limits );
void paintFinal( QImage & backImage, int xScale, int yScale, const QRect & limits );
//Text (post-it like)
//FreeText (direct on page)
enum Type { InPlace, Popup };
private:
Type m_type;
};
class LineAnnotation : public Annotation
{
//Line (arrows too)
public:
enum Type { Line, DestArrow, SrcArrow, BiArrow };
LineAnnotation( Type type );
// [Annotation] inherited methods
QString usageTip() const;
bool mouseEvent( MouseEvent e, double x, double y, Qt::ButtonState b );
void paintOverlay( QPainter * painter, int xScale, int yScale, const QRect & limits );
void paintFinal( QImage & backImage, int xScale, int yScale, const QRect & limits );
private:
Type m_type;
};
class GeomAnnotation : public Annotation
{
//Square, Circle
//Square, Circle, Polygon
};
class PathAnnotation : public Annotation
{
//Ink (one or more disjoints paths)
//Polygon, PolyLine
};
//Ink (one or more disjoints paths), Polygon, PolyLine
public:
enum Type { Ink, PolyLine };
PathAnnotation( Type type );
struct FloatPoint
{
double x, y;
// [Annotation] inherited methods
QString usageTip() const;
bool mouseEvent( MouseEvent e, double x, double y, Qt::ButtonState b );
void paintOverlay( QPainter * painter, int xScale, int yScale, const QRect & limits );
void paintFinal( QImage & backImage, int xScale, int yScale, const QRect & limits );
private:
Type m_type;
QValueList<FloatPoint> m_points;
};
class HighlightAnnotation : public Annotation
......
......@@ -5,9 +5,8 @@ INCLUDES = -I$(srcdir)/.. -I$(top_builddir)/kpdf $(all_includes)
METASOURCES = AUTO
libkpdfui_la_SOURCES = pagepainter.cpp pageview.cpp pageviewutils.cpp \
pageviewtoolbox.cpp minibar.cpp thumbnaillist.cpp \
searchwidget.cpp toc.cpp propertiesdialog.cpp \
presentationwidget.cpp
minibar.cpp thumbnaillist.cpp searchwidget.cpp\
toc.cpp propertiesdialog.cpp presentationwidget.cpp
noinst_LTLIBRARIES = libkpdfui.la
......
......@@ -44,7 +44,6 @@
// local includes
#include "pageview.h"
#include "pageviewutils.h"
#include "pageviewtoolbox.h"
#include "pagepainter.h"
#include "core/document.h"
#include "core/page.h"
......@@ -550,19 +549,16 @@ void PageView::viewportPaintEvent( QPaintEvent * pe )
void PageView::viewportResizeEvent( QResizeEvent * )
{
if ( d->items.isEmpty() )
return;
// start a timer that will refresh the pixmap after 0.5s
if ( !d->items.isEmpty() )
if ( !d->delayResizeTimer )
{
if ( !d->delayResizeTimer )
{
d->delayResizeTimer = new QTimer( this );
connect( d->delayResizeTimer, SIGNAL( timeout() ), this, SLOT( slotRelayoutPages() ) );
}
d->delayResizeTimer->start( 333, true );
d->delayResizeTimer = new QTimer( this );
connect( d->delayResizeTimer, SIGNAL( timeout() ), this, SLOT( slotRelayoutPages() ) );
}
// update geometry of tools slider widget (if any)
if ( d->editToolsWindow )
d->editToolsWindow->anchorChanged();
d->delayResizeTimer->start( 333, true );
}
void PageView::keyPressEvent( QKeyEvent * e )
......@@ -875,9 +871,14 @@ void PageView::contentsMousePressEvent( QMouseEvent * e )
void PageView::contentsMouseReleaseEvent( QMouseEvent * e )
{
// don't perform any mouse action when no document is shown
// don't perform any mouse action when no document is shown..
if ( d->items.isEmpty() )
{
// ..except for right Clicks (emitted even it viewport is empty)
if ( e->button() == RightButton )
emit rightClick( 0, e->globalPos() );
return;
}
// don't perform any mouse action when viewport is autoscrolling
if ( d->viewportMoveActive )
......@@ -1937,6 +1938,15 @@ void PageView::slotSetAnnotationTool( int toolID )
}
// [take a look at pageviewtoolbox.cpp for toolIDs]
if ( toolID == 1 )
d->localAnnotation = new TextAnnotation( TextAnnotation::InPlace );
else if ( toolID == 2 )
d->localAnnotation = new HighlightAnnotation( HighlightAnnotation::Highlight );
else if ( toolID == 3 )
d->localAnnotation = new PathAnnotation( PathAnnotation::Ink );
else
d->localAnnotation = new LineAnnotation( LineAnnotation::Line );
/*
d->localAnnotation = new HighlightAnnotation( HighlightAnnotation::Highlight );
if ( toolID == 2 )
d->localAnnotation->setBaseColor( Qt::yellow );
......@@ -1946,7 +1956,7 @@ void PageView::slotSetAnnotationTool( int toolID )
d->localAnnotation->setBaseColor( Qt::green );
else
d->localAnnotation->setBaseColor( Qt::black );
*/
// display usage tip of the tool
d->messageWindow->display( d->localAnnotation->usageTip(), PageViewMessage::Annotation );
}
......
/***************************************************************************
* Copyright (C) 2005 by Enrico Ros <eros.kde@email.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
// qt/kde includes
#include <qbitmap.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qpainter.h>
#include <qtimer.h>
#include <qtooltip.h>
#include <kiconloader.h>
#include <kimageeffect.h>
#include <klocale.h>
#include <kdeversion.h>
#include <kaccelmanager.h>
#include <kdebug.h>
// system includes
#include <math.h>
// local includes
#include "pageviewtoolbox.h"
#include "conf/settings.h"
/** ToolboxButton **/
static const int ToolboxButtonIcon = 32;
static const int ToolboxButtonSize = 40;
// a flat button that enlights on hover and has an ID
class ToolboxButton : public QPushButton
{
public:
ToolboxButton( QWidget * parent, const ToolboxItem & item, const QPixmap & backPixmap );
int toolboxID() const;
protected:
void mouseMoveEvent( QMouseEvent * e );
void mouseReleaseEvent( QMouseEvent * e );
void paintEvent( QPaintEvent * e );
private:
int m_id;
bool m_hovering;
const QPixmap & m_background;
};
ToolboxButton::ToolboxButton( QWidget * parent, const ToolboxItem & item, const QPixmap & pix )
: QPushButton( parent ), m_id( item.id ), m_hovering( false ), m_background( pix )
{
setMouseTracking( true );
setToggleButton( true );
resize( ToolboxButtonSize, ToolboxButtonSize );
setPixmap( DesktopIcon( item.pixmap, ToolboxButtonIcon ) );
QToolTip::add( this, item.text );
setWFlags( Qt::WNoAutoErase );
#if KDE_IS_VERSION(3,3,90)
KAcceleratorManager::setNoAccel( this );
#endif
}
int ToolboxButton::toolboxID() const
{
return m_id;
}
void ToolboxButton::mouseMoveEvent( QMouseEvent * e )
{
// check for mouse hovering
const QRect myGeom( 0,0, width(), height() );
bool hover = myGeom.contains( e->pos() );
// if hover state changed update gfx
if ( m_hovering != hover )
{
m_hovering = hover;
update();
}
}
void ToolboxButton::mouseReleaseEvent( QMouseEvent * e )
{
// call default handler
QPushButton::mouseReleaseEvent( e );
// reset hover state when clicking
m_hovering = false;
update();
}
void ToolboxButton::paintEvent( QPaintEvent * e )
{
// always not hovering in disabled state
if ( !isEnabled() )
m_hovering = false;
// paint button in different flavours
if ( isOn() || m_hovering )
{
// if the button is pressed or we're hovering it, use QPushButton style
QPushButton::paintEvent( e );
}
else
{
// else draw button's pixmap over the parent's background (fake transparency)
QPainter p( this );
QRect backRect = e->rect();
backRect.moveBy( x(), y() );
p.drawPixmap( e->rect().topLeft(), m_background, backRect );
drawButtonLabel( &p );
}
}
/** PageViewToolbox **/
static const int ToolboxGridSize = 40;
static const int AnchorRBMargin = 2;
PageViewToolbox::PageViewToolbox( QWidget * parent, QWidget * anchorWidget )
: QWidget( parent, "", Qt::WNoAutoErase ), m_anchor( anchorWidget ),
m_side( Left ), m_timerID( 0 ), m_hiding( false )
{
}
void PageViewToolbox::showItems( Side side, const QValueList<ToolboxItem> & items )
{
// cache side
m_side = side;
// delete buttons if already present
if ( !m_buttons.isEmpty() )
{
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end();
for ( ; it != end; ++it )
delete *it;
m_buttons.clear();
}
// create new buttons for given items
QValueList<ToolboxItem>::const_iterator it = items.begin(), end = items.end();
for ( ; it != end; ++it )
{
ToolboxButton * button = new ToolboxButton( this, *it, m_pixmap );
connect( button, SIGNAL( clicked() ), this, SLOT( slotButtonClicked() ) );
m_buttons.append( button );
}
// rebuild pixmap and mask
buildGfx();
QWidget::show();
// set scroll parameters
m_hiding = false;
m_currentPosition = getStartPoint();
m_endPosition = getEndPoint();
move( m_currentPosition );
// start scrolling in
if ( m_timerID )
killTimer( m_timerID );
m_timerID = startTimer( 20 );
}
void PageViewToolbox::hideAndDestroy()
{
// set scroll parameters
m_hiding = true;
m_endPosition = getStartPoint();
// start scrolling out
if ( m_timerID )
killTimer( m_timerID );
m_timerID = startTimer( 10 );
}
void PageViewToolbox::anchorChanged()
{
// stop timer
if ( m_timerID )
{
killTimer( m_timerID );
m_timerID = 0;
}
// if was hiding delete this
if ( m_hiding )
delete this;
else
showFinal();
}
void PageViewToolbox::mousePressEvent( QMouseEvent * e )
{
// set 'dragging' cursor
if ( e->button() == Qt::LeftButton )
setCursor( sizeAllCursor );
}
void PageViewToolbox::mouseMoveEvent( QMouseEvent * e )
{
if ( e->state() != Qt::LeftButton )
return;
// compute the nearest side
QPoint parentPos = mapToParent( e->pos() );
float nX = (float)parentPos.x() / (float)m_anchor->width(),
nY = (float)parentPos.y() / (float)m_anchor->height();
if ( nX > 0.3 && nX < 0.7 && nY > 0.3 && nY < 0.7 )
return;
bool LT = nX < (1.0 - nY);
bool LB = nX < (nY);
Side side = LT ? ( LB ? Left : Top ) : ( LB ? Bottom : Right );
// if side changed, update stuff
if ( side != m_side )
{
// inform subclasses about orientation change
orientationChanged( m_side = side );
// rebuild and display the widget
showFinal();
}
}
void PageViewToolbox::mouseReleaseEvent( QMouseEvent * e )
{
// set normal cursor
if ( e->button() == Qt::LeftButton )
setCursor( arrowCursor );
}
void PageViewToolbox::paintEvent( QPaintEvent * e )
{
// paint the internal pixmap over the widget
bitBlt( this, e->rect().topLeft(), &m_pixmap, e->rect() );
}
void PageViewToolbox::timerEvent( QTimerEvent * )
{
// move currentPosition towards endPosition
int dX = m_endPosition.x() - m_currentPosition.x(),
dY = m_endPosition.y() - m_currentPosition.y();
dX = dX / 6 + QMAX( -1, QMIN( 1, dX) );
dY = dY / 6 + QMAX( -1, QMIN( 1, dY) );
m_currentPosition.setX( m_currentPosition.x() + dX );
m_currentPosition.setY( m_currentPosition.y() + dY );
// move the widget
move( m_currentPosition );
// handle arrival to the end
if ( m_currentPosition == m_endPosition )
{
killTimer( m_timerID );
m_timerID = 0;
if ( m_hiding )
delete this;
}
}
void PageViewToolbox::showFinal()
{
// the following gives a better gfx result on repositioning, but ends
// drag operation
//QWidget::hide();
// rebuild widget and move it to its final place
buildGfx();
m_currentPosition = getEndPoint();
move( m_currentPosition );
// repaint all buttons (to update background)
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end();
for ( ; it != end; ++it )
(*it)->update();