📄 pageview.cpp.svn-base
字号:
if ( cursor().shape() == Qt::SizeAllCursor ) updateCursor( e->pos() ); PageViewItem * pageItem = pickItemOnPoint( e->x(), e->y() ); // if the mouse has not moved since the press, that's a -click- if ( leftButton && pageItem && d->mousePressPos == e->globalPos()) { double nX = (double)(e->x() - pageItem->geometry().left()) / (double)pageItem->width(), nY = (double)(e->y() - pageItem->geometry().top()) / (double)pageItem->height(); const ObjectRect * rect; rect = pageItem->page()->getObjectRect( ObjectRect::Link, nX, nY ); if ( rect ) { // handle click over a link const KPDFLink * link = static_cast< const KPDFLink * >( rect->pointer() ); d->document->processLink( link ); } else { // a link can move us to another page or even to another document, there's no point in trying to // process the click on the image once we have processes the click on the link rect = pageItem->page()->getObjectRect( ObjectRect::Image, nX, nY ); if ( rect ) { // handle click over a image }/* Enrico and me have decided this is not worth the trouble it generates else { // if not on a rect, the click selects the page // if ( pageItem->pageNumber() != (int)d->document->currentPage() ) d->document->setViewportPage( pageItem->pageNumber(), PAGEVIEW_ID ); }*/ } } 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() ); } }break; case MouseZoom: // if a selection rect has been defined, zoom into it if ( leftButton && d->mouseSelecting ) { QRect selRect = d->mouseSelectionRect.normalized(); if ( selRect.width() <= 8 && selRect.height() <= 8 ) { selectionClear(); break; } // find out new zoom ratio and normalized view center (relative to the contentsRect) double zoom = qMin( (double)visibleWidth() / (double)selRect.width(), (double)visibleHeight() / (double)selRect.height() ); double nX = (double)(selRect.left() + selRect.right()) / (2.0 * (double)contentsWidth()); double nY = (double)(selRect.top() + selRect.bottom()) / (2.0 * (double)contentsHeight()); // zoom up to 400% if ( d->zoomFactor <= 4.0 || zoom <= 1.0 ) { d->zoomFactor *= zoom; viewport()->setUpdatesEnabled( false ); updateZoom( ZoomRefreshCurrent ); viewport()->setUpdatesEnabled( true ); } // recenter view and update the viewport center( (int)(nX * contentsWidth()), (int)(nY * contentsHeight()) ); updateContents(); // hide message box and delete overlay window selectionClear(); } break; case MouseSelect:{ // if mouse is released and selection is null this is a rightClick if ( rightButton && !d->mouseSelecting ) { PageViewItem * pageItem = pickItemOnPoint( e->x(), e->y() ); emit rightClick( pageItem ? pageItem->page() : 0, e->globalPos() ); break; } // if a selection is defined, display a popup if ( (!leftButton && !d->aPrevAction) || (!rightButton && d->aPrevAction) || !d->mouseSelecting ) break; QRect selectionRect = d->mouseSelectionRect.normalized(); if ( selectionRect.width() <= 8 && selectionRect.height() <= 8 ) { selectionClear(); if ( d->aPrevAction ) { d->aPrevAction->trigger(); d->aPrevAction = 0; } break; } // if we support text generation QString selectedText; if (d->document->supportsSearching()) { // grab text in selection by extracting it from all intersected pages RegularAreaRect * rects=new RegularAreaRect; const KPDFPage * kpdfPage=0; QVector< PageViewItem * >::iterator iIt = d->items.begin(), iEnd = d->items.end(); for ( ; iIt != iEnd; ++iIt ) { PageViewItem * item = *iIt; const QRect & itemRect = item->geometry(); if ( selectionRect.intersects( itemRect ) ) { // request the textpage if there isn't one kpdfPage= item->page(); kWarning() << "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 QRect relativeRect = selectionRect.intersect( itemRect ); relativeRect.translate( -itemRect.left(), -itemRect.top() ); rects->append(new NormalizedRect( relativeRect, item->width(), item->height() )); } } if (kpdfPage) selectedText = kpdfPage->getText( rects ); } // popup that ask to copy:text and copy/save:image KMenu menu( this ); QAction *textToClipboard = 0, *speakText = 0, *imageToClipboard = 0, *imageToFile = 0; if ( d->document->supportsSearching() && !selectedText.isEmpty() ) { menu.addTitle( i18np( "Text (1 character)", "Text (%n characters)", selectedText.length() ) ); textToClipboard = menu.addAction( SmallIconSet("editcopy"), i18n( "Copy to Clipboard" ) ); if ( !d->document->isAllowed( KPDFDocument::AllowCopy ) ) { textToClipboard->setEnabled( false ); textToClipboard->setText( i18n("Copy forbidden by DRM") ); } if ( KpdfSettings::useKTTSD() ) speakText = menu.addAction( SmallIconSet("kttsd"), i18n( "Speak Text" ) ); } menu.addTitle( i18n( "Image (%1 by %2 pixels)", selectionRect.width(), selectionRect.height() ) ); imageToClipboard = menu.addAction( QIcon(SmallIcon("image")), i18n( "Copy to Clipboard" ) ); imageToFile = menu.addAction( QIcon(SmallIcon("filesave")), i18n( "Save to File..." ) ); QAction *choice = menu.exec( e->globalPos() ); // check if the user really selected an action if ( choice ) { // IMAGE operation choosen if ( choice == imageToClipboard || choice == imageToFile ) { // renders page into a pixmap QPixmap copyPix( selectionRect.width(), selectionRect.height() ); QPainter copyPainter( ©Pix ); copyPainter.translate( -selectionRect.left(), -selectionRect.top() ); drawDocumentOnPainter( selectionRect, ©Painter ); if ( choice == imageToClipboard ) { // [2] copy pixmap to clipboard QClipboard *cb = QApplication::clipboard(); cb->setPixmap( copyPix, QClipboard::Clipboard ); if ( cb->supportsSelection() ) cb->setPixmap( copyPix, QClipboard::Selection ); d->messageWindow->display( i18n( "Image [%1x%2] copied to clipboard.", copyPix.width(), copyPix.height() ) ); } else if ( choice == imageToFile ) { // [3] save pixmap to file QString fileName = KFileDialog::getSaveFileName( KUrl(), "image/png image/jpeg", this ); if ( fileName.isEmpty() ) d->messageWindow->display( i18n( "File not saved." ), PageViewMessage::Warning ); else { KMimeType::Ptr mime = KMimeType::findByURL( fileName ); QString type; if ( !mime ) type = "PNG"; else type = mime->name().section( '/', -1 ).toUpper(); copyPix.save( fileName, qPrintable( type ) ); d->messageWindow->display( i18n( "Image [%1x%2] saved to %3 file.", copyPix.width(), copyPix.height(), type ) ); } } } // TEXT operation choosen else { if ( choice == textToClipboard ) { // [1] copy text to clipboard QClipboard *cb = QApplication::clipboard(); cb->setText( selectedText, QClipboard::Clipboard ); if ( cb->supportsSelection() ) cb->setText( selectedText, QClipboard::Selection ); } else if ( choice == speakText ) { // [2] speech selection using KTTSD // Albert says is this ever necessary? // we already attached on Part constructor // If KTTSD not running, start it. QDBusReply<bool> reply = QDBus::sessionBus().interface()->isServiceRegistered("org.kde.kttsd"); bool kttsdactive = false; if ( reply.isValid() ) kttsdactive = reply.value(); if ( !kttsdactive ) { QString error; if (KToolInvocation::startServiceByDesktopName("kttsd", QStringList(), &error)) { d->messageWindow->display( i18n("Starting KTTSD Failed: %1", error) ); } else { kttsdactive = true; } } if ( kttsdactive ) { // creating the connection to the kspeech interface QDBusInterface kspeech("org.kde.kttsd", "/KSpeech", "org.kde.KSpeech"); kspeech.call("setApplicationName", "okular"); kspeech.call("say", selectedText, 0); } } } } // clear widget selection and invalidate rect selectionClear(); // restore previous action if came from it using right button if ( d->aPrevAction ) { d->aPrevAction->trigger(); d->aPrevAction = 0; } }break; } // reset mouse press / 'drag start' position d->mousePressPos = QPoint();}}void PageView::wheelEvent( QWheelEvent *e ){if (d->document->handleEvent( e ) ){ // don't perform any mouse action when viewport is autoscrolling if ( d->viewportMoveActive ) return; int delta = e->delta(), vScroll = verticalScrollBar()->value(); e->accept(); if ( (e->state() & Qt::ControlButton) == Qt::ControlButton ) { if ( e->delta() < 0 ) slotZoomOut(); else slotZoomIn(); } else if ( delta <= -120 && !KpdfSettings::viewContinuous() && vScroll == verticalScrollBar()->maximum() ) { // go to next page if ( d->document->currentPage() < d->items.count() - 1 ) { // more optimized than document->setNextPage and then move view to top DocumentViewport newViewport = d->document->viewport(); newViewport.pageNumber += d->document->currentPage() ? viewColumns() : 1; if ( newViewport.pageNumber >= (int)d->items.count() ) newViewport.pageNumber = d->items.count() - 1; newViewport.rePos.enabled = true; newViewport.rePos.normalizedY = 0.0; d->document->setViewport( newViewport ); } } else if ( delta >= 120 && !KpdfSettings::viewContinuous() && vScroll == verticalScrollBar()->minimum() ) { // go to prev page if ( d->document->currentPage() > 0 ) { // more optimized than document->setPrevPage and then move view to bottom DocumentViewport newViewport = d->document->viewport(); newViewport.pageNumber -= viewColumns(); if ( newViewport.pageNumber < 0 ) newViewport.pageNumber = 0; newViewport.rePos.enabled = true; newViewport.rePos.normalizedY = 1.0; d->document->setViewport( newViewport ); } } else Q3ScrollView::wheelEvent( e ); QPoint cp = viewportToContents(e->pos()); updateCursor(cp);}}void PageView::dragEnterEvent( QDragEnterEvent * ev ){if (d->document->handleEvent( ev ) ){ ev->accept();}}void PageView::dropEvent( QDropEvent * ev ){if (d->docu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -