📄 pageviewannotator.cpp.svn-base
字号:
NormalizedPoint newPoint; newPoint.x = nX; newPoint.y = nY; rect.left = rect.right =newPoint.x; rect.top = rect.bottom =newPoint.y; points.append( newPoint ); return QRect(); } // move the second point else if ( type == Move && !points.isEmpty() ) { if ( points.count() == 2 ) points.pop_back(); NormalizedPoint newPoint; newPoint.x = nX; newPoint.y = nY; points.append( newPoint ); NormalizedPoint firstPoint = points.front(); rect.left = qMin( firstPoint.x, nX ) - 2.0 / (double)xScale; rect.right = qMax( firstPoint.x, nX ) + 2.0 / (double)xScale; rect.top = qMin( firstPoint.y, nY ) - 2.0 / (double)yScale; rect.bottom = qMax( firstPoint.y, nY ) + 2.0 / (double)yScale; } // end creation if we have 2 points else if ( type == Release && points.count() == 2 ) m_creationCompleted = true; return rect.geometry( (int)xScale, (int)yScale ); } void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ ) { if ( points.count() != 2 ) return; NormalizedPoint first = points[0]; NormalizedPoint second = points[1]; if ( m_block ) { // draw a semitransparent block around the 2 points painter->setPen( m_engineColor ); painter->setBrush( QBrush( m_engineColor.light(), Qt::Dense4Pattern ) ); painter->drawRect( (int)(first.x * (double)xScale), (int)(first.y * (double)yScale), (int)((second.x - first.x) * (double)xScale), (int)((second.y - first.y) * (double)yScale) ); } else { // draw a line that connects the 2 points painter->setPen( QPen( m_engineColor, 2 ) ); painter->drawLine( (int)(first.x * (double)xScale), (int)(first.y * (double)yScale), (int)(second.x * (double)xScale), (int)(second.y * (double)yScale) ); } } 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 LineAnnotation from path if ( typeString == "Line") //<annotation type="Text" { if ( points.count() != 2 ) return 0; //add note LineAnnotation * la = new LineAnnotation(); ann = la; la->linePoints.append(points[0]); la->linePoints.append(points[1]); la->boundary=this->rect; } // 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: QList<NormalizedPoint> points; NormalizedRect rect; bool m_block;};/** PageViewAnnotator **/PageViewAnnotator::PageViewAnnotator( PageView * parent, KPDFDocument * storage ) : QObject( parent ), m_document( storage ), m_pageView( parent ), 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( KStandardDirs::locate("data", "okular/tools.xml") ); if ( infoFile.exists() && infoFile.open( QIODevice::ReadOnly ) ) { QDomDocument doc( "annotatingTools" ); if ( doc.setContent( &infoFile ) ) m_toolsDefinition = doc.elementsByTagName("annotatingTools").item( 0 ).toElement(); else kWarning() << "AnnotatingTools XML file seems to be damaged" << endl; infoFile.close(); } else kWarning() << "Unable to open AnnotatingTools XML definition" << endl;}PageViewAnnotator::~PageViewAnnotator(){ delete m_engine;}void PageViewAnnotator::setEnabled( bool on ){ if ( !on ) { // remove toolBar if ( m_toolBar ) m_toolBar->hideAndDestroy(); m_toolBar = 0; return; } // if no tools are defined, don't show the toolbar if ( !m_toolsDefinition.hasChildNodes() ) return; // create toolBar if ( !m_toolBar ) { m_toolBar = new PageViewToolBar( m_pageView, m_pageView->viewport() ); connect( m_toolBar, SIGNAL( toolSelected(int) ), this, SLOT( slotToolSelected(int) ) ); connect( m_toolBar, SIGNAL( orientationChanged(int) ), this, SLOT( slotSaveToolbarOrientation(int) ) ); } // create the ToolBarItems from the XML dom tree QLinkedList<ToolBarItem> items; QDomNode toolDescription = m_toolsDefinition.firstChild(); while ( toolDescription.isElement() ) { QDomElement toolElement = toolDescription.toElement(); if ( toolElement.tagName() == "tool" ) { ToolBarItem item; item.id = toolElement.attribute("id").toInt(); item.text = toolElement.attribute("name"); item.pixmap = toolElement.attribute("pixmap"); QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 ); if ( shortcutNode.isElement() ) item.shortcut = shortcutNode.toElement().text(); items.push_back( item ); } toolDescription = toolDescription.nextSibling(); } // show the toolBar m_toolBar->showItems( (PageViewToolBar::Side)KpdfSettings::editToolBarPlacement(), items ); // ask for Author's name if not already set if ( KpdfSettings::annotationsAuthor().isEmpty() ) { // get default username from the kdelibs/kdecore/KUser KUser currentUser; QString userName = currentUser.fullName(); // ask the user for confirmation/change bool firstTry = true; while ( firstTry || userName.isEmpty() ) { QString prompt = firstTry ? i18n( "Please insert your name or initials:" ) : i18n( "You must set this name:" ); userName = KInputDialog::getText( i18n("Annotations author"), prompt, userName ); firstTry = false; } // save the name KpdfSettings::setAnnotationsAuthor( userName ); KpdfSettings::writeConfig(); }}bool PageViewAnnotator::routeEvents() const{ return m_engine && m_toolBar;}void PageViewAnnotator::routeEvent( QMouseEvent * e, PageViewItem * item ){if ( !item ) return; //STRAPAAAATCH !!! FIXME // find out mouse event type AnnotatorEngine::EventType eventType = AnnotatorEngine::Press; if ( e->type() == QEvent::MouseMove ) eventType = AnnotatorEngine::Move; else if ( e->type() == QEvent::MouseButtonRelease ) eventType = AnnotatorEngine::Release; // find out the pressed button AnnotatorEngine::Button button = AnnotatorEngine::None; Qt::ButtonState buttonState = ( eventType == AnnotatorEngine::Move ) ? e->state() : e->button(); if ( buttonState == Qt::LeftButton ) button = AnnotatorEngine::Left; else if ( buttonState == Qt::RightButton ) button = AnnotatorEngine::Right; // find out normalized mouse coords inside current item const QRect & itemRect = item->geometry(); double itemWidth = (double)itemRect.width(); double itemHeight = (double)itemRect.height(); double nX = (double)(e->x() - itemRect.left()) / itemWidth; double nY = (double)(e->y() - itemRect.top()) / itemHeight; // 1. lock engine to current item if ( m_lockedItem && item != m_lockedItem ) return; if ( !m_lockedItem && eventType == AnnotatorEngine::Press ) m_lockedItem = item; // 2. use engine to perform operations QRect paintRect = m_engine->event( eventType, button, nX, nY, itemWidth, itemHeight ); // 3. update absolute extents rect and send paint event(s) if ( paintRect.isValid() ) { // 3.1. unite old and new painting regions QRegion compoundRegion( m_lastDrawnRect ); m_lastDrawnRect = paintRect; m_lastDrawnRect.translate( itemRect.left(), itemRect.top() ); // 3.2. decompose paint region in rects and send paint events QVector<QRect> rects = compoundRegion.unite( m_lastDrawnRect ).rects(); for ( int i = 0; i < rects.count(); i++ ) m_pageView->updateContents( rects[i] ); } // 4. if engine has finished, apply Annotation to the page if ( m_engine->creationCompleted() ) { // apply engine data to Annotation and reset engine Annotation * annotation = m_engine->end(); // attach the newly filled annotation to the page if ( annotation ) { annotation->author = KpdfSettings::annotationsAuthor(); m_document->addPageAnnotation( m_lockedItem->pageNumber(), annotation ); } // go on creating annotations of the same type slotToolSelected( m_lastToolID ); }}bool PageViewAnnotator::routePaints( const QRect & wantedRect ) const{ return m_engine && m_toolBar && wantedRect.intersects( m_lastDrawnRect );}void PageViewAnnotator::routePaint( QPainter * painter, const QRect & paintRect ){#ifndef NDEBUG // [DEBUG] draw the paint region if enabled if ( KpdfSettings::debugDrawAnnotationRect() ) painter->drawRect( paintRect );#endif // move painter to current itemGeometry rect const QRect & itemGeometry = m_lockedItem->geometry(); painter->save(); painter->translate( itemGeometry.left(), itemGeometry.top() ); // transform cliprect from absolute to item relative coords QRect annotRect = paintRect.intersect( m_lastDrawnRect ); annotRect.translate( itemGeometry.left(), itemGeometry.top() ); // use current engine for painting m_engine->paint( painter, m_lockedItem->width(), m_lockedItem->height(), annotRect ); painter->restore();}void PageViewAnnotator::slotToolSelected( int toolID ){ // terminate any previous operation if ( m_engine ) { delete m_engine; m_engine = 0; } m_lockedItem = 0; if ( m_lastDrawnRect.isValid() ) { m_pageView->updateContents( m_lastDrawnRect ); m_lastDrawnRect = QRect(); } // store current tool for later usage m_lastToolID = toolID; // handle tool deselection if ( toolID == -1 ) { m_pageView->displayMessage( QString() ); return; } // for the selected tool create the Engine QDomNode toolNode = m_toolsDefinition.firstChild(); while ( toolNode.isElement() ) { QDomElement toolElement = toolNode.toElement(); toolNode = toolNode.nextSibling(); // only find out the element describing selected tool if ( toolElement.tagName() != "tool" || toolElement.attribute("id").toInt() != toolID ) continue; // parse tool properties QDomNode toolSubNode = toolElement.firstChild(); while ( toolSubNode.isElement() ) { QDomElement toolSubElement = toolSubNode.toElement(); toolSubNode = toolSubNode.nextSibling(); // create the AnnotatorEngine if ( toolSubElement.tagName() == "engine" ) { QString type = toolSubElement.attribute( "type" ); if ( type == "SmoothLine" ) m_engine = new SmoothPathEngine( toolSubElement ); else if ( type == "PickPoint" ) m_engine = new PickPointEngine( toolSubElement ); else if ( type == "TwoPoints" ) m_engine = new TwoPointsEngine( toolSubElement ); else kWarning() << "tools.xml: engine type:'" << type << "' is not defined!" << endl; } // display the tooltip else if ( toolSubElement.tagName() == "tooltip" ) m_pageView->displayMessage( toolSubElement.text() ); } // consistancy warning if ( !m_engine ) kWarning() << "tools.xml: couldn't find good engine description. check xml." << endl; // stop after parsing selected tool's node break; }}void PageViewAnnotator::slotSaveToolbarOrientation( int side ){ KpdfSettings::setEditToolBarPlacement( (int)side ); KpdfSettings::writeConfig();}Annotation* PageViewAnnotator::getAnnotationbyPos(const KPDFPage * page, double nX, double nY ){ QLinkedList< Annotation * >::const_iterator aIt = page->m_annotations.begin(), aEnd =page->m_annotations.end(); for ( ; aIt != aEnd; ++aIt ) { Annotation * ann = *aIt; if ( ann->boundary.contains( nX, nY ) ) { return ann; } } return 0;}#include "pageviewannotator.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -