AlbumShaper  1.0a3
Public Slots | Signals | Public Member Functions | Protected Member Functions | Private Slots | Private Member Functions | Private Attributes
EditingInterface Class Reference

Interface for editing photo. More...

#include <editingInterface.h>

Inheritance diagram for EditingInterface:
Inheritance graph
[legend]
Collaboration diagram for EditingInterface:
Collaboration graph
[legend]

List of all members.

Public Slots

void handleSelectionChanged ()
void handleAspectRatioChanged ()
void setFocus ()

Signals

void photoModified ()

Public Member Functions

 EditingInterface (QWidget *parent=0, const char *name=0)
 Constructs layout.
 ~EditingInterface ()
void setPhoto (Subalbum *collection, Photo *photo)
 Sets the photo pointer and constructs scaled qimage's for painting.
PhotogetPhoto ()
 Returns a pointer to the currently selected photo.
bool currentPhotoRevertable ()
void revertCurrentPhoto ()
 reverts current photo and updates display

Protected Member Functions

void keyPressEvent (QKeyEvent *e)

Private Slots

void showPrevPhoto ()
 Show prev photo.
void showNextPhoto ()
 Show next photo.
void showFirstPhoto ()
 Show first photo.
void showLastPhoto ()
 Show last photo.
void rotateRight ()
 Rotate image right 90 degrees.
void rotateLeft ()
 Rotate image left 90 degrees.
void flipHorizontal ()
 Flip image horizontally.
void startCorrectTilt ()
 Enter correct image tilt mode.
void finishCorrectTilt (QPoint p1, QPoint p2)
 Finish correcting and image's tilt.
void flipVertical ()
 Flip image vertically.
void selectAspectRatio ()
 Aspect ratio selection changed.
void screenResolutionChanged ()
 Update recorded screen resolution and selection if necessary.
void rotateSelection ()
 Rotate current selection.
void crop ()
 Cropped image.
void enhanceContrast ()
 Enhance image contrast.
void colorBalance ()
 Improve color balance.
void removeRedeye ()
 Applies redeye removal.
void tuneLevels ()
 Opens levels editor for manual histogram and brightness/contrast adjustments.
void adjustGrain ()
 Opens image grain editor.
void selectEffect ()
 Effect seletion changed.
void applyEffect ()
 Apply selected effect.
void returnAction ()
 Exit editing interface.

Private Member Functions

void showNextPrevFirstLastPhoto (Photo *newPhoto)
 Utility method for show prev/next photos.
void rotateFlip (TRANSFORM_CODE rotationFlipType)
 Utility method for rotation + flip slots.
bool findSelection (QPoint &topLeft, QPoint &bottomRight)
 Finds the selected region of the image.
void selectAll (QPoint &topLeft, QPoint &bottomRight)
 Return coordinates that select entire image.
QImage * applyEffect (QString filename, ManipulationOptions *options=NULL)
 utlity function for apply effect and preview effect slots
void applyImageUpdate (QImage *editedImage, bool resetSelection)
 Applies update to image.

Private Attributes

ClickableLabelpreviousButton
ClickableLabelnextButton
SelectionInterfaceselectionInterface
 This widget scales and displays the photo to fit the available screen space, and provides extensive support for selecting regions of the photo for editing/cropping.
QComboBox * aspectRatios
 Widget for selection aspect ratio to crop to.
QComboBox * orientations
int displayResolutionIndex
 Index for screen resolution, needed if this value pair changes during program executing.
QSize * aspectRatioValues
 array of common aspect ratios to crop to
double * maxDimensions
bool selectionRotated
 state variable indicating if the user wants to use a rotate aspect ratio
QToolButton * correctTiltButton
 The start tilt button is disabled while a line is being selected.
QToolButton * cropButton
 The crop buttons is disabled when no seletion is present.
ClickableLabelredEyeReductionButton
 The red eye reduction button is disabled when no selection is present.
QComboBox * effectsList
 List of effects that can be applied to photos.
QPushButton * applyEffectButton
 The apply effect button is disabled when no effect has been chosen.
QLabeleffectPreview
 Label that shows preview of effect.
Subalbumcollection
 ========== Pointer to backend collection
Photophoto
 Pointer to backend photo.
QString effectPreviewImageFilename
 Path to scaled down version of image for fast generation of previews of effects.
LayoutWidgetlayout
 Pointer to the parent layout widget.
int displayWidth
 Dimension of photo in display coordinates.
int displayHeight
int imageWidth
 Dimension of photo in image coordinates.
int imageHeight

Detailed Description

Interface for editing photo.

Definition at line 53 of file editingInterface.h.


Constructor & Destructor Documentation

EditingInterface::EditingInterface ( QWidget parent = 0,
const char *  name = 0 
)

Constructs layout.

Definition at line 71 of file editingInterface.cpp.

References adjustGrain(), applyEffect(), applyEffectButton, aspectRatios, aspectRatioValues, BW_EFFECT, colorBalance(), correctTiltButton, crop(), cropButton, displayResolutionIndex, effectPreview, effectsList, EMBOSS_EFFECT, enhanceContrast(), finishCorrectTilt(), flipHorizontal(), flipVertical(), handleAspectRatioChanged(), handleSelectionChanged(), IMAGE_PATH, INVERT_EFFECT, layout, maxDimensions, MOSAIC_EFFECT, nextButton, NUM_MANIPULATIONS, PAINTING_EFFECT, photo, POINTILLISM_EFFECT, previousButton, redEyeReductionButton, removeRedeye(), rotateLeft(), rotateRight(), rotateSelection(), screenResolutionChanged(), selectAspectRatio(), selectEffect(), selectionInterface, SEPIA_EFFECT, ClickableLabel::setEnabled(), ClickableLabel::setPixmap(), showNextPhoto(), showPrevPhoto(), startCorrectTilt(), TIGHT_WIDGET_SPACING, tuneLevels(), and WIDGET_SPACING.

                                 : QWidget(parent,name)
{
  //create a smaller font for drawing various labels and items
  QFont smallerFont = font();
  smallerFont.setPointSize( smallerFont.pointSize() - 1 );  

  setFocusPolicy(QWidget::StrongFocus);

  //set photo pointer to null by default
  photo = NULL;

  //store layout pointer
  layout = (LayoutWidget*)parent;

  //----------  
  //Construct photo frame that houses photo being edited and prev and next buttons
  QFrame* photoFrame = new QFrame(this, "photoFrame" );
  
  //Construct the frame that houses all the controls
  QFrame* controlsFrame = new QFrame(this, "controlsFrame");

  //Place photo fram and control widgets in a top level grid
  QGridLayout* mainGrid = new QGridLayout( this, 3, 3, 0 );
  mainGrid->addWidget( photoFrame, 0, 1 );
  mainGrid->setRowStretch(0, 1);
  mainGrid->addMultiCellWidget( controlsFrame, 1,1, 0,2 );
  mainGrid->setRowSpacing( 2, WIDGET_SPACING );
  //----------  
  //Previous photo button
  previousButton = new ClickableLabel( photoFrame, "previousButton" );
  previousButton->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/previous.png") ); 
  connect( previousButton, SIGNAL(clicked()), SLOT(showPrevPhoto()) );    

  //Create widget for displaying and selecting regions of the current photo
  selectionInterface = new SelectionInterface( photoFrame, "selectionInterface" );
  connect( selectionInterface, SIGNAL( selectionChanged() ), this, SLOT( handleSelectionChanged() ) );
  connect( selectionInterface, SIGNAL( aspectRatioChanged() ), this, SLOT( handleAspectRatioChanged() ) );
  connect( selectionInterface, SIGNAL( ctrlClick() ), this, SLOT( rotateSelection() ) );
  
  //Next photo button
  nextButton = new ClickableLabel( photoFrame, "nextButton" );
  nextButton->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/next.png") ); 
  connect( nextButton, SIGNAL(clicked()), SLOT(showNextPhoto()) );    

  //Place above widgets in grid, allow seletion interface to take up extra room
  QGridLayout* selectionGrid = new QGridLayout( photoFrame, 1, 5, 0 );
  selectionGrid->setColSpacing( 0, WIDGET_SPACING );
  selectionGrid->addWidget( previousButton,     0, 1, Qt::AlignCenter );
  selectionGrid->addWidget( selectionInterface, 0, 2 );
  selectionGrid->setColStretch( 2, 1 );
  selectionGrid->addWidget( nextButton,         0, 3, Qt::AlignCenter );
  selectionGrid->setColSpacing( 4, WIDGET_SPACING );
  selectionGrid->setSpacing( WIDGET_SPACING );
  //-----------
  //construct the frames each set of controls is placed in
  QHGroupBox* frameControls   = new QHGroupBox( tr("Frame"),   controlsFrame, "frameControls"   );
  frameControls->setAlignment( Qt::AlignHCenter );
  frameControls->setInsideMargin( WIDGET_SPACING );

  QHGroupBox* enhanceControls = new QHGroupBox( tr("Enhance"), controlsFrame, "enhanceControls" );
  enhanceControls->setAlignment( Qt::AlignHCenter ); 
  enhanceControls->setInsideMargin( WIDGET_SPACING );
  
  QHGroupBox* manipulateControls = new QHGroupBox( tr("Manipulate"), controlsFrame, "applyEffect" );
  manipulateControls->setAlignment( Qt::AlignHCenter );
  manipulateControls->setInsideMargin( WIDGET_SPACING );
      
  //layout groups of controls
  QGridLayout* controlsGrid = new QGridLayout( controlsFrame, 1, 5, 0 );
  controlsGrid->addWidget( frameControls,      0, 1 );  
  controlsGrid->addWidget( enhanceControls,    0, 2 );  
  controlsGrid->addWidget( manipulateControls, 0, 3 );  
  
  controlsGrid->setSpacing( WIDGET_SPACING );    
  controlsGrid->setColSpacing(0, WIDGET_SPACING );
  controlsGrid->setColStretch(0, 1);
  controlsGrid->setColSpacing(4, WIDGET_SPACING );
  controlsGrid->setColStretch(4, 1);
  
  //----------   
  //Frame Controls
  //----------    
  QFrame* frameControlsFrame = new QFrame( frameControls );
 
  //-----
  //rotate and flip buttons
  QFrame* rotateFlipFrame = new QFrame( frameControlsFrame );
  
  QToolButton* rotateRightButton = new QToolButton( rotateFlipFrame, "rotateRight" );
  rotateRightButton->setIconSet( QPixmap(QString(IMAGE_PATH)+"buttonIcons/rotate90.png") );
  rotateRightButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  connect( rotateRightButton, SIGNAL(clicked()), SLOT(rotateRight()) );
  QToolTip::add( rotateRightButton, tr("Rotate clockwise") );  
  
  QToolButton* rotateLeftButton = new QToolButton( rotateFlipFrame, "rotateLeft" );
  rotateLeftButton->setIconSet( QPixmap(QString(IMAGE_PATH)+"buttonIcons/rotate270.png") ); 
  rotateLeftButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  connect( rotateLeftButton, SIGNAL(clicked()), SLOT(rotateLeft()) );
  QToolTip::add( rotateLeftButton, tr("Rotate counterclockwise") );  

  QToolButton* flipHorizontalButton = new QToolButton( rotateFlipFrame, "flipHorizontal" );
  flipHorizontalButton->setIconSet( QPixmap(QString(IMAGE_PATH)+"buttonIcons/flipHorizontally.png") );
  flipHorizontalButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  connect( flipHorizontalButton, SIGNAL(clicked()), SLOT(flipHorizontal()) );
  QToolTip::add( flipHorizontalButton, tr("Flip horizontally") );  
  
  QToolButton* flipVerticalButton = new QToolButton( rotateFlipFrame, "flipVertical" );
  flipVerticalButton->setIconSet( QPixmap(QString(IMAGE_PATH)+"buttonIcons/flipVertically.png") ); 
  flipVerticalButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  connect( flipVerticalButton, SIGNAL(clicked()), SLOT(flipVertical()) );  
  QToolTip::add( flipVerticalButton, tr("Flip vertically") );  
  
  correctTiltButton = new QToolButton( rotateFlipFrame, "correctTilt" );
  correctTiltButton->setIconSet( QPixmap(QString(IMAGE_PATH)+"buttonIcons/correctTilt.png") ); 
  correctTiltButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  
  connect( correctTiltButton, SIGNAL(clicked()), SLOT(startCorrectTilt()) );

  connect( selectionInterface, SIGNAL(lineSelected(QPoint, QPoint)),
           this, SLOT(finishCorrectTilt( QPoint, QPoint)) );

  QToolTip::add( correctTiltButton, tr("Correct tilt") );  

  //Place buttons in grid
  QGridLayout* rotateFlipGrid = new QGridLayout( rotateFlipFrame, 1, 5, 0 );
  rotateFlipGrid->setSpacing(TIGHT_WIDGET_SPACING);  
  rotateFlipGrid->addWidget( rotateRightButton,    0, 0 );
  rotateFlipGrid->addWidget( rotateLeftButton,     0, 1 );
  rotateFlipGrid->addWidget( flipHorizontalButton, 0, 2 );
  rotateFlipGrid->addWidget( flipVerticalButton,   0, 3 );
  rotateFlipGrid->addWidget( correctTiltButton,    0, 4 );
  //-----
  //aspect ratio selection and crop controls
  aspectRatios = new QComboBox( frameControlsFrame );
  aspectRatios->setFont( smallerFont );
  connect( aspectRatios, SIGNAL(activated(int)), this, SLOT(selectAspectRatio()) );  
  aspectRatioValues = new QSize[8];
  maxDimensions = new double[8];
  int curAspectRatio = 0;
  //--
  aspectRatios->insertItem( tr("Custom") );
  maxDimensions[curAspectRatio] = -1.0;
  aspectRatioValues[curAspectRatio++] = QSize( -1, -1 );
  //--  
  aspectRatios->insertItem( tr("Photo (3.5 x 5)") );
  maxDimensions[curAspectRatio] = 5.0;
  aspectRatioValues[curAspectRatio++] = QSize( 10, 7 );
  //--  
  aspectRatios->insertItem( tr("Photo (4 x 6)") );
  maxDimensions[curAspectRatio] = 6.0;
  aspectRatioValues[curAspectRatio++] = QSize( 6, 4 );
  //--  
  aspectRatios->insertItem( tr("Photo (5 x 7)") );
  maxDimensions[curAspectRatio] = 7.0;
  aspectRatioValues[curAspectRatio++] = QSize( 7, 5 );
  //--  
  aspectRatios->insertItem( tr("Photo (8 x 10)") );
  maxDimensions[curAspectRatio] = 10.0;
  aspectRatioValues[curAspectRatio++] = QSize( 10, 8 );
  //--  
  aspectRatios->insertItem( tr("Postcard") );
  maxDimensions[curAspectRatio] = 6.0;
  aspectRatioValues[curAspectRatio++] = QSize( 6, 4 );
  //--  
  aspectRatios->insertItem( tr("Wallet") );
  maxDimensions[curAspectRatio] = 3.0;
  aspectRatioValues[curAspectRatio++] = QSize( 3, 2 );
  //--  
  aspectRatios->insertItem( tr("Desktop") );
  displayResolutionIndex = curAspectRatio;
  maxDimensions[curAspectRatio] = -1.0;
  aspectRatioValues[curAspectRatio++] = qApp->desktop()->screenGeometry().size();
  //--  
  //connect signal emitted when screen resolution changes 
  //so as to update this stored value (and selction if necessary)
  connect( qApp->desktop(), SIGNAL( resized(int)), this, SLOT(screenResolutionChanged()) );

  QToolTip::add( aspectRatios, tr("Select region for cropping using a particular aspect ratio") );  

  QLabel* aspectRatioLabel = new QLabel( tr("Aspect Ratio"), frameControlsFrame );
  aspectRatioLabel->setFont( smallerFont );
  //--

  //Crop button
  cropButton = new QToolButton( frameControlsFrame );
  QIconSet cropIcon;
  cropIcon.setPixmap( QString(IMAGE_PATH)+"buttonIcons/crop.png",
                      QIconSet::Automatic,
                      QIconSet::Normal );
                       
  cropIcon.setPixmap( QString(IMAGE_PATH)+"buttonIcons/crop_disabled.png",
                      QIconSet::Automatic,
                      QIconSet::Disabled );
  cropButton->setIconSet( cropIcon );
  connect( cropButton, SIGNAL(clicked()), SLOT(crop()) );
  QToolTip::add( cropButton, tr("Crop photo to selected region") );  

  QLabel* cropLabel = new QLabel( tr("Crop"), frameControlsFrame );
  cropLabel->setFont( smallerFont );  
  
  //--  

  //Place frame controls in a grid
  QGridLayout* frameControlsGrid = new QGridLayout( frameControlsFrame, 3, 2, 0 );
  frameControlsGrid->setSpacing(TIGHT_WIDGET_SPACING);  
  frameControlsGrid->addMultiCellWidget( rotateFlipFrame, 0,0,  0,1 );
  frameControlsGrid->addWidget( aspectRatios,     1, 0, Qt::AlignHCenter );  
  frameControlsGrid->addWidget( cropButton,       1, 1, Qt::AlignHCenter );  
  frameControlsGrid->addWidget( aspectRatioLabel, 2, 0, Qt::AlignHCenter );  
  frameControlsGrid->addWidget( cropLabel,        2, 1, Qt::AlignHCenter );    

  //----------  
  //Enhance Controls
  //----------    
  QFrame* enhanceControlsFrame = new QFrame( enhanceControls );  
  
  //setup params for large buttons  
  int numLargeButtons = 3;
  int curButtonIndex=0;
  ClickableLabel** largeButtons = new ClickableLabel*[numLargeButtons];
  

  //--------------------
  //Frame for semi-automatic enhance controls
  QFrame* autoEnhanceControlsFrame = new QFrame( enhanceControlsFrame );  

  //Enhance Color
  ClickableLabel* enhanceColorButton = largeButtons[curButtonIndex] = 
    new ClickableLabel( autoEnhanceControlsFrame );
  largeButtons[curButtonIndex]->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/improveColorBalance.png") );
  connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(colorBalance()) );
  QToolTip::add( largeButtons[curButtonIndex], tr("Enhance color balance") );  
  curButtonIndex++;

  QLabel* enhanceColorLabel = new QLabel( tr("Color"), autoEnhanceControlsFrame );
  enhanceColorLabel->setFont( smallerFont );  
  
  //Enhance Contrast
  ClickableLabel* enhanceContrastButton = largeButtons[curButtonIndex] = 
    new ClickableLabel( autoEnhanceControlsFrame );
  largeButtons[curButtonIndex]->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/enhanceContrast.png") );
  connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(enhanceContrast()) );
  QToolTip::add( largeButtons[curButtonIndex], tr("Enhance contrast") );  
  curButtonIndex++;
  
  QLabel* enhanceContrastLabel = new QLabel( tr("Contrast"), autoEnhanceControlsFrame );
  enhanceContrastLabel->setFont( smallerFont );  

  //Remove Red-Eye  
  redEyeReductionButton = largeButtons[curButtonIndex] = new ClickableLabel( autoEnhanceControlsFrame );
  redEyeReductionButton->setEnabled( false );
  
  largeButtons[curButtonIndex]->setPixmap( QPixmap( QString(IMAGE_PATH)+"buttonIcons/redEyeReduction.png" ) );
  connect( largeButtons[curButtonIndex], SIGNAL(clicked()), SLOT(removeRedeye()) );
  QToolTip::add( largeButtons[curButtonIndex], tr("Remove red-eye") );  
  curButtonIndex++;

  QLabel* removeRedyEyeLabel = new QLabel( tr("Red Eye"), autoEnhanceControlsFrame );
  removeRedyEyeLabel->setFont( smallerFont );  

  //Place semi-automatic enhance controls in grid
  QGridLayout* autoEnhanceControlsGrid = new QGridLayout( autoEnhanceControlsFrame, 2, 3, 0 );
  autoEnhanceControlsGrid->setSpacing(TIGHT_WIDGET_SPACING);  
  autoEnhanceControlsGrid->addWidget( enhanceColorButton,    0, 0, Qt::AlignHCenter );
  autoEnhanceControlsGrid->addWidget( enhanceColorLabel,     1, 0, Qt::AlignHCenter );  

  autoEnhanceControlsGrid->addWidget( enhanceContrastButton, 0, 1, Qt::AlignHCenter );
  autoEnhanceControlsGrid->addWidget( enhanceContrastLabel,  1, 1, Qt::AlignHCenter );  

  autoEnhanceControlsGrid->addWidget( redEyeReductionButton, 0, 2, Qt::AlignHCenter );
  autoEnhanceControlsGrid->addWidget( removeRedyEyeLabel,    1, 2, Qt::AlignHCenter );  
  //--------------------
  //Frame for more labor intensive enhance controls
  QFrame* manualEnhanceControlsFrame = new QFrame( enhanceControlsFrame );  
  
  //Tune Levels Button
  ClickableLabel* tuneLevelsButton = new ClickableLabel( manualEnhanceControlsFrame );
  tuneLevelsButton->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/tuneLevels.png") );
  connect( tuneLevelsButton, SIGNAL(clicked()), SLOT(tuneLevels()) );
  QToolTip::add( tuneLevelsButton, tr("Fine tune brightness, contrast, and colors") );  
  
  QLabel* tuneLevelsLabel = new QLabel( tr("Levels..."), manualEnhanceControlsFrame );
  tuneLevelsLabel->setFont( smallerFont );  

  //Adjust Grain Button
  ClickableLabel* adjustGrainButton = new ClickableLabel( manualEnhanceControlsFrame );
  adjustGrainButton->setPixmap( QPixmap(QString(IMAGE_PATH)+"buttonIcons/adjustGrain.png") );
  connect( adjustGrainButton, SIGNAL(clicked()), SLOT(adjustGrain()) );
  QToolTip::add( adjustGrainButton, tr("Blur or sharpen image") );  

  QLabel* adjustGrainLabel = new QLabel( tr("Grain..."), manualEnhanceControlsFrame );
  adjustGrainLabel->setFont( smallerFont );  

  //Place manual enhance controls in grid
  QGridLayout* manualEnhanceControlsGrid = new QGridLayout( manualEnhanceControlsFrame, 2, 3, 0 );
  manualEnhanceControlsGrid->setSpacing(TIGHT_WIDGET_SPACING);  
  manualEnhanceControlsGrid->addWidget( tuneLevelsButton,    0, 0, Qt::AlignHCenter );
  manualEnhanceControlsGrid->addWidget( tuneLevelsLabel,     1, 0, Qt::AlignHCenter );
  manualEnhanceControlsGrid->setColSpacing( 1, WIDGET_SPACING );
  manualEnhanceControlsGrid->addWidget( adjustGrainButton, 0, 2, Qt::AlignHCenter );
  manualEnhanceControlsGrid->addWidget( adjustGrainLabel,  1, 2, Qt::AlignHCenter );
  //--------------------

  //Place enhance controls in a grid
  QGridLayout* enhanceControlsGrid = new QGridLayout( enhanceControlsFrame, 4, 2, 0 );
  enhanceControlsGrid->setSpacing(WIDGET_SPACING);  
  enhanceControlsGrid->addWidget( autoEnhanceControlsFrame,   0, 0, Qt::AlignHCenter );
  enhanceControlsGrid->addWidget( manualEnhanceControlsFrame, 1, 0, Qt::AlignHCenter );
  enhanceControlsGrid->setRowStretch( 0, 1 );
  enhanceControlsGrid->setRowStretch( 3, 1 );
  
  //----------  
  //Effects Controls
  //----------  
  QFrame* manipulateControlsFrame = new QFrame( manipulateControls, "manipulateControlsFrame" );
  //--  
  //Effects
  effectsList = new QComboBox( manipulateControlsFrame );
  effectsList->setFont( smallerFont );  
  connect( effectsList, SIGNAL(activated(int)), this, SLOT(selectEffect()) );

  int i;
  for(i=0; i<NUM_MANIPULATIONS; i++)
  {
    switch(i)
    {
      case BW_EFFECT:          effectsList->insertItem( tr("B + W") );       break;
      case SEPIA_EFFECT:       effectsList->insertItem( tr("Sepia") );       break;
      case INVERT_EFFECT:      effectsList->insertItem( tr("Invert") );      break;
      case EMBOSS_EFFECT:      effectsList->insertItem( tr("Emboss") );      break;
      case MOSAIC_EFFECT:      effectsList->insertItem( tr("Mosaic") );       break;
      case PAINTING_EFFECT:    effectsList->insertItem( tr("Painting") );    break;
      case POINTILLISM_EFFECT: effectsList->insertItem( tr("Pointillism") ); break;
    }
  }

  //Apply effect button
  applyEffectButton = new QPushButton( tr("Apply"), manipulateControlsFrame );
  applyEffectButton->setFont( smallerFont );  
  connect( applyEffectButton, SIGNAL(clicked()), SLOT(applyEffect()) );   
  
  //preview of seleted effect
  effectPreview = new QLabel( manipulateControlsFrame );
 
  //Place effects controls in a grid
  QGridLayout* manipulateControlsGrid = new QGridLayout( manipulateControlsFrame, 2, 2, 0 );
  manipulateControlsGrid->setSpacing(TIGHT_WIDGET_SPACING);  
  manipulateControlsGrid->addWidget( effectsList, 0, 0 );
  manipulateControlsGrid->addWidget( applyEffectButton, 1, 0, Qt::AlignHCenter );  
  manipulateControlsGrid->addMultiCellWidget( effectPreview, 0,1, 1,1, Qt::AlignHCenter );  

  //make sure preview image always requires EFFECT_PREVIEW_WIDTH width so contorls don't
  //move around when rotating photos
  manipulateControlsGrid->setColSpacing(1, 85 );
}
EditingInterface::~EditingInterface ( )

Definition at line 428 of file editingInterface.cpp.

{ }

Member Function Documentation

void EditingInterface::adjustGrain ( ) [private, slot]

Opens image grain editor.

Definition at line 748 of file editingInterface.cpp.

References applyImageUpdate(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, and StatusWidget::releaseInput().

Referenced by EditingInterface().

{
  //load photo in grain editor
  //if changes took place update image
  GrainEditor editor( photo->getImageFilename(), this);
  if( editor.exec() ) 
  { 
    //set busy cursor
    qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
    qApp->processEvents();
    
    //disable user input
    layout->getWindow()->getStatus()->grabInput();

    //update image    
    applyImageUpdate( editor.getModifiedImage(), false ); 
    
    //enable user input
    layout->getWindow()->getStatus()->releaseInput();

    //remove busy cursor
    qApp->restoreOverrideCursor();
    qApp->processEvents();
  }
}
void EditingInterface::applyEffect ( ) [private, slot]

Apply selected effect.

Definition at line 788 of file editingInterface.cpp.

References applyEffectButton, applyImageUpdate(), editedImage, effectsList, Photo::getImageFilename(), MosaicOptionsDialog::getOptions(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, MOSAIC_EFFECT, photo, StatusWidget::releaseInput(), StatusWidget::setStatus(), and StatusWidget::showProgressBar().

Referenced by EditingInterface(), and selectEffect().

{  
  //--------------------------------
  //Get any manipulation options if needed
  ManipulationOptions* options = NULL;
  if( effectsList->currentItem() == MOSAIC_EFFECT )   
  {
    MosaicOptionsDialog optionsDialog(this);
    //user accepted so get selected options
    if( optionsDialog.exec() ) 
    { 
      //constructing the tiles list can unfortunately be quite slow so show a preparing tiles message
      //and busy icon while getting the options chosen
      layout->getWindow()->getStatus()->showProgressBar( QString(tr("Preparing Tiles")), 100 );
      qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
      qApp->processEvents();       
      options = optionsDialog.getOptions(); 
      qApp->restoreOverrideCursor();
    }
    //user hit cancel so bail
    else 
    { return; }
  }
  else
  { options = new ManipulationOptions( layout->getWindow()->getStatus() ); }
  //--------------------------------
  //Disable user input
  layout->getWindow()->getStatus()->grabInput();
  applyEffectButton->setEnabled(false);
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();
  //--------------------------------
  //Apply effect
  QImage* editedImage = applyEffect( photo->getImageFilename(), options );
  applyImageUpdate( editedImage, false );
  delete options; options = NULL;
  //--------------------------------
  //Remove status bar if present and reenable user input
  layout->getWindow()->getStatus()->setStatus( "" );
  layout->getWindow()->getStatus()->releaseInput();
  applyEffectButton->setEnabled(true);
  qApp->restoreOverrideCursor();
  qApp->processEvents();
  //--------------------------------
} 
QImage * EditingInterface::applyEffect ( QString  filename,
ManipulationOptions options = NULL 
) [private]

utlity function for apply effect and preview effect slots

Definition at line 834 of file editingInterface.cpp.

References blackWhiteEffect(), BW_EFFECT, effectsList, EMBOSS_EFFECT, embossEffect(), INVERT_EFFECT, invertEffect(), MOSAIC_EFFECT, mosaicEffect(), oilPaintingEffect(), PAINTING_EFFECT, POINTILLISM_EFFECT, pointillismEffect(), SEPIA_EFFECT, and sepiaEffect().

{
  //apply effect
  QImage* effectedImage = NULL;
  switch( effectsList->currentItem() )
  {
    case BW_EFFECT:          effectedImage = blackWhiteEffect(  filename, options ); break;
    case SEPIA_EFFECT:       effectedImage = sepiaEffect(       filename, options ); break;
    case INVERT_EFFECT:      effectedImage = invertEffect(      filename, options ); break;
    case EMBOSS_EFFECT:      effectedImage = embossEffect(      filename, options ); break;
    case PAINTING_EFFECT:    effectedImage = oilPaintingEffect( filename, options ); break;
    case POINTILLISM_EFFECT: effectedImage = pointillismEffect( filename, options ); break;
    case MOSAIC_EFFECT:      effectedImage = mosaicEffect(      filename, (MosaicOptions*) options ); break;
  }

  //return effected image
  return effectedImage;
}
void EditingInterface::applyImageUpdate ( QImage *  editedImage,
bool  resetSelection 
) [private]

Applies update to image.

Definition at line 853 of file editingInterface.cpp.

References displayHeight, displayWidth, editedImage, EFFECT_PREVIEW_HEIGHT, EFFECT_PREVIEW_WIDTH, effectPreviewImageFilename, SelectionInterface::getDisplaySize(), Photo::getImageFilename(), getImageSize(), imageHeight, imageWidth, photo, photoModified(), scaleImage(), selectEffect(), selectionInterface, selectionRotated, SelectionInterface::selectNone(), Photo::setImage(), and SelectionInterface::setPhoto().

Referenced by adjustGrain(), applyEffect(), colorBalance(), crop(), enhanceContrast(), finishCorrectTilt(), removeRedeye(), and tuneLevels().

{  
  //skip apply step if pointer is null. this usually means
  //no modifications were made (for example: no red eyes were detected)
  if(editedImage == NULL) 
  { 
    //sometimes the user instructs the program to modify an image in a way
    //where no real changes are actually necessary. case in point, red eye reduction
    //on a region where there is no red stuff at all! in order to be consistant, if
    //the user is expecting the selection to be reset then always reset it! this
    //normally occurs below when resetting the photo but we'll do it here 
    //since resetting the photo will not take place
    if(resetSelection) 
    { 
      selectionInterface->selectNone(); 
    }
    
    return; 
  }
  
  //construct edited image path
  QString editedImagePath = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() + "/editedImage.jpg";

  //save edited image to temporary location
  //TODO: EXIF information is lost at this point, Qt does not support
  //storing exif information, but perhaps a 2nd pass can be made on the file
  //where exif info is added using libjpeg functions?
  editedImage->save( editedImagePath, "JPEG", 95 );
  delete editedImage;
  editedImage = NULL;
    
  //apply changes to photo
  photo->setImage( editedImagePath );
  
  //Reload photo view
  selectionInterface->setPhoto( editedImagePath, resetSelection );  

  //If we're resetting the selection (due to cropping), reset the 
  //selection rotated bit as well
  if( resetSelection ) { selectionRotated = false; }
  
  //update image dimension variables
  getImageSize( photo->getImageFilename(), imageWidth, imageHeight );  

  //get display size photo dimensions
  selectionInterface->getDisplaySize( displayWidth, displayHeight );

  //update effect preview
  scaleImage( photo->getImageFilename(), effectPreviewImageFilename, EFFECT_PREVIEW_WIDTH, EFFECT_PREVIEW_HEIGHT );
  selectEffect();
  
  //emit modified signal
  emit photoModified();
}
void EditingInterface::colorBalance ( ) [private, slot]

Improve color balance.

Definition at line 672 of file editingInterface.cpp.

References applyImageUpdate(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), improveColorBalance(), layout, photo, and StatusWidget::releaseInput().

Referenced by EditingInterface().

{
  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();

  //disable user input
  layout->getWindow()->getStatus()->grabInput();

  //improve color balance
  applyImageUpdate( improveColorBalance( photo->getImageFilename(),
                                         layout->getWindow()->getStatus() ),
                    false );

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
  qApp->processEvents();
}
void EditingInterface::crop ( ) [private, slot]

Cropped image.

Definition at line 626 of file editingInterface.cpp.

References applyImageUpdate(), bottomRight, cropImage(), findSelection(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, StatusWidget::releaseInput(), and topLeft.

Referenced by EditingInterface().

{
  //find selection, if empty bail!
  QPoint topLeft, bottomRight;
  if (!findSelection(topLeft, bottomRight) )
    return;

  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));

  //disable user input
  layout->getWindow()->getStatus()->grabInput();

  //crop image
  applyImageUpdate( cropImage( photo->getImageFilename(), topLeft, bottomRight ),
                    true );

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
}
bool EditingInterface::currentPhotoRevertable ( )

Definition at line 995 of file editingInterface.cpp.

References photo, and Photo::revertPossible().

Referenced by LayoutWidget::photoStateChangedEvent(), and revertCurrentPhoto().

{
  if(photo == NULL) 
    return false;
  else
    return photo->revertPossible();
}
void EditingInterface::enhanceContrast ( ) [private, slot]

Enhance image contrast.

Definition at line 650 of file editingInterface.cpp.

References applyImageUpdate(), enhanceImageContrast(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, and StatusWidget::releaseInput().

Referenced by EditingInterface().

{
  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();

  //disable user input
  layout->getWindow()->getStatus()->grabInput();

  //enhance image
  applyImageUpdate( enhanceImageContrast( photo->getImageFilename(),
                                          layout->getWindow()->getStatus() ),
                    false );

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
  qApp->processEvents();
}
bool EditingInterface::findSelection ( QPoint &  topLeft,
QPoint &  bottomRight 
) [private]

Finds the selected region of the image.

Definition at line 914 of file editingInterface.cpp.

References SelectionInterface::getSelection(), and selectionInterface.

Referenced by crop(), handleSelectionChanged(), and removeRedeye().

{
  //get raw selection in display coordinates
  selectionInterface->getSelection(topLeft, bottomRight);

  //if range is empty then retrun false
  if(topLeft.x() >= bottomRight.x() ||
     topLeft.y() >= bottomRight.y())
    return false;
  
  //return success
  return true;
}
void EditingInterface::finishCorrectTilt ( QPoint  p1,
QPoint  p2 
) [private, slot]

Finish correcting and image's tilt.

Definition at line 1215 of file editingInterface.cpp.

References applyImageUpdate(), correctImageTilt(), correctTiltButton, Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, and StatusWidget::releaseInput().

Referenced by EditingInterface().

{
  //if either point is invalid ignore action
  if( p1.x() == -1 || p2.x() == -1 )
  {
    //reenable tilt button
    correctTiltButton->setEnabled( true );
    return;
  }
  
  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  
  //disable user input
  layout->getWindow()->getStatus()->grabInput();
  
  //rotate image by determining correct angle from two points
  QImage* rotatedImage = correctImageTilt( photo->getImageFilename(), p1, p2,
                                           layout->getWindow()->getStatus() );
  applyImageUpdate( rotatedImage, true );
  
  //reenable tilt button
  correctTiltButton->setEnabled( true );

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
}
void EditingInterface::flipHorizontal ( ) [private, slot]

Flip image horizontally.

Definition at line 557 of file editingInterface.cpp.

References FLIP_H, and rotateFlip().

Referenced by EditingInterface(), and keyPressEvent().

void EditingInterface::flipVertical ( ) [private, slot]

Flip image vertically.

Definition at line 562 of file editingInterface.cpp.

References FLIP_V, and rotateFlip().

Referenced by EditingInterface(), and keyPressEvent().

Photo * EditingInterface::getPhoto ( )

Returns a pointer to the currently selected photo.

Definition at line 430 of file editingInterface.cpp.

References photo.

Referenced by LayoutWidget::tabChanged().

{ return photo; }
void EditingInterface::handleAspectRatioChanged ( ) [slot]

Definition at line 938 of file editingInterface.cpp.

References aspectRatios.

Referenced by EditingInterface().

{
  //change aspect ratio combo box to custom
  aspectRatios->setCurrentItem(0);  
}
void EditingInterface::handleSelectionChanged ( ) [slot]

Definition at line 928 of file editingInterface.cpp.

References bottomRight, cropButton, findSelection(), redEyeReductionButton, ClickableLabel::setEnabled(), and topLeft.

Referenced by EditingInterface().

{
  //crop button is enabled only when a portion of the image is selected
  QPoint topLeft, bottomRight;
  bool selectionPresent = findSelection(topLeft,bottomRight);     

  cropButton->setEnabled( selectionPresent );
  redEyeReductionButton->setEnabled( selectionPresent );  
}
void EditingInterface::keyPressEvent ( QKeyEvent *  e) [protected]

Definition at line 952 of file editingInterface.cpp.

References flipHorizontal(), flipVertical(), returnAction(), rotateLeft(), rotateRight(), showFirstPhoto(), showLastPhoto(), showNextPhoto(), and showPrevPhoto().

{
  //next handle additional keys
  switch( e->key() )
  {
    //apply changes and exit
    case Qt::Key_Escape:
      returnAction();
      break;
    case Qt::Key_Prior:
      showPrevPhoto();
      break;
    case Qt::Key_Next:
      showNextPhoto();
      break;
    case Qt::Key_Home:
      showFirstPhoto();
      break;
    case Qt::Key_End:
      showLastPhoto();
      break;
    case Qt::Key_R:
      if(e->state() & Qt::ControlButton)
        rotateRight();
      break;
    case Qt::Key_L:
      if(e->state() & Qt::ControlButton)
        rotateLeft();
      break;
    case Qt::Key_F:
      if(e->state() & Qt::ControlButton)
      {
        if( e->state() & Qt::AltButton )
          flipVertical();
        else
          flipHorizontal();
      }
      break;
    default:
      e->ignore();
  }
}
void EditingInterface::photoModified ( ) [signal]
void EditingInterface::removeRedeye ( ) [private, slot]

Applies redeye removal.

Definition at line 694 of file editingInterface.cpp.

References applyImageUpdate(), bottomRight, findSelection(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, StatusWidget::releaseInput(), removeRedeyeRegions(), and topLeft.

Referenced by EditingInterface().

{
  //find selection, if empty bail!
  QPoint topLeft, bottomRight;
  if (!findSelection(topLeft, bottomRight) )
    return;

  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();
  
  //disable user input
  layout->getWindow()->getStatus()->grabInput();

  //remove redeye image
  applyImageUpdate( removeRedeyeRegions( photo->getImageFilename(), 
                                         topLeft, bottomRight,
                                         layout->getWindow()->getStatus() ),
                    true );

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
  qApp->processEvents();
}
void EditingInterface::returnAction ( ) [private, slot]

Exit editing interface.

Definition at line 908 of file editingInterface.cpp.

References layout, and LayoutWidget::organize().

Referenced by keyPressEvent().

{
  //exit edit mode
  layout->organize();
}
void EditingInterface::revertCurrentPhoto ( )

reverts current photo and updates display

Revert photo

Definition at line 1003 of file editingInterface.cpp.

References currentPhotoRevertable(), displayHeight, displayWidth, EFFECT_PREVIEW_HEIGHT, EFFECT_PREVIEW_WIDTH, effectPreviewImageFilename, SelectionInterface::getDisplaySize(), Photo::getImageFilename(), getImageSize(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), imageHeight, imageWidth, layout, Photo::originalImageFilename(), photo, photoModified(), StatusWidget::releaseInput(), Photo::revertPhoto(), scaleImage(), selectEffect(), selectionInterface, and SelectionInterface::setPhoto().

Referenced by LayoutWidget::revertPhotos().

{
  //if current photo not revertable immediately bail
  if( ! currentPhotoRevertable() ) return;
  
  //set busy cursor
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  
  //disable user input
  layout->getWindow()->getStatus()->grabInput();

  //get current and reverted image sizes and compare to see if size has changed.
  //if so reset selected region
  int origWidth, origHeight;
  getImageSize( photo->originalImageFilename(), origWidth, origHeight );  
  bool resetSelection = (origWidth != imageWidth) || (origHeight != imageHeight);
  
  photo->revertPhoto();

  //Reload photo view
  selectionInterface->setPhoto( photo->getImageFilename(), resetSelection );  
  
  //update image dimension variables
  getImageSize( photo->getImageFilename(), imageWidth, imageHeight );  
  
  //get display size photo dimensions
  selectionInterface->getDisplaySize( displayWidth, displayHeight );
  
  //update effect preview
  scaleImage( photo->getImageFilename(), effectPreviewImageFilename, EFFECT_PREVIEW_WIDTH, EFFECT_PREVIEW_HEIGHT );
  selectEffect();  
  
  //emit modified signal
  emit photoModified();

  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
}
void EditingInterface::rotateFlip ( TRANSFORM_CODE  rotationFlipType) [private]

Utility method for rotation + flip slots.

Definition at line 567 of file editingInterface.cpp.

References displayHeight, displayWidth, EFFECT_PREVIEW_HEIGHT, EFFECT_PREVIEW_WIDTH, effectPreviewImageFilename, SelectionInterface::getDisplaySize(), Photo::getImageFilename(), getImageSize(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), imageHeight, imageWidth, layout, photo, photoModified(), StatusWidget::releaseInput(), ROTATE_270, ROTATE_90, scaleImage(), selectAspectRatio(), selectEffect(), selectionInterface, selectionRotated, Photo::setImage(), SelectionInterface::setPhoto(), and transformImage().

Referenced by flipHorizontal(), flipVertical(), rotateLeft(), and rotateRight().

{
  //set busy pointer
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();
  
  //disable user input
  layout->getWindow()->getStatus()->grabInput();
  
  //rotate image, bail if rotation fails
  QString editedImagePath = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() + "/editedImage.jpg";
  transformImage( photo->getImageFilename(), editedImagePath, rotationFlipType );

  //apply changes to photo
  photo->setImage( editedImagePath );
  
  //Reload photo view
  bool aspectRatioChanged = ( rotationFlipType == ROTATE_90 || rotationFlipType == ROTATE_270 );  
  selectionInterface->setPhoto( editedImagePath, aspectRatioChanged );  
  
  //update image dimension variables
  getImageSize( photo->getImageFilename(), imageWidth, imageHeight );  
  
  //get display size photo dimensions
  selectionInterface->getDisplaySize( displayWidth, displayHeight );
  
  //reapply selected aspect ratio selection if aspect ratio changed
  if( aspectRatioChanged )
  {
    //reset selectionRotated bool to false
    selectionRotated = false;
    selectAspectRatio();      
  }
  
  //update effect preview
  scaleImage( photo->getImageFilename(), effectPreviewImageFilename, EFFECT_PREVIEW_WIDTH, EFFECT_PREVIEW_HEIGHT );
  selectEffect();
  
  //emit modified signal
  emit photoModified();
  
  //enable user input
  layout->getWindow()->getStatus()->releaseInput();

  //remove busy cursor
  qApp->restoreOverrideCursor();
  qApp->processEvents();
}
void EditingInterface::rotateLeft ( ) [private, slot]

Rotate image left 90 degrees.

Definition at line 552 of file editingInterface.cpp.

References ROTATE_270, and rotateFlip().

Referenced by EditingInterface(), and keyPressEvent().

void EditingInterface::rotateRight ( ) [private, slot]

Rotate image right 90 degrees.

Definition at line 547 of file editingInterface.cpp.

References ROTATE_90, and rotateFlip().

Referenced by EditingInterface(), and keyPressEvent().

void EditingInterface::rotateSelection ( ) [private, slot]

Rotate current selection.

Definition at line 1052 of file editingInterface.cpp.

References aspectRatios, bottomRight, calcScaledImageDimensions(), SelectionInterface::getSelection(), imageHeight, imageWidth, selectAspectRatio(), selectionInterface, selectionRotated, SelectionInterface::setSelection(), and topLeft.

Referenced by EditingInterface().

{
  //invert rotate bool
  selectionRotated = !selectionRotated;
  
  //rotate custom selection in place, scale/shift if necessary to keep on image
  if(aspectRatios->currentItem() == 0)
  {
    //get cur selection
    QPoint curTopLeft, curBottomRight;
    selectionInterface->getSelection(curTopLeft, curBottomRight); 

    //find center
    QPoint selectionCenter = QPoint( ( curTopLeft.x() + curBottomRight.x() ) / 2,
                                     ( curTopLeft.y() + curBottomRight.y() ) / 2 );    

    //scale rotated width/height to fit image
    int newWidth = curBottomRight.y() - curTopLeft.y() + 1;
    int newHeight =curBottomRight.x() - curTopLeft.x() + 1;
    calcScaledImageDimensions( newWidth, newHeight,
                               imageWidth, imageHeight,
                               newWidth, newHeight );

    //center new selection over old selection
    QPoint topLeft = QPoint( selectionCenter.x() - newWidth/2,
                             selectionCenter.y() - newHeight/2 );
    QPoint bottomRight = QPoint( topLeft.x() + newWidth - 1,
                                 topLeft.y() + newHeight - 1 );

    //shift selection area to not go outside image boundary
    if(topLeft.x() < 0)
    {
      bottomRight.setX( bottomRight.x() - topLeft.x() );
      topLeft.setX( 0 );
    }

    if(topLeft.y() < 0)
    {
      bottomRight.setY( bottomRight.y() - topLeft.y() );
      topLeft.setY( 0 );
    }
    
    if(bottomRight.x() >= imageWidth )
    {
      topLeft.setX( topLeft.x() - ( bottomRight.x() - imageWidth + 1 ) );
      bottomRight.setX( imageWidth - 1 );
    }

    if(bottomRight.y() >= imageHeight )
    {
      topLeft.setY( topLeft.y() - ( bottomRight.y() - imageHeight + 1 ) );
      bottomRight.setY( imageHeight - 1 );
    }
    
    //select new region
    selectionInterface->setSelection(topLeft, bottomRight);    
  }
  //else call selectAspectRatio passing true that we're
  //using the rotated version of the current aspect ratio
  else
  { 
    selectAspectRatio(); 
  }
}
void EditingInterface::screenResolutionChanged ( ) [private, slot]

Update recorded screen resolution and selection if necessary.

Definition at line 616 of file editingInterface.cpp.

References aspectRatios, aspectRatioValues, displayResolutionIndex, and selectAspectRatio().

Referenced by EditingInterface().

{
  //reset display resolution
  aspectRatioValues[displayResolutionIndex] = qApp->desktop()->screenGeometry().size();

  //if user is currently constraining the current selection then reset to fit new display resolution
  if(aspectRatios->currentItem() == displayResolutionIndex )
  { selectAspectRatio(); }
}
void EditingInterface::selectAll ( QPoint &  topLeft,
QPoint &  bottomRight 
) [private]

Return coordinates that select entire image.

Definition at line 944 of file editingInterface.cpp.

References imageHeight, and imageWidth.

{
  topLeft.setX(0); 
  topLeft.setY(0);
  bottomRight.setX(imageWidth - 1); 
  bottomRight.setY(imageHeight - 1);     
}
void EditingInterface::selectAspectRatio ( ) [private, slot]

Aspect ratio selection changed.

Definition at line 1117 of file editingInterface.cpp.

References aspectRatios, aspectRatioValues, calcScaledImageDimensions(), displayResolutionIndex, SelectionInterface::getSelection(), imageHeight, imageWidth, maxDimensions, selectionInterface, selectionRotated, and SelectionInterface::setSelection().

Referenced by EditingInterface(), rotateFlip(), rotateSelection(), screenResolutionChanged(), and showNextPrevFirstLastPhoto().

{
  //if user selected "custom" don't modify current selection
  if( aspectRatios->currentItem() == 0 ) return;
  
  //get default aspect ratio
  QSize aspectRatio = aspectRatioValues[ aspectRatios->currentItem() ];  

  //automatically rotate default if current photo is taller than wide
  if( imageHeight > imageWidth )
  { aspectRatio = QSize( aspectRatio.height(), aspectRatio.width() ); }
  
  //exchange aspect ratio dimensions if we're in rotated selection mode
  if( selectionRotated )
  { aspectRatio = QSize( aspectRatio.height(), aspectRatio.width() ); }
    
  //determine selected width and height;
  int selectedWidth = 0; 
  int selectedHeight = 0;
  
  //display resolution, match exactly or scale down
  if(aspectRatios->currentItem() == displayResolutionIndex)
  {    
    //select region less than or equal to display resolution while maintaining aspect ratio
    selectedWidth = aspectRatio.width();
    selectedHeight = aspectRatio.height();
    calcScaledImageDimensions( selectedWidth, selectedHeight,
                               imageWidth, imageHeight,
                               selectedWidth, selectedHeight );
  }
  //else use aspect ratio directly as a ratio
  else
  {  
    //select region using same aspect ratio
    selectedWidth = imageWidth;
    selectedHeight = (int) (((double) (imageWidth * aspectRatio.height()) ) / aspectRatio.width() );
    calcScaledImageDimensions( selectedWidth, selectedHeight,
                               imageWidth, imageHeight,
                               selectedWidth, selectedHeight );
    
  }
  
  //get current selection boundary
  QPoint curTopLeft, curBottomRight;
  selectionInterface->getSelection( curTopLeft, curBottomRight );
  
  //get current selection center
  QPoint curCenter;
  curCenter.setX( (curTopLeft.x() + curBottomRight.x()) / 2 );
  curCenter.setY( (curTopLeft.y() + curBottomRight.y()) / 2 );

  //if center is off image (no previous selection) then
  //fix center to center of image
  if( curCenter.x() < 0 || curCenter.y() < 0 )
  {
    curCenter.setX( imageWidth/2 );
    curCenter.setY( imageHeight/2 );
  }
  
  //attempt to center new selection overold selection, only
  //offset if necessary
  QPoint newTopLeft, newBottomRight;

  newTopLeft.setX( curCenter.x() - selectedWidth/2 );
  newTopLeft.setY( curCenter.y() - selectedHeight/2 );

  //push right/down if necessary
  if( newTopLeft.x() < 0 ) newTopLeft.setX( 0 );
  if( newTopLeft.y() < 0 ) newTopLeft.setY( 0 );
  
  //push left/up if necessary
  newBottomRight.setX( newTopLeft.x() + selectedWidth - 1 );
  if( newBottomRight.x() >= imageWidth )
  {
    newBottomRight.setX( imageWidth-1 );
    newTopLeft.setX( newBottomRight.x() - selectedWidth + 1 );
  }
  
  newBottomRight.setY( newTopLeft.y() + selectedHeight - 1 );
  if( newBottomRight.y() >= imageHeight )
  {
    newBottomRight.setY( imageHeight-1 );
    newTopLeft.setY( newBottomRight.y() - selectedHeight + 1 );
  }

  //select region
  selectionInterface->setSelection(newTopLeft, newBottomRight,
                                   maxDimensions[aspectRatios->currentItem()] );    
} 
void EditingInterface::selectEffect ( ) [private, slot]

Effect seletion changed.

Definition at line 774 of file editingInterface.cpp.

References applyEffect(), editedImage, effectPreview, and effectPreviewImageFilename.

Referenced by applyImageUpdate(), EditingInterface(), revertCurrentPhoto(), rotateFlip(), setPhoto(), and showNextPrevFirstLastPhoto().

{  
  //apply effect on preview image
  QImage* editedImage = applyEffect( effectPreviewImageFilename );
  
  //bail if generated preview image failed
  if( editedImage == NULL ) return;
  
  //refresh displayed preview image
  effectPreview->setPixmap( QPixmap(*editedImage) );
  delete editedImage;
  editedImage = NULL;  
}
void EditingInterface::setFocus ( ) [slot]

Definition at line 1046 of file editingInterface.cpp.

References selectionInterface.

Referenced by LayoutWidget::tabChanged().

{
  //always pass off focus even to selection interface so it can get key strokes
  selectionInterface->setFocus();
}
void EditingInterface::setPhoto ( Subalbum collection,
Photo photo 
)

Sets the photo pointer and constructs scaled qimage's for painting.

Definition at line 432 of file editingInterface.cpp.

References aspectRatios, collection, cropButton, displayHeight, displayWidth, EFFECT_PREVIEW_HEIGHT, EFFECT_PREVIEW_WIDTH, effectPreviewImageFilename, effectsList, SelectionInterface::getDisplaySize(), Photo::getImageFilename(), getImageSize(), Photo::getNext(), Photo::getPrev(), imageHeight, imageWidth, nextButton, photo, previousButton, redEyeReductionButton, scaleImage(), selectEffect(), selectionInterface, selectionRotated, ClickableLabel::setEnabled(), ClickableLabel::setInvisible(), and SelectionInterface::setPhoto().

Referenced by LayoutWidget::tabChanged().

{
  //store photo and collection object handles
  this->collection = collection;
  this->photo = photo;

  //update visibility of prev and next buttons
  previousButton->setInvisible( photo->getPrev() == NULL );
  nextButton->setInvisible( photo->getNext() == NULL );
  
  //reset combo menu's back to first entries
  aspectRatios->setCurrentItem(0);
  effectsList->setCurrentItem(0);

  //reset selectionRotated bool to false
  selectionRotated = false;
  
  //update view of photo
  selectionInterface->setPhoto( photo->getImageFilename() );  
 
  //created effect preview image  
  effectPreviewImageFilename = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() + 
                               "/effectPreviewImage.jpg";
  scaleImage( photo->getImageFilename(), effectPreviewImageFilename, EFFECT_PREVIEW_WIDTH, EFFECT_PREVIEW_HEIGHT );
  selectEffect();
  
  //get full size photo dimensions
  getImageSize( photo->getImageFilename(), imageWidth, imageHeight );
  
  //get display size photo dimensions
  selectionInterface->getDisplaySize( displayWidth, displayHeight );

  //disable the crop and reset buttons
  cropButton->setEnabled( false );
  redEyeReductionButton->setEnabled( false );  
}
void EditingInterface::showFirstPhoto ( ) [private, slot]

Show first photo.

Definition at line 487 of file editingInterface.cpp.

References collection, Subalbum::getFirst(), photo, and showNextPrevFirstLastPhoto().

Referenced by keyPressEvent().

{ 
  Photo* firstPhoto = collection->getFirst();

  if(firstPhoto != photo)
  { showNextPrevFirstLastPhoto( firstPhoto ); }
}
void EditingInterface::showLastPhoto ( ) [private, slot]

Show last photo.

Definition at line 495 of file editingInterface.cpp.

References collection, Subalbum::getLast(), photo, and showNextPrevFirstLastPhoto().

Referenced by keyPressEvent().

{ 
  Photo* lastPhoto = collection->getLast();
  
  if(lastPhoto != photo)
  { showNextPrevFirstLastPhoto( lastPhoto ); }
}
void EditingInterface::showNextPhoto ( ) [private, slot]

Show next photo.

Definition at line 478 of file editingInterface.cpp.

References Photo::getNext(), photo, and showNextPrevFirstLastPhoto().

Referenced by EditingInterface(), and keyPressEvent().

{ 
  Photo* nextPhoto = photo->getNext();

  if( nextPhoto != NULL &&
      nextPhoto != photo )
  { showNextPrevFirstLastPhoto( nextPhoto ); }
}  
void EditingInterface::showNextPrevFirstLastPhoto ( Photo newPhoto) [private]

Utility method for show prev/next photos.

Definition at line 503 of file editingInterface.cpp.

References aspectRatios, displayHeight, displayWidth, EFFECT_PREVIEW_HEIGHT, EFFECT_PREVIEW_WIDTH, effectPreviewImageFilename, SelectionInterface::getDisplaySize(), Photo::getImageFilename(), getImageSize(), Photo::getNext(), Photo::getPrev(), imageHeight, imageWidth, nextButton, photo, photoModified(), previousButton, scaleImage(), selectAspectRatio(), selectEffect(), selectionInterface, selectionRotated, ClickableLabel::setInvisible(), SelectionInterface::setPhoto(), and SelectionInterface::setSelection().

Referenced by showFirstPhoto(), showLastPhoto(), showNextPhoto(), and showPrevPhoto().

{  
  //set busy pointer
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  qApp->processEvents();

  //reset photo object handle
  photo = newPhoto;

  //reset selectionRotated bool to false
  selectionRotated = false;
  
  //update visibility of prev and next buttons
  previousButton->setInvisible( photo->getPrev() == NULL );
  nextButton->setInvisible( photo->getNext() == NULL );
    
  //update view of photo
  selectionInterface->setPhoto( photo->getImageFilename() );  

  //created effect preview image  
  effectPreviewImageFilename = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +     "/effectPreviewImage.jpg";
  scaleImage( photo->getImageFilename(), effectPreviewImageFilename, EFFECT_PREVIEW_WIDTH, EFFECT_PREVIEW_HEIGHT );
  selectEffect();

  //get full size photo dimensions
  getImageSize( photo->getImageFilename(), imageWidth, imageHeight );

  //get display size photo dimensions
  selectionInterface->getDisplaySize( displayWidth, displayHeight );

  //auto select region if custom not selected, else select nothing
  if(aspectRatios->currentItem() != 0)
  { selectAspectRatio(); }
  else  
  { selectionInterface->setSelection( QPoint(-1,-1), QPoint(-1, -1) ); }
  
  //emit signal that photo state possibly has changed
  emit photoModified();
  
  //remove busy cursor
  qApp->restoreOverrideCursor();
  qApp->processEvents();
}
void EditingInterface::showPrevPhoto ( ) [private, slot]

Show prev photo.

Definition at line 469 of file editingInterface.cpp.

References Photo::getPrev(), photo, and showNextPrevFirstLastPhoto().

Referenced by EditingInterface(), and keyPressEvent().

{ 
  Photo* prevPhoto = photo->getPrev();

  if( prevPhoto != NULL && 
      prevPhoto != photo )
  { showNextPrevFirstLastPhoto( prevPhoto ); }
}
void EditingInterface::startCorrectTilt ( ) [private, slot]

Enter correct image tilt mode.

Definition at line 1207 of file editingInterface.cpp.

References correctTiltButton, SelectionInterface::enterDrawLineMode(), and selectionInterface.

Referenced by EditingInterface().

{
  //instruct user to select a horizontal or vertical line in the image by
  //beginning draw line mode in the selection interface
  correctTiltButton->setEnabled( false );
  selectionInterface->enterDrawLineMode();
}
void EditingInterface::tuneLevels ( ) [private, slot]

Opens levels editor for manual histogram and brightness/contrast adjustments.

Definition at line 722 of file editingInterface.cpp.

References applyImageUpdate(), Photo::getImageFilename(), Window::getStatus(), LayoutWidget::getWindow(), StatusWidget::grabInput(), layout, photo, and StatusWidget::releaseInput().

Referenced by EditingInterface().

{
  //load photo in histogram editor
  //if changes took place update image
  HistogramEditor editor( photo->getImageFilename(), this);
  if( editor.exec() ) 
  { 
    //set busy cursor
    qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
    qApp->processEvents();

    //disable user input
    layout->getWindow()->getStatus()->grabInput();

    //update image    
    applyImageUpdate( editor.getModifiedImage(), false ); 

    //enable user input
    layout->getWindow()->getStatus()->releaseInput();

    //remove busy cursor
    qApp->restoreOverrideCursor();
    qApp->processEvents();
  }
}

Member Data Documentation

QPushButton* EditingInterface::applyEffectButton [private]

The apply effect button is disabled when no effect has been chosen.

Definition at line 208 of file editingInterface.h.

Referenced by applyEffect(), and EditingInterface().

QComboBox* EditingInterface::aspectRatios [private]

array of common aspect ratios to crop to

Definition at line 189 of file editingInterface.h.

Referenced by EditingInterface(), screenResolutionChanged(), and selectAspectRatio().

========== Pointer to backend collection

Definition at line 214 of file editingInterface.h.

Referenced by setPhoto(), showFirstPhoto(), and showLastPhoto().

QToolButton* EditingInterface::correctTiltButton [private]

The start tilt button is disabled while a line is being selected.

Definition at line 196 of file editingInterface.h.

Referenced by EditingInterface(), finishCorrectTilt(), and startCorrectTilt().

QToolButton* EditingInterface::cropButton [private]

The crop buttons is disabled when no seletion is present.

Definition at line 199 of file editingInterface.h.

Referenced by EditingInterface(), handleSelectionChanged(), and setPhoto().

Index for screen resolution, needed if this value pair changes during program executing.

Definition at line 186 of file editingInterface.h.

Referenced by EditingInterface(), screenResolutionChanged(), and selectAspectRatio().

Dimension of photo in display coordinates.

Definition at line 226 of file editingInterface.h.

Referenced by applyImageUpdate(), revertCurrentPhoto(), rotateFlip(), setPhoto(), and showNextPrevFirstLastPhoto().

Label that shows preview of effect.

Definition at line 211 of file editingInterface.h.

Referenced by EditingInterface(), and selectEffect().

Path to scaled down version of image for fast generation of previews of effects.

Definition at line 220 of file editingInterface.h.

Referenced by applyImageUpdate(), revertCurrentPhoto(), rotateFlip(), selectEffect(), setPhoto(), and showNextPrevFirstLastPhoto().

QComboBox* EditingInterface::effectsList [private]

List of effects that can be applied to photos.

Definition at line 205 of file editingInterface.h.

Referenced by applyEffect(), EditingInterface(), and setPhoto().

Dimension of photo in image coordinates.

Definition at line 229 of file editingInterface.h.

Referenced by applyImageUpdate(), revertCurrentPhoto(), rotateFlip(), rotateSelection(), selectAll(), selectAspectRatio(), setPhoto(), and showNextPrevFirstLastPhoto().

Definition at line 190 of file editingInterface.h.

Referenced by EditingInterface(), and selectAspectRatio().

Definition at line 173 of file editingInterface.h.

Referenced by EditingInterface(), setPhoto(), and showNextPrevFirstLastPhoto().

QComboBox* EditingInterface::orientations [private]

Definition at line 183 of file editingInterface.h.

------------ Buttons for changing the shown image

Definition at line 173 of file editingInterface.h.

Referenced by EditingInterface(), setPhoto(), and showNextPrevFirstLastPhoto().

The red eye reduction button is disabled when no selection is present.

Definition at line 202 of file editingInterface.h.

Referenced by EditingInterface(), handleSelectionChanged(), and setPhoto().

This widget scales and displays the photo to fit the available screen space, and provides extensive support for selecting regions of the photo for editing/cropping.

Definition at line 177 of file editingInterface.h.

Referenced by applyImageUpdate(), EditingInterface(), findSelection(), revertCurrentPhoto(), rotateFlip(), rotateSelection(), selectAspectRatio(), setFocus(), setPhoto(), showNextPrevFirstLastPhoto(), and startCorrectTilt().

state variable indicating if the user wants to use a rotate aspect ratio

Definition at line 193 of file editingInterface.h.

Referenced by applyImageUpdate(), rotateFlip(), rotateSelection(), selectAspectRatio(), setPhoto(), and showNextPrevFirstLastPhoto().


The documentation for this class was generated from the following files: