Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

titleWidget.cpp

Go to the documentation of this file.
00001 //==============================================
00002 //  copyright            : (C) 2003 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 //  As a special exception, Will Stokes gives permission to 
00011 //  link this program with Qt non-commercial edition, and 
00012 //  distribute the resulting executable, without including the 
00013 //  source code for the Qt non-commercial edition in the 
00014 //  source distribution. 
00015 //==============================================
00016 
00017 //Systemwide includes
00018 #include <qwidget.h>
00019 #include <qmenubar.h>
00020 #include <qpopupmenu.h>
00021 #include <qlayout.h>
00022 #include <qlabel.h>
00023 #include <qfont.h>
00024 #include <qpixmap.h>
00025 #include <qimage.h>
00026 #include <qtoolbutton.h>
00027 #include <qlineedit.h>
00028 #include <qapplication.h>
00029 #include <qdir.h>
00030 #include <qcursor.h>
00031 #include <qfiledialog.h>
00032 #include <qtooltip.h>
00033 
00034 //Projectwide includes
00035 #include "window.h"
00036 #include "albumStatistics.h"
00037 #include "about.h"
00038 #include "handbook.h"
00039 #include "titleWidget.h"
00040 #include "layoutWidget.h"
00041 #include "subalbumsWidget.h"
00042 #include "subalbumWidget.h"
00043 #include "questionDialog.h"
00044 #include "alertDialog.h"
00045 #include "../backend/album.h"
00046 #include "../backend/photo.h"
00047 #include "../config.h"
00048 #include "guiTools.h"
00049 #include "statusWidget.h"
00050 #include "saveDialog.h"
00051 
00052 //==============================================
00053 TitleWidget::TitleWidget(QWidget *parent, 
00054                          const char* name ) : QFrame(parent,name)
00055 {
00057   window = (Window*)parent;
00058 
00060   albumStats = NULL;
00061   
00063   about = NULL;
00064   
00066   handbookWindow = NULL;
00067   
00068   //create menus
00069   menu = new QMenuBar( this, "menuBar" );
00070   
00071   file = new QPopupMenu( this, "fileMenu" );
00072   NEW_ALBUM = file->insertItem( tr("&New"), this, SLOT(newAlbum()), CTRL+Key_N );
00073   OPEN_ALBUM = file->insertItem( tr("&Open"), this, SLOT(loadAlbum()), CTRL+Key_O );
00074   SAVE_ALBUM = file->insertItem( tr("&Save"), this, SLOT(saveAlbum()), CTRL+Key_S );
00075   SAVEAS_ALBUM = file->insertItem( tr("&Save As"), this, SLOT(saveAsAlbum()), CTRL+SHIFT+Key_S );
00076 //  SMALL_SAVE = file->insertItem( tr("Small Save"), this, SLOT(smallSave()) );
00077   file->insertItem( tr("&Quit"), this, SLOT(quitApplication()), CTRL+Key_Q);
00078   
00079   tools = new QPopupMenu( this, "toolsMenu" );
00080   tools->insertItem( tr("Album Statistics"), this, SLOT(albumStatistics()) );
00081   
00082   help = new QPopupMenu( this, "helpMenu" );
00083   help->insertItem( tr("Handbook"), this, SLOT(handbook()) );
00084   help->insertItem( tr("&About"), this, SLOT(aboutProgram()) );
00085   
00086   menu->insertItem( tr("&File"), file );
00087   menu->insertItem( tr("&Tools"), tools );
00088   menu->insertSeparator();
00089   menu->insertItem( tr("&Help"), help );
00090   
00091   //create backend album object
00092   albm = new Album();
00093 
00094   //create labels and text entries
00095   albumName = new QLabel( this );
00096   albumName->setText( tr("Album Name:") );
00097   albumName->setFont( QFont( "Times", 12, QFont::Bold ) );
00098   albumNameVal = new QLineEdit( this );
00099   albumNameVal->setFont( QFont( "Times", 12, QFont::Bold ) );
00100   connect( albumNameVal, SIGNAL(textChanged( const QString&)),
00101            SLOT( updateName(const QString&)) );
00102   
00103   albumDescription = new QLabel( this );
00104   albumDescription->setText( tr("Description:") );
00105   albumDescription->setFont( QFont( "Times", 12, QFont::Bold ) );
00106   albumDescriptionVal = new QLineEdit( this );
00107   albumDescriptionVal->setFont( QFont( "Times", 12, QFont::Bold ) );
00108   connect( albumDescriptionVal, SIGNAL(textChanged( const QString&)),
00109            SLOT( updateDescription(const QString&)) );
00110 
00111   albumAuthor = new QLabel( this );
00112   albumAuthor->setText( tr("Author:") );
00113   albumAuthor->setFont( QFont( "Times", 12, QFont::Bold ) );
00114   albumAuthorVal = new QLineEdit( this );
00115   albumAuthorVal->setFont( QFont( "Times", 12, QFont::Bold ) );
00116   connect( albumAuthorVal, SIGNAL(textChanged( const QString&)),
00117            SLOT( updateAuthor(const QString&)) );
00118   
00119   //create set image button
00120   representativeImageText = new QLabel( this );
00121   representativeImageText->setText( tr("Thumbnail:") );
00122   representativeImageText->setFont( QFont( "Times", 12, QFont::Bold ) );
00123   
00124   QFont buttonFont( qApp->font() );
00125   buttonFont.setBold(true);
00126   buttonFont.setPointSize( 11 );
00127   
00128   setImage = new QToolButton( this );
00129   setImage->setTextLabel(tr("Set") );
00130   setImage->setTextPosition(QToolButton::Right);
00131   setImage->setFont( buttonFont );
00132   setImage->setUsesTextLabel( true );
00133   setImage->setEnabled(false);
00134   QToolTip::add( setImage, tr("Set album image to selected photo") );
00135   connect( setImage, SIGNAL(clicked()), SLOT(setImageAction()) );
00136   
00137   //create representative image
00138   representativeLogo = new QLabel( this );
00139   representativeLogo->setPixmap( *albm->getRepresentativeImage(SMALL) );
00140            
00141   //create album Shaper image
00142   albumShaperLogo = new QLabel( this );
00143   albumShaperLogo->setPixmap( QPixmap( QString(IMAGE_PATH)+"albumShaper.png" ) );
00144 
00145   //Create horizontal line
00146   line = new QFrame(this);
00147   line->setFrameShadow( QFrame::Plain );
00148   line->setLineWidth( 2 );
00149   line->setFrameShape( QFrame::HLine );
00150 
00151   //place all labels in grid layout
00152   grid = new QGridLayout( this, 5, 7, 0 );
00153   grid->addMultiCellWidget( menu, 0, 0, 0, 6 );
00154   grid->addWidget( albumName,                   1, 0, Qt::AlignLeft);
00155   grid->addWidget( albumNameVal,                1, 1);
00156   grid->addWidget( albumDescription,            2, 0, Qt::AlignLeft);
00157   grid->addWidget( albumDescriptionVal,         2, 1);
00158   grid->addWidget( albumAuthor,                 3, 0, Qt::AlignLeft);
00159   grid->addWidget( albumAuthorVal,              3, 1);
00160   grid->addWidget( representativeImageText,     1, 3, Qt::AlignLeft );
00161   grid->addWidget( setImage,                    2, 3, Qt::AlignLeft );
00162   grid->addMultiCellWidget( representativeLogo, 1, 3, 4, 4 );
00163   grid->addMultiCellWidget( line,               4, 4, 0, 6);
00164   grid->addMultiCellWidget( albumShaperLogo,     1, 3, 6, 6 );
00165 
00166   //Set the second column, the actual album name and description and author
00167   //to have a minimum width
00168   grid->addColSpacing(1, 300 );
00169 
00170   //create blank space between album name/desc/author and the thumbnail
00171   grid->addColSpacing(2, 10 );
00172     
00173   //set the blank colum to stretch more than others to take
00174   //up leftover room
00175   grid->setColStretch( 4, 1 );
00176 
00177   //set the background of the widget to be white
00178   setPaletteBackgroundColor( QColor(255, 255, 255) );
00179   
00181   busy = false;
00182 }
00183 //==============================================
00184 void TitleWidget::updateName( const QString& val )
00185 {
00186   albm->setName(val);
00187 }
00188 //==============================================
00189 void TitleWidget::updateDescription( const QString& val )
00190 {
00191   albm->setDescription(val);
00192 }
00193 //==============================================
00194 void TitleWidget::updateAuthor( const QString& val )
00195 {
00196   albm->setAuthor(val);
00197 }
00198 //==============================================
00199 void TitleWidget::setAlbum( Album* val)
00200 {
00201   //delete old album
00202   delete albm;
00203   albm = val;
00204 }
00205 //==============================================
00206 Album* TitleWidget::getAlbum()
00207 {
00208   return albm;
00209 }
00210 //==============================================
00211 //called when user clicks "set image" button
00212 void TitleWidget::setImageAction()
00213 {
00214   //---------------------------------------------------------    
00215   //determine if a subalbum is even selected
00216   SubalbumWidget* sw = window->getLayout()->getSubalbum();
00217   if(sw == NULL)
00218     return;
00219   //---------------------------------------------------------        
00220   //determine if a photo is selected
00221   Photo* selectedPhoto = sw->getSelectedPhoto();
00222   if(selectedPhoto == NULL)
00223     return;
00224   //---------------------------------------------------------     
00225   //set representative iamges
00226   QImage* img = selectedPhoto->getImage(IMAGE);
00227   albm->setRepresentativeImages( img );
00228   delete img;
00229   img = NULL;
00230   //---------------------------------------------------------    
00231   //update onscreen images
00232   representativeLogo->setPixmap( *(albm->getRepresentativeImage(SMALL)) );
00233   //---------------------------------------------------------    
00234 }
00235 //==============================================
00236 void TitleWidget::refresh()
00237 {
00238   albumNameVal->setText( albm->getName() );
00239   albumDescriptionVal->setText( albm->getDescription() );
00240   albumAuthorVal->setText( albm->getAuthor() );
00241   representativeLogo->setPixmap( *(albm->getRepresentativeImage(SMALL)) );
00242 }                 
00243 //==============================================
00244 void TitleWidget::newAlbum()
00245 {
00246   //if modifications exist ask user if they are sure before creating a new album
00247   if(albm->albumModified() )
00248   {
00249     QuestionDialog sure( tr("New album?"),
00250                                    tr("Warning, unsaved modifications to the current album exist. Creating a new album will result in lost work. Are you sure you want to do this?"),    
00251                                    "warning.png",
00252                                    this );
00253     if(!sure.exec())
00254       return;
00255   }
00256     
00257   //delete old album
00258   delete albm;
00259     
00260   //create new one
00261   albm = new Album();
00262   
00263   //refresh screen
00264   refresh();
00265   window->refresh();
00266   
00267   albm->setModified(false);
00268 }
00269 //==============================================
00270 void TitleWidget::loadAlbum()
00271 {
00272   //if unsaved modifications exist as the user before proceding with loading a new album
00273   if(albm->albumModified() )
00274   {
00275     QuestionDialog sure( tr("Load album?"),
00276                                    tr("Warning, unsaved modifications to the current album exist. Loading a new album will result in lost work. Are you sure you want to do this?"),
00277                                    "warning.png",
00278                                    this );
00279     if(!sure.exec())
00280       return;
00281   }
00282 
00283   //set busy flag and deactivate buttons
00284   setBusy(true);
00285   window->getLayout()->getSubalbums()->updateButtons(false);
00286   if(window->getLayout()->getSubalbum() != NULL)
00287     window->getLayout()->getSubalbum()->updateButtons(false);
00288   
00289   QString albumXML = QFileDialog::getOpenFileName(NULL,
00290                                                   tr("XML Files (*.xml)"),
00291                                                   this,
00292                                                   "open file dialog",
00293                                                   tr("Choose an album to load") );
00294 
00295   //if null return
00296   if(albumXML.isNull())
00297   {
00298     //nolonger busy
00299     setBusy(false);
00300     window->getLayout()->getSubalbums()->updateButtons(true);
00301     if(window->getLayout()->getSubalbum() != NULL)
00302       window->getLayout()->getSubalbum()->updateButtons(true);
00303     return;
00304   }
00305     
00306   qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00307   
00308   //create a new album
00309   delete albm;
00310   albm = new Album();
00311   
00312   //attempt to load xml file
00313   
00314   int errorCode = albm->importFromDisk(window->getStatus(), albumXML );
00315    
00316   //refresh screen
00317   refresh();
00318   window->refresh();
00319   
00320   //set album as not modified
00321   albm->setModified(false);
00322   
00323   //nolonger busy
00324   setBusy(false);
00325   window->getLayout()->getSubalbums()->updateButtons(true);
00326   if(window->getLayout()->getSubalbum() != NULL)
00327     window->getLayout()->getSubalbum()->updateButtons(true);
00328   qApp->restoreOverrideCursor();
00329   
00330   
00331   if(errorCode != ALBUM_LOADED)
00332   {
00333     QString errorMessage, errorDescription;
00334     if(errorCode == ALBUM_READ_ERROR)
00335     {
00336       errorMessage = tr("Unable to open file!");
00337       errorDescription = tr("An error was encountered attempting to load the XML file. Perhaps you do not have read access?");
00338     }
00339     else if(errorCode == ALBUM_XML_ERROR)
00340     {
00341       errorMessage = tr("Unable to construct DOM!");
00342       errorDescription = tr("The XML file you selected is not valid XML.");
00343     }
00344     else
00345     {
00346       errorMessage = tr("Unknown loading error!");
00347       errorDescription = tr("An unknown error was encountered loading the specified file.");
00348     }
00349         
00350     AlertDialog alert( errorMessage, errorDescription, "warning.png", this );
00351     alert.exec();
00352   }
00353 }
00354 //==============================================
00355 void TitleWidget::smallSave()
00356 {
00357 //  saveAsAlbum(true);
00358 }
00359 //==============================================
00360 void TitleWidget::saveAlbum(bool smallSave)
00361 {
00362   //if album not previously saved then
00363   //run saveas dialog
00364   if(!getAlbum()->prevSave())
00365   {
00366     saveAsAlbum(smallSave);
00367     return;
00368   }
00369   
00370   //if previously used theme not available for use again alert user, 
00371   //then run saveas dialog
00372   if(!SaveDialog::themeAvailable( getAlbum()->getTheme() ))
00373   {
00374     AlertDialog alert( tr("Previous theme not available!"),
00375                             tr("Theme previously used to save this album not available on this machine. Click ok to open the save-as dialog to save an alternative theme."), 
00376                             "warning.png", this );
00377     alert.exec();
00378     saveAsAlbum(smallSave);
00379     return;
00380   }
00381   
00382   //set busy flag and disable buttons
00383   setBusy(true);
00384   window->getLayout()->getSubalbums()->updateButtons(false);
00385   if(window->getLayout()->getSubalbum() != NULL)
00386     window->getLayout()->getSubalbum()->updateButtons(false);
00387   qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00388     
00389   //sync current subalbum to ensure all photo descriptions saved
00390   if(  window->getLayout()->getSubalbum() != NULL )
00391     window->getLayout()->getSubalbum()->syncPhotos();
00392     
00393   getAlbum()->exportToDisk(window->getStatus(), smallSave);  
00394       
00395   //nolonger busy
00396   setBusy(false);
00397   window->getLayout()->getSubalbums()->updateButtons(true);
00398   if(window->getLayout()->getSubalbum() != NULL)
00399     window->getLayout()->getSubalbum()->updateButtons(true);
00400   qApp->restoreOverrideCursor();
00401 }
00402 //==============================================
00403 void TitleWidget::saveAsAlbum(bool smallSave)
00404 {
00405   //setup dialog title and default path
00406   QString dialogTitle, defaultPath;
00407   if(smallSave)
00408     dialogTitle = tr( "Small Save As:" );
00409   else
00410     dialogTitle = tr( "Save As:" );
00411   if(getAlbum()->prevSave())
00412     defaultPath = getAlbum()->getSaveLocation();
00413   else
00414   {
00415     defaultPath = QDir::homeDirPath() + "/" + getAlbum()->getName();  
00416     defaultPath.replace( QChar(' '), "_" );
00417     defaultPath.replace( "<", "" );
00418     defaultPath.replace( ">", "" );
00419     defaultPath.replace( "&", "and" );
00420     defaultPath.replace( "\"", "" );
00421     defaultPath.replace( "\'", "" );
00422     defaultPath.replace( "?", "" );
00423   }
00424   
00425   //get directory name in which album directory will be placed in
00426   QString theme, savePath;  
00427   theme = getAlbum()->getTheme();
00428   if( !SaveDialog::selectThemeAndPath( dialogTitle, defaultPath, theme, savePath ) )
00429     return;
00430       
00431   //check if directory already exists, if not attempt to create it
00432   QDir d(savePath);
00433   if(!d.exists())
00434   {
00435     if(!d.mkdir(savePath))
00436     {      
00437       AlertDialog alert( tr("Error creating directory!"), 
00438                               tr("Unable to create directory to save album in. Perhaps you are running out of disk space or you don't have sufficient privledges?"),
00439                               "warning.png", this );
00440       alert.exec();
00441       return;
00442     }
00443   }
00444   else
00445   {
00446     if(!d.isReadable())
00447     {
00448       AlertDialog alert( tr("Destination directory not readable!"), 
00449                               tr("The destination directory is not readable. Perhaps you don't have sufficient privledges?"),
00450                               "warning.png", this );
00451       alert.exec();
00452       return;
00453     }
00454   }
00455   
00456   //set busy flag and disable buttons
00457   setBusy(true);
00458   window->getLayout()->getSubalbums()->updateButtons(false);
00459   if(window->getLayout()->getSubalbum() != NULL)
00460     window->getLayout()->getSubalbum()->updateButtons(false);
00461   qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
00462     
00463   //sync current subalbum to ensure all photo descriptions saved
00464   if(  window->getLayout()->getSubalbum() != NULL )
00465     window->getLayout()->getSubalbum()->syncPhotos();
00466     
00467   //save
00468   getAlbum()->exportToDisk(window->getStatus(), smallSave, savePath, theme);
00469       
00470   //nolonger busy
00471   setBusy(false);
00472   window->getLayout()->getSubalbums()->updateButtons(true);
00473   if(window->getLayout()->getSubalbum() != NULL)
00474     window->getLayout()->getSubalbum()->updateButtons(true);
00475   qApp->restoreOverrideCursor();
00476 }
00477 //==============================================
00478 void TitleWidget::albumStatistics()
00479 {
00480   //create window and center, always create a new window
00481   //in case album information has changed
00482   if(albumStats != NULL)
00483     delete albumStats;
00484     
00485   albumStats = new AlbumStatistics(albm);
00486   connect( albumStats, SIGNAL(albumStatisticsClosed()),
00487            this, SLOT(albumStatisticsClosed()));
00488   albumStats->show();
00489   centerWindow(albumStats);
00490 }
00491 //==============================================
00492 void TitleWidget::aboutProgram()
00493 {
00494   //create window and center if not already present
00495   if(about == NULL)
00496   {
00497     about = new About();
00498     connect( about, SIGNAL(aboutClosed()),
00499              this, SLOT(aboutClosed()));
00500     about->show();
00501     centerWindow(about);
00502   }
00503   //else raise window
00504   else
00505   {
00506     about->raise();   
00507   }
00508 }
00509 //==============================================
00510 void TitleWidget::handbook()
00511 {
00512   //create window and center if not already present
00513   if(handbookWindow == NULL)
00514   {
00515     handbookWindow = new Handbook(0);
00516     connect( handbookWindow, SIGNAL(closed()),
00517              this, SLOT(handbookClosed()));
00518     handbookWindow->show();
00519     centerWindow(handbookWindow);
00520   }
00521   //else raise window
00522   else
00523   {
00524     handbookWindow->raise();   
00525   }
00526 }
00527 //==============================================
00528 void TitleWidget::albumStatisticsClosed()
00529 {
00530   delete albumStats;
00531   albumStats = NULL;
00532 }
00533 //==============================================
00534 void TitleWidget::aboutClosed()
00535 {
00536   delete about;
00537   about = NULL;
00538 }
00539 //==============================================
00540 void TitleWidget::handbookClosed()
00541 {
00542   delete handbookWindow;
00543   handbookWindow = NULL;
00544 }
00545 //==============================================
00546 void TitleWidget::setSetButtonState(bool state)
00547 {
00548   setImage->setEnabled(state);
00549 }
00550 //==============================================
00551 bool TitleWidget::getBusy()
00552 {
00553   return busy;
00554 }
00555 //==============================================
00556 void TitleWidget::setBusy(bool val)
00557 {
00558   busy = val;
00559   
00560   //disable/enable file operations
00561   if(busy)
00562   {
00563     file->setItemEnabled(NEW_ALBUM, false);
00564     file->setItemEnabled(OPEN_ALBUM, false);
00565     file->setItemEnabled(SAVE_ALBUM, false);
00566     file->setItemEnabled(SAVEAS_ALBUM, false);
00567     cacheSetButtonState = setImage->isEnabled();
00568     setSetButtonState(false);
00569   }
00570   else
00571   {
00572     file->setItemEnabled(NEW_ALBUM, true);
00573     file->setItemEnabled(OPEN_ALBUM, true);
00574     file->setItemEnabled(SAVE_ALBUM, true);
00575     file->setItemEnabled(SAVEAS_ALBUM, true);
00576     setSetButtonState(cacheSetButtonState);
00577   }
00578 }
00579 //==============================================
00580 void TitleWidget::quitApplication()
00581 {
00582   window->close();
00583 }
00584 //==============================================

Generated on Thu Nov 13 00:10:54 2003 for AlbumShaper by doxygen 1.3.4