27#include <QtGui/QPainter>
28#include <QtGui/QColor>
29#include <QtGui/QImage>
31#include <QtGui/QLayout>
39#include <QtGui/QCursor>
40#include <QtGui/QApplication>
44class KPixmapRegionSelectorWidget::Private
57 QRect calcSelectionRectangle(
const QPoint &startPoint,
const QPoint & endPoint );
59 enum CursorState {
None=0, Resizing, Moving };
62 QPixmap m_unzoomedPixmap;
63 QPixmap m_originalPixmap;
64 QPixmap m_linedPixmap;
65 QRect m_selectedRegion;
68 QPoint m_tempFirstClick;
69 double m_forcedAspectRatio;
71 int m_maxWidth, m_maxHeight;
74 QRubberBand *m_rubberBand;
78 :
QWidget( parent ), d(new Private(this))
80 QHBoxLayout * hboxLayout=
new QHBoxLayout(
this );
82 hboxLayout->addStretch();
83 QVBoxLayout * vboxLayout=
new QVBoxLayout();
84 hboxLayout->addItem(vboxLayout);
86 vboxLayout->addStretch();
87 d->m_label =
new QLabel(
this);
88 d->m_label->setAttribute(Qt::WA_NoSystemBackground,
true);
89 d->m_label->installEventFilter(
this );
91 vboxLayout->addWidget(d->m_label);
92 vboxLayout->addStretch();
94 hboxLayout->addStretch();
96 d->m_forcedAspectRatio=0;
99 d->m_rubberBand =
new QRubberBand(QRubberBand::Rectangle, d->m_label);
100 d->m_rubberBand->hide();
110 return d->m_unzoomedPixmap;
115 Q_ASSERT(!pixmap.isNull());
116 d->m_originalPixmap = pixmap;
117 d->m_unzoomedPixmap = pixmap;
118 d->m_label->setPixmap( pixmap );
124 d->m_selectedRegion = d->m_originalPixmap.rect();
125 d->m_rubberBand->hide();
131 return d->m_selectedRegion;
139 d->m_selectedRegion=rect;
144void KPixmapRegionSelectorWidget::Private::updatePixmap()
146 Q_ASSERT(!m_originalPixmap.isNull());
147 if (m_originalPixmap.isNull()) { m_label->setPixmap(m_originalPixmap);
return; }
148 if (m_selectedRegion.width()>m_originalPixmap.width()) m_selectedRegion.setWidth( m_originalPixmap.width() );
149 if (m_selectedRegion.height()>m_originalPixmap.height()) m_selectedRegion.setHeight( m_originalPixmap.height() );
152 if (m_linedPixmap.isNull())
154 m_linedPixmap = m_originalPixmap;
155 QPainter p(&m_linedPixmap);
156 p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
157 p.fillRect(m_linedPixmap.rect(), QColor(0, 0, 0, 100));
160 QPixmap pixmap = m_linedPixmap;
161 painter.begin(&pixmap);
162 painter.drawPixmap( m_selectedRegion.topLeft(),
163 m_originalPixmap, m_selectedRegion );
168 m_label->setPixmap(pixmap);
170 qApp->sendPostedEvents(0,QEvent::LayoutRequest);
172 if (m_selectedRegion == m_originalPixmap.rect())
173 m_rubberBand->hide();
176 m_rubberBand->setGeometry(QRect(m_selectedRegion.topLeft(),
177 m_selectedRegion.size()));
182 if (m_state!=None) m_rubberBand->show();
192 popup->setObjectName(
"PixmapRegionSelectorPopup");
196 action->setText(
i18n(
"&Rotate Clockwise"));
197 action->setIcon(
KIcon(
"object-rotate-right" ) );
198 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(
rotateClockwise()) );
200 popup->addAction(action);
202 action = actions->
addAction(
"rotatecounterclockwise");
203 action->setText(
i18n(
"Rotate &Counterclockwise"));
204 action->setIcon(
KIcon(
"object-rotate-left" ) );
207 popup->addAction(action);
218 int w=d->m_originalPixmap.width();
219 int h=d->m_originalPixmap.height();
220 QImage img=d->m_unzoomedPixmap.toImage();
222 img = img.transformed(QTransform().
rotate(90.0));
224 img = img.transformed(QTransform().
rotate(180.0));
226 img = img.transformed(QTransform().
rotate(270.0));
228 d->m_unzoomedPixmap=QPixmap::fromImage(img);
230 img=d->m_originalPixmap.toImage();
232 img = img.transformed(QTransform().
rotate(90.0));
234 img = img.transformed(QTransform().
rotate(180.0));
236 img = img.transformed(QTransform().
rotate(270.0));
238 d->m_originalPixmap=QPixmap::fromImage(img);
240 d->m_linedPixmap=QPixmap();
242 if (d->m_forcedAspectRatio>0 && d->m_forcedAspectRatio!=1)
250 int x=h-d->m_selectedRegion.y()-d->m_selectedRegion.height();
251 int y=d->m_selectedRegion.x();
252 d->m_selectedRegion.setRect(x, y, d->m_selectedRegion.height(), d->m_selectedRegion.width() );
260 int x=d->m_selectedRegion.y();
261 int y=w-d->m_selectedRegion.x()-d->m_selectedRegion.width();
262 d->m_selectedRegion.setRect(x, y, d->m_selectedRegion.height(), d->m_selectedRegion.width() );
284bool KPixmapRegionSelectorWidget::eventFilter(
QObject *obj, QEvent *ev)
286 if ( ev->type() == QEvent::MouseButtonPress )
288 QMouseEvent *mev= (QMouseEvent *)(ev);
291 if ( mev->button() == Qt::RightButton )
293 KMenu *popup = createPopupMenu( );
294 popup->exec( mev->globalPos() );
301 if ( d->m_selectedRegion.contains( mev->pos() )
302 && d->m_selectedRegion!=d->m_originalPixmap.rect() )
304 d->m_state=Private::Moving;
305 cursor.setShape( Qt::SizeAllCursor );
306 d->m_rubberBand->show();
310 d->m_state=Private::Resizing;
311 cursor.setShape( Qt::CrossCursor );
313 QApplication::setOverrideCursor(cursor);
315 d->m_tempFirstClick=mev->pos();
321 if ( ev->type() == QEvent::MouseMove )
323 QMouseEvent *mev= (QMouseEvent *)(ev);
327 if ( d->m_state == Private::Resizing )
330 d->calcSelectionRectangle( d->m_tempFirstClick, mev->pos() ) );
332 else if (d->m_state == Private::Moving )
336 bool mouseOutside=
false;
339 d->m_selectedRegion.translate(-d->m_selectedRegion.x(),0);
342 else if ( mevx > d->m_originalPixmap.width() )
344 d->m_selectedRegion.translate(d->m_originalPixmap.width()-d->m_selectedRegion.width()-d->m_selectedRegion.x(),0);
349 d->m_selectedRegion.translate(0,-d->m_selectedRegion.y());
352 else if ( mevy > d->m_originalPixmap.height() )
354 d->m_selectedRegion.translate(0,d->m_originalPixmap.height()-d->m_selectedRegion.height()-d->m_selectedRegion.y());
357 if (mouseOutside) { d->updatePixmap();
return true; };
359 d->m_selectedRegion.translate( mev->x()-d->m_tempFirstClick.x(),
360 mev->y()-d->m_tempFirstClick.y() );
363 if (d->m_selectedRegion.x() < 0)
364 d->m_selectedRegion.translate(-d->m_selectedRegion.x(),0);
365 else if (d->m_selectedRegion.right() > d->m_originalPixmap.width())
366 d->m_selectedRegion.translate(-(d->m_selectedRegion.right()-d->m_originalPixmap.width()),0);
368 if (d->m_selectedRegion.y() < 0)
369 d->m_selectedRegion.translate(0,-d->m_selectedRegion.y());
370 else if (d->m_selectedRegion.bottom() > d->m_originalPixmap.height())
371 d->m_selectedRegion.translate(0,-(d->m_selectedRegion.bottom()-d->m_originalPixmap.height()));
373 d->m_tempFirstClick=mev->pos();
379 if ( ev->type() == QEvent::MouseButtonRelease )
381 QMouseEvent *mev= (QMouseEvent *)(ev);
383 if ( d->m_state == Private::Resizing && mev->pos() == d->m_tempFirstClick)
386 d->m_state=Private::None;
387 QApplication::restoreOverrideCursor();
388 d->m_rubberBand->hide();
392 QWidget::eventFilter(obj, ev);
396QRect KPixmapRegionSelectorWidget::Private::calcSelectionRectangle(
const QPoint & startPoint,
const QPoint & _endPoint )
398 QPoint endPoint = _endPoint;
399 if ( endPoint.x() < 0 ) endPoint.setX(0);
400 else if ( endPoint.x() > m_originalPixmap.width() ) endPoint.setX(m_originalPixmap.width());
401 if ( endPoint.y() < 0 ) endPoint.setY(0);
402 else if ( endPoint.y() > m_originalPixmap.height() ) endPoint.setY(m_originalPixmap.height());
403 int w=abs(startPoint.x()-endPoint.x());
404 int h=abs(startPoint.y()-endPoint.y());
406 if (m_forcedAspectRatio>0)
408 double aspectRatio=w/double(h);
410 if (aspectRatio>m_forcedAspectRatio)
411 h=(int)(w/m_forcedAspectRatio);
413 w=(int)(h*m_forcedAspectRatio);
417 if ( startPoint.x() < endPoint.x() )
421 if ( startPoint.y() < endPoint.y() )
430 h=(int)(w/m_forcedAspectRatio);
432 if ( startPoint.y() > endPoint.y() )
435 else if (x+w>m_originalPixmap.width())
437 w=m_originalPixmap.width()-x;
438 h=(int)(w/m_forcedAspectRatio);
440 if ( startPoint.y() > endPoint.y() )
447 w=(int)(h*m_forcedAspectRatio);
449 if ( startPoint.x() > endPoint.x() )
452 else if (y+h>m_originalPixmap.height())
454 h=m_originalPixmap.height()-y;
455 w=(int)(h*m_forcedAspectRatio);
457 if ( startPoint.x() > endPoint.x() )
461 return QRect(x,y,w,h);
466 return QRect((
int)(d->m_selectedRegion.x()/d->m_zoomFactor),
467 (
int)(d->m_selectedRegion.y()/d->m_zoomFactor),
468 (
int)(d->m_selectedRegion.width()/d->m_zoomFactor),
469 (
int)(d->m_selectedRegion.height()/d->m_zoomFactor));
474 QImage origImage=d->m_unzoomedPixmap.toImage();
480 d->m_forcedAspectRatio=width/double(height);
485 d->m_forcedAspectRatio=0;
491 d->m_maxHeight=height;
493 if (d->m_selectedRegion == d->m_originalPixmap.rect()) d->m_selectedRegion=QRect();
494 d->m_originalPixmap=d->m_unzoomedPixmap;
499 if ( !d->m_originalPixmap.isNull() &&
500 ( d->m_originalPixmap.width() > d->m_maxWidth ||
501 d->m_originalPixmap.height() > d->m_maxHeight ) )
504 QImage image=d->m_originalPixmap.toImage();
505 d->m_originalPixmap=QPixmap::fromImage( image.scaled( width, height, Qt::KeepAspectRatio,Qt::SmoothTransformation ) );
506 double oldZoomFactor = d->m_zoomFactor;
507 d->m_zoomFactor=d->m_originalPixmap.width()/(double)d->m_unzoomedPixmap.width();
509 if (d->m_selectedRegion.isValid())
512 QRect((
int)(d->m_selectedRegion.x()*d->m_zoomFactor/oldZoomFactor),
513 (
int)(d->m_selectedRegion.y()*d->m_zoomFactor/oldZoomFactor),
514 (
int)(d->m_selectedRegion.width()*d->m_zoomFactor/oldZoomFactor),
515 (
int)(d->m_selectedRegion.height()*d->m_zoomFactor/oldZoomFactor) );
519 if (!d->m_selectedRegion.isValid()) d->m_selectedRegion = d->m_originalPixmap.rect();
521 d->m_linedPixmap=QPixmap();
523 resize(d->m_label->width(), d->m_label->height());
526#include "kpixmapregionselectorwidget.moc"
A container for a set of QAction objects.
QAction * addAction(const QString &name, QAction *action)
Add an action under the given name to the collection.
A wrapper around QIcon that provides KDE icon features.
QString i18n(const char *text)