AlbumShaper  1.0a3
titleWidget.cpp
Go to the documentation of this file.
1 //==============================================
2 // copyright : (C) 2003-2005 by Will Stokes
3 //==============================================
4 // This program is free software; you can redistribute it
5 // and/or modify it under the terms of the GNU General
6 // Public License as published by the Free Software
7 // Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //==============================================
10 
11 //Systemwide includes
12 #include <qwidget.h>
13 #include <qmenubar.h>
14 #include <q3popupmenu.h>
15 #include <qlayout.h>
16 #include <qlabel.h>
17 #include <qfont.h>
18 #include <qpixmap.h>
19 #include <qmovie.h>
20 #include <qimage.h>
21 #include <qtoolbutton.h>
22 #include <qfileinfo.h>
23 #include <qlineedit.h>
24 #include <qapplication.h>
25 #include <qdir.h>
26 #include <qcursor.h>
27 #include <q3filedialog.h>
28 #include <qtooltip.h>
29 #include <qicon.h>
30 #include <qdatetime.h>
31 //Added by qt3to4:
32 #include <Q3GridLayout>
33 #include <Q3Frame>
34 #include <QDragEnterEvent>
35 #include <QDropEvent>
36 #include <Q3VBoxLayout>
37 
38 #include <math.h>
39 
40 //Projectwide includes
41 #include "window.h"
42 #include "titleWidget.h"
43 #include "layoutWidget.h"
44 #include "subalbumsWidget.h"
45 #include "subalbumWidget.h"
46 #include "statusWidget.h"
47 #include "ALabel.h"
48 #include "subalbumPreviewWidget.h"
49 #include "recentAlbumMenuItem.h"
50 
52 #include "dialogs/about.h"
53 #include "help/helpWindow.h"
54 #include "dialogs/questionDialog.h"
55 #include "dialogs/alertDialog.h"
56 #include "dialogs/saveDialog.h"
57 
58 #include "../config.h"
59 #include "../backend/album.h"
60 #include "../backend/subalbum.h"
61 #include "../backend/photo.h"
62 #include "../backend/tools/fileTools.h"
63 #include "../backend/tools/guiTools.h"
64 #include "../configuration/configurationWidget.h"
65 #include "../configuration/configuration.h"
66 
67 //==============================================
69  const char* name ) : Q3Frame(parent,name)
70 {
71  tmpDirErrorMessage = tr("Error! Unable to create temp directory!");
72  tmpDirErrorDesc = tr("Album Shaper was unable to create the necessary temp directory required: ");
73  //--------------------------------------------------------------
74  QColor white(255, 255, 255);
75  QColor lightBlue(193, 210, 238);
76  QColor darkBlue(35, 75, 139);
77  QColor black(0, 0, 0);
78  //--------------------------------------------------------------
80  window = (Window*)parent;
81 
83  busy = false;
84 
85  //detect changes to text fields
86  detectModifications = true;
87 
89  albumStats = NULL;
90  settingsWindow = NULL;
91  about = NULL;
92  helpWindow = NULL;
93 
94  //create backend album object
95  albm = new Album( createTmpDir() );
96  if(albm->getTmpDir().isNull() )
97  {
98  AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
99  "alertIcons/warning.png", this );
100  alert.exec();
101  quitApplication();
102  }
103  //-------------------------------------
104  //initialize recent albums object
105  int i;
106  QString recentName, recentLocation, recentPhotoCount;
107  for(i = 0; i<recentAlbums.getMaxItems(); i++)
108  {
109  //get album name and location
110  recentName = window->getConfig()->getString( "recentAlbums", QString("%1_name").arg(i) );
111  recentLocation = window->getConfig()->getString("recentAlbums", QString("%1_location").arg(i) );
112  recentPhotoCount = window->getConfig()->getString("recentAlbums", QString("%1_photoCount").arg(i) );
113 
114  //no such listing? since listings are continious all listings must be loaded
115  if(recentLocation.compare("-1") == 0)
116  break;
117 
118  //insert item into list
119  recentAlbums.insertEntry( recentName, recentLocation, recentPhotoCount );
120  }
121  //--------------------------------------------------------------
122  //create menus
123  menu = new QMenuBar( this, "menuBar" );
124  //---
125  //File menu
126  file = new Q3PopupMenu( this, "fileMenu" );
127  NEW_ALBUM = file->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/new.png") ),
128  tr("&New"), this, SLOT(newAlbum()), Qt::CTRL+Qt::Key_N );
129 
130  OPEN_ALBUM = file->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/open.png") ),
131  tr("&Open..."), this, SLOT(loadAlbum()), Qt::CTRL+Qt::Key_O );
132 
133  openRecent = new Q3PopupMenu( this, "openRecentMenu" );
136  file->insertItem( tr("Open Recent"), openRecent );
137  //----------------------
138  file->insertSeparator();
139  //----------------------
140  SAVE_ALBUM = file->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/save.png") ),
141  tr("&Save"), this, SLOT(saveAlbum()), Qt::CTRL+Qt::Key_S );
142 
143  SAVEAS_ALBUM = file->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/saveas.png") ),
144  tr("&Save As..."), this, SLOT(saveAsAlbum()), Qt::CTRL+Qt::SHIFT+Qt::Key_S );
145 
146  REVERT_TO_SAVED_ALBUM = file->insertItem( tr("Revert to Saved"), this, SLOT(revertToSaved()) );
147  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, false );
148  //----------------------
149  file->insertSeparator();
150  //----------------------
151  Q3PopupMenu* exportAs = new Q3PopupMenu( this, "exportAs" );
152  EXPORT_SMALL_WEB_GALLERY = exportAs->insertItem( tr("Small Web Gallery..."),
153  this, SLOT(exportSmallWebGallery()) );
154  EXPORT_LARGE_IMAGES = exportAs->insertItem( tr("Images for Printing..."),
155  this, SLOT(exportLargeImages()) );
156 
157  file->insertItem( tr("Export"), exportAs );
158  //----------------------
159  file->insertSeparator();
160  //----------------------
161  file->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/quit.png") ),
162  tr("&Quit"), this, SLOT(quitApplication()), Qt::CTRL+Qt::Key_Q);
163 
164 
165  menu->insertItem( tr("&File"), file );
166  //---
167  //Photo menu
168  photoMenu = new Q3PopupMenu( this, "phooMenu" );
169 
170  REMOVE_DESCRIPTIONS = photoMenu->insertItem( tr("Remove Description"), this, SLOT(removeSelectedPhotoDesc()) );
171  REVERT_PHOTOS = photoMenu->insertItem( tr("Revert to Original"), this, SLOT(revertPhotos()) );
172 
173  menu->insertItem( tr("&Photos"), photoMenu );
174  //---
175  //Tools menu
176  tools = new Q3PopupMenu( this, "toolsMenu" );
177 /*
178  BEGIN_PRESENTATION_AT = tools->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/startPresentation.png") ),
179  tr("Begin Presentation"),
180  window, SLOT(startSlideshowWithSelectedPhoto()), CTRL+Key_P );
181  BEGIN_PRESENTATION = tools->insertItem( tr("Begin Presentation at Beginning"),
182  window, SLOT(startSlideshowAtBeginning()), CTRL+SHIFT+Key_P );
183  updateMenus();
184  */
185 
186  tools->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/albumStatistics.png") ),
187  tr("Album Statistics"), this, SLOT(albumStatistics()), Qt::CTRL+Qt::Key_I );
188 
189  tools->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/settings.png") ),
190  tr("Settings"), this, SLOT(settings()) );
191 
192  menu->insertItem( tr("&Tools"), tools );
193  //---
194  //PLATFORM_SPECIFIC_CODE
195  //Window menu
196  #if defined(Q_OS_MACX)
197  windowMenu = new Q3PopupMenu( this, "windoMenu" );
198  WINDOW_MINIMIZE = windowMenu->insertItem( tr("&Minimize"), (QWidget*)window, SLOT(showMinimized()), Qt::CTRL+Qt::Key_M );
199  menu->insertItem( tr("&Window"), windowMenu );
200  #endif
201  //---
202  //Help menu
203  helpMenu = new Q3PopupMenu( this, "helpMenu" );
204  helpMenu->insertItem( tr("Album Shaper Help"), this, SLOT(help()), Qt::CTRL+Qt::Key_Question );
205 
206  helpMenu->insertItem( QIcon( QPixmap(QString(IMAGE_PATH)+"menuIcons/about.png") ),
207  tr("About"), this, SLOT(aboutProgram()) );
208  menu->insertSeparator();
209  menu->insertItem( tr("&Help"), helpMenu );
210  //--------------------------------------------------------------
211  //create all widgets
212  mainFrame = new Q3Frame( this, "mainFrame" );
213  mainFrame->setPaletteBackgroundColor( darkBlue );
214  //------
215  //album annotations
216  albumAnnotationFrame = new Q3Frame( mainFrame, "albumAnnotationFrame" );
217  albumAnnotationFrame->setLineWidth(2);
218  albumAnnotationFrame->setMidLineWidth(0);
219  albumAnnotationFrame->setFrameStyle( Q3Frame::Panel | Q3Frame::Plain );
220  albumAnnotationFrame->setPaletteForegroundColor( white );
221  albumAnnotationFrame->setPaletteBackgroundColor( darkBlue );
222 
223  Q3Frame* albumImageFrame = new Q3Frame( albumAnnotationFrame, "albumImageFrame" );
224  albumImage = new ALabel( albumImageFrame, "albumImage",
225  new QPixmap( QString(IMAGE_PATH)+"buttonIcons/removeImage.png") );
226  connect( albumImage, SIGNAL(mouseRelease()),
227  this, SLOT(unsetAlbumImage()) );
228 
229  //allow drop events
230  this->setAcceptDrops(true);
231 
232  albumName = new QLabel( tr("Album Name:"), albumAnnotationFrame, "albumName" );
233  albumNameVal = new QLineEdit( albumAnnotationFrame, "albumNameVal" );
234  connect( albumNameVal, SIGNAL(textChanged( const QString&)),
235  SLOT( storeAnnotations()) );
236 
237  albumDescription = new QLabel( tr("Description:"), albumAnnotationFrame, "albumDescription" );
238  albumDescriptionVal = new QLineEdit( albumAnnotationFrame, "albumDescriptionVal" );
239  connect( albumDescriptionVal, SIGNAL(textChanged( const QString&)),
240  SLOT( storeAnnotations()) );
241 
242  albumAuthor = new QLabel( tr("Author:"), albumAnnotationFrame, "albumAuthor" );
243  albumAuthorVal = new QLineEdit( albumAnnotationFrame, "albumAuthorVal" );
244  connect( albumAuthorVal, SIGNAL(textChanged( const QString&)),
245  SLOT( storeAnnotations()) );
246  //------
247  //subalbum annotations
248  subalbumAnnotationFrame = new Q3Frame( mainFrame, "subalbumAnnotationFrame" );
249  subalbumAnnotationFrame->setLineWidth(2);
250  subalbumAnnotationFrame->setMidLineWidth(0);
251  subalbumAnnotationFrame->setFrameStyle( Q3Frame::Panel | Q3Frame::Plain );
252  subalbumAnnotationFrame->setPaletteForegroundColor( white );
253  subalbumAnnotationFrame->setPaletteBackgroundColor( darkBlue );
254 
255  Q3Frame* subalbumImageFrame = new Q3Frame( subalbumAnnotationFrame, "subalbumImageFrame" );
256  subalbumImage = new ALabel( subalbumImageFrame, "subalbumImage",
257  new QPixmap( QString(IMAGE_PATH)+"buttonIcons/removeImage.png") );
258 
259  connect( subalbumImage, SIGNAL(mouseRelease()),
260  this, SLOT(unsetSubalbumImage()) );
261 
262  subalbumName = new QLabel( tr("Collection Name:"), subalbumAnnotationFrame );
263  subalbumNameVal = new QLineEdit( subalbumAnnotationFrame );
264  connect( subalbumNameVal, SIGNAL(textChanged( const QString&)),
265  SLOT( storeAnnotations()) );
266 
267  subalbumDescription = new QLabel( tr("Description:"), subalbumAnnotationFrame );
269  connect( subalbumDescriptionVal, SIGNAL(textChanged( const QString&)),
270  SLOT( storeAnnotations()) );
271  //--------------------------------------------------------------
272  //Set fonts + colors
273  QFont labelFont = albumName->font();
274  labelFont.setWeight(QFont::Bold);
275 
276  albumName->setFont( labelFont );
277  albumName->setPaletteForegroundColor( white );
278  albumName->setPaletteBackgroundColor( darkBlue );
279 
280  albumNameVal->setFont( labelFont );
281  albumNameVal->setPaletteForegroundColor( black );
282  albumNameVal->setPaletteBackgroundColor( lightBlue );
283  albumNameVal->setFrame ( false );
284 
285  albumDescription->setFont( labelFont );
286  albumDescription->setPaletteForegroundColor( white );
287  albumDescription->setPaletteBackgroundColor( darkBlue );
288 
289  albumDescriptionVal->setFont( labelFont );
290  albumDescriptionVal->setPaletteForegroundColor( black );
291  albumDescriptionVal->setPaletteBackgroundColor( lightBlue );
292  albumDescriptionVal->setFrame ( false );
293 
294  albumAuthor->setFont( labelFont );
295  albumAuthor->setPaletteForegroundColor( white );
296  albumAuthor->setPaletteBackgroundColor( darkBlue );
297 
298  albumAuthorVal->setFont( labelFont );
299  albumAuthorVal->setPaletteForegroundColor( black );
300  albumAuthorVal->setPaletteBackgroundColor( lightBlue );
301  albumAuthorVal->setFrame ( false );
302 
303  subalbumName->setFont( labelFont );
304  subalbumName->setPaletteForegroundColor( white );
305  subalbumName->setPaletteBackgroundColor( darkBlue );
306 
307  subalbumNameVal->setFont( labelFont );
308  subalbumNameVal->setPaletteForegroundColor( black );
309  subalbumNameVal->setPaletteBackgroundColor( lightBlue );
310  subalbumNameVal->setFrame ( false );
311 
312  subalbumDescription->setFont( labelFont );
313  subalbumDescription->setPaletteForegroundColor( white );
314  subalbumDescription->setPaletteBackgroundColor( darkBlue );
315 
316  subalbumDescriptionVal->setFont( labelFont );
317  subalbumDescriptionVal->setPaletteForegroundColor( black );
318  subalbumDescriptionVal->setPaletteBackgroundColor( lightBlue );
319  subalbumDescriptionVal->setFrame ( false );
320  //--------------------------------------------------------------
321  //place widgets in grids
322  //------------------------
323  //album annotations
324  Q3GridLayout* albumImageGrid = new Q3GridLayout( albumImageFrame, 1, 1 );
325  albumImageGrid->addWidget( albumImage, 0, 0 );
326  albumImageGrid->setRowSpacing( 0, REP_IMAGE_HEIGHT );
327 
328  albumAnnotationGrid = new Q3GridLayout( albumAnnotationFrame, 3, 3);
330  albumAnnotationGrid->setSpacing(WIDGET_SPACING);
331 
332  albumAnnotationGrid->addMultiCellWidget( albumImageFrame, 0, 2, 0, 0 );
333 
334  albumAnnotationGrid->addWidget ( albumName, 0, 1, Qt::AlignLeft);
335  albumAnnotationGrid->addWidget ( albumDescription, 1, 1, Qt::AlignLeft);
336  albumAnnotationGrid->addWidget ( albumAuthor, 2, 1, Qt::AlignLeft);
337 
338  albumAnnotationGrid->setColStretch(2, 1);
339  albumAnnotationGrid->addWidget( albumNameVal, 0, 2);
340  albumAnnotationGrid->addWidget( albumDescriptionVal, 1, 2);
341  albumAnnotationGrid->addWidget( albumAuthorVal, 2, 2);
342  //------------------------
343  //subalbum annotations
344  Q3GridLayout* subalbumImageGrid = new Q3GridLayout( subalbumImageFrame, 1, 1 );
345  subalbumImageGrid->addWidget( subalbumImage, 0, 0 );
346  subalbumImageGrid->setRowSpacing( 0, REP_IMAGE_HEIGHT );
347 
348  subalbumAnnotationGrid = new Q3GridLayout( subalbumAnnotationFrame, 5, 5);
351 
352  subalbumAnnotationGrid->addMultiCellWidget( subalbumImageFrame, 0, 2, 0, 0);
353 
354  subalbumAnnotationGrid->setRowStretch(2, 1);
355  subalbumAnnotationGrid->addWidget ( subalbumName, 0, 1, Qt::AlignLeft);
356  subalbumAnnotationGrid->addWidget ( subalbumDescription, 1, 1, Qt::AlignLeft);
357 
358  subalbumAnnotationGrid->setColStretch(2, 1);
359  subalbumAnnotationGrid->addWidget( subalbumNameVal, 0, 2);
361  //------------------------
362  //place menu and album and subalbum annotations into main grid
363  mainGrid = new Q3GridLayout( mainFrame, 1, 2);
364  mainGrid->setMargin(WIDGET_SPACING);
365  mainGrid->setSpacing(WIDGET_SPACING);
366 
367  mainGrid->addWidget ( albumAnnotationFrame, 0, 0);
368  mainGrid->setColStretch(0, 1);
369 
370  mainGrid->addWidget ( subalbumAnnotationFrame, 0, 1);
371  mainGrid->setColStretch(1, 1);
372 
373  Q3VBoxLayout* vb = new Q3VBoxLayout(this);
374  this->layout()->setMenuBar( menu );
375  vb->addWidget(mainFrame);
376  //-----------------------------------------------
377 }
378 //==============================================
380 {
381  //enable animation
382  if(val)
383  {
388  }
389  //disable animation
390  else
391  {
394  }
395 }
396 //==============================================
398 {
399  //delete old album
400  delete albm;
401  albm = NULL;
402 }
403 //==============================================
405 {
406  //only sync backend album/collection data when detectModifications is enabled
407  if( !detectModifications ) return;
408 
409  //set album annotations
410  albm->setName ( albumNameVal->text() );
412  albm->setAuthor ( albumAuthorVal->text() );
413 
414  //get subalbum pointer
416  if(collection != NULL )
417  {
418  //store old subalbum name
419  QString oldName = collection->getName();
420 
421  //set name and description
422  collection->setName( subalbumNameVal->text() );
423  collection->setDescription( subalbumDescriptionVal->text() );
424 
425  //if subalbum name has changed emit signal
426  if(oldName.compare( collection->getName() ) != 0)
427  emit subalbumNameChanged();
428  }
429 }
430 //==============================================
432 {
433  //disable modification detection while updating fields
434  detectModifications = false;
435 
436  //set album annotations
437 
438  //if no image then remove pixmap
439  if( albm->getRepresentativeImage(LARGE) != NULL)
441  else
443 
444  albumNameVal->setText( albm->getName() );
445  albumNameVal->setCursorPosition(0);
446  albumDescriptionVal->setText( albm->getDescription() );
447  albumDescriptionVal->setCursorPosition(0);
448  albumAuthorVal->setText( albm->getAuthor() );
449  albumAuthorVal->setCursorPosition(0);
450 
451  //enable modification detection
452  detectModifications = true;
453 }
454 //==============================================
456 {
457  //disable modification detection while updating fields
458  detectModifications = false;
459 
460  //get subalbum pointer
461  if( collection == NULL )
462  {
463  subalbumAnnotationFrame->hide();
465  }
466  else
467  {
468  subalbumAnnotationFrame->show();
469 
470  //if no image then remove pixmap
471  if( collection->getRepresentativeImage(LARGE) != NULL)
473  else
475 
476  subalbumNameVal->setText( collection->getName() );
477  subalbumNameVal->setCursorPosition(0);
478  subalbumDescriptionVal->setText( collection->getDescription() );
479  subalbumDescriptionVal->setCursorPosition(0);
480  }
481 
482  //enable modification detection
483  detectModifications = true;
484 }
485 //==============================================
487 {
488  //delete old album
489  delete albm;
490  albm = val;
491 }
492 //==============================================
494 {
495  return albm;
496 }
497 //==============================================
499 {
500  //---------------------------------------------------------
501  //determine if a subalbum is even selected
503  if(sw == NULL)
504  return;
505  //---------------------------------------------------------
506  //set image to photo
508 }
509 //==============================================
510 void TitleWidget::setAlbumImage(Photo* selectedPhoto)
511 {
512  if(selectedPhoto == NULL)
513  return;
514  //---------------------------------------------------------
515  //set album image
516  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
517  albm->setRepresentativeImages( selectedPhoto->getImageFilename() );
518  //---------------------------------------------------------
519  //update onscreen image
521  qApp->restoreOverrideCursor();
522  //---------------------------------------------------------
523 }
524 //==============================================
526 {
527  albm->setRepresentativeImages( QString::null );
528 }
529 //==============================================
531 {
532  //---------------------------------------------------------
533  //determine if a subalbum is even selected
535  if(sw == NULL)
536  return;
537  //---------------------------------------------------------
538  //set collection image to selected photo
540 }
541 //==============================================
543 {
544  if(selectedPhoto == NULL)
545  return;
546 
547  //---------------------------------------------------------
548  //set subalbum image
549  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
551  sw->getSubalbum()->setRepresentativeImage( selectedPhoto->getThumbnailFilename() );
552  //---------------------------------------------------------
553  //update onscreen image
556  item->setPixmap( *sw->getSubalbum()->getRepresentativeImage(MEDIUM), false );
557  qApp->restoreOverrideCursor();
558  //---------------------------------------------------------
559 }
560 //==============================================
562 {
564  if(item != NULL && ((SubalbumPreviewWidget*)item)->getSubalbum() != NULL)
565  {
566  Subalbum* subalbm = ((SubalbumPreviewWidget*)item)->getSubalbum();
567  subalbm->setRepresentativeImage( QString::null );
568  item->setPixmap( *subalbm->getRepresentativeImage(MEDIUM), false );
569  }
570 }
571 //==============================================
573 {
574  //first refresh the subalbums listing. this is
575  //IMPERATIVE! Right now current subalbum selection contains a pointer
576  //to dead memory where previous subalbum was deleted.
577  //AKA not refreshing the subalbums iconview first will cause a crash!
578  window->refresh();
579 
580  //update the album annotations (name, desc, author, images)
581  //subalbum auto updated since window refresh auto selected first item
583 }
584 //==============================================
586 {
587  //if modifications exist and user wants to receive destructive action warnings,
588  //ask if they are sure before creating a new album
589  if( albm->albumModified() && window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
590  {
591  QuestionDialog sure( tr("New album?"),
592  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?"),
593  "alertIcons/warning.png",
594  this );
595  if(!sure.exec())
596  return;
597  }
598 
599  //delete old album
600  delete albm;
601 
602  //create new one
603  albm = new Album( createTmpDir() );
604 
605  if(albm->getTmpDir().isNull() )
606  {
607  AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
608  "alertIcons/warning.png", this );
609  alert.exec();
610  quitApplication();
611  }
612 
613  //refresh screen
616 
617  //disable revert menu option since there is no loaded album
618  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, false );
619 
620  //reset editing interface since old pointers are invalid
621  window->getLayout()->getSubalbum()->setSubalbum( NULL );
622  refresh();
623 
624  albm->setModified(false);
625 }
626 //==============================================
628 {
630  if(!proceedWithLoad())
631  return;
632 
633  QString path = window->getConfig()->getString( "loadSave", "loadSaveDir" );
634  QDir testPath(path);
635  if(!testPath.exists())
636  {
637  window->getConfig()->resetSetting( "loadSave", "loadSaveDir" );
638  path = window->getConfig()->getString( "loadSave", "loadSaveDir" );
639  }
640 
641  QString albumXML = Q3FileDialog::getOpenFileName( path,
642  tr("XML Files (*.xml)"),
643  this,
644  "open file dialog",
645  tr("Choose an album to load") );
646 
647  //if null bail
648  if(albumXML.isNull()) return;
649 
650  //attempt to load album
651  loadAlbum( albumXML );
652 }
653 //==============================================
655 {
657  if(!proceedWithLoad())
658  return;
659  //load album
660  QString recentName, recentLocation, recentPhotoCount;
661  recentAlbums.getEntry( index, recentName, recentLocation, recentPhotoCount );
662  loadAlbum( QDir::convertSeparators( recentLocation + "/Album.xml") );
663 }
664 //==============================================
666 {
667  //if modifications exist and user wants to receive destructive action warnings,
668  //ask if they are sure before creating a new album
669  if( albm->albumModified() && window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
670  {
671  QuestionDialog sure( tr("Load album?"),
672  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?"),
673  "alertIcons/warning.png",
674  this );
675  if(!sure.exec())
676  return false;
677  }
678 
679  return true;
680 }
681 //==============================================
683 {
684  //if there are no changed then immediately return since reverting will have no effect
685  //TODO: disable "revert" menu entry when no modifications exist
686  if( !albm->albumModified() )
687  return;
688 
690  //if modifications exist and user wants to receive destructive action warnings,
691  //ask if they are sure before creating a new album
692  if( window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
693  {
694  QuestionDialog sure( tr("Revert to Saved?"),
695  tr("Warning, unsaved modifications to the current album exist. These changes will be lost if you revert to the album's last saved form. Are you sure you want to do this?"),
696  "alertIcons/warning.png",
697  this );
698  if(!sure.exec())
699  return;
700  }
701 
702  //reload album
703  loadAlbum( QDir::convertSeparators( albm->getSaveLocation() + "/Album.xml") );
704 }
705 //==============================================
707 {
708  //if the Album's theme is not currently available alert user and bail
709  if(!SaveDialog::themeAvailable( getAlbum()->getTheme() ))
710  {
711  AlertDialog alert( tr("Previous theme not available!"),
712  QString(tr("Theme previously used to save this album not available on this machine. Before exporting the %1 theme must be installed, or the album must be resaved using a different theme.")).arg( getAlbum()->getTheme() ),
713  "alertIcons/warning.png", this );
714  alert.exec();
715  return;
716  }
717 
718 
719  //setup dialog title and default path
720  QString dialogTitle = tr( "Export Small Web Gallery" );
721 
722  //new directory name in which all images will be contained
723  QString newDir;
724  if(getAlbum()->prevSave())
725  { newDir = QDir( getAlbum()->getSaveLocation() ).dirName() + "_WEB"; }
726  else
727  { newDir = getAlbum()->getName() + "_WEB"; }
728  newDir = fixFilename( newDir );
729 
730  //get filename from user
731  Q3FileDialog* fd = new Q3FileDialog( this, "file dialog", TRUE );
732  fd->setCaption( tr("Export Location") );
733  fd->setMode( Q3FileDialog::DirectoryOnly );
734  fd->setDir( window->getConfig()->getString( "loadSave", "loadSaveDir" ) );
735 
736  //user canceled operation
737  if ( !fd->exec() == QDialog::Accepted ) { return; }
738 
739  //get export path
740  QString exportPath = QDir::convertSeparators( fd->selectedFile() + "/" + newDir );
741 
742  //check to make sure the album is not in this location, if so raise red flag and abort!!
743  if( getAlbum()->prevSave() && getAlbum()->getSaveLocation().compare( exportPath ) == 0 )
744  {
745  QString errorMessage = tr("Error! Cannot export to album location on disk!");
746  QString errorDesc = tr("Exporting small web galleries to the same location the album is stored will corrupt it and is not allowed. Try using the default location when exporting images, or chose a different directory.");
747  AlertDialog alert( errorMessage, errorDesc,
748  "alertIcons/warning.png", this );
749  alert.exec();
750  return;
751  }
752 
753  //otherwise check if directory already exists, if so warn user and ask before proceeding
754  QDir tmpDir;
755  if(tmpDir.exists( exportPath ) )
756  {
757  QString warningMessage =
758  QString(tr("Warning! A directory named %1 already exists in %2. Continue with export?")).arg
759  ( newDir ).arg( fd->selectedFile() );
760 
761  QuestionDialog sure( tr("Directory Exists!"),
762  warningMessage, "alertIcons/warning.png",
763  this );
764  if(!sure.exec()) { return; }
765  }
766  //else create directory
767  else
768  {
769  if( !tmpDir.mkdir( exportPath ) )
770  {
771  AlertDialog alert( tr("Error creating directory!"),
772  tr("Unable to create directory to export images to. Perhaps you are running out of disk space or you don't have sufficient privileges?"),
773  "alertIcons/warning.png", this );
774  alert.exec();
775  return;
776  }
777  }
778 
779  //set busy flag and disable buttons
780  setBusy(true);
782  if(window->getLayout()->getSubalbum() != NULL)
784  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
785 
786  //setup progress bar
787  int numPhotos = getAlbum()->getNumPhotos();
788  QString exportMessage = tr( "Exporting %1 photos to web gallery" );
789  window->getStatus()->showProgressBar( exportMessage.arg(numPhotos), numPhotos );
790  qApp->processEvents();
791 
792  //export large images
793  getAlbum()->exportCompressedWebAlbum(window->getStatus(), exportPath, exportMessage);
794 
795  //remove progress bar
796  window->getStatus()->setStatus( tr("Exporting photos complete.") );
797 
798  //nolonger busy
799  setBusy(false);
801  if(window->getLayout()->getSubalbum() != NULL)
803  qApp->restoreOverrideCursor();
804 }
805 //==============================================
807 {
808  //setup dialog title and default path
809  QString dialogTitle = tr( "Export Large Images" );
810 
811  //new directory name in which all images will be contained
812  QString newDir;
813  if(getAlbum()->prevSave())
814  { newDir = QDir( getAlbum()->getSaveLocation() ).dirName() + "_IMAGES"; }
815  else
816  { newDir = getAlbum()->getName() + "_IMAGES"; }
817  newDir = fixFilename( newDir );
818 
819  //get filename from user
820  Q3FileDialog* fd = new Q3FileDialog( this, "file dialog", TRUE );
821  fd->setCaption( tr("Export Location") );
822  fd->setMode( Q3FileDialog::DirectoryOnly );
823  fd->setDir( window->getConfig()->getString( "loadSave", "loadSaveDir" ) );
824 
825  //user canceled operation
826  if ( !fd->exec() == QDialog::Accepted ) { return; }
827 
828  //get export path
829  QString exportPath = QDir::convertSeparators( fd->selectedFile() + "/" + newDir );
830 
831  //check to make sure the album is not in this location, if so raise red flag and abort!!
832  if( getAlbum()->prevSave() && getAlbum()->getSaveLocation().compare( exportPath ) == 0 )
833  {
834  QString errorMessage = tr("Error! Cannot export to album location on disk!");
835  QString errorDesc = tr("Exporting large images to the same location the album is stored will corrupt it and is not allowed. Try using the default location when exporting images, or chose a different directory.");
836  AlertDialog alert( errorMessage, errorDesc,
837  "alertIcons/warning.png", this );
838  alert.exec();
839  return;
840  }
841 
842  //otherwise check if directory already exists, if so warn user and ask before proceeding
843  QDir tmpDir;
844  if(tmpDir.exists( exportPath ) )
845  {
846  QString warningMessage =
847  QString(tr("Warning! A directory named %1 already exists in %2. Continue with export?")).arg
848  ( newDir ).arg( fd->selectedFile() );
849 
850  QuestionDialog sure( tr("Directory Exists!"),
851  warningMessage, "alertIcons/warning.png",
852  this );
853  if(!sure.exec()) { return; }
854  }
855  //else create directory
856  else
857  {
858  if( !tmpDir.mkdir( exportPath ) )
859  {
860  AlertDialog alert( tr("Error creating directory!"),
861  tr("Unable to create directory to export images to.Perhaps you are running out of disk space or you don't have sufficient privileges?"),
862  "alertIcons/warning.png", this );
863  alert.exec();
864  return;
865  }
866  }
867 
868  //set busy flag and disable buttons
869  setBusy(true);
871  if(window->getLayout()->getSubalbum() != NULL)
873  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
874 
875  //setup progress bar
876  int numPhotos = getAlbum()->getNumPhotos();
877  QString exportMessage = tr( "Exporting %1 photos" );
878  window->getStatus()->showProgressBar( exportMessage.arg(numPhotos), numPhotos );
879  qApp->processEvents();
880 
881  //export large images
882  getAlbum()->exportLargeImages(window->getStatus(), exportPath, exportMessage);
883 
884  //remove progress bar
885  window->getStatus()->setStatus( tr("Exporting photos complete.") );
886 
887  //nolonger busy
888  setBusy(false);
890  if(window->getLayout()->getSubalbum() != NULL)
892  qApp->restoreOverrideCursor();
893 }
894 //==============================================
895 void TitleWidget::loadAlbum(QString albumXML)
896 {
897  //disable user input
898  window->getStatus()->grabInput();
899 
900  //enable busy cursor, set busy flag, and deactivate buttons
901  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
902  setBusy(true);
904  if(window->getLayout()->getSubalbum() != NULL)
906 
907  //store load/save location
908  QDir lastDir = QDir( QFileInfo(albumXML).dirPath() );
909  lastDir.cdUp();
910  window->getConfig()->setString( "loadSave", "loadSaveDir", lastDir.path() );
911 
912  //create a new album (with no subalbums, hense false)
913  delete albm;
914 
915  albm = new Album( createTmpDir( QFileInfo(albumXML).dirPath() ), false );
916  if(albm->getTmpDir().isNull() )
917  {
918  AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
919  "alertIcons/warning.png", this );
920  alert.exec();
921  quitApplication();
922  }
923 
924  //attempt to load xml file
925  int errorCode = albm->importFromDisk(window->getStatus(), albumXML,
926  window->getConfig()->getBool( "loadSave", "disableCheckPhotoMods" ) );
927 
928  //if no subalbums in album then hide subalbum annotations
929  if(albm->getFirstSubalbum() == NULL)
930  {
931  subalbumAnnotationFrame->hide();
933  }
934 
935  //reset editing interface since old pointers are invalid
936  window->getLayout()->getSubalbum()->setSubalbum( NULL );
937  refresh();
938 
939  //set album as not modified
940  albm->setModified(false);
941 
942  //update recent albums listing
944  QString("%1").arg(albm->getNumPhotos()), false );
946 
947  //nolonger busy
948  qApp->restoreOverrideCursor();
949  setBusy(false);
951  if(window->getLayout()->getSubalbum() != NULL)
953 
954  //enable user input
956 
957  //load successful
958  if(errorCode == ALBUM_LOADED)
959  {
960  //enable "revert" menu option
961  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );
962 
963  //update presentation command based on if there are photos in this album
964  updateMenus();
965  }
966  //else display appropriate error message
967  else
968  {
969  QString errorMessage, errorDescription;
970  if(errorCode == ALBUM_READ_ERROR)
971  {
972  errorMessage = tr("Unable to open file!");
973  errorDescription = tr("An error was encountered attempting to load the XML file. Perhaps you do not have read access?");
974  }
975  else if(errorCode == ALBUM_XML_ERROR)
976  {
977  errorMessage = tr("Unable to construct DOM!");
978  errorDescription = tr("The XML file you selected is not valid XML.");
979  }
980  else
981  {
982  errorMessage = tr("Unknown loading error!");
983  errorDescription = tr("An unknown error was encountered loading the specified file.");
984  }
985 
986  AlertDialog alert( errorMessage, errorDescription, "alertIcons/warning.png", this );
987  alert.exec();
988  }
989 }
990 //==============================================
992 {
993  //if album not previously saved then
994  //run saveas dialog
995  if(!getAlbum()->prevSave())
996  {
997  saveAsAlbum();
998  return;
999  }
1000 
1001  //if previously used theme not available for use again alert user,
1002  //then run saveas dialog
1003  if(!SaveDialog::themeAvailable( getAlbum()->getTheme() ))
1004  {
1005  AlertDialog alert( tr("Previous theme not available!"),
1006  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."),
1007  "alertIcons/warning.png", this );
1008  alert.exec();
1009  saveAsAlbum();
1010  return;
1011  }
1012 
1013  //set busy flag and disable buttons
1014  setBusy(true);
1016  if(window->getLayout()->getSubalbum() != NULL)
1017  window->getLayout()->getSubalbum()->updateButtons(false);
1018  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
1019 
1021 
1022  window->getConfig()->setString( "loadSave", "lastUsedTheme", getAlbum()->getTheme() );
1023 
1024  //update recent albums listing
1026  QString("%1").arg(albm->getNumPhotos()), false );
1028 
1029  //enable revert command since saved album now exists
1030  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );
1031 
1032  //nolonger busy
1033  setBusy(false);
1035  if(window->getLayout()->getSubalbum() != NULL)
1037  qApp->restoreOverrideCursor();
1038 }
1039 //==============================================
1041 {
1042  //setup dialog title and default path
1043  QString dialogTitle = tr( "Save As" );
1044  QString defaultPath;
1045 
1046  if(getAlbum()->prevSave())
1047  defaultPath = getAlbum()->getSaveLocation();
1048  else
1049  {
1050  defaultPath = getAlbum()->getName();
1051  defaultPath.replace( QChar(' '), "_" );
1052  defaultPath.replace( "<", "" );
1053  defaultPath.replace( ">", "" );
1054  defaultPath.replace( "&", "and" );
1055  defaultPath.replace( "\"", "" );
1056  defaultPath.replace( "\'", "" );
1057  defaultPath.replace( "?", "" );
1058  defaultPath = QDir::convertSeparators
1059  ( window->getConfig()->getString( "loadSave", "loadSaveDir" ) + "/" + defaultPath );
1060  }
1061 
1062  //get directory name in which album directory will be placed in
1063  QString theme, savePath;
1064 
1065  //if abum saved before then auto select last used theme
1066  if(getAlbum()->getTheme().compare("-1") != 0)
1067  theme = getAlbum()->getTheme();
1068  else
1069  {
1070  if(window->getConfig()->getString( "loadSave", "defaultTheme" ).compare( "Last Used" ) == 0)
1071  theme = window->getConfig()->getString( "loadSave", "lastUsedTheme" );
1072  else
1073  theme = window->getConfig()->getString( "loadSave", "defaultTheme" );
1074  }
1075 
1076  if( !SaveDialog::selectThemeAndPath( dialogTitle, defaultPath, theme, savePath ) )
1077  return;
1078 
1079  //check if directory already exists, if not attempt to create it
1080  QDir d(savePath);
1081  if(!d.exists())
1082  {
1083  if(!d.mkdir(savePath))
1084  {
1085  AlertDialog alert( tr("Error creating directory!"),
1086  tr("Unable to create directory to save album in. Perhaps you are running out of disk space or you don't have sufficient privileges?"),
1087  "alertIcons/warning.png", this );
1088  alert.exec();
1089  return;
1090  }
1091  }
1092  else
1093  {
1094  if(!d.isReadable())
1095  {
1096  AlertDialog alert( tr("Destination directory not readable!"),
1097  tr("The destination directory is not readable. Perhaps you don't have sufficient privileges?"),
1098  "alertIcons/warning.png", this );
1099  alert.exec();
1100  return;
1101  }
1102  }
1103 
1104  //store this load/Save location
1105  QDir lastDir = QDir( savePath );
1106  lastDir.cdUp();
1107  window->getConfig()->setString( "loadSave", "loadSaveDir", lastDir.path() );
1108  window->getConfig()->setString( "loadSave", "lastUsedTheme", theme );
1109 
1110  //set busy flag and disable buttons
1111  setBusy(true);
1113  if(window->getLayout()->getSubalbum() != NULL)
1114  window->getLayout()->getSubalbum()->updateButtons(false);
1115  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
1116 
1117  //save
1118  getAlbum()->exportToDisk(window->getStatus(), savePath, theme);
1119  window->getConfig()->setString( "misc", "defaultAuthor", albumAuthorVal->text() );
1120 
1121  //update recent albums listing
1123  QString("%1").arg(albm->getNumPhotos()), false );
1125 
1126  //enable revert command since saved album now exists
1127  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );
1128 
1129  //nolonger busy
1130  setBusy(false);
1132  if(window->getLayout()->getSubalbum() != NULL)
1134  qApp->restoreOverrideCursor();
1135 }
1136 //==============================================
1138 {
1139  //create window and center if not already present
1140  if(albumStats == NULL)
1141  {
1143  connect( albumStats, SIGNAL(closed()),
1144  this, SLOT(albumStatisticsClosed()));
1145  albumStats->show();
1147  }
1148 
1149  albumStats->raise();
1150  albumStats->setActiveWindow();
1151 }
1152 //==============================================
1154 {
1155  //if no subalbum or photos selected ignore command
1156  if(window->getLayout()->getSubalbum() == NULL ||
1158  return;
1159 
1160  //ask user if they are sure they want to remove selected photo descriptions
1161  if( window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
1162  {
1163  QuestionDialog sure( tr("Remove Selected Photo Descriptions?"),
1164  tr("This action cannot be undone. Are you sure you want to proceed?"),
1165  "alertIcons/warning.png",
1166  this );
1167  if(!sure.exec())
1168  return;
1169  }
1170 
1171  //proceed with stripping of photo descriptions
1173 }
1174 //==============================================
1176 {
1178 }
1179 //==============================================
1181 {
1182  //create window and center if not already present
1183  if(settingsWindow == NULL)
1184  {
1186  connect( settingsWindow, SIGNAL(closed()),
1187  this, SLOT(settingsWindowClosed()));
1188  settingsWindow->show();
1190  }
1191 
1192  settingsWindow->raise();
1193  settingsWindow->setActiveWindow();
1194 }
1195 //==============================================
1197 {
1198  //create window and center if not already present
1199  if(about == NULL)
1200  {
1201  about = new About(mode);
1202  connect( about, SIGNAL(closed()),
1203  this, SLOT(aboutClosed()));
1204  about->show();
1206  }
1207 
1208  about->raise();
1209  about->setActiveWindow();
1210 }
1211 //==============================================
1213 {
1214  //create window and center if not already present
1215  if(helpWindow == NULL)
1216  {
1217  helpWindow = new HelpWindow(0);
1218  connect( helpWindow, SIGNAL(closed()),
1219  this, SLOT(helpClosed()));
1220  helpWindow->show();
1222  }
1223 
1224  helpWindow->raise();
1225  helpWindow->setActiveWindow();
1226 }
1227 //==============================================
1229 {
1230  delete albumStats;
1231  albumStats = NULL;
1232 }
1233 //==============================================
1235 {
1236  delete about;
1237  about = NULL;
1238 }
1239 //==============================================
1241 {
1242  delete helpWindow;
1243  helpWindow = NULL;
1244 }
1245 //==============================================
1247 {
1248  delete settingsWindow;
1249  settingsWindow = NULL;
1250 }
1251 //==============================================
1253 {
1254  return busy;
1255 }
1256 //==============================================
1257 void TitleWidget::setBusy(bool val)
1258 {
1259  busy = val;
1260 
1261  //disable/enable file operations
1262  if(busy)
1263  {
1264  file->setItemEnabled(NEW_ALBUM, false);
1265  file->setItemEnabled(OPEN_ALBUM, false);
1266  file->setItemEnabled(SAVE_ALBUM, false);
1267  file->setItemEnabled(SAVEAS_ALBUM, false);
1268  }
1269  else
1270  {
1271  file->setItemEnabled(NEW_ALBUM, true);
1272  file->setItemEnabled(OPEN_ALBUM, true);
1273  file->setItemEnabled(SAVE_ALBUM, true);
1274  file->setItemEnabled(SAVEAS_ALBUM, true);
1275  }
1276 }
1277 //==============================================
1279 {
1280  window->close();
1281 }
1282 //==============================================
1283 void TitleWidget::dragEnterEvent( QDragEnterEvent* e)
1284 {
1285  e->accept(true);
1286 }
1287 //==============================================
1288 void TitleWidget::dropEvent( QDropEvent* e )
1289 {
1290  //force redraw so we don't see missing unpainted
1291  //region while we resize an image which takes a while.
1292  repaint(false);
1293  qApp->processEvents();
1294 
1295  //if the source is not the origanize icon view then ignore the event
1296  if(e->source() == NULL ||
1297  e->source()->parentWidget() != window->getLayout()->getSubalbum()->getPhotos())
1298  return;
1299 
1300  if( e->pos().x() < (width() / 2) )
1301  setAlbumImage();
1302  else
1303  setSubalbumImage();
1304 }
1305 //==============================================
1306 QString TitleWidget::createTmpDir(QString albumPath)
1307 {
1308  //if album path provided attempt to create tmp directory in there to
1309  //minimize cost of doing moves when saving album changes.
1310  //the other reasoning is that user will have hopefully provided enough
1311  //space for saving large files on directory where they previously saved,
1312  //so this minmizes the chance of running out of disk hopefully
1313  if(!albumPath.isNull())
1314  {
1315  QDir rootDir( albumPath );
1316  if(rootDir.exists( "tmp" ) || rootDir.mkdir( "tmp" ))
1317  return QDir::convertSeparators( albumPath + "/tmp" );
1318  }
1319 
1320  //otherwise create unique tmp dir under scratch dir user specified in preferences
1321  QDate date = QDate::currentDate();
1322  QTime time = QTime::currentTime();
1323  QString baseDir = window->getConfig()->getString( "loadSave", "tempImageDirectory" );
1324 
1325  QDir testPath(baseDir);
1326  if(!testPath.exists())
1327  {
1328  window->getConfig()->resetSetting( "loadSave", "tempImageDirectory" );
1329  baseDir = window->getConfig()->getString( "loadSave", "tempImageDirectory" );
1330  }
1331 
1332  QString tmpDir = QString("albumshaper_tmp%1%2%3%4%5%6%7").arg( date.year() ).arg( date.month() ).arg
1333  ( date.day() ).arg( time.hour() ).arg( time.minute() ).arg( time.second() ).arg( time.msec() );
1334 
1335  QDir rootDir( baseDir );
1336  if(rootDir.exists() && (rootDir.exists( tmpDir ) || rootDir.mkdir( tmpDir) ) )
1337  {
1338 /* AlertDialog alert( "tmpDir:", QDir::convertSeparators( QString("(" + baseDir + "/" + tmpDir ) ),
1339  "alertIcons/warning.png", this );
1340  alert.exec();
1341 */
1342  return QDir::convertSeparators( baseDir + "/" + tmpDir );
1343  }
1344  else
1345  {
1346 // cout << "ERROR!\n";
1347  return QString::null;
1348  }
1349 }
1350 //==============================================
1351 //PLATFORM_SPECIFIC_CODE
1352 #if defined(Q_OS_MACX)
1353 void TitleWidget::windowStateChanged(bool state)
1354 {
1355  //disable "Minimize" menu entry if window is minimized
1356  windowMenu->setItemEnabled(WINDOW_MINIMIZE, state);
1357 }
1358 #else
1360 {
1361 //Do nothing
1362 }
1363 #endif
1364 //==============================================
1366 {
1367  //clear recent list
1369 
1370  //refresh menu
1372 }
1373 //==============================================
1375 {
1376  int maxItems = recentAlbums.getMaxItems();
1377  numRecentMenuItems = maxItems + 2; //+2 for seperator and clear entry
1379  customRecentMenuItems = new RecentAlbumMenuItem*[maxItems];
1380 
1381  //insert recent albums into menu
1382  int i;
1383  for(i = 0; i<maxItems; i++)
1384  {
1385  Qt::Key key;
1386  if(i == 0) key = Qt::Key_1;
1387  else if(i == 1) key = Qt::Key_2;
1388  else if(i == 2) key = Qt::Key_3;
1389  else if(i == 3) key = Qt::Key_4;
1390  else if(i == 4) key = Qt::Key_5;
1391  else if(i == 5) key = Qt::Key_6;
1392  else if(i == 6) key = Qt::Key_7;
1393  else if(i == 7) key = Qt::Key_8;
1394  else if(i == 8) key = Qt::Key_9;
1395  else key = Qt::Key_unknown;
1396 
1397  //get album name + location
1398  QString recentName = "recentName";
1399  QString recentLocation = "recentLocation";
1400  QString recentPhotoCount = "recentPhotoCount";
1401 
1402  //----------------------------------------------
1403  //PLATFORM_SPECIFIC_CODE
1404 #if defined(Q_OS_MACX)
1405  //Mac OS X does not support custom painted system menu entries. :(
1406  recentMenuItems[i] = openRecent->insertItem( "uninitialized recent album",
1407  this, SLOT(loadRecentAlbum(int)) );
1408  //----------------------------------------------
1409  //Under other operating systems (Windows, Linux, FreeBSD) use custom recent album menu item
1410  //such that album image is larger and more detail is provided
1411 #else
1413  recentMenuItems[i] = openRecent->insertItem( customRecentMenuItems[i] );
1414  openRecent->connectItem( recentMenuItems[i], this, SLOT(loadRecentAlbum(int)) );
1415 #endif
1416  //----------------------------------------------
1417  //Set accelerator key sequence if valid
1418  if( key != Qt::Key_unknown )
1419  {
1420  openRecent->setAccel( Qt::CTRL+key, recentMenuItems[i] );
1421  openRecent->setItemParameter( recentMenuItems[i], i );
1422  }
1423 
1424  //hide + disable entry
1425  openRecent->setItemVisible( recentMenuItems[i], false );
1426  openRecent->setItemEnabled( recentMenuItems[i], false );
1427  //----------------------------------------------
1428  }
1429 
1430  //insert separator and "clear menu" entry.
1431  recentMenuItems[numRecentMenuItems-2] = openRecent->insertSeparator();
1432  recentMenuItems[numRecentMenuItems-1] = openRecent->insertItem( tr("Clear Menu"),
1433  this,
1434  SLOT(clearOpenRecentMenu()) );
1435 
1436  //hide separtor, disable clear entry
1437  openRecent->setItemVisible( recentMenuItems[numRecentMenuItems-2], false );
1438  openRecent->setItemEnabled( recentMenuItems[numRecentMenuItems-1], false );
1439 }
1440 //==============================================
1442 {
1443  //update text, visibility, and enabled bit for all items in list
1444  int i;
1445 
1446 #ifndef Q_OS_MACX
1447  int maxWidth=0;
1448 #endif
1449 
1450  for(i=0; i<numRecentMenuItems; i++)
1451  {
1452  //----------------------------------------------
1453  //item - update fields, enable, and show
1454  QString recentName, recentLocation, recentPhotoCount;
1455  QDir tempDir;
1456  if( i < recentAlbums.numEntries())
1457  {
1458  //get album name + location
1459  recentAlbums.getEntry( i, recentName, recentLocation, recentPhotoCount );
1460  //----------------------------------------------
1461  //PLATFORM_SPECIFIC_CODE
1462  //Mac OS X does not support custom painted system menu entries. :(
1463 #if defined(Q_OS_MACX)
1464  QString albumImageLocation = QDir::convertSeparators( recentLocation + "/img/album.jpg" );
1465 
1466  //don't display photo count if not available (-1)
1467  if(recentPhotoCount.compare("-1") == 0)
1468  recentPhotoCount = "";
1469  else
1470  recentPhotoCount = " (" + recentPhotoCount + ")";
1471 
1472  //if album image exits resize it and use for menu item icon
1473  if( tempDir.exists( albumImageLocation ) )
1474  {
1475  //scale image
1476  QImage scaledAlbumImage;
1477  scaleImage( albumImageLocation, scaledAlbumImage, 32, 32 );
1478 
1479  //use text and pixmap
1480  QPixmap scaledAlbumImagePixmap;
1481  scaledAlbumImagePixmap.convertFromImage( scaledAlbumImage );
1482 
1483  openRecent->changeItem( recentMenuItems[i],
1484  QIcon( scaledAlbumImagePixmap ),
1485  QString("%1%2").arg(recentName).arg(recentPhotoCount) );
1486  }
1487  //otherwise simply display the album name and number of phots (if available)
1488  else
1489  {
1490  //using just text
1491  openRecent->changeItem( recentMenuItems[i],
1492  QIcon(NULL),
1493  QString("%1%2").arg(recentName).arg(recentPhotoCount) );
1494  }
1495  //----------------------------------------------
1496  //Under other operating systems (Windows, Linux, FreeBSD) use custom recent album menu item
1497  //such that album image is larger and more detail is provided
1498 #else
1499  customRecentMenuItems[i]->changeItem( recentName, recentLocation, recentPhotoCount );
1500  maxWidth = QMAX( maxWidth, customRecentMenuItems[i]->sizeHint().width() );
1501 #endif
1502  //----------------------------------------------
1503  openRecent->setItemEnabled( recentMenuItems[i], true );
1504  openRecent->setItemVisible( recentMenuItems[i], true );
1505 
1506  //if the Album.xml file is unavailable then disable menu entry
1507  if( !tempDir.exists( QDir::convertSeparators(recentLocation + "/Album.xml") ) )
1508  openRecent->setItemEnabled( recentMenuItems[i], false );
1509  }
1510  //----------------------------------------------
1511  //hidden item - disable and hide
1512  else if( i >= recentAlbums.numEntries() &&
1513  i < numRecentMenuItems-2 )
1514  {
1515  openRecent->setItemEnabled( recentMenuItems[i], false );
1516  openRecent->setItemVisible( recentMenuItems[i], false );
1517  }
1518  //----------------------------------------------
1519  //separtor - show if one or more items in list
1520  else if (i == numRecentMenuItems-2)
1521  {
1522  openRecent->setItemVisible( recentMenuItems[numRecentMenuItems-2],
1523  recentAlbums.numEntries() > 0 );
1524  }
1525  //----------------------------------------------
1526  //clear items - enable if items in list
1527  else if (i == numRecentMenuItems-1)
1528  {
1529  openRecent->setItemEnabled( recentMenuItems[numRecentMenuItems-1],
1530  recentAlbums.numEntries() > 0 );
1531  }
1532  //----------------------------------------------
1533  }
1534 
1535 
1536  //pass over custom menu items a second time letting them know the maximum item width
1537 #ifndef Q_OS_MACX
1538  for(i=0; i<recentAlbums.numEntries(); i++)
1539  {
1540  customRecentMenuItems[i]->setMaxWidth( maxWidth );
1541  }
1542 #endif
1543 
1544 }
1545 //==============================================
1547 {
1548  return &recentAlbums;
1549 }
1550 //==============================================
1551 void TitleWidget::updateMenus(bool anySelected, bool anyRevertable)
1552 {
1553  //no photos? disable begin presentation command
1554 // tools->setItemEnabled( BEGIN_PRESENTATION, albm->getNumPhotos() != 0 );
1555 // tools->setItemEnabled( BEGIN_PRESENTATION_AT, albm->getNumPhotos() != 0 );
1556 
1557  //none selected? disable removing photo descriptions
1558  photoMenu->setItemEnabled( REMOVE_DESCRIPTIONS, anySelected );
1559 
1560  //none revertable? disable revert photos
1561  photoMenu->setItemEnabled( REVERT_PHOTOS, anyRevertable );
1562 }
1563 //==============================================
bool albumModified()
Returns true if album has been modified since the last save operation.
Definition: album.cpp:139
int numRecentMenuItems
Definition: titleWidget.h:220
void albumStatistics()
Pops up album statistics window.
QLineEdit * albumNameVal
Definition: titleWidget.h:249
#define SLIDE_IN_LEFT
Definition: ALabel.h:20
QLabel * albumName
Definition: titleWidget.h:248
void revertPhotos()
Reverts all selected photos in organize mode, or currently shown photo if in editing mode...
void setDescription(QString val)
Sets the album description.
Definition: album.cpp:168
void setPixmap(const QPixmap &p)
animates setting an image
Definition: ALabel.cpp:81
Q3Frame * subalbumAnnotationFrame
Definition: titleWidget.h:257
QString getDescription()
Gets the album description.
Definition: album.cpp:125
QString getName()
Gets the album name.
Definition: album.cpp:124
Q3PopupMenu * file
File menu.
Definition: titleWidget.h:215
int EXPORT_SMALL_WEB_GALLERY
Definition: titleWidget.h:294
A configurable alert dialog that displays an alert/error message.
Definition: alertDialog.h:36
Q3PopupMenu * openRecent
Open recent submenu.
Definition: titleWidget.h:218
void changeItem(QString albumName, QString albumLocation, QString numPhotos)
updates entry as per arguments passed (used by constructor during intiailization as well) ...
void centerWindow(QWidget *window)
Definition: guiTools.cpp:26
QString getImageFilename()
Gets the image filename.
Definition: photo.cpp:192
#define LARGE
Definition: album.h:19
void setMaxWidth(int val)
after all menu items have been refreshed hint at maximum width so we can adequately position the acce...
A photo consists of a full size image, a smaller slide show image, a very small thumbnail image...
Definition: photo.h:44
void setRepresentativeImage(QString imageFilename)
sets a sized representative image
Definition: subalbum.cpp:125
QString fixFilename(QString filename)
Replaces invalid characters in filenames with valid ones.
Definition: fileTools.cpp:137
void refreshCollectionAnnotations(Subalbum *collection)
Update displayed collection name and cover image.
RecentAlbumMenuItem ** customRecentMenuItems
Definition: titleWidget.h:221
void dragEnterEvent(QDragEnterEvent *e)
Help window widget.
Definition: helpWindow.h:28
QLineEdit * albumAuthorVal
Definition: titleWidget.h:253
void saveAlbum()
Saves album.
void newAlbum()
Resets to empty album.
Window * window
Window pointer.
Definition: titleWidget.h:268
#define FADE_TRANSITION
Definition: ALabel.h:24
void stripDescriptionsFromSelectedPhotos()
Strip descriptions from selected photos.
Photo * getSelectedPhoto()
Returns currently selected photo. If no or multiple photos selected returns NULL. ...
void dropEvent(QDropEvent *e)
void unsetAlbumImage()
Unsets the Album Image.
QString getSaveLocation()
Returns the current save location of all images.
Definition: album.cpp:141
Top level widget, encapsulates the title widget, the layout widget, and the toolbar widget...
Definition: window.h:39
void updateMenus(bool anySelected=false, bool anyRevertable=false)
update begin presentation menu entry - disabled when no photos in album
void showProgressBar(QString message, int numSteps)
Initializes the progress bar.
StatusWidget * getStatus()
returns a pointer to the status widget
Definition: window.cpp:198
QString getString(QString group, QString key)
Fetch string setting.
#define MEDIUM
Definition: album.h:18
Q3Frame * albumAnnotationFrame
Definition: titleWidget.h:246
void unsetSubalbumImage()
Unsets the Subalbum Image.
bool getBool(QString group, QString key)
Fetch bool setting.
#define ALBUM_XML_ERROR
Definition: album.h:24
void resetSetting(QString group, QString key)
Resets a setting to it&#39;s default value.
void quitApplication()
Quit slot.
QString getThumbnailFilename()
Gets the thumbnail filename.
Definition: photo.cpp:194
void aboutProgram(int mode=ABOUT)
Pops up about dialog.
void setString(QString group, QString key, QString value)
Sets a setting value, if group does not exist it is created, if setting does not exist it is also cre...
ALabel * subalbumImage
Definition: titleWidget.h:258
void setAuthor(QString val)
Sets the album author.
Definition: album.cpp:177
QPixmap * getRepresentativeImage(int size)
Returns the representative image.
Definition: album.cpp:128
A custom menu entry, displays album image, name, and number of photos.
#define SMALL
Definition: album.h:17
QLineEdit * subalbumNameVal
Definition: titleWidget.h:260
void subalbumNameChanged()
Emitted when user changes subalbum name.
void removePixmap(bool forceImmediate=false)
animates removing an image
Definition: ALabel.cpp:136
void settingsWindowClosed()
void setBusy(bool val)
set program busy state
ALabel * albumImage
Definition: titleWidget.h:247
void setAlbumImage()
Sets the Album Image.
#define REP_IMAGE_HEIGHT
Definition: config.h:29
#define ALBUM_LOADED
Definition: album.h:22
bool busy
Is the program currently busy? helps block other operations.
Definition: titleWidget.h:283
int * recentMenuItems
Definition: titleWidget.h:219
QString IMAGE_PATH
Definition: config.cpp:18
void saveAsAlbum()
Saves album as.
Album Statistics Window.
int importFromDisk(StatusWidget *status, QString fileName, bool disableCheckPhotoMods)
Imports album from XML format, returning int indicates success or not.
Definition: album.cpp:295
Q3GridLayout * subalbumAnnotationGrid
Subalbum annotation grid.
Definition: titleWidget.h:256
AlbumStatistics * albumStats
Album Statistics dialog pointer.
Definition: titleWidget.h:271
Q3Frame * mainFrame
Definition: titleWidget.h:242
void refreshOpenRecentMenu()
Refreshes open recent menu.
void storeAnnotations()
Store annotations.
static bool selectThemeAndPath(QString titleMessage, QString defaultPath, QString &theme, QString &path)
Definition: saveDialog.cpp:276
void removeSelectedPhotoDesc()
Strip descriptions from selected photos.
void setStatus(QString message)
Update message.
bool getBusy()
is program busy?
Configuration * getConfig()
get setting object
Definition: window.cpp:235
void revertPhotos()
Revert selected photos to original form.
static bool themeAvailable(QString theme)
Definition: saveDialog.cpp:296
Q3IconViewItem * getCurrentSelection()
Returns current selection.
QLabel * albumDescription
Definition: titleWidget.h:250
void setSubalbumImage()
Sets the Subalbum Image.
Definition: ALabel.h:41
void setSubalbum(Subalbum *salbum)
Resets the subalbum this subalbum widget is displaying.
int getNumPhotos()
Returns the number of photos.
Definition: album.cpp:146
QString tmpDirErrorDesc
Definition: titleWidget.h:309
About window widget.
Definition: about.h:38
A subalbum contains photos.
Definition: subalbum.h:48
int width
Definition: blur.cpp:79
void setModified(bool val=true)
Sets the album as modified.
Definition: album.cpp:1418
void setRepresentativeImages(QString imageFilename)
Sets the representative image.
Definition: album.cpp:186
void insertEntry(QString name, QString location, QString photos="-1", bool insertAtBack=true)
QLabel * albumAuthor
Definition: titleWidget.h:252
About * about
About dialog pointer.
Definition: titleWidget.h:277
void useAnimation(bool val)
Use animation for rep images?
void loadAlbum()
Loads an album specified with file chooser.
void releaseInput()
void albumStatisticsClosed()
Frees album statistics dialog once closed.
This class maintains and handles saving and loading a list of recently viewed albums.
Definition: recentAlbums.h:26
Displays subalbum icon and name.
QLabel * subalbumName
Definition: titleWidget.h:259
LayoutWidget * getLayout()
returns a pointer to the layout object
Definition: window.cpp:193
int REVERT_TO_SAVED_ALBUM
Definition: titleWidget.h:293
#define ALBUM_READ_ERROR
Definition: album.h:23
void setAlbum(Album *val)
Sets new pointer to the album object.
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
Definition: imageTools.cpp:157
#define WIDGET_SPACING
Definition: config.h:31
void setAnimationMethods(int setMethod=APPEAR_IMMEDIATELY, int removalMethod=DISAPPEAR_IMMEDIATELY, int resetMethod=APPEAR_IMMEDIATELY, int removalBeforeResetMethod=DISAPPEAR_IMMEDIATELY)
alter animation methods
Definition: ALabel.cpp:71
bool proceedWithLoad()
Helper function for load methods, checks if there are any unsaved changes and if so warns user any su...
QPixmap * getRepresentativeImage(int size)
gets a sized representative image
Definition: subalbum.cpp:87
void loadRecentAlbum(int index)
Loads a recent album.
void settings()
Pops up settings window.
QMenuBar * menu
Menubar file menu and help menu inserted in.
Definition: titleWidget.h:212
Subalbum * getFirstSubalbum()
Returns a pointer to the first Subalbum.
Definition: album.cpp:135
void getEntry(int index, QString &name, QString &location, QString &photoCount)
QString getDescription()
Gets the Subalbum description.
Definition: subalbum.cpp:85
void exportSmallWebGallery()
Export small web gallery (excludes full size images and Album.xml file)
Album * albm
Backend album object.
Definition: titleWidget.h:265
int exportLargeImages(StatusWidget *status, QString exportPath, QString exportMessage)
Export fullsize images (excludes slideshow and thumbnail images, album and collection iamges...
Definition: album.cpp:726
QLineEdit * albumDescriptionVal
Definition: titleWidget.h:251
bool prevSave()
Returns true if album previously saved to disk.
Definition: album.cpp:138
QString createTmpDir(QString albumPath=QString::null)
TitleWidget(QWidget *parent=0, const char *name=0)
Creates layout.
Definition: titleWidget.cpp:68
Subalbum * getSubalbum()
returns a pointer to the backend subalbum
RecentAlbums recentAlbums
Definition: titleWidget.h:312
QString getTmpDir()
Returns the temporary directory for use when modifying and adding new images.
Definition: album.cpp:142
SubalbumWidget * getSubalbum()
Returns a pointer to the subalbum.
void exportLargeImages()
Export large images only to a new directory for printing purposes.
Q3PopupMenu * tools
Tools menu.
Definition: titleWidget.h:228
void clearOpenRecentMenu()
Clears albums from open recent menu.
Displays subalbum layout.
Subalbum * getSelectedSubalbum()
Returns the currently selected subalbum.
QString getName()
Gets the Subalbum Name.
Definition: subalbum.cpp:84
void updateButtons(bool enable)
Activates/Deactives create/delete buttons.
#define SLIDE_OUT_LEFT
Definition: ALabel.h:21
void updateButtons(bool enable)
Activates/Deactives remove/rotate buttons.
void setName(QString val)
Sets the Subalbum Name.
Definition: subalbum.cpp:107
void help()
Pops up HelpWindow.
bool anyPhotosSelected()
Returns true if any phtos are selected.
Q3PopupMenu * helpMenu
Window menu, only used in OSX.
Definition: titleWidget.h:238
Q3GridLayout * mainGrid
Main grid.
Definition: titleWidget.h:241
An album contains Subalbums.
Definition: album.h:52
bool detectModifications
Definition: titleWidget.h:286
Q3GridLayout * albumAnnotationGrid
Album annotation grid.
Definition: titleWidget.h:245
QString tmpDirErrorMessage
error message and description when temp directory cannot be created
Definition: titleWidget.h:309
void revertToSaved()
Revert to last saved album.
Configuration/Settings Interface.
ConfigurationWidget * settingsWindow
Settings dialog pointer.
Definition: titleWidget.h:274
int exportCompressedWebAlbum(StatusWidget *status, QString exportLocation, QString exportMessage)
Export a compressed web album (excludes full size images and xml data)
Definition: album.cpp:616
void setDescription(QString val)
Sets the Subalbum description.
Definition: subalbum.cpp:116
int REVERT_PHOTOS
Definition: titleWidget.h:299
int SAVEAS_ALBUM
Definition: titleWidget.h:292
QLineEdit * subalbumDescriptionVal
Definition: titleWidget.h:262
Q3PopupMenu * photoMenu
Photos menu.
Definition: titleWidget.h:225
QString getAuthor()
Gets the album author.
Definition: album.cpp:126
SubalbumsWidget * getSubalbums()
Returns a pointer to the subalbums.
Album * getAlbum()
Returns a pointer to the album object.
QString getTheme()
Returns currently selected theme.
Definition: album.cpp:143
RecentAlbums * getRecentAlbums()
returns handle to recent albums object
int EXPORT_LARGE_IMAGES
Definition: titleWidget.h:295
void refresh()
refreshes the layout
Definition: window.cpp:203
void clearList()
QLabel * subalbumDescription
Definition: titleWidget.h:261
Q3IconView * getPhotos()
Returns pointer to icon view.
~TitleWidget()
Deletes stuff!
void setName(QString val)
Sets the album name.
Definition: album.cpp:159
void populateOpenRecentMenu()
Populates the open recent menu with a default set of 9 items + clear.
int exportToDisk(StatusWidget *status, QString dirName, QString themeName)
Exports album in XML and HTML format, along with resized images.
Definition: album.cpp:452
void refresh()
Refreshs data from backend objects.
void windowStateChanged(bool state)
Enables/disables "minimize" window menu entry depending on window state.
A configurable question dialog that returns true/false.
HelpWindow * helpWindow
HelpWindow pointer.
Definition: titleWidget.h:280
int REMOVE_DESCRIPTIONS
photos menu item id&#39;s
Definition: titleWidget.h:298
void aboutClosed()
Frees about dialog once closed.
void helpClosed()
Frees HelpWindow once closed.
void updateAlbumAnnotations()
Updates subalbum annotations.