• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kpixmapregionselectorwidget.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, 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"

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal