00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include <qimage.h>
00013
#include <qpixmap.h>
00014
#include <qstring.h>
00015
#include <qtextstream.h>
00016
#include <qdom.h>
00017
#include <fstream>
00018
#include <qdir.h>
00019
#include <qregexp.h>
00020
#include <qapplication.h>
00021
00022
00023
#include "album.h"
00024
#include "subalbum.h"
00025
#include "photo.h"
00026
#include "tools/imageTools.h"
00027
#include "tools/xmlTools.h"
00028
#include "tools/md5.h"
00029
#include "../config.h"
00030
#include "../gui/photoPreviewWidget.h"
00031
#include "../gui/statusWidget.h"
00032
#include "../gui/subalbumPreviewWidget.h"
00033
00034
00035 Subalbum::Subalbum(
Album* albm,
int number)
00036 {
00037
00038 this->number = number;
00039
00040
00041
numPhotos = 0;
00042
loadedPhotos = 0;
00043
00044
00045
name = qApp->translate(
"Subalbum",
"Collection %1").arg(number);
00046
description =
"";
00047
00048
00049
smallRepresentativeImage = NULL;
00050
mediumRepresentativeImage = SubalbumPreviewWidget::createSubalbumPixmap
00051 ( QString(
IMAGE_PATH)+
"miscImages/subalbum.png" );
00052
largeRepresentativeImage = NULL;
00053
00054
00055
firstPhoto = NULL;
00056
lastPhoto = NULL;
00057
00058
00059
prevSubalbum = NULL;
00060
nextSubalbum = NULL;
00061
00062
00063 this->albm = albm;
00064 }
00065
00066 Subalbum::~Subalbum()
00067 {
00068
00069
delete smallRepresentativeImage;
00070
delete mediumRepresentativeImage;
00071
delete largeRepresentativeImage;
00072
00073
00074
Photo* current =
firstPhoto;
00075
while(current != NULL)
00076 {
00077
Photo* temp = current->
getNext();
00078
delete current;
00079 current = temp;
00080 }
00081 }
00082
00083 QString
Subalbum::getName() {
return QString(
name); }
00084 QString
Subalbum::getDescription() {
return QString(
description); }
00085
00086 QPixmap*
Subalbum::getRepresentativeImage(
int size)
00087 {
00088
if(size ==
SMALL)
return smallRepresentativeImage;
00089
if(size ==
MEDIUM)
return mediumRepresentativeImage;
00090
if(size ==
LARGE)
return largeRepresentativeImage;
00091
else return NULL;
00092 }
00093
00094 Album*
Subalbum::getAlbum() {
return albm; }
00095
00096 Subalbum*
Subalbum::getPrev() {
return prevSubalbum; }
00097 Subalbum*
Subalbum::getNext() {
return nextSubalbum; }
00098
00099 Photo*
Subalbum::getFirst() {
return firstPhoto; }
00100 Photo*
Subalbum::getLast() {
return lastPhoto; }
00101
00102 int Subalbum::getSubalbumNumber() {
return number; }
00103 int Subalbum::getNumPhotos() {
return numPhotos; }
00104 int Subalbum::getNumLoadedPhotos() {
return loadedPhotos; }
00105
00106 void Subalbum::setName(QString val)
00107 {
00108
if(
name != val)
00109 {
00110
name = val;
00111
albm->
setModified();
00112 }
00113 }
00114
00115 void Subalbum::setDescription(QString val)
00116 {
00117
if(
description != val)
00118 {
00119
description = val;
00120
albm->
setModified();
00121 }
00122 }
00123
00124 void Subalbum::setRepresentativeImage(QString imageFilename)
00125 {
00126
00127
delete smallRepresentativeImage;
00128
delete mediumRepresentativeImage;
00129
delete largeRepresentativeImage;
00130
00131
00132
if(imageFilename.isNull())
00133 {
00134
smallRepresentativeImage = NULL;
00135
largeRepresentativeImage = NULL;
00136
00137
mediumRepresentativeImage = SubalbumPreviewWidget::createSubalbumPixmap
00138 ( QString(
IMAGE_PATH)+
"miscImages/subalbum.png" );
00139 }
00140
00141
else
00142 {
00143
int imageWidth, imageHeight;
00144
getImageSize( imageFilename, imageWidth, imageHeight );
00145
00146
00147
int smallRepWidth = 0;
00148
int smallRepHeight = 0;
00149
calcScaledImageDimensions( imageWidth, imageHeight,
00150 107,
REP_IMAGE_HEIGHT,
00151 smallRepWidth, smallRepHeight);
00152 QImage thumbnailSmall;
00153
scaleImage( imageFilename, thumbnailSmall, smallRepWidth, smallRepHeight );
00154
smallRepresentativeImage =
new QPixmap( thumbnailSmall.width(), thumbnailSmall.height() );
00155
smallRepresentativeImage->convertFromImage( thumbnailSmall );
00156
00157
00158
mediumRepresentativeImage = SubalbumPreviewWidget::createSubalbumPixmap( imageFilename );
00159
00160
00161
largeRepresentativeImage =
new QPixmap( imageFilename );
00162
00163 }
00164
00165
00166
albm->
setModified();
00167 }
00168
00169 void Subalbum::setSubalbumNumber(
int newVal) {
number = newVal; }
00170 void Subalbum::resetNumLoadedPhotos() {
loadedPhotos =
numPhotos; }
00171 void Subalbum::setModified() {
albm->
setModified(); }
00172
00173 void Subalbum::addPhoto(
Photo* newPhoto)
00174 {
00175
00176 newPhoto->
setNext(NULL);
00177 newPhoto->
setPrev(NULL);
00178
00179
00180
if(
firstPhoto == NULL)
00181 {
00182
firstPhoto = newPhoto;
00183
lastPhoto = newPhoto;
00184 }
00185
00186
else
00187 {
00188
lastPhoto->
setNext(newPhoto);
00189 newPhoto->
setPrev(
lastPhoto );
00190
lastPhoto = newPhoto;
00191 }
00192
00193
numPhotos++;
00194
albm->
setModified();
00195 }
00196
00197 bool Subalbum::addPhoto(QString fileName,
bool replaceDescription,
Photo* newPhoto)
00198 {
00199
00200
if(newPhoto == NULL)
00201 newPhoto =
new Photo(
this,
getLast(),
numPhotos);
00202
00203
00204
00205
if(replaceDescription)
00206 {
00207
00208 QString desc(fileName);
00209
00210
00211 desc = desc.section( QRegExp(
"/"), -1);
00212
00213
00214
int extensionIndex = desc.findRev(
'.' );
00215
if(extensionIndex > 0 )
00216 desc.truncate(extensionIndex);
00217
00218
00219 desc = desc.replace(
'_',
' ');
00220
00221
00222 newPhoto->
setDescription( desc );
00223 }
00224
00225
00226
if(!newPhoto->
setImage(fileName,
albm->
getNextUniquePhotoID() ))
00227 {
00228
delete newPhoto;
00229
return false;
00230 }
00231
00232
00233
if(
firstPhoto == NULL)
00234 {
00235
firstPhoto = newPhoto;
00236
lastPhoto = newPhoto;
00237 }
00238
00239
else
00240 {
00241
lastPhoto->
setNext(newPhoto);
00242 newPhoto->
setPrev(
lastPhoto );
00243
lastPhoto = newPhoto;
00244 }
00245
00246
numPhotos++;
00247
albm->
setModified();
00248
return true;
00249 }
00250
00251 bool Subalbum::lazyAddPhoto(QString imageName, QString slideshowName, QString thumbnailName,
00252
Photo* newPhoto)
00253 {
00254
00255
if(!newPhoto->
setImage(imageName, slideshowName, thumbnailName))
00256 {
00257
delete newPhoto;
00258
return false;
00259 }
00260
00261
00262
if(
firstPhoto == NULL)
00263 {
00264
firstPhoto = newPhoto;
00265
lastPhoto = newPhoto;
00266 }
00267
00268
else
00269 {
00270
lastPhoto->
setNext(newPhoto);
00271 newPhoto->
setPrev(
lastPhoto );
00272
lastPhoto = newPhoto;
00273 }
00274
00275
numPhotos++;
00276
albm->
setModified();
00277
return true;
00278 }
00279
00280 void Subalbum::removePhoto(
Photo* val)
00281 {
00282
00283
if(val == NULL)
return;
00284
00285
00286
if( val ==
firstPhoto )
firstPhoto = val->
getNext();
00287
if( val ==
lastPhoto )
lastPhoto = val->
getPrev();
00288
00289
00290
if( val->
getPrev() != NULL ) val->
getPrev()->
setNext( val->
getNext() );
00291
if( val->
getNext() != NULL ) val->
getNext()->
setPrev( val->
getPrev() );
00292
00293
00294
delete val;
00295 val = NULL;
00296
numPhotos--;
00297
albm->
setModified();
00298 }
00299
00300 void Subalbum::setPrev(
Subalbum* val)
00301 {
00302
prevSubalbum = val;
00303
albm->
setModified();
00304 }
00305
00306 void Subalbum::setNext(
Subalbum* val)
00307 {
00308
nextSubalbum = val;
00309
albm->
setModified();
00310 }
00311
00312 void Subalbum::exportToXML(
StatusWidget*, QTextStream& stream)
00313 {
00314
00315 stream <<
" <subalbum>\n";
00316
00317
00318
if(
getRepresentativeImage(
LARGE) != NULL )
00319 {
00320 stream <<
" <thumb path=\"img/" <<
number <<
"_thumb.jpg\"/>\n";
00321 stream <<
" <name>" <<
fixXMLString(
name) <<
"</name>\n";
00322 }
00323
00324
00325
else
00326 {
00327 QString strippedName =
fixXMLString(
name);
00328
if(strippedName.stripWhiteSpace() ==
"")
00329 stream << QString(
" <name>%1 %2</name>\n").arg(qApp->translate(
"Subalbum",
"Collection")).arg(
number);
00330
else
00331 stream <<
" <name>" <<
fixXMLString(
name) <<
"</name>\n";
00332 }
00333
00334 stream <<
" <description>" <<
fixXMLString(
description) <<
"</description>\n";
00335
00336
00337
Photo* current =
firstPhoto;
00338
while(current != NULL)
00339 {
00340 current->
exportToXML(stream);
00341 current = current->
getNext();
00342 }
00343
00344
00345 stream <<
" </subalbum>\n";
00346
00347 }
00348
00349 void Subalbum::importFromDisk(QDomNode* root,
00350
int subalbumNum,
00351
StatusWidget* status,
00352 QString dirName,
00353
bool disableCheckPhotoMods)
00354 {
00355
00356 QString repName = QString(dirName +
"/img/%1_thumb.jpg").arg(subalbumNum);
00357 QImage repImage(repName);
00358
if(!repImage.isNull())
00359 {
00360
setRepresentativeImage(repName);
00361 }
00362
00363 QDomNode node = root->firstChild();
00364 QDomText val;
00365
int photoNum = 0;
00366
while( !node.isNull() )
00367 {
00368
00369
00370
if( node.isElement() && node.nodeName() ==
"name" )
00371 {
00372 val = node.firstChild().toText();
00373
if(!val.isNull())
00374
name = val.nodeValue();
00375
name.replace(
"\\"",
"\"");
00376 }
00377
00378
00379
else if( node.isElement() && node.nodeName() ==
"description" )
00380 {
00381 val = node.firstChild().toText();
00382
if(!val.isNull())
00383
description = val.nodeValue();
00384
description.replace(
"\\"",
"\"");
00385 }
00386
00387
00388
else if( node.isElement() && node.nodeName() ==
"photo" )
00389 {
00390
00391 photoNum++;
00392
00393
00394 QString imageName = QString(dirName +
"img/%1/%2.jpg").arg(subalbumNum).arg(photoNum);
00395 QString slideshowName = QString(dirName +
"img/%1/%2_slideshow.jpg").arg(subalbumNum).arg(photoNum);
00396 QString thumbName = QString(dirName +
"img/%1/%2_thumb.jpg").arg(subalbumNum).arg(photoNum);
00397
Photo* newPhoto =
new Photo(
this,
getLast(), photoNum);
00398
00399
00400 QDateTime* modificationTimes = newPhoto->
importFromDisk( &node );
00401
00402
00403
bool lazyLoad =
true;
00404
00405
00406
if(!disableCheckPhotoMods)
00407 {
00408 QFileInfo info[3];
00409 info[0].setFile( imageName );
00410 info[1].setFile( slideshowName );
00411 info[2].setFile( thumbName );
00412
if(
00413 modificationTimes[0] != info[0].lastModified() ||
00414 modificationTimes[1] != info[1].lastModified() ||
00415 modificationTimes[2] != info[2].lastModified()
00416 )
00417 lazyLoad =
false;
00418 }
00419
00420
00421
00422
00423 std::ifstream imageFile ( QFile::encodeName(imageName) );
00424 std::ifstream slideshowFile( QFile::encodeName(slideshowName) );
00425 std::ifstream thumbnailFile( QFile::encodeName(thumbName) );
00426
00427
if( imageFile.is_open() &&
00428 thumbnailFile.is_open() &&
00429 slideshowFile.is_open() &&
00430 (
00431 lazyLoad ||
00432 (
00433
getMD5(imageFile) == newPhoto->
getImageChecksum() &&
00434
getMD5(slideshowFile) == newPhoto->
getSlideshowChecksum() &&
00435
getMD5(thumbnailFile) == newPhoto->
getThumbnailChecksum()
00436 )
00437 )
00438 )
00439 {
00440
00441 imageFile.close();
00442 slideshowFile.close();
00443 thumbnailFile.close();
00444
00445
00446
lazyAddPhoto(imageName, slideshowName, thumbName, newPhoto);
00447 }
00448
00449
else
00450 {
00451
00452
if(imageFile.is_open())
00453 imageFile.close();
00454
if(thumbnailFile.is_open())
00455 thumbnailFile.close();
00456
00457
00458
addPhoto(imageName,
false, newPhoto);
00459 }
00460
00461
if(imageFile.is_open())
00462 imageFile.close();
00463
if(slideshowFile.is_open())
00464 slideshowFile.close();
00465
if(thumbnailFile.is_open())
00466 thumbnailFile.close();
00467
00468
00469
status->
incrementProgress();
00470 qApp->processEvents();
00471 }
00472
00473
00474 node = node.nextSibling();
00475
00476 }
00477
00478
00479
resetNumLoadedPhotos();
00480
00481 }
00482
00483 void Subalbum::photoMoved(
Photo* val)
00484 {
00485
00486
if(val == NULL)
return;
00487
00488
00489
if(val ==
firstPhoto)
firstPhoto = val->
getNext();
00490
if(val ==
lastPhoto)
lastPhoto = val->
getPrev();
00491
00492
00493
if(val->
getPrev() != NULL) val->
getPrev()->
setNext( val->
getNext() );
00494
if(val->
getNext() != NULL) val->
getNext()->
setPrev( val->
getPrev() );
00495
00496
numPhotos--;
00497
albm->
setModified();
00498 }
00499
00500 void Subalbum::syncPhotoList(
PhotoPreviewWidget* item)
00501 {
00502
00503
if(item == NULL)
00504 {
00505
firstPhoto = NULL;
00506
lastPhoto = NULL;
00507
return;
00508 }
00509
00510
00511
firstPhoto = item->
getPhoto();
00512
firstPhoto->
setNext(NULL);
00513
firstPhoto->
setPrev(NULL);
00514
lastPhoto =
firstPhoto;
00515
00516
00517
while(item->nextItem() != NULL)
00518 {
00519 item->
getPhoto()->
setNext( ((
PhotoPreviewWidget*)item->nextItem())->getPhoto() );
00520 item->
getPhoto()->
getNext()->
setPrev( item->
getPhoto() );
00521 item = (
PhotoPreviewWidget*)item->nextItem();
00522
lastPhoto = item->
getPhoto();
00523
lastPhoto->
setNext(NULL);
00524 }
00525
00526 }
00527