kdeui Library API Documentation

kpixmapregionselectorwidget.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2004 Antonio Larrosa <larrosa@kde.org 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 /* NOTE: There are two copies of this .h and the .cpp file, with subtle differences. 00021 * One copy is in kdelibs/kdeui, and the other copy is in kdepim/libkdepim 00022 * This is because kdepim has to remain backwards compatible. Any changes 00023 * to either file should be made to the other. 00024 */ 00025 00026 #include "kpixmapregionselectorwidget.h" 00027 #include <qpainter.h> 00028 #include <qcolor.h> 00029 #include <qimage.h> 00030 #include <qlayout.h> 00031 #include <kimageeffect.h> 00032 #include <kdebug.h> 00033 #include <klocale.h> 00034 #include <kpopupmenu.h> 00035 #include <kaction.h> 00036 #include <stdlib.h> 00037 #include <qcursor.h> 00038 #include <qapplication.h> 00039 00040 KPixmapRegionSelectorWidget::KPixmapRegionSelectorWidget( QWidget *parent, 00041 const char *name) : QWidget( parent, name) 00042 { 00043 QHBoxLayout * hboxLayout=new QHBoxLayout( this ); 00044 00045 hboxLayout->addStretch(); 00046 QVBoxLayout * vboxLayout=new QVBoxLayout( hboxLayout ); 00047 00048 vboxLayout->addStretch(); 00049 m_label = new QLabel(this, "pixmapHolder"); 00050 m_label->setBackgroundMode( Qt::NoBackground ); 00051 m_label->installEventFilter( this ); 00052 00053 vboxLayout->addWidget(m_label); 00054 vboxLayout->addStretch(); 00055 00056 hboxLayout->addStretch(); 00057 00058 m_forcedAspectRatio=0; 00059 00060 m_zoomFactor=1.0; 00061 } 00062 00063 KPixmapRegionSelectorWidget::~KPixmapRegionSelectorWidget() 00064 { 00065 } 00066 00067 void KPixmapRegionSelectorWidget::setPixmap( const QPixmap &pixmap ) 00068 { 00069 Q_ASSERT(!pixmap.isNull()); //This class isn't designed to deal with null pixmaps. 00070 m_originalPixmap = pixmap; 00071 m_unzoomedPixmap = pixmap; 00072 m_label->setPixmap( pixmap ); 00073 resetSelection(); 00074 } 00075 00076 void KPixmapRegionSelectorWidget::resetSelection() 00077 { 00078 m_selectedRegion = m_originalPixmap.rect(); 00079 updatePixmap(); 00080 } 00081 00082 QRect KPixmapRegionSelectorWidget::selectedRegion() const 00083 { 00084 return m_selectedRegion; 00085 } 00086 00087 void KPixmapRegionSelectorWidget::setSelectedRegion(const QRect &rect) 00088 { 00089 if (!rect.isValid()) resetSelection(); 00090 else 00091 { 00092 m_selectedRegion=rect; 00093 updatePixmap(); 00094 00095 QRect r=unzoomedSelectedRegion(); 00096 } 00097 } 00098 00099 void KPixmapRegionSelectorWidget::updatePixmap() 00100 { 00101 Q_ASSERT(!m_originalPixmap.isNull()); if(m_originalPixmap.isNull()) { m_label->setPixmap(m_originalPixmap); return; } 00102 if (m_selectedRegion.width()>m_originalPixmap.width()) m_selectedRegion.setWidth( m_originalPixmap.width() ); 00103 if (m_selectedRegion.height()>m_originalPixmap.height()) m_selectedRegion.setHeight( m_originalPixmap.height() ); 00104 00105 QPainter painter; 00106 if (m_linedPixmap.isNull()) 00107 { 00108 m_linedPixmap = m_originalPixmap; 00109 00110 painter.begin(&m_linedPixmap); 00111 painter.setRasterOp( Qt::XorROP ); 00112 painter.fillRect(0,0,m_linedPixmap.width(), m_linedPixmap.height(), 00113 QBrush( QColor(255,255,255), Qt::BDiagPattern) ); 00114 painter.end(); 00115 00116 QImage image=m_linedPixmap.convertToImage(); 00117 image=KImageEffect::fade(image, (float)0.4, QColor(0,0,0)); 00118 m_linedPixmap.convertFromImage(image); 00119 } 00120 00121 QPixmap pixmap = m_linedPixmap; 00122 00123 painter.begin(&pixmap); 00124 painter.drawPixmap( m_selectedRegion.topLeft(), 00125 m_originalPixmap, m_selectedRegion ); 00126 00127 painter.setPen( QColor(255,255,255) ); 00128 painter.setRasterOp( Qt::XorROP ); 00129 00130 painter.drawRect( m_selectedRegion ); 00131 00132 painter.end(); 00133 00134 m_label->setPixmap(pixmap); 00135 } 00136 00137 00138 KPopupMenu *KPixmapRegionSelectorWidget::createPopupMenu() 00139 { 00140 KPopupMenu *popup=new KPopupMenu(this, "PixmapRegionSelectorPopup"); 00141 popup->insertTitle(i18n("Image Operations")); 00142 00143 KAction *action = new KAction(i18n("&Rotate Clockwise"), "rotate_cw", 00144 0, this, SLOT(rotateClockwise()), 00145 popup, "rotateclockwise"); 00146 action->plug(popup); 00147 00148 action = new KAction(i18n("Rotate &Counterclockwise"), "rotate_ccw", 00149 0, this, SLOT(rotateCounterclockwise()), 00150 popup, "rotatecounterclockwise"); 00151 action->plug(popup); 00152 00153 /* 00154 I wonder if it would be appropiate to have here an "Open with..." option to 00155 edit the image (antlarr) 00156 */ 00157 return popup; 00158 } 00159 00160 void KPixmapRegionSelectorWidget::rotate(KImageEffect::RotateDirection direction) 00161 { 00162 int w=m_originalPixmap.width(); 00163 int h=m_originalPixmap.height(); 00164 QImage img=m_unzoomedPixmap.convertToImage(); 00165 img= KImageEffect::rotate(img, direction); 00166 m_unzoomedPixmap.convertFromImage(img); 00167 00168 img=m_originalPixmap.convertToImage(); 00169 img= KImageEffect::rotate(img, direction); 00170 m_originalPixmap.convertFromImage(img); 00171 00172 m_linedPixmap=QPixmap(); 00173 00174 if (m_forcedAspectRatio>0 && m_forcedAspectRatio!=1) 00175 resetSelection(); 00176 else 00177 { 00178 switch (direction) 00179 { 00180 case ( KImageEffect::Rotate90 ): 00181 { 00182 int x=h-m_selectedRegion.y()-m_selectedRegion.height(); 00183 int y=m_selectedRegion.x(); 00184 m_selectedRegion.setRect(x, y, m_selectedRegion.height(), m_selectedRegion.width() ); 00185 updatePixmap(); 00186 } break; 00187 case ( KImageEffect::Rotate270 ): 00188 { 00189 int x=m_selectedRegion.y(); 00190 int y=w-m_selectedRegion.x()-m_selectedRegion.width(); 00191 m_selectedRegion.setRect(x, y, m_selectedRegion.height(), m_selectedRegion.width() ); 00192 updatePixmap(); 00193 } break; 00194 default: resetSelection(); 00195 } 00196 } 00197 } 00198 00199 void KPixmapRegionSelectorWidget::rotateClockwise() 00200 { 00201 rotate(KImageEffect::Rotate90); 00202 } 00203 00204 void KPixmapRegionSelectorWidget::rotateCounterclockwise() 00205 { 00206 rotate(KImageEffect::Rotate270); 00207 } 00208 00209 bool KPixmapRegionSelectorWidget::eventFilter(QObject *obj, QEvent *ev) 00210 { 00211 if ( ev->type() == QEvent::MouseButtonPress ) 00212 { 00213 QMouseEvent *mev= (QMouseEvent *)(ev); 00214 //kdDebug() << QString("click at %1,%2").arg( mev->x() ).arg( mev->y() ) << endl; 00215 00216 if ( mev->button() == RightButton ) 00217 { 00218 KPopupMenu *popup = createPopupMenu( ); 00219 popup->exec( mev->globalPos() ); 00220 delete popup; 00221 return TRUE; 00222 }; 00223 00224 QCursor cursor; 00225 00226 if ( m_selectedRegion.contains( mev->pos() ) 00227 && m_selectedRegion!=m_originalPixmap.rect() ) 00228 { 00229 m_state=Moving; 00230 cursor.setShape( Qt::SizeAllCursor ); 00231 } 00232 else 00233 { 00234 m_state=Resizing; 00235 cursor.setShape( Qt::CrossCursor ); 00236 } 00237 QApplication::setOverrideCursor(cursor); 00238 00239 m_tempFirstClick=mev->pos(); 00240 00241 00242 return TRUE; 00243 } 00244 00245 if ( ev->type() == QEvent::MouseMove ) 00246 { 00247 QMouseEvent *mev= (QMouseEvent *)(ev); 00248 00249 //kdDebug() << QString("move to %1,%2").arg( mev->x() ).arg( mev->y() ) << endl; 00250 00251 if ( m_state == Resizing ) 00252 { 00253 setSelectedRegion ( 00254 calcSelectionRectangle( m_tempFirstClick, mev->pos() ) ); 00255 } 00256 else if (m_state == Moving ) 00257 { 00258 int mevx = mev->x(); 00259 int mevy = mev->y(); 00260 bool mouseOutside=false; 00261 if ( mevx < 0 ) 00262 { 00263 m_selectedRegion.moveBy(-m_selectedRegion.x(),0); 00264 mouseOutside=true; 00265 } 00266 else if ( mevx > m_originalPixmap.width() ) 00267 { 00268 m_selectedRegion.moveBy(m_originalPixmap.width()-m_selectedRegion.width()-m_selectedRegion.x(),0); 00269 mouseOutside=true; 00270 } 00271 if ( mevy < 0 ) 00272 { 00273 m_selectedRegion.moveBy(0,-m_selectedRegion.y()); 00274 mouseOutside=true; 00275 } 00276 else if ( mevy > m_originalPixmap.height() ) 00277 { 00278 m_selectedRegion.moveBy(0,m_originalPixmap.height()-m_selectedRegion.height()-m_selectedRegion.y()); 00279 mouseOutside=true; 00280 } 00281 if (mouseOutside) { updatePixmap(); return TRUE; }; 00282 00283 m_selectedRegion.moveBy( mev->x()-m_tempFirstClick.x(), 00284 mev->y()-m_tempFirstClick.y() ); 00285 00286 // Check that the region has not fallen outside the image 00287 if (m_selectedRegion.x() < 0) 00288 m_selectedRegion.moveBy(-m_selectedRegion.x(),0); 00289 else if (m_selectedRegion.right() > m_originalPixmap.width()) 00290 m_selectedRegion.moveBy(-(m_selectedRegion.right()-m_originalPixmap.width()),0); 00291 00292 if (m_selectedRegion.y() < 0) 00293 m_selectedRegion.moveBy(0,-m_selectedRegion.y()); 00294 else if (m_selectedRegion.bottom() > m_originalPixmap.height()) 00295 m_selectedRegion.moveBy(0,-(m_selectedRegion.bottom()-m_originalPixmap.height())); 00296 00297 m_tempFirstClick=mev->pos(); 00298 updatePixmap(); 00299 } 00300 return TRUE; 00301 } 00302 00303 if ( ev->type() == QEvent::MouseButtonRelease ) 00304 { 00305 QMouseEvent *mev= (QMouseEvent *)(ev); 00306 00307 if ( m_state == Resizing && mev->pos() == m_tempFirstClick) 00308 resetSelection(); 00309 00310 m_state=None; 00311 QApplication::restoreOverrideCursor(); 00312 00313 return TRUE; 00314 } 00315 00316 QWidget::eventFilter(obj, ev); 00317 return FALSE; 00318 } 00319 00320 QRect KPixmapRegionSelectorWidget::calcSelectionRectangle( const QPoint & startPoint, const QPoint & _endPoint ) 00321 { 00322 QPoint endPoint = _endPoint; 00323 if ( endPoint.x() < 0 ) endPoint.setX(0); 00324 else if ( endPoint.x() > m_originalPixmap.width() ) endPoint.setX(m_originalPixmap.width()); 00325 if ( endPoint.y() < 0 ) endPoint.setY(0); 00326 else if ( endPoint.y() > m_originalPixmap.height() ) endPoint.setY(m_originalPixmap.height()); 00327 int w=abs(startPoint.x()-endPoint.x()); 00328 int h=abs(startPoint.y()-endPoint.y()); 00329 00330 if (m_forcedAspectRatio>0) 00331 { 00332 double aspectRatio=w/double(h); 00333 00334 if (aspectRatio>m_forcedAspectRatio) 00335 h=(int)(w/m_forcedAspectRatio); 00336 else 00337 w=(int)(h*m_forcedAspectRatio); 00338 } 00339 00340 int x,y; 00341 if ( startPoint.x() < endPoint.x() ) 00342 x=startPoint.x(); 00343 else 00344 x=startPoint.x()-w; 00345 if ( startPoint.y() < endPoint.y() ) 00346 y=startPoint.y(); 00347 else 00348 y=startPoint.y()-h; 00349 00350 if (x<0) 00351 { 00352 w+=x; 00353 x=0; 00354 h=(int)(w/m_forcedAspectRatio); 00355 00356 if ( startPoint.y() > endPoint.y() ) 00357 y=startPoint.y()-h; 00358 } 00359 else if (x+w>m_originalPixmap.width()) 00360 { 00361 w=m_originalPixmap.width()-x; 00362 h=(int)(w/m_forcedAspectRatio); 00363 00364 if ( startPoint.y() > endPoint.y() ) 00365 y=startPoint.y()-h; 00366 } 00367 if (y<0) 00368 { 00369 h+=y; 00370 y=0; 00371 w=(int)(h*m_forcedAspectRatio); 00372 00373 if ( startPoint.x() > endPoint.x() ) 00374 x=startPoint.x()-w; 00375 } 00376 else if (y+h>m_originalPixmap.height()) 00377 { 00378 h=m_originalPixmap.height()-y; 00379 w=(int)(h*m_forcedAspectRatio); 00380 00381 if ( startPoint.x() > endPoint.x() ) 00382 x=startPoint.x()-w; 00383 } 00384 00385 return QRect(x,y,w,h); 00386 } 00387 00388 QRect KPixmapRegionSelectorWidget::unzoomedSelectedRegion() const 00389 { 00390 return QRect((int)(m_selectedRegion.x()/m_zoomFactor), 00391 (int)(m_selectedRegion.y()/m_zoomFactor), 00392 (int)(m_selectedRegion.width()/m_zoomFactor), 00393 (int)(m_selectedRegion.height()/m_zoomFactor)); 00394 } 00395 00396 QImage KPixmapRegionSelectorWidget::selectedImage() const 00397 { 00398 QImage origImage=m_unzoomedPixmap.convertToImage(); 00399 return origImage.copy(unzoomedSelectedRegion()); 00400 } 00401 00402 void KPixmapRegionSelectorWidget::setSelectionAspectRatio(int width, int height) 00403 { 00404 m_forcedAspectRatio=width/double(height); 00405 } 00406 00407 void KPixmapRegionSelectorWidget::setFreeSelectionAspectRatio() 00408 { 00409 m_forcedAspectRatio=0; 00410 } 00411 00412 void KPixmapRegionSelectorWidget::setMaximumWidgetSize(int width, int height) 00413 { 00414 m_maxWidth=width; 00415 m_maxHeight=height; 00416 00417 m_originalPixmap=m_unzoomedPixmap; 00418 if (m_selectedRegion == m_originalPixmap.rect()) m_selectedRegion=QRect(); 00419 00420 // kdDebug() << QString(" original Pixmap :") << m_originalPixmap.rect() << endl; 00421 // kdDebug() << QString(" unzoomed Pixmap : %1 x %2 ").arg(m_unzoomedPixmap.width()).arg(m_unzoomedPixmap.height()) << endl; 00422 00423 if ( !m_originalPixmap.isNull() && 00424 ( m_originalPixmap.width() > m_maxWidth || 00425 m_originalPixmap.height() > m_maxHeight ) ) 00426 { 00427 /* We have to resize the pixmap to get it complete on the screen */ 00428 QImage image=m_originalPixmap.convertToImage(); 00429 m_originalPixmap.convertFromImage( image.smoothScale( width, height, QImage::ScaleMin ) ); 00430 double oldZoomFactor = m_zoomFactor; 00431 m_zoomFactor=m_originalPixmap.width()/(double)m_unzoomedPixmap.width(); 00432 00433 if (m_selectedRegion.isValid()) 00434 { 00435 m_selectedRegion= 00436 QRect((int)(m_selectedRegion.x()*m_zoomFactor/oldZoomFactor), 00437 (int)(m_selectedRegion.y()*m_zoomFactor/oldZoomFactor), 00438 (int)(m_selectedRegion.width()*m_zoomFactor/oldZoomFactor), 00439 (int)(m_selectedRegion.height()*m_zoomFactor/oldZoomFactor) ); 00440 } 00441 } 00442 00443 if (!m_selectedRegion.isValid()) m_selectedRegion = m_originalPixmap.rect(); 00444 00445 m_linedPixmap=QPixmap(); 00446 updatePixmap(); 00447 resize(m_label->width(), m_label->height()); 00448 } 00449 00450 #include "kpixmapregionselectorwidget.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:10:14 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003