00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <qpixmap.h>
00012 #include <qimage.h>
00013 #include <qstring.h>
00014 #include <qtextstream.h>
00015 #include <qdom.h>
00016 #include <qdir.h>
00017 #include <qfileinfo.h>
00018 #include <qregexp.h>
00019
00020
00021 #include "photo.h"
00022 #include "subalbum.h"
00023 #include "album.h"
00024 #include "tools/fileTools.h"
00025 #include "tools/imageTools.h"
00026 #include "tools/xmlTools.h"
00027 #include "tools/md5.h"
00028 #include "../config.h"
00029
00030
00031 Photo::Photo(Subalbum* subalbum, Photo* prev, int photoNumber)
00032 {
00033
00034 this->subalbum = subalbum;
00035
00036
00037 this->prev = prev;
00038
00039
00040
00041 next = NULL;
00042
00043
00044 initialPhotoNumber = photoNumber;
00045 initialSubalbumNumber = subalbum->getSubalbumNumber();
00046
00047
00048 description = QString::null;
00049
00050
00051 thumbnailImage = NULL;
00052
00053
00054 imageLocation = QString::null;
00055 imageChecksum = QString::null;
00056
00057 slideshowLocation = QString::null;
00058 slideshowChecksum = QString::null;
00059
00060 thumbnailLocation = QString::null;
00061 thumbnailChecksum = QString::null;
00062
00063
00064
00065
00066 needsSaving = false;
00067
00068
00069
00070 everSaved = true;
00071
00072
00073 recentlyReverted = false;
00074 }
00075
00076 Photo::~Photo()
00077 {
00078
00079 delete thumbnailImage;
00080 }
00081
00082 QImage* Photo::getThumbnailImage() { return thumbnailImage; }
00083
00084 bool Photo::constructSmallerImages()
00085 {
00086
00087 QImage TslideshowImage, TthumbnailImage;
00088 constructImages( imageLocation, TslideshowImage, TthumbnailImage );
00089 TslideshowImage.save( slideshowLocation, "JPEG", 95 );
00090 TthumbnailImage.save( thumbnailLocation, "JPEG", 95 );
00091
00092
00093 delete thumbnailImage;
00094 thumbnailImage = new QImage(thumbnailLocation);
00095
00096
00097 needsSaving = true;
00098
00099
00100 subalbum->setModified();
00101 return true;
00102 }
00103
00104 bool Photo::setImage(QString imageName,
00105 QString slideshowName,
00106 QString thumbnailName)
00107 {
00108
00109 imageLocation = imageName;
00110 slideshowLocation = slideshowName;
00111 thumbnailLocation = thumbnailName;
00112
00113
00114 delete thumbnailImage;
00115 thumbnailImage = new QImage(thumbnailName);
00116 if(thumbnailImage->isNull()) return false;
00117
00118
00119 needsSaving = false;
00120 return true;
00121 }
00122
00123 bool Photo::setImage(QString imageName, int uniqueID)
00124 {
00125
00126 setEverSaved(false);
00127 initialSubalbumNumber = 0;
00128 initialPhotoNumber = uniqueID;
00129
00130 QString tmpDir = subalbum->getAlbum()->getTmpDir();
00131 imageLocation = QString("%1/%2_%3.jpg") .arg(tmpDir).arg(initialSubalbumNumber).arg(initialPhotoNumber);
00132 slideshowLocation = QString("%1/%2_%3_slideshow.jpg").arg(tmpDir).arg(initialSubalbumNumber).arg(initialPhotoNumber);
00133 thumbnailLocation = QString("%1/%2_%3_thumb.jpg") .arg(tmpDir).arg(initialSubalbumNumber).arg(initialPhotoNumber);
00134
00135
00136 if( isJpeg(imageName) )
00137 {
00138 copyFile( imageName, imageLocation );
00139 }
00140
00141 else
00142 {
00143
00144 QImage tempImage(imageName);
00145 if( tempImage.isNull() ) { return false; }
00146
00147
00148 tempImage.save( imageLocation, "JPEG", 95 );
00149 }
00150
00151
00152 return constructSmallerImages();
00153 }
00154
00155 bool Photo::setImage(QString editedImageFilename)
00156 {
00157
00158
00159
00160 if( getEverSaved() )
00161 {
00162 imageLocation = subalbum->getAlbum()->getTmpDir() +
00163 QString("/%1_%2.jpg").arg(initialSubalbumNumber).arg(initialPhotoNumber);
00164 slideshowLocation = subalbum->getAlbum()->getTmpDir() +
00165 QString("/%1_%2_slideshow.jpg").arg(initialSubalbumNumber).arg(initialPhotoNumber);
00166 thumbnailLocation = subalbum->getAlbum()->getTmpDir() +
00167 QString("/%1_%2_thumb.jpg").arg(initialSubalbumNumber).arg(initialPhotoNumber);
00168 }
00169
00170 else
00171 {
00172 QString tempOrigLocation = imageLocation;
00173 tempOrigLocation.truncate( imageLocation.length() - 4 );
00174 tempOrigLocation = tempOrigLocation + "_orig.jpg";
00175
00176 QDir tmpDir;
00177 if(!tmpDir.exists( tempOrigLocation ) )
00178 { copyFile( imageLocation, tempOrigLocation ); }
00179 }
00180
00181
00182 copyFile( editedImageFilename, imageLocation );
00183
00184
00185 recentlyReverted = false;
00186
00187
00188 return constructSmallerImages();
00189 }
00190
00191 QString Photo::getImageFilename() { return imageLocation; }
00192 QString Photo::getSlideshowFilename() { return slideshowLocation; }
00193 QString Photo::getThumbnailFilename() { return thumbnailLocation; }
00194
00195 void Photo::setImageFilename(QString val) { imageLocation = val; }
00196 void Photo::setSlideshowFilename(QString val) { slideshowLocation = val; }
00197 void Photo::setThumbnailFilename(QString val) { thumbnailLocation = val; }
00198
00199 QString Photo::getImageChecksum() { return imageChecksum; }
00200 QString Photo::getThumbnailChecksum() { return thumbnailChecksum; }
00201 QString Photo::getSlideshowChecksum() { return slideshowChecksum; }
00202
00203 void Photo::setImageChecksum(QString val) { imageChecksum = val; }
00204 void Photo::setThumbnailChecksum(QString val) { thumbnailChecksum = val; }
00205 void Photo::setSlideshowChecksum(QString val) { slideshowChecksum = val; }
00206
00207 QString Photo::getDescription() { return QString(description); }
00208
00209 void Photo::setDescription(QString val)
00210 {
00211
00212
00213 if( val.isEmpty() )
00214 val = QString::null;
00215
00216 if(description.compare(val) != 0)
00217 {
00218 description = val;
00219 subalbum->setModified();
00220 }
00221 }
00222
00223 Photo* Photo::getPrev() { return prev; }
00224 Photo* Photo::getNext() { return next; }
00225
00226 void Photo::setPrev(Photo* val)
00227 {
00228 prev = val;
00229 subalbum->setModified();
00230 }
00231
00232 void Photo::setNext(Photo* val)
00233 {
00234 next = val;
00235 subalbum->setModified();
00236 }
00237
00238 QDateTime* Photo::importFromDisk(QDomNode* root)
00239 {
00240
00241 QDateTime* modified = new QDateTime[3];
00242
00243 QDomNode node = root->firstChild();
00244 QDomText val;
00245 while( !node.isNull() )
00246 {
00247
00248
00249 if( node.isElement() && node.nodeName() == "description" )
00250 {
00251 val = node.firstChild().toText();
00252 if(!val.isNull())
00253 description = val.nodeValue();
00254 description.replace("\\"","\"");
00255 }
00256
00257
00258 else if( node.isElement() && node.nodeName() == "image" )
00259 {
00260 QDomNode childNode = node.firstChild();
00261 while( !childNode.isNull() )
00262 {
00263
00264 if( childNode.isElement() && childNode.nodeName() == "md5" )
00265 {
00266 val = childNode.firstChild().toText();
00267 if(!val.isNull())
00268 imageChecksum = val.nodeValue();
00269 }
00270
00271 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00272 {
00273 val = childNode.firstChild().toText();
00274
00275
00276 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00277 int i=0;
00278 int intVals[7];
00279 QStringList::Iterator it;
00280 for ( it = vals.begin(); it != vals.end(); ++it )
00281 {
00282
00283 if(i >6)
00284 break;
00285
00286 intVals[i] = QString(*it).toInt();
00287 i++;
00288 }
00289 modified[0].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00290 modified[0].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00291 }
00292
00293 childNode = childNode.nextSibling();
00294 }
00295 }
00296
00297
00298 else if( node.isElement() && node.nodeName() == "slideshow" )
00299 {
00300 QDomNode childNode = node.firstChild();
00301 while( !childNode.isNull() )
00302 {
00303
00304 if( childNode.isElement() && childNode.nodeName() == "md5" )
00305 {
00306 val = childNode.firstChild().toText();
00307 if(!val.isNull())
00308 slideshowChecksum = val.nodeValue();
00309 }
00310
00311 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00312 {
00313 val = childNode.firstChild().toText();
00314
00315
00316 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00317 int i=0;
00318 int intVals[7];
00319 QStringList::Iterator it;
00320 for ( it = vals.begin(); it != vals.end(); ++it )
00321 {
00322
00323 if(i >6)
00324 break;
00325
00326 intVals[i] = QString(*it).toInt();
00327 i++;
00328 }
00329 modified[1].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00330 modified[1].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00331 }
00332
00333 childNode = childNode.nextSibling();
00334 }
00335 }
00336
00337
00338 else if( node.isElement() && node.nodeName() == "thumb" )
00339 {
00340 QDomNode childNode = node.firstChild();
00341 while( !childNode.isNull() )
00342 {
00343
00344 if( childNode.isElement() && childNode.nodeName() == "md5" )
00345 {
00346 val = childNode.firstChild().toText();
00347 if(!val.isNull())
00348 thumbnailChecksum = val.nodeValue();
00349 }
00350
00351 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00352 {
00353 val = childNode.firstChild().toText();
00354
00355
00356 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00357 int i=0;
00358 int intVals[7];
00359 QStringList::Iterator it;
00360 for ( it = vals.begin(); it != vals.end(); ++it )
00361 {
00362
00363 if(i >6)
00364 break;
00365
00366 intVals[i] = QString(*it).toInt();
00367 i++;
00368 }
00369 modified[2].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00370 modified[2].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00371 }
00372
00373 childNode = childNode.nextSibling();
00374 }
00375 }
00376
00377
00378
00379
00380 else if( node.isElement() && node.nodeName() == "imageMD5" )
00381 {
00382 val = node.firstChild().toText();
00383 if(!val.isNull())
00384 imageChecksum = val.nodeValue();
00385 }
00386
00387
00388 else if( node.isElement() && node.nodeName() == "slideMD5" )
00389 {
00390 val = node.firstChild().toText();
00391 if(!val.isNull())
00392 slideshowChecksum = val.nodeValue();
00393 }
00394
00395
00396 else if( node.isElement() && node.nodeName() == "thumbMD5" )
00397 {
00398 val = node.firstChild().toText();
00399 if(!val.isNull())
00400 thumbnailChecksum = val.nodeValue();
00401 }
00402
00403
00404
00405 node = node.nextSibling();
00406
00407 }
00408
00409
00410 return modified;
00411 }
00412
00413 void Photo::exportToXML(QTextStream& stream)
00414 {
00415 QFileInfo info;
00416
00417
00418 stream << " <photo>\n";
00419
00420 stream << " <description>" << fixXMLString(description) << "</description>\n";
00421
00422
00423 info.setFile( getImageFilename() );
00424 QDateTime modified = info.lastModified();
00425 stream << " <image>\n";
00426 stream << " <md5>" << fixXMLString(imageChecksum) << "</md5>\n";
00427 stream << " <modified>";
00428 stream << modified.date().year() << " ";
00429 stream << modified.date().month() << " ";
00430 stream << modified.date().day() << " ";
00431 stream << modified.time().hour() << " ";
00432 stream << modified.time().minute() << " ";
00433 stream << modified.time().second() << " ";
00434 stream << modified.time().msec() << "</modified>\n";
00435 stream << " </image>\n";
00436
00437
00438 info.setFile( getSlideshowFilename() );
00439 modified = info.lastModified();
00440 stream << " <slideshow>\n";
00441 stream << " <md5>" << fixXMLString(slideshowChecksum) << "</md5>\n";
00442 stream << " <modified>";
00443 stream << modified.date().year() << " ";
00444 stream << modified.date().month() << " ";
00445 stream << modified.date().day() << " ";
00446 stream << modified.time().hour() << " ";
00447 stream << modified.time().minute() << " ";
00448 stream << modified.time().second() << " ";
00449 stream << modified.time().msec() << "</modified>\n";
00450 stream << " </slideshow>\n";
00451
00452
00453 info.setFile( getThumbnailFilename() );
00454 modified = info.lastModified();
00455 stream << " <thumb>\n";
00456 stream << " <md5>" << fixXMLString(thumbnailChecksum) << "</md5>\n";
00457 stream << " <modified>";
00458 stream << modified.date().year() << " ";
00459 stream << modified.date().month() << " ";
00460 stream << modified.date().day() << " ";
00461 stream << modified.time().hour() << " ";
00462 stream << modified.time().minute() << " ";
00463 stream << modified.time().second() << " ";
00464 stream << modified.time().msec() << "</modified>\n";
00465 stream << " </thumb>\n";
00466
00467 stream << " </photo>\n";
00468 }
00469
00470 void Photo::rotate90() { applyTransformation( ROTATE_90 ); }
00471 void Photo::rotate270() { applyTransformation( ROTATE_270 ); }
00472 void Photo::flipHorizontally() { applyTransformation( FLIP_H ); }
00473 void Photo::flipVertically() { applyTransformation( FLIP_V ); }
00474
00475 void Photo::applyTransformation(TRANSFORM_CODE transformation)
00476 {
00477
00478 QString oldName = imageLocation;
00479
00480
00481
00482
00483 if(!needsSaving)
00484 {
00485 imageLocation = subalbum->getAlbum()->getTmpDir() + QString("/%1_%2.jpg")
00486 .arg(initialSubalbumNumber)
00487 .arg(initialPhotoNumber);
00488 slideshowLocation = subalbum->getAlbum()->getTmpDir() + QString("/%1_%2_slideshow.jpg")
00489 .arg(initialSubalbumNumber)
00490 .arg(initialPhotoNumber);
00491 thumbnailLocation = subalbum->getAlbum()->getTmpDir() + QString("/%1_%2_thumb.jpg")
00492 .arg(initialSubalbumNumber)
00493 .arg(initialPhotoNumber);
00494 transformImage( oldName, imageLocation, transformation );
00495 }
00496 else
00497 {
00498
00499
00500
00501
00502 QString intermediateName = QString("%1_intermdiate.jpg").arg(oldName);
00503 transformImage( oldName, intermediateName, transformation );
00504
00505
00506
00507
00508
00509 QString origName = subalbum->getAlbum()->getTmpDir() + QString("/0_%1_orig.jpg")
00510 .arg(initialPhotoNumber);
00511 QDir tmpDir;
00512 if( !getEverSaved() && !tmpDir.exists(origName) )
00513 {
00514 moveFile( oldName, origName );
00515 moveFile( intermediateName, imageLocation );
00516 }
00517 else
00518 {
00519 moveFile( intermediateName, imageLocation );
00520 }
00521 }
00522
00523
00524 recentlyReverted = false;
00525
00526
00527 constructSmallerImages();
00528 }
00529
00530 bool Photo::getNeedsSavingVal() { return needsSaving; }
00531 void Photo::setNeedsSavingVal(bool val) { needsSaving = val; }
00532
00533 bool Photo::getEverSaved() { return everSaved; }
00534 void Photo::setEverSaved(bool val) { everSaved = val; }
00535
00536 bool Photo::revertPossible()
00537 {
00538
00539 QString newName = getImageFilename();
00540 QString origName = originalImageFilename();
00541
00542 return ( !recentlyReverted &&
00543 origName.compare( newName ) !=0 );
00544 }
00545
00546 bool Photo::getRecentlyReverted()
00547 {
00548 return recentlyReverted;
00549 }
00550
00551 void Photo::setRecentlyReverted(bool val)
00552 {
00553 recentlyReverted = val;
00554 }
00555
00556 void Photo::revertPhoto()
00557 {
00558
00559 if(!revertPossible())
00560 return;
00561
00562
00563 QString origName = originalImageFilename();
00564 setImage( origName );
00565
00566
00567
00568 recentlyReverted = true;
00569 }
00570
00571 QString Photo::originalImageFilename()
00572 {
00573
00574
00575
00576 if( !getEverSaved() )
00577 {
00578 QString tempOrigLocation = imageLocation;
00579 tempOrigLocation.truncate( imageLocation.length() - 4 );
00580 tempOrigLocation = tempOrigLocation + "_orig.jpg";
00581
00582 QDir tmpDir;
00583 if(tmpDir.exists( tempOrigLocation ) )
00584 return tempOrigLocation;
00585 else
00586 return imageLocation;
00587 }
00588
00589
00590
00591 else
00592 {
00593 QString storedOrigLocation = subalbum->getAlbum()->getSaveLocation() +
00594 QString("/img/%1/%2_orig.jpg").arg(initialSubalbumNumber).arg(initialPhotoNumber);
00595
00596 QString lastSavedLocation = subalbum->getAlbum()->getSaveLocation() +
00597 QString("/img/%1/%2.jpg").arg(initialSubalbumNumber).arg(initialPhotoNumber);
00598
00599 QDir tmpDir;
00600 if(tmpDir.exists( storedOrigLocation ) )
00601 return storedOrigLocation;
00602 else
00603 return lastSavedLocation;
00604 }
00605 }
00606
00607 int Photo::getInitialPhotoNumber() { return initialPhotoNumber; }
00608 void Photo::setInitialPhotoNumber(int val) { initialPhotoNumber = val; }
00609
00610 int Photo::getInitialSubalbumNumber() { return initialSubalbumNumber; }
00611 void Photo::setInitialSubalbumNumber(int val) { initialSubalbumNumber = val; }
00612