Kraxy/EBN: missing Q_OBJECT
[kphotoalbum.git] / HTMLGenerator / HTMLDialog.cpp
blob72e49090d6ac14ed1ee0734d1d35955acb083f7e
1 /* Copyright (C) 2003-2006 Jesper K. Pedersen <blackie@kde.org>
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "HTMLDialog.h"
20 #include <QComboBox>
22 #include <klocale.h>
23 #include <qlayout.h>
24 #include <klineedit.h>
25 #include <qlabel.h>
26 #include <qspinbox.h>
27 #include <qcheckbox.h>
28 #include <kfiledialog.h>
29 #include <qpushbutton.h>
30 #include "Settings/SettingsData.h"
31 #include <q3hgroupbox.h>
32 #include <kstandarddirs.h>
33 #include <kmessagebox.h>
34 #include <kfileitem.h>
35 #include <kio/netaccess.h>
36 #include "MainWindow/Window.h"
37 #include "DB/CategoryCollection.h"
38 #include "DB/ImageDB.h"
39 #include "Generator.h"
40 #include "ImageSizeCheckBox.h"
41 #include <QTextEdit>
42 #include <QStringMatcher>
43 using namespace HTMLGenerator;
46 HTMLDialog::HTMLDialog( QWidget* parent )
47 : KPageDialog(parent)
48 , _list()
50 setWindowTitle( i18n("HTML Export") );
51 setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Help );
52 enableButtonOk( false );
53 createContentPage();
54 createLayoutPage();
55 createDestinationPage();
56 setHelp( QString::fromLatin1( "chp-generating-html" ) );
57 connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
60 void HTMLDialog::createContentPage()
62 QWidget* contentPage = new QWidget;
63 KPageWidgetItem* page = new KPageWidgetItem( contentPage, i18n("Content" ) );
64 page->setHeader( i18n("Content" ) );
65 page->setIcon( KIcon( QString::fromLatin1( "document-properties" ) ) );
66 addPage( page );
68 QVBoxLayout* lay1 = new QVBoxLayout( contentPage );
69 QGridLayout* lay2 = new QGridLayout;
70 lay1->addLayout( lay2 );
72 QLabel* label = new QLabel( i18n("Page title:"), contentPage );
73 lay2->addWidget( label, 0, 0 );
74 _title = new KLineEdit( contentPage );
75 label->setBuddy( _title );
76 lay2->addWidget( _title, 0, 1 );
78 // Copyright
79 label = new QLabel( i18n("Copyright:"), contentPage );
80 label->setAlignment( Qt::AlignTop );
81 lay2->addWidget( label, 1, 0 );
82 _copyright = new KLineEdit( contentPage );
83 _copyright->setText( Settings::SettingsData::instance()->HTMLCopyright() );
84 label->setBuddy( _copyright );
85 lay2->addWidget( _copyright, 1, 1 );
87 // Description
88 label = new QLabel( i18n("Description:"), contentPage );
89 label->setAlignment( Qt::AlignTop );
90 lay2->addWidget( label, 2, 0 );
91 _description = new QTextEdit( contentPage );
92 label->setBuddy( _description );
93 lay2->addWidget( _description, 2, 1 );
95 _generateKimFile = new QCheckBox( i18n("Create .kim export file"), contentPage );
96 _generateKimFile->setChecked( Settings::SettingsData::instance()->HTMLKimFile() );
97 lay1->addWidget( _generateKimFile );
99 _inlineMovies = new QCheckBox( i18n( "Inline Movies in pages" ), contentPage );
100 _inlineMovies->setChecked( Settings::SettingsData::instance()->HTMLInlineMovies() );
101 lay1->addWidget( _inlineMovies );
103 // What to include
104 QGroupBox* whatToInclude = new QGroupBox( i18n( "What to Include" ), contentPage );
105 lay1->addWidget( whatToInclude );
106 QGridLayout* lay3 = new QGridLayout( whatToInclude );
108 QCheckBox* cb = new QCheckBox( i18n("Description"), whatToInclude );
109 _whatToIncludeMap.insert( QString::fromLatin1("**DESCRIPTION**"), cb );
110 lay3->addWidget( cb, 0, 0 );
112 _date = new QCheckBox( i18n("Date"), whatToInclude );
113 _date->setChecked( Settings::SettingsData::instance()->HTMLDate() );
114 _whatToIncludeMap.insert( QString::fromLatin1("**DATE**"), _date );
115 lay3->addWidget( _date, 0, 1 );
117 int row=1;
118 int col=0;
119 QString selectionsTmp = Settings::SettingsData::instance()->HTMLIncludeSelections();
120 QStringMatcher* pattern = new QStringMatcher();
121 pattern->setPattern(QString::fromLatin1("**DESCRIPTION**"));
122 cb->setChecked( pattern->indexIn (selectionsTmp) >= 0 ? 1 : 0 );
124 QList<DB::CategoryPtr> categories = DB::ImageDB::instance()->categoryCollection()->categories();
125 for( QList<DB::CategoryPtr>::Iterator it = categories.begin(); it != categories.end(); ++it ) {
126 if ( ! (*it)->isSpecialCategory() ) {
127 QCheckBox* cb = new QCheckBox( (*it)->text(), whatToInclude );
128 lay3->addWidget( cb, row, col%2 );
129 _whatToIncludeMap.insert( (*it)->name(), cb );
130 pattern->setPattern((*it)->name());
131 cb->setChecked( pattern->indexIn (selectionsTmp) >= 0 ? 1 : 0 );
132 if ( ++col % 2 == 0 )
133 ++row;
138 void HTMLDialog::createLayoutPage()
140 QWidget* layoutPage = new QWidget;
141 KPageWidgetItem* page = new KPageWidgetItem( layoutPage, i18n("Layout" ) );
142 page->setHeader( i18n("Layout" ) );
143 page->setIcon( KIcon( QString::fromLatin1( "matrix" )) );
144 addPage(page);
146 QVBoxLayout* lay1 = new QVBoxLayout( layoutPage );
147 QGridLayout* lay2 = new QGridLayout;
148 lay1->addLayout( lay2 );
150 // Thumbnail size
151 QLabel* label = new QLabel( i18n("Thumbnail size:"), layoutPage );
152 lay2->addWidget( label, 0, 0 );
154 QHBoxLayout* lay3 = new QHBoxLayout;
155 lay2->addLayout( lay3, 0, 1 );
157 _thumbSize = new QSpinBox;
158 _thumbSize->setRange( 16, 256 );
160 _thumbSize->setValue( Settings::SettingsData::instance()->HTMLThumbSize() );
161 lay3->addWidget( _thumbSize );
162 lay3->addStretch(1);
163 label->setBuddy( _thumbSize );
165 // Number of columns
166 label = new QLabel( i18n("Number of columns:"), layoutPage );
167 lay2->addWidget( label, 1, 0 );
169 QHBoxLayout* lay4 = new QHBoxLayout;
170 lay2->addLayout( lay4, 1, 1 );
171 _numOfCols = new QSpinBox;
172 _numOfCols->setRange( 1, 10 );
174 label->setBuddy( _numOfCols);
176 _numOfCols->setValue( Settings::SettingsData::instance()->HTMLNumOfCols() );
177 lay4->addWidget( _numOfCols );
178 lay4->addStretch( 1 );
180 // Theme box
181 label = new QLabel( i18n("Theme:"), layoutPage );
182 lay2->addWidget( label, 2, 0 );
183 lay4 = new QHBoxLayout;
184 lay2->addLayout( lay4, 2, 1 );
185 _themeBox = new QComboBox( layoutPage );
186 label->setBuddy( _themeBox );
187 lay4->addWidget( _themeBox );
188 lay4->addStretch( 1 );
189 populateThemesCombo();
191 // Image sizes
192 Q3HGroupBox* sizes = new Q3HGroupBox( i18n("Image Sizes"), layoutPage );
193 lay1->addWidget( sizes );
194 QWidget* content = new QWidget( sizes );
195 QGridLayout* lay5 = new QGridLayout( content );
196 ImageSizeCheckBox* size320 = new ImageSizeCheckBox( 320, 200, content );
197 ImageSizeCheckBox* size640 = new ImageSizeCheckBox( 640, 480, content );
198 ImageSizeCheckBox* size800 = new ImageSizeCheckBox( 800, 600, content );
199 ImageSizeCheckBox* size1024 = new ImageSizeCheckBox( 1024, 768, content );
200 ImageSizeCheckBox* size1280 = new ImageSizeCheckBox( 1280, 1024, content );
201 ImageSizeCheckBox* size1600 = new ImageSizeCheckBox( 1600, 1200, content );
202 ImageSizeCheckBox* sizeOrig = new ImageSizeCheckBox( i18n("Full size"), content );
205 int row = 0;
206 int col = -1;
207 lay5->addWidget( size320, row, ++col );
208 lay5->addWidget( size640, row, ++col );
209 lay5->addWidget( size800, row, ++col );
210 lay5->addWidget( size1024, row, ++col );
211 col =-1;
212 lay5->addWidget( size1280, ++row, ++col );
213 lay5->addWidget( size1600, row, ++col );
214 lay5->addWidget( sizeOrig, row, ++col );
217 QString tmp;
218 if ((tmp = Settings::SettingsData::instance()->HTMLSizes()) != QString::fromLatin1("")) {
219 QStringMatcher* pattern = new QStringMatcher(QString::fromLatin1("320"));
220 size320->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
221 pattern->setPattern(QString::fromLatin1("640"));
222 size640->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
223 pattern->setPattern(QString::fromLatin1("800"));
224 size800->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0 );
225 pattern->setPattern(QString::fromLatin1("1024"));
226 size1024->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
227 pattern->setPattern(QString::fromLatin1("1280"));
228 size1280->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
229 pattern->setPattern(QString::fromLatin1("1600"));
230 size1600->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
231 pattern->setPattern(QString::fromLatin1("-1"));
232 sizeOrig->setChecked( pattern->indexIn (tmp) >= 0 ? 1 : 0);
233 } else
234 size800->setChecked( 1 );
236 _cbs << size800 << size1024 << size1280 << size640 << size1600 << size320 << sizeOrig;
238 lay1->addStretch(1);
241 void HTMLDialog::createDestinationPage()
243 QWidget* destinationPage = new QWidget;
245 KPageWidgetItem* page = new KPageWidgetItem( destinationPage, i18n("Destination" ) );
246 page->setHeader( i18n("Destination" ) );
247 page->setIcon( KIcon( QString::fromLatin1( "drive-harddisk" ) ) );
248 addPage( page );
250 QVBoxLayout* lay1 = new QVBoxLayout( destinationPage );
251 QGridLayout* lay2 = new QGridLayout;
252 lay1->addLayout( lay2 );
254 // Base Directory
255 QLabel* label = new QLabel( i18n("Base directory:"), destinationPage );
256 lay2->addWidget( label, 0, 0 );
258 QHBoxLayout* lay3 = new QHBoxLayout;
259 lay2->addLayout( lay3, 0, 1 );
261 _baseDir = new KLineEdit( destinationPage );
262 lay3->addWidget( _baseDir );
263 label->setBuddy( _baseDir );
265 QPushButton* but = new QPushButton( QString::fromLatin1( ".." ), destinationPage );
266 lay3->addWidget( but );
267 but->setFixedWidth( 25 );
269 connect( but, SIGNAL( clicked() ), this, SLOT( selectDir() ) );
270 _baseDir->setText( Settings::SettingsData::instance()->HTMLBaseDir() );
272 // Base URL
273 label = new QLabel( i18n("Base URL:"), destinationPage );
274 lay2->addWidget( label, 1, 0 );
276 _baseURL = new KLineEdit( destinationPage );
277 _baseURL->setText( Settings::SettingsData::instance()->HTMLBaseURL() );
278 lay2->addWidget( _baseURL, 1, 1 );
279 label->setBuddy( _baseURL );
281 // Destination URL
282 label = new QLabel( i18n("URL for final destination:" ), destinationPage );
283 lay2->addWidget( label, 2, 0 );
284 _destURL = new KLineEdit( destinationPage );
285 _destURL->setText( Settings::SettingsData::instance()->HTMLDestURL() );
286 lay2->addWidget( _destURL, 2, 1 );
287 label->setBuddy( _destURL );
289 // Output Directory
290 label = new QLabel( i18n("Output directory:"), destinationPage );
291 lay2->addWidget( label, 3, 0 );
292 _outputDir = new KLineEdit( destinationPage );
293 lay2->addWidget( _outputDir, 3, 1 );
294 label->setBuddy( _outputDir );
296 label = new QLabel( i18n("<b>Hint: Press the help button for descriptions of the fields</b>"), destinationPage );
297 lay1->addWidget( label );
298 lay1->addStretch( 1 );
301 void HTMLDialog::slotOk()
303 if ( !checkVars() )
304 return;
306 if( activeResolutions().count() < 1 ) {
307 KMessageBox::error( 0, i18n( "You must select at least one resolution." ) );
308 return;
311 accept();
313 Settings::SettingsData::instance()->setHTMLBaseDir( _baseDir->text() );
314 Settings::SettingsData::instance()->setHTMLBaseURL( _baseURL->text() );
315 Settings::SettingsData::instance()->setHTMLDestURL( _destURL->text() );
316 Settings::SettingsData::instance()->setHTMLCopyright( _copyright->text() );
317 Settings::SettingsData::instance()->setHTMLDate( _date->isChecked() );
318 Settings::SettingsData::instance()->setHTMLTheme( _themeBox->currentIndex() );
319 Settings::SettingsData::instance()->setHTMLKimFile( _generateKimFile->isChecked() );
320 Settings::SettingsData::instance()->setHTMLInlineMovies( _inlineMovies->isChecked() );
321 Settings::SettingsData::instance()->setHTMLThumbSize( _thumbSize->value() );
322 Settings::SettingsData::instance()->setHTMLNumOfCols( _numOfCols->value() );
323 Settings::SettingsData::instance()->setHTMLSizes( activeSizes() );
324 Settings::SettingsData::instance()->setHTMLIncludeSelections( includeSelections() );
326 Generator generator( setup(), this );
327 generator.generate();
330 void HTMLDialog::selectDir()
332 KUrl dir = KFileDialog::getExistingDirectoryUrl( _baseDir->text(), this );
333 if ( !dir.url().isNull() )
334 _baseDir->setText( dir.url() );
337 bool HTMLDialog::checkVars()
339 QString outputDir = _baseDir->text() + QString::fromLatin1( "/" ) + _outputDir->text();
342 // Ensure base dir is specified
343 QString baseDir = _baseDir->text();
344 if ( baseDir.isEmpty() ) {
345 KMessageBox::error( this, i18n("<p>You did not specify a base directory. "
346 "This is the topmost directory for your images. "
347 "Under this directory you will find each generated collection "
348 "in separate directories.</p>"),
349 i18n("No Base Directory Specified") );
350 return false;
353 // ensure output directory is specified
354 if ( _outputDir->text().isEmpty() ) {
355 KMessageBox::error( this, i18n("<p>You did not specify an output directory. "
356 "This is a directory containing the actual images. "
357 "The directory will be in the base directory specified above.</p>"),
358 i18n("No Output Directory Specified") );
359 return false;
362 // ensure base dir exists
363 KIO::UDSEntry result;
364 bool ok = KIO::NetAccess::stat( KUrl(baseDir), result, this );
365 if ( !ok ) {
366 KMessageBox::error( this, i18n("<p>Error while reading information about %1. "
367 "This is most likely because the directory does not exist.</p>")
368 .arg( baseDir ) );
369 return false;
372 KFileItem fileInfo( result, KUrl(baseDir) );
373 if ( !fileInfo.isDir() ) {
374 KMessageBox::error( this, i18n("<p>%1 does not exist, is not a directory or "
375 "cannot be written to.</p>").arg( baseDir ) );
376 return false;
380 // test if destination directory exists.
381 bool exists = KIO::NetAccess::exists( KUrl(outputDir), KIO::NetAccess::DestinationSide, MainWindow::Window::theMainWindow() );
382 if ( exists ) {
383 int answer = KMessageBox::warningYesNo( this,
384 i18n("<p>Output directory %1 already exists. "
385 "Usually, this means you should specify a new directory.</p>"
386 "<p>Should %2 be deleted first?</p>").arg( outputDir ).arg( outputDir ),
387 i18n("Directory Exists"), KStandardGuiItem::yes(), KStandardGuiItem::no(),
388 QString::fromLatin1("html_export_delete_original_directory") );
389 if ( answer == KMessageBox::Yes ) {
390 KIO::NetAccess::del( KUrl(outputDir), MainWindow::Window::theMainWindow() );
392 else
393 return false;
395 return true;
398 QList<ImageSizeCheckBox*> HTMLDialog::activeResolutions() const
400 QList<ImageSizeCheckBox*> res;
401 for( QList<ImageSizeCheckBox*>::ConstIterator sizeIt = _cbs.begin(); sizeIt != _cbs.end(); ++sizeIt ) {
402 if ( (*sizeIt)->isChecked() )
403 res << *sizeIt;
405 return res;
408 QString HTMLDialog::activeSizes() const
410 QString res;
411 for( QList<ImageSizeCheckBox*>::ConstIterator sizeIt = _cbs.begin(); sizeIt != _cbs.end(); ++sizeIt ) {
412 if ( (*sizeIt)->isChecked() ) {
413 if (res.length() > 0)
414 res.append(QString::fromLatin1(","));
415 res.append(QString::number((*sizeIt)->width()));
418 return res;
421 QString HTMLDialog::includeSelections() const
423 QString sel;
424 Setup _setup = setup();
426 for( QMap<QString,QCheckBox*>::ConstIterator it = _whatToIncludeMap.begin();
427 it != _whatToIncludeMap.end(); ++it ) {
428 QString name = it.key();
429 if ( _setup.includeCategory(name) ) {
430 if (sel.length() > 0)
431 sel.append(QString::fromLatin1(","));
432 sel.append(name);
435 return sel;
438 void HTMLDialog::populateThemesCombo()
440 QStringList dirs = KGlobal::dirs()->findDirs( "data", QString::fromLocal8Bit("kphotoalbum/themes/") );
441 int i = 0;
442 int theme = 0;
443 int defaultthemes = 0;
444 for(QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it) {
445 QDir dir(*it);
446 QStringList themes = dir.entryList( QDir::Dirs | QDir::Readable );
447 for(QStringList::Iterator it = themes.begin(); it != themes.end(); ++it) {
448 if(*it == QString::fromLatin1(".") || *it == QString::fromLatin1("..")) continue;
449 QString themePath = QString::fromLatin1("%1/%2/").arg(dir.path()).arg(*it);
451 KConfig themeconfig( QString::fromLatin1( "%1/kphotoalbum.theme").arg( themePath ), KConfig::SimpleConfig );
452 KConfigGroup config = themeconfig.group("theme");
453 QString themeName = config.readEntry( "Name" );
454 QString themeAuthor = config.readEntry( "Author" );
455 QString themeDefault = config.readEntry( "Default" );
457 enableButtonOk( true );
458 _themeBox->insertItem( i, i18n( "%1 (by %2)",themeName, themeAuthor ) );
459 _themes.insert( i, themePath );
461 if (themeDefault == QString::fromLatin1("true")) {
462 theme = i;
463 defaultthemes++;
465 i++;
468 if(_themeBox->count() < 1) {
469 KMessageBox::error( this, i18n("Could not find any themes - this is very likely an installation error" ) );
471 if (Settings::SettingsData::instance()->HTMLTheme() >= 0)
472 _themeBox->setCurrentIndex( Settings::SettingsData::instance()->HTMLTheme() );
473 else {
474 _themeBox->setCurrentIndex( theme );
475 if (defaultthemes > 1)
476 KMessageBox::information( this, i18n("More than one theme is set as default, using theme %1", _themeBox->currentText()) );
480 int HTMLDialog::exec(const DB::Result& list)
482 _list = list;
483 return KDialog::exec();
488 Setup HTMLGenerator::HTMLDialog::setup() const
490 Setup setup;
491 setup.setTitle( _title->text() );
492 setup.setBaseDir( _baseDir->text() );
493 setup.setBaseURL( _baseURL->text() );
494 setup.setDestURL( _destURL->text() );
495 setup.setOutputDir( _outputDir->text() );
496 setup.setThumbSize( _thumbSize->value() );
497 setup.setCopyright( _copyright->text() );
498 setup.setDate( _date->isChecked() );
499 setup.setDescription( _description->toPlainText() );
500 setup.setNumOfCols( _numOfCols->value() );
501 setup.setGenerateKimFile( _generateKimFile->isChecked() );
502 setup.setThemePath( _themes[_themeBox->currentIndex()] );
503 for( QMap<QString,QCheckBox*>::ConstIterator includeIt = _whatToIncludeMap.begin();
504 includeIt != _whatToIncludeMap.end(); ++includeIt ) {
505 setup.setIncludeCategory( includeIt.key(), includeIt.value()->isChecked() );
507 setup.setImageList( _list );
509 setup.setResolutions( activeResolutions() );
510 setup.setInlineMovies( _inlineMovies->isChecked() );
511 return setup;
514 #include "HTMLDialog.moc"