[calligra/krita-animation-pentikainen] krita: [FEATURE] Implemented the first "somewhat usable" Level of Detail functionality
Dmitry Kazakov
dimula73 at gmail.com
Mon Jul 27 17:25:54 UTC 2015
Git commit 580313c3e5539ef8a69ff4ad86f042a5a7c87e3b by Dmitry Kazakov.
Committed on 27/07/2015 at 17:23.
Pushed by dkazakov into branch 'krita-animation-pentikainen'.
[FEATURE] Implemented the first "somewhat usable" Level of Detail functionality
Now you can Enable/Disable it via View->Fast Preview Mode (LOD) button
(or just press Shift+L).
Please note that when you switch on/off, Krita should synchronize all
the caches, so it hangs up of a couple of seconds to render all unfinished
strokes.
CC:kimageshop at kde.org
M +4 -14 krita/image/kis_image.cc
M +2 -7 krita/image/kis_image.h
M +5 -0 krita/image/kis_lod_transform.h
M +3 -2 krita/image/tests/kis_image_test.cpp
M +1 -0 krita/krita.action
M +2 -2 krita/krita.rc
M +13 -0 krita/ui/KisViewManager.cpp
M +50 -0 krita/ui/canvas/kis_canvas2.cpp
M +6 -0 krita/ui/canvas/kis_canvas2.h
M +23 -0 krita/ui/canvas/kis_canvas_controller.cpp
M +2 -0 krita/ui/canvas/kis_canvas_controller.h
M +13 -0 krita/ui/canvas/kis_coordinates_converter.cpp
M +6 -1 krita/ui/canvas/kis_coordinates_converter.h
M +9 -0 krita/ui/kis_config.cc
M +2 -0 krita/ui/kis_config.h
M +4 -34 krita/ui/kis_zoom_manager.cc
M +0 -3 krita/ui/kis_zoom_manager.h
http://commits.kde.org/calligra/580313c3e5539ef8a69ff4ad86f042a5a7c87e3b
diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 68ecb59..dedcf5e 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -1676,25 +1676,15 @@ int KisImage::currentLevelOfDetail() const
return m_d->scheduler->currentLevelOfDetail();
}
-void KisImage::blockLevelOfDetail()
+void KisImage::setLevelOfDetailBlocked(bool value)
{
KisImageBarrierLockerRaw l(this);
- if (!m_d->blockLevelOfDetail) {
- m_d->scheduler->setDesiredLevelOfDetail(0);
- }
- m_d->blockLevelOfDetail++;
-}
-
-bool KisImage::unblockLevelOfDetail(int newLevelOfDetail)
-{
- KisImageBarrierLockerRaw l(this);
- m_d->blockLevelOfDetail--;
- if (!m_d->blockLevelOfDetail) {
- m_d->scheduler->setDesiredLevelOfDetail(newLevelOfDetail);
+ if (value && !m_d->blockLevelOfDetail) {
+ m_d->scheduler->setDesiredLevelOfDetail(0);
}
- return m_d->blockLevelOfDetail;
+ m_d->blockLevelOfDetail = value;
}
bool KisImage::levelOfDetailBlocked() const
diff --git a/krita/image/kis_image.h b/krita/image/kis_image.h
index 27110ab..f9ea7e2 100644
--- a/krita/image/kis_image.h
+++ b/krita/image/kis_image.h
@@ -527,15 +527,10 @@ public:
* Blocks usage of level of detail functionality. After this method
* has been called, no new strokes will use LoD.
*/
- void blockLevelOfDetail();
+ void setLevelOfDetailBlocked(bool value);
/**
- * \see blockLevelOfDetail()
- */
- bool unblockLevelOfDetail(int newLevelOfDetail);
-
- /**
- * \see blockLevelOfDetail()
+ * \see setLevelOfDetailBlocked()
*/
bool levelOfDetailBlocked() const;
diff --git a/krita/image/kis_lod_transform.h b/krita/image/kis_lod_transform.h
index e262359..9ffc849 100644
--- a/krita/image/kis_lod_transform.h
+++ b/krita/image/kis_lod_transform.h
@@ -19,6 +19,7 @@
#ifndef __KIS_LOD_TRANSFORM_H
#define __KIS_LOD_TRANSFORM_H
+#include <QtCore/qmath.h>
#include <QTransform>
#include <kis_paint_information.h>
@@ -38,6 +39,10 @@ public:
m_levelOfDetail = levelOfDetail;
}
+ static int scaleToLod(qreal scale, int maxLod) {
+ return qMin(maxLod, qMax(0, qFloor(log2(1.0 / scale))));
+ }
+
static qreal lodToScale(int levelOfDetail) {
return 1.0 / (1 << qMax(0, levelOfDetail));
}
diff --git a/krita/image/tests/kis_image_test.cpp b/krita/image/tests/kis_image_test.cpp
index 690ca5e..cdf5f8d 100644
--- a/krita/image/tests/kis_image_test.cpp
+++ b/krita/image/tests/kis_image_test.cpp
@@ -125,7 +125,7 @@ void KisImageTest::testBlockLevelOfDetail()
QVERIFY(lodCreated);
}
- p.image->blockLevelOfDetail();
+ p.image->setLevelOfDetailBlocked(true);
{
bool lodCreated = false;
@@ -138,7 +138,8 @@ void KisImageTest::testBlockLevelOfDetail()
QVERIFY(!lodCreated);
}
- p.image->unblockLevelOfDetail(1);
+ p.image->setLevelOfDetailBlocked(false);
+ p.image->setDesiredLevelOfDetail(1);
{
bool lodCreated = false;
diff --git a/krita/krita.action b/krita/krita.action
index 14b8fa92..0b7fedf 100644
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -8,6 +8,7 @@
<Action name="rotate_canvas_right" icon="" text="Rotate Canvas Right" whatsThis="" toolTip="Rotate Canvas Right" iconText="Rotate Canvas Right" shortcut="Ctrl+]" defaultShortcut="Ctrl+]" isCheckable="false" statusTip=""/>
<Action name="rotate_canvas_left" icon="" text="Rotate Canvas Left" whatsThis="" toolTip="Rotate Canvas Left" iconText="Rotate Canvas Left" shortcut="Ctrl+[" defaultShortcut="Ctrl+[" isCheckable="false" statusTip=""/>
<Action name="wrap_around_mode" icon="" text="Wrap Around Mode" whatsThis="" toolTip="Wrap Around Mode" iconText="Wrap Around Mode" shortcut="W" defaultShortcut="W" isCheckable="false" statusTip=""/>
+ <Action name="level_of_detail_mode" icon="" text="Fast Preview Mode (LOD)" whatsThis="" toolTip="Fast Preview Mode (LOD)" iconText="Fast Preview Mode (LOD)" shortcut="Shift+L" defaultShortcut="Shift+L" isCheckable="true" statusTip=""/>
<Action name="showStatusBar" icon="" text="Hide Status Bar" whatsThis="" toolTip="Shows or hides the status bar" iconText="Hide Status Bar" shortcut="" defaultShortcut="" isCheckable="true" statusTip=""/>
<Action name="view_show_just_the_canvas" icon="" text="Show Canvas Only" whatsThis="" toolTip="Shows just the canvas or the whole window" iconText="Show Canvas Only" shortcut="Tab" defaultShortcut="Tab" isCheckable="false" statusTip=""/>
<Action name="edit_blacklist_cleanup" icon="" text="Cleanup removed files..." whatsThis="" toolTip="Cleanup removed files" iconText="Cleanup removed files" shortcut="" defaultShortcut="" isCheckable="false" statusTip=""/>
diff --git a/krita/krita.rc b/krita/krita.rc
index a494358..345b15c 100644
--- a/krita/krita.rc
+++ b/krita/krita.rc
@@ -2,7 +2,7 @@
<kpartgui xmlns="http://www.kde.org/standards/kxmlgui/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="Krita"
-version="73"
+version="74"
xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd">
<MenuBar>
<Menu name="file" noMerge="1">
@@ -60,8 +60,8 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org
<text>&View</text>
<Action name="view_show_just_the_canvas"/>
<Action name="fullscreen"/>
-
<Action name="wrap_around_mode"/>
+ <Action name="level_of_detail_mode"/>
<Separator/>
<Menu name="Canvas">
<text>&Canvas</text>
diff --git a/krita/ui/KisViewManager.cpp b/krita/ui/KisViewManager.cpp
index e2f36c6..dc89ced 100644
--- a/krita/ui/KisViewManager.cpp
+++ b/krita/ui/KisViewManager.cpp
@@ -221,6 +221,7 @@ public:
, rotateCanvasRight(0)
, rotateCanvasLeft(0)
, wrapAroundAction(0)
+ , levelOfDetailAction(0)
, showRulersAction(0)
, zoomTo100pct(0)
, zoomIn(0)
@@ -273,6 +274,7 @@ public:
KisAction *rotateCanvasRight;
KisAction *rotateCanvasLeft;
KisAction *wrapAroundAction;
+ KisAction *levelOfDetailAction;
KisAction *showRulersAction;
KisAction *zoomTo100pct;
KisAction *zoomIn;
@@ -420,8 +422,13 @@ void KisViewManager::setCurrentView(KisView *view)
d->viewConnections.addUniqueConnection(d->nodeManager, SIGNAL(sigNodeActivated(KisNodeSP)), doc->image(), SLOT(requestStrokeEnd()));
d->viewConnections.addUniqueConnection(d->rotateCanvasRight, SIGNAL(triggered()), canvasController, SLOT(rotateCanvasRight15()));
d->viewConnections.addUniqueConnection(d->rotateCanvasLeft, SIGNAL(triggered()),canvasController, SLOT(rotateCanvasLeft15()));
+
d->viewConnections.addUniqueConnection(d->wrapAroundAction, SIGNAL(toggled(bool)), canvasController, SLOT(slotToggleWrapAroundMode(bool)));
d->wrapAroundAction->setChecked(canvasController->wrapAroundMode());
+
+ d->viewConnections.addUniqueConnection(d->levelOfDetailAction, SIGNAL(toggled(bool)), canvasController, SLOT(slotToggleLevelOfDetailMode(bool)));
+ d->levelOfDetailAction->setChecked(canvasController->levelOfDetailMode());
+
d->viewConnections.addUniqueConnection(d->currentImageView->canvasController(), SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget> >)), mainWindow(), SLOT(newOptionWidgets(QList<QPointer<QWidget> >)));
d->viewConnections.addUniqueConnection(d->currentImageView->image(), SIGNAL(sigColorSpaceChanged(const KoColorSpace*)), d->controlFrame->paintopBox(), SLOT(slotColorSpaceChanged(const KoColorSpace*)));
d->viewConnections.addUniqueConnection(d->showRulersAction, SIGNAL(toggled(bool)), imageView->zoomManager(), SLOT(toggleShowRulers(bool)));
@@ -717,6 +724,12 @@ void KisViewManager::createActions()
actionManager()->addAction("wrap_around_mode", d->wrapAroundAction);
d->wrapAroundAction->setShortcut(QKeySequence(Qt::Key_W));
+ d->levelOfDetailAction = new KisAction(i18n("Fast Preview Mode (LOD)"), this);
+ d->levelOfDetailAction->setCheckable(true);
+ d->levelOfDetailAction->setActivationFlags(KisAction::ACTIVE_IMAGE);
+ actionManager()->addAction("level_of_detail_mode", d->levelOfDetailAction);
+ d->levelOfDetailAction->setShortcut(QKeySequence("Shift+L"));
+
KisAction *tAction = new KisAction(i18n("Show Status Bar"), this);
tAction->setCheckable(true);
tAction->setChecked(true);
diff --git a/krita/ui/canvas/kis_canvas2.cpp b/krita/ui/canvas/kis_canvas2.cpp
index 6cd8bfe..dfeec17 100644
--- a/krita/ui/canvas/kis_canvas2.cpp
+++ b/krita/ui/canvas/kis_canvas2.cpp
@@ -131,6 +131,8 @@ public:
KisAnimationPlayer *animationPlayer;
KisAnimationFrameCacheSP frameCache;
+
+ bool lodAllowedInCanvas;
};
KisCanvas2::KisCanvas2(KisCoordinatesConverter *coordConverter, KoCanvasResourceManager *resourceManager, QPointer<KisView>view, KoShapeBasedDocumentBase *sc)
@@ -140,9 +142,12 @@ KisCanvas2::KisCanvas2(KisCoordinatesConverter *coordConverter, KoCanvasResource
// a bit of duplication from slotConfigChanged()
KisConfig cfg;
m_d->vastScrolling = cfg.vastScrolling();
+ m_d->lodAllowedInCanvas = cfg.levelOfDetailEnabled();
createCanvas(cfg.useOpenGL());
+ setLodAllowedInCanvas(m_d->lodAllowedInCanvas);
+
m_d->animationPlayer = new KisAnimationPlayer(this);
connect(view->canvasController()->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), SLOT(documentOffsetMoved(QPoint)));
@@ -465,6 +470,7 @@ void KisCanvas2::connectCurrentCanvas()
startResizingImage();
emit imageChanged(image);
+ setLodAllowedInCanvas(m_d->lodAllowedInCanvas);
}
void KisCanvas2::disconnectCurrentCanvas()
@@ -743,9 +749,25 @@ void KisCanvas2::notifyZoomChanged()
m_d->prescaledProjection->notifyZoomChanged();
}
+ notifyLevelOfDetailChange();
updateCanvas(); // update the canvas, because that isn't done when zooming using KoZoomAction
}
+void KisCanvas2::notifyLevelOfDetailChange()
+{
+ if (!m_d->lodAllowedInCanvas) return;
+
+ KisImageSP image = this->image();
+
+ const qreal effectiveZoom = m_d->coordinatesConverter->effectiveZoom();
+
+ KisConfig cfg;
+ const int maxLod = cfg.numMipmapLevels();
+
+ int lod = KisLodTransform::scaleToLod(effectiveZoom, maxLod);
+ image->setDesiredLevelOfDetail(lod);
+}
+
void KisCanvas2::preScale()
{
if (!m_d->currentCanvasIsOpenGL) {
@@ -931,6 +953,34 @@ bool KisCanvas2::wrapAroundViewingMode() const
return false;
}
+void KisCanvas2::setLodAllowedInCanvas(bool value)
+{
+#ifdef HAVE_OPENGL
+ m_d->lodAllowedInCanvas =
+ value &&
+ m_d->currentCanvasIsOpenGL &&
+ KisOpenGL::supportsGLSL13();
+#else
+ Q_UNUSED(value);
+ m_d->lodAllowedInCanvas = false;
+#endif
+
+ KisImageSP image = this->image();
+
+ if (m_d->lodAllowedInCanvas != !image->levelOfDetailBlocked()) {
+ image->setLevelOfDetailBlocked(!m_d->lodAllowedInCanvas);
+ notifyLevelOfDetailChange();
+ }
+
+ KisConfig cfg;
+ cfg.setLevelOfDetailEnabled(m_d->lodAllowedInCanvas);
+}
+
+bool KisCanvas2::lodAllowedInCanvas() const
+{
+ return m_d->lodAllowedInCanvas;
+}
+
KoGuidesData *KisCanvas2::guidesData()
{
return &m_d->view->document()->guidesData();
diff --git a/krita/ui/canvas/kis_canvas2.h b/krita/ui/canvas/kis_canvas2.h
index 454aa67..4cd13d7 100644
--- a/krita/ui/canvas/kis_canvas2.h
+++ b/krita/ui/canvas/kis_canvas2.h
@@ -241,6 +241,10 @@ public:
// interface for KisCanvasController only
void setWrapAroundViewingMode(bool value);
bool wrapAroundViewingMode() const;
+
+ void setLodAllowedInCanvas(bool value);
+ bool lodAllowedInCanvas() const;
+
void initializeImage();
// interface for KisViewManager only
void resetCanvas(bool useOpenGL);
@@ -258,6 +262,8 @@ private:
void createOpenGLCanvas();
void updateCanvasWidgetImpl(const QRect &rc = QRect());
+ void notifyLevelOfDetailChange();
+
private:
class KisCanvas2Private;
diff --git a/krita/ui/canvas/kis_canvas_controller.cpp b/krita/ui/canvas/kis_canvas_controller.cpp
index 8b2bcf1..2b33642 100644
--- a/krita/ui/canvas/kis_canvas_controller.cpp
+++ b/krita/ui/canvas/kis_canvas_controller.cpp
@@ -235,3 +235,26 @@ bool KisCanvasController::wrapAroundMode() const
return kritaCanvas->wrapAroundViewingMode();
}
+
+void KisCanvasController::slotToggleLevelOfDetailMode(bool value)
+{
+ KisCanvas2 *kritaCanvas = dynamic_cast<KisCanvas2*>(canvas());
+ Q_ASSERT(kritaCanvas);
+
+ kritaCanvas->setLodAllowedInCanvas(value);
+
+ int result = levelOfDetailMode();
+
+ m_d->view->viewManager()->showFloatingMessage(
+ i18n("Fast Preview Mode (LOD): %1", result ?
+ i18n("ON") : i18n("OFF")),
+ QIcon(), 500, KisFloatingMessage::Low);
+}
+
+bool KisCanvasController::levelOfDetailMode() const
+{
+ KisCanvas2 *kritaCanvas = dynamic_cast<KisCanvas2*>(canvas());
+ Q_ASSERT(kritaCanvas);
+
+ return kritaCanvas->lodAllowedInCanvas();
+}
diff --git a/krita/ui/canvas/kis_canvas_controller.h b/krita/ui/canvas/kis_canvas_controller.h
index 8faa8918..8115ff3 100644
--- a/krita/ui/canvas/kis_canvas_controller.h
+++ b/krita/ui/canvas/kis_canvas_controller.h
@@ -44,6 +44,7 @@ public:
public:
using KoCanvasController::documentSize;
bool wrapAroundMode() const;
+ bool levelOfDetailMode() const;
public Q_SLOTS:
void mirrorCanvas(bool enable);
@@ -52,6 +53,7 @@ public Q_SLOTS:
void rotateCanvasLeft15();
void resetCanvasRotation();
void slotToggleWrapAroundMode(bool value);
+ void slotToggleLevelOfDetailMode(bool value);
Q_SIGNALS:
void documentSizeChanged();
diff --git a/krita/ui/canvas/kis_coordinates_converter.cpp b/krita/ui/canvas/kis_coordinates_converter.cpp
index 544dc42..119e745 100644
--- a/krita/ui/canvas/kis_coordinates_converter.cpp
+++ b/krita/ui/canvas/kis_coordinates_converter.cpp
@@ -181,6 +181,19 @@ void KisCoordinatesConverter::setZoom(qreal zoom)
recalculateTransformations();
}
+qreal KisCoordinatesConverter::effectiveZoom() const
+{
+ qreal scaleX, scaleY;
+ this->imageScale(&scaleX, &scaleY);
+
+ if (scaleX != scaleY) {
+ qWarning() << "WARNING: Zoom is not isotropic!" << ppVar(scaleX) << ppVar(scaleY) << ppVar(qFuzzyCompare(scaleX, scaleY));
+ }
+
+ // zoom by average of x and y
+ return 0.5 * (scaleX + scaleY);
+}
+
QPoint KisCoordinatesConverter::rotate(QPointF center, qreal angle)
{
QTransform rot;
diff --git a/krita/ui/canvas/kis_coordinates_converter.h b/krita/ui/canvas/kis_coordinates_converter.h
index 7711424..e72c683 100644
--- a/krita/ui/canvas/kis_coordinates_converter.h
+++ b/krita/ui/canvas/kis_coordinates_converter.h
@@ -73,7 +73,12 @@ public:
QPoint resetRotation(QPointF center);
virtual void setZoom(qreal zoom);
-
+
+ /**
+ * A composition of to scale methods: zoom level + image resolution
+ */
+ qreal effectiveZoom() const;
+
template<class T> typename _Private::Traits<T>::Result
imageToViewport(const T& obj) const { return _Private::Traits<T>::map(imageToViewportTransform(), obj); }
template<class T> typename _Private::Traits<T>::Result
diff --git a/krita/ui/kis_config.cc b/krita/ui/kis_config.cc
index d9ba199..20204d7 100644
--- a/krita/ui/kis_config.cc
+++ b/krita/ui/kis_config.cc
@@ -1198,6 +1198,15 @@ void KisConfig::setFavoritePresets(const int value)
m_cfg.writeEntry("numFavoritePresets", value);
}
+bool KisConfig::levelOfDetailEnabled(bool defaultValue) const
+{
+ return (defaultValue ? false : m_cfg.readEntry("levelOfDetailEnabled", false));
+}
+
+void KisConfig::setLevelOfDetailEnabled(bool value)
+{
+ m_cfg.writeEntry("levelOfDetailEnabled", value);
+}
KisConfig::OcioColorManagementMode
KisConfig::ocioColorManagementMode(bool defaultValue) const
diff --git a/krita/ui/kis_config.h b/krita/ui/kis_config.h
index c0ce02b..9a90690 100644
--- a/krita/ui/kis_config.h
+++ b/krita/ui/kis_config.h
@@ -324,6 +324,8 @@ public:
int favoritePresets(bool defaultValue = false) const;
void setFavoritePresets(const int value);
+ bool levelOfDetailEnabled(bool defaultValue = false) const;
+ void setLevelOfDetailEnabled(bool value);
enum OcioColorManagementMode {
INTERNAL = 0,
diff --git a/krita/ui/kis_zoom_manager.cc b/krita/ui/kis_zoom_manager.cc
index 6816177..302841d 100644
--- a/krita/ui/kis_zoom_manager.cc
+++ b/krita/ui/kis_zoom_manager.cc
@@ -49,6 +49,8 @@
#include "krita_utils.h"
#include "kis_canvas_resource_provider.h"
#include "opengl/kis_opengl.h"
+#include "kis_lod_transform.h"
+
class KisZoomController : public KoZoomController
@@ -246,43 +248,11 @@ void KisZoomManager::slotZoomChanged(KoZoomMode::Mode mode, qreal zoom)
KritaUtils::prettyFormatReal(humanZoom)),
QIcon(), 500, KisFloatingMessage::Low, Qt::AlignCenter);
}
- qreal scaleX, scaleY;
- m_view->canvasBase()->coordinatesConverter()->imageScale(&scaleX, &scaleY);
- if (scaleX != scaleY) {
- qWarning() << "WARNING: Zoom is not isotropic!" << ppVar(scaleX) << ppVar(scaleY) << ppVar(qFuzzyCompare(scaleX, scaleY));
- }
+ const qreal effectiveZoom =
+ m_view->canvasBase()->coordinatesConverter()->effectiveZoom();
- // zoom by average of x and y
- const qreal effectiveZoom = 0.5 * (scaleX + scaleY);
m_view->canvasBase()->resourceManager()->setResource(KisCanvasResourceProvider::EffectiveZoom, effectiveZoom);
-
- nofityLevelOfDetailChange(effectiveZoom);
-}
-
-void KisZoomManager::nofityLevelOfDetailChange(qreal zoom)
-{
- KisCanvas2 *kritaCanvas = m_view->canvasBase();
-
- int lod = 0;
-
-#ifdef HAVE_OPENGL
-
- if (!kritaCanvas->canvasIsOpenGL() ||
- !KisOpenGL::supportsGLSL13()) {
-
- qWarning() << "WARNING: Level of Detail functionality is available only with openGL + GLSL 1.3 support";
- } else {
- KisConfig cfg;
- const int maxLod = cfg.numMipmapLevels();
-
- lod = qMin(maxLod, qMax(0, qFloor(log2(1.0 / zoom))));
- qDebug() << ppVar(lod);
- }
-#endif // HAVE_OPENGL
-
-
- m_view->image()->setDesiredLevelOfDetail(lod);
}
void KisZoomManager::slotScrollAreaSizeChanged()
diff --git a/krita/ui/kis_zoom_manager.h b/krita/ui/kis_zoom_manager.h
index 3d8e344..592b9d3 100644
--- a/krita/ui/kis_zoom_manager.h
+++ b/krita/ui/kis_zoom_manager.h
@@ -79,9 +79,6 @@ public:
bool verticalRulerVisible() const;
private:
- void nofityLevelOfDetailChange(qreal zoom);
-
-private:
QPointer<KisView> m_view;
KoZoomHandler * m_zoomHandler;
More information about the kimageshop
mailing list