• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegraphics API Reference
  • KDE Home
  • Contact Us
 

libs/libksane/libksane

  • sources
  • kde-4.14
  • kdegraphics
  • libs
  • libksane
  • libksane
ksane_viewer.cpp
Go to the documentation of this file.
1 /* ============================================================
2 *
3 * This file is part of the KDE project
4 *
5 * Date : 2008-11-15
6 * Description : Preview image viewer that can handle a selection.
7 *
8 * Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) version 3, or any
14 * later version accepted by the membership of KDE e.V. (or its
15 * successor approved by the membership of KDE e.V.), which shall
16 * act as a proxy defined in Section 6 of version 3 of the license.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this program. If not, see <http://www.gnu.org/licenses/>.
25 *
26 * ============================================================ */
27 
28 #include "ksane_viewer.h"
29 #include "ksane_viewer.moc"
30 #include "selectionitem.h"
31 
32 #include <QGraphicsPixmapItem>
33 #include <QGraphicsScene>
34 #include <QGraphicsRectItem>
35 #include <QWheelEvent>
36 #include <QScrollBar>
37 #include <QAction>
38 #include <QList>
39 #include <QVector>
40 #include <KIcon>
41 #include <KLocale>
42 
43 #include <KDebug>
44 
45 #include <math.h>
46 
47 namespace KSaneIface
48 {
49 
50 struct KSaneViewer::Private
51 {
52  QGraphicsScene *scene;
53  SelectionItem *selection;
54  QImage *img;
55 
56  QList<SelectionItem *> selectionList;
57  SelectionItem::Intersects change;
58 
59  QPointF lastSPoint;
60  int m_left_last_x;
61  int m_left_last_y;
62 
63  QAction *zoomInAction;
64  QAction *zoomOutAction;
65  QAction *zoomSelAction;
66  QAction *zoom2FitAction;
67  QAction *clrSelAction;
68 
69  QGraphicsRectItem *hideLeft;
70  QGraphicsRectItem *hideRight;
71  QGraphicsRectItem *hideTop;
72  QGraphicsRectItem *hideBottom;
73  QGraphicsRectItem *hideArea;
74 };
75 
76 KSaneViewer::KSaneViewer(QImage * img, QWidget *parent) : QGraphicsView(parent), d(new Private)
77 {
78  d->img = img;
79 
80  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
81  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
82  setMouseTracking(true);
83 
84  // Init the scene
85  d->scene = new QGraphicsScene;
86  d->scene->setSceneRect(0, 0, img->width(), img->height());
87  setScene(d->scene);
88 
89  d->selection = new SelectionItem(QRectF());
90  d->selection->setZValue(10);
91  d->selection->setSaved(false);
92  d->selection->setMaxRight(img->width());
93  d->selection->setMaxBottom(img->height());
94  d->selection->setRect(d->scene->sceneRect());
95  d->selection->setVisible(false);
96 
97  d->hideTop = new QGraphicsRectItem;
98  d->hideBottom = new QGraphicsRectItem;
99  d->hideRight = new QGraphicsRectItem;
100  d->hideLeft = new QGraphicsRectItem;
101  d->hideArea = new QGraphicsRectItem;
102 
103  d->hideTop->setOpacity(0.4);
104  d->hideBottom->setOpacity(0.4);
105  d->hideRight->setOpacity(0.4);
106  d->hideLeft->setOpacity(0.4);
107  d->hideArea->setOpacity(0.6);
108 
109  d->hideTop->setPen(Qt::NoPen);
110  d->hideBottom->setPen(Qt::NoPen);
111  d->hideRight->setPen(Qt::NoPen);
112  d->hideLeft->setPen(Qt::NoPen);
113  d->hideArea->setPen(Qt::NoPen);
114 
115  d->hideTop->setBrush(QBrush(Qt::black));
116  d->hideBottom->setBrush(QBrush(Qt::black));
117  d->hideRight->setBrush(QBrush(Qt::black));
118  d->hideLeft->setBrush(QBrush(Qt::black));
119 
120  d->scene->addItem(d->selection);
121  d->scene->addItem(d->hideLeft);
122  d->scene->addItem(d->hideRight);
123  d->scene->addItem(d->hideTop);
124  d->scene->addItem(d->hideBottom);
125  d->scene->addItem(d->hideArea);
126 
127  d->change = SelectionItem::None;
128  d->selectionList.clear();
129 
130  // create context menu
131  d->zoomInAction = new QAction(KIcon("zoom-in"), i18n("Zoom In"), this);
132  connect(d->zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn()));
133 
134  d->zoomOutAction = new QAction(KIcon("zoom-out"), i18n("Zoom Out"), this);
135  connect(d->zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut()));
136 
137  d->zoomSelAction = new QAction(KIcon("zoom-fit-best"), i18n("Zoom to Selection"), this);
138  connect(d->zoomSelAction, SIGNAL(triggered()), this, SLOT(zoomSel()));
139 
140  d->zoom2FitAction = new QAction(KIcon("document-preview"), i18n("Zoom to Fit"), this);
141  connect(d->zoom2FitAction, SIGNAL(triggered()), this, SLOT(zoom2Fit()));
142 
143  d->clrSelAction = new QAction(KIcon("edit-clear"), i18n("Clear Selections"), this);
144  connect(d->clrSelAction, SIGNAL(triggered()), this, SLOT(clearSelections()));
145 
146  addAction(d->zoomInAction);
147  addAction(d->zoomOutAction);
148  addAction(d->zoomSelAction);
149  addAction(d->zoom2FitAction);
150  addAction(d->clrSelAction);
151  setContextMenuPolicy(Qt::ActionsContextMenu);
152 }
153 
154 // ------------------------------------------------------------------------
155 void KSaneViewer::drawBackground(QPainter *painter, const QRectF &rect)
156 {
157  painter->fillRect(rect, QColor(0x70, 0x70, 0x70));
158  painter->drawImage(rect, *d->img, rect);
159 }
160 
161 // ------------------------------------------------------------------------
162 KSaneViewer::~KSaneViewer()
163 {
164  // first remove any old saved selections
165  clearSavedSelections();
166 
167  delete d;
168 }
169 
170 // ------------------------------------------------------------------------
171 void KSaneViewer::setQImage(QImage *img)
172 {
173  if (img == 0) return;
174 
175  // remove selections
176  clearSelections();
177 
178  // clear zoom
179  setMatrix(QMatrix());
180 
181  d->scene->setSceneRect(0, 0, img->width(), img->height());
182  d->selection->setMaxRight(img->width());
183  d->selection->setMaxBottom(img->height());
184  d->img = img;
185 }
186 
187 // ------------------------------------------------------------------------
188 void KSaneViewer::updateImage()
189 {
190  setCacheMode(QGraphicsView::CacheNone);
191  repaint();
192  setCacheMode(QGraphicsView::CacheBackground);
193 }
194 
195 // ------------------------------------------------------------------------
196 void KSaneViewer::zoomIn()
197 {
198  scale(1.5, 1.5);
199  d->selection->saveZoom(transform().m11());
200  for (int i=0; i<d->selectionList.size(); ++i) {
201  d->selectionList[i]->saveZoom(transform().m11());
202  }
203 }
204 
205 // ------------------------------------------------------------------------
206 void KSaneViewer::zoomOut()
207 {
208  scale(1.0 / 1.5, 1.0 / 1.5);
209  d->selection->saveZoom(transform().m11());
210  for (int i=0; i<d->selectionList.size(); ++i) {
211  d->selectionList[i]->saveZoom(transform().m11());
212  }
213 }
214 
215 // ------------------------------------------------------------------------
216 void KSaneViewer::zoomSel()
217 {
218  if (d->selection->isVisible()) {
219  fitInView(d->selection->boundingRect() , Qt::KeepAspectRatio);
220  d->selection->saveZoom(transform().m11());
221  for (int i=0; i<d->selectionList.size(); ++i) {
222  d->selectionList[i]->saveZoom(transform().m11());
223  }
224  }
225  else {
226  zoom2Fit();
227  }
228 }
229 
230 // ------------------------------------------------------------------------
231 void KSaneViewer::zoom2Fit()
232 {
233  fitInView(d->img->rect(), Qt::KeepAspectRatio);
234  d->selection->saveZoom(transform().m11());
235  for (int i=0; i<d->selectionList.size(); ++i) {
236  d->selectionList[i]->saveZoom(transform().m11());
237  }
238 }
239 
240 // ------------------------------------------------------------------------
241 void KSaneViewer::setTLX(float ratio)
242 {
243  if (!d->selection->isVisible()) return; // only correct the selection if it is visible
244  QRectF rect = d->selection->rect();
245  rect.setLeft(ratio * d->img->width());
246  d->selection->setRect(rect);
247  updateSelVisibility();
248 }
249 
250 // ------------------------------------------------------------------------
251 void KSaneViewer::setTLY(float ratio)
252 {
253  if (!d->selection->isVisible()) return; // only correct the selection if it is visible
254  QRectF rect = d->selection->rect();
255  rect.setTop(ratio * d->img->height());
256  d->selection->setRect(rect);
257  updateSelVisibility();
258 }
259 
260 // ------------------------------------------------------------------------
261 void KSaneViewer::setBRX(float ratio)
262 {
263  if (!d->selection->isVisible()) return; // only correct the selection if it is visible
264  QRectF rect = d->selection->rect();
265  rect.setRight(ratio * d->img->width());
266  d->selection->setRect(rect);
267  updateSelVisibility();
268 }
269 
270 // ------------------------------------------------------------------------
271 void KSaneViewer::setBRY(float ratio)
272 {
273  if (!d->selection->isVisible()) return; // only correct the selection if it is visible
274  QRectF rect = d->selection->rect();
275  rect.setBottom(ratio * d->img->height());
276  d->selection->setRect(rect);
277  updateSelVisibility();
278 }
279 
280 // ------------------------------------------------------------------------
281 void KSaneViewer::setSelection(float tl_x, float tl_y, float br_x, float br_y)
282 {
283  QRectF rect;
284  rect.setCoords(tl_x * d->img->width(),
285  tl_y * d->img->height(),
286  br_x * d->img->width(),
287  br_y * d->img->height());
288 
289  d->selection->setRect(rect);
290  updateSelVisibility();
291 }
292 
293 // ------------------------------------------------------------------------
294 void KSaneViewer::setHighlightArea(float tl_x, float tl_y, float br_x, float br_y)
295 {
296  QRectF rect;
297 
298  // Left reason for rect: setCoords(x1,y1,x2,y2) != setRect(x1,x2, width, height)
299  rect.setCoords(0,0, tl_x * d->img->width(), d->img->height());
300  d->hideLeft->setRect(rect);
301 
302  // Right
303  rect.setCoords(br_x * d->img->width(),
304  0,
305  d->img->width(),
306  d->img->height());
307  d->hideRight->setRect(rect);
308 
309  // Top
310  rect.setCoords(tl_x * d->img->width(),
311  0,
312  br_x * d->img->width(),
313  tl_y * d->img->height());
314  d->hideTop->setRect(rect);
315 
316  // Bottom
317  rect.setCoords(tl_x * d->img->width(),
318  br_y * d->img->height(),
319  br_x * d->img->width(),
320  d->img->height());
321  d->hideBottom->setRect(rect);
322 
323  // hide area
324  rect.setCoords(tl_x * d->img->width(), tl_y* d->img->height(),
325  br_x * d->img->width(), br_y* d->img->height());
326 
327  d->hideArea->setRect(rect);
328 
329  d->hideLeft->show();
330  d->hideRight->show();
331  d->hideTop->show();
332  d->hideBottom->show();
333  // the hide area is hidden until setHighlightShown is called.
334  d->hideArea->hide();
335 }
336 
337 // ------------------------------------------------------------------------
338 void KSaneViewer::setHighlightShown(int percentage, QColor hideColor)
339 {
340  if (percentage >= 100) {
341  d->hideArea->hide();
342  return;
343  }
344 
345  d->hideArea->setBrush(hideColor);
346 
347  qreal diff = d->hideBottom->rect().top() - d->hideTop->rect().bottom();
348  diff -= (diff * percentage) / 100;
349 
350  QRectF rect = d->hideArea->rect();
351  rect.setTop(d->hideBottom->rect().top() - diff);
352 
353  d->hideArea->setRect(rect);
354 
355  d->hideArea->show();
356 }
357 
358 // ------------------------------------------------------------------------
359 void KSaneViewer::updateHighlight()
360 {
361  if (d->selection->isVisible()) {
362  QRectF rect;
363  // Left
364  rect.setCoords(0,0, d->selection->rect().left(), d->img->height());
365  d->hideLeft->setRect(rect);
366 
367  // Right
368  rect.setCoords(d->selection->rect().right(),
369  0,
370  d->img->width(),
371  d->img->height());
372  d->hideRight->setRect(rect);
373 
374  // Top
375  rect.setCoords(d->selection->rect().left(),
376  0,
377  d->selection->rect().right(),
378  d->selection->rect().top());
379  d->hideTop->setRect(rect);
380 
381  // Bottom
382  rect.setCoords(d->selection->rect().left(),
383  d->selection->rect().bottom(),
384  d->selection->rect().right(),
385  d->img->height());
386  d->hideBottom->setRect(rect);
387 
388  d->hideLeft->show();
389  d->hideRight->show();
390  d->hideTop->show();
391  d->hideBottom->show();
392  d->hideArea->hide();
393  }
394  else {
395  d->hideLeft->hide();
396  d->hideRight->hide();
397  d->hideTop->hide();
398  d->hideBottom->hide();
399  d->hideArea->hide();
400  }
401 }
402 
403 // ------------------------------------------------------------------------
404 void KSaneViewer::clearHighlight()
405 {
406  d->hideLeft
407  ->hide();
408  d->hideRight->hide();
409  d->hideTop->hide();
410  d->hideBottom->hide();
411  d->hideArea->hide();
412 }
413 
414 // ------------------------------------------------------------------------
415 void KSaneViewer::updateSelVisibility()
416 {
417  if ((d->selection->rect().width() >0.001) &&
418  (d->selection->rect().height() > 0.001) &&
419  ((d->img->width() - d->selection->rect().width() > 0.1) ||
420  (d->img->height() - d->selection->rect().height() > 0.1)))
421  {
422  d->selection->setVisible(true);
423  }
424  else {
425  d->selection->setVisible(false);
426  }
427  updateHighlight();
428 }
429 
430 // ---- Return the saved selection list size + 1 if the selection is visible -
431 int KSaneViewer::selListSize() {
432  if (d->selection->isVisible()) {
433  return (d->selectionList.size() + 1);
434  }
435  else {
436  return d->selectionList.size();
437  }
438 }
439 
440 // ---- First return the "saved" selection sthen the active selection -----------
441 bool KSaneViewer::selectionAt(int index, float &tl_x, float &tl_y, float &br_x, float &br_y)
442 {
443  if ((index < 0) || (index > d->selectionList.size())) {
444  activeSelection(tl_x, tl_y, br_x, br_y);
445  return false;
446  }
447  if (index == d->selectionList.size()) {
448  return activeSelection(tl_x, tl_y, br_x, br_y);
449  }
450 
451  tl_x = d->selectionList[index]->rect().left() / d->img->width();
452  tl_y = d->selectionList[index]->rect().top() / d->img->height();
453  br_x = d->selectionList[index]->rect().right() / d->img->width();
454  br_y = d->selectionList[index]->rect().bottom() / d->img->height();
455  return true;
456 }
457 
458 // ------------------------------------------------------------------------
459 bool KSaneViewer::activeSelection(float &tl_x, float &tl_y, float &br_x, float &br_y)
460 {
461  if (!d->selection->isVisible()) {
462  tl_x = 0.0;
463  tl_y = 0.0;
464  br_x = 1.0;
465  br_y = 1.0;
466  return true;
467  }
468 
469  tl_x = d->selection->rect().left() / d->img->width();
470  tl_y = d->selection->rect().top() / d->img->height();
471  br_x = d->selection->rect().right() / d->img->width();
472  br_y = d->selection->rect().bottom() / d->img->height();
473 
474  if ((tl_x == br_x) || (tl_y == br_y)) {
475  tl_x = 0.0;
476  tl_y = 0.0;
477  br_x = 1.0;
478  br_y = 1.0;
479  return false; // just precaution
480  }
481  return true;
482 }
483 
484 // ------------------------------------------------------------------------
485 void KSaneViewer::clearActiveSelection()
486 {
487  d->selection->setRect(QRectF(0,0,0,0));
488  d->selection->intersects(QPointF(100,100)); // don't show the add sign
489  d->selection->setVisible(false);
490 }
491 
492 // ------------------------------------------------------------------------
493 void KSaneViewer::clearSavedSelections()
494 {
495  // first remove any old saved selections
496  SelectionItem *tmp;
497  while (!d->selectionList.isEmpty()) {
498  tmp = d->selectionList.takeFirst();
499  d->scene->removeItem(tmp);
500  delete tmp;
501  }
502 }
503 
504 // ------------------------------------------------------------------------
505 void KSaneViewer::clearSelections()
506 {
507  clearActiveSelection();
508  clearSavedSelections();
509 }
510 
511 // ------------------------------------------------------------------------
512 void KSaneViewer::wheelEvent(QWheelEvent *e)
513 {
514  if(e->modifiers() == Qt::ControlModifier) {
515  if(e->delta() > 0) {
516  zoomIn();
517  } else {
518  zoomOut();
519  }
520  } else {
521  QGraphicsView::wheelEvent(e);
522  }
523 }
524 
525 // ------------------------------------------------------------------------
526 void KSaneViewer::mousePressEvent(QMouseEvent *e)
527 {
528  if (e->button() == Qt::LeftButton)
529  {
530  d->m_left_last_x = e->x();
531  d->m_left_last_y = e->y();
532  QPointF scenePoint = mapToScene(e->pos());
533  d->lastSPoint = scenePoint;
534  if (e->modifiers() != Qt::ControlModifier) {
535  if (!d->selection->isVisible()) {
536  d->selection->setVisible(true);
537  d->selection->setRect(QRectF(scenePoint, QSizeF(0,0)));
538  d->selection->intersects(scenePoint); // just to disable add/remove
539  d->change = SelectionItem::BottomRight;
540  }
541  else if (d->selection->intersects(scenePoint) == SelectionItem::None) {
542  d->selection->setRect(QRectF(scenePoint, QSizeF(0,0)));
543  d->change = SelectionItem::BottomRight;
544  }
545  updateHighlight();
546  }
547  }
548  QGraphicsView::mousePressEvent(e);
549 }
550 
551 // ------------------------------------------------------------------------
552 void KSaneViewer::mouseReleaseEvent(QMouseEvent *e)
553 {
554  bool removed = false;
555  if (e->button() == Qt::LeftButton) {
556  if ((d->selection->rect().width() < 0.001) ||
557  (d->selection->rect().height() < 0.001))
558  {
559  emit newSelection(0.0,0.0, 0.0, 0.0);
560  clearActiveSelection();
561  }
562 
563  QPointF scenePoint = mapToScene(e->pos());
564  for (int i=0; i<d->selectionList.size(); i++) {
565  if (d->selectionList[i]->intersects(scenePoint) == SelectionItem::AddRemove) {
566  d->scene->removeItem(d->selectionList[i]);
567  SelectionItem *tmp = d->selectionList[i];
568  d->selectionList.removeAt(i);
569  d->selection->setVisible(true);
570  d->selection->setRect(tmp->rect());
571  d->selection->intersects(scenePoint); // just to enable add/remove
572  delete tmp;
573  removed = true;
574  break;
575  }
576  }
577  if (!removed && (d->selection->intersects(scenePoint) == SelectionItem::AddRemove)) {
578  // add the current selection
579  SelectionItem *tmp = new SelectionItem(d->selection->rect());
580  d->selectionList.push_back(tmp);
581  d->selectionList.back()->setSaved(true);
582  d->selectionList.back()->saveZoom(transform().m11());
583  d->scene->addItem(d->selectionList.back());
584  d->selectionList.back()->setZValue(9);
585  d->selectionList.back()->intersects(scenePoint);
586 
587  // clear the old one
588  emit newSelection(0.0,0.0, 0.0, 0.0);
589  clearActiveSelection();
590  }
591  }
592 
593  if ((e->modifiers() != Qt::ControlModifier) &&
594  (d->selection->isVisible()) &&
595  (d->img->width() > 0.001) &&
596  (d->img->height() > 0.001))
597  {
598  float tlx = d->selection->rect().left() / d->img->width();
599  float tly = d->selection->rect().top() / d->img->height();
600  float brx = d->selection->rect().right() / d->img->width();
601  float bry = d->selection->rect().bottom() / d->img->height();
602 
603  emit newSelection(tlx, tly, brx, bry);
604  }
605  updateHighlight();
606  QGraphicsView::mouseReleaseEvent(e);
607 }
608 
609 // ------------------------------------------------------------------------
610 void KSaneViewer::mouseMoveEvent(QMouseEvent *e)
611 {
612  QPointF scenePoint = mapToScene(e->pos());
613 
614  if (e->buttons()&Qt::LeftButton)
615  {
616  if (e->modifiers() == Qt::ControlModifier)
617  {
618  int dx = e->x() - d->m_left_last_x;
619  int dy = e->y() - d->m_left_last_y;
620  verticalScrollBar()->setValue(verticalScrollBar()->value()-dy);
621  horizontalScrollBar()->setValue(horizontalScrollBar()->value()-dx);
622  d->m_left_last_x = e->x();
623  d->m_left_last_y = e->y();
624  }
625  else {
626  ensureVisible(QRectF(scenePoint, QSizeF(0,0)), 1, 1);
627  QRectF rect = d->selection->rect();
628  switch (d->change)
629  {
630  case SelectionItem::None:
631  // should not be here :)
632  break;
633  case SelectionItem::Top:
634  if (scenePoint.y() < rect.bottom()) rect.setTop(scenePoint.y());
635  else {
636  d->change = SelectionItem::Bottom;
637  rect.setBottom(scenePoint.y());
638  }
639  break;
640  case SelectionItem::TopRight:
641  if (scenePoint.x() > rect.left()) rect.setRight(scenePoint.x());
642  else {
643  rect.setLeft(scenePoint.x());
644  d->change = SelectionItem::TopLeft;
645  }
646  if (scenePoint.y() < rect.bottom()) rect.setTop(scenePoint.y());
647  else {
648  rect.setBottom(scenePoint.y());
649  d->change = SelectionItem::BottomLeft;
650  } // FIXME arrow
651  break;
652  case SelectionItem::Right:
653  if (scenePoint.x() > rect.left()) rect.setRight(scenePoint.x());
654  else {
655  rect.setLeft(scenePoint.x());
656  d->change = SelectionItem::Left;
657  }
658  break;
659  case SelectionItem::BottomRight:
660  if (scenePoint.x() > rect.left()) rect.setRight(scenePoint.x());
661  else {
662  rect.setLeft(scenePoint.x());
663  d->change = SelectionItem::BottomLeft;
664  }
665  if (scenePoint.y() > rect.top()) rect.setBottom(scenePoint.y());
666  else {
667  rect.setTop(scenePoint.y());
668  d->change = SelectionItem::TopRight;
669  } // FIXME arrow
670  break;
671  case SelectionItem::Bottom:
672  if (scenePoint.y() > rect.top()) rect.setBottom(scenePoint.y());
673  else {
674  d->change = SelectionItem::Top;
675  rect.setTop(scenePoint.y());
676  }
677  break;
678  case SelectionItem::BottomLeft:
679  if (scenePoint.x() < rect.right()) rect.setLeft(scenePoint.x());
680  else {
681  rect.setRight(scenePoint.x());
682  d->change = SelectionItem::BottomRight;
683  }
684  if (scenePoint.y() > rect.top()) rect.setBottom(scenePoint.y());
685  else {
686  rect.setTop(scenePoint.y());
687  d->change = SelectionItem::TopLeft;
688  } // FIXME arrow
689  break;
690  case SelectionItem::Left:
691  if (scenePoint.x() < rect.right()) rect.setLeft(scenePoint.x());
692  else {
693  rect.setRight(scenePoint.x());
694  d->change = SelectionItem::Right;
695  }
696  break;
697  case SelectionItem::TopLeft:
698  if (scenePoint.x() < rect.right()) rect.setLeft(scenePoint.x());
699  else {
700  rect.setRight(scenePoint.x());
701  d->change = SelectionItem::TopRight;
702  }
703  if (scenePoint.y() < rect.bottom()) rect.setTop(scenePoint.y());
704  else {
705  rect.setBottom(scenePoint.y());
706  d->change = SelectionItem::BottomLeft;
707  }// FIXME arrow
708  break;
709  case SelectionItem::Move:
710  rect.translate(d->selection->fixTranslation(scenePoint-d->lastSPoint));
711  break;
712  case SelectionItem::AddRemove:
713  // do nothing
714  break;
715  }
716  d->selection->setRect(rect);
717  }
718  }
719  else if (d->selection->isVisible()) {
720  d->change = d->selection->intersects(scenePoint);
721 
722  switch (d->change)
723  {
724  case SelectionItem::None:
725  viewport()->setCursor(Qt::CrossCursor);
726  break;
727  case SelectionItem::Top:
728  viewport()->setCursor(Qt::SizeVerCursor);
729  break;
730  case SelectionItem::TopRight:
731  viewport()->setCursor(Qt::SizeBDiagCursor);
732  break;
733  case SelectionItem::Right:
734  viewport()->setCursor(Qt::SizeHorCursor);
735  break;
736  case SelectionItem::BottomRight:
737  viewport()->setCursor(Qt::SizeFDiagCursor);
738  break;
739  case SelectionItem::Bottom:
740  viewport()->setCursor(Qt::SizeVerCursor);
741  break;
742  case SelectionItem::BottomLeft:
743  viewport()->setCursor(Qt::SizeBDiagCursor);
744  break;
745  case SelectionItem::Left:
746  viewport()->setCursor(Qt::SizeHorCursor);
747  break;
748  case SelectionItem::TopLeft:
749  viewport()->setCursor(Qt::SizeFDiagCursor);
750  break;
751  case SelectionItem::Move:
752  viewport()->setCursor(Qt::SizeAllCursor);
753  break;
754  case SelectionItem::AddRemove:
755  viewport()->setCursor(Qt::ArrowCursor);
756  break;
757  }
758  }
759  else {
760  viewport()->setCursor(Qt::CrossCursor);
761  }
762 
763  // now check the selection list
764  for (int i=0; i<d->selectionList.size(); i++) {
765  if (d->selectionList[i]->intersects(scenePoint) == SelectionItem::AddRemove) {
766  viewport()->setCursor(Qt::ArrowCursor);
767  }
768  }
769 
770  d->lastSPoint = scenePoint;
771  updateHighlight();
772  QGraphicsView::mouseMoveEvent(e);
773 }
774 
775 // The change trigger before adding to the sum
776 static const int DIFF_TRIGGER = 8;
777 
778 // The selection start/stop level trigger
779 static const int SUM_TRIGGER = 4;
780 
781 // The selection start/stop level trigger for the floating average
782 static const int AVERAGE_TRIGGER = 7;
783 
784 // The selection start/stop margin
785 static const int SEL_MARGIN = 3;
786 
787 // Maximum number of allowed selections (this could be a settable variable)
788 static const int MAX_NUM_SELECTIONS = 8;
789 
790 // floating average 'div' must be one less than 'count'
791 static const int AVERAGE_COUNT = 50;
792 static const int AVERAGE_MULT = 49;
793 
794 // Minimum selection area compared to the whole image
795 static const float MIN_AREA_SIZE = 0.01;
796 // ------------------------------------------------------------------------
797 void KSaneViewer::findSelections(float area)
798 {
799  // Reduce the size of the image to decrease noise and calculation time
800  float multiplier = sqrt(area/(d->img->height() * d->img->width()));
801 
802  int width = (int)(d->img->width() * multiplier);
803  int height = (int)(d->img->height() * multiplier);
804 
805  QImage img = d->img->scaled(width, height, Qt::KeepAspectRatio);
806  height = img.height(); // the size was probably not exact
807  width = img.width();
808 
809  QVector<qint64> colSums(width + SEL_MARGIN + 1);
810  qint64 rowSum;
811  colSums.fill(0);
812  int pix;
813  int diff;
814  int hSelStart=-1;
815  int hSelEnd=-1;
816  int hSelMargin = 0;
817  int wSelStart=-1;
818  int wSelEnd=-1;
819  int wSelMargin = 0;
820 
821  for (int h=1; h<height; h++) {
822  rowSum = 0;
823  if (h<height-1) {
824  // Special case for the left most pixel
825  pix = qGray(img.pixel(0, h));
826  diff = qAbs(pix - qGray(img.pixel(1, h)));
827  diff += qAbs(pix - qGray(img.pixel(0, h-1)));
828  diff += qAbs(pix - qGray(img.pixel(0, h+1)));
829  if (diff > DIFF_TRIGGER) {
830  colSums[0] += diff;
831  rowSum += diff;
832  }
833 
834  // Special case for the right most pixel
835  pix = qGray(img.pixel(width - 1, h));
836  diff = qAbs(pix - qGray(img.pixel(width - 2, h)));
837  diff += qAbs(pix - qGray(img.pixel(width - 1, h-1)));
838  diff += qAbs(pix - qGray(img.pixel(width - 1, h+1)));
839  if (diff > DIFF_TRIGGER) {
840  colSums[width - 1] += diff;
841  rowSum += diff;
842  }
843 
844  for (int w=1; w < (width - 1); w++) {
845  pix = qGray(img.pixel(w, h));
846  diff = 0;
847  // how much does the pixel differ from the surrounding
848  diff += qAbs(pix - qGray(img.pixel(w - 1, h)));
849  diff += qAbs(pix - qGray(img.pixel(w + 1, h)));
850  diff += qAbs(pix - qGray(img.pixel(w, h - 1)));
851  diff += qAbs(pix - qGray(img.pixel(w, h + 1)));
852  if (diff > DIFF_TRIGGER) {
853  colSums[w] += diff;
854  rowSum += diff;
855  }
856  }
857  }
858 
859  if ((rowSum/width) > SUM_TRIGGER) {
860  if (hSelStart < 0) {
861  if (hSelMargin < SEL_MARGIN) hSelMargin++;
862  if (hSelMargin == SEL_MARGIN) hSelStart = h - SEL_MARGIN + 1;
863  }
864  }
865  else {
866  if (hSelStart >= 0) {
867  if (hSelMargin > 0) hSelMargin--;
868  }
869  if ((hSelStart > -1) && ((hSelMargin == 0) || (h==height-1))) {
870  if (h==height-1) {
871  hSelEnd = h - hSelMargin;
872  }
873  else {
874  hSelEnd = h - SEL_MARGIN;
875  }
876  // We have the end of the vertical selection
877  // now figure out the horizontal part of the selection
878  for (int w=0; w <= width; w++) { // colSums[width] will be 0
879  if ((colSums[w]/(h - hSelStart)) > SUM_TRIGGER) {
880  if (wSelStart < 0) {
881  if (wSelMargin < SEL_MARGIN) wSelMargin++;
882  if (wSelMargin == SEL_MARGIN) wSelStart = w - SEL_MARGIN + 1;
883  }
884  }
885  else {
886  if (wSelStart >= 0) {
887  if (wSelMargin > 0) wSelMargin--;
888  }
889  if ((wSelStart >= 0) && ((wSelMargin == 0) || (w == width))) {
890  if (w == width) {
891  wSelEnd = width;
892  }
893  else {
894  wSelEnd = w - SEL_MARGIN +1;
895  }
896 
897  // we have the end of a horizontal selection
898  if ((wSelEnd-wSelStart) < width) {
899  // skip selections that span the whole width
900  // calculate the coordinates in the original size
901  int x1 = wSelStart / multiplier;
902  int y1 = hSelStart / multiplier;
903  int x2 = wSelEnd / multiplier;
904  int y2 = hSelEnd / multiplier;
905  float selArea = (float)(wSelEnd - wSelStart) * (float)(hSelEnd-hSelStart);
906  if (selArea > (area * MIN_AREA_SIZE)) {
907  SelectionItem *tmp = new SelectionItem(QRect(QPoint(x1, y1), QPoint(x2, y2)));
908  d->selectionList.push_back(tmp);
909  d->selectionList.back()->setSaved(true);
910  d->selectionList.back()->saveZoom(transform().m11());
911  d->scene->addItem(d->selectionList.back());
912  d->selectionList.back()->setZValue(9);
913  }
914  }
915  wSelStart = -1;
916  wSelEnd = -1;
917  wSelMargin = 0;
918  }
919  }
920  }
921  hSelStart = -1;
922  hSelEnd = -1;
923  hSelMargin = 0;
924  colSums.fill(0);
925  }
926  }
927  }
928 
929  if (d->selectionList.size() > MAX_NUM_SELECTIONS) {
930  // smaller area or should we give up??
931  clearSavedSelections();
932  //findSelections(area/2);
933  // instead of trying to find probably broken selections just give up
934  // and do not force broken selections on the user.
935  }
936  else {
937  // 1/multiplier is the error margin caused by the resolution reduction
938  refineSelections(qRound(1/multiplier));
939  // check that the selections are big enough
940  float minArea = d->img->height() * d->img->width() * MIN_AREA_SIZE;
941 
942  int i = 0;
943  while (i < d->selectionList.size()) {
944  if ((d->selectionList[i]->rect().width() * d->selectionList[i]->rect().height()) < minArea) {
945  d->scene->removeItem(d->selectionList[i]);
946  d->selectionList.removeAt(i);
947  }
948  else {
949  i++;
950  }
951  }
952  }
953 }
954 
955 QSize KSaneViewer::sizeHint() const
956 {
957  return QSize(250, 300); // a sensible size for a scan preview
958 }
959 
960 void KSaneViewer::refineSelections(int pixelMargin)
961 {
962  // The end result
963  int hSelStart;
964  int hSelEnd;
965  int wSelStart;
966  int wSelEnd;
967 
968  for (int i=0; i<d->selectionList.size(); i++) {
969  QRectF selRect = d->selectionList.at(i)->rect();
970 
971  // original values
972  hSelStart = (int)selRect.top();
973  hSelEnd = (int)selRect.bottom();
974  wSelStart = (int)selRect.left();
975  wSelEnd = (int)selRect.right();
976 
977  // Top
978  // Too long iteration should not be a problem since the loop should be interrupted by the limit
979  hSelStart = refineRow(hSelStart - pixelMargin, hSelEnd, wSelStart, wSelEnd);
980 
981  // Bottom (from the bottom up wards)
982  hSelEnd = refineRow(hSelEnd + pixelMargin, hSelStart, wSelStart, wSelEnd);
983 
984  // Left
985  wSelStart = refineColumn(wSelStart - pixelMargin, wSelEnd, hSelStart, hSelEnd);
986 
987  // Right
988  wSelEnd = refineColumn(wSelEnd + pixelMargin, wSelStart, hSelStart, hSelEnd);
989 
990  // Now update the selection
991  d->selectionList.at(i)->setRect(QRectF(QPointF(wSelStart, hSelStart), QPointF(wSelEnd, hSelEnd)));
992  }
993 }
994 
995 int KSaneViewer::refineRow(int fromRow, int toRow, int colStart, int colEnd)
996 {
997  int pix;
998  int diff;
999  float rowTrigger;
1000  int row;
1001  int addSub = (fromRow < toRow) ? 1 : -1;
1002 
1003  colStart -= 2; //add some margin
1004  colEnd += 2; //add some margin
1005 
1006  if (colStart < 1) colStart = 1;
1007  if (colEnd >= d->img->width()-1) colEnd = d->img->width() - 2;
1008 
1009  if (fromRow < 1) fromRow = 1;
1010  if (fromRow >= d->img->height()-1) fromRow = d->img->height() - 2;
1011 
1012  if (toRow < 1) toRow = 1;
1013  if (toRow >= d->img->height()-1) toRow = d->img->height() - 2;
1014 
1015  row = fromRow;
1016  while (row != toRow) {
1017  rowTrigger = 0;
1018  for (int w=colStart; w<colEnd; w++) {
1019  diff = 0;
1020  pix = qGray(d->img->pixel(w, row));
1021  // how much does the pixel differ from the surrounding
1022  diff += qAbs(pix - qGray(d->img->pixel(w-1, row)));
1023  diff += qAbs(pix - qGray(d->img->pixel(w+1, row)));
1024  diff += qAbs(pix - qGray(d->img->pixel(w, row-1)));
1025  diff += qAbs(pix - qGray(d->img->pixel(w, row+1)));
1026  if (diff <= DIFF_TRIGGER) diff = 0;
1027 
1028  rowTrigger = ((rowTrigger * AVERAGE_MULT) + diff) / AVERAGE_COUNT;
1029 
1030  if (rowTrigger > AVERAGE_TRIGGER) {
1031  break;
1032  }
1033  }
1034 
1035  if (rowTrigger > AVERAGE_TRIGGER) {
1036  // row == 1 _probably_ means that the selection should start from 0
1037  // but that can not be detected if we start from 1 => include one extra column
1038  if (row == 1) row = 0;
1039  if (row == (d->img->width() -2)) row = d->img->width();
1040  return row;
1041  }
1042  row += addSub;
1043  }
1044  return row;
1045 }
1046 
1047 int KSaneViewer::refineColumn(int fromCol, int toCol, int rowStart, int rowEnd)
1048 {
1049  int pix;
1050  int diff;
1051  float colTrigger;
1052  int col;
1053  int count;
1054  int addSub = (fromCol < toCol) ? 1 : -1;
1055 
1056  rowStart -= 2; //add some margin
1057  rowEnd += 2; //add some margin
1058 
1059  if (rowStart < 1) rowStart = 1;
1060  if (rowEnd >= d->img->height()-1) rowEnd = d->img->height() - 2;
1061 
1062  if (fromCol < 1) fromCol = 1;
1063  if (fromCol >= d->img->width()-1) fromCol = d->img->width() - 2;
1064 
1065  if (toCol < 1) toCol = 1;
1066  if (toCol >= d->img->width()-1) toCol = d->img->width() - 2;
1067 
1068  col = fromCol;
1069  while (col != toCol) {
1070  colTrigger = 0;
1071  count = 0;
1072  for (int row=rowStart; row<rowEnd; row++) {
1073  count++;
1074  diff = 0;
1075  pix = qGray(d->img->pixel(col, row));
1076  // how much does the pixel differ from the surrounding
1077  diff += qAbs(pix - qGray(d->img->pixel(col-1, row)));
1078  diff += qAbs(pix - qGray(d->img->pixel(col+1, row)));
1079  diff += qAbs(pix - qGray(d->img->pixel(col, row-1)));
1080  diff += qAbs(pix - qGray(d->img->pixel(col, row+1)));
1081  if (diff <= DIFF_TRIGGER) diff = 0;
1082 
1083  colTrigger = ((colTrigger * AVERAGE_MULT) + diff) / AVERAGE_COUNT;
1084 
1085  if (colTrigger > AVERAGE_TRIGGER) {
1086  break;
1087  }
1088  }
1089 
1090  if (colTrigger > AVERAGE_TRIGGER) {
1091  // col == 1 _probably_ means that the selection should start from 0
1092  // but that can not be detected if we start from 1 => include one extra column
1093  if (col == 1) col = 0;
1094  if (col == (d->img->width() -2)) col = d->img->width();
1095  return col;
1096  }
1097  col += addSub;
1098  }
1099  return col;
1100 }
1101 
1102 } // NameSpace KSaneIface
QGraphicsView::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *event)
QWidget
KSaneIface::SelectionItem::None
Definition: selectionitem.h:41
KSaneIface::DIFF_TRIGGER
static const int DIFF_TRIGGER
Definition: ksane_viewer.cpp:776
QGraphicsScene
QWidget::setCursor
void setCursor(const QCursor &)
KSaneIface::KSaneViewer::mousePressEvent
void mousePressEvent(QMouseEvent *e)
Definition: ksane_viewer.cpp:526
QPainter::fillRect
void fillRect(const QRectF &rectangle, const QBrush &brush)
QGraphicsView::setMatrix
void setMatrix(const QMatrix &matrix, bool combine)
KSaneIface::SelectionItem::Right
Definition: selectionitem.h:44
KSaneIface::KSaneViewer::setQImage
void setQImage(QImage *img)
Definition: ksane_viewer.cpp:171
QWidget::addAction
void addAction(QAction *action)
QRectF::setRight
void setRight(qreal x)
KSaneIface::KSaneViewer::zoom2Fit
void zoom2Fit()
Definition: ksane_viewer.cpp:231
KSaneIface::SUM_TRIGGER
static const int SUM_TRIGGER
Definition: ksane_viewer.cpp:779
QVector::fill
QVector< T > & fill(const T &value, int size)
QMouseEvent::x
int x() const
QMouseEvent::y
int y() const
QGraphicsView::mapToScene
QPointF mapToScene(const QPoint &point) const
KSaneIface::KSaneViewer::setHighlightArea
void setHighlightArea(float tl_x, float tl_y, float br_x, float br_y)
This function is used to darken everything except what is inside the given area.
Definition: ksane_viewer.cpp:294
QWheelEvent
KSaneIface::KSaneViewer::zoomOut
void zoomOut()
Definition: ksane_viewer.cpp:206
QGraphicsView::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event)
QAbstractScrollArea::viewport
QWidget * viewport() const
QRectF::top
qreal top() const
QBrush
KSaneIface::KSaneViewer::setTLY
void setTLY(float ratio)
Definition: ksane_viewer.cpp:251
QPoint
QMouseEvent
QMouseEvent::buttons
Qt::MouseButtons buttons() const
KSaneIface::SelectionItem::rect
QRectF rect()
Definition: selectionitem.cpp:212
QGraphicsView::scene
QGraphicsScene * scene() const
KSaneIface::SelectionItem
Definition: selectionitem.h:36
KSaneIface::SelectionItem::Move
Definition: selectionitem.h:50
KSaneIface::SelectionItem::Intersects
Intersects
Definition: selectionitem.h:39
QRectF::left
qreal left() const
KSaneIface::KSaneViewer::setBRX
void setBRX(float ratio)
Definition: ksane_viewer.cpp:261
QRectF::setLeft
void setLeft(qreal x)
KSaneIface::SelectionItem::Top
Definition: selectionitem.h:42
QPointF
QWidget::width
int width() const
KSaneIface::KSaneViewer::setSelection
void setSelection(float tl_x, float tl_y, float br_x, float br_y)
This function is used to set a selection without the user setting it.
Definition: ksane_viewer.cpp:281
QRectF::bottom
qreal bottom() const
QGraphicsView::scale
void scale(qreal sx, qreal sy)
KSaneIface::KSaneViewer::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *e)
Definition: ksane_viewer.cpp:552
QRect
QGraphicsView::transform
QTransform transform() const
QImage::pixel
QRgb pixel(int x, int y) const
QPointF::x
qreal x() const
QPointF::y
qreal y() const
QRectF::translate
void translate(qreal dx, qreal dy)
KSaneIface::KSaneViewer::drawBackground
void drawBackground(QPainter *painter, const QRectF &rect)
Definition: ksane_viewer.cpp:155
KSaneIface::KSaneViewer::~KSaneViewer
~KSaneViewer()
Definition: ksane_viewer.cpp:162
KSaneIface::SelectionItem::Left
Definition: selectionitem.h:48
KSaneIface::KSaneViewer::setHighlightShown
void setHighlightShown(int percentage, QColor hideColor=Qt::white)
This function sets the percentage of the highlighted area that is visible.
Definition: ksane_viewer.cpp:338
QImage::width
int width() const
QMouseEvent::button
Qt::MouseButton button() const
QAbstractScrollArea::setHorizontalScrollBarPolicy
void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy)
QPainter
KSaneIface::KSaneViewer::updateImage
void updateImage()
Definition: ksane_viewer.cpp:188
KSaneIface::KSaneViewer::setTLX
void setTLX(float ratio)
Definition: ksane_viewer.cpp:241
KSaneIface::KSaneViewer::findSelections
void findSelections(float area=10000.0)
Find selections in the picture.
Definition: ksane_viewer.cpp:797
KSaneIface::AVERAGE_MULT
static const int AVERAGE_MULT
Definition: ksane_viewer.cpp:792
KSaneIface::AVERAGE_COUNT
static const int AVERAGE_COUNT
Definition: ksane_viewer.cpp:791
QGraphicsView::setScene
void setScene(QGraphicsScene *scene)
ksane_viewer.h
QList
QColor
KSaneIface::KSaneViewer::clearSelections
void clearSelections()
Definition: ksane_viewer.cpp:505
QGraphicsView::setCacheMode
void setCacheMode(QFlags< QGraphicsView::CacheModeFlag > mode)
QAbstractScrollArea::verticalScrollBar
QScrollBar * verticalScrollBar() const
KSaneIface::SelectionItem::TopLeft
Definition: selectionitem.h:49
KSaneIface::KSaneViewer::KSaneViewer
KSaneViewer(QImage *img, QWidget *parent=0)
Definition: ksane_viewer.cpp:76
KSaneIface::KSaneViewer::sizeHint
virtual QSize sizeHint() const
Definition: ksane_viewer.cpp:955
QWidget::rect
QRect rect() const
KSaneIface::KSaneViewer::zoomIn
void zoomIn()
Definition: ksane_viewer.cpp:196
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
KSaneIface::AVERAGE_TRIGGER
static const int AVERAGE_TRIGGER
Definition: ksane_viewer.cpp:782
QRectF::right
qreal right() const
QSize
QGraphicsView::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event)
QWidget::setContextMenuPolicy
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
QAbstractSlider::setValue
void setValue(int)
QImage
KSaneIface::KSaneViewer::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *e)
Definition: ksane_viewer.cpp:610
QWheelEvent::delta
int delta() const
KSaneIface::KSaneViewer::clearSavedSelections
void clearSavedSelections()
Definition: ksane_viewer.cpp:493
QWidget::repaint
void repaint()
KSaneIface::SelectionItem::TopRight
Definition: selectionitem.h:43
QGraphicsView::ensureVisible
void ensureVisible(const QRectF &rect, int xmargin, int ymargin)
KSaneIface::MAX_NUM_SELECTIONS
static const int MAX_NUM_SELECTIONS
Definition: ksane_viewer.cpp:788
KSaneIface::MIN_AREA_SIZE
static const float MIN_AREA_SIZE
Definition: ksane_viewer.cpp:795
KSaneIface::KSaneViewer::setBRY
void setBRY(float ratio)
Definition: ksane_viewer.cpp:271
QPainter::drawImage
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
QVector
KSaneIface::SEL_MARGIN
static const int SEL_MARGIN
Definition: ksane_viewer.cpp:785
QSizeF
QRectF::setBottom
void setBottom(qreal y)
QGraphicsRectItem
QRectF::setCoords
void setCoords(qreal x1, qreal y1, qreal x2, qreal y2)
QRectF
QRectF::setTop
void setTop(qreal y)
KSaneIface::KSaneViewer::selectionAt
bool selectionAt(int index, float &tl_x, float &tl_y, float &br_x, float &br_y)
Definition: ksane_viewer.cpp:441
QAction
QMatrix
selectionitem.h
QWidget::setMouseTracking
void setMouseTracking(bool enable)
KSaneIface::SelectionItem::BottomLeft
Definition: selectionitem.h:47
QAbstractScrollArea::horizontalScrollBar
QScrollBar * horizontalScrollBar() const
QImage::height
int height() const
KSaneIface::SelectionItem::AddRemove
Definition: selectionitem.h:51
KSaneIface::KSaneViewer::clearActiveSelection
void clearActiveSelection()
Definition: ksane_viewer.cpp:485
KSaneIface::KSaneViewer::newSelection
void newSelection(float tl_x, float tl_y, float br_x, float br_y)
QMouseEvent::pos
const QPoint & pos() const
KSaneIface::SelectionItem::Bottom
Definition: selectionitem.h:46
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KSaneIface::KSaneViewer::clearHighlight
void clearHighlight()
This function removes the highlight area.
Definition: ksane_viewer.cpp:404
KSaneIface::KSaneViewer::selListSize
int selListSize()
Definition: ksane_viewer.cpp:431
QAbstractScrollArea::setVerticalScrollBarPolicy
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy)
QGraphicsView
QGraphicsView::wheelEvent
virtual void wheelEvent(QWheelEvent *event)
QWidget::height
int height() const
KSaneIface::KSaneViewer::zoomSel
void zoomSel()
Definition: ksane_viewer.cpp:216
KSaneIface::KSaneViewer::wheelEvent
void wheelEvent(QWheelEvent *e)
Definition: ksane_viewer.cpp:512
KSaneIface::SelectionItem::BottomRight
Definition: selectionitem.h:45
QGraphicsView::fitInView
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:19:47 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libs/libksane/libksane

Skip menu "libs/libksane/libksane"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdegraphics API Reference

Skip menu "kdegraphics API Reference"
  •     libkdcraw
  •     libkexiv2
  •     libkipi
  •     libksane
  • okular

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal