Hello, as a regular Okular user, I have an itch that I was scratching: I was looking for a zoom setting that is appropriate both for viewing presentations (in non-fullscreen mode) and text documents (portrait format). I came up with a "best fit" zoom level which corresponds to the existing "fit width" and "fit page" zoom levels. The best-fit setting compares the aspect ratios of the document and the viewing area it is shown in. If the aspect ratios nearly match, a page will be shown in "fit page" mode. This is useful e.g. for presentations, where a slide has a similar aspect ratio like the screen. If the aspect ratio is very different, such as in cases with portrait text documents, the document is scaled to "fit width" and you only have to scroll vertically. If the document is much wider, it is scaled to fit the height and you scroll horizontally only.
The attached patch introduces this feature while being just below 7k in size. Additionally, I removed/replaced some "fit text" zoom which seemed to be dead code. The patch is for KDE 4.3.4, but it should be no problem apply it to the upcoming 4.4 or trunk. However, there is one major bug in my patch. If the ratio between aspect ratios is very close to switching between either of the three zooming modes, Okular may continuously switch between two modes. This seems to happen as Okular shows scrollbars if necessary, which change the view area's size (and this aspect), which in turn triggers the change in mode. As this new mode does not need scrollbars, they get disabled again and the circle closes. I have not yet found a nice and clean solution here. Comments are welcome. Bye, Thomas
diff -Naur orig_kdegraphics-4.3.4/okular/part.rc kdegraphics-4.3.4/okular/part.rc --- orig_kdegraphics-4.3.4/okular/part.rc 2009-02-18 17:28:33.000000000 +0100 +++ kdegraphics-4.3.4/okular/part.rc 2010-01-16 17:38:49.000000000 +0100 @@ -29,6 +29,7 @@ <Action name="view_zoom_out"/> <Action name="view_fit_to_width"/> <Action name="view_fit_to_page"/> + <Action name="view_fit_to_best"/> <Action name="zoom_fit_rect"/> <Separator/> <Action name="view_continuous"/> diff -Naur orig_kdegraphics-4.3.4/okular/ui/pageview.cpp kdegraphics-4.3.4/okular/ui/pageview.cpp --- orig_kdegraphics-4.3.4/okular/ui/pageview.cpp 2009-11-27 14:03:14.000000000 +0100 +++ kdegraphics-4.3.4/okular/ui/pageview.cpp 2010-01-16 18:44:47.000000000 +0100 @@ -159,7 +159,7 @@ KAction * aZoomOut; KToggleAction * aZoomFitWidth; KToggleAction * aZoomFitPage; - KToggleAction * aZoomFitText; + KToggleAction * aZoomFitBest; KActionMenu * aViewMode; KToggleAction * aViewContinuous; QAction * aPrevAction; @@ -345,7 +345,7 @@ d->aToggleAnnotator = 0; d->aZoomFitWidth = 0; d->aZoomFitPage = 0; - d->aZoomFitText = 0; + d->aZoomFitBest = 0; d->aViewMode = 0; d->aViewContinuous = 0; d->aPrevAction = 0; @@ -465,11 +465,10 @@ ac->addAction("view_fit_to_page", d->aZoomFitPage ); connect( d->aZoomFitPage, SIGNAL( toggled( bool ) ), SLOT( slotFitToPageToggled( bool ) ) ); -/* - d->aZoomFitText = new KToggleAction(KIcon( "zoom-fit-best" ), i18n("Fit &Text"), this); - ac->addAction("zoom_fit_text", d->aZoomFitText ); - connect( d->aZoomFitText, SIGNAL( toggled( bool ) ), SLOT( slotFitToTextToggled( bool ) ) ); -*/ + d->aZoomFitBest = new KToggleAction(KIcon( "zoom-fit-best" ), i18n("Fit &Best"), this); + ac->addAction("view_fit_to_best", d->aZoomFitBest ); + connect( d->aZoomFitBest, SIGNAL( toggled( bool ) ), SLOT( slotFitToBestToggled( bool ) ) ); + // View-Layout actions d->aViewMode = new KActionMenu( KIcon( "view-split-left-right" ), i18n( "&View Mode" ), this ); @@ -592,7 +591,7 @@ Okular::Settings::setViewMode( 0 ); d->aZoomFitWidth->setChecked( true ); d->aZoomFitPage->setChecked( false ); -// d->aZoomFitText->setChecked( false ); + d->aZoomFitBest->setChecked( false ); d->aViewMode->menu()->actions().at( 0 )->setChecked( true ); viewport()->setUpdatesEnabled( false ); slotRelayoutPages(); @@ -2462,6 +2461,35 @@ item->setWHZC( (int)(zoom * width), (int)(zoom * height), zoom, crop ); d->zoomFactor = zoom; } + else if ( d->zoomMode == ZoomFitBest ) + { + double uiAspect = (double)rowHeight / (double)colWidth; + double pageAspect = (double)height / (double)width; + + if ( ( uiAspect / pageAspect ) > 1.25 ) + { + // UI space is relatively much higher than the page + zoom = (double)rowHeight / (double)height; + } + else if ( ( uiAspect / pageAspect ) < 0.8 ) + { + // UI space is relatively much wider than the page in relation + zoom = (double)colWidth / (double)width; + } + else + { + // aspect ratios of page and UI space are very similar + double scaleW = (double)colWidth / (double)width; + double scaleH = (double)rowHeight / (double)height; + zoom = qMin( scaleW, scaleH ); + } + item->setWHZC( (int)(zoom * width), (int)(zoom * height), zoom, crop ); + d->zoomFactor = zoom; + +#ifndef NDEBUG + kDebug() << " rowHeight=" << rowHeight << " colWidth=" << colWidth << " height=" << height << " width=" << width << " uiAspect=" << uiAspect << " pageAspect=" << pageAspect << " uiAspect/pageAspect=" << (uiAspect / pageAspect) << " zoom=" << zoom; +#endif + } #ifndef NDEBUG else kDebug() << "calling updateItemSize with unrecognized d->zoomMode!"; @@ -2604,6 +2632,8 @@ newZoomMode = ZoomFitWidth; else if ( d->aZoom->currentItem() == 1 ) newZoomMode = ZoomFitPage; + else if ( d->aZoom->currentItem() == 2 ) + newZoomMode = ZoomFitBest; } float newFactor = d->zoomFactor; @@ -2631,8 +2661,8 @@ case ZoomFitPage: checkedZoomAction = d->aZoomFitPage; break; - case ZoomFitText: - checkedZoomAction = d->aZoomFitText; + case ZoomFitBest: + checkedZoomAction = d->aZoomFitBest; break; case ZoomRefreshCurrent: newZoomMode = ZoomFixed; @@ -2663,7 +2693,7 @@ { d->aZoomFitWidth->setChecked( checkedZoomAction == d->aZoomFitWidth ); d->aZoomFitPage->setChecked( checkedZoomAction == d->aZoomFitPage ); -// d->aZoomFitText->setChecked( checkedZoomAction == d->aZoomFitText ); + d->aZoomFitBest->setChecked( checkedZoomAction == d->aZoomFitBest ); } } @@ -2681,7 +2711,7 @@ // add items that describe fit actions QStringList translated; - translated << i18n("Fit Width") << i18n("Fit Page") /*<< i18n("Fit Text")*/; + translated << i18n("Fit Width") << i18n("Fit Page") << i18n("Fit Best"); // add percent items QString double_oh( "00" ); @@ -2714,7 +2744,7 @@ selIdx = 0; else if ( d->zoomMode == ZoomFitPage ) selIdx = 1; - else if ( d->zoomMode == ZoomFitText ) + else if ( d->zoomMode == ZoomFitBest ) selIdx = 2; d->aZoom->setCurrentItem( selIdx ); } @@ -3230,9 +3260,9 @@ if ( on ) updateZoom( ZoomFitPage ); } -void PageView::slotFitToTextToggled( bool on ) +void PageView::slotFitToBestToggled( bool on ) { - if ( on ) updateZoom( ZoomFitText ); + if ( on ) updateZoom( ZoomFitBest ); } void PageView::slotViewMode( QAction *action ) diff -Naur orig_kdegraphics-4.3.4/okular/ui/pageview.h kdegraphics-4.3.4/okular/ui/pageview.h --- orig_kdegraphics-4.3.4/okular/ui/pageview.h 2008-10-17 13:00:05.000000000 +0200 +++ kdegraphics-4.3.4/okular/ui/pageview.h 2010-01-16 17:46:03.000000000 +0100 @@ -57,7 +57,7 @@ ~PageView(); // Zoom mode ( last 4 are internally used only! ) - enum ZoomMode { ZoomFixed = 0, ZoomFitWidth = 1, ZoomFitPage = 2, ZoomFitText, + enum ZoomMode { ZoomFixed = 0, ZoomFitWidth = 1, ZoomFitPage = 2, ZoomFitBest = 3, ZoomIn, ZoomOut, ZoomRefreshCurrent }; enum MouseMode { MouseNormal, MouseZoom, MouseSelect, MouseImageSelect, MouseTextSelect }; @@ -189,7 +189,7 @@ void slotZoomOut(); void slotFitToWidthToggled( bool ); void slotFitToPageToggled( bool ); - void slotFitToTextToggled( bool ); + void slotFitToBestToggled( bool ); void slotViewMode( QAction *action ); void slotContinuousToggled( bool ); void slotSetMouseNormal();
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Okular-devel mailing list Okular-devel@kde.org https://mail.kde.org/mailman/listinfo/okular-devel