00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <qpixmap.h>
00019 #include <qimage.h>
00020 #include <qstring.h>
00021 #include <qtextstream.h>
00022 #include <qdom.h>
00023 #include <qdir.h>
00024 #include <qfileinfo.h>
00025 #include <qregexp.h>
00026
00027
00028 #include "photo.h"
00029 #include "subalbum.h"
00030 #include "imageTools.h"
00031 #include "xmlTools.h"
00032 #include "../config.h"
00033
00034
00036 Photo::Photo(Subalbum* subalbum, int number)
00037 {
00038
00039 this->subalbum = subalbum;
00040
00041
00042 initialNumber = number;
00043 initialSubalbumNumber = subalbum->getSubalbumNumber();
00044
00045
00046 description = QString::null;;
00047
00048
00049 next = NULL;
00050
00051
00052 thumbnailImage = NULL;
00053 paddedThumbnailImage = NULL;
00054 slideshowImage = NULL;
00055 fullImage = NULL;
00056
00057
00058 imageChecksum = QString::null;
00059 slideshowChecksum = QString::null;
00060 thumbnailChecksum = QString::null;
00061
00062
00063 needsSaving = false;
00064
00065
00066 imageLocation = QString::null;
00067 slideshowLocation = QString::null;
00068 thumbnailLocation = QString::null;
00069
00070
00071 slideshowWidth = -1;
00072 slideshowHeight = -1;
00073 }
00074
00076 Photo::~Photo()
00077 {
00078 if(paddedThumbnailImage != thumbnailImage)
00079 delete paddedThumbnailImage;
00080 delete thumbnailImage;
00081 delete slideshowImage;
00082 delete fullImage;
00083 }
00084
00085 bool Photo::setImage(const QString &filename)
00086 {
00087
00088 delete fullImage;
00089
00090
00091 QImage tempImage = QImage(filename).convertDepth(32);
00092 fullImage = new QImage(tempImage.width(), tempImage.height(), 32);
00093 if(fullImage->isNull()) return false;
00094 int x, y;
00095 for(x = 0; x<tempImage.width(); x++)
00096 {
00097 for(y = 0; y<tempImage.height(); y++)
00098 {
00099 fullImage->setPixel(x, y, tempImage.pixel(x,y) );
00100 }
00101 }
00102
00103
00104 createImages(fullImage,
00105 &slideshowImage,
00106 &thumbnailImage,
00107 &paddedThumbnailImage,
00108 slideshowWidth,
00109 slideshowHeight);
00110
00111
00112 imageLocation = filename;
00113
00114
00115 needsSaving = true;
00116
00117
00118 subalbum->setModified();
00119
00120 return true;
00121 }
00122
00123 bool Photo::setImage(const QString &imageName,
00124 const QString &slideshowName,
00125 const QString &thumbnailName)
00126 {
00127
00128
00129 delete fullImage;
00130 if(paddedThumbnailImage != thumbnailImage)
00131 delete paddedThumbnailImage;
00132 delete thumbnailImage;
00133 delete slideshowImage;
00134
00135 fullImage = NULL;
00136 paddedThumbnailImage = NULL;
00137 thumbnailImage = NULL;
00138 slideshowImage = NULL;
00139
00140
00141 thumbnailImage = new QImage(thumbnailName);
00142 if(thumbnailImage->isNull()) return false;
00143
00144
00145
00146 if(thumbnailImage->width() == THUMBNAIL_WIDTH &&
00147 thumbnailImage->height() == THUMBNAIL_HEIGHT)
00148 {
00149 paddedThumbnailImage = thumbnailImage;
00150 }
00151
00152 else
00153 {
00154
00155 paddedThumbnailImage = new QImage(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, thumbnailImage->depth());
00156 paddedThumbnailImage->setAlphaBuffer(true);
00157
00158
00159 int xDiff = THUMBNAIL_WIDTH - thumbnailImage->width();
00160 int yDiff = THUMBNAIL_HEIGHT - thumbnailImage->height();
00161
00162
00163 paddedThumbnailImage->fill(Qt::white.rgb());
00164
00165 int x,y;
00166 int x2 = 0;
00167 int y2;
00168 for(x = xDiff/2; x< (xDiff/2) + thumbnailImage->width(); x++)
00169 {
00170 y2 = 0;
00171 for(y = yDiff/2; y < (yDiff/2) + thumbnailImage->height(); y++)
00172 {
00173 paddedThumbnailImage->setPixel(x, y, thumbnailImage->pixel(x2, y2));
00174 y2++;
00175 }
00176 x2++;
00177 }
00178 }
00179
00180
00181 imageLocation = imageName;
00182 slideshowLocation = slideshowName;
00183 thumbnailLocation = thumbnailName;
00184
00185
00186 needsSaving = false;
00187
00188
00189 subalbum->setModified();
00190
00191 return true;
00192
00193 }
00194
00195 bool Photo::setImage(QImage* newFullImage)
00196 {
00197
00198 delete fullImage;
00199 fullImage = newFullImage;
00200 if(fullImage->isNull()) return false;
00201
00202
00203 createImages(fullImage,
00204 &slideshowImage,
00205 &thumbnailImage,
00206 &paddedThumbnailImage,
00207 slideshowWidth,
00208 slideshowHeight);
00209
00210
00211 imageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00212 .arg(initialSubalbumNumber)
00213 .arg(initialNumber);
00214 slideshowLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00215 .arg(initialSubalbumNumber)
00216 .arg(initialNumber);
00217 thumbnailLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_thumb.jpg")
00218 .arg(initialSubalbumNumber)
00219 .arg(initialNumber);
00220
00221 fullImage->save( imageLocation, "JPEG", 100);
00222 slideshowImage->save( slideshowLocation, "JPEG", 100);
00223
00224
00225 needsSaving = true;
00226
00227
00228 subalbum->setModified();
00229
00230
00231 deallocateLargeImages();
00232
00233 return true;
00234 }
00235
00236 void Photo::setDescription(QString val)
00237 {
00238 if(description != val)
00239 {
00240 description = val;
00241 subalbum->setModified();
00242 }
00243 }
00244
00246 QString Photo::getDescription()
00247 {
00248 return QString(description);
00249 }
00250
00252 Photo* Photo::getNext()
00253 {
00254 return next;
00255 }
00256
00258 void Photo::setNext(Photo* val)
00259 {
00260 next = val;
00261
00262
00263 subalbum->setModified();
00264 }
00265
00266 QImage* Photo::getImage(int size)
00267 {
00268 if(size == THUMBNAIL)
00269 return thumbnailImage;
00270 else if(size == PADDED_THUMBNAIL)
00271 return paddedThumbnailImage;
00272 else if(size == SLIDESHOW)
00273 {
00274 if( slideshowImage != NULL)
00275 return slideshowImage;
00276 else
00277 {
00278 if(!needsSaving)
00279 {
00280 return new QImage(slideshowLocation);
00281 }
00282 else
00283 {
00284 QString tmpImageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00285 .arg(initialSubalbumNumber)
00286 .arg(initialNumber);
00287 return new QImage(tmpImageLocation);
00288 }
00289 }
00290 }
00291 else if(size == IMAGE)
00292 {
00293 if( fullImage != NULL)
00294 return fullImage;
00295 else
00296 {
00297 if(!needsSaving)
00298 {
00299 return new QImage(imageLocation);
00300 }
00301 else
00302 {
00303 QString tmpImageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00304 .arg(initialSubalbumNumber)
00305 .arg(initialNumber);
00306 return new QImage(tmpImageLocation);
00307 }
00308 }
00309 }
00310 else
00311 return NULL;
00312 }
00313
00314 void Photo::exportToXML(QTextStream& stream)
00315 {
00316 QFileInfo info;
00317
00318
00319
00320 stream << " <photo>\n";
00321
00322 stream << " <description>" << fixXMLString(description) << "</description>\n";
00323
00324
00325 info.setFile( getImageFilename() );
00326 QDateTime modified = info.lastModified();
00327 stream << " <image>\n";
00328 stream << " <md5>" << fixXMLString(imageChecksum) << "</md5>\n";
00329 stream << " <modified>";
00330 stream << modified.date().year() << " ";
00331 stream << modified.date().month() << " ";
00332 stream << modified.date().day() << " ";
00333 stream << modified.time().hour() << " ";
00334 stream << modified.time().minute() << " ";
00335 stream << modified.time().second() << " ";
00336 stream << modified.time().msec() << "</modified>\n";
00337 stream << " </image>\n";
00338
00339
00340 info.setFile( getSlideshowFilename() );
00341 modified = info.lastModified();
00342 stream << " <slideshow>\n";
00343 stream << " <md5>" << fixXMLString(slideshowChecksum) << "</md5>\n";
00344 stream << " <modified>";
00345 stream << modified.date().year() << " ";
00346 stream << modified.date().month() << " ";
00347 stream << modified.date().day() << " ";
00348 stream << modified.time().hour() << " ";
00349 stream << modified.time().minute() << " ";
00350 stream << modified.time().second() << " ";
00351 stream << modified.time().msec() << "</modified>\n";
00352 stream << " </slideshow>\n";
00353
00354
00355 info.setFile( getThumbnailFilename() );
00356 modified = info.lastModified();
00357 stream << " <thumb>\n";
00358 stream << " <md5>" << fixXMLString(thumbnailChecksum) << "</md5>\n";
00359 stream << " <modified>";
00360 stream << modified.date().year() << " ";
00361 stream << modified.date().month() << " ";
00362 stream << modified.date().day() << " ";
00363 stream << modified.time().hour() << " ";
00364 stream << modified.time().minute() << " ";
00365 stream << modified.time().second() << " ";
00366 stream << modified.time().msec() << "</modified>\n";
00367 stream << " </thumb>\n";
00368
00369 stream << " </photo>\n";
00370 }
00371
00372 void Photo::exportThumbnailHTML(QTextStream& stream)
00373 {
00374
00375 stream << "?";
00376 }
00377
00378 void Photo::exportSlideshowHTML(QTextStream& stream)
00379 {
00380
00381 stream << "?";
00382 }
00383
00384 QDateTime* Photo::importFromDisk(QDomNode* root)
00385 {
00386
00387 QDateTime* modified = new QDateTime[3];
00388
00389 QDomNode node = root->firstChild();
00390 QDomText val;
00391 while( !node.isNull() )
00392 {
00393
00394
00395 if( node.isElement() && node.nodeName() == "description" )
00396 {
00397 val = node.firstChild().toText();
00398 if(!val.isNull())
00399 description = val.nodeValue();
00400 }
00401
00402
00403 else if( node.isElement() && node.nodeName() == "image" )
00404 {
00405 QDomNode childNode = node.firstChild();
00406 while( !childNode.isNull() )
00407 {
00408
00409 if( childNode.isElement() && childNode.nodeName() == "md5" )
00410 {
00411 val = childNode.firstChild().toText();
00412 if(!val.isNull())
00413 imageChecksum = val.nodeValue();
00414 }
00415
00416 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00417 {
00418 val = childNode.firstChild().toText();
00419
00420
00421 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00422 int i=0;
00423 int intVals[7];
00424 QStringList::Iterator it;
00425 for ( it = vals.begin(); it != vals.end(); ++it )
00426 {
00427
00428 if(i >6)
00429 break;
00430
00431 intVals[i] = QString(*it).toInt();
00432 i++;
00433 }
00434 modified[0].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00435 modified[0].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00436 }
00437
00438 childNode = childNode.nextSibling();
00439 }
00440 }
00441
00442
00443 else if( node.isElement() && node.nodeName() == "slideshow" )
00444 {
00445 QDomNode childNode = node.firstChild();
00446 while( !childNode.isNull() )
00447 {
00448
00449 if( childNode.isElement() && childNode.nodeName() == "md5" )
00450 {
00451 val = childNode.firstChild().toText();
00452 if(!val.isNull())
00453 slideshowChecksum = val.nodeValue();
00454 }
00455
00456 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00457 {
00458 val = childNode.firstChild().toText();
00459
00460
00461 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00462 int i=0;
00463 int intVals[7];
00464 QStringList::Iterator it;
00465 for ( it = vals.begin(); it != vals.end(); ++it )
00466 {
00467
00468 if(i >6)
00469 break;
00470
00471 intVals[i] = QString(*it).toInt();
00472 i++;
00473 }
00474 modified[1].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00475 modified[1].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00476 }
00477
00478 childNode = childNode.nextSibling();
00479 }
00480 }
00481
00482
00483 else if( node.isElement() && node.nodeName() == "thumb" )
00484 {
00485 QDomNode childNode = node.firstChild();
00486 while( !childNode.isNull() )
00487 {
00488
00489 if( childNode.isElement() && childNode.nodeName() == "md5" )
00490 {
00491 val = childNode.firstChild().toText();
00492 if(!val.isNull())
00493 thumbnailChecksum = val.nodeValue();
00494 }
00495
00496 else if( childNode.isElement() && childNode.nodeName() == "modified" )
00497 {
00498 val = childNode.firstChild().toText();
00499
00500
00501 QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00502 int i=0;
00503 int intVals[7];
00504 QStringList::Iterator it;
00505 for ( it = vals.begin(); it != vals.end(); ++it )
00506 {
00507
00508 if(i >6)
00509 break;
00510
00511 intVals[i] = QString(*it).toInt();
00512 i++;
00513 }
00514 modified[2].setDate( QDate(intVals[0], intVals[1], intVals[2]) );
00515 modified[2].setTime( QTime(intVals[3], intVals[4], intVals[5], intVals[6]) );
00516 }
00517
00518 childNode = childNode.nextSibling();
00519 }
00520 }
00521
00522
00523
00524
00525 else if( node.isElement() && node.nodeName() == "imageMD5" )
00526 {
00527 val = node.firstChild().toText();
00528 if(!val.isNull())
00529 imageChecksum = val.nodeValue();
00530 }
00531
00532
00533 else if( node.isElement() && node.nodeName() == "slideMD5" )
00534 {
00535 val = node.firstChild().toText();
00536 if(!val.isNull())
00537 slideshowChecksum = val.nodeValue();
00538 }
00539
00540
00541 else if( node.isElement() && node.nodeName() == "thumbMD5" )
00542 {
00543 val = node.firstChild().toText();
00544 if(!val.isNull())
00545 thumbnailChecksum = val.nodeValue();
00546 }
00547
00548
00549
00550
00551
00552 node = node.nextSibling();
00553
00554 }
00555
00556
00557 return modified;
00558 }
00559
00560 void Photo::rotate90()
00561 {
00562
00563
00564 fullImage = new QImage(imageLocation);
00565
00566
00567 QImage* rotatedImage = new QImage(fullImage->height(),
00568 fullImage->width(),
00569 fullImage->depth());
00570 rotatedImage->setAlphaBuffer(true);
00571
00572
00573 int x,y;
00574 for(x=0; x < fullImage->height(); x++)
00575 {
00576 for(y=0; y < fullImage->width(); y++)
00577 {
00578 rotatedImage->setPixel(fullImage->height() - 1 - x, y, fullImage->pixel(y, x) );
00579 }
00580 }
00581
00582
00583 delete fullImage;
00584 fullImage = rotatedImage;
00585
00586
00587 createImages(fullImage,
00588 &slideshowImage,
00589 &thumbnailImage,
00590 &paddedThumbnailImage,
00591 slideshowWidth,
00592 slideshowHeight);
00593
00594
00595 imageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00596 .arg(initialSubalbumNumber)
00597 .arg(initialNumber);
00598 slideshowLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00599 .arg(initialSubalbumNumber)
00600 .arg(initialNumber);
00601
00602 fullImage->save( imageLocation, "JPEG", 100);
00603 slideshowImage->save( slideshowLocation, "JPEG", 100);
00604
00605
00606 needsSaving = true;
00607
00608
00609 deallocateLargeImages();
00610
00611
00612 subalbum->setModified();
00613 }
00614
00615 void Photo::rotate270()
00616 {
00617
00618
00619 fullImage = new QImage(imageLocation);
00620
00621
00622 QImage* rotatedImage = new QImage(fullImage->height(),
00623 fullImage->width(),
00624 fullImage->depth());
00625 rotatedImage->setAlphaBuffer(true);
00626
00627 int x,y;
00628 for(x=0; x < fullImage->height(); x++)
00629 {
00630 for(y=0; y < fullImage->width(); y++)
00631 {
00632 rotatedImage->setPixel(x, fullImage->width() - 1 - y, fullImage->pixel(y, x) );
00633 }
00634 }
00635
00636
00637 delete fullImage;
00638 fullImage = rotatedImage;
00639
00640
00641 createImages(fullImage,
00642 &slideshowImage,
00643 &thumbnailImage,
00644 &paddedThumbnailImage,
00645 slideshowWidth,
00646 slideshowHeight);
00647
00648
00649 imageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00650 .arg(initialSubalbumNumber)
00651 .arg(initialNumber);
00652 slideshowLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00653 .arg(initialSubalbumNumber)
00654 .arg(initialNumber);
00655
00656 fullImage->save( imageLocation, "JPEG", 100);
00657 slideshowImage->save( slideshowLocation, "JPEG", 100);
00658
00659
00660
00661 needsSaving = true;
00662
00663
00664 deallocateLargeImages();
00665
00666
00667 subalbum->setModified();
00668 }
00669
00670 void Photo::flipHorizontally()
00671 {
00672
00673 QImage origImage(imageLocation);
00674 QImage newImage = origImage.mirror(false,true);
00675
00676
00677 createImages(&newImage,
00678 &slideshowImage,
00679 &thumbnailImage,
00680 &paddedThumbnailImage,
00681 slideshowWidth,
00682 slideshowHeight);
00683
00684
00685 imageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00686 .arg(initialSubalbumNumber)
00687 .arg(initialNumber);
00688 slideshowLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00689 .arg(initialSubalbumNumber)
00690 .arg(initialNumber);
00691
00692 newImage.save( imageLocation, "JPEG", 100);
00693 slideshowImage->save( slideshowLocation, "JPEG", 100);
00694
00695
00696 needsSaving = true;
00697
00698
00699 deallocateLargeImages();
00700
00701
00702 subalbum->setModified();
00703 }
00704
00705 void Photo::flipVertically()
00706 {
00707
00708 QImage origImage(imageLocation);
00709 QImage newImage = origImage.mirror(true,false);
00710
00711
00712 createImages(&newImage,
00713 &slideshowImage,
00714 &thumbnailImage,
00715 &paddedThumbnailImage,
00716 slideshowWidth,
00717 slideshowHeight);
00718
00719
00720 imageLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2.jpg")
00721 .arg(initialSubalbumNumber)
00722 .arg(initialNumber);
00723 slideshowLocation = QDir::homeDirPath() + QString("/.albumShaper/tmp/%1_%2_slideshow.jpg")
00724 .arg(initialSubalbumNumber)
00725 .arg(initialNumber);
00726
00727 newImage.save( imageLocation, "JPEG", 100);
00728 slideshowImage->save( slideshowLocation, "JPEG", 100);
00729
00730
00731 needsSaving = true;
00732
00733
00734 deallocateLargeImages();
00735
00736
00737 subalbum->setModified();
00738 }
00739
00740 void Photo::setThumbnailChecksum(QString val)
00741 {
00742 thumbnailChecksum = val;
00743 }
00744
00745 void Photo::setSlideshowChecksum(QString val)
00746 {
00747 slideshowChecksum = val;
00748 }
00749
00750 void Photo::setImageChecksum(QString val)
00751 {
00752 imageChecksum = val;
00753 }
00754
00755 QString Photo::getThumbnailChecksum()
00756 {
00757 return thumbnailChecksum;
00758 }
00759
00760 QString Photo::getSlideshowChecksum()
00761 {
00762 return slideshowChecksum;
00763 }
00764
00765 QString Photo::getImageChecksum()
00766 {
00767 return imageChecksum;
00768 }
00769
00770 void Photo::deallocateLargeImages()
00771 {
00772 delete fullImage;
00773 fullImage = NULL;
00774
00775 delete slideshowImage;
00776 slideshowImage = NULL;
00777 }
00778
00779 void Photo::setImageFilename(QString val)
00780 {
00781 imageLocation = val;
00782 }
00783
00784 void Photo::setSlideshowFilename(QString val)
00785 {
00786 slideshowLocation = val;
00787 }
00788
00789 void Photo::setThumbnailFilename(QString val)
00790 {
00791 thumbnailLocation = val;
00792 }
00793
00794 QString Photo::getImageFilename()
00795 {
00796 return imageLocation;
00797 }
00798
00799 QString Photo::getSlideshowFilename()
00800 {
00801 return slideshowLocation;
00802 }
00803
00804 QString Photo::getThumbnailFilename()
00805 {
00806 return thumbnailLocation;
00807 }
00808
00809 void Photo::setNeedsSavingVal(bool val)
00810 {
00811 needsSaving = val;
00812 }
00813
00814 bool Photo::getNeedsSavingVal()
00815 {
00816 return needsSaving;
00817 }
00818
00819 int Photo::getInitialPhotoNumber()
00820 {
00821 return initialNumber;
00822 }
00823
00824 int Photo::getInitialSubalbumNumber()
00825 {
00826 return initialSubalbumNumber;
00827 }
00828
00829 void Photo::setInitialPhotoNumber(int val)
00830 {
00831 initialNumber = val;
00832 }
00833
00834 void Photo::setInitialSubalbumNumber(int val)
00835 {
00836 initialSubalbumNumber = val;
00837 }
00838
00839 int Photo::actualSlideshowWidth()
00840 {
00841 return slideshowWidth;;
00842 }
00843
00844 int Photo::actualSlideshowHeight()
00845 {
00846 return slideshowHeight;
00847 }
00848
00849 void Photo::setActualSlideshowDimensions(int w, int h)
00850 {
00851 slideshowWidth = w;
00852 slideshowHeight = h;
00853 }
00854