Commit 451a3091 authored by Enrico Ros's avatar Enrico Ros

Opening kdpf_annotations branch. Code changes:

 User Interface: added a toolbox for selecting an annotation tool without
   polluting the toolbar (pageviewtoolbox animated widget). Icons of that
   toolbar are gimped version of ones in nuvola icontheme.
 Core: added annotation class. this will support all features (except for
   silly ones (really there are some!)) from pdf 1.6 specs but abstracted
   in the kdpf way. (api changes in progress...)

About annotations: only some incomplete interfaces are in plasefor now.
Every type of pdf annotations has tens of parameters. I think we'll render
correctly everything but provide only simple and useful tools for making
annotations over the pages, otherwise a 'Qt designer like' property view
will be required to do fine adjustment over the crappy thousands of
settings. (and we're aiming at a quick and simple viewer with lots of
coolness, not chaos).

Note: the code has been wrongly committed to HEAD before,but soon reverted.
Have fun!

svn path=/branches/kpdf_annotations/kdegraphics/kpdf/; revision=388768
parent 7883b068
......@@ -5,7 +5,8 @@ INCLUDES = -I$(srcdir)/generator_pdf -I$(srcdir)/.. -I$(srcdir)/../xpdf -I$(srcd
METASOURCES = AUTO
libkpdfcore_la_LIBADD = ./generator_pdf/libgeneratorpdf.la
libkpdfcore_la_SOURCES = document.cpp link.cpp page.cpp pagetransition.cpp
libkpdfcore_la_SOURCES = page.cpp document.cpp link.cpp annotations.cpp \
pagetransition.cpp
noinst_LTLIBRARIES = libkpdfcore.la
......
/***************************************************************************
* 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 <qrect.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qimage.h>
// local includes
#include "annotations.h"
Annotation::Annotation()
: NormalizedRect()
{
}
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 );
void overlayPaint( QPainter * painter );
void finalPaint( QPixmap * pixmap, MouseState mouseState );
*/
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef _KPDF_ANNOTATIONS_H_
#define _KPDF_ANNOTATIONS_H_
#include <qstring.h>
#include <qdatetime.h>
#include "page.h"
/**
* @short Base options for an annotation (highlight, stamp, boxes, ..).
*
* From PDFreferece v.1.6:
* An annotation associates an object such as a note, sound, or movie with a
* location on a page of a PDF document ...
*
* Inherited classes must modify protected variables as appropriate.
* Other fields in pdf reference we dropped here:
* -subtype, rectangle(we are a rect), border stuff
*/
class Annotation : public NormalizedRect
{
public:
Annotation();
virtual ~Annotation();
enum State { Creating, Modifying, Closed, Opened };
enum MouseState { Normal, Hovered, Pressed };
enum Flags { Hidden, NoOpenable, Print, Locked, ReadOnly };
State state() const { return m_state; }
const QString & text() const { return m_text; }
const QString & uniqueName() const { return m_uniqueName; }
const QDateTime & creationDate() const { return m_creationDate; }
const QDateTime & modifyDate() const { return m_modifyDate; }
const QColor & baseColor() const { return m_baseColor; }
// event handlers (must update state)
virtual void mousePressEvent( double x, double y, Qt::ButtonState b ) = 0;
virtual void mouseMoveEvent( double x, double y, Qt::ButtonState b ) = 0;
virtual void mouseReleaseEvent( double x, double y, Qt::ButtonState b ) = 0;
// paint roughtly over a cleared area
virtual void overlayPaint( QPainter * painter ) = 0;
// cool-paint over a pixmap
virtual void finalPaint( QPixmap * pixmap, MouseState mouseState ) = 0;
protected:
State m_state;
MouseState m_mouseState;
QString m_text;
QString m_uniqueName;
QDateTime m_modifyDate;
QColor m_baseColor;
private:
QDateTime m_creationDate;
};
class TextAnnotation : public Annotation
{
//Text (post-it like)
//FreeText (direct on page)
enum Type { InPlace, Popup };
};
class LineAnnotation : public Annotation
{
//Line (arrows too)
};
class GeomAnnotation : public Annotation
{
//Square, Circle
};
class PathAnnotation : public Annotation
{
//Ink (one or more disjoints paths)
//Polygon, PolyLine
};
class HighlightAnnotation : public Annotation
{
//Highlight, Underline, Squiggly, StrikeOut, BLOCK
enum BrushHor { Horizontal, Vertical };
};
class StampAnnotation : public Annotation
{
// (14 default symbols + ours)
};
class MediaAnnotation : public Annotation
{
//FileAttachment, Sound, Movie
enum Type { FileAttachment, Sound, Movie };
};
#endif
......@@ -260,7 +260,10 @@ void KPDFDocument::addObserver( DocumentObserver * pObserver )
// if the observer is added while a document is already opened, tell it
if ( !pages_vector.isEmpty() )
{
pObserver->notifySetup( pages_vector, true );
pObserver->notifyViewportChanged( false /*disables smoothMove*/ );
}
}
void KPDFDocument::removeObserver( DocumentObserver * pObserver )
......
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="kpdf_part" version="16">
<kpartgui name="kpdf_part" version="17">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Action name="save" group="file_save"/>
......@@ -61,5 +61,6 @@
<Action name="mouse_drag"/>
<Action name="mouse_zoom"/>
<Action name="mouse_select"/>
<Action name="mouse_edit"/>
</ToolBar>
</kpartgui>
SUBDIRS = icons
INCLUDES = -I$(srcdir)/.. -I$(top_builddir)/kpdf $(all_includes)
METASOURCES = AUTO
libkpdfui_la_SOURCES = pagepainter.cpp pageview.cpp pageviewutils.cpp \
minibar.cpp thumbnaillist.cpp searchwidget.cpp \
toc.cpp propertiesdialog.cpp presentationwidget.cpp
pageviewtoolbox.cpp minibar.cpp thumbnaillist.cpp \
searchwidget.cpp toc.cpp propertiesdialog.cpp \
presentationwidget.cpp
noinst_LTLIBRARIES = libkpdfui.la
......
icons_DATA = highlight_green.png highlight_orange.png highlight_pink.png \
highlight_yellow.png pencil.png pinnote.png
iconsdir = $(kde_datadir)/kpdf/pics
......@@ -44,6 +44,7 @@
// local includes
#include "pageview.h"
#include "pageviewutils.h"
#include "pageviewtoolbox.h"
#include "pagepainter.h"
#include "core/document.h"
#include "core/page.h"
......@@ -94,6 +95,7 @@ public:
bool blockViewport; // prevents changes to viewport
bool blockPixmapsRequest; // prevent pixmap requests
PageViewMessage * messageWindow; // in pageviewutils.h
PageViewEditTools * editToolsWindow;// in pageviewtoolbox.h
// actions
KToggleAction * aMouseNormal;
......@@ -142,6 +144,7 @@ PageView::PageView( QWidget *parent, KPDFDocument *document )
d->blockViewport = false;
d->blockPixmapsRequest = false;
d->messageWindow = new PageViewMessage(this);
d->editToolsWindow = 0;
d->aPrevAction = 0;
// widget setup: setup focus, accept drops and track mouse
......@@ -213,9 +216,8 @@ void PageView::setupActions( KActionCollection * ac )
d->aMouseSelect = new KRadioAction( i18n("&Select"), "frame_edit", 0, this, SLOT( slotSetMouseSelect() ), ac, "mouse_select" );
d->aMouseSelect->setExclusiveGroup( "MouseType" );
d->aMouseEdit = new KRadioAction( i18n("Draw"), "edit", 0, this, SLOT( slotSetMouseDraw() ), ac, "mouse_draw" );
d->aMouseEdit = new KRadioAction( i18n("&Review"), "pencil", 0, this, SLOT( slotSetMouseDraw() ), ac, "mouse_edit" );
d->aMouseEdit->setExclusiveGroup("MouseType");
d->aMouseEdit->setEnabled( false ); // implement feature before removing this line
// Other actions
KAction * su = new KAction( i18n("Scroll Up"), 0, this, SLOT( slotScrollUp() ), ac, "view_scroll_up" );
......@@ -539,12 +541,18 @@ void PageView::viewportPaintEvent( QPaintEvent * pe )
void PageView::viewportResizeEvent( QResizeEvent * )
{
// start a timer that will refresh the pixmap after 0.5s
if ( !d->delayResizeTimer )
if ( !d->items.isEmpty() )
{
d->delayResizeTimer = new QTimer( this );
connect( d->delayResizeTimer, SIGNAL( timeout() ), this, SLOT( slotRelayoutPages() ) );
if ( !d->delayResizeTimer )
{
d->delayResizeTimer = new QTimer( this );
connect( d->delayResizeTimer, SIGNAL( timeout() ), this, SLOT( slotRelayoutPages() ) );
}
d->delayResizeTimer->start( 333, true );
}
d->delayResizeTimer->start( 333, true );
// update geometry of tools slider widget (if any)
if ( d->editToolsWindow )
d->editToolsWindow->anchorChanged();
}
void PageView::keyPressEvent( QKeyEvent * e )
......@@ -1861,26 +1869,52 @@ void PageView::slotContinousToggled( bool on )
void PageView::slotSetMouseNormal()
{
d->mouseMode = MouseNormal;
// hide the messageWindow
d->messageWindow->hide();
// hide the 'tools overlay' if present
if ( d->editToolsWindow )
{
d->editToolsWindow->hideAndDestroy();
d->editToolsWindow = 0;
}
}
void PageView::slotSetMouseZoom()
{
d->mouseMode = MouseZoom;
// change the text in messageWindow (and show it if hidden)
d->messageWindow->display( i18n( "Select zooming area. Right-click to zoom out." ), PageViewMessage::Info, -1 );
// hide the 'tools overlay' if present
if ( d->editToolsWindow )
{
d->editToolsWindow->hideAndDestroy();
d->editToolsWindow = 0;
}
}
void PageView::slotSetMouseSelect()
{
d->mouseMode = MouseSelect;
// change the text in messageWindow (and show it if hidden)
d->messageWindow->display( i18n( "Draw a rectangle around the text/graphics to copy." ), PageViewMessage::Info, -1 );
// hide the 'tools overlay' if present
if ( d->editToolsWindow )
{
d->editToolsWindow->hideAndDestroy();
d->editToolsWindow = 0;
}
}
void PageView::slotSetMouseDraw()
{
d->mouseMode = MouseEdit;
d->aMouseEdit->setChecked( true );
// hide the messageWindow
d->messageWindow->hide();
// reuse a previous instance if present or create a new one
if ( d->editToolsWindow )
d->editToolsWindow->show();
else
d->editToolsWindow = new PageViewEditTools( this, viewport() );
}
void PageView::slotScrollUp()
......
......@@ -68,7 +68,7 @@ class PageView : public QScrollView, public DocumentObserver
void rightClick( const KPDFPage *, const QPoint & );
protected:
// main draw loop, draws pageViews on viewport
// viewport events
void viewportPaintEvent( QPaintEvent * pe );
void viewportResizeEvent( QResizeEvent* );
......
This diff is collapsed.
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef _KPDF_PAGEVIEWTOOLBOX_H_
#define _KPDF_PAGEVIEWTOOLBOX_H_
#include <qpushbutton.h>
class ToolboxItem;
class ToolboxButton;
/**
* @short A widget (containing exclusive buttons) that slides in from left/top.
*/
class PageViewToolbox : public QWidget
{
Q_OBJECT
public:
PageViewToolbox( QWidget * parent, QWidget * anchorWidget, bool isVertical );
void setItems( const QValueList<ToolboxItem> & items );
void show();
void hideAndDestroy();
void anchorChanged();
void paintEvent( QPaintEvent * );
void timerEvent( QTimerEvent * );
signals:
void toolSelected( int toolID );
private:
QPoint getStartPoint();
QPoint getEndPoint();
void buildGfx();
QWidget * m_anchor;
bool m_vertical;
QPoint m_currentPosition;
QPoint m_endPosition;
int m_timerID;
bool m_hiding;
QPixmap m_pixmap;
QValueList< ToolboxButton * > m_buttons;
private slots:
void slotButtonClicked();
};
class PageViewEditTools : public PageViewToolbox
{
public:
PageViewEditTools( QWidget * parent, QWidget * anchorWidget );
};
struct ToolboxItem
{
int id;
QString text;
QString pixmap;
ToolboxItem() {};
ToolboxItem( int _id, const QString & _text, const QString & _pixmap )
: id( _id ), text( _text ), pixmap( _pixmap ) {};
};
#endif
/***************************************************************************
* Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2004-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 *
......@@ -10,9 +10,7 @@
// qt/kde includes
#include <qbitmap.h>
#include <qpainter.h>
#include <qimage.h>
#include <qtimer.h>
#include <kimageeffect.h>
#include <kiconloader.h>
// local includes
......@@ -20,6 +18,65 @@
#include "core/page.h"
#include "conf/settings.h"
/** PageViewItem **/
PageViewItem::PageViewItem( const KPDFPage * page )
: m_page( page ), m_zoomFactor( 1.0 )
{
}
const KPDFPage * PageViewItem::page() const
{
return m_page;
}
int PageViewItem::pageNumber() const
{
return m_page->number();
}
const QRect& PageViewItem::geometry() const
{
return m_geometry;
}
int PageViewItem::width() const
{
return m_geometry.width();
}
int PageViewItem::height() const
{
return m_geometry.height();
}
double PageViewItem::zoomFactor() const
{
return m_zoomFactor;
}
void PageViewItem::setGeometry( int x, int y, int width, int height )
{
m_geometry.setRect( x, y, width, height );
}
void PageViewItem::setWHZ( int w, int h, double z )
{
m_geometry.setWidth( w );
m_geometry.setHeight( h );
m_zoomFactor = z;
}
void PageViewItem::moveTo( int x, int y )
{
m_geometry.moveLeft( x );
m_geometry.moveTop( y );
}
/** PageViewMessage **/
PageViewMessage::PageViewMessage( QWidget * parent )
: QWidget( parent, "pageViewMessage" ), m_timer( 0 )
{
......@@ -122,8 +179,8 @@ void PageViewMessage::display( const QString & message, Icon icon, int durationM
void PageViewMessage::paintEvent( QPaintEvent * e )
{
QPainter p( this );
p.drawPixmap( e->rect().topLeft(), m_pixmap, e->rect() );
// paint the internal pixmap over the widget
bitBlt( this, e->rect().topLeft(), &m_pixmap, e->rect() );
}
void PageViewMessage::mousePressEvent( QMouseEvent * /*e*/ )
......@@ -132,58 +189,3 @@ void PageViewMessage::mousePressEvent( QMouseEvent * /*e*/ )
m_timer->stop();
hide();
}
PageViewItem::PageViewItem( const KPDFPage * page )
: m_page( page ), m_zoomFactor( 1.0 )
{
}
const KPDFPage * PageViewItem::page() const
{
return m_page;
}
int PageViewItem::pageNumber() const
{
return m_page->number();
}
const QRect& PageViewItem::geometry() const
{
return m_geometry;
}
int PageViewItem::width() const
{
return m_geometry.width();
}
int PageViewItem::height() const
{
return m_geometry.height();
}
double PageViewItem::zoomFactor() const
{
return m_zoomFactor;
}
void PageViewItem::setGeometry( int x, int y, int width, int height )
{
m_geometry.setRect( x, y, width, height );
}
void PageViewItem::setWHZ( int w, int h, double z )
{
m_geometry.setWidth( w );
m_geometry.setHeight( h );
m_zoomFactor = z;
}
void PageViewItem::moveTo( int x, int y )
{
m_geometry.moveLeft( x );
m_geometry.moveTop( y );
}
/***************************************************************************
* Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2004-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 *
......@@ -7,17 +7,14 @@
* (at your option) any later version. *
***************************************************************************/
#ifndef _PAGEVIEW_UTILS_H
#define _PAGEVIEW_UTILS_H
#ifndef _PAGEVIEW_UTILS_H_
#define _PAGEVIEW_UTILS_H_
#include <qwidget.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <qrect.h>
class QTimer;
class PageView;
class KPDFPage;
/**
......@@ -51,6 +48,10 @@ class PageViewItem
/**
* @short A widget that displays messages in the top-left corner.
*
* This is a widget with thin border and rounded corners that displays a given
* text along as an icon. It's meant to be used for displaying messages to the
* user by placing this above other widgets.
*/
class PageViewMessage : public QWidget
{
......
......@@ -78,19 +78,11 @@ PresentationWidget::PresentationWidget( KPDFDocument * doc )
connect( m_transitionTimer, SIGNAL( timeout() ), this, SLOT( slotTransitionStep() ) );
m_overlayHideTimer = new QTimer( this );
connect( m_overlayHideTimer, SIGNAL( timeout() ), this, SLOT( slotHideOverlay() ) );
m_advanceTimer = new QTimer( this );
connect( m_advanceTimer, SIGNAL( timeout() ), this, SLOT( slotNextPage() ) );
// register this observer in document
m_document->addObserver( this );
// show widget and take control
showFullScreen();
if ( Settings::slidesShowSummary() )
generatePage();
else
slotNextPage();
// handle cursor appearance as specified in configuration
if ( Settings::slidesCursor() == Settings::EnumSlidesCursor::HiddenDelay )
{
KCursor::setAutoHideCursor( this, true );
......@@ -100,6 +92,13 @@ PresentationWidget::PresentationWidget( KPDFDocument * doc )
{
setCursor( KCursor::blankCursor() );
}
// register this observer in document. events will come immediately
m_document->addObserver( this );
// show summary if requested
if ( Settings::slidesShowSummary() )
generatePage();
}
PresentationWidget::~PresentationWidget()
......@@ -107,6 +106,10 @@ PresentationWidget::~PresentationWidget()
// remove this widget from document observer
m_document->removeObserver( this );
// set a new viewport in document if page number differs
if ( m_frameIndex != -1 && m_frameIndex != m_document->viewport().pageNumber )
m_document->setViewportPage( m_frameIndex/*, PRESENTATION_ID*/ );
// delete frames
QValueVector< PresentationFrame * >::iterator fIt = m_frames.begin(), fEnd = m_frames.end();
for ( ; fIt != fEnd; ++fIt )
......@@ -162,7 +165,16 @@ void PresentationWidget::notifySetup( const QValueVector< KPDFPage * > & pageSet
void PresentationWidget::notifyViewportChanged( bool /*smoothMove*/ )
{
changePage( m_document->viewport().pageNumber );
// discard notifications if displaying the summary
if ( m_frameIndex == -1 && Settings::slidesShowSummary() )
return;
// display the current page
changePage( m_document->viewport().pageNumber );
// auto advance to the next page if set
if ( Settings::slidesAdvance() )
QTimer::singleShot( Settings::slidesAdvanceTime() * 1000, this, SLOT( slotNextPage() ) );
}