album.cpp

Go to the documentation of this file.
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 <qimage.h>
00013 #include <qpixmap.h>
00014 #include <qstring.h>
00015 #include <qstringlist.h>
00016 #include <time.h>
00017 #include <qfile.h>
00018 #include <qfileinfo.h>
00019 #include <qtextstream.h>
00020 #include <qdom.h>
00021 #include <qdir.h>
00022 #include <qapplication.h>
00023 #include <qregexp.h>
00024 #include <qdatetime.h>
00025 #include <math.h>
00026 
00027 //Projectwide includes
00028 #include "album.h"
00029 #include "subalbum.h"
00030 #include "photo.h"
00031 #include "tools/imageTools.h"
00032 #include "tools/fileTools.h"
00033 #include "tools/md5.h"
00034 #include "tools/xmlTools.h"
00035 #include "../config.h"
00036 #include "../gui/subalbumPreviewWidget.h"
00037 #include "../gui/statusWidget.h"
00038 
00039 //==============================================
00041 Album::Album( QString tmpDir, bool createSubalbum )
00042 {
00043   //set strings to default values
00044   name = "";
00045   description ="";
00046   author = ""; 
00047   theme = "Slick";
00048   this->tmpDir = tmpDir;
00049 
00050   //by default no representative image
00051   smallRepresentativeImage = NULL;
00052   largeRepresentativeImage = NULL;
00053 
00054   //no Subalbums by default
00055   firstSubalbum = NULL;
00056   lastSubalbum = NULL;
00057 
00058   //set the creation/modification date to today
00059   updateCreationDate();
00060   updateModificationDate();
00061 
00062   //no subalbums
00063   numSubalbums = 0;
00064   numLoadedSubalbums = 0;
00065 
00066   //not previously saved by default
00067   savedToDisk = false;
00068 
00069   //set default save location (where images are placed before saving) to the tmp directory
00070   saveLocation = getTmpDir();
00071 
00072   if(createSubalbum)
00073   {
00074     Subalbum* s = new Subalbum( this, 1 );
00075     appendSubalbum( s );
00076   }
00077   
00078   //no interesting modifications yet
00079   modified = false;
00080 
00081   nextUniqueID = 0;
00082 }
00083 //==============================================
00084 Album::~Album()
00085 {
00086   //delete representative image
00087   delete smallRepresentativeImage;
00088   delete largeRepresentativeImage;
00089 
00090   //delete subalbums
00091   Subalbum* current = firstSubalbum;
00092   Subalbum* temp;
00093   while(current != NULL)
00094   {
00095     temp = current->getNext();
00096     delete current;
00097     current = temp;
00098   }
00099 
00100   //remove all old tmp dir contents and directory itself
00101   if(!tmpDir.isNull())
00102   {
00103     QDir oldTmpDir(tmpDir);
00104     QString tmpDirName = oldTmpDir.dirName();
00105     QStringList strLst = oldTmpDir.entryList();
00106     QStringList::iterator it;
00107     for(it = strLst.begin(); it != strLst.end(); it++)
00108     {
00109       oldTmpDir.remove(tmpDir + "/" + *it);
00110     }
00111     oldTmpDir.cdUp();
00112     oldTmpDir.rmdir( tmpDirName );
00113   }
00114 }
00115 //==============================================
00116 int Album::getModificationYear()  { return modificationYear;     }
00117 int Album::getModificationMonth() { return modificationMonth;    }
00118 int Album::getModificationDay()   { return modificationDay;      }
00119 
00120 int Album::getCreationYear()      { return creationYear;         }
00121 int Album::getCreationMonth()     { return creationMonth;        }
00122 int Album::getCreationDay()       { return creationDay;          }
00123 
00124 QString Album::getName()          { return QString(name);        }
00125 QString Album::getDescription()   { return QString(description); }
00126 QString Album::getAuthor()        { return QString(author);      }
00127 //==============================================
00128 QPixmap* Album::getRepresentativeImage(int size)
00129 {
00130   if(size == SMALL)      return smallRepresentativeImage;
00131   else if(size == LARGE) return largeRepresentativeImage;
00132   else                   return NULL;
00133 }
00134 //==============================================
00135 Subalbum* Album::getFirstSubalbum() { return firstSubalbum; }
00136 Subalbum* Album::getLastSubalbum()  { return lastSubalbum;  }
00137 //==============================================
00138 bool Album::prevSave()      { return savedToDisk; }
00139 bool Album::albumModified() { return modified;    }
00140 //==============================================
00141 QString Album::getSaveLocation() { return saveLocation; }
00142 QString Album::getTmpDir()       { return tmpDir;       }
00143 QString Album::getTheme()        { return theme;        }
00144 int Album::getNumSubalbums()     { return numSubalbums; }
00145 //==============================================
00146 int Album::getNumPhotos()
00147 {
00148   //compute number of photos and size on disk
00149   int numPhotos = 0;
00150   Subalbum* curr = firstSubalbum;
00151   while(curr != NULL)
00152   {
00153     numPhotos+= curr->getNumPhotos();
00154     curr = curr->getNext();
00155   }
00156   return numPhotos; 
00157 }
00158 //==============================================
00159 void Album::setName(QString val)
00160 {
00161   if(name != val)
00162   {
00163     name = val;
00164     modified = true;
00165   }
00166 }
00167 //==============================================
00168 void Album::setDescription(QString val)
00169 {
00170   if(description != val)
00171   {
00172     description = val;
00173     modified = true;
00174   }
00175 }
00176 //==============================================
00177 void Album::setAuthor(QString val)
00178 {
00179   if(author != val)
00180   {
00181     author = val;
00182     modified = true;
00183   }
00184 }
00185 //==============================================
00186 void Album::setRepresentativeImages(QString imageFilename)
00187 {
00188   //delete representative images
00189   delete smallRepresentativeImage;
00190   delete largeRepresentativeImage;
00191 
00192   //if being set to null, set back to defaults
00193   if(imageFilename.isNull())
00194   {
00195     smallRepresentativeImage = NULL;
00196     largeRepresentativeImage = NULL;
00197   }
00198   else
00199   {
00200     //compute representative image sizes
00201     int imageWidth, imageHeight;
00202     getImageSize( imageFilename, imageWidth, imageHeight );
00203     
00204     int smallRepWidth = 0;
00205     int smallRepHeight = 0;
00206     int largeRepWidth = 0;
00207     int largeRepHeight = 0;
00208     calcScaledImageDimensions( imageWidth, imageHeight,
00209                                107, REP_IMAGE_HEIGHT,
00210                                smallRepWidth, smallRepHeight);
00211     calcScaledImageDimensions( imageWidth, imageHeight,
00212                                500, 320,
00213                                largeRepWidth, largeRepHeight);
00214 
00215     //create various representative images
00216 
00217     //copy and scale small version
00218     QImage thumbnailSmall;
00219     scaleImage( imageFilename, thumbnailSmall, smallRepWidth, smallRepHeight );
00220     smallRepresentativeImage = new QPixmap( thumbnailSmall.width(), thumbnailSmall.height() );
00221     smallRepresentativeImage->convertFromImage( thumbnailSmall );
00222 
00223     //copy and scale large version
00224     QImage thumbnailLarge;
00225     scaleImage( imageFilename, thumbnailLarge, largeRepWidth, largeRepHeight );
00226     largeRepresentativeImage = new QPixmap( thumbnailLarge.width(), thumbnailLarge.height() );
00227     largeRepresentativeImage->convertFromImage( thumbnailLarge );
00228   }
00229 
00230   //set modified
00231   modified = true;
00232 }
00233 //==============================================
00234 void Album::appendSubalbum(Subalbum* val)
00235 {
00236   //if passed a null pointer bail!
00237   if( val == NULL) return;
00238 
00239   //empty list - stick on front
00240   if(firstSubalbum == NULL)
00241   {
00242     firstSubalbum = val;
00243     lastSubalbum = val;
00244   }
00245   //else - append to end
00246   else
00247   {
00248     lastSubalbum->setNext( val );
00249     val->setPrev( lastSubalbum );
00250     lastSubalbum = val;
00251   }
00252 
00253   numSubalbums++;
00254   modified = true;
00255 }
00256 //==============================================
00257 void Album::removeSubalbum(Subalbum* val)
00258 {
00259   //if passed a null pointer bail!
00260   if( val == NULL) return;
00261   
00262   //reset head and tail pointers if necessary
00263   if( val == firstSubalbum ) firstSubalbum = val->getNext();
00264   if( val == lastSubalbum )  lastSubalbum  = val->getPrev();
00265   
00266   //split out
00267   if( val->getPrev() != NULL ) val->getPrev()->setNext( val->getNext() );
00268   if( val->getNext() != NULL ) val->getNext()->setPrev( val->getPrev() );
00269   
00270   //delete object
00271   delete val;
00272   val = NULL;
00273   numSubalbums--;
00274   modified = true;
00275 }
00276 //==============================================
00277 void Album::updateCreationDate()
00278 {
00279   //set creation date to today
00280   QDate date    = QDate::currentDate();
00281   creationYear  = date.year();
00282   creationMonth = date.month();
00283   creationDay   = date.day();
00284 }
00285 //==============================================
00286 void Album::updateModificationDate()
00287 {
00288   //set last modification date to today
00289   QDate date        = QDate::currentDate();
00290   modificationYear  = date.year();
00291   modificationMonth = date.month();
00292   modificationDay   = date.day();
00293 }
00294 //==============================================
00295 int Album::importFromDisk(StatusWidget* status, QString fileName, bool disableCheckPhotoMods)
00296 {
00297   //update file
00298   updateXML( QFileInfo(fileName).dirPath(TRUE) );
00299 
00300   //open file
00301   QFile albumFile( fileName );
00302 
00303   //unable to open xml file? alert user
00304   if( !albumFile.open( IO_ReadOnly ) )
00305     return ALBUM_READ_ERROR;
00306 
00307   //parse dom
00308   QDomDocument albumDom;
00309   if( !albumDom.setContent( &albumFile ) )
00310     return ALBUM_XML_ERROR;
00311 
00312   //close file
00313   albumFile.close();
00314 
00315   //get main directory all other files and subdirectories are in
00316   QString rootDir = QFileInfo(albumFile).dirPath(TRUE);
00317   saveLocation = rootDir + "/img";
00318 
00319   //if representative image exists load
00320   QImage repImage(rootDir + "/img/album.jpg");
00321   if(!repImage.isNull())
00322   {
00323     setRepresentativeImages( rootDir + "/img/album.jpg");
00324   }
00325 
00326   //count number of photos in album, needed for showing loading progress
00327   int numPhotos = 0;
00328   QDomElement root = albumDom.documentElement();
00329   QDomNode node = root.firstChild();
00330   while( !node.isNull() )
00331   {
00332     if( node.isElement() && node.nodeName() == "subalbum" )
00333     {
00334       QDomNode childNode = node.firstChild();
00335       while( !childNode.isNull() )
00336       {
00337         if( childNode.isElement() && childNode.nodeName() == "photo" )
00338           numPhotos++;
00339         childNode = childNode.nextSibling();
00340       }
00341     }
00342     node = node.nextSibling();
00343   }
00344 
00345   //setup progress bar
00346   status->showProgressBar( StatusWidget::tr("Loading:"), numPhotos );
00347   qApp->processEvents();
00348 
00349   int subalbumNum = 0;
00350 
00351   //get root node and start parsing DOM
00352   root = albumDom.documentElement();
00353   node = root.firstChild();
00354   QDomText val;
00355   while( !node.isNull() )
00356   {
00357     //------------------------------------------------------------
00358     //album name
00359     if( node.isElement() && node.nodeName() == "name" )
00360     {
00361       val = node.firstChild().toText();
00362       if(!val.isNull())
00363         name = val.nodeValue();
00364      name.replace("\\&quot;","\"");
00365     }
00366     //------------------------------------------------------------
00367     //album description
00368     else if( node.isElement() && node.nodeName() == "description" )
00369     {
00370       val = node.firstChild().toText();
00371       if(!val.isNull())
00372         description = val.nodeValue();
00373      description.replace("\\&quot;","\"");
00374     }
00375     //------------------------------------------------------------
00376     //album author
00377     else if( node.isElement() && node.nodeName() == "author" )
00378     {
00379       val = node.firstChild().toText();
00380       if(!val.isNull())
00381         author = val.nodeValue();
00382      author.replace("\\&quot;","\"");
00383     }
00384     //------------------------------------------------------------
00385     //album theme
00386     else if( node.isElement() && node.nodeName() == "theme" )
00387     {
00388       val = node.firstChild().toText();
00389       if(!val.isNull())
00390         theme = val.nodeValue();
00391      theme.replace("\\&quot;","\"");
00392     }
00393     //------------------------------------------------------------
00394     //album creation date
00395     else if( node.isElement() && node.nodeName() == "created" )
00396     {
00397       val = node.firstChild().toText();
00398 
00399       //split value based on spaces, should be 7 fields
00400       QStringList vals = QStringList::split( QRegExp(" "), val.nodeValue() );
00401       int i=0;
00402       int intVals[3];
00403       QStringList::Iterator it;
00404       for ( it = vals.begin(); it != vals.end(); ++it )
00405       {
00406         intVals[i] = QString(*it).toInt();
00407         i++;
00408         //only read first 3 entires, year/month/day, don't overwrite
00409         //buffer on addition entries if xml messed up
00410         if(i > 2)
00411           break;
00412       }
00413       creationYear = intVals[0];
00414       creationMonth = intVals[1];
00415       creationDay = intVals[2];
00416     }
00417     //------------------------------------------------------------
00418     //subalbum
00419     else if( node.isElement() && node.nodeName() == "subalbum" )
00420     {
00421       //increase counter
00422       subalbumNum++;
00423 
00424       //create new subalbum
00425       Subalbum* salbum = new Subalbum(this, numSubalbums+1);
00426 
00427       //populate it
00428       salbum->importFromDisk( &node, subalbumNum, status, (rootDir + "/"), disableCheckPhotoMods );
00429 
00430       //append it to list of subalbums
00431       appendSubalbum(salbum);
00432     }
00433     //------------------------------------------------------------
00434     //advance to next node
00435     node = node.nextSibling();
00436     //------------------------------------------------------------
00437   }
00438 
00439   //reset number of loaded subalbums
00440   numLoadedSubalbums = numSubalbums;
00441 
00442   //hide progress bar
00443   status->setStatus( qApp->translate("Album", "Album loaded.") );
00444 
00445   //save load directory name and loaded/saved bit
00446   saveLocation = rootDir;
00447   savedToDisk = true;
00448 
00449   return ALBUM_LOADED;
00450 }
00451 //==============================================
00452 int Album::exportToDisk(StatusWidget* status, QString dirName, QString themeName)
00453 {
00454   //check to see if save location has actually changed, if not don't force save images
00455   //this occurs when user blindly selects the same old spot, or is just changing the theme used by default
00456   bool forceSave = true;
00457 
00458   if(saveLocation == dirName)
00459     forceSave = false;
00460 
00461   //backup theme and save location, if save fails revert to previous values
00462   oldSaveLocation = saveLocation;
00463   QString oldTheme = theme;
00464 
00465   //attempt to save album
00466   saveLocation = dirName;
00467   theme = themeName;
00468   int result = exportToDisk(status, forceSave);
00469 
00470   //if album saving failed revert save location and theme
00471   if(result != ALBUM_EXPORTED)
00472   {
00473     saveLocation = oldSaveLocation;
00474     theme = oldTheme;
00475   }
00476   //else update tmp save dir
00477   else
00478   {
00479     //remove all old tmp dir contents and directory itself
00480     QDir oldTmpDir(tmpDir);
00481     QString tmpDirName = oldTmpDir.dirName();
00482     QStringList strLst = oldTmpDir.entryList();
00483     QStringList::iterator it;
00484     for(it = strLst.begin(); it != strLst.end(); it++)
00485     {
00486       oldTmpDir.remove( tmpDir + "/" + *it);
00487     }
00488 
00489     oldTmpDir.cdUp();
00490     oldTmpDir.rmdir( tmpDirName );
00491 
00492     //create and set new temp dir location
00493     QDir saveDir( saveLocation );
00494     if(!saveDir.exists( "tmp" ))
00495       saveDir.mkdir( "tmp" );
00496     tmpDir = saveLocation + "/tmp";
00497     
00498     //reset unique id counter
00499     nextUniqueID = 0;
00500   }
00501 
00502   //return result
00503   return result;
00504 }
00505 //==============================================
00506 int Album::exportToDisk(StatusWidget* status, bool forceSave)
00507 {
00508   //------------------------------------------
00509   //create subdirs
00510   QDir localDir(saveLocation);
00511   //img dirs
00512   localDir.mkdir("img");
00513   //subalbum dirs
00514   localDir.setPath(saveLocation + "/img");
00515 
00516   //make a temporary 0 directory for copying new images, they'll be moved to their final
00517   //location during the reordering step
00518   localDir.mkdir( "0" );
00519   
00520   //iterate over each subalbum and create its image directory
00521   Subalbum* current = firstSubalbum;  
00522   int collectionNum = 0;
00523   while(current != NULL)
00524   {
00525     collectionNum++;
00526     QString dirName = QString("%1") .arg( collectionNum );
00527     localDir.mkdir(dirName);
00528     current = current->getNext();
00529   }
00530   //------------------------------------------
00531   //checks worked, go ahead with export
00532 
00533   //count number of photos
00534   int totalPhotos=0;
00535   current = firstSubalbum;
00536   while(current != NULL)
00537   {
00538     totalPhotos+=current->getNumPhotos();
00539     current = current->getNext();
00540   }
00541 
00542   //setup progress bar
00543   status->showProgressBar( StatusWidget::tr("Saving:"), 4*totalPhotos );
00544   qApp->processEvents();
00545 
00546   //copy over theme resources
00547   exportThemeResources( theme );
00548 
00549   //export album cover image, subalbum thumbnails
00550   exportTopLevelImages();
00551 
00552   //export subalbum images (thumbnail, slideshow, and full versions of all images)
00553   exportSubalbumImages(status, forceSave);
00554 
00555   //remove any _orig images for photos which have been reverted to their original form
00556   removeStagnantOrigFiles(status);
00557   
00558   //apply reordering to all images
00559   reorderSubalbumImages(status);
00560 
00561   //reset subalbum numbers to current ordering
00562   current = firstSubalbum;
00563   int n=0;
00564   while(current !=NULL)
00565   {
00566     n++;
00567     current->setSubalbumNumber(n);
00568     current = current->getNext();
00569   }
00570 
00571   //remove collection 0 directory
00572   QDir rootDir(saveLocation + "/img/");
00573   rootDir.rmdir( "0" );
00574   
00575   //remove old images that nolonger belong
00576   removeStagnantImages();
00577 
00578   //remove previous html/htm files
00579   localDir.setPath(saveLocation);
00580   QStringList list = localDir.entryList( QDir::Files );
00581   QStringList::Iterator file;
00582   for ( file = list.begin(); file != list.end(); ++file )
00583   {
00584     if( (*file).endsWith(".html") || (*file).endsWith(".htm") )
00585       localDir.remove( saveLocation + "/" + *file );
00586   }
00587 
00588   //export xml structure of album
00589   int result = exportToXML(status, saveLocation);
00590   if(result != ALBUM_EXPORTED) { return result; }
00591 
00592   //export various html pages using selected theme
00593   transformXMLtoHTML( saveLocation, theme, false );
00594 
00595   //------------------------------------------
00596   //remove files from temp folder
00597   QDir tmpDirHandle( getTmpDir() );
00598   QStringList strLst = tmpDirHandle.entryList();
00599   QStringList::iterator it;
00600   for(it = strLst.begin(); it != strLst.end(); it++)
00601   {
00602     tmpDirHandle.remove( getTmpDir() + "/" + *it);
00603   }
00604   //------------------------------------------
00605   savedToDisk = true;
00606 
00607   //just saved so no modifications since last save
00608   modified = false;
00609 
00610   //hide progress bar
00611   status->setStatus( qApp->translate("Album", "Album saved.") );
00612   //------------------------------------------
00613   return ALBUM_EXPORTED;
00614 }
00615 //==============================================
00616 int Album::exportCompressedWebAlbum(StatusWidget* status, 
00617                                     QString exportLocation, 
00618                                     QString exportMessage)
00619 {
00620   //------------------------------------------
00621   //copy all images
00622   QDir localDir(exportLocation);
00623   localDir.mkdir("img");
00624   localDir.setPath(exportLocation + "/img");
00625   
00626   //copy album image
00627   if(getRepresentativeImage(LARGE) != NULL)
00628   { getRepresentativeImage(LARGE)->save(exportLocation + "/img/album.jpg", "JPEG", 95); }
00629   else
00630   { localDir.remove(exportLocation + "/img/album.jpg"); }
00631     
00632   int numPhotos = getNumPhotos();  
00633   int photosLeft = numPhotos;  
00634   int updateInverval = numPhotos / 50;
00635   int updateCount = 0;
00636   
00637   //iterate over each collection
00638   Subalbum* curCollection = firstSubalbum;
00639   int collectionNum=1;
00640   while(curCollection != NULL)
00641   {
00642     QString collectionDir = QString("%1").arg( collectionNum );
00643     localDir.mkdir( collectionDir );
00644 
00645     //copy collection image
00646     QString collectionThumbFilename = QString(exportLocation + "/img/%1_thumb.jpg" ).arg(collectionNum);
00647     if(curCollection->getRepresentativeImage(LARGE) != NULL )
00648     { curCollection->getRepresentativeImage(LARGE)->save( collectionThumbFilename, "JPEG", 95); }
00649     else
00650     { localDir.remove( collectionThumbFilename ); }
00651     
00652     //copy each photo
00653     Photo* curPhoto = curCollection->getFirst();
00654     int photoNum = 1;
00655     while(curPhoto != NULL)
00656     {
00657       //update status message
00658       status->updateProgress( numPhotos - photosLeft, exportMessage.arg( photosLeft ) );
00659       
00660       //make sure events are processed every 2% of the photos that are processes
00661       updateCount++;
00662       if(updateCount > updateInverval)
00663       {
00664         updateCount = 0;
00665         qApp->processEvents();        
00666       }      
00667       
00668       //copy files
00669       QString newFilePath = QDir::convertSeparators( exportLocation + "/img/" + 
00670                                                      collectionDir + "/" + 
00671                                                      QString("%1").arg(photoNum) );
00672 
00673       copyFile( curPhoto->getSlideshowFilename(), newFilePath + "_slideshow.jpg" );
00674       copyFile( curPhoto->getThumbnailFilename(), newFilePath + "_thumb.jpg" );
00675       
00676       curPhoto = curPhoto->getNext();
00677       photoNum++;
00678       photosLeft--;
00679     }
00680     
00681     curCollection = curCollection->getNext();
00682     collectionNum++;
00683   }
00684   //------------------------------------------
00685   //copy theme resources
00686   QStringList fileList;
00687   QStringList::Iterator file;
00688   
00689   //create HTML and misc resources directories
00690   localDir.setPath(exportLocation);
00691   localDir.mkdir("resources");
00692   
00693   //remove all files in these directories from previous saves with other themes
00694   localDir.setPath(exportLocation + "/resources");
00695   fileList = localDir.entryList( QDir::Files );
00696   for ( file = fileList.begin(); file != fileList.end(); ++file )
00697   { localDir.remove( exportLocation + "/resources/" + *file ); }
00698   
00699   //copy files over from theme's directory
00700   localDir.setPath(THEMES_PATH + theme + "/resources");
00701   fileList = localDir.entryList( QDir::Files );
00702   for ( file = fileList.begin(); file != fileList.end(); ++file )
00703   { copyFile( THEMES_PATH + theme + "/resources/" + *file, exportLocation + "/resources/" + *file); }
00704   //------------------------------------------
00705   //export xml file
00706   exportToXML(status, exportLocation);
00707   //------------------------------------------  
00708   //remove previous html/htm files
00709   localDir.setPath(exportLocation);
00710   fileList = localDir.entryList( QDir::Files );
00711   for ( file = fileList.begin(); file != fileList.end(); ++file )
00712   {
00713     if( (*file).endsWith(".html") || (*file).endsWith(".htm") )
00714       localDir.remove( exportLocation + "/" + *file );
00715   }
00716   //------------------------------------------
00717   //construct html files
00718   transformXMLtoHTML( exportLocation, theme, true );
00719   //------------------------------------------
00720   //remove xml file
00721   localDir.remove( exportLocation + "/Album.xml" );  
00722   //------------------------------------------
00723   return ALBUM_EXPORTED;
00724 }
00725 //==============================================
00726 int Album::exportLargeImages(StatusWidget* status, QString exportPath, QString exportMessage)
00727 {
00728   //determine number of digits collecion # requires
00729   uint collectionDigits = (uint) (1 + log( (double) getNumSubalbums() ) / log( 10.0 ) );
00730   
00731   //determine number of digits photo # requires, this
00732   //involves walking through the album and finding the collection with the most phots first
00733   int mostPhotos = 0;  
00734   Subalbum* curCollection = getFirstSubalbum();
00735   while(curCollection != NULL )
00736   {
00737     mostPhotos = QMAX( mostPhotos, curCollection->getNumPhotos() );
00738     curCollection = curCollection->getNext(); 
00739   }
00740   uint photoDigits = (uint) ( 1 + log( (double) mostPhotos ) / log( 10.0 ) );   
00741   //------------
00742   //copy files  
00743   int numPhotos = getNumPhotos();  
00744   int photosLeft = numPhotos;  
00745   
00746   int collectionNum = 1;
00747   curCollection = getFirstSubalbum();
00748   
00749   int updateInverval = numPhotos / 50;
00750   int updateCount = 0;
00751   
00752   while(curCollection != NULL )
00753   {
00754     //construct collection string
00755     QString collectionString = QString("%1").arg(collectionNum);
00756     while(collectionString.length() < collectionDigits)
00757     { collectionString = "0" + collectionString; }  
00758     
00759     //copy all photos in collection
00760     int photoNum = 1;
00761     Photo* curPhoto = curCollection->getFirst();
00762     while(curPhoto != NULL)
00763     {
00764       //update status message
00765       status->updateProgress( numPhotos - photosLeft, exportMessage.arg( photosLeft ) );
00766       
00767       //make sure events are processed every 2% of the photos that are processes
00768       updateCount++;
00769       if(updateCount > updateInverval)
00770       {
00771         updateCount = 0;
00772         qApp->processEvents();        
00773       }
00774 
00775       //construct photo string
00776       QString photoString = QString("%1").arg(photoNum);
00777       while(photoString.length() < photoDigits)
00778       { photoString = "0" + photoString; }  
00779       
00780       //construct new photo path
00781       QString newFilePath = QDir::convertSeparators( exportPath + "/" + collectionString + 
00782                                                      "_" + photoString + ".jpg" );
00783       //copy file
00784       copyFile( curPhoto->getImageFilename(), newFilePath );
00785       
00786       //move on to next file
00787       photosLeft--;
00788       curPhoto = curPhoto->getNext();
00789       photoNum++;
00790       
00791     } //while photo
00792     
00793     //move on to next collection
00794     curCollection = curCollection->getNext();
00795     collectionNum++;    
00796   }// while collection
00797    //------------
00798   return ALBUM_EXPORTED;
00799 }
00800 //==============================================
00801 int Album::exportToXML(StatusWidget* status, QString exportPath)
00802 {
00803   //update modification date
00804   updateModificationDate();
00805 
00806   //create/open xml file
00807   QFile file( exportPath + "/Album.xml" );
00808   if(file.open(IO_WriteOnly))
00809   {
00810     //-----
00811     QTextStream stream;
00812     stream.setDevice( &file );
00813     stream.setEncoding( QTextStream::UnicodeUTF8 );
00814     
00815     //write album information
00816     stream << "<?xml version=\"1.0\"?>\n";
00817     stream << "<album version=\"1.1\">\n";
00818     stream << "  <name>" << fixXMLString(name) << "</name>\n";
00819     stream << "  <description>" << fixXMLString(description) << "</description>\n";
00820     stream << "  <author>" << fixXMLString(author) << "</author>\n";
00821     stream << "  <created>" << creationYear << " " << creationMonth << " " << creationDay << "</created>\n";
00822     stream << "  <modified>" << modificationYear << " " << modificationMonth << " " << modificationDay << "</modified>\n";
00823     stream << "  <theme>" << theme << "</theme>\n";
00824     stream << "  <thumbnailDimensions>" << THUMBNAIL_WIDTH << " " << THUMBNAIL_HEIGHT << "</thumbnailDimensions>\n";
00825     stream << "  <slideshowDimensions>" << SLIDESHOW_WIDTH << " " << SLIDESHOW_HEIGHT << "</slideshowDimensions>\n";
00826 
00827     //if album has a represenatative image save it's path
00828     if(getRepresentativeImage(LARGE) != NULL )
00829     {
00830       stream << "  <thumb path=\"img/album.jpg\"/>\n";
00831     }
00832 
00833     //write subalbums
00834     Subalbum* current = firstSubalbum;
00835     while(current != NULL)
00836     {
00837       current->exportToXML(status, stream);
00838       current = current->getNext();
00839     }
00840 
00841     //end album
00842     stream << "</album>\n";
00843     file.close();
00844 
00845     return ALBUM_EXPORTED;
00846   }
00847   else
00848   {
00849     return ALBUM_ERROR_OPEN_FILE;
00850   }
00851 }
00852 //==============================================
00853 void Album::exportTopLevelImages()
00854 {
00855   //if image set export it
00856   if(getRepresentativeImage(LARGE) != NULL)
00857   {
00858     getRepresentativeImage(LARGE)->save(saveLocation + "/img/album.jpg", "JPEG", 95);
00859   }
00860   //else make sure any previously set images are removed
00861   else
00862   {
00863     QDir rootDir(saveLocation + "/img/");
00864     rootDir.remove(saveLocation + "/img/album.jpg");
00865   }
00866 
00867   //export subalbum thumbs
00868   int n=0;
00869   Subalbum* current = firstSubalbum;
00870   while(current != NULL)
00871   {
00872     n++;
00873     //if subalbum has representative image export it
00874     if(current->getRepresentativeImage(LARGE) != NULL )
00875     {
00876       QString fileName = QString(saveLocation + "/img/%1_thumb.jpg" ).arg(n);
00877       current->getRepresentativeImage(LARGE)->save(fileName, "JPEG", 95);
00878     }
00879     //otherwise make sure anyprevious set images are removed
00880     else
00881     {
00882       QDir rootDir(saveLocation + "/img/");
00883       rootDir.remove( saveLocation + QString("/img/%1_thumb.jpg").arg(n) );
00884     }
00885     current = current->getNext();
00886   }
00887 }
00888 //==============================================
00889 void Album::exportSubalbumImages(StatusWidget* status, bool forceSave)
00890 {
00891   //iterate over all subalbums
00892   int subalbumNumber=0;
00893   Subalbum* currentSubalbum = firstSubalbum;
00894   while(currentSubalbum != NULL)
00895   {
00896     subalbumNumber++;
00897 
00898     //iterate over all photos in this subalbum
00899     int photoNumber=0;
00900     Photo* currentPhoto = currentSubalbum->getFirst();
00901     while(currentPhoto != NULL)
00902     {
00903       photoNumber++;
00904       //---------------------------------------
00905       //if the current photo does not need to be saved then move on
00906       if( !forceSave && !currentPhoto->getNeedsSavingVal() )
00907       {
00908         currentPhoto = currentPhoto->getNext();
00909         status->incrementProgress();
00910         qApp->processEvents();
00911         continue;
00912       }
00913       //---------------------------------------
00914       //get initial photo # and subalbum #, used for saving
00915       int initPhotoNumber = currentPhoto->getInitialPhotoNumber();
00916       int initSubalbumNumber = currentPhoto->getInitialSubalbumNumber();
00917       //---------------------------------------
00918       //export thumbnail image
00919       QString oldName = currentPhoto->getThumbnailFilename();
00920       QString newName = QString(saveLocation + "/img/%1/%2_thumb.jpg" )
00921                         .arg(initSubalbumNumber).arg(initPhotoNumber);
00922       
00923       //if file has been modified move from current location to final location
00924       if( currentPhoto->getNeedsSavingVal() ) { moveFile( oldName, newName ); }
00925       //If file has not been modified we must be doing a save-as and saving has been forced. In this case
00926       //COPY file from current location to final location, DON'T delete previous copy!!!
00927       else { copyFile(oldName, newName); }
00928 
00929       //compute and store md5 for slideshow image
00930       std::ifstream thumbnailFile( QFile::encodeName(newName) );
00931       if(thumbnailFile.is_open())
00932       {
00933         currentPhoto->setThumbnailChecksum( getMD5(thumbnailFile) );
00934         thumbnailFile.close();
00935       }
00936       //---------------------------------------
00937       //export slideshow image
00938       oldName = currentPhoto->getSlideshowFilename();
00939       newName = QString(saveLocation + "/img/%1/%2_slideshow.jpg" )
00940                         .arg(initSubalbumNumber).arg(initPhotoNumber);
00941 
00942       //if file has been modified move from current location to final location
00943       if( currentPhoto->getNeedsSavingVal() ) { moveFile( oldName, newName ); }
00944       //If file has not been modified we must be doing a save-as and saving has been forced. In this case
00945       //COPY file from current location to final location, DON'T delete previous copy!!!
00946       else { copyFile(oldName, newName); }
00947 
00948       //compute and store md5 for slideshow image
00949       std::ifstream slideshowFile( QFile::encodeName(newName) );
00950       if(slideshowFile.is_open())
00951       {
00952         currentPhoto->setSlideshowChecksum( getMD5(slideshowFile) );
00953         slideshowFile.close();
00954       }
00955       //---------------------------------------
00956       //export full size image
00957       oldName = currentPhoto->getImageFilename();
00958       newName = QString(saveLocation + "/img/%1/%2.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
00959 
00960       //if file has been modified move from current location to final location
00961       if( currentPhoto->getNeedsSavingVal() ) 
00962       {
00963         QString tempOrigName = getTmpDir() + QString("/%1_%2_orig.jpg")
00964         .arg(initSubalbumNumber).arg(initPhotoNumber);
00965                      
00966         QString finalOrigName = QString(saveLocation + "/img/%1/%2_orig.jpg" )
00967           .arg(initSubalbumNumber).arg(initPhotoNumber);
00968 
00973         QDir tmpDir;
00974         if( !currentPhoto->getRecentlyReverted() &&
00975             tmpDir.exists(newName) &&
00976             !tmpDir.exists(finalOrigName) )
00977         {
00978           moveFile( newName, finalOrigName );
00979         }      
00980         //if photo previously saved, there is no orig file, but the photo 
00981         //is modified and we're doing a force save than make sure to copy 
00982         //over the original as well even though it's not an orig file
00983         else if ( currentPhoto->getEverSaved() &&
00984                   currentPhoto->getNeedsSavingVal() &&
00985                   forceSave &&
00986                   saveLocation.compare( oldSaveLocation ) != 0 )
00987         {
00988           QString storedOrigLocation = oldSaveLocation +         
00989                                        QString("/img/%1/%2_orig.jpg").arg(currentPhoto->getInitialSubalbumNumber())
00990                                                                      .arg(currentPhoto->getInitialPhotoNumber());
00991           QString storedLocation = oldSaveLocation +         
00992                                    QString("/img/%1/%2.jpg").arg(currentPhoto->getInitialSubalbumNumber())
00993                                                             .arg(currentPhoto->getInitialPhotoNumber());
00994           
00995           if( tmpDir.exists(storedOrigLocation) )
00996             copyFile( storedOrigLocation, finalOrigName );
00997           else if( tmpDir.exists(storedLocation) )
00998             copyFile( storedLocation, finalOrigName );
00999         }
01004         else if( !currentPhoto->getRecentlyReverted() &&
01005                  !tmpDir.exists(newName) &&
01006                  tmpDir.exists(tempOrigName) )
01007         {
01008           moveFile( tempOrigName, finalOrigName );
01009         }
01010 
01012         moveFile( oldName, newName );
01013       }
01014       //If file does not need to be saved a force save is taking place. This occurs when a user chooses
01015       //save as and copies an entire album to a different location so all files must be copied. Make
01016       //sure to copy over the original form of the photo as well if this file exists
01017       else
01018       {
01019         //copy current image
01020         copyFile( oldName, newName );
01021         
01023         //if orig file exists copy it too
01024         QDir tmpDir;
01025          
01026         QString tempOrigName = getTmpDir() + QString("/%1_%2_orig.jpg")
01027            .arg(initSubalbumNumber).arg(initPhotoNumber);
01028 
01029         QString curOrigName = currentPhoto->getImageFilename();
01030         curOrigName.truncate( curOrigName.length() - 4 );
01031         curOrigName = curOrigName + "_orig.jpg";
01032 
01033         QString finalOrigName = QString(saveLocation + "/img/%1/%2_orig.jpg" )
01034            .arg(initSubalbumNumber).arg(initPhotoNumber);
01035 
01036         //if the photo was recently reverted ignore the presence of orig files
01037         if( !currentPhoto->getRecentlyReverted() )
01038         {
01039           //if the photo was never previously saved and an orig file
01040           //exists in the tmp directory make sure to copy it over
01041           if( !currentPhoto->getEverSaved() &&
01042               tmpDir.exists( tempOrigName ) )
01043           {
01044             copyFile( tempOrigName, finalOrigName );
01045           }        
01046           //if the photo was previously saved and an orig file exists
01047           //in the previous save location make sure to copy it over
01048           else if( currentPhoto->getEverSaved() &&
01049                    tmpDir.exists( curOrigName ) )
01050           {
01051             copyFile( curOrigName, finalOrigName );
01052           }        
01053         }
01055       }
01056       //---------------------------------------
01057       //compute and store md5 for image
01058       std::ifstream imageFile( QFile::encodeName(newName) );
01059       if(imageFile.is_open())
01060       {
01061         currentPhoto->setImageChecksum( getMD5(imageFile) );
01062         imageFile.close();
01063       }
01064       //---------------------------------------
01065       //set new storage locations of files
01066       currentPhoto->setImageFilename
01067         ( QString(saveLocation + "/img/%1/%2.jpg").arg(initSubalbumNumber).arg(initPhotoNumber) );
01068       
01069       currentPhoto->setSlideshowFilename
01070         ( QString(saveLocation + "/img/%1/%2_slideshow.jpg").arg(initSubalbumNumber).arg(initPhotoNumber) );
01071       
01072       currentPhoto->setThumbnailFilename
01073         ( QString(saveLocation + "/img/%1/%2_thumb.jpg").arg(initSubalbumNumber).arg(initPhotoNumber) );
01074       //---------------------------------------
01075       //set image as not needing saving and as being saved
01076       currentPhoto->setNeedsSavingVal(false);
01077       currentPhoto->setEverSaved(true);
01078       //---------------------------------------
01079       //update progress bar
01080       status->incrementProgress();
01081       qApp->processEvents();
01082       //---------------------------------------
01083       //move on to next photo in subalbum
01084       currentPhoto = currentPhoto->getNext();
01085       //---------------------------------------
01086     }
01087     //---------------------------------------
01088     //move on to next subalbum
01089     currentSubalbum = currentSubalbum->getNext();
01090   }
01091 }
01092 //==============================================
01093 void Album::removeStagnantOrigFiles(StatusWidget* status)
01094 {
01095   QDir tmpDir;
01096   
01097   //iterate over all collections
01098   Subalbum* currentSubalbum = firstSubalbum;
01099   while(currentSubalbum != NULL)
01100   {
01101     //iterate over all photos in this subalbum
01102     Photo* currentPhoto = currentSubalbum->getFirst();
01103     while(currentPhoto != NULL)
01104     {
01105       //if photo recently reverted and orig file is not the current filename remove orig file
01106       //the orig and current name will match up if a previously saved (but not modified) photo 
01107       //is modified, reverted, then saved out again
01108       if(currentPhoto->getRecentlyReverted() &&
01109          currentPhoto->getImageFilename().compare( currentPhoto->originalImageFilename() ) != 0 )
01110       {
01111         tmpDir.remove( currentPhoto->originalImageFilename() );
01112         currentPhoto->setRecentlyReverted( false );
01113       }
01114       
01115       //move on to next photo
01116       currentPhoto = currentPhoto->getNext();
01117       status->incrementProgress();
01118       qApp->processEvents();
01119     }
01120     
01121     //move on to next subalbum
01122     currentSubalbum  = currentSubalbum->getNext();
01123   }      
01124 }
01125 //==============================================
01126 void Album::reorderSubalbumImages(StatusWidget* status)
01127 {
01128   //--------------------------------------------------------
01129   //--------------------------------------------------------
01130   //first pass over all photos, those whose initial and current numbers don't match up
01131   //rename slightly so we don't overwrte them the second time around
01132   //--------------------------------------------------------
01133   //--------------------------------------------------------
01134   //iterate over all subalbums
01135   QDir tmpDir;
01136   int subalbumNumber=0;
01137   Subalbum* currentSubalbum = firstSubalbum;
01138   while(currentSubalbum != NULL)
01139   {
01140     subalbumNumber++;
01141 
01142     //iterate over all photos in this subalbum
01143     int photoNumber=0;
01144     Photo* currentPhoto = currentSubalbum->getFirst();
01145     while(currentPhoto != NULL)
01146     {
01147       photoNumber++;
01148       int initPhotoNumber    = currentPhoto->getInitialPhotoNumber();
01149       int initSubalbumNumber = currentPhoto->getInitialSubalbumNumber();
01150 
01151       //if photo has moved rename full image, orig image (if it exists), slideshow image, and thumbnail images
01152       if( initPhotoNumber != photoNumber || initSubalbumNumber != subalbumNumber)
01153       {
01154         QString oldName = QString(saveLocation + "/img/%1/%2.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01155         QString newName = QString(saveLocation + "/img/%1/%2_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01156         moveFile( oldName, newName );
01157         //-----      
01158         oldName = QString(saveLocation + "/img/%1/%2_orig.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01159         newName = QString(saveLocation + "/img/%1/%2_orig_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01160         if(tmpDir.exists(oldName) ) { moveFile( oldName, newName ); }
01161         //-----
01162         oldName = QString(saveLocation + "/img/%1/%2_slideshow.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01163         newName = QString(saveLocation + "/img/%1/%2_slideshow_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01164         moveFile( oldName, newName );
01165         //-----
01166         oldName = QString(saveLocation + "/img/%1/%2_thumb.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01167         newName = QString(saveLocation + "/img/%1/%2_thumb_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01168         moveFile( oldName, newName );
01169       }
01170       
01171       //move on to next photo
01172       currentPhoto = currentPhoto->getNext();
01173       status->incrementProgress();
01174       qApp->processEvents();
01175     }
01176 
01177     //move on to next subalbum
01178     currentSubalbum = currentSubalbum->getNext();
01179   }
01180 
01181   //--------------------------------------------------------
01182   //--------------------------------------------------------
01183   //second pass over all photos, those whose initial and current numbers don't match up
01184   //rename to their final names and reset initial photo and subalbum numbers
01185   //--------------------------------------------------------
01186   //--------------------------------------------------------
01187   //iterate over all subalbums
01188   subalbumNumber=0;
01189   currentSubalbum = firstSubalbum;
01190   while(currentSubalbum != NULL)
01191   {
01192     subalbumNumber++;
01193 
01194     //iterate over all photos in this subalbum
01195     int photoNumber=0;
01196     Photo* currentPhoto = currentSubalbum->getFirst();
01197     while(currentPhoto != NULL)
01198     {
01199       photoNumber++;
01200       int initPhotoNumber    = currentPhoto->getInitialPhotoNumber();
01201       int initSubalbumNumber = currentPhoto->getInitialSubalbumNumber();
01202       
01203       //if the current photo has moved rename full image, slideshow image, and thumbnail image to their final names
01204       if( initPhotoNumber != photoNumber || initSubalbumNumber != subalbumNumber)
01205       { 
01206         QString oldName = QString(saveLocation + "/img/%1/%2_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01207         QString newName = QString(saveLocation + "/img/%1/%2.jpg" ).arg(subalbumNumber).arg(photoNumber);
01208         moveFile( oldName, newName );
01209         //-----
01210         oldName = QString(saveLocation + "/img/%1/%2_orig_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01211         newName = QString(saveLocation + "/img/%1/%2_orig.jpg" ).arg(subalbumNumber).arg(photoNumber);
01212         if(tmpDir.exists(oldName) ) { moveFile( oldName, newName ); }
01213         //-----
01214         oldName = QString(saveLocation + "/img/%1/%2_slideshow_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01215         newName = QString(saveLocation + "/img/%1/%2_slideshow.jpg" ).arg(subalbumNumber).arg(photoNumber);
01216         moveFile( oldName, newName );
01217         //-----
01218         oldName = QString(saveLocation + "/img/%1/%2_thumb_moved.jpg" ).arg(initSubalbumNumber).arg(initPhotoNumber);
01219         newName = QString(saveLocation + "/img/%1/%2_thumb.jpg" ).arg(subalbumNumber).arg(photoNumber);
01220         moveFile( oldName, newName );
01221         //---------------------------------------
01222         //reset initial photo and subalbum numbers, and filenames
01223         currentPhoto->setInitialPhotoNumber(photoNumber);
01224         currentPhoto->setInitialSubalbumNumber(subalbumNumber);
01225         currentPhoto->setImageFilename( QString(saveLocation + "/img/%1/%2.jpg").
01226                                         arg(subalbumNumber).arg(photoNumber) );
01227         currentPhoto->setSlideshowFilename( QString(saveLocation + "/img/%1/%2_slideshow.jpg").
01228                                             arg(subalbumNumber).arg(photoNumber) );
01229         currentPhoto->setThumbnailFilename( QString(saveLocation + "/img/%1/%2_thumb.jpg").
01230                                             arg(subalbumNumber).arg(photoNumber) );
01231       }
01232       
01233       //move on to next photo
01234       currentPhoto = currentPhoto->getNext();
01235       status->incrementProgress();
01236       qApp->processEvents();
01237     }
01238 
01239     //move on to next subalbum
01240     currentSubalbum = currentSubalbum->getNext();
01241   }
01242 }
01243 //==============================================
01244 void Album::removeStagnantImages()
01245 {
01246   QDir rootDir(saveLocation + "/img/");
01247 
01248   //iterate over each collection
01249   int subalbumNumber=0;
01250   Subalbum* currentSubalbum = firstSubalbum;
01251   while(currentSubalbum != NULL)
01252   {
01253     subalbumNumber++;
01254 
01255     //remove all photos who are numbered greater
01256     //than the number of photos in the subalbum
01257     int photoNum = currentSubalbum->getNumPhotos()+1;
01258     while(true)
01259     {
01260       QString imageString     = QString(saveLocation + "/img/%1/%2.jpg").arg(subalbumNumber).arg(photoNum);
01261       QString origString      = QString(saveLocation + "/img/%1/%2_orig.jpg").arg(subalbumNumber).arg(photoNum);
01262       QString slideshowString = QString(saveLocation + "/img/%1/%2_slideshow.jpg").arg(subalbumNumber).arg(photoNum);
01263       QString thumbString     = QString(saveLocation + "/img/%1/%2_thumb.jpg").arg(subalbumNumber).arg(photoNum);
01264       
01265       //if none of the possible images exist then assume 
01266       //no more stagnant images exist in this collection
01267       //
01268       if( !rootDir.exists(imageString)     && !rootDir.exists(origString) &&
01269           !rootDir.exists(slideshowString) && !rootDir.exists(thumbString) )
01270         break;
01271       //else delete photos and move on
01272       else
01273       {
01274         rootDir.remove( imageString );
01275         rootDir.remove( origString );
01276         rootDir.remove( slideshowString );
01277         rootDir.remove( thumbString );
01278         photoNum++;
01279       }
01280     }
01281 
01282     //reset number of loaded photos since old photos removed now
01283     currentSubalbum->resetNumLoadedPhotos();
01284 
01285     //move on to next collection
01286     currentSubalbum = currentSubalbum->getNext();
01287   }
01288   //---------------------------------
01289   //remove stagnant collections and all their contents
01290   subalbumNumber = numSubalbums+1;
01291   while(true)
01292   {    
01293     //check to see if the directory exists, if not we are done
01294     QString imageDirString = QString(saveLocation + "/img/%1/").arg(subalbumNumber);
01295     if( !rootDir.exists(imageDirString) )
01296       break;
01297 
01298     //get filelist for directory
01299     QDir imageDir(  imageDirString );
01300     QStringList list = imageDir.entryList( QDir::Files );
01301 
01302     //remove each file in directory
01303     QStringList::Iterator file;
01304     for ( file = list.begin(); file != list.end(); ++file )
01305     { rootDir.remove( QString(saveLocation + "/img/%1/" + *file).arg(subalbumNumber) ); }
01306 
01307     //remove directory
01308     rootDir.rmdir( QString("%1").arg(subalbumNumber) );
01309 
01310     //remove thumbnail image
01311     rootDir.remove( QString(saveLocation + "/img/%1_thumb.jpg").arg(subalbumNumber) );
01312 
01313     //move on to next subalbum
01314     subalbumNumber++;
01315   }
01316 
01317   //reset number of loaded subalbums since stagnant directories removed now
01318   numLoadedSubalbums = numSubalbums;
01319   //---------------------------------
01320 }
01321 //==============================================
01322 void Album::exportThemeResources( QString theme )
01323 {
01324   QStringList fileList;
01325   QStringList::Iterator file;
01326   QDir localDir;
01327   
01328   //remove any "resources" directories created by 1.0* versions of Album Shaper
01329   localDir.setPath( saveLocation + "/resources" );
01330   fileList = localDir.entryList();
01331   for(file = fileList.begin(); file != fileList.end(); file++)
01332   {
01333     localDir.remove(saveLocation + "/resources/" + *file);
01334   }
01335   localDir.cdUp();
01336   localDir.rmdir( "resources" );
01337   
01338   //create HTML and misc resources directories
01339   localDir.setPath(saveLocation);
01340   localDir.mkdir("resources");
01341 //  localDir.mkdir("misc_resources");
01342 
01343   //remove all files in these directories from previous saves with other themes
01344   localDir.setPath(saveLocation + "/resources");
01345   fileList = localDir.entryList( QDir::Files );
01346   for ( file = fileList.begin(); file != fileList.end(); ++file )
01347   { localDir.remove( saveLocation + "/resources/" + *file ); }
01348   //--
01349 /*
01350  localDir.setPath(saveLocation + "/misc_resources");
01351   fileList = localDir.entryList( QDir::Files );
01352   for ( file = fileList.begin(); file != fileList.end(); ++file )
01353   { localDir.remove( saveLocation + "/misc_resources/" + *file ); }
01354 */    
01355   //copy files over from theme's directory
01356   localDir.setPath(THEMES_PATH + theme + "/resources");
01357   fileList = localDir.entryList( QDir::Files );
01358   for ( file = fileList.begin(); file != fileList.end(); ++file )
01359   { copyFile( THEMES_PATH + theme + "/resources/" + *file, saveLocation + "/resources/" + *file); }
01360   //--
01361 /*
01362  localDir.setPath(THEMES_PATH + theme + "/misc_resources");
01363   fileList = localDir.entryList( QDir::Files );
01364   for ( file = fileList.begin(); file != fileList.end(); ++file )
01365   { copyFile( THEMES_PATH + theme + "/misc_resources/" + *file, saveLocation + "/misc_resources/" + *file); }  
01366 */
01367 }
01368 //==============================================
01369 void Album::syncSubalbumList(SubalbumPreviewWidget* item)
01370 {
01371   //check to see if any changes actually took place
01372   bool change = false;
01373   Subalbum* tmp = firstSubalbum;
01374   SubalbumPreviewWidget* tmp2 = item;
01375   while( tmp2 != NULL)
01376   {
01377     //pointers do not match up
01378     if(tmp != tmp2->getSubalbum() )
01379     {
01380       change = true;
01381       break;
01382     }
01383 
01384     tmp = tmp->getNext();
01385     tmp2 = (SubalbumPreviewWidget*)tmp2->nextItem();
01386   }
01387 
01388   //if no change then quit
01389   if(!change)
01390     return;
01391 
01392   //base case, no items
01393   if(item == NULL)
01394   {
01395     firstSubalbum = NULL;
01396     lastSubalbum = NULL;
01397     return;
01398   }
01399 
01400   //set first and last pointers
01401   firstSubalbum = item->getSubalbum();
01402   firstSubalbum->setNext(NULL);
01403   firstSubalbum->setPrev(NULL);
01404   lastSubalbum = firstSubalbum;
01405 
01406   //set all next pointers
01407   while(item->nextItem() != NULL)
01408   {
01409     item->getSubalbum()->setNext( ((SubalbumPreviewWidget*)item->nextItem())->getSubalbum() );
01410     item->getSubalbum()->getNext()->setPrev( item->getSubalbum() );
01411     item = (SubalbumPreviewWidget*)item->nextItem();
01412     lastSubalbum = item->getSubalbum();
01413     lastSubalbum->setNext(NULL);
01414   }
01415   
01416 }
01417 //==============================================
01418 void Album::setModified(bool val) { modified = val; }
01419 //==============================================
01420 int Album::getNextUniquePhotoID()
01421 {
01422   nextUniqueID++;
01423   return nextUniqueID;
01424 }
01425 //==============================================
01426 QStringList Album::getThumbnailFilenames()
01427 {
01428   //iterate over all collections
01429   QStringList thumbnailList;
01430   Subalbum* currCollection = firstSubalbum;
01431   while(currCollection != NULL)
01432   {
01433     //iterate over all photos
01434     Photo* currPhoto = currCollection->getFirst();
01435     while( currPhoto != NULL )
01436     {
01437       thumbnailList.append( currPhoto->getThumbnailFilename() );
01438       currPhoto = currPhoto->getNext();
01439     }
01440     
01441     currCollection = currCollection->getNext();
01442   }
01443 
01444   return thumbnailList; 
01445 }
01446 //==============================================

Generated on Wed Nov 8 16:37:13 2006 for AlbumShaper by  doxygen 1.4.7