photoDescEdit.cpp

Go to the documentation of this file.
00001 //==============================================
00002 //  copyright            : (C) 2003-2005 by Will Stokes
00003 //==============================================
00004 //  This program is free software; you can redistribute it
00005 //  and/or modify it under the terms of the GNU General
00006 //  Public License as published by the Free Software
00007 //  Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //==============================================
00010 
00011 //Systemwide includes
00012 #include <qlayout.h>
00013 #include <qlabel.h>
00014 #include <qimage.h>
00015 #include <qpixmap.h>
00016 #include <qtimer.h>
00017 #include <qapplication.h>
00018 #include <qpainter.h>
00019 #include <qtextedit.h>
00020 #include <qcursor.h>
00021 
00022 //Projectwide includes
00023 #include "photoDescEdit.h"
00024 #include "photoPreviewWidget.h"
00025 #include "photosIconView.h"
00026 #include "clickableLabel.h"
00027 #include "../config.h"
00028 #include "../backend/photo.h"
00029 #include "../backend/tools/imageTools.h"
00030 
00031 #define EDIT_MARGIN 4
00032 
00033 //PLATFORM_SPECIFIC_CODE
00034 #if defined(Q_OS_MACX)
00035 #include "/Developer/Headers/FlatCarbon/MacWindows.h"
00036 #endif
00037 
00038 //PLATFORM_SPECIFIC_CODE
00039 #if defined(Q_OS_WIN)
00040 #include <windows.h>
00041 #include <winuser.h>
00042 #define SPI_GETDROPSHADOW 0x1024
00043 #define SPI_SETDROPSHADOW 0x1025
00044 #endif
00045 
00046 //==============================================
00047 PhotoDescEdit::PhotoDescEdit( PhotoPreviewWidget* ppw, bool useAnimation,
00048                               QWidget* parent, const char* name ) :
00049                               QWidget(parent,name, 
00050                               Qt::WStyle_Customize | 
00051 #if defined(Q_OS_MACX)
00052                               Qt::WStyle_Splash )
00053 #else 
00054                               Qt::WStyle_NoBorder | Qt::WType_Popup )
00055 #endif
00056 {
00057   //PLATFORM_SPECIFIC_CODE
00058   //disable drop shadow on mac os x
00059   #if defined(Q_OS_MACX)
00060   ChangeWindowAttributes( (OpaqueWindowPtr*)winId(), kWindowNoShadowAttribute, kWindowNoAttributes );
00061   #endif
00062 
00063   //PLATFORM_SPECIFIC_CODE
00064   //disable drop shadow on win xp
00065   #if defined(Q_OS_WIN)
00066   SystemParametersInfo( SPI_GETDROPSHADOW, 0, &dropShadowsEnabled, 0 );
00067   SystemParametersInfo( SPI_SETDROPSHADOW, 0, NULL, 0 );
00068   #endif
00069 
00070   this->ppw = ppw;
00071   //-----------------------------------------------
00072   //don't erase before painting, avoids flicker
00073   setWFlags(WNoAutoErase);
00074   //-----------------------------------------------
00075   //determine small image size
00076   getImageSize( ppw->getPhoto()->getThumbnailFilename(), smallWidth, smallHeight );
00077   //-------------------------------------------
00078   QRect appRec = qApp->mainWidget()->frameGeometry();
00079   int finalWidth, finalHeight;
00080   int actualFinalWidth, actualFinalHeight;
00081   
00082   //image is wider than tall, place text and buttons below image
00083   if(smallWidth > smallHeight )
00084   {
00085     finalWidth = 400;
00086     finalHeight = (finalWidth * smallHeight) / smallWidth;
00087 
00088     //fix width
00089     if(finalWidth +2*EDIT_MARGIN> appRec.width())
00090     {
00091       finalWidth = appRec.width() - 2*EDIT_MARGIN;
00092       finalHeight = (finalWidth * smallHeight) / smallWidth;
00093     }
00094 
00095     //fix height
00096     QFontMetrics fm( qApp->font() );
00097     idealTextSize = 4*fm.height() + 5*fm.leading() + 4;
00098     
00099     if(finalHeight + idealTextSize + 2*EDIT_MARGIN > appRec.height() )
00100     {
00101       finalHeight = appRec.height() - idealTextSize - 2*EDIT_MARGIN;
00102       finalWidth = (finalHeight * smallWidth) / smallHeight;
00103     }
00104 
00105     //sanity check
00106     if(finalHeight < 0)
00107     {
00108       finalHeight = (appRec.height() - 2*EDIT_MARGIN) / 2;
00109       finalWidth = (finalHeight * smallWidth) / smallHeight;
00110       idealTextSize = finalHeight;
00111     }
00112 
00113     actualFinalWidth = finalWidth + 2*EDIT_MARGIN;
00114     actualFinalHeight = finalHeight + idealTextSize + 2*EDIT_MARGIN;
00115     
00116     //an additional fudge is necessary for MacOSX, not sure why
00117 #if defined(Q_OS_MACX)
00118     actualFinalHeight+=2;
00119 #endif
00120   }
00121   //image is taller than wide, text and buttons will be placed to the right
00122   else
00123   {
00124     finalHeight = 300;
00125     finalWidth = (finalHeight * smallWidth) / smallHeight;
00126 
00127     //fix height
00128     if(finalHeight + 2*EDIT_MARGIN > appRec.height())
00129     {
00130       finalHeight = appRec.height() - 2*EDIT_MARGIN;
00131       finalWidth = (finalHeight * smallWidth) / smallHeight;
00132     }
00133 
00134     //fix width
00135     QString calibrationString( qApp->translate("PhotoDescEdit", "This is the photo description calibration string.") );
00136     QFontMetrics fm( qApp->font() );
00137     idealTextSize = fm.width( calibrationString );
00138     if(finalWidth + idealTextSize + 2*EDIT_MARGIN > appRec.width() )
00139     {
00140       finalWidth = appRec.width() - idealTextSize - 2*EDIT_MARGIN;
00141       finalHeight = (finalWidth * smallHeight) / smallWidth;
00142     }
00143 
00144     //sanity check
00145     if(finalWidth < 0)
00146     {
00147       finalWidth = (appRec.width() - 2*EDIT_MARGIN) / 2;
00148       finalHeight = (finalWidth * smallHeight) / smallWidth;
00149     idealTextSize = finalWidth;
00150     }
00151 
00152     actualFinalWidth = finalWidth + idealTextSize + 2*EDIT_MARGIN;
00153     actualFinalHeight = finalHeight + 2*EDIT_MARGIN;
00154   }
00155   //-----------------------------------------------
00156   //setup scaled up image
00157   //find full size photo dimensions, if unable to then use scaled up thumbnail image
00158   int fullWidth, fullHeight;
00159   if(!getImageSize( ppw->getPhoto()->getImageFilename(), fullWidth, fullHeight ) )
00160   {
00161     imageLarge = new QImage( QImage( ppw->getPhoto()->getThumbnailFilename()).
00162                              scale(finalWidth,finalHeight, QImage::ScaleFree ));
00163   }
00164   //else find cropped region of slideshow image using these dimensions
00165   else
00166   {
00167     //load padded slideshow image
00168     QImage paddedSSImage( ppw->getPhoto()->getSlideshowFilename() );
00169 
00170     //unpadded dimensions
00171     int actualWidth, actualHeight;
00172     calcScaledImageDimensions( fullWidth, fullHeight, 
00173                                paddedSSImage.width(), paddedSSImage.height(), 
00174                                actualWidth, actualHeight );
00175 
00176     //construct new image with padding removed
00177     int leftOffset = (paddedSSImage.width() - actualWidth) / 2;
00178     int topOffset = (paddedSSImage.height() - actualHeight) / 2;
00179     QImage SSImage( actualWidth, actualHeight, paddedSSImage.depth() );
00180       
00181     int x,  y;
00182     for(x=0; x<actualWidth; x++)
00183     {
00184       for(y=0; y<actualHeight; y++)
00185       {
00186         SSImage.setPixel( x, y, red.rgb() );
00187         SSImage.setPixel( x, y, paddedSSImage.pixel(x+leftOffset, y+topOffset) );
00188       }
00189     }
00190     imageLarge = new QImage(SSImage.smoothScale(finalWidth,finalHeight, QImage::ScaleFree ));
00191   }
00192   //-----------------------------------------------
00193   //construct final text area pixmap used for morphing text region
00194   TextEdit tmpTextEdit;
00195   tmpTextEdit.setText( ppw->getPhoto()->getDescription() );
00196 
00197   if(smallWidth > smallHeight )
00198     tmpTextEdit.resize( finalWidth, idealTextSize );
00199   else
00200     tmpTextEdit.resize( idealTextSize, finalHeight );
00201 
00202   tmpTextEdit.setLineWidth( 0 );
00203   tmpTextEdit.setMargin( 0 );
00204   tmpTextEdit.setMidLineWidth( 0 );
00205   tmpTextEdit.setFrameStyle( QFrame::NoFrame | QFrame::Plain );
00206   
00207   tmpTextEdit.setWrapPolicy( QTextEdit::AtWordOrDocumentBoundary );
00208   tmpTextEdit.constPolish();
00209   tmpTextEdit.polish();
00210 
00211   tmpTextEdit.setWordWrap( QTextEdit::FixedPixelWidth );
00212   if(smallWidth > smallHeight )
00213     tmpTextEdit.setWrapColumnOrWidth( finalWidth );
00214   else
00215     tmpTextEdit.setWrapColumnOrWidth( idealTextSize );
00216   tmpTextEdit.updateScrollBars();
00217   tmpTextEdit.constPolish();
00218   tmpTextEdit.polish();
00219 
00220   if(smallWidth > smallHeight )
00221   {
00222     if(tmpTextEdit.lines() > 4)
00223     {
00224       tmpTextEdit.setWrapColumnOrWidth( finalWidth - tmpTextEdit.verticalScrollBar()->width() );
00225       tmpTextEdit.updateScrollBars();
00226       tmpTextEdit.constPolish();
00227       tmpTextEdit.polish();
00228     }
00229   }
00230   else
00231   {
00232     QFontMetrics fm( qApp->font() );
00233     if(tmpTextEdit.lines() > idealTextSize / (fm.leading() + fm.height()) )
00234     {
00235       tmpTextEdit.setWrapColumnOrWidth( idealTextSize - tmpTextEdit.verticalScrollBar()->width() );
00236       tmpTextEdit.updateScrollBars();
00237       tmpTextEdit.constPolish();
00238       tmpTextEdit.polish();
00239     }
00240   }
00241 
00242   //paint to pixmap
00243   tmpTextEdit.paintNow();
00244   textRectangle = new QImage( QPixmap::grabWidget(&tmpTextEdit).convertToImage() );
00245   //-----------------------------------------------
00246   //set beginning and end positions
00247   initPos = ppw->getPhotoPos();
00248 
00249   //offset by margin
00250   initPos += QPoint( -EDIT_MARGIN, -EDIT_MARGIN );
00251 
00252   int initCenterX = initPos.x() + smallWidth/2;
00253   int initCenterY = initPos.y() + smallHeight/2;
00254 
00255   finalPos = QPoint( initCenterX - actualFinalWidth/2, initCenterY - actualFinalHeight/2 );
00256   if(finalPos.x() < appRec.x() )
00257     finalPos.setX( appRec.x() );
00258   if(finalPos.x() + actualFinalWidth > appRec.x() + appRec.width() )
00259     finalPos.setX( appRec.x() + appRec.width()- actualFinalWidth );
00260 
00261   if(finalPos.y() < appRec.y() )
00262     finalPos.setY( appRec.y() );
00263   if(finalPos.y() + actualFinalHeight > appRec.y() + appRec.height() )
00264     finalPos.setY( appRec.y() + appRec.height()- actualFinalHeight );
00265   //-----------------------------------------------
00266   //find bounding rectangle
00267   left   = QMIN( finalPos.x(), initPos.x() );
00268   top    = QMIN( finalPos.y(), initPos.y() );
00269   right  = QMAX( finalPos.x() + actualFinalWidth, initPos.x() + smallWidth );
00270   bottom = QMAX( finalPos.y() + actualFinalHeight, initPos.y() + smallHeight );
00271   //-----------------------------------------------
00272   //grab window in region of interest, setup label and use this image
00273   backgroundImage = new QPixmap( QPixmap::grabWindow(QApplication::desktop()->winId(),
00274                                                      left, top, 
00275                                                      right-left, bottom-top) );
00276   setBackgroundMode( Qt::NoBackground );
00277   //-----------------------------------------------
00278   //Setup animation widgets and place in main grid
00279   animationLabel = new QLabel(this, "animationLabel", WNoAutoErase);
00280   animationLabel->setPixmap( *backgroundImage );
00281   animationLabel->setBackgroundMode( Qt::NoBackground );
00282   buffer = new QPixmap(  backgroundImage->width(), backgroundImage->height() );
00283 
00284   mainGrid = new QGridLayout( this, 1, 2, 0 );
00285   mainGrid->addWidget(animationLabel, 0, 0 );
00286   //-----------------------------------------------
00287   //Setup static widgets
00288   staticFrame = new QWidget(this);
00289   staticFrame->hide();
00290   staticFrame->setBackgroundMode( Qt::NoBackground );
00291   mainGrid->addWidget(staticFrame, 0, 1 );
00292 
00293   staticPhoto = new QLabel( staticFrame, "staticPhoto", WNoAutoErase);
00294   staticPhoto->setPixmap( QPixmap( *imageLarge) );
00295   staticPhoto->setBackgroundMode( Qt::NoBackground );
00296 
00297   photoDesc = new TextEdit( staticFrame );
00298   photoDesc->setText( ppw->getPhoto()->getDescription() );
00299 
00300   photoDesc->setWrapPolicy( QTextEdit::AtWordOrDocumentBoundary );
00301   photoDesc->setFrameStyle( QFrame::NoFrame );
00302   photoDesc->setLineWidth( 0 );
00303   photoDesc->setMargin( 0 );
00304   photoDesc->setMidLineWidth( 0 );
00305   photoDesc->setFrameStyle( QFrame::MenuBarPanel | QFrame::Plain );
00306 
00307   //start disappearing once the text edit reports the user is finished
00308   connect( photoDesc, SIGNAL( finished() ),
00309            this, SLOT( disappear() ) );
00310   
00311   QWidget* bw1 = new QWidget(staticFrame);
00312   QWidget* bw2 = new QWidget(staticFrame);
00313   QWidget* bw3 = new QWidget(staticFrame);
00314   QWidget* bw4 = new QWidget(staticFrame);
00315   QColor darkBlue(35, 75, 139);
00316   bw1->setPaletteBackgroundColor( darkBlue );
00317   bw2->setPaletteBackgroundColor( darkBlue );
00318   bw3->setPaletteBackgroundColor( darkBlue );
00319   bw4->setPaletteBackgroundColor( darkBlue );
00320 
00321   //image is wider than tall, place text and buttons below image
00322   if(smallWidth > smallHeight )
00323   {
00324     staticGrid = new QGridLayout( staticFrame, 4, 3);
00325 
00326     staticGrid->addWidget( staticPhoto, 1, 1 );
00327     staticGrid->addWidget( photoDesc, 2, 1 );
00328 
00329     staticGrid->setColSpacing( 2, staticPhoto->width() );
00330     staticGrid->setRowSpacing( 2, idealTextSize );
00331 
00332     staticGrid->addMultiCellWidget( bw1, 0, 0, 0, 2 );
00333     staticGrid->addMultiCellWidget( bw2, 1, 2, 0, 0 );
00334     staticGrid->addMultiCellWidget( bw3, 1, 2, 2, 2 );
00335     staticGrid->addMultiCellWidget( bw4, 3, 3, 0, 2 );
00336     staticGrid->setRowSpacing( 0, EDIT_MARGIN );
00337     staticGrid->setRowSpacing( 3, EDIT_MARGIN );
00338     staticGrid->setColSpacing( 0, EDIT_MARGIN );
00339     staticGrid->setColSpacing( 2, EDIT_MARGIN );
00340   }
00341   else
00342   {
00343     staticGrid = new QGridLayout( staticFrame, 3, 4);
00344 
00345     staticGrid->addWidget( staticPhoto, 1, 1 );
00346     staticGrid->addWidget( photoDesc, 1, 2 );
00347 
00348     staticGrid->setRowSpacing( 1, staticPhoto->height() );
00349     staticGrid->setColSpacing( 2, idealTextSize );
00350 
00351     staticGrid->addMultiCellWidget( bw1, 0, 0, 0, 3 );
00352     staticGrid->addWidget( bw2, 1, 0 );
00353     staticGrid->addWidget( bw3, 1, 3 );
00354     staticGrid->addMultiCellWidget( bw4, 2, 2, 0, 3 );
00355     staticGrid->setRowSpacing( 0, EDIT_MARGIN );
00356     staticGrid->setRowSpacing( 2, EDIT_MARGIN );
00357     staticGrid->setColSpacing( 0, EDIT_MARGIN );
00358     staticGrid->setColSpacing( 3, EDIT_MARGIN );
00359   }
00360   //-----------------------------------------------
00361   //set delay defaults
00362   initDelay = 130;
00363   accel = 50;
00364   minDelay = 1;
00365 
00366   this->useAnimation = useAnimation;
00367   if(useAnimation)
00368     step = 0;
00369   else
00370     step = 100;
00371 
00372   mode = STATIC;
00373 
00374   //create timer object and setup signals
00375   timer = new QTimer();
00376   connect(timer, SIGNAL(timeout()), this, SLOT(animate()) );
00377   //---------------------------
00378   //place widget in intial position
00379   move( left, top );
00380   show();
00381 
00382   //start appearing process
00383   mode = APPEARING;
00384   delay = initDelay;
00385   lastTime.start();
00386   animate();
00387 }
00388 //==============================================
00389 PhotoDescEdit::~PhotoDescEdit()
00390 {
00391   delete textRectangle;
00392   delete timer;
00393   delete buffer;
00394   delete backgroundImage;
00395   delete imageLarge;
00396 }
00397 //==============================================
00398 void PhotoDescEdit::animate()
00399 {
00400   //---------------------------------
00401   //determine # of ms that have passed since last redraw
00402   currentTime.start();
00403   double ms = lastTime.msecsTo(currentTime);
00404 
00405   //determine increment
00406   int inc = (int)(ms/(delay+1));
00407 
00408   //if increment is not zero then update last time
00409   if(inc != 0)
00410   {
00411     lastTime = currentTime;
00412 
00413     //update step
00414     step = step + inc;
00415     if(step > 100)
00416       step = 100;
00417 
00418     //update position and size
00419     double alpha = ((double)step) / 100.0;
00420     int newX, newY;
00421     int imageW, imageH;
00422     int textDim;
00423     QColor darkBlue(35, 75, 139);
00424     if(mode == APPEARING)
00425     {
00426       newX = (int)((1-alpha)*initPos.x() + alpha*finalPos.x());
00427       newY = (int)((1-alpha)*initPos.y() + alpha*finalPos.y());
00428       imageW = (int)((1-alpha)*smallWidth + alpha*imageLarge->width());
00429       imageH = (int)((1-alpha)*smallHeight + alpha*imageLarge->height());
00430       textDim = (int) (alpha * idealTextSize);
00431     }
00432     else
00433     {
00434       newX = (int)(alpha*initPos.x() + (1-alpha)*finalPos.x());
00435       newY = (int)(alpha*initPos.y() + (1-alpha)*finalPos.y());
00436       imageW = (int)(alpha*smallWidth + (1-alpha)*imageLarge->width());
00437       imageH = (int)(alpha*smallHeight + (1-alpha)*imageLarge->height());
00438       textDim = (int) ((1-alpha) * idealTextSize);
00439     }
00440 
00441     //draw background image to buffer
00442     QPainter bufferPainter( buffer );
00443     bufferPainter.drawPixmap(0,0, *backgroundImage );
00444 
00445     //draw selection and white text rectangles
00446     if(smallWidth > smallHeight )
00447     {
00448       bufferPainter.fillRect( newX - left, 
00449                               newY - top,
00450                               imageW + 2*EDIT_MARGIN,
00451                               imageH + 2*EDIT_MARGIN + textDim,
00452                               darkBlue );
00453 
00454       bufferPainter.drawPixmap( newX - left + EDIT_MARGIN,
00455                                 newY - top + EDIT_MARGIN + imageH,
00456                                 QPixmap( textRectangle->scale( imageW, textDim ) ) );
00457     }
00458     else
00459     {
00460       bufferPainter.fillRect( newX - left, newY - top,
00461                               imageW + 2*EDIT_MARGIN + textDim,
00462                               imageH + 2*EDIT_MARGIN,
00463                               darkBlue );
00464 
00465       bufferPainter.drawPixmap( newX - left + EDIT_MARGIN + imageW,
00466                                 newY - top + EDIT_MARGIN,
00467                                 QPixmap( textRectangle->scale( textDim, imageH ) ) );
00468     }
00469 
00470     //draw scaled moved image to buffer
00471     bufferPainter.drawPixmap( newX - left + EDIT_MARGIN,
00472                               newY - top + EDIT_MARGIN,
00473                               QPixmap( imageLarge->scale( imageW, imageH ) ) );
00474 
00475     //set label to use buffer pixmap
00476     animationLabel->setPixmap( *buffer );
00477   }
00478 
00479   //not done restart timer
00480   if(step < 100)
00481   {
00482     //update speed
00483     delay = delay - accel;
00484     if(delay < minDelay) delay = minDelay;
00485 
00486     //restart timer
00487     timer->start( delay, TRUE );
00488   }
00489   else
00490   {
00491     if(mode == APPEARING)
00492     {
00493       animationLabel->hide();
00494       staticFrame->show();
00495 
00496       //auto focus text area, put cursor at very end
00497       photoDesc->setFocus();
00498 
00499       mode = STATIC;
00500     }
00501     else
00502     {
00503       //reenable drop shadows on windows xp if they were previously enabled
00504       #if defined(Q_OS_WIN)
00505       if(dropShadowsEnabled)
00506         SystemParametersInfo( SPI_SETDROPSHADOW, 0, &dropShadowsEnabled, 0 );
00507       else
00508         SystemParametersInfo( SPI_SETDROPSHADOW, 0, NULL, 0 );
00509       #endif //Q_OS_WIN
00510 
00511       mode = DISAPPEARED;
00512       hide();
00513       qApp->mainWidget()->repaint(false);
00514     }
00515   }
00516 }
00517 //==============================================
00518 void PhotoDescEdit::disappear()
00519 {
00520   delete textRectangle;
00521   textRectangle = new QImage( QPixmap::grabWidget(photoDesc).convertToImage() );
00522 
00523   ppw->getPhoto()->setDescription( photoDesc->text() );
00524   ppw->setText( photoDesc->text() );
00525 
00526   //start disappearing process
00527   staticFrame->hide();
00528   animationLabel->show();
00529 
00530   initDelay = 130;
00531   accel = 50;
00532   minDelay = 1;
00533 
00534   if(useAnimation)
00535     step = 0;
00536   else
00537     step = 100;
00538 
00539   mode = DISAPPEARING;
00540   lastTime.start();
00541   animate();
00542 }
00543 //==============================================
00544 void PhotoDescEdit::hide()
00545 {
00546   if(mode == DISAPPEARED )
00547   {
00548     QWidget::hide();
00549 
00550     //check to see if mouse is over a new item, 
00551     //if so immediately set it as being moused over
00552     QIconView* iconView = ppw->iconView();
00553     QIconViewItem* item = iconView->findItem( iconView->viewport()->mapFromGlobal( QCursor::pos() )+=QPoint( iconView->contentsX(), iconView->contentsY() )  );
00554     if(item != NULL && item != ppw )
00555     {
00556       ((PhotosIconView*)item->iconView())->repaintGroup( item );
00557     }
00558   }
00559   else if(mode == STATIC)
00560   {
00561     disappear();
00562   }
00563 }
00564 //==============================================
00565 TextEdit::TextEdit( QWidget* parent, const char* name ) : QTextEdit(parent,name) 
00566 { 
00567   setHScrollBarMode( QScrollView::AlwaysOff );
00568   setTextFormat( Qt::PlainText );
00569   contextMenu = NULL;
00570 }
00571 //==============================================
00572 void TextEdit::paintNow()
00573 {
00574   constPolish();
00575   repaint( rect(), false );
00576 }
00577 //==============================================
00578 void TextEdit::keyPressEvent ( QKeyEvent * e )
00579 {
00580   //finish when user hits escape
00581   if( e->key() == Qt::Key_Escape )
00582   {
00583     emit finished();
00584   }
00585   //if Ctrl+A then select all text, otherwise, apply base class key press rules
00586   else if( (e->state() & Qt::ControlButton) && e->key() == Qt::Key_A )
00587   {
00588     selectAll();
00589   }
00590   else
00591   {
00592     QTextEdit::keyPressEvent( e );
00593   }
00594 }
00595 //==============================================
00596 void TextEdit::focusOutEvent ( QFocusEvent * )
00597 {
00598   //if user right clicked on text field a context menu is popping up so ignore focusOut.
00599   //otherwise user has clicked off photo description so close
00600   if( contextMenu == NULL ) emit finished();
00601 }
00602 //==============================================
00603 QPopupMenu* TextEdit::createPopupMenu ( const QPoint& pos )
00604 {
00605   //when context menu's are created store their handle
00606   contextMenu = QTextEdit::createPopupMenu( pos );
00607   connect( ((QObject*)contextMenu), SIGNAL(aboutToHide()),
00608            this, SLOT(contextMenuHiding()) );
00609   return contextMenu;
00610 }
00611 //==============================================
00612 void TextEdit::contextMenuHiding()
00613 {
00614   //clear context menu handle since it's disappearing
00615   disconnect( ((QObject*)contextMenu), SIGNAL(aboutToHide()),
00616               this, SLOT(contextMenuHiding()) );
00617   contextMenu = NULL;
00618 }
00619 //==============================================

Generated on Thu Jan 3 10:54:40 2008 for AlbumShaper by  doxygen 1.5.4