// vim: set tabstop=4 shiftwidth=4 expandtab: /* Gwenview: an image viewer Copyright 2008 Aurélien Gâteau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. */ // Self #include "gvcore.h" // Qt #include #include // KDE #include #include #include #include #include #include #include #include // Local #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Gwenview { struct GvCorePrivate { GvCore* q; MainWindow* mMainWindow; SortedDirModel* mDirModel; HistoryModel* mRecentFoldersModel; HistoryModel* mRecentUrlsModel; QPalette mPalettes[4]; bool showSaveAsDialog(const KUrl& url, KUrl* outUrl, QByteArray* format) { KFileDialog dialog(url, QString(), mMainWindow); dialog.setOperationMode(KFileDialog::Saving); dialog.setSelection(url.fileName()); dialog.setMimeFilter( KImageIO::mimeTypes(KImageIO::Writing), // List MimeTypeUtils::urlMimeType(url) // Default ); // Show dialog do { if (!dialog.exec()) { return false; } const QString mimeType = dialog.currentMimeFilter(); if (mimeType.isEmpty()) { KMessageBox::sorry( mMainWindow, i18nc("@info", "No image format selected.") ); continue; } const QString formatType = KImageIO::typeForMime(mimeType, KImageIO::Writing); if (!formatType.isEmpty()) { *format = formatType.toAscii(); break; } KMessageBox::sorry( mMainWindow, i18nc("@info", "Gwenview cannot save images as %1.", mimeType) ); } while (true); *outUrl = dialog.selectedUrl(); return true; } void setupPalettes() { QPalette pal; int value = GwenviewConfig::viewBackgroundValue(); QColor fgColor = value > 128 ? Qt::black : Qt::white; // Normal mPalettes[GvCore::NormalPalette] = KGlobalSettings::createApplicationPalette(); pal = mPalettes[GvCore::NormalPalette]; pal.setColor(QPalette::Base, QColor::fromHsv(0, 0, value)); pal.setColor(QPalette::Text, fgColor); mPalettes[GvCore::NormalViewPalette] = pal; // Fullscreen mPalettes[GvCore::FullScreenPalette] = mPalettes[GvCore::NormalPalette]; pal = mPalettes[GvCore::FullScreenPalette]; QString path = KStandardDirs::locate("data", "gwenview/images/background.png"); QPixmap bgTexture(path); pal.setBrush(QPalette::Base, bgTexture); mPalettes[GvCore::FullScreenViewPalette] = pal; } }; GvCore::GvCore(MainWindow* mainWindow, SortedDirModel* dirModel) : QObject(mainWindow) , d(new GvCorePrivate) { d->q = this; d->mMainWindow = mainWindow; d->mDirModel = dirModel; d->mRecentFoldersModel = 0; d->mRecentUrlsModel = 0; d->setupPalettes(); connect(GwenviewConfig::self(), SIGNAL(configChanged()), SLOT(slotConfigChanged())); } GvCore::~GvCore() { delete d; } QAbstractItemModel* GvCore::recentFoldersModel() const { if (!d->mRecentFoldersModel) { d->mRecentFoldersModel = new HistoryModel(const_cast(this), KStandardDirs::locateLocal("appdata", "recentfolders/")); } return d->mRecentFoldersModel; } QAbstractItemModel* GvCore::recentUrlsModel() const { if (!d->mRecentUrlsModel) { d->mRecentUrlsModel = new HistoryModel(const_cast(this), KStandardDirs::locateLocal("appdata", "recenturls/")); } return d->mRecentUrlsModel; } SortedDirModel* GvCore::sortedDirModel() const { return d->mDirModel; } void GvCore::addUrlToRecentFolders(KUrl url) { if (!GwenviewConfig::historyEnabled()) { return; } if (!url.isValid()) { return; } if (url.path() != "") { // This check is a workaraound for bug #312060 url.adjustPath(KUrl::AddTrailingSlash); } recentFoldersModel(); d->mRecentFoldersModel->addUrl(url); } void GvCore::addUrlToRecentUrls(const KUrl& url) { if (!GwenviewConfig::historyEnabled()) { return; } recentUrlsModel(); d->mRecentUrlsModel->addUrl(url); } void GvCore::saveAll() { SaveAllHelper helper(d->mMainWindow); helper.save(); } void GvCore::save(const KUrl& url) { Document::Ptr doc = DocumentFactory::instance()->load(url); QByteArray format = doc->format(); const QStringList availableTypes = KImageIO::types(KImageIO::Writing); if (availableTypes.contains(QString(format))) { DocumentJob* job = doc->save(url, format); connect(job, SIGNAL(result(KJob*)), SLOT(slotSaveResult(KJob*))); } else { // We don't know how to save in 'format', ask the user for a format we can // write to. KGuiItem saveUsingAnotherFormat = KStandardGuiItem::saveAs(); saveUsingAnotherFormat.setText(i18n("Save using another format")); int result = KMessageBox::warningContinueCancel( d->mMainWindow, i18n("Gwenview cannot save images in '%1' format.", QString(format)), QString() /* caption */, saveUsingAnotherFormat ); if (result == KMessageBox::Continue) { saveAs(url); } } } void GvCore::saveAs(const KUrl& url) { QByteArray format; KUrl saveAsUrl; if (!d->showSaveAsDialog(url, &saveAsUrl, &format)) { return; } // Check for overwrite if (KIO::NetAccess::exists(saveAsUrl, KIO::NetAccess::DestinationSide, d->mMainWindow)) { int answer = KMessageBox::warningContinueCancel( d->mMainWindow, i18nc("@info", "A file named %1 already exists.\n" "Are you sure you want to overwrite it?", saveAsUrl.fileName()), QString(), KStandardGuiItem::overwrite()); if (answer == KMessageBox::Cancel) { return; } } // Start save Document::Ptr doc = DocumentFactory::instance()->load(url); KJob* job = doc->save(saveAsUrl, format.data()); if (!job) { const QString name = saveAsUrl.fileName().isEmpty() ? saveAsUrl.pathOrUrl() : saveAsUrl.fileName(); const QString msg = i18nc("@info", "Saving %1 failed:
%2", name, doc->errorString()); KMessageBox::sorry(QApplication::activeWindow(), msg); } else { connect(job, SIGNAL(result(KJob*)), SLOT(slotSaveResult(KJob*))); } } static void applyTransform(const KUrl& url, Orientation orientation) { TransformImageOperation* op = new TransformImageOperation(orientation); Document::Ptr doc = DocumentFactory::instance()->load(url); op->applyToDocument(doc); } void GvCore::slotSaveResult(KJob* _job) { SaveJob* job = static_cast(_job); KUrl oldUrl = job->oldUrl(); KUrl newUrl = job->newUrl(); if (job->error()) { QString name = newUrl.fileName().isEmpty() ? newUrl.pathOrUrl() : newUrl.fileName(); QString msg = i18nc("@info", "Saving %1 failed:
%2", name, job->errorString()); int result = KMessageBox::warningContinueCancel( d->mMainWindow, msg, QString() /* caption */, KStandardGuiItem::saveAs()); if (result == KMessageBox::Continue) { saveAs(newUrl); } return; } if (oldUrl != newUrl) { d->mMainWindow->goToUrl(newUrl); ViewMainPage* page = d->mMainWindow->viewMainPage(); if (page->isVisible()) { HudMessageBubble* bubble = new HudMessageBubble(); bubble->setText(i18n("You are now viewing the new document.")); KGuiItem item = KStandardGuiItem::back(); item.setText(i18n("Go back to the original")); HudButton* button = bubble->addButton(item); BinderRef::bind(button, SIGNAL(clicked()), d->mMainWindow, &MainWindow::goToUrl, oldUrl); connect(button, SIGNAL(clicked()), bubble, SLOT(deleteLater())); page->showMessageWidget(bubble); } } } void GvCore::rotateLeft(const KUrl& url) { applyTransform(url, ROT_270); } void GvCore::rotateRight(const KUrl& url) { applyTransform(url, ROT_90); } static void clearModel(QAbstractItemModel* model) { model->removeRows(0, model->rowCount()); } void GvCore::slotConfigChanged() { if (!GwenviewConfig::historyEnabled()) { clearModel(recentFoldersModel()); clearModel(recentUrlsModel()); } d->setupPalettes(); } QPalette GvCore::palette(GvCore::PaletteType type) const { return d->mPalettes[type]; } } // namespace