📄 pageviewannotator.cpp.svn-base
字号:
/*************************************************************************** * 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 <qfile.h>#include <qcolor.h>#include <qevent.h>#include <qpainter.h>#include <kiconloader.h>#include <klocale.h>#include <kstandarddirs.h>#include <kinputdialog.h>#include <kuser.h>#include <kdebug.h>#include <kmenu.h>// system includes#include <math.h>// local includes#include "core/document.h"#include "core/page.h"#include "core/annotations.h"#include "settings.h"#include "pageview.h"#include "pageviewutils.h"#include "pageviewannotator.h"/** * @short Engine: filter events to distill an Annotation. */class AnnotatorEngine{ public: AnnotatorEngine( const QDomElement & engineElement ) : m_engineElement( engineElement ), m_creationCompleted( false ) { // parse common engine attributes if ( engineElement.hasAttribute( "color" ) ) m_engineColor = QColor( engineElement.attribute( "color" ) ); } virtual ~AnnotatorEngine() {}; // enum definitions enum EventType { Press, Move, Release }; enum Button { None, Left, Right }; // perform operations virtual QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale ) = 0; virtual void paint( QPainter * painter, double xScale, double yScale, const QRect & clipRect ) = 0; virtual Annotation * end() = 0; // query creation state //PageViewItem * editingItem() const { return m_lockedItem; } bool creationCompleted() const { return m_creationCompleted; } protected: // common engine attributes (the element includes annotation desc) QDomElement m_engineElement; QColor m_engineColor; // other vars (remove this!) bool m_creationCompleted;};/** @short SmoothPathEngine */class SmoothPathEngine : public AnnotatorEngine{ public: SmoothPathEngine( const QDomElement & engineElement ) : AnnotatorEngine( engineElement ) { // parse engine specific attributes } QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale ) { // only proceed if pressing left button if ( button != Left ) return QRect(); // start operation if ( type == Press && points.isEmpty() ) { 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 else if ( type == Move && points.count() > 0 ) { //double dist = hypot( nX - points.last().x, nY - points.last().y ); //if ( dist > 0.0001 ) //{ // append mouse position (as normalized point) to the list NormalizedPoint nextPoint = NormalizedPoint( nX, nY ); points.append( nextPoint ); // update total rect double dX = 2.0 / (double)xScale; double dY = 2.0 / (double)yScale; totalRect.left = qMin( totalRect.left, nX - dX ); totalRect.top = qMin( totalRect.top, nY - dY ); totalRect.right = qMax( nX + dX, totalRect.right ); totalRect.bottom = qMax( nY + dY, totalRect.bottom ); // paint the difference to previous full rect NormalizedRect incrementalRect; incrementalRect.left = qMin( nextPoint.x, lastPoint.x ) - dX; incrementalRect.right = qMax( nextPoint.x, lastPoint.x ) + dX; incrementalRect.top = qMin( nextPoint.y, lastPoint.y ) - dY; incrementalRect.bottom = qMax( nextPoint.y, lastPoint.y ) + dY; lastPoint = nextPoint; return incrementalRect.geometry( (int)xScale, (int)yScale ); //} } // terminate process else if ( type == Release && points.count() > 0 ) { if ( points.count() < 2 ) points.clear(); else m_creationCompleted = true; return totalRect.geometry( (int)xScale, (int)yScale ); } return QRect(); } void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ ) { // draw SmoothPaths with at least 2 points if ( points.count() > 1 ) { // use engine's color for painting painter->setPen( QPen( m_engineColor, 1 ) ); QLinkedList<NormalizedPoint>::iterator pIt = points.begin(), pEnd = points.end(); NormalizedPoint pA = *pIt; ++pIt; for ( ; pIt != pEnd; ++pIt ) { NormalizedPoint 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; } } } Annotation * end() { // find out annotation's description node const QDomElement & annElement = m_engineElement.firstChild().toElement(); if ( annElement.isNull() || annElement.tagName() != "annotation" ) return 0; // find out annotation's type Annotation * ann = 0; QString typeString = annElement.attribute( "type" ); // create HighlightAnnotation from path if ( typeString == "Highlight" ) { HighlightAnnotation * ha = new HighlightAnnotation(); ann = ha; // TODO } // create InkAnnotation from path else if ( typeString == "Ink" ) { InkAnnotation * ia = new InkAnnotation(); ann = ia; if ( annElement.hasAttribute( "width" ) ) ann->style.width = annElement.attribute( "width" ).toDouble(); // fill points ia->inkPaths.append( points ); // set boundaries ia->boundary = totalRect; } // safety check if ( !ann ) return 0; // set common attributes ann->style.color = annElement.hasAttribute( "color" ) ? annElement.attribute( "color" ) : m_engineColor; if ( annElement.hasAttribute( "opacity" ) ) ann->style.opacity = annElement.attribute( "opacity" ).toDouble(); // return annotation return ann; } private: // data QLinkedList<NormalizedPoint> points; NormalizedRect totalRect; NormalizedPoint lastPoint;};/** @short PickPointEngine */class PickPointEngine : public AnnotatorEngine{ public: PickPointEngine( const QDomElement & engineElement ) : AnnotatorEngine( engineElement ), clicked( false ), xscale(1.0), yscale(1.0) { // parse engine specific attributes QString pixmapName = engineElement.attribute( "hoverIcon" ); if ( pixmapName.isNull() ) pixmapName = "okular"; // create engine objects pixmap = new QPixmap( DesktopIcon( "okular", 32 ) ); } ~PickPointEngine() { delete pixmap; } QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale ) { xscale=xScale; yscale=yScale; // only proceed if pressing left button if ( button != Left ) return QRect(); // start operation on click if ( type == Press && clicked == false ) { clicked = true; startpoint.x=nX; startpoint.y=nY; } // repaint if moving while pressing else if ( type == Move && clicked == true ) { } // operation finished on release else if ( type == Release && clicked == true ) { m_creationCompleted = true; } else return QRect(); // 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) ; return rect.geometry( (int)xScale, (int)yScale ); } void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ ) { if ( clicked && pixmap ) { int pX = (int)(point.x * (double)xScale); int pY = (int)(point.y * (double)yScale); painter->drawPixmap( pX - 15, pY - 15, *pixmap ); } } Annotation * end() { // find out annotation's description node const QDomElement & annElement = m_engineElement.firstChild().toElement(); if ( annElement.isNull() || annElement.tagName() != "annotation" ) return 0; // find out annotation's type Annotation * ann = 0; QString typeString = annElement.attribute( "type" ); // create TextAnnotation from path if ( typeString == "FreeText") //<annotation type="Text" { //note dialog QString prompt = i18n( "Please input the free text:" ) ; bool resok; QString note =""; note= KInputDialog::getText( i18n("FreeText"), prompt, note,&resok ); if(resok) { //add note TextAnnotation * ta = new TextAnnotation(); ann = ta; ta->inplaceText=note; ta->textType = TextAnnotation::InPlace; //set boundary QFontMetricsF mf(ta->textFont); QRectF rcf=mf.boundingRect(ta->inplaceText); rect.left = qMin(startpoint.x,point.x); rect.top = qMin(startpoint.y,point.y); rect.right = qMax(startpoint.x,point.x); rect.bottom = qMax(startpoint.y,point.y); kDebug()<<"astario: xyScale="<<xscale<<","<<yscale<<endl; double pixfactor=0.002; rect.right = qMax(rect.right, rect.left+rcf.width()*pixfactor); rect.bottom = qMax(rect.bottom, rect.top+rcf.height()*pixfactor*xscale/yscale); ta->boundary=this->rect; ta->window.summary="TextBox"; } } else if ( typeString == "Text") { TextAnnotation * ta = new TextAnnotation(); ann = ta; ta->textType = TextAnnotation::Linked; ta->window.text=""; //ta->window.flags &= ~(Annotation::Hidden); ta->textIcon="comment"; double iconhei=0.03; rect.left = point.x; rect.top = point.y; rect.right=rect.left+iconhei; rect.bottom=rect.top+iconhei*xscale/yscale; ta->boundary=this->rect; ta->window.summary="Note"; } // create StampAnnotation from path else if ( typeString == "Stamp" ) { StampAnnotation * sa = new StampAnnotation(); ann = sa; sa->stampIconName="okular"; } // safety check if ( !ann ) return 0; // set common attributes ann->style.color = annElement.hasAttribute( "color" ) ? annElement.attribute( "color" ) : m_engineColor; if ( annElement.hasAttribute( "opacity" ) ) ann->style.opacity = annElement.attribute( "opacity" ).toDouble(); ann->creationDate=ann->modifyDate=QDateTime::currentDateTime(); // return annotation return ann; } private: bool clicked; NormalizedRect rect; NormalizedPoint startpoint; NormalizedPoint point; QPixmap * pixmap; double xscale,yscale;};/** @short TwoPointsEngine */class TwoPointsEngine : public AnnotatorEngine{ public: TwoPointsEngine( const QDomElement & engineElement ) : AnnotatorEngine( engineElement ) { // parse engine specific attributes m_block = engineElement.attribute( "block" ) == "true"; } QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale ) { // only proceed if pressing left button if ( button != Left ) return QRect(); // start operation if ( type == Press && points.isEmpty() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -