| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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"

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:20 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003