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"
24 #include <klineedit.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"
42 #include <QStringMatcher>
43 using namespace HTMLGenerator
;
46 HTMLDialog::HTMLDialog( QWidget
* parent
)
50 setWindowTitle( i18n("HTML Export") );
51 setButtons( KDialog::Ok
| KDialog::Cancel
| KDialog::Help
);
52 enableButtonOk( false );
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" ) ) );
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 );
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 );
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
);
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 );
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 )
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" )) );
146 QVBoxLayout
* lay1
= new QVBoxLayout( layoutPage
);
147 QGridLayout
* lay2
= new QGridLayout
;
148 lay1
->addLayout( lay2
);
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
);
163 label
->setBuddy( _thumbSize
);
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 );
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();
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
);
207 lay5
->addWidget( size320
, row
, ++col
);
208 lay5
->addWidget( size640
, row
, ++col
);
209 lay5
->addWidget( size800
, row
, ++col
);
210 lay5
->addWidget( size1024
, row
, ++col
);
212 lay5
->addWidget( size1280
, ++row
, ++col
);
213 lay5
->addWidget( size1600
, row
, ++col
);
214 lay5
->addWidget( sizeOrig
, row
, ++col
);
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);
234 size800
->setChecked( 1 );
236 _cbs
<< size800
<< size1024
<< size1280
<< size640
<< size1600
<< size320
<< sizeOrig
;
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" ) ) );
250 QVBoxLayout
* lay1
= new QVBoxLayout( destinationPage
);
251 QGridLayout
* lay2
= new QGridLayout
;
252 lay1
->addLayout( lay2
);
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() );
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
);
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
);
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()
306 if( activeResolutions().count() < 1 ) {
307 KMessageBox::error( 0, i18n( "You must select at least one resolution." ) );
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") );
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") );
362 // ensure base dir exists
363 KIO::UDSEntry result
;
364 bool ok
= KIO::NetAccess::stat( KUrl(baseDir
), result
, this );
366 KMessageBox::error( this, i18n("<p>Error while reading information about %1. "
367 "This is most likely because the directory does not exist.</p>")
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
) );
380 // test if destination directory exists.
381 bool exists
= KIO::NetAccess::exists( KUrl(outputDir
), KIO::NetAccess::DestinationSide
, MainWindow::Window::theMainWindow() );
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() );
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() )
408 QString
HTMLDialog::activeSizes() const
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()));
421 QString
HTMLDialog::includeSelections() const
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(","));
438 void HTMLDialog::populateThemesCombo()
440 QStringList dirs
= KGlobal::dirs()->findDirs( "data", QString::fromLocal8Bit("kphotoalbum/themes/") );
443 int defaultthemes
= 0;
444 for(QStringList::Iterator it
= dirs
.begin(); it
!= dirs
.end(); ++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")) {
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() );
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
)
483 return KDialog::exec();
488 Setup
HTMLGenerator::HTMLDialog::setup() const
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() );
514 #include "HTMLDialog.moc"