From 928369e7516d52873abb8e7d0f6c258a179e352f Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Wed, 16 Mar 2016 23:50:28 +0000 Subject: [PATCH] import my own image viewer experiment Signed-off-by: Ivailo Monev --- kimageviewer/CMakeLists.txt | 51 ++++++ kimageviewer/kimagepart.cpp | 114 +++++++++++++ kimageviewer/kimagepart.h | 68 ++++++++ kimageviewer/kimageui.ui | 172 ++++++++++++++++++++ kimageviewer/kimageviewer.desktop | 10 ++ kimageviewer/kimageviewerpart.desktop | 8 + kimageviewer/kimagewidget.cpp | 222 ++++++++++++++++++++++++++ kimageviewer/kimagewidget.h | 72 +++++++++ kimageviewer/main.cpp | 83 ++++++++++ 9 files changed, 800 insertions(+) create mode 100644 kimageviewer/CMakeLists.txt create mode 100644 kimageviewer/kimagepart.cpp create mode 100644 kimageviewer/kimagepart.h create mode 100644 kimageviewer/kimageui.ui create mode 100644 kimageviewer/kimageviewer.desktop create mode 100644 kimageviewer/kimageviewerpart.desktop create mode 100644 kimageviewer/kimagewidget.cpp create mode 100644 kimageviewer/kimagewidget.h create mode 100644 kimageviewer/main.cpp diff --git a/kimageviewer/CMakeLists.txt b/kimageviewer/CMakeLists.txt new file mode 100644 index 00000000..8d9856a4 --- /dev/null +++ b/kimageviewer/CMakeLists.txt @@ -0,0 +1,51 @@ +project(KImageViewer) + +find_package(KDE4 REQUIRED) +include(KDE4Defaults) +include_directories(${KDE4_INCLUDES}) + +# application +set(kimageviewer_SRCS + main.cpp + kimagewidget.cpp +) + +add_executable(kimageviewer ${kimageviewer_SRCS}) + +target_link_libraries(kimageviewer + ${KDE4_KDECORE_LIBS} + ${KDE4_KPARTS_LIBS} + ${KDE4_KDEUI_LIBS} +) + +## part +set(kimageviewerpart_SRCS + kimagepart.cpp + kimagewidget.cpp +) + +kde4_add_plugin(kimageviewerpart ${kimageviewerpart_SRCS}) + +target_link_libraries(kimageviewerpart + ${KDE4_KDECORE_LIBS} + ${KDE4_KPARTS_LIBS} + ${KDE4_KDEUI_LIBS} +) + +## install everything +install( + TARGETS kimageviewer + DESTINATION ${BIN_INSTALL_DIR} +) +install( + TARGETS kimageviewerpart + DESTINATION ${PLUGIN_INSTALL_DIR} +) +install( + PROGRAMS kimageviewer.desktop + DESTINATION ${XDG_APPS_INSTALL_DIR} +) +install( + PROGRAMS kimageviewerpart.desktop + DESTINATION ${SERVICES_INSTALL_DIR} +) diff --git a/kimageviewer/kimagepart.cpp b/kimageviewer/kimagepart.cpp new file mode 100644 index 00000000..e82a9572 --- /dev/null +++ b/kimageviewer/kimagepart.cpp @@ -0,0 +1,114 @@ +/*********************************************************************** +* Copyright 2016 Ivailo Monev +* +* 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) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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, see . +***********************************************************************/ + +#include "kimagepart.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace KImageViewer { + +K_PLUGIN_FACTORY(KImageViewerPartFactory, registerPlugin();) // produce a factory +K_EXPORT_PLUGIN(KImageViewerPartFactory(KAboutData( + "kimageviewerpart", + 0, + ki18n("KImageViewer"), + "1.0.0", + ki18n("Simple image viewer for KDE."), + KAboutData::License_GPL_V2, + ki18n("(c) 2014 Ivailo Monev"), + KLocalizedString(), + "http://github.com/fluxer/kde-playground", + "xakepa10@gmail.com"). + setProgramIconName(QLatin1String("KImageViewer")). + setCatalogName("kimageviewer"))) + +BrowserExtension::BrowserExtension(KImagePart *parent) + : KParts::BrowserExtension(parent) +{} + + +KImagePart::KImagePart(QWidget *parentWidget, QObject *parent, const QList&) + : ReadOnlyPart(parent) + , m_ext(new BrowserExtension(this)) + , m_statusbar(new StatusBarExtension(this)) + , m_viewer(0) +{ + setComponentData(KImageViewerPartFactory::componentData()); + + m_viewer = new KImageWidget(parentWidget); + setWidget(m_viewer); +} + +void KImagePart::setApplication(bool application) +{ + m_viewer->setApplication(application); +} + +bool KImagePart::openFile() +{ + KUrl url = KUrl::fromPath(localFilePath()); + if (url.isEmpty()) { + //do nothing, chances are the user accidently pressed ENTER + } else if (!url.isValid()) { + KMessageBox::information(widget(), i18n("The entered URL is not invalid.")); + } else if (url.protocol() != QLatin1String("file")) { + KMessageBox::information(widget(), i18n("Only file paths are accepted.")); + } else { + m_viewer->setImage(url.path()); + m_statusbar->statusBar()->showMessage(i18n("Opened: %1", url.path())); + return true; + } + + return false; +} + +bool KImagePart::closeUrl() +{ + m_statusbar->statusBar()->showMessage(i18n("Closing viewer...")); + + return ReadOnlyPart::closeUrl(); +} + +void KImagePart::updateURL(const KUrl &u) +{ + // update the interface + emit m_ext->openUrlNotify(); //must be done first + emit m_ext->setLocationBarUrl(u.prettyUrl()); + + m_viewer->setImage(u.path()); + + //do this last, or it breaks Konqi location bar + setUrl(u); +} + +} //namespace KImageViewer + +#include "moc_kimagepart.cpp" diff --git a/kimageviewer/kimagepart.h b/kimageviewer/kimagepart.h new file mode 100644 index 00000000..bf661380 --- /dev/null +++ b/kimageviewer/kimagepart.h @@ -0,0 +1,68 @@ +/*********************************************************************** +* Copyright 2016 Ivailo Monev +* +* 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) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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, see . +***********************************************************************/ + +#ifndef KIMAGEPART_H +#define KIMAGEPART_H + +#include "kimagewidget.h" + +#include +#include +#include +#include + +#include + +using KParts::StatusBarExtension; + +namespace KImageViewer +{ + +class KImagePart; +class BrowserExtension : public KParts::BrowserExtension +{ +public: + explicit BrowserExtension(KImagePart*); +}; + +class KImagePart : public KParts::ReadOnlyPart +{ + Q_OBJECT + +public: + KImagePart(QWidget *, QObject *, const QList&); + + virtual bool openFile(); + virtual bool closeUrl(); + void setApplication(bool application); + +private slots: + void updateURL(const KUrl &); + +private: + BrowserExtension *m_ext; + StatusBarExtension *m_statusbar; + QGridLayout *m_layout; + KImageWidget *m_viewer; +}; + +} // namespace KImageViewer + +#endif // KIMAGEPART_H diff --git a/kimageviewer/kimageui.ui b/kimageviewer/kimageui.ui new file mode 100644 index 00000000..bcd6bd80 --- /dev/null +++ b/kimageviewer/kimageui.ui @@ -0,0 +1,172 @@ + + + KImageUI + + + + 0 + 0 + 503 + 399 + + + + Form + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Open + + + + + + + + + + + + false + + + + 0 + 0 + + + + Save + + + + + + + + + + + + false + + + Rotate left + + + + + + + + + + + + Qt::Vertical + + + + 20 + 217 + + + + + + + + false + + + Rotate right + + + + + + + + + + + + true + + + Quit + + + + + + + + + + + + + 0 + 0 + + + + QFrame::Box + + + QFrame::Plain + + + + + + + + + + + Ignore + + + + + Keep + + + + + Expanding + + + + + + + + Qt::ScrollBarAlwaysOff + + + QListView::LeftToRight + + + + + + + + diff --git a/kimageviewer/kimageviewer.desktop b/kimageviewer/kimageviewer.desktop new file mode 100644 index 00000000..c7111001 --- /dev/null +++ b/kimageviewer/kimageviewer.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=KImageViewer +GenericName=Simple image viewer for KDE +Comment=A simple program to view your image files +Exec=kimageviewer --icon '%i' --caption '%c' %U +Terminal=false +Icon=view-preview +Type=Application +Categories=Qt;KDE;Graphics;Viewer;Photography; +MimeType=image/gif;image/jpeg;image/png;image/bmp;image/x-eps;image/x-ico;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/tiff;image/x-psd;image/x-webp;image/webp; diff --git a/kimageviewer/kimageviewerpart.desktop b/kimageviewer/kimageviewerpart.desktop new file mode 100644 index 00000000..3f659170 --- /dev/null +++ b/kimageviewer/kimageviewerpart.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=view-preview +Name=KImageViwer +Comment=A simple program to view your image files +X-KDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=kimageviewerpart +Type=Service +MimeType=image/gif;image/jpeg;image/png;image/bmp;image/x-eps;image/x-ico;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/tiff;image/x-psd;image/x-webp;image/webp; diff --git a/kimageviewer/kimagewidget.cpp b/kimageviewer/kimagewidget.cpp new file mode 100644 index 00000000..f52d82e4 --- /dev/null +++ b/kimageviewer/kimagewidget.cpp @@ -0,0 +1,222 @@ +/*********************************************************************** +* Copyright 2016 Ivailo Monev +* +* 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) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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, see . +***********************************************************************/ + +#include "kimagewidget.h" +#include "ui_kimageui.h" + +#include +#include +#include +#include +#include + +namespace KImageViewer { + +#define mimefilter "image/gif image/jpeg image/png image/bmp image/x-eps image/x-ico image/x-portable-bitmap image/x-portable-graymap image/x-portable-pixmap image/x-xbitmap image/x-xpixmap image/tiff image/x-psd image/x-webp image/webp" + +KImageWidget::KImageWidget(QWidget *parent) + : QWidget(parent), m_ui(0) +{ + m_ui = new Ui_KImageUI(); + m_ui->setupUi(this); + m_mode = Qt::KeepAspectRatio; + setApplication(false); + + connect(m_ui->m_open, SIGNAL(clicked()), this, SLOT(openImage())); + connect(m_ui->m_save, SIGNAL(clicked()), this, SLOT(saveImage())); + connect(m_ui->m_rotateleft, SIGNAL(clicked()), this, SLOT(rotateLeft())); + connect(m_ui->m_rotateright, SIGNAL(clicked()), this, SLOT(rotateRight())); + connect(m_ui->m_view, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeMode(QString))); + connect(m_ui->m_quit, SIGNAL(clicked()), qApp, SLOT(quit())); +} + +bool KImageWidget::saveImage() +{ + if (m_ui->m_image->pixmap()->isNull()) { + return false; + } + + QString path = KFileDialog::getSaveFileName(KUrl(), QLatin1String(mimefilter), this); + + if (path.isEmpty()) { + // probably canceled open request + return false; + } else if (!m_ui->m_image->pixmap()->save(path)) { + KMessageBox::information(this, i18n("Could not save image to path: %1.", path)); + return false; + } + return true; +} + +bool KImageWidget::openImage() +{ + QString path = KFileDialog::getOpenFileName(KUrl(), QLatin1String(mimefilter), this); + + if (path.isEmpty()) { + // probably canceled open request + return false; + } + if (!setImage(path)) { + return false; + } + return true; +} + +bool KImageWidget::rotateLeft() +{ + // TODO: implement + return false; +} + +bool KImageWidget::rotateRight() +{ + // TODO: implement + return false; +} + +bool KImageWidget::changeMode(QString mode) +{ + if (mode == QLatin1String("Ignore")) { + m_ui->m_image->setPixmap(resizeIfNeeded(m_original, Qt::IgnoreAspectRatio)); + return true; + } else if (mode == QLatin1String("Keep")) { + m_ui->m_image->setPixmap(resizeIfNeeded(m_original, Qt::KeepAspectRatio)); + return true; + } else if (mode == QLatin1String("Expanding")) { + m_ui->m_image->setPixmap(resizeIfNeeded(m_original, Qt::KeepAspectRatioByExpanding)); + return true; + } + return false; +} + +bool KImageWidget::setImage(QString path, Qt::AspectRatioMode mode) +{ + QPixmap p; + p.load(path); + if (p.isNull()) { + return false; + } + m_original = p; + m_ui->m_image->setPixmap(resizeIfNeeded(p, mode)); + setWrite(true); // TODO: make that conditional + return true; +} + +bool KImageWidget::setImage(QImage image, Qt::AspectRatioMode mode) +{ + QPixmap p = QPixmap::fromImage(image); + if (p.isNull()) { + return false; + } + m_original = p; + m_ui->m_image->setPixmap(resizeIfNeeded(p, mode)); + setWrite(true); // TODO: make that conditional + return true; +} + +bool KImageWidget::setImage(QPixmap pixmap, Qt::AspectRatioMode mode) +{ + if (pixmap.isNull()) { + return false; + } + m_original = pixmap; + m_ui->m_image->setPixmap(resizeIfNeeded(pixmap, mode)); + setWrite(true); // TODO: make that conditional + return true; +} + +void KImageWidget::setMode(Qt::AspectRatioMode mode) +{ + m_mode = mode; + if (!m_original.isNull()) { + m_ui->m_image->setPixmap(resizeIfNeeded(m_original, mode)); + } +} + +Qt::AspectRatioMode KImageWidget::mode() +{ + return m_mode; +} + +void KImageWidget::setApplication(bool application) +{ + m_application = application; + if (application) { + m_ui->m_open->setEnabled(true); + m_ui->m_quit->show(); + } else { + m_ui->m_open->setEnabled(false); + m_ui->m_quit->hide(); + } +} + +bool KImageWidget::application() +{ + return m_application; +} + +void KImageWidget::setWrite(bool write) +{ + m_write = write; + if (write) { + m_ui->m_save->setEnabled(true); + m_ui->m_rotateleft->setEnabled(true); + m_ui->m_rotateright->setEnabled(true); + } else { + m_ui->m_save->setEnabled(false); + m_ui->m_rotateleft->setEnabled(false); + m_ui->m_rotateright->setEnabled(false); + } +} + +bool KImageWidget::write() +{ + return m_write; +} + +QSize KImageWidget::sizeHint() const +{ + if (m_original.isNull()) { + // since no image has been set yet the size is useless + return QSize(640, 480); + } + return m_ui->m_image->size(); +} + +QPixmap KImageWidget::resizeIfNeeded(QPixmap pixmap, Qt::AspectRatioMode mode) +{ + if (pixmap.height() > m_ui->m_image->height()) { + return pixmap.scaled(m_ui->m_image->size(), mode); + } + return pixmap; +} + +void KImageWidget::resizeEvent(QResizeEvent *event) +{ + if(m_original.isNull()) { + // can happend upon application startup before setImage() + return; + } + m_ui->m_image->setPixmap(resizeIfNeeded(m_original, m_mode)); +} + +} //namespace KImageViewer + +#include "moc_kimagewidget.cpp" diff --git a/kimageviewer/kimagewidget.h b/kimageviewer/kimagewidget.h new file mode 100644 index 00000000..f94c117b --- /dev/null +++ b/kimageviewer/kimagewidget.h @@ -0,0 +1,72 @@ +/*********************************************************************** +* Copyright 2016 Ivailo Monev +* +* 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) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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, see . +***********************************************************************/ + +#ifndef KIMAGEWIDGET_H +#define KIMAGEWIDGET_H + +#include +#include + +class Ui_KImageUI; + +namespace KImageViewer +{ + +class KImageWidget : public QWidget +{ + Q_OBJECT + +public: + KImageWidget(QWidget *parent = 0); + + bool setImage(QString path, Qt::AspectRatioMode mode = Qt::KeepAspectRatio); + bool setImage(QImage image, Qt::AspectRatioMode mode = Qt::KeepAspectRatio); + bool setImage(QPixmap pixmap, Qt::AspectRatioMode mode = Qt::KeepAspectRatio); + + void setMode(Qt::AspectRatioMode mode); + Qt::AspectRatioMode mode(); + void setApplication(bool application); + bool application(); + void setWrite(bool write); + bool write(); + + QSize sizeHint() const; + +public slots: + bool saveImage(); + bool openImage(); + bool rotateLeft(); + bool rotateRight(); + bool changeMode(QString mode); + +private: + Ui_KImageUI *m_ui; + QPixmap resizeIfNeeded(QPixmap pixmap, Qt::AspectRatioMode mode); + void resizeEvent(QResizeEvent *event); + int m_resizehits; + QPixmap m_original; + Qt::AspectRatioMode m_mode; + bool m_application; + bool m_write; +}; + +} // namespace KImageViewer + +#endif // KIMAGEWIDGET_H diff --git a/kimageviewer/main.cpp b/kimageviewer/main.cpp new file mode 100644 index 00000000..a180d1f1 --- /dev/null +++ b/kimageviewer/main.cpp @@ -0,0 +1,83 @@ +/*********************************************************************** +* Copyright 2016 Ivailo Monev +* +* 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) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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, see . +***********************************************************************/ + +#include "kimagepart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + KAboutData aboutData("kimageviewer", 0, ki18n("KImageViewer"), + "1.0.0", ki18n("Simple image viewer for KDE."), + KAboutData::License_GPL_V2, + ki18n("(c) 2016 Ivailo Monev"), + KLocalizedString(), + "http://github.com/fluxer/kde-playground" + ); + + aboutData.addAuthor(ki18n("Ivailo Monev"), + ki18n("Maintainer"), + "xakepa10@gmail.com"); + aboutData.setProgramIconName(QLatin1String("view-preview")); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineOptions option; + option.add("+[url]", ki18n("URL to be opened")); + KCmdLineArgs::addCmdLineOptions(option); + + KApplication *app = new KApplication(); + + KMainWindow *window = new KMainWindow(); + + KPluginLoader loader(QLatin1String("kimageviewerpart")); + KPluginFactory *factory = loader.factory(); + KParts::ReadOnlyPart *part; + if (factory) { + part = factory->create(window); + } + if (!factory || !part) { + KMessageBox::error(window, i18n("Unable to load KImageViwer's KPart component, please check your installation.")); + kWarning() << "Error loading KImageViwer KPart: " << loader.errorString(); + return false; + } + + part->setObjectName(QLatin1String("KImageViwer")); + static_cast(part->widget())->setApplication(true); + window->setCentralWidget(part->widget()); + // window->setAutoSaveSettings(); + window->show(); + + app->connect(app, SIGNAL(saveYourself()), part, SLOT(closeUrl())); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + for (int pos = 0; pos < args->count(); ++pos) { + part->openUrl(args->url(pos)); + } + + return app->exec(); +}