00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "kpixmapregionselectorwidget.h"
00029 #include <qpainter.h>
00030 #include <qcolor.h>
00031 #include <qimage.h>
00032 #include <qlayout.h>
00033 #include <kimageeffect.h>
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kpopupmenu.h>
00037 #include <kaction.h>
00038 #include <stdlib.h>
00039 #include <qcursor.h>
00040 #include <qapplication.h>
00041
00042 using namespace KPIM;
00043
00044 KPixmapRegionSelectorWidget::KPixmapRegionSelectorWidget( QWidget *parent,
00045 const char *name) : QWidget( parent, name)
00046 {
00047 QHBoxLayout * hboxLayout=new QHBoxLayout( this );
00048
00049 hboxLayout->addStretch();
00050 QVBoxLayout * vboxLayout=new QVBoxLayout( hboxLayout );
00051
00052 vboxLayout->addStretch();
00053 m_label = new QLabel(this, "pixmapHolder");
00054 m_label->setBackgroundMode( Qt::NoBackground );
00055 m_label->installEventFilter( this );
00056
00057 vboxLayout->addWidget(m_label);
00058 vboxLayout->addStretch();
00059
00060 hboxLayout->addStretch();
00061
00062 m_forcedAspectRatio=0;
00063
00064 m_zoomFactor=1.0;
00065 }
00066
00067 KPixmapRegionSelectorWidget::~KPixmapRegionSelectorWidget()
00068 {
00069 }
00070
00071 void KPixmapRegionSelectorWidget::setPixmap( const QPixmap &pixmap )
00072 {
00073 Q_ASSERT(!pixmap.isNull());
00074 m_originalPixmap = pixmap;
00075 m_unzoomedPixmap = pixmap;
00076 m_label->setPixmap( pixmap );
00077 resetSelection();
00078 }
00079
00080 void KPixmapRegionSelectorWidget::resetSelection()
00081 {
00082 m_selectedRegion = m_originalPixmap.rect();
00083 updatePixmap();
00084 }
00085
00086 QRect KPixmapRegionSelectorWidget::selectedRegion() const
00087 {
00088 return m_selectedRegion;
00089 }
00090
00091 void KPixmapRegionSelectorWidget::setSelectedRegion(const QRect &rect)
00092 {
00093 if (!rect.isValid()) resetSelection();
00094 else
00095 {
00096 m_selectedRegion=rect;
00097 updatePixmap();
00098
00099 QRect r=unzoomedSelectedRegion();
00100 }
00101 }
00102
00103 void KPixmapRegionSelectorWidget::updatePixmap()
00104 {
00105 Q_ASSERT(!m_originalPixmap.isNull()); if(m_originalPixmap.isNull()) { m_label->setPixmap(m_originalPixmap); return; }
00106 if (m_selectedRegion.width()>m_originalPixmap.width()) m_selectedRegion.setWidth( m_originalPixmap.width() );
00107 if (m_selectedRegion.height()>m_originalPixmap.height()) m_selectedRegion.setHeight( m_originalPixmap.height() );
00108
00109 QPainter painter;
00110 if (m_linedPixmap.isNull())
00111 {
00112 m_linedPixmap = m_originalPixmap;
00113
00114 painter.begin(&m_linedPixmap);
00115 painter.setRasterOp( Qt::XorROP );
00116 painter.fillRect(0,0,m_linedPixmap.width(), m_linedPixmap.height(),
00117 QBrush( QColor(255,255,255), Qt::BDiagPattern) );
00118 painter.end();
00119
00120 QImage image=m_linedPixmap.convertToImage();
00121 image=KImageEffect::fade(image, 0.4, QColor(0,0,0));
00122 m_linedPixmap.convertFromImage(image);
00123 }
00124
00125 QPixmap pixmap = m_linedPixmap;
00126
00127 painter.begin(&pixmap);
00128 painter.drawPixmap( m_selectedRegion.topLeft(),
00129 m_originalPixmap, m_selectedRegion );
00130
00131 painter.setPen( QColor(255,255,255) );
00132 painter.setRasterOp( Qt::XorROP );
00133
00134 painter.drawRect( m_selectedRegion );
00135
00136 painter.end();
00137
00138 m_label->setPixmap(pixmap);
00139 }
00140
00141 KPopupMenu *KPixmapRegionSelectorWidget::createPopupMenu()
00142 {
00143 KPopupMenu *popup=new KPopupMenu(this, "PixmapRegionSelectorPopup");
00144 popup->insertTitle(i18n("Image Operations"));
00145
00146 KAction *action = new KAction(i18n("&Rotate Clockwise"), "rotate_cw",
00147 0, this, SLOT(rotateClockwise()),
00148 popup, "rotateclockwise");
00149 action->plug(popup);
00150
00151 action = new KAction(i18n("Rotate &Counterclockwise"), "rotate_ccw",
00152 0, this, SLOT(rotateCounterclockwise()),
00153 popup, "rotatecounterclockwise");
00154 action->plug(popup);
00155
00156
00157
00158
00159
00160 return popup;
00161 }
00162
00163 void KPixmapRegionSelectorWidget::rotate(KImageEffect::RotateDirection direction)
00164 {
00165 int w=m_originalPixmap.width();
00166 int h=m_originalPixmap.height();
00167 QImage img=m_unzoomedPixmap.convertToImage();
00168 img= KImageEffect::rotate(img, direction);
00169 m_unzoomedPixmap.convertFromImage(img);
00170
00171 img=m_originalPixmap.convertToImage();
00172 img= KImageEffect::rotate(img, direction);
00173 m_originalPixmap.convertFromImage(img);
00174
00175 m_linedPixmap=QPixmap();
00176
00177 if (m_forcedAspectRatio>0 && m_forcedAspectRatio!=1)
00178 resetSelection();
00179 else
00180 {
00181 switch (direction)
00182 {
00183 case ( KImageEffect::Rotate90 ):
00184 {
00185 int x=h-m_selectedRegion.y()-m_selectedRegion.height();
00186 int y=m_selectedRegion.x();
00187 m_selectedRegion.setRect(x, y, m_selectedRegion.height(), m_selectedRegion.width() );
00188 updatePixmap();
00189 } break;
00190 case ( KImageEffect::Rotate270 ):
00191 {
00192 int x=m_selectedRegion.y();
00193 int y=w-m_selectedRegion.x()-m_selectedRegion.width();
00194 m_selectedRegion.setRect(x, y, m_selectedRegion.height(), m_selectedRegion.width() );
00195 updatePixmap();
00196 } break;
00197 default: resetSelection();
00198 }
00199 }
00200 }
00201
00202 void KPixmapRegionSelectorWidget::rotateClockwise()
00203 {
00204 rotate(KImageEffect::Rotate90);
00205 }
00206
00207 void KPixmapRegionSelectorWidget::rotateCounterclockwise()
00208 {
00209 rotate(KImageEffect::Rotate270);
00210 }
00211
00212
00213
00214 bool KPixmapRegionSelectorWidget::eventFilter(QObject *obj, QEvent *ev)
00215 {
00216 if ( ev->type() == QEvent::MouseButtonPress )
00217 {
00218 QMouseEvent *mev= (QMouseEvent *)(ev);
00219
00220
00221 if ( mev->button() == RightButton )
00222 {
00223 KPopupMenu *popup = createPopupMenu( );
00224 popup->exec( mev->globalPos() );
00225 delete popup;
00226 return TRUE;
00227 };
00228
00229 QCursor cursor;
00230 if ( m_selectedRegion.contains( mev->pos() )
00231 && m_selectedRegion!=m_originalPixmap.rect() )
00232 {
00233 m_state=Moving;
00234 cursor=QCursor(Qt::SizeAllCursor);
00235 }
00236 else
00237 {
00238 m_state=Resizing;
00239 cursor=QCursor(Qt::CrossCursor);
00240 }
00241 QApplication::setOverrideCursor(cursor);
00242
00243 m_tempFirstClick=mev->pos();
00244
00245 return TRUE;
00246 }
00247
00248 if ( ev->type() == QEvent::MouseMove )
00249 {
00250 QMouseEvent *mev= (QMouseEvent *)(ev);
00251
00252
00253
00254 if ( m_state == Resizing )
00255 {
00256 setSelectedRegion (
00257 calcSelectionRectangle( m_tempFirstClick, mev->pos() ) );
00258 }
00259 else if (m_state == Moving )
00260 {
00261 int mevx = mev->x();
00262 int mevy = mev->y();
00263 bool mouseOutside=false;
00264 if ( mevx < 0 )
00265 {
00266 m_selectedRegion.moveBy(-m_selectedRegion.x(),0);
00267 mouseOutside=true;
00268 }
00269 else if ( mevx > m_originalPixmap.width() )
00270 {
00271 m_selectedRegion.moveBy(m_originalPixmap.width()-m_selectedRegion.width()-m_selectedRegion.x(),0);
00272 mouseOutside=true;
00273 }
00274 if ( mevy < 0 )
00275 {
00276 m_selectedRegion.moveBy(0,-m_selectedRegion.y());
00277 mouseOutside=true;
00278 }
00279 else if ( mevy > m_originalPixmap.height() )
00280 {
00281 m_selectedRegion.moveBy(0,m_originalPixmap.height()-m_selectedRegion.height()-m_selectedRegion.y());
00282 mouseOutside=true;
00283 }
00284 if (mouseOutside) { updatePixmap(); return TRUE; };
00285
00286 m_selectedRegion.moveBy( mev->x()-m_tempFirstClick.x(),
00287 mev->y()-m_tempFirstClick.y() );
00288
00289
00290 if (m_selectedRegion.x() < 0)
00291 m_selectedRegion.moveBy(-m_selectedRegion.x(),0);
00292 else if (m_selectedRegion.right() > m_originalPixmap.width())
00293 m_selectedRegion.moveBy(-(m_selectedRegion.right()-m_originalPixmap.width()),0);
00294
00295 if (m_selectedRegion.y() < 0)
00296 m_selectedRegion.moveBy(0,-m_selectedRegion.y());
00297 else if (m_selectedRegion.bottom() > m_originalPixmap.height())
00298 m_selectedRegion.moveBy(0,-(m_selectedRegion.bottom()-m_originalPixmap.height()));
00299
00300 m_tempFirstClick=mev->pos();
00301 updatePixmap();
00302 }
00303 return TRUE;
00304 }
00305
00306 if ( ev->type() == QEvent::MouseButtonRelease )
00307 {
00308 QMouseEvent *mev= (QMouseEvent *)(ev);
00309
00310 if ( m_state == Resizing && mev->pos() == m_tempFirstClick)
00311 resetSelection();
00312
00313 m_state=None;
00314 QApplication::restoreOverrideCursor();
00315
00316 return TRUE;
00317 }
00318
00319 QWidget::eventFilter(obj, ev);
00320 return FALSE;
00321 }
00322
00323 QRect KPixmapRegionSelectorWidget::calcSelectionRectangle( const QPoint & startPoint, const QPoint & _endPoint )
00324 {
00325 QPoint endPoint = _endPoint;
00326 if ( endPoint.x() < 0 ) endPoint.setX(0);
00327 else if ( endPoint.x() > m_originalPixmap.width() ) endPoint.setX(m_originalPixmap.width());
00328 if ( endPoint.y() < 0 ) endPoint.setY(0);
00329 else if ( endPoint.y() > m_originalPixmap.height() ) endPoint.setY(m_originalPixmap.height());
00330 int w=abs(startPoint.x()-endPoint.x());
00331 int h=abs(startPoint.y()-endPoint.y());
00332
00333 if (m_forcedAspectRatio>0)
00334 {
00335 double aspectRatio=w/double(h);
00336
00337 if (aspectRatio>m_forcedAspectRatio)
00338 h=(int)(w/m_forcedAspectRatio);
00339 else
00340 w=(int)(h*m_forcedAspectRatio);
00341 }
00342
00343 int x,y;
00344 if ( startPoint.x() < endPoint.x() )
00345 x=startPoint.x();
00346 else
00347 x=startPoint.x()-w;
00348 if ( startPoint.y() < endPoint.y() )
00349 y=startPoint.y();
00350 else
00351 y=startPoint.y()-h;
00352
00353 if (x<0)
00354 {
00355 w+=x;
00356 x=0;
00357 h=(int)(w/m_forcedAspectRatio);
00358
00359 if ( startPoint.y() > endPoint.y() )
00360 y=startPoint.y()-h;
00361 }
00362 else if (x+w>m_originalPixmap.width())
00363 {
00364 w=m_originalPixmap.width()-x;
00365 h=(int)(w/m_forcedAspectRatio);
00366
00367 if ( startPoint.y() > endPoint.y() )
00368 y=startPoint.y()-h;
00369 }
00370 if (y<0)
00371 {
00372 h+=y;
00373 y=0;
00374 w=(int)(h*m_forcedAspectRatio);
00375
00376 if ( startPoint.x() > endPoint.x() )
00377 x=startPoint.x()-w;
00378 }
00379 else if (y+h>m_originalPixmap.height())
00380 {
00381 h=m_originalPixmap.height()-y;
00382 w=(int)(h*m_forcedAspectRatio);
00383
00384 if ( startPoint.x() > endPoint.x() )
00385 x=startPoint.x()-w;
00386 }
00387
00388 return QRect(x,y,w,h);
00389 }
00390
00391 QRect KPixmapRegionSelectorWidget::unzoomedSelectedRegion() const
00392 {
00393 return QRect((int)(m_selectedRegion.x()/m_zoomFactor),
00394 (int)(m_selectedRegion.y()/m_zoomFactor),
00395 (int)(m_selectedRegion.width()/m_zoomFactor),
00396 (int)(m_selectedRegion.height()/m_zoomFactor));
00397 }
00398
00399 QImage KPixmapRegionSelectorWidget::selectedImage() const
00400 {
00401 QImage origImage=m_unzoomedPixmap.convertToImage();
00402 return origImage.copy(unzoomedSelectedRegion());
00403 }
00404
00405 void KPixmapRegionSelectorWidget::setSelectionAspectRatio(int width, int height)
00406 {
00407 m_forcedAspectRatio=width/double(height);
00408 }
00409
00410 void KPixmapRegionSelectorWidget::setFreeSelectionAspectRatio()
00411 {
00412 m_forcedAspectRatio=0;
00413 }
00414
00415 void KPixmapRegionSelectorWidget::setMaximumWidgetSize(int width, int height)
00416 {
00417 m_maxWidth=width;
00418 m_maxHeight=height;
00419
00420 m_originalPixmap=m_unzoomedPixmap;
00421 if (m_selectedRegion == m_originalPixmap.rect()) m_selectedRegion=QRect();
00422
00423
00424
00425
00426 if ( !m_originalPixmap.isNull() &&
00427 ( m_originalPixmap.width() > m_maxWidth ||
00428 m_originalPixmap.height() > m_maxHeight ) )
00429 {
00430
00431 QImage image=m_originalPixmap.convertToImage();
00432 m_originalPixmap.convertFromImage( image.smoothScale( width, height, QImage::ScaleMin ) );
00433
00434 double oldZoomFactor = m_zoomFactor;
00435 m_zoomFactor=m_originalPixmap.width()/(double)m_unzoomedPixmap.width();
00436
00437 if (m_selectedRegion.isValid())
00438 {
00439 m_selectedRegion=
00440 QRect((int)(m_selectedRegion.x()*m_zoomFactor/oldZoomFactor),
00441 (int)(m_selectedRegion.y()*m_zoomFactor/oldZoomFactor),
00442 (int)(m_selectedRegion.width()*m_zoomFactor/oldZoomFactor),
00443 (int)(m_selectedRegion.height()*m_zoomFactor/oldZoomFactor) );
00444 }
00445 }
00446
00447 if (!m_selectedRegion.isValid()) m_selectedRegion = m_originalPixmap.rect();
00448
00449 m_linedPixmap=QPixmap();
00450 updatePixmap();
00451 resize(m_label->width(), m_label->height());
00452 }
00453
00454 #include "kpixmapregionselectorwidget.moc"