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
#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());
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
00155
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
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
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
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
00421
00422
00423
if ( !m_originalPixmap.isNull() &&
00424 ( m_originalPixmap.width() > m_maxWidth ||
00425 m_originalPixmap.height() > m_maxHeight ) )
00426 {
00427
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"