AlbumShaper
1.0a3
|
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 //==============================================