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"
49#include "recentAlbumMenuItem.h"
50
52#include "dialogs/about.h"
53#include "help/helpWindow.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"
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
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();
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);
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);
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 {
465 }
466 else
467 {
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//==============================================
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();
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
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//==============================================
895void TitleWidget::loadAlbum(QString albumXML)
896{
897 //disable user input
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();
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 {
933 }
934
935 //reset editing interface since old pointers are invalid
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)
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)
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//==============================================
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//==============================================
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//==============================================
1283void TitleWidget::dragEnterEvent( QDragEnterEvent* e)
1284{
1285 e->accept(true);
1286}
1287//==============================================
1288void 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
1304}
1305//==============================================
1306QString 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)
1353void 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
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//==============================================
1550//==============================================
1551void 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//==============================================
#define FADE_TRANSITION
Definition ALabel.h:24
#define SLIDE_IN_LEFT
Definition ALabel.h:20
#define SLIDE_OUT_LEFT
Definition ALabel.h:21
#define ALBUM_READ_ERROR
Definition album.h:23
#define SMALL
Definition album.h:17
#define ALBUM_LOADED
Definition album.h:22
#define MEDIUM
Definition album.h:18
#define ALBUM_XML_ERROR
Definition album.h:24
#define LARGE
Definition album.h:19
int width
Definition blur.cpp:79
void setPixmap(const QPixmap &p)
animates setting an image
Definition ALabel.cpp:81
void removePixmap(bool forceImmediate=false)
animates removing an image
Definition ALabel.cpp:136
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
About window widget.
Definition about.h:39
Album Statistics Window.
An album contains Subalbums.
Definition album.h:53
Subalbum * getFirstSubalbum()
Returns a pointer to the first Subalbum.
Definition album.cpp:135
void setRepresentativeImages(QString imageFilename)
Sets the representative image.
Definition album.cpp:186
void setAuthor(QString val)
Sets the album author.
Definition album.cpp:177
int importFromDisk(StatusWidget *status, QString fileName, bool disableCheckPhotoMods)
Imports album from XML format, returning int indicates success or not.
Definition album.cpp:295
QString getDescription()
Gets the album description.
Definition album.cpp:125
int exportLargeImages(StatusWidget *status, QString exportPath, QString exportMessage)
Export fullsize images (excludes slideshow and thumbnail images, album and collection iamges,...
Definition album.cpp:726
int exportToDisk(StatusWidget *status, QString dirName, QString themeName)
Exports album in XML and HTML format, along with resized images.
Definition album.cpp:452
void setName(QString val)
Sets the album name.
Definition album.cpp:159
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 setModified(bool val=true)
Sets the album as modified.
Definition album.cpp:1418
QString getTmpDir()
Returns the temporary directory for use when modifying and adding new images.
Definition album.cpp:142
int getNumPhotos()
Returns the number of photos.
Definition album.cpp:146
QString getTheme()
Returns currently selected theme.
Definition album.cpp:143
QString getAuthor()
Gets the album author.
Definition album.cpp:126
void setDescription(QString val)
Sets the album description.
Definition album.cpp:168
QString getSaveLocation()
Returns the current save location of all images.
Definition album.cpp:141
bool albumModified()
Returns true if album has been modified since the last save operation.
Definition album.cpp:139
QString getName()
Gets the album name.
Definition album.cpp:124
QPixmap * getRepresentativeImage(int size)
Returns the representative image.
Definition album.cpp:128
A configurable alert dialog that displays an alert/error message.
Definition alertDialog.h:37
Configuration/Settings Interface.
bool getBool(QString group, QString key)
Fetch bool setting.
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...
void resetSetting(QString group, QString key)
Resets a setting to it's default value.
QString getString(QString group, QString key)
Fetch string setting.
Help window widget.
Definition helpWindow.h:29
void revertPhotos()
Reverts all selected photos in organize mode, or currently shown photo if in editing mode.
SubalbumWidget * getSubalbum()
Returns a pointer to the subalbum.
SubalbumsWidget * getSubalbums()
Returns a pointer to the subalbums.
A photo consists of a full size image, a smaller slide show image, a very small thumbnail image,...
Definition photo.h:45
QString getImageFilename()
Gets the image filename.
Definition photo.cpp:192
QString getThumbnailFilename()
Gets the thumbnail filename.
Definition photo.cpp:194
A configurable question dialog that returns true/false.
A custom menu entry, displays album image, name, and number of photos.
void changeItem(QString albumName, QString albumLocation, QString numPhotos)
updates entry as per arguments passed (used by constructor during intiailization as well)
void setMaxWidth(int val)
after all menu items have been refreshed hint at maximum width so we can adequately position the acce...
This class maintains and handles saving and loading a list of recently viewed albums.
void getEntry(int index, QString &name, QString &location, QString &photoCount)
void insertEntry(QString name, QString location, QString photos="-1", bool insertAtBack=true)
static bool selectThemeAndPath(QString titleMessage, QString defaultPath, QString &theme, QString &path)
static bool themeAvailable(QString theme)
void setStatus(QString message)
Update message.
void showProgressBar(QString message, int numSteps)
Initializes the progress bar.
Displays subalbum icon and name.
Displays subalbum layout.
Photo * getSelectedPhoto()
Returns currently selected photo. If no or multiple photos selected returns NULL.
void setSubalbum(Subalbum *salbum)
Resets the subalbum this subalbum widget is displaying.
void updateButtons(bool enable)
Activates/Deactives remove/rotate buttons.
bool anyPhotosSelected()
Returns true if any phtos are selected.
Q3IconView * getPhotos()
Returns pointer to icon view.
void stripDescriptionsFromSelectedPhotos()
Strip descriptions from selected photos.
Subalbum * getSubalbum()
returns a pointer to the backend subalbum
A subalbum contains photos.
Definition subalbum.h:49
void setRepresentativeImage(QString imageFilename)
sets a sized representative image
Definition subalbum.cpp:125
QString getDescription()
Gets the Subalbum description.
Definition subalbum.cpp:85
void setName(QString val)
Sets the Subalbum Name.
Definition subalbum.cpp:107
QPixmap * getRepresentativeImage(int size)
gets a sized representative image
Definition subalbum.cpp:87
QString getName()
Gets the Subalbum Name.
Definition subalbum.cpp:84
void setDescription(QString val)
Sets the Subalbum description.
Definition subalbum.cpp:116
void updateButtons(bool enable)
Activates/Deactives create/delete buttons.
Subalbum * getSelectedSubalbum()
Returns the currently selected subalbum.
Q3IconViewItem * getCurrentSelection()
Returns current selection.
void dropEvent(QDropEvent *e)
bool detectModifications
void settingsWindowClosed()
QString createTmpDir(QString albumPath=QString::null)
void windowStateChanged(bool state)
Enables/disables "minimize" window menu entry depending on window state.
Q3Frame * albumAnnotationFrame
int REMOVE_DESCRIPTIONS
photos menu item id's
Album * getAlbum()
Returns a pointer to the album object.
QString tmpDirErrorDesc
void albumStatistics()
Pops up album statistics window.
TitleWidget(QWidget *parent=0, const char *name=0)
Creates layout.
Window * window
Window pointer.
void unsetAlbumImage()
Unsets the Album Image.
void revertToSaved()
Revert to last saved album.
RecentAlbums * getRecentAlbums()
returns handle to recent albums object
void loadRecentAlbum(int index)
Loads a recent album.
Q3PopupMenu * tools
Tools menu.
void albumStatisticsClosed()
Frees album statistics dialog once closed.
QLabel * subalbumName
int numRecentMenuItems
QLineEdit * albumDescriptionVal
void revertPhotos()
Revert selected photos to original form.
QLineEdit * albumAuthorVal
void refreshOpenRecentMenu()
Refreshes open recent menu.
QLabel * albumDescription
void aboutClosed()
Frees about dialog once closed.
Q3Frame * subalbumAnnotationFrame
void clearOpenRecentMenu()
Clears albums from open recent menu.
void storeAnnotations()
Store annotations.
void exportLargeImages()
Export large images only to a new directory for printing purposes.
bool proceedWithLoad()
Helper function for load methods, checks if there are any unsaved changes and if so warns user any su...
void setBusy(bool val)
set program busy state
void quitApplication()
Quit slot.
Q3PopupMenu * file
File menu.
void subalbumNameChanged()
Emitted when user changes subalbum name.
HelpWindow * helpWindow
HelpWindow pointer.
void aboutProgram(int mode=ABOUT)
Pops up about dialog.
void updateAlbumAnnotations()
Updates subalbum annotations.
~TitleWidget()
Deletes stuff!
void removeSelectedPhotoDesc()
Strip descriptions from selected photos.
void helpClosed()
Frees HelpWindow once closed.
QLineEdit * subalbumDescriptionVal
int EXPORT_SMALL_WEB_GALLERY
ALabel * albumImage
QString tmpDirErrorMessage
error message and description when temp directory cannot be created
Q3PopupMenu * helpMenu
Window menu, only used in OSX.
void updateMenus(bool anySelected=false, bool anyRevertable=false)
update begin presentation menu entry - disabled when no photos in album
About * about
About dialog pointer.
void setAlbumImage()
Sets the Album Image.
void settings()
Pops up settings window.
int EXPORT_LARGE_IMAGES
void exportSmallWebGallery()
Export small web gallery (excludes full size images and Album.xml file)
QLabel * albumName
Q3Frame * mainFrame
bool getBusy()
is program busy?
void setSubalbumImage()
Sets the Subalbum Image.
Q3GridLayout * subalbumAnnotationGrid
Subalbum annotation grid.
Q3GridLayout * albumAnnotationGrid
Album annotation grid.
QLabel * subalbumDescription
void dragEnterEvent(QDragEnterEvent *e)
QLineEdit * albumNameVal
void help()
Pops up HelpWindow.
ALabel * subalbumImage
void setAlbum(Album *val)
Sets new pointer to the album object.
void unsetSubalbumImage()
Unsets the Subalbum Image.
void saveAlbum()
Saves album.
void populateOpenRecentMenu()
Populates the open recent menu with a default set of 9 items + clear.
RecentAlbums recentAlbums
int REVERT_TO_SAVED_ALBUM
void loadAlbum()
Loads an album specified with file chooser.
AlbumStatistics * albumStats
Album Statistics dialog pointer.
QMenuBar * menu
Menubar file menu and help menu inserted in.
QLabel * albumAuthor
void refresh()
Refreshs data from backend objects.
QLineEdit * subalbumNameVal
void newAlbum()
Resets to empty album.
void saveAsAlbum()
Saves album as.
ConfigurationWidget * settingsWindow
Settings dialog pointer.
void refreshCollectionAnnotations(Subalbum *collection)
Update displayed collection name and cover image.
bool busy
Is the program currently busy? helps block other operations.
Album * albm
Backend album object.
int * recentMenuItems
Q3PopupMenu * openRecent
Open recent submenu.
Q3GridLayout * mainGrid
Main grid.
Q3PopupMenu * photoMenu
Photos menu.
RecentAlbumMenuItem ** customRecentMenuItems
void useAnimation(bool val)
Use animation for rep images?
Top level widget, encapsulates the title widget, the layout widget, and the toolbar widget.
Definition window.h:40
LayoutWidget * getLayout()
returns a pointer to the layout object
Definition window.cpp:193
StatusWidget * getStatus()
returns a pointer to the status widget
Definition window.cpp:198
void refresh()
refreshes the layout
Definition window.cpp:203
Configuration * getConfig()
get setting object
Definition window.cpp:235
QString IMAGE_PATH
Definition config.cpp:18
#define WIDGET_SPACING
Definition config.h:31
#define REP_IMAGE_HEIGHT
Definition config.h:29
QString fixFilename(QString filename)
Replaces invalid characters in filenames with valid ones.
void centerWindow(QWidget *window)
Definition guiTools.cpp:26
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.