00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include <qlayout.h>
00013
#include <qlabel.h>
00014
#include <qfont.h>
00015
#include <qframe.h>
00016
#include <qsize.h>
00017
#include <qtoolbutton.h>
00018
#include <qimage.h>
00019
#include <qcursor.h>
00020
#include <qapplication.h>
00021
#include <math.h>
00022
#include <qtooltip.h>
00023
#include <qhgroupbox.h>
00024
#include <qpushbutton.h>
00025
#include <qcombobox.h>
00026
#include <math.h>
00027
00028
00029
#include "../clickableLabel.h"
00030
#include "editingInterface.h"
00031
#include "selectionInterface.h"
00032
#include "histogramEditor.h"
00033
#include "grainEditor.h"
00034
#include "manipulations/mosaicOptionsDialog.h"
00035
#include "../statusWidget.h"
00036
#include "../layoutWidget.h"
00037
#include "../window.h"
00038
#include "../titleWidget.h"
00039
#include "../dialogs/questionDialog.h"
00040
#include "../../config.h"
00041
#include "../../backend/album.h"
00042
#include "../../backend/subalbum.h"
00043
#include "../../backend/photo.h"
00044
#include "../../backend/tools/fileTools.h"
00045
#include "../../backend/tools/imageTools.h"
00046
00047
#include "../../backend/enhancements/color.h"
00048
#include "../../backend/enhancements/contrast.h"
00049
#include "../../backend/enhancements/redEye.h"
00050
#include "../../backend/enhancements/tilt.h"
00051
00052
#include "../../backend/manipulations/manipulationOptions.h"
00053
#include "../../backend/manipulations/blackWhite.h"
00054
#include "../../backend/manipulations/crop.h"
00055
#include "../../backend/manipulations/emboss.h"
00056
#include "../../backend/manipulations/invert.h"
00057
#include "../../backend/manipulations/mosaic.h"
00058
#include "../../backend/manipulations/painting.h"
00059
#include "../../backend/manipulations/pointillism.h"
00060
#include "../../backend/manipulations/sepia.h"
00061
00062
#include "../../configuration/configuration.h"
00063
00064 #define EFFECT_PREVIEW_WIDTH 107
00065 #define EFFECT_PREVIEW_HEIGHT 80
00066
00067
#include <iostream>
00068
using namespace std;
00069
00070
00071 EditingInterface::EditingInterface(
QWidget *parent,
const char* name )
00072 :
QWidget(parent,name)
00073 {
00074
00075 QFont smallerFont = font();
00076 smallerFont.setPointSize( smallerFont.pointSize() - 1 );
00077
00078 setFocusPolicy(QWidget::StrongFocus);
00079
00080
00081
photo = NULL;
00082
00083
00084
layout = (
LayoutWidget*)parent;
00085
00086
00087
00088
QFrame* photoFrame =
new QFrame(
this,
"photoFrame" );
00089
00090
00091 QFrame* controlsFrame =
new QFrame(
this,
"controlsFrame");
00092
00093
00094 QGridLayout* mainGrid =
new QGridLayout(
this, 3, 3, 0 );
00095 mainGrid->addWidget( photoFrame, 0, 1 );
00096 mainGrid->setRowStretch(0, 1);
00097 mainGrid->addMultiCellWidget( controlsFrame, 1,1, 0,2 );
00098 mainGrid->setRowSpacing( 2,
WIDGET_SPACING );
00099
00100
00101
previousButton =
new ClickableLabel( photoFrame,
"previousButton" );
00102
previousButton->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/previous.png") );
00103 connect(
previousButton, SIGNAL(clicked()), SLOT(
showPrevPhoto()) );
00104
00105
00106
selectionInterface =
new SelectionInterface( photoFrame,
"selectionInterface" );
00107 connect(
selectionInterface, SIGNAL( selectionChanged() ),
this, SLOT(
handleSelectionChanged() ) );
00108 connect(
selectionInterface, SIGNAL( aspectRatioChanged() ),
this, SLOT(
handleAspectRatioChanged() ) );
00109 connect(
selectionInterface, SIGNAL( ctrlClick() ),
this, SLOT(
rotateSelection() ) );
00110
00111
00112
nextButton =
new ClickableLabel( photoFrame,
"nextButton" );
00113
nextButton->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/next.png") );
00114 connect(
nextButton, SIGNAL(clicked()), SLOT(
showNextPhoto()) );
00115
00116
00117 QGridLayout* selectionGrid =
new QGridLayout( photoFrame, 1, 5, 0 );
00118 selectionGrid->setColSpacing( 0,
WIDGET_SPACING );
00119 selectionGrid->addWidget(
previousButton, 0, 1, Qt::AlignCenter );
00120 selectionGrid->addWidget(
selectionInterface, 0, 2 );
00121 selectionGrid->setColStretch( 2, 1 );
00122 selectionGrid->addWidget(
nextButton, 0, 3, Qt::AlignCenter );
00123 selectionGrid->setColSpacing( 4,
WIDGET_SPACING );
00124 selectionGrid->setSpacing(
WIDGET_SPACING );
00125
00126
00127 QHGroupBox* frameControls =
new QHGroupBox( tr(
"Frame"), controlsFrame,
"frameControls" );
00128 frameControls->setAlignment( Qt::AlignHCenter );
00129 frameControls->setInsideMargin(
WIDGET_SPACING );
00130
00131 QHGroupBox* enhanceControls =
new QHGroupBox( tr(
"Enhance"), controlsFrame,
"enhanceControls" );
00132 enhanceControls->setAlignment( Qt::AlignHCenter );
00133 enhanceControls->setInsideMargin(
WIDGET_SPACING );
00134
00135 QHGroupBox* manipulateControls =
new QHGroupBox( tr(
"Manipulate"), controlsFrame,
"applyEffect" );
00136 manipulateControls->setAlignment( Qt::AlignHCenter );
00137 manipulateControls->setInsideMargin(
WIDGET_SPACING );
00138
00139
00140 QGridLayout* controlsGrid =
new QGridLayout( controlsFrame, 1, 5, 0 );
00141 controlsGrid->addWidget( frameControls, 0, 1 );
00142 controlsGrid->addWidget( enhanceControls, 0, 2 );
00143 controlsGrid->addWidget( manipulateControls, 0, 3 );
00144
00145 controlsGrid->setSpacing(
WIDGET_SPACING );
00146 controlsGrid->setColSpacing(0,
WIDGET_SPACING );
00147 controlsGrid->setColStretch(0, 1);
00148 controlsGrid->setColSpacing(4,
WIDGET_SPACING );
00149 controlsGrid->setColStretch(4, 1);
00150
00151
00152
00153
00154 QFrame* frameControlsFrame =
new QFrame( frameControls );
00155
00156
00157
00158 QFrame* rotateFlipFrame =
new QFrame( frameControlsFrame );
00159
00160 QToolButton* rotateRightButton =
new QToolButton( rotateFlipFrame,
"rotateRight" );
00161 rotateRightButton->setIconSet( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/rotate90.png") );
00162 rotateRightButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00163 connect( rotateRightButton, SIGNAL(clicked()), SLOT(
rotateRight()) );
00164 QToolTip::add( rotateRightButton, tr(
"Rotate clockwise") );
00165
00166 QToolButton* rotateLeftButton =
new QToolButton( rotateFlipFrame,
"rotateLeft" );
00167 rotateLeftButton->setIconSet( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/rotate270.png") );
00168 rotateLeftButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00169 connect( rotateLeftButton, SIGNAL(clicked()), SLOT(
rotateLeft()) );
00170 QToolTip::add( rotateLeftButton, tr(
"Rotate counterclockwise") );
00171
00172 QToolButton* flipHorizontalButton =
new QToolButton( rotateFlipFrame,
"flipHorizontal" );
00173 flipHorizontalButton->setIconSet( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/flipHorizontally.png") );
00174 flipHorizontalButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00175 connect( flipHorizontalButton, SIGNAL(clicked()), SLOT(
flipHorizontal()) );
00176 QToolTip::add( flipHorizontalButton, tr(
"Flip horizontally") );
00177
00178 QToolButton* flipVerticalButton =
new QToolButton( rotateFlipFrame,
"flipVertical" );
00179 flipVerticalButton->setIconSet( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/flipVertically.png") );
00180 flipVerticalButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00181 connect( flipVerticalButton, SIGNAL(clicked()), SLOT(
flipVertical()) );
00182 QToolTip::add( flipVerticalButton, tr(
"Flip vertically") );
00183
00184
correctTiltButton =
new QToolButton( rotateFlipFrame,
"correctTilt" );
00185
correctTiltButton->setIconSet( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/correctTilt.png") );
00186
correctTiltButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00187
00188 connect(
correctTiltButton, SIGNAL(clicked()), SLOT(
startCorrectTilt()) );
00189
00190 connect(
selectionInterface, SIGNAL(lineSelected(QPoint, QPoint)),
00191
this, SLOT(
finishCorrectTilt( QPoint, QPoint)) );
00192
00193 QToolTip::add(
correctTiltButton, tr(
"Correct tilt") );
00194
00195
00196 QGridLayout* rotateFlipGrid =
new QGridLayout( rotateFlipFrame, 1, 5, 0 );
00197 rotateFlipGrid->setSpacing(
TIGHT_WIDGET_SPACING);
00198 rotateFlipGrid->addWidget( rotateRightButton, 0, 0 );
00199 rotateFlipGrid->addWidget( rotateLeftButton, 0, 1 );
00200 rotateFlipGrid->addWidget( flipHorizontalButton, 0, 2 );
00201 rotateFlipGrid->addWidget( flipVerticalButton, 0, 3 );
00202 rotateFlipGrid->addWidget(
correctTiltButton, 0, 4 );
00203
00204
00205
aspectRatios =
new QComboBox( frameControlsFrame );
00206
aspectRatios->setFont( smallerFont );
00207 connect(
aspectRatios, SIGNAL(activated(
int)),
this, SLOT(
selectAspectRatio()) );
00208
aspectRatioValues =
new QSize[8];
00209
maxDimensions =
new double[8];
00210
int curAspectRatio = 0;
00211
00212
aspectRatios->insertItem( tr(
"Custom") );
00213
maxDimensions[curAspectRatio] = -1.0;
00214
aspectRatioValues[curAspectRatio++] = QSize( -1, -1 );
00215
00216
aspectRatios->insertItem( tr(
"Photo (3.5 x 5)") );
00217
maxDimensions[curAspectRatio] = 5.0;
00218
aspectRatioValues[curAspectRatio++] = QSize( 10, 7 );
00219
00220
aspectRatios->insertItem( tr(
"Photo (4 x 6)") );
00221
maxDimensions[curAspectRatio] = 6.0;
00222
aspectRatioValues[curAspectRatio++] = QSize( 6, 4 );
00223
00224
aspectRatios->insertItem( tr(
"Photo (5 x 7)") );
00225
maxDimensions[curAspectRatio] = 7.0;
00226
aspectRatioValues[curAspectRatio++] = QSize( 7, 5 );
00227
00228
aspectRatios->insertItem( tr(
"Photo (8 x 10)") );
00229
maxDimensions[curAspectRatio] = 10.0;
00230
aspectRatioValues[curAspectRatio++] = QSize( 10, 8 );
00231
00232
aspectRatios->insertItem( tr(
"Postcard") );
00233
maxDimensions[curAspectRatio] = 6.0;
00234
aspectRatioValues[curAspectRatio++] = QSize( 6, 4 );
00235
00236
aspectRatios->insertItem( tr(
"Wallet") );
00237
maxDimensions[curAspectRatio] = 3.0;
00238
aspectRatioValues[curAspectRatio++] = QSize( 3, 2 );
00239
00240
aspectRatios->insertItem( tr(
"Desktop") );
00241
displayResolutionIndex = curAspectRatio;
00242
maxDimensions[curAspectRatio] = -1.0;
00243
aspectRatioValues[curAspectRatio++] = qApp->desktop()->screenGeometry().size();
00244
00245
00246
00247 connect( qApp->desktop(), SIGNAL( resized(
int)),
this, SLOT(
screenResolutionChanged()) );
00248
00249 QToolTip::add(
aspectRatios, tr(
"Select region for cropping using a particular aspect ratio") );
00250
00251
QLabel* aspectRatioLabel =
new QLabel( tr(
"Aspect Ratio"), frameControlsFrame );
00252 aspectRatioLabel->setFont( smallerFont );
00253
00254
00255
00256
cropButton =
new QToolButton( frameControlsFrame );
00257 QIconSet cropIcon;
00258 cropIcon.setPixmap( QString(
IMAGE_PATH)+
"buttonIcons/crop.png",
00259 QIconSet::Automatic,
00260 QIconSet::Normal );
00261
00262 cropIcon.setPixmap( QString(
IMAGE_PATH)+
"buttonIcons/crop_disabled.png",
00263 QIconSet::Automatic,
00264 QIconSet::Disabled );
00265
cropButton->setIconSet( cropIcon );
00266 connect(
cropButton, SIGNAL(clicked()), SLOT(
crop()) );
00267 QToolTip::add(
cropButton, tr(
"Crop photo to selected region") );
00268
00269 QLabel* cropLabel =
new QLabel( tr(
"Crop"), frameControlsFrame );
00270 cropLabel->setFont( smallerFont );
00271
00272
00273
00274
00275 QGridLayout* frameControlsGrid =
new QGridLayout( frameControlsFrame, 3, 2, 0 );
00276 frameControlsGrid->setSpacing(
TIGHT_WIDGET_SPACING);
00277 frameControlsGrid->addMultiCellWidget( rotateFlipFrame, 0,0, 0,1 );
00278 frameControlsGrid->addWidget(
aspectRatios, 1, 0, Qt::AlignHCenter );
00279 frameControlsGrid->addWidget(
cropButton, 1, 1, Qt::AlignHCenter );
00280 frameControlsGrid->addWidget( aspectRatioLabel, 2, 0, Qt::AlignHCenter );
00281 frameControlsGrid->addWidget( cropLabel, 2, 1, Qt::AlignHCenter );
00282
00283
00284
00285
00286 QFrame* enhanceControlsFrame =
new QFrame( enhanceControls );
00287
00288
00289
int numLargeButtons = 3;
00290
int curButtonIndex=0;
00291 ClickableLabel** largeButtons =
new ClickableLabel*[numLargeButtons];
00292
00293
00294
00295
00296 QFrame* autoEnhanceControlsFrame =
new QFrame( enhanceControlsFrame );
00297
00298
00299 ClickableLabel* enhanceColorButton = largeButtons[curButtonIndex] =
00300
new ClickableLabel( autoEnhanceControlsFrame );
00301 largeButtons[curButtonIndex]->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/improveColorBalance.png") );
00302 connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(
colorBalance()) );
00303 QToolTip::add( largeButtons[curButtonIndex], tr(
"Enhance color balance") );
00304 curButtonIndex++;
00305
00306 QLabel* enhanceColorLabel =
new QLabel( tr(
"Color"), autoEnhanceControlsFrame );
00307 enhanceColorLabel->setFont( smallerFont );
00308
00309
00310 ClickableLabel* enhanceContrastButton = largeButtons[curButtonIndex] =
00311
new ClickableLabel( autoEnhanceControlsFrame );
00312 largeButtons[curButtonIndex]->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/enhanceContrast.png") );
00313 connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(
enhanceContrast()) );
00314 QToolTip::add( largeButtons[curButtonIndex], tr(
"Enhance contrast") );
00315 curButtonIndex++;
00316
00317 QLabel* enhanceContrastLabel =
new QLabel( tr(
"Contrast"), autoEnhanceControlsFrame );
00318 enhanceContrastLabel->setFont( smallerFont );
00319
00320
00321
redEyeReductionButton = largeButtons[curButtonIndex] =
new ClickableLabel( autoEnhanceControlsFrame );
00322
redEyeReductionButton->
setEnabled(
false );
00323
00324 largeButtons[curButtonIndex]->setPixmap( QPixmap( QString(
IMAGE_PATH)+
"buttonIcons/redEyeReduction.png" ) );
00325 connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(
removeRedeye()) );
00326 QToolTip::add( largeButtons[curButtonIndex], tr(
"Remove red-eye") );
00327 curButtonIndex++;
00328
00329 QLabel* removeRedyEyeLabel =
new QLabel( tr(
"Red Eye"), autoEnhanceControlsFrame );
00330 removeRedyEyeLabel->setFont( smallerFont );
00331
00332
00333 QGridLayout* autoEnhanceControlsGrid =
new QGridLayout( autoEnhanceControlsFrame, 2, 3, 0 );
00334 autoEnhanceControlsGrid->setSpacing(
TIGHT_WIDGET_SPACING);
00335 autoEnhanceControlsGrid->addWidget( enhanceColorButton, 0, 0, Qt::AlignHCenter );
00336 autoEnhanceControlsGrid->addWidget( enhanceColorLabel, 1, 0, Qt::AlignHCenter );
00337
00338 autoEnhanceControlsGrid->addWidget( enhanceContrastButton, 0, 1, Qt::AlignHCenter );
00339 autoEnhanceControlsGrid->addWidget( enhanceContrastLabel, 1, 1, Qt::AlignHCenter );
00340
00341 autoEnhanceControlsGrid->addWidget(
redEyeReductionButton, 0, 2, Qt::AlignHCenter );
00342 autoEnhanceControlsGrid->addWidget( removeRedyEyeLabel, 1, 2, Qt::AlignHCenter );
00343
00344
00345 QFrame* manualEnhanceControlsFrame =
new QFrame( enhanceControlsFrame );
00346
00347
00348 ClickableLabel* tuneLevelsButton =
new ClickableLabel( manualEnhanceControlsFrame );
00349 tuneLevelsButton->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/tuneLevels.png") );
00350 connect( tuneLevelsButton, SIGNAL(clicked()), SLOT(
tuneLevels()) );
00351 QToolTip::add( tuneLevelsButton, tr(
"Fine tune brightness, contrast, and colors") );
00352
00353 QLabel* tuneLevelsLabel =
new QLabel( tr(
"Levels..."), manualEnhanceControlsFrame );
00354 tuneLevelsLabel->setFont( smallerFont );
00355
00356
00357 ClickableLabel* adjustGrainButton =
new ClickableLabel( manualEnhanceControlsFrame );
00358 adjustGrainButton->
setPixmap( QPixmap(QString(
IMAGE_PATH)+
"buttonIcons/adjustGrain.png") );
00359 connect( adjustGrainButton, SIGNAL(clicked()), SLOT(
adjustGrain()) );
00360 QToolTip::add( adjustGrainButton, tr(
"Blur or sharpen image") );
00361
00362 QLabel* adjustGrainLabel =
new QLabel( tr(
"Grain..."), manualEnhanceControlsFrame );
00363 adjustGrainLabel->setFont( smallerFont );
00364
00365
00366 QGridLayout* manualEnhanceControlsGrid =
new QGridLayout( manualEnhanceControlsFrame, 2, 3, 0 );
00367 manualEnhanceControlsGrid->setSpacing(
TIGHT_WIDGET_SPACING);
00368 manualEnhanceControlsGrid->addWidget( tuneLevelsButton, 0, 0, Qt::AlignHCenter );
00369 manualEnhanceControlsGrid->addWidget( tuneLevelsLabel, 1, 0, Qt::AlignHCenter );
00370 manualEnhanceControlsGrid->setColSpacing( 1,
WIDGET_SPACING );
00371 manualEnhanceControlsGrid->addWidget( adjustGrainButton, 0, 2, Qt::AlignHCenter );
00372 manualEnhanceControlsGrid->addWidget( adjustGrainLabel, 1, 2, Qt::AlignHCenter );
00373
00374
00375
00376 QGridLayout* enhanceControlsGrid =
new QGridLayout( enhanceControlsFrame, 4, 2, 0 );
00377 enhanceControlsGrid->setSpacing(
WIDGET_SPACING);
00378 enhanceControlsGrid->addWidget( autoEnhanceControlsFrame, 0, 0, Qt::AlignHCenter );
00379 enhanceControlsGrid->addWidget( manualEnhanceControlsFrame, 1, 0, Qt::AlignHCenter );
00380 enhanceControlsGrid->setRowStretch( 0, 1 );
00381 enhanceControlsGrid->setRowStretch( 3, 1 );
00382
00383
00384
00385
00386 QFrame* manipulateControlsFrame =
new QFrame( manipulateControls,
"manipulateControlsFrame" );
00387
00388
00389
effectsList =
new QComboBox( manipulateControlsFrame );
00390
effectsList->setFont( smallerFont );
00391 connect(
effectsList, SIGNAL(activated(
int)),
this, SLOT(
selectEffect()) );
00392
00393
int i;
00394
for(i=0; i<
NUM_MANIPULATIONS; i++)
00395 {
00396
switch(i)
00397 {
00398
case BW_EFFECT:
effectsList->insertItem( tr(
"B + W") );
break;
00399
case SEPIA_EFFECT:
effectsList->insertItem( tr(
"Sepia") );
break;
00400
case INVERT_EFFECT:
effectsList->insertItem( tr(
"Invert") );
break;
00401
case EMBOSS_EFFECT:
effectsList->insertItem( tr(
"Emboss") );
break;
00402
case MOSAIC_EFFECT:
effectsList->insertItem( tr(
"Mosaic") );
break;
00403
case PAINTING_EFFECT:
effectsList->insertItem( tr(
"Painting") );
break;
00404
case POINTILLISM_EFFECT:
effectsList->insertItem( tr(
"Pointillism") );
break;
00405 }
00406 }
00407
00408
00409
applyEffectButton =
new QPushButton( tr(
"Apply"), manipulateControlsFrame );
00410
applyEffectButton->setFont( smallerFont );
00411 connect(
applyEffectButton, SIGNAL(clicked()), SLOT(
applyEffect()) );
00412
00413
00414
effectPreview =
new QLabel( manipulateControlsFrame );
00415
00416
00417 QGridLayout* manipulateControlsGrid =
new QGridLayout( manipulateControlsFrame, 2, 2, 0 );
00418 manipulateControlsGrid->setSpacing(
TIGHT_WIDGET_SPACING);
00419 manipulateControlsGrid->addWidget(
effectsList, 0, 0 );
00420 manipulateControlsGrid->addWidget(
applyEffectButton, 1, 0, Qt::AlignHCenter );
00421 manipulateControlsGrid->addMultiCellWidget(
effectPreview, 0,1, 1,1, Qt::AlignHCenter );
00422
00423
00424
00425 manipulateControlsGrid->setColSpacing(1, 85 );
00426 }
00427
00428 EditingInterface::~EditingInterface() { }
00429
00430 Photo*
EditingInterface::getPhoto() {
return photo; }
00431
00432 void EditingInterface::setPhoto(
Subalbum* collection,
Photo* photo)
00433 {
00434
00435 this->collection = collection;
00436 this->photo = photo;
00437
00438
00439
previousButton->
setInvisible( photo->getPrev() == NULL );
00440
nextButton->
setInvisible( photo->getNext() == NULL );
00441
00442
00443
aspectRatios->setCurrentItem(0);
00444
effectsList->setCurrentItem(0);
00445
00446
00447
selectionRotated =
false;
00448
00449
00450
selectionInterface->
setPhoto( photo->getImageFilename() );
00451
00452
00453
effectPreviewImageFilename = ((
Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
00454
"/effectPreviewImage.jpg";
00455
scaleImage( photo->getImageFilename(),
effectPreviewImageFilename,
EFFECT_PREVIEW_WIDTH,
EFFECT_PREVIEW_HEIGHT );
00456
selectEffect();
00457
00458
00459
getImageSize( photo->getImageFilename(),
imageWidth,
imageHeight );
00460
00461
00462
selectionInterface->
getDisplaySize(
displayWidth,
displayHeight );
00463
00464
00465
cropButton->setEnabled(
false );
00466
redEyeReductionButton->
setEnabled(
false );
00467 }
00468
00469 void EditingInterface::showPrevPhoto()
00470 {
00471
Photo* prevPhoto =
photo->
getPrev();
00472
00473
if( prevPhoto != NULL &&
00474 prevPhoto !=
photo )
00475 {
showNextPrevFirstLastPhoto( prevPhoto ); }
00476 }
00477
00478 void EditingInterface::showNextPhoto()
00479 {
00480
Photo* nextPhoto =
photo->
getNext();
00481
00482
if( nextPhoto != NULL &&
00483 nextPhoto !=
photo )
00484 {
showNextPrevFirstLastPhoto( nextPhoto ); }
00485 }
00486
00487 void EditingInterface::showFirstPhoto()
00488 {
00489
Photo* firstPhoto =
collection->
getFirst();
00490
00491
if(firstPhoto !=
photo)
00492 {
showNextPrevFirstLastPhoto( firstPhoto ); }
00493 }
00494
00495 void EditingInterface::showLastPhoto()
00496 {
00497
Photo* lastPhoto =
collection->
getLast();
00498
00499
if(lastPhoto !=
photo)
00500 {
showNextPrevFirstLastPhoto( lastPhoto ); }
00501 }
00502
00503 void EditingInterface::showNextPrevFirstLastPhoto(
Photo* newPhoto )
00504 {
00505
00506 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00507 qApp->processEvents();
00508
00509
00510
photo = newPhoto;
00511
00512
00513
selectionRotated =
false;
00514
00515
00516
previousButton->
setInvisible(
photo->
getPrev() == NULL );
00517
nextButton->
setInvisible(
photo->
getNext() == NULL );
00518
00519
00520
selectionInterface->
setPhoto(
photo->
getImageFilename() );
00521
00522
00523
effectPreviewImageFilename = ((
Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
"/effectPreviewImage.jpg";
00524
scaleImage(
photo->
getImageFilename(),
effectPreviewImageFilename,
EFFECT_PREVIEW_WIDTH,
EFFECT_PREVIEW_HEIGHT );
00525
selectEffect();
00526
00527
00528
getImageSize(
photo->
getImageFilename(),
imageWidth,
imageHeight );
00529
00530
00531
selectionInterface->
getDisplaySize(
displayWidth,
displayHeight );
00532
00533
00534
if(
aspectRatios->currentItem() != 0)
00535 {
selectAspectRatio(); }
00536
else
00537 {
selectionInterface->
setSelection( QPoint(-1,-1), QPoint(-1, -1) ); }
00538
00539
00540 emit
photoModified();
00541
00542
00543 qApp->restoreOverrideCursor();
00544 qApp->processEvents();
00545 }
00546
00547 void EditingInterface::rotateRight()
00548 {
00549
rotateFlip(
ROTATE_90 );
00550 }
00551
00552 void EditingInterface::rotateLeft()
00553 {
00554
rotateFlip(
ROTATE_270 );
00555 }
00556
00557 void EditingInterface::flipHorizontal()
00558 {
00559
rotateFlip(
FLIP_H );
00560 }
00561
00562 void EditingInterface::flipVertical()
00563 {
00564
rotateFlip(
FLIP_V );
00565 }
00566
00567 void EditingInterface::rotateFlip( TRANSFORM_CODE rotationFlipType )
00568 {
00569
00570 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00571 qApp->processEvents();
00572
00573
00574
layout->
getWindow()->
getStatus()->
grabInput();
00575
00576
00577 QString editedImagePath = ((
Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
"/editedImage.jpg";
00578
transformImage(
photo->
getImageFilename(), editedImagePath, rotationFlipType );
00579
00580
00581
photo->
setImage( editedImagePath );
00582
00583
00584
bool aspectRatioChanged = ( rotationFlipType ==
ROTATE_90 || rotationFlipType ==
ROTATE_270 );
00585
selectionInterface->
setPhoto( editedImagePath, aspectRatioChanged );
00586
00587
00588
getImageSize(
photo->
getImageFilename(),
imageWidth,
imageHeight );
00589
00590
00591
selectionInterface->
getDisplaySize(
displayWidth,
displayHeight );
00592
00593
00594
if( aspectRatioChanged )
00595 {
00596
00597
selectionRotated =
false;
00598
selectAspectRatio();
00599 }
00600
00601
00602
scaleImage(
photo->
getImageFilename(),
effectPreviewImageFilename,
EFFECT_PREVIEW_WIDTH,
EFFECT_PREVIEW_HEIGHT );
00603
selectEffect();
00604
00605
00606 emit
photoModified();
00607
00608
00609
layout->
getWindow()->
getStatus()->
releaseInput();
00610
00611
00612 qApp->restoreOverrideCursor();
00613 qApp->processEvents();
00614 }
00615
00616 void EditingInterface::screenResolutionChanged()
00617 {
00618
00619
aspectRatioValues[
displayResolutionIndex] = qApp->desktop()->screenGeometry().size();
00620
00621
00622
if(
aspectRatios->currentItem() ==
displayResolutionIndex )
00623 {
selectAspectRatio(); }
00624 }
00625
00626 void EditingInterface::crop()
00627 {
00628
00629 QPoint
topLeft,
bottomRight;
00630
if (!
findSelection(
topLeft,
bottomRight) )
00631
return;
00632
00633
00634 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00635
00636
00637
layout->
getWindow()->
getStatus()->
grabInput();
00638
00639
00640
applyImageUpdate(
cropImage(
photo->
getImageFilename(),
topLeft,
bottomRight ),
00641
true );
00642
00643
00644
layout->
getWindow()->
getStatus()->
releaseInput();
00645
00646
00647 qApp->restoreOverrideCursor();
00648 }
00649
00650 void EditingInterface::enhanceContrast()
00651 {
00652
00653 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00654 qApp->processEvents();
00655
00656
00657
layout->
getWindow()->
getStatus()->
grabInput();
00658
00659
00660
applyImageUpdate(
enhanceImageContrast(
photo->
getImageFilename(),
00661
layout->
getWindow()->
getStatus() ),
00662
false );
00663
00664
00665
layout->
getWindow()->
getStatus()->
releaseInput();
00666
00667
00668 qApp->restoreOverrideCursor();
00669 qApp->processEvents();
00670 }
00671
00672 void EditingInterface::colorBalance()
00673 {
00674
00675 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00676 qApp->processEvents();
00677
00678
00679
layout->
getWindow()->
getStatus()->
grabInput();
00680
00681
00682
applyImageUpdate(
improveColorBalance(
photo->
getImageFilename(),
00683
layout->
getWindow()->
getStatus() ),
00684
false );
00685
00686
00687
layout->
getWindow()->
getStatus()->
releaseInput();
00688
00689
00690 qApp->restoreOverrideCursor();
00691 qApp->processEvents();
00692 }
00693
00694 void EditingInterface::removeRedeye()
00695 {
00696
00697 QPoint
topLeft,
bottomRight;
00698
if (!
findSelection(
topLeft,
bottomRight) )
00699
return;
00700
00701
00702 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00703 qApp->processEvents();
00704
00705
00706
layout->
getWindow()->
getStatus()->
grabInput();
00707
00708
00709
applyImageUpdate(
removeRedeyeRegions(
photo->
getImageFilename(),
00710
topLeft,
bottomRight,
00711
layout->
getWindow()->
getStatus() ),
00712
true );
00713
00714
00715
layout->
getWindow()->
getStatus()->
releaseInput();
00716
00717
00718 qApp->restoreOverrideCursor();
00719 qApp->processEvents();
00720 }
00721
00722 void EditingInterface::tuneLevels()
00723 {
00724
00725
00726
HistogramEditor editor(
photo->
getImageFilename(),
this);
00727
if( editor.exec() )
00728 {
00729
00730 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00731 qApp->processEvents();
00732
00733
00734
layout->
getWindow()->
getStatus()->
grabInput();
00735
00736
00737
applyImageUpdate( editor.
getModifiedImage(),
false );
00738
00739
00740
layout->
getWindow()->
getStatus()->
releaseInput();
00741
00742
00743 qApp->restoreOverrideCursor();
00744 qApp->processEvents();
00745 }
00746 }
00747
00748 void EditingInterface::adjustGrain()
00749 {
00750
00751
00752
GrainEditor editor(
photo->
getImageFilename(),
this);
00753
if( editor.exec() )
00754 {
00755
00756 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00757 qApp->processEvents();
00758
00759
00760
layout->
getWindow()->
getStatus()->
grabInput();
00761
00762
00763
applyImageUpdate( editor.
getModifiedImage(),
false );
00764
00765
00766
layout->
getWindow()->
getStatus()->
releaseInput();
00767
00768
00769 qApp->restoreOverrideCursor();
00770 qApp->processEvents();
00771 }
00772 }
00773
00774 void EditingInterface::selectEffect()
00775 {
00776
00777 QImage*
editedImage =
applyEffect(
effectPreviewImageFilename );
00778
00779
00780
if(
editedImage == NULL )
return;
00781
00782
00783
effectPreview->setPixmap( QPixmap(*
editedImage) );
00784
delete editedImage;
00785
editedImage = NULL;
00786 }
00787
00788 void EditingInterface::applyEffect()
00789 {
00790
00791
00792
ManipulationOptions* options = NULL;
00793
if(
effectsList->currentItem() ==
MOSAIC_EFFECT )
00794 {
00795
MosaicOptionsDialog optionsDialog(
this);
00796
00797
if( optionsDialog.exec() )
00798 {
00799
00800
00801
layout->
getWindow()->
getStatus()->
showProgressBar( QString(tr(
"Preparing Tiles")), 100 );
00802 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00803 qApp->processEvents();
00804 options = optionsDialog.
getOptions();
00805 qApp->restoreOverrideCursor();
00806 }
00807
00808
else
00809 {
return; }
00810 }
00811
else
00812 { options =
new ManipulationOptions(
layout->
getWindow()->
getStatus() ); }
00813
00814
00815
layout->
getWindow()->
getStatus()->
grabInput();
00816
applyEffectButton->setEnabled(
false);
00817 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00818 qApp->processEvents();
00819
00820
00821 QImage*
editedImage =
applyEffect(
photo->
getImageFilename(), options );
00822
applyImageUpdate(
editedImage,
false );
00823
delete options; options = NULL;
00824
00825
00826
layout->
getWindow()->
getStatus()->
setStatus(
"" );
00827
layout->
getWindow()->
getStatus()->
releaseInput();
00828
applyEffectButton->setEnabled(
true);
00829 qApp->restoreOverrideCursor();
00830 qApp->processEvents();
00831
00832 }
00833
00834 QImage*
EditingInterface::applyEffect(QString filename,
ManipulationOptions* options)
00835 {
00836
00837 QImage* effectedImage = NULL;
00838
switch(
effectsList->currentItem() )
00839 {
00840
case BW_EFFECT: effectedImage =
blackWhiteEffect( filename, options );
break;
00841
case SEPIA_EFFECT: effectedImage =
sepiaEffect( filename, options );
break;
00842
case INVERT_EFFECT: effectedImage =
invertEffect( filename, options );
break;
00843
case EMBOSS_EFFECT: effectedImage =
embossEffect( filename, options );
break;
00844
case PAINTING_EFFECT: effectedImage =
oilPaintingEffect( filename, options );
break;
00845
case POINTILLISM_EFFECT: effectedImage =
pointillismEffect( filename, options );
break;
00846
case MOSAIC_EFFECT: effectedImage =
mosaicEffect( filename, (
MosaicOptions*) options );
break;
00847 }
00848
00849
00850
return effectedImage;
00851 }
00852
00853 void EditingInterface::applyImageUpdate(QImage* editedImage,
bool resetSelection)
00854 {
00855
00856
00857
if(
editedImage == NULL)
00858 {
00859
00860
00861
00862
00863
00864
00865
if(resetSelection)
00866 {
00867
selectionInterface->
selectNone();
00868 }
00869
00870
return;
00871 }
00872
00873
00874 QString editedImagePath = ((
Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
"/editedImage.jpg";
00875
00876
00877
00878
00879
00880
editedImage->save( editedImagePath,
"JPEG", 95 );
00881
delete editedImage;
00882
editedImage = NULL;
00883
00884
00885
photo->
setImage( editedImagePath );
00886
00887
00888
selectionInterface->
setPhoto( editedImagePath, resetSelection );
00889
00890
00891
00892
if( resetSelection ) {
selectionRotated =
false; }
00893
00894
00895
getImageSize(
photo->
getImageFilename(),
imageWidth,
imageHeight );
00896
00897
00898
selectionInterface->
getDisplaySize(
displayWidth,
displayHeight );
00899
00900
00901
scaleImage(
photo->
getImageFilename(),
effectPreviewImageFilename,
EFFECT_PREVIEW_WIDTH,
EFFECT_PREVIEW_HEIGHT );
00902
selectEffect();
00903
00904
00905 emit
photoModified();
00906 }
00907
00908 void EditingInterface::returnAction()
00909 {
00910
00911
layout->
organize();
00912 }
00913
00914 bool EditingInterface::findSelection(QPoint& topLeft, QPoint& bottomRight)
00915 {
00916
00917
selectionInterface->
getSelection(
topLeft,
bottomRight);
00918
00919
00920
if(
topLeft.x() >=
bottomRight.x() ||
00921
topLeft.y() >=
bottomRight.y())
00922
return false;
00923
00924
00925
return true;
00926 }
00927
00928 void EditingInterface::handleSelectionChanged()
00929 {
00930
00931 QPoint
topLeft,
bottomRight;
00932
bool selectionPresent =
findSelection(
topLeft,
bottomRight);
00933
00934
cropButton->setEnabled( selectionPresent );
00935
redEyeReductionButton->
setEnabled( selectionPresent );
00936 }
00937
00938 void EditingInterface::handleAspectRatioChanged()
00939 {
00940
00941
aspectRatios->setCurrentItem(0);
00942 }
00943
00944 void EditingInterface::selectAll(QPoint& topLeft, QPoint& bottomRight)
00945 {
00946
topLeft.setX(0);
00947
topLeft.setY(0);
00948
bottomRight.setX(
imageWidth - 1);
00949
bottomRight.setY(
imageHeight - 1);
00950 }
00951
00952 void EditingInterface::keyPressEvent( QKeyEvent *e )
00953 {
00954
00955
switch( e->key() )
00956 {
00957
00958
case Qt::Key_Escape:
00959
returnAction();
00960
break;
00961
case Qt::Key_Prior:
00962
showPrevPhoto();
00963
break;
00964
case Qt::Key_Next:
00965
showNextPhoto();
00966
break;
00967
case Qt::Key_Home:
00968
showFirstPhoto();
00969
break;
00970
case Qt::Key_End:
00971
showLastPhoto();
00972
break;
00973
case Qt::Key_R:
00974
if(e->state() & Qt::ControlButton)
00975
rotateRight();
00976
break;
00977
case Qt::Key_L:
00978
if(e->state() & Qt::ControlButton)
00979
rotateLeft();
00980
break;
00981
case Qt::Key_F:
00982
if(e->state() & Qt::ControlButton)
00983 {
00984
if( e->state() & Qt::AltButton )
00985
flipVertical();
00986
else
00987
flipHorizontal();
00988 }
00989
break;
00990
default:
00991 e->ignore();
00992 }
00993 }
00994
00995 bool EditingInterface::currentPhotoRevertable()
00996 {
00997
if(
photo == NULL)
00998
return false;
00999
else
01000
return photo->
revertPossible();
01001 }
01002
01003 void EditingInterface::revertCurrentPhoto()
01004 {
01005
01006
if( !
currentPhotoRevertable() )
return;
01007
01008
01009 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
01010
01011
01012
layout->
getWindow()->
getStatus()->
grabInput();
01013
01014
01015
01016
int origWidth, origHeight;
01017
getImageSize(
photo->
originalImageFilename(), origWidth, origHeight );
01018
bool resetSelection = (origWidth !=
imageWidth) || (origHeight !=
imageHeight);
01019
01021
photo->
revertPhoto();
01022
01023
01024
selectionInterface->
setPhoto(
photo->
getImageFilename(), resetSelection );
01025
01026
01027
getImageSize(
photo->
getImageFilename(),
imageWidth,
imageHeight );
01028
01029
01030
selectionInterface->
getDisplaySize(
displayWidth,
displayHeight );
01031
01032
01033
scaleImage(
photo->
getImageFilename(),
effectPreviewImageFilename,
EFFECT_PREVIEW_WIDTH,
EFFECT_PREVIEW_HEIGHT );
01034
selectEffect();
01035
01036
01037 emit
photoModified();
01038
01039
01040
layout->
getWindow()->
getStatus()->
releaseInput();
01041
01042
01043 qApp->restoreOverrideCursor();
01044 }
01045
01046 void EditingInterface::setFocus()
01047 {
01048
01049
selectionInterface->setFocus();
01050 }
01051
01052 void EditingInterface::rotateSelection()
01053 {
01054
01055
selectionRotated = !
selectionRotated;
01056
01057
01058
if(
aspectRatios->currentItem() == 0)
01059 {
01060
01061 QPoint curTopLeft, curBottomRight;
01062
selectionInterface->
getSelection(curTopLeft, curBottomRight);
01063
01064
01065 QPoint selectionCenter = QPoint( ( curTopLeft.x() + curBottomRight.x() ) / 2,
01066 ( curTopLeft.y() + curBottomRight.y() ) / 2 );
01067
01068
01069
int newWidth = curBottomRight.y() - curTopLeft.y() + 1;
01070
int newHeight =curBottomRight.x() - curTopLeft.x() + 1;
01071
calcScaledImageDimensions( newWidth, newHeight,
01072
imageWidth,
imageHeight,
01073 newWidth, newHeight );
01074
01075
01076 QPoint
topLeft = QPoint( selectionCenter.x() - newWidth/2,
01077 selectionCenter.y() - newHeight/2 );
01078 QPoint
bottomRight = QPoint(
topLeft.x() + newWidth - 1,
01079
topLeft.y() + newHeight - 1 );
01080
01081
01082
if(
topLeft.x() < 0)
01083 {
01084
bottomRight.setX(
bottomRight.x() -
topLeft.x() );
01085
topLeft.setX( 0 );
01086 }
01087
01088
if(
topLeft.y() < 0)
01089 {
01090
bottomRight.setY(
bottomRight.y() -
topLeft.y() );
01091
topLeft.setY( 0 );
01092 }
01093
01094
if(
bottomRight.x() >=
imageWidth )
01095 {
01096
topLeft.setX(
topLeft.x() - (
bottomRight.x() -
imageWidth + 1 ) );
01097
bottomRight.setX(
imageWidth - 1 );
01098 }
01099
01100
if(
bottomRight.y() >=
imageHeight )
01101 {
01102
topLeft.setY(
topLeft.y() - (
bottomRight.y() -
imageHeight + 1 ) );
01103
bottomRight.setY(
imageHeight - 1 );
01104 }
01105
01106
01107
selectionInterface->
setSelection(
topLeft,
bottomRight);
01108 }
01109
01110
01111
else
01112 {
01113
selectAspectRatio();
01114 }
01115 }
01116
01117 void EditingInterface::selectAspectRatio()
01118 {
01119
01120
if(
aspectRatios->currentItem() == 0 )
return;
01121
01122
01123 QSize aspectRatio =
aspectRatioValues[
aspectRatios->currentItem() ];
01124
01125
01126
if(
imageHeight >
imageWidth )
01127 { aspectRatio = QSize( aspectRatio.height(), aspectRatio.width() ); }
01128
01129
01130
if(
selectionRotated )
01131 { aspectRatio = QSize( aspectRatio.height(), aspectRatio.width() ); }
01132
01133
01134
int selectedWidth = 0;
01135
int selectedHeight = 0;
01136
01137
01138
if(
aspectRatios->currentItem() ==
displayResolutionIndex)
01139 {
01140
01141 selectedWidth = aspectRatio.width();
01142 selectedHeight = aspectRatio.height();
01143
calcScaledImageDimensions( selectedWidth, selectedHeight,
01144
imageWidth,
imageHeight,
01145 selectedWidth, selectedHeight );
01146 }
01147
01148
else
01149 {
01150
01151 selectedWidth =
imageWidth;
01152 selectedHeight = (
int) (((
double) (imageWidth * aspectRatio.height()) ) / aspectRatio.width() );
01153
calcScaledImageDimensions( selectedWidth, selectedHeight,
01154 imageWidth,
imageHeight,
01155 selectedWidth, selectedHeight );
01156
01157 }
01158
01159
01160 QPoint curTopLeft, curBottomRight;
01161
selectionInterface->
getSelection( curTopLeft, curBottomRight );
01162
01163
01164 QPoint curCenter;
01165 curCenter.setX( (curTopLeft.x() + curBottomRight.x()) / 2 );
01166 curCenter.setY( (curTopLeft.y() + curBottomRight.y()) / 2 );
01167
01168
01169
01170
if( curCenter.x() < 0 || curCenter.y() < 0 )
01171 {
01172 curCenter.setX(
imageWidth/2 );
01173 curCenter.setY(
imageHeight/2 );
01174 }
01175
01176
01177
01178 QPoint newTopLeft, newBottomRight;
01179
01180 newTopLeft.setX( curCenter.x() - selectedWidth/2 );
01181 newTopLeft.setY( curCenter.y() - selectedHeight/2 );
01182
01183
01184
if( newTopLeft.x() < 0 ) newTopLeft.setX( 0 );
01185
if( newTopLeft.y() < 0 ) newTopLeft.setY( 0 );
01186
01187
01188 newBottomRight.setX( newTopLeft.x() + selectedWidth - 1 );
01189
if( newBottomRight.x() >=
imageWidth )
01190 {
01191 newBottomRight.setX(
imageWidth-1 );
01192 newTopLeft.setX( newBottomRight.x() - selectedWidth + 1 );
01193 }
01194
01195 newBottomRight.setY( newTopLeft.y() + selectedHeight - 1 );
01196
if( newBottomRight.y() >=
imageHeight )
01197 {
01198 newBottomRight.setY(
imageHeight-1 );
01199 newTopLeft.setY( newBottomRight.y() - selectedHeight + 1 );
01200 }
01201
01202
01203
selectionInterface->
setSelection(newTopLeft, newBottomRight,
01204
maxDimensions[
aspectRatios->currentItem()] );
01205 }
01206
01207 void EditingInterface::startCorrectTilt()
01208 {
01209
01210
01211
correctTiltButton->setEnabled(
false );
01212
selectionInterface->
enterDrawLineMode();
01213 }
01214
01215 void EditingInterface::finishCorrectTilt( QPoint p1, QPoint p2 )
01216 {
01217
01218
if( p1.x() == -1 || p2.x() == -1 )
01219 {
01220
01221
correctTiltButton->setEnabled(
true );
01222
return;
01223 }
01224
01225
01226 qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
01227
01228
01229
layout->
getWindow()->
getStatus()->
grabInput();
01230
01231
01232 QImage* rotatedImage =
correctImageTilt(
photo->
getImageFilename(), p1, p2,
01233
layout->
getWindow()->
getStatus() );
01234
applyImageUpdate( rotatedImage,
true );
01235
01236
01237
correctTiltButton->setEnabled(
true );
01238
01239
01240
layout->
getWindow()->
getStatus()->
releaseInput();
01241
01242
01243 qApp->restoreOverrideCursor();
01244 }
01245
01246
01247