2 Copyright (c) 2013-2015 Montel Laurent <montel@kde.org>
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License, version 2, as
6 published by the Free Software Foundation.
8 This program is distributed in the hope that it will be useful, but
9 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 along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "themeeditorpage.h"
19 #include "desktopfilepage.h"
20 #include "editorpage.h"
21 #include "themeeditorwidget.h"
22 #include "previewwidget.h"
23 #include "themesession.h"
24 #include "themeeditortabwidget.h"
26 #include <kns3/uploaddialog.h>
28 #include <KLocalizedString>
29 #include <QInputDialog>
31 #include <QTemporaryDir>
32 #include "headerthemeeditor_debug.h"
33 #include <KMessageBox>
36 #include <QHBoxLayout>
39 #include <QFileDialog>
41 ThemeEditorPage::ThemeEditorPage(const QString
&projectDir
, const QString
&themeName
, QWidget
*parent
)
43 mThemeSession(new GrantleeThemeEditor::ThemeSession(projectDir
, QStringLiteral("headerthemeeditor"))),
46 QHBoxLayout
*lay
= new QHBoxLayout
;
47 mTabWidget
= new GrantleeThemeEditor::ThemeEditorTabWidget
;
48 connect(mTabWidget
, &GrantleeThemeEditor::ThemeEditorTabWidget::currentChanged
, this, &ThemeEditorPage::slotCurrentWidgetChanged
);
49 lay
->addWidget(mTabWidget
);
50 mEditorPage
= new EditorPage(EditorPage::MainPage
, projectDir
);
51 connect(mEditorPage
, &EditorPage::needUpdateViewer
, this, &ThemeEditorPage::slotUpdateViewer
);
52 connect(mEditorPage
, &EditorPage::changed
, this, &ThemeEditorPage::slotChanged
);
53 mTabWidget
->addTab(mEditorPage
, i18n("Editor (%1)", QStringLiteral("header.html")));
55 GrantleeThemeEditor::DesktopFilePage::DesktopFileOptions opt
;
56 opt
|= GrantleeThemeEditor::DesktopFilePage::ExtraDisplayVariables
;
57 opt
|= GrantleeThemeEditor::DesktopFilePage::SpecifyFileName
;
59 mDesktopPage
= new GrantleeThemeEditor::DesktopFilePage(QStringLiteral("header.html"), opt
);
60 mDesktopPage
->setDefaultDesktopName(QStringLiteral("header.desktop"));
61 mDesktopPage
->setThemeName(themeName
);
62 mTabWidget
->addTab(mDesktopPage
, i18n("Desktop File"));
64 connect(mDesktopPage
, &GrantleeThemeEditor::DesktopFilePage::mainFileNameChanged
, mEditorPage
->preview(), &GrantleeThemeEditor::PreviewWidget::slotMainFileNameChanged
);
65 connect(mDesktopPage
, &GrantleeThemeEditor::DesktopFilePage::mainFileNameChanged
, mTabWidget
, &GrantleeThemeEditor::ThemeEditorTabWidget::slotMainFileNameChanged
);
66 connect(mDesktopPage
, &GrantleeThemeEditor::DesktopFilePage::extraDisplayHeaderChanged
, this, &ThemeEditorPage::slotExtraHeaderDisplayChanged
);
67 connect(mDesktopPage
, &GrantleeThemeEditor::DesktopFilePage::changed
, this, &ThemeEditorPage::slotChanged
);
68 connect(mTabWidget
, &GrantleeThemeEditor::ThemeEditorTabWidget::tabCloseRequested
, this, &ThemeEditorPage::slotCloseTab
);
72 ThemeEditorPage::~ThemeEditorPage()
74 qDeleteAll(mExtraPage
);
79 void ThemeEditorPage::slotCurrentWidgetChanged(int index
)
84 GrantleeThemeEditor::EditorPage
*page
= dynamic_cast<GrantleeThemeEditor::EditorPage
*>(mTabWidget
->widget(index
));
85 Q_EMIT
canInsertFile(page
);
88 void ThemeEditorPage::updatePreview()
90 mEditorPage
->preview()->updateViewer();
93 void ThemeEditorPage::setPrinting(bool print
)
95 mEditorPage
->preview()->setPrinting(print
);
98 void ThemeEditorPage::slotExtraHeaderDisplayChanged(const QStringList
&extraHeaders
)
100 mEditorPage
->preview()->slotExtraHeaderDisplayChanged(extraHeaders
);
103 Q_FOREACH (QString var
, extraHeaders
) {
104 var
= QLatin1String("header.") + var
.remove(QLatin1Char('-'));
108 mEditorPage
->editor()->createCompleterList(result
);
109 Q_FOREACH (EditorPage
*page
, mExtraPage
) {
110 page
->editor()->createCompleterList(result
);
114 void ThemeEditorPage::slotChanged()
119 void ThemeEditorPage::setChanged(bool b
)
127 void ThemeEditorPage::slotUpdateViewer()
129 if (themeWasChanged()) {
132 mEditorPage
->preview()->updateViewer();
135 void ThemeEditorPage::slotCloseTab(int index
)
137 mTabWidget
->removeTab(index
);
141 void ThemeEditorPage::insertFile()
143 QWidget
*w
= mTabWidget
->currentWidget();
147 GrantleeThemeEditor::EditorPage
*page
= dynamic_cast<GrantleeThemeEditor::EditorPage
*>(w
);
149 const QString fileName
= QFileDialog::getOpenFileName(this);
150 if (!fileName
.isEmpty()) {
151 page
->insertFile(fileName
);
156 bool ThemeEditorPage::themeWasChanged() const
161 void ThemeEditorPage::installTheme(const QString
&themePath
)
164 QDir
themeDir(themePath
+ QDir::separator() + mDesktopPage
->themeName());
165 if (themeDir
.exists()) {
166 if (KMessageBox::questionYesNo(this, i18n("Theme already exists. Do you want to overwrite it?"), i18n("Theme already exists")) == KMessageBox::No
) {
170 if (!dir
.mkdir(mDesktopPage
->themeName())) {
171 KMessageBox::error(this, i18n("Cannot create theme folder."));
175 const QString newPath
= themePath
+ QDir::separator() + mDesktopPage
->themeName();
176 mEditorPage
->setPageFileName(mDesktopPage
->filename());
177 mEditorPage
->installTheme(newPath
);
178 Q_FOREACH (EditorPage
*page
, mExtraPage
) {
179 page
->installTheme(newPath
);
181 mDesktopPage
->installTheme(newPath
);
182 KMessageBox::information(this, i18n("Theme installed in \"%1\"", themeDir
.absolutePath()));
185 void ThemeEditorPage::uploadTheme()
187 //force update for screenshot
188 mEditorPage
->preview()->updateViewer();
190 const QString themename
= mDesktopPage
->themeName();
191 const QString zipFileName
= tmp
.path() + QDir::separator() + themename
+ QLatin1String(".zip");
192 KZip
*zip
= new KZip(zipFileName
);
193 if (zip
->open(QIODevice::WriteOnly
)) {
194 const QString previewFileName
= tmp
.path() + QDir::separator() + themename
+ QLatin1String("_preview.png");
195 //qCDebug(HEADERTHEMEEDITOR_LOG)<<" previewFileName"<<previewFileName;
197 lst
<< previewFileName
;
198 mEditorPage
->preview()->createScreenShot(lst
);
200 const bool fileAdded
= zip
->addLocalFile(previewFileName
, themename
+ QLatin1Char('/') + QLatin1String("theme_preview.png"));
202 KMessageBox::error(this, i18n("We cannot add preview file in zip file"), i18n("Failed to add file."));
207 createZip(themename
, zip
);
209 //qCDebug(HEADERTHEMEEDITOR_LOG)<< "zipFilename"<<zipFileName;
211 QPointer
<KNS3::UploadDialog
> dialog
= new KNS3::UploadDialog(QStringLiteral("messageviewer_header_themes.knsrc"), this);
212 dialog
->setUploadFile(QUrl::fromLocalFile(zipFileName
));
213 dialog
->setUploadName(themename
);
214 dialog
->setPreviewImageFile(0, QUrl::fromLocalFile(previewFileName
));
215 const QString description
= mDesktopPage
->description();
216 dialog
->setDescription(description
.isEmpty() ? i18n("My favorite KMail header") : description
);
220 qCDebug(HEADERTHEMEEDITOR_LOG
) << " We can't open in zip write mode";
225 void ThemeEditorPage::createZip(const QString
&themeName
, KZip
*zip
)
227 mEditorPage
->createZip(themeName
, zip
);
229 Q_FOREACH (EditorPage
*page
, mExtraPage
) {
230 page
->createZip(themeName
, zip
);
232 mDesktopPage
->createZip(themeName
, zip
);
235 void ThemeEditorPage::addExtraPage()
237 QString filename
= QInputDialog::getText(this, i18n("Filename of extra page"), i18n("Filename:"));
238 if (!filename
.trimmed().isEmpty()) {
239 if (!filename
.endsWith(QStringLiteral(".html")) && !filename
.endsWith(QStringLiteral(".css")) && !filename
.endsWith(QStringLiteral(".js"))) {
240 filename
+= QLatin1String(".html");
242 createExtraPage(filename
);
243 mThemeSession
->addExtraPage(filename
);
248 EditorPage
*ThemeEditorPage::createExtraPage(const QString
&filename
)
250 EditorPage
*extraPage
= new EditorPage(EditorPage::ExtraPage
, QString());
251 connect(extraPage
, &EditorPage::changed
, this, &ThemeEditorPage::slotChanged
);
252 extraPage
->setPageFileName(filename
);
253 mTabWidget
->addTab(extraPage
, filename
);
254 mTabWidget
->setCurrentWidget(extraPage
);
255 mExtraPage
.append(extraPage
);
259 void ThemeEditorPage::storeTheme(const QString
&directory
)
261 const QString themeDirectory
= directory
.isEmpty() ? projectDirectory() : directory
;
262 //set default page filename before saving
263 mEditorPage
->setPageFileName(mDesktopPage
->filename());
264 mEditorPage
->saveTheme(themeDirectory
);
266 Q_FOREACH (EditorPage
*page
, mExtraPage
) {
267 page
->saveTheme(themeDirectory
);
269 mDesktopPage
->saveTheme(themeDirectory
);
270 mThemeSession
->setMainPageFileName(mDesktopPage
->filename());
271 mThemeSession
->writeSession(directory
);
272 if (directory
.isEmpty()) {
277 bool ThemeEditorPage::saveTheme(bool withConfirmation
)
279 if (themeWasChanged()) {
280 if (withConfirmation
) {
281 const int result
= KMessageBox::questionYesNoCancel(this, i18n("Do you want to save current project?"), i18n("Save current project"));
282 if (result
== KMessageBox::Yes
) {
284 } else if (result
== KMessageBox::Cancel
) {
295 void ThemeEditorPage::loadTheme(const QString
&filename
)
297 if (mThemeSession
->loadSession(filename
)) {
298 mDesktopPage
->loadTheme(mThemeSession
->projectDirectory());
299 mEditorPage
->loadTheme(mThemeSession
->projectDirectory() + QDir::separator() + mThemeSession
->mainPageFileName());
300 mEditorPage
->preview()->setThemePath(mThemeSession
->projectDirectory(), mThemeSession
->mainPageFileName());
302 const QStringList lstExtraPages
= mThemeSession
->extraPages();
303 Q_FOREACH (const QString
&page
, lstExtraPages
) {
304 EditorPage
*extraPage
= createExtraPage(page
);
305 extraPage
->loadTheme(mThemeSession
->projectDirectory() + QDir::separator() + page
);
307 mTabWidget
->setCurrentIndex(0);
312 void ThemeEditorPage::reloadConfig()
314 mEditorPage
->preview()->loadConfig();
317 QString
ThemeEditorPage::projectDirectory() const
319 return mThemeSession
->projectDirectory();
322 void ThemeEditorPage::saveThemeAs(const QString
&directory
)
324 storeTheme(directory
);