00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
00034
#if defined(Q_OS_MACX)
00035
#include "/Developer/Headers/FlatCarbon/MacWindows.h"
00036
#endif
00037
00038
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
00058
00059
#if defined(Q_OS_MACX)
00060
ChangeWindowAttributes( (OpaqueWindowPtr*)winId(), kWindowNoShadowAttribute, kWindowNoAttributes );
00061
#endif
00062
00063
00064
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
00073 setWFlags(WNoAutoErase);
00074
00075
00076
getImageSize( ppw->getPhoto()->getThumbnailFilename(),
smallWidth,
smallHeight );
00077
00078 QRect appRec = qApp->mainWidget()->frameGeometry();
00079
int finalWidth, finalHeight;
00080
int actualFinalWidth, actualFinalHeight;
00081
00082
00083
if(
smallWidth >
smallHeight )
00084 {
00085 finalWidth = 400;
00086 finalHeight = (finalWidth *
smallHeight) /
smallWidth;
00087
00088
00089
if(finalWidth +2*
EDIT_MARGIN> appRec.width())
00090 {
00091 finalWidth = appRec.width() - 2*
EDIT_MARGIN;
00092 finalHeight = (finalWidth *
smallHeight) /
smallWidth;
00093 }
00094
00095
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
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
00117
#if defined(Q_OS_MACX)
00118
actualFinalHeight+=2;
00119
#endif
00120
}
00121
00122
else
00123 {
00124 finalHeight = 300;
00125 finalWidth = (finalHeight *
smallWidth) /
smallHeight;
00126
00127
00128
if(finalHeight + 2*
EDIT_MARGIN > appRec.height())
00129 {
00130 finalHeight = appRec.height() - 2*
EDIT_MARGIN;
00131 finalWidth = (finalHeight *
smallWidth) /
smallHeight;
00132 }
00133
00134
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
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
00157
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
00165
else
00166 {
00167
00168 QImage paddedSSImage( ppw->getPhoto()->getSlideshowFilename() );
00169
00170
00171
int actualWidth, actualHeight;
00172
calcScaledImageDimensions( fullWidth, fullHeight,
00173 paddedSSImage.width(), paddedSSImage.height(),
00174 actualWidth, actualHeight );
00175
00176
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
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
00243 tmpTextEdit.
paintNow();
00244
textRectangle =
new QImage( QPixmap::grabWidget(&tmpTextEdit).convertToImage() );
00245
00246
00247
initPos = ppw->getPhotoPos();
00248
00249
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
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
00273
backgroundImage =
new QPixmap( QPixmap::grabWindow(QApplication::desktop()->winId(),
00274
left,
top,
00275
right-
left,
bottom-
top) );
00276 setBackgroundMode( Qt::NoBackground );
00277
00278
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
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
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
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
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
00375
timer =
new QTimer();
00376 connect(
timer, SIGNAL(timeout()),
this, SLOT(
animate()) );
00377
00378
00379 move( left, top );
00380 show();
00381
00382
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
00402
currentTime.start();
00403
double ms =
lastTime.msecsTo(
currentTime);
00404
00405
00406
int inc = (
int)(ms/(
delay+1));
00407
00408
00409
if(inc != 0)
00410 {
00411
lastTime =
currentTime;
00412
00413
00414
step =
step + inc;
00415
if(
step > 100)
00416
step = 100;
00417
00418
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
00442 QPainter bufferPainter(
buffer );
00443 bufferPainter.drawPixmap(0,0, *
backgroundImage );
00444
00445
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
00471 bufferPainter.drawPixmap( newX -
left +
EDIT_MARGIN,
00472 newY -
top +
EDIT_MARGIN,
00473 QPixmap(
imageLarge->scale( imageW, imageH ) ) );
00474
00475
00476
animationLabel->setPixmap( *
buffer );
00477 }
00478
00479
00480
if(
step < 100)
00481 {
00482
00483
delay =
delay -
accel;
00484
if(
delay <
minDelay)
delay =
minDelay;
00485
00486
00487
timer->start(
delay, TRUE );
00488 }
00489
else
00490 {
00491
if(
mode ==
APPEARING)
00492 {
00493
animationLabel->hide();
00494
staticFrame->show();
00495
00496
00497
photoDesc->setFocus();
00498
00499
mode =
STATIC;
00500 }
00501
else
00502 {
00503
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
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
00551
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
00581
if( e->key() == Qt::Key_Escape )
00582 {
00583 emit
finished();
00584 }
00585
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
00599
00600
if(
contextMenu == NULL ) emit
finished();
00601 }
00602
00603 QPopupMenu*
TextEdit::createPopupMenu (
const QPoint& pos )
00604 {
00605
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
00615 disconnect( ((QObject*)
contextMenu), SIGNAL(aboutToHide()),
00616
this, SLOT(
contextMenuHiding()) );
00617 contextMenu = NULL;
00618 }
00619