[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [calligra] krita/plugins/extensions/dockers: Add image docker again
From: Silvio Heinrich <plassy () web ! de>
Date: 2011-08-17 15:03:50
Message-ID: 20110817150350.3824DA60A4 () git ! kde ! org
[Download RAW message or body]
Git commit 21ec0724af1706fdefa02f77622cc875026a4b69 by Silvio Heinrich.
Committed on 17/08/2011 at 17:02.
Pushed by heinrich into branch 'master'.
Add image docker again to master. Was removed... Why??
A +99 -0 krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.h \
[License: LGPL (v2)] M +1 -0 krita/plugins/extensions/dockers/CMakeLists.txt
A +255 -0 krita/plugins/extensions/dockers/imagedocker/forms/wdgimagedocker.ui
A +486 -0 krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.cpp \
[License: LGPL (v2)] A +177 -0 \
krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.cpp [License: \
LGPL (v2)] A +261 -0 \
krita/plugins/extensions/dockers/imagedocker/kis_image_view.cpp [License: LGPL \
(v2)] A +31 -0 krita/plugins/extensions/dockers/imagedocker/imagedocker.h \
[License: LGPL (v2)] A +9 -0 \
krita/plugins/extensions/dockers/imagedocker/kritaimagedocker.desktop A +94 -0 \
krita/plugins/extensions/dockers/imagedocker/kis_image_view.h [License: LGPL \
(v2)] A +121 -0 \
krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.h [License: \
LGPL (v2)] A +60 -0 \
krita/plugins/extensions/dockers/imagedocker/imagedocker.cpp [License: LGPL (v2)] \
A +114 -0 krita/plugins/extensions/dockers/imagedocker/forms/wdgImageViewPopup.ui
A +15 -0 krita/plugins/extensions/dockers/imagedocker/CMakeLists.txt
http://commits.kde.org/calligra/21ec0724af1706fdefa02f77622cc875026a4b69
diff --git a/krita/plugins/extensions/dockers/CMakeLists.txt \
b/krita/plugins/extensions/dockers/CMakeLists.txt index 51690c0..d06930a 100644
--- a/krita/plugins/extensions/dockers/CMakeLists.txt
+++ b/krita/plugins/extensions/dockers/CMakeLists.txt
@@ -6,3 +6,4 @@ add_subdirectory(advancedcolorselector)
add_subdirectory(presetdocker)
add_subdirectory(historydocker)
add_subdirectory(channeldocker)
+add_subdirectory(imagedocker)
\ No newline at end of file
diff --git a/krita/plugins/extensions/dockers/imagedocker/CMakeLists.txt \
b/krita/plugins/extensions/dockers/imagedocker/CMakeLists.txt new file mode 100644
index 0000000..ad23303
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/CMakeLists.txt
@@ -0,0 +1,15 @@
+
+set(kritaimagedocker_PART_SRCS
+ imagedocker.cpp
+ imagedocker_dock.cpp
+ kis_image_strip_scene.cpp
+ kis_image_view.cpp
+)
+
+kde4_add_ui_files(kritaimagedocker_PART_SRCS forms/wdgimagedocker.ui \
forms/wdgImageViewPopup.ui) +
+kde4_add_plugin(kritaimagedocker ${kritaimagedocker_PART_SRCS})
+target_link_libraries(kritaimagedocker kritaui)
+
+install(TARGETS kritaimagedocker DESTINATION ${PLUGIN_INSTALL_DIR})
+install(FILES kritaimagedocker.desktop DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/krita/plugins/extensions/dockers/imagedocker/forms/wdgImageViewPopup.ui \
b/krita/plugins/extensions/dockers/imagedocker/forms/wdgImageViewPopup.ui new file \
mode 100644 index 0000000..e45986e
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/forms/wdgImageViewPopup.ui
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>wdgImageViewPopup</class>
+ <widget class="QWidget" name="wdgImageViewPopup">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>59</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="bnZoomFit">
+ <property name="text">
+ <string>Fit</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bnZoomAdjust">
+ <property name="text">
+ <string>Adjust</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bnZoom100">
+ <property name="text">
+ <string>100%</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bnZoom75">
+ <property name="text">
+ <string>75%</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bnZoom50">
+ <property name="text">
+ <string>50%</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bnZoom25">
+ <property name="text">
+ <string>25%</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="KisSliderSpinBox" name="zoomSlider" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KisSliderSpinBox</class>
+ <extends>QWidget</extends>
+ <header location="global">kis_slider_spin_box.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/plugins/extensions/dockers/imagedocker/forms/wdgimagedocker.ui \
b/krita/plugins/extensions/dockers/imagedocker/forms/wdgimagedocker.ui new file mode \
100644 index 0000000..a6e5341
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/forms/wdgimagedocker.ui
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>wdgImageDocker</class>
+ <widget class="QWidget" name="wdgImageDocker">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>399</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="tabPosition">
+ <enum>QTabWidget::North</enum>
+ </property>
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <property name="elideMode">
+ <enum>Qt::ElideNone</enum>
+ </property>
+ <property name="usesScrollButtons">
+ <bool>true</bool>
+ </property>
+ <property name="documentMode">
+ <bool>true</bool>
+ </property>
+ <property name="tabsClosable">
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="imgBrowserTab">
+ <attribute name="title">
+ <string>Browse</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="QWidget" name="verticalLayoutWidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="cmbPath">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnBack">
+ <property name="text">
+ <string>Back</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnUp">
+ <property name="text">
+ <string>Up</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnHome">
+ <property name="text">
+ <string>Home</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>true</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>true</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="headerCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>200</number>
+ </attribute>
+ <attribute name="headerHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QGraphicsView" name="thumbView">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="imgViewTab">
+ <attribute name="title">
+ <string>Images</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,1">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1,0,0,0">
+ <item>
+ <widget class="KisPopupButton" name="bnPopup">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cmbImg">
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnImgPrev">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Prev</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnImgNext">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Next</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="bnImgClose">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="KisImageView" name="imgView">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KisImageView</class>
+ <extends>QFrame</extends>
+ <header>kis_image_view.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>KisPopupButton</class>
+ <extends>QPushButton</extends>
+ <header location="global">kis_popup_button.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/plugins/extensions/dockers/imagedocker/imagedocker.cpp \
b/krita/plugins/extensions/dockers/imagedocker/imagedocker.cpp new file mode 100644
index 0000000..4643016
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/imagedocker.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "imagedocker.h"
+#include "imagedocker_dock.h"
+
+#include <kpluginfactory.h>
+#include <klocale.h>
+#include <KoDockFactoryBase.h>
+#include <KoDockRegistry.h>
+
+K_PLUGIN_FACTORY(ImageDockerPluginFactory, registerPlugin<ImageDockerPlugin>();)
+K_EXPORT_PLUGIN(ImageDockerPluginFactory("krita"))
+
+class ImageDockerDockFactory: public KoDockFactoryBase {
+public:
+ ImageDockerDockFactory() { }
+
+ virtual QString id() const
+ {
+ return QString("ImageDocker");
+ }
+
+ virtual Qt::DockWidgetArea defaultDockWidgetArea() const
+ {
+ return Qt::RightDockWidgetArea;
+ }
+
+ virtual QDockWidget* createDockWidget()
+ {
+ ImageDockerDock* dockWidget = new ImageDockerDock();
+ dockWidget->setObjectName(id());
+ return dockWidget;
+ }
+
+ DockPosition defaultDockPosition() const
+ {
+ return DockMinimized;
+ }
+};
+
+ImageDockerPlugin::ImageDockerPlugin(QObject* parent, const QVariantList&):
+ QObject(parent)
+{
+ KoDockRegistry::instance()->add(new ImageDockerDockFactory());
+}
diff --git a/krita/plugins/extensions/dockers/imagedocker/imagedocker.h \
b/krita/plugins/extensions/dockers/imagedocker/imagedocker.h new file mode 100644
index 0000000..8810313
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/imagedocker.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef H_IMAGEDOCKER_H_
+#define H_IMAGEDOCKER_H_
+
+#include <QObject>
+#include <QVariantList>
+
+class ImageDockerPlugin: public QObject
+{
+ Q_OBJECT
+public:
+ ImageDockerPlugin(QObject* parent, const QVariantList&);
+};
+
+#endif // H_IMAGEDOCKER_H_
diff --git a/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.cpp \
b/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.cpp new file mode \
100644 index 0000000..7c3294d
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.cpp
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "imagedocker_dock.h"
+#include "kis_image_strip_scene.h"
+#include "kis_image_view.h"
+
+#include <klocale.h>
+#include <KoResourceManager.h>
+#include <KoCanvasBase.h>
+#include <KoColorSpaceRegistry.h>
+
+#include <QFileSystemModel>
+#include <QImageReader>
+#include <QSortFilterProxyModel>
+#include <QFileInfo>
+#include <QMouseEvent>
+#include <QDir>
+#include <QLineEdit>
+#include <QLabel>
+#include <QIcon>
+#include <QAbstractListModel>
+#include <QButtonGroup>
+
+#include "ui_wdgimagedocker.h"
+#include "ui_wdgImageViewPopup.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// --------- ImageFilter --------------------------------------------------- //
+
+class ImageFilter: public QSortFilterProxyModel
+{
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) \
const { + QFileSystemModel* model = \
static_cast<QFileSystemModel*>(sourceModel()); + QModelIndex index = \
sourceModel()->index(source_row, 0, source_parent); +
+ if(model->isDir(index))
+ return true;
+
+ m_reader.setFileName(model->filePath(index));
+ return m_reader.canRead();
+ }
+
+ virtual bool filterAcceptsColumn(int source_column, const QModelIndex& \
source_parent) const { + Q_UNUSED(source_parent);
+ return source_column == 0;
+ }
+
+ mutable QImageReader m_reader;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// --------- ImageListModel ------------------------------------------------ //
+
+class ImageListModel: public QAbstractListModel
+{
+ struct Data
+ {
+ QPixmap icon;
+ QString text;
+ qint64 id;
+ };
+
+public:
+ void addImage(const QPixmap& pixmap, const QString& text, qint64 id) {
+ Data data;
+ data.icon = pixmap.scaled(70, 70, Qt::KeepAspectRatio);
+ data.text = text;
+ data.id = id;
+ emit layoutAboutToBeChanged();
+ m_data.push_back(data);
+ emit layoutChanged();
+ }
+
+ qint64 imageID(int index) const { return m_data[index].id; }
+
+ void removeImage(qint64 id) {
+ typedef QList<Data>::iterator Iterator;
+
+ for(Iterator data=m_data.begin(); data!=m_data.end(); ++data) {
+ if(data->id == id) {
+ emit layoutAboutToBeChanged();
+ m_data.erase(data);
+ emit layoutChanged();
+ return;
+ }
+ }
+ }
+
+ int indexFromID(qint64 id) {
+ for(int i=0; i<m_data.size(); ++i) {
+ if(m_data[i].id == id)
+ return i;
+ }
+ return -1;
+ }
+
+ virtual int rowCount(const QModelIndex& parent=QModelIndex()) const {
+ Q_UNUSED(parent);
+ return m_data.size();
+ }
+
+ virtual QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const \
{ + if(index.isValid() && index.row() < m_data.size()) {
+ switch(role)
+ {
+ case Qt::DisplayRole:
+ return m_data[index.row()].text;
+ case Qt::DecorationRole:
+ return m_data[index.row()].icon;
+ }
+ }
+ return QVariant();
+ }
+
+private:
+ QList<Data> m_data;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// --------- ImageDockerUI ------------------------------------------------- //
+
+struct ImageDockerUI: public QWidget, public Ui_wdgImageDocker
+{
+ ImageDockerUI() {
+ setupUi(this);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// --------- PopupWidgetUI ------------------------------------------------- //
+
+struct PopupWidgetUI: public QWidget, public Ui_wdgImageViewPopup
+{
+ PopupWidgetUI() {
+ setupUi(this);
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// --------- ImageDockerDock ----------------------------------------------- //
+
+ImageDockerDock::ImageDockerDock():
+ QDockWidget(i18n("Image Docker")),
+ m_canvas(0),
+ m_currImageID(-1)
+{
+ m_ui = new ImageDockerUI();
+ m_popupUi = new PopupWidgetUI();
+ m_zoomButtons = new QButtonGroup();
+ m_imgListModel = new ImageListModel();
+ m_thumbModel = new KisImageStripScene();
+ m_model = new QFileSystemModel();
+ m_proxyModel = new ImageFilter();
+ m_proxyModel->setSourceModel(m_model);
+ m_proxyModel->setDynamicSortFilter(true);
+
+ m_ui->bnBack->setIcon(QIcon::fromTheme("go-previous"));
+ m_ui->bnUp->setIcon(QIcon::fromTheme("go-up"));
+ m_ui->bnHome->setIcon(QIcon::fromTheme("go-home"));
+ m_ui->bnImgPrev->setIcon(QIcon::fromTheme("go-previous"));
+ m_ui->bnImgNext->setIcon(QIcon::fromTheme("go-next"));
+ m_ui->bnImgClose->setIcon(QIcon::fromTheme("window-close"));
+ m_ui->thumbView->setScene(m_thumbModel);
+ m_ui->treeView->setModel(m_proxyModel);
+ m_ui->cmbImg->setModel(m_imgListModel);
+ m_ui->bnPopup->setIcon(QIcon::fromTheme("zoom-original"));
+ m_ui->bnPopup->setPopupWidget(m_popupUi);
+
+ m_popupUi->zoomSlider->setRange(5, 500);
+ m_popupUi->zoomSlider->setValue(100);
+
+ m_zoomButtons->addButton(m_popupUi->bnZoomFit , KisImageView::VIEW_MODE_FIT);
+ m_zoomButtons->addButton(m_popupUi->bnZoomAdjust, \
KisImageView::VIEW_MODE_ADJUST); + m_zoomButtons->addButton(m_popupUi->bnZoom25 \
, 25); + m_zoomButtons->addButton(m_popupUi->bnZoom50 , 50);
+ m_zoomButtons->addButton(m_popupUi->bnZoom75 , 75);
+ m_zoomButtons->addButton(m_popupUi->bnZoom100 , 100);
+
+ m_model->setRootPath(QDir::rootPath());
+ m_ui->treeView->setRootIndex(m_proxyModel->mapFromSource(m_model->index(QDir::homePath())));
+ updatePath(QDir::homePath());
+
+ connect(m_ui->treeView , SIGNAL(doubleClicked(const QModelIndex&)) \
, SLOT(slotItemDoubleClicked(const QModelIndex&))); + connect(m_ui->bnBack \
, SIGNAL(clicked(bool)) , SLOT(slotBackButtonClicked())); + \
connect(m_ui->bnHome , SIGNAL(clicked(bool)) , \
SLOT(slotHomeButtonClicked())); + connect(m_ui->bnUp , \
SIGNAL(clicked(bool)) , SLOT(slotUpButtonClicked())); + \
connect(m_thumbModel , SIGNAL(sigImageActivated(const QString&)) , \
SLOT(slotOpenImage(QString))); + connect(m_ui->bnImgNext , \
SIGNAL(clicked(bool)) , SLOT(slotNextImage())); + \
connect(m_ui->bnImgPrev , SIGNAL(clicked(bool)) , \
SLOT(slotPrevImage())); + connect(m_ui->bnImgClose , SIGNAL(clicked(bool)) \
, SLOT(slotCloseCurrentImage())); + connect(m_ui->cmbImg , \
SIGNAL(activated(int)) , \
SLOT(slotImageChoosenFromComboBox(int))); + connect(m_ui->imgView , \
SIGNAL(sigColorSelected(const QColor&)) , SLOT(slotColorSelected(const \
QColor))); + connect(m_ui->imgView , SIGNAL(sigViewModeChanged(int, \
qreal)) , SLOT(slotViewModeChanged(int, qreal))); + \
connect(m_popupUi->zoomSlider , SIGNAL(valueChanged(int)) , \
SLOT(slotZoomChanged(int))); + connect(m_zoomButtons , \
SIGNAL(buttonClicked(int)) , SLOT(slotZoomChanged(int))); + \
connect(m_zoomButtons , SIGNAL(buttonClicked(int)) , \
SLOT(slotCloseZoomPopup())); + connect(this , \
SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), \
SLOT(slotDockLocationChanged(Qt::DockWidgetArea))); + connect(this \
, SIGNAL(topLevelChanged(bool)) , SLOT(slotTopLevelChanged(bool))); \
+ + setWidget(m_ui);
+}
+
+ImageDockerDock::~ImageDockerDock()
+{
+ delete m_proxyModel;
+ delete m_model;
+ delete m_thumbModel;
+ delete m_imgListModel;
+ delete m_zoomButtons;
+}
+
+void ImageDockerDock::setCanvas(KoCanvasBase* canvas)
+{
+ // "Every connection you make emits a signal, so duplicate connections emit two \
signals" + if(m_canvas)
+ m_canvas->disconnectCanvasObserver(this);
+
+ m_canvas = canvas;
+}
+
+void ImageDockerDock::addCurrentPathToHistory()
+{
+ m_history.push_back(m_model->filePath(m_proxyModel->mapToSource(m_ui->treeView->rootIndex())));
+}
+
+void ImageDockerDock::updatePath(const QString& path)
+{
+ m_ui->cmbPath->lineEdit()->setText(path);
+ m_ui->bnBack->setDisabled(m_history.empty());
+ m_thumbModel->setCurrentDirectory(path);
+}
+
+qint64 ImageDockerDock::generateImageID() const
+{
+ static qint64 id = 0;
+ return ++id;
+}
+
+void ImageDockerDock::setCurrentImage(qint64 imageID)
+{
+ if(m_imgInfoMap.contains(m_currImageID))
+ m_imgInfoMap[m_currImageID].scrollPos = m_ui->imgView->getScrollPos();
+
+ m_ui->bnImgClose->setDisabled(imageID < 0);
+ m_ui->bnPopup->setDisabled(imageID < 0);
+
+ if(imageID < 0) {
+ m_currImageID = -1;
+ m_ui->imgView->setPixmap(QPixmap());
+ }
+ else if(m_imgInfoMap.contains(imageID)) {
+ ImageInfoIter info = m_imgInfoMap.find(imageID);
+
+ m_ui->imgView->blockSignals(true);
+ m_ui->imgView->setPixmap(info->pixmap);
+ setZoom(*info);
+ m_ui->imgView->blockSignals(false);
+
+ m_ui->bnImgPrev->setDisabled(info == m_imgInfoMap.begin());
+ m_ui->bnImgNext->setDisabled((info+1) == m_imgInfoMap.end());
+
+ m_ui->cmbImg->blockSignals(true);
+ m_ui->cmbImg->setCurrentIndex(m_imgListModel->indexFromID(imageID));
+ m_ui->cmbImg->blockSignals(false);
+
+ m_currImageID = imageID;
+ }
+}
+
+void ImageDockerDock::setZoom(const ImageInfo& info)
+{
+ m_ui->imgView->setViewMode(info.viewMode, info.scale);
+ m_ui->imgView->setScrollPos(info.scrollPos);
+
+ int zoom = qRound(m_ui->imgView->getScale() * 100.0f);
+
+ m_popupUi->zoomSlider->blockSignals(true);
+ m_popupUi->zoomSlider->setValue(zoom);
+ m_popupUi->zoomSlider->blockSignals(false);
+}
+
+
+// ------------ slots ------------------------------------------------- //
+
+void ImageDockerDock::slotItemDoubleClicked(const QModelIndex& index)
+{
+ QModelIndex mappedIndex = m_proxyModel->mapToSource(index);
+ mappedIndex = m_model->index(mappedIndex.row(), 0, mappedIndex.parent());
+ QString path(m_model->filePath(mappedIndex));
+
+ if(m_model->isDir(mappedIndex)) {
+ addCurrentPathToHistory();
+ updatePath(path);
+ m_ui->treeView->setRootIndex(m_proxyModel->mapFromSource(mappedIndex));
+ }
+ else slotOpenImage(path);
+}
+
+void ImageDockerDock::slotBackButtonClicked()
+{
+ if(!m_history.empty()) {
+ QString path = m_history.last();
+ QModelIndex index = m_proxyModel->mapFromSource(m_model->index(path));
+ m_ui->treeView->setRootIndex(index);
+ m_history.pop_back();
+ updatePath(path);
+ }
+}
+
+void ImageDockerDock::slotHomeButtonClicked()
+{
+ addCurrentPathToHistory();
+ QModelIndex index = \
m_proxyModel->mapFromSource(m_model->index(QDir::homePath())); + \
m_ui->treeView->setRootIndex(index); + updatePath(QDir::homePath());
+}
+
+void ImageDockerDock::slotUpButtonClicked()
+{
+ addCurrentPathToHistory();
+
+ QModelIndex index = m_proxyModel->mapToSource(m_ui->treeView->rootIndex());
+ QDir dir(m_model->filePath(index));
+ dir.makeAbsolute();
+
+ if(dir.cdUp()) {
+ index = m_proxyModel->mapFromSource(m_model->index(dir.path()));
+ m_ui->treeView->setRootIndex(index);
+ updatePath(dir.path());
+ }
+}
+
+void ImageDockerDock::slotOpenImage(const QString& path)
+{
+ QPixmap pixmap(path);
+
+ if(!pixmap.isNull()) {
+ QFileInfo fileInfo(path);
+ ImageInfo imgInfo;
+ imgInfo.id = generateImageID();
+ imgInfo.name = fileInfo.fileName();
+ imgInfo.path = fileInfo.absoluteFilePath();
+ imgInfo.viewMode = KisImageView::VIEW_MODE_FIT;
+ imgInfo.scale = 1.0f;
+ imgInfo.pixmap = pixmap;
+ imgInfo.scrollPos = QPoint(0, 0);
+
+ m_imgInfoMap[imgInfo.id] = imgInfo;
+ m_imgListModel->addImage(imgInfo.pixmap, imgInfo.name, imgInfo.id);
+ setCurrentImage(imgInfo.id);
+ m_ui->tabWidget->setCurrentIndex(1);
+ }
+}
+
+void ImageDockerDock::slotCloseCurrentImage()
+{
+ ImageInfoIter info = m_imgInfoMap.find(m_currImageID);
+
+ if(info != m_imgInfoMap.end()) {
+ ImageInfoIter next = info + 1;
+ ImageInfoIter prev = info - 1;
+ qint64 id = -1;
+
+ if(next != m_imgInfoMap.end())
+ id = next->id;
+ else if(info != m_imgInfoMap.begin())
+ id = prev->id;
+
+ m_imgListModel->removeImage(info->id);
+ m_imgInfoMap.erase(info);
+ setCurrentImage(id);
+
+ if(id < 0)
+ m_ui->tabWidget->setCurrentIndex(0);
+ }
+}
+
+void ImageDockerDock::slotNextImage()
+{
+ ImageInfoIter info = m_imgInfoMap.find(m_currImageID);
+
+ if(info != m_imgInfoMap.end()) {
+ ++info;
+ if(info != m_imgInfoMap.end())
+ setCurrentImage(info->id);
+ }
+}
+
+void ImageDockerDock::slotPrevImage()
+{
+ ImageInfoIter info = m_imgInfoMap.find(m_currImageID);
+
+ if(info != m_imgInfoMap.end() && info != m_imgInfoMap.begin()) {
+ --info;
+ setCurrentImage(info->id);
+ }
+}
+
+void ImageDockerDock::slotImageChoosenFromComboBox(int index)
+{
+ setCurrentImage(m_imgListModel->imageID(index));
+}
+
+void ImageDockerDock::slotZoomChanged(int zoom)
+{
+ if(isImageLoaded()) {
+ ImageInfoIter info = m_imgInfoMap.find(m_currImageID);
+
+ switch(zoom)
+ {
+ case KisImageView::VIEW_MODE_FIT:
+ case KisImageView::VIEW_MODE_ADJUST:
+ info->viewMode = zoom;
+ break;
+
+ default:
+ info->viewMode = KisImageView::VIEW_MODE_FREE;
+ info->scale = float(zoom) / 100.0f;
+ break;
+ }
+
+ setZoom(*info);
+ }
+}
+
+void ImageDockerDock::slotColorSelected(const QColor& color)
+{
+ m_canvas->resourceManager()->setForegroundColor(
+ KoColor(color, KoColorSpaceRegistry::instance()->rgb8())
+ );
+}
+
+void ImageDockerDock::slotDockLocationChanged(Qt::DockWidgetArea area)
+{
+ if(area == Qt::AllDockWidgetAreas)
+ m_ui->tabWidget->setTabPosition(QTabWidget::North);
+ else if(area & Qt::LeftDockWidgetArea)
+ m_ui->tabWidget->setTabPosition(QTabWidget::East);
+ else if(area & Qt::RightDockWidgetArea)
+ m_ui->tabWidget->setTabPosition(QTabWidget::West);
+ else
+ m_ui->tabWidget->setTabPosition(QTabWidget::North);
+}
+
+void ImageDockerDock::slotTopLevelChanged(bool topLevel)
+{
+ if(topLevel)
+ m_ui->tabWidget->setTabPosition(QTabWidget::North);
+}
+
+void ImageDockerDock::slotViewModeChanged(int viewMode, qreal scale)
+{
+ if(isImageLoaded()) {
+ m_imgInfoMap[m_currImageID].viewMode = viewMode;
+ m_imgInfoMap[m_currImageID].scale = scale;
+
+ int zoom = qRound(scale * 100.0);
+
+ m_popupUi->zoomSlider->blockSignals(true);
+ m_popupUi->zoomSlider->setValue(zoom);
+ m_popupUi->zoomSlider->blockSignals(false);
+ }
+}
+
+void ImageDockerDock::slotCloseZoomPopup()
+{
+ m_ui->bnPopup->hidePopupWidget();
+}
diff --git a/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.h \
b/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.h new file mode \
100644 index 0000000..0501a3a
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/imagedocker_dock.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef H_IMAGEDOCKER_DOCK_H_
+#define H_IMAGEDOCKER_DOCK_H_
+
+#include <QDockWidget>
+#include <KoCanvasObserverBase.h>
+#include <QStringList>
+#include <QPixmap>
+#include <QMap>
+
+class QModelIndex;
+class QFileSystemModel;
+class QButtonGroup;
+class KoCanvasBase;
+class ImageFilter;
+class KisImageStripScene;
+class ImageListModel;
+struct ImageDockerUI;
+struct PopupWidgetUI;
+
+class ImageDockerDock: public QDockWidget, public KoCanvasObserverBase
+{
+ Q_OBJECT
+
+ struct ImageInfo
+ {
+ qint64 id;
+ int viewMode;
+ QString path;
+ QString name;
+ float scale;
+ QPixmap pixmap;
+ QPoint scrollPos;
+ };
+
+ typedef QMap<qint64,ImageInfo>::iterator ImageInfoIter;
+
+public:
+ ImageDockerDock();
+ virtual ~ImageDockerDock();
+ virtual void setCanvas(KoCanvasBase* canvas);
+ virtual void unsetCanvas() { m_canvas = 0; }
+
+private slots:
+ void slotItemDoubleClicked(const QModelIndex& index);
+ void slotBackButtonClicked();
+ void slotUpButtonClicked();
+ void slotHomeButtonClicked();
+ void slotCloseCurrentImage();
+ void slotNextImage();
+ void slotPrevImage();
+ void slotOpenImage(const QString& path);
+ void slotImageChoosenFromComboBox(int index);
+ void slotZoomChanged(int zoom);
+ void slotColorSelected(const QColor& color);
+ void slotDockLocationChanged(Qt::DockWidgetArea area);
+ void slotTopLevelChanged(bool topLevel);
+ void slotViewModeChanged(int viewMode, qreal scale);
+ void slotCloseZoomPopup();
+
+private:
+ void addCurrentPathToHistory();
+ void updatePath(const QString& path);
+ qint64 generateImageID() const;
+ void setCurrentImage(qint64 imageID);
+ bool isImageLoaded() const { return m_currImageID != -1; }
+ void setZoom(const ImageInfo& info);
+
+private:
+ QFileSystemModel* m_model;
+ QButtonGroup* m_zoomButtons;
+ KoCanvasBase* m_canvas;
+ ImageFilter* m_proxyModel;
+ ImageListModel* m_imgListModel;
+ QStringList m_history;
+ KisImageStripScene* m_thumbModel;
+ ImageDockerUI* m_ui;
+ PopupWidgetUI* m_popupUi;
+ QMap<qint64,ImageInfo> m_imgInfoMap;
+ qint64 m_currImageID;
+};
+
+#endif // H_IMAGEDOCKER_DOCK_H_
diff --git a/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.cpp \
b/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.cpp new file \
mode 100644 index 0000000..b92a847
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_image_strip_scene.h"
+
+#include <QDir>
+#include <QPainter>
+#include <QHash>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsWidget>
+#include <QMutexLocker>
+#include <QIcon>
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ------------- KisImageLoader \
---------------------------------------------------------- // +
+void KisImageLoader::run()
+{
+ typedef QHash<KisImageItem*,Data>::iterator Iterator;
+
+ QImageReader reader;
+
+ for(Iterator data=m_data.begin(); data!=m_data.end() && m_run; ++data) {
+ reader.setFileName(data->path);
+ qreal w = m_size;
+ qreal h = m_size;
+
+ if(reader.supportsOption(QImageIOHandler::Size)) {
+ QSizeF imgSize = reader.size();
+
+ if(imgSize.width() > imgSize.height()) {
+ qreal div = m_size / imgSize.width();
+ h = imgSize.height() * div;
+ }
+ else {
+ qreal div = m_size / imgSize.height();
+ w = imgSize.width() * div;
+ }
+ }
+
+ reader.setScaledSize(QSize(w,h));
+ data->image = reader.read();
+ data->isLoaded = true;
+ emit sigItemContentChanged(data.key());
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ------------- KisImageItem \
------------------------------------------------------------ // +
+void KisImageItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, \
QWidget* widget) +{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ if(m_loader->isImageLoaded(this)) {
+ QImage image = m_loader->getImage(this);
+
+ if(!image.isNull()) {
+ QPointF offset((m_size-image.width()) / 2.0, (m_size-image.height()) / \
2.0); + painter->drawImage(offset, image);
+ }
+ else {
+ QIcon icon = QIcon::fromTheme("image-missing");
+ QRect rect = boundingRect().toRect();
+ QPixmap img = icon.pixmap(rect.size());
+ painter->drawPixmap(rect, img, img.rect());
+ }
+ }
+ else {
+ QIcon icon = QIcon::fromTheme("image-loading");
+ QRect rect = boundingRect().toRect();
+ QPixmap img = icon.pixmap(rect.size());
+ painter->drawPixmap(rect, img, img.rect());
+ }
+
+ if(isSelected())
+ painter->fillRect(boundingRect(), Qt::Dense5Pattern);
+
+ painter->drawRect(boundingRect());
+}
+
+QSizeF KisImageItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ return QSizeF(m_size, m_size);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ------------- KisImageStripScene \
------------------------------------------------------ // +
+KisImageStripScene::KisImageStripScene():
+ m_imgSize(80), m_loader(0) { }
+
+bool KisImageStripScene::setCurrentDirectory(const QString& path)
+{
+ QMutexLocker locker(&m_mutex);
+ QDir directory(path);
+ QImageReader reader;
+
+ if(directory.exists()) {
+ clear();
+
+ if(m_loader) {
+ m_loader->disconnect(this);
+ m_loader->stopExecution();
+
+ if(!m_loader->wait(500)) {
+ m_loader->terminate();
+ m_loader->wait();
+ }
+ }
+
+ delete m_loader;
+
+ m_numItems = 0;
+ m_loader = new KisImageLoader(m_imgSize);
+ connect(m_loader, SIGNAL(sigItemContentChanged(KisImageItem*)), \
SLOT(slotItemContentChanged(KisImageItem*))); +
+ QStringList files = directory.entryList(QDir::Files);
+ QGraphicsLinearLayout* layout = new QGraphicsLinearLayout();
+
+ for(QStringList::iterator name=files.begin(); name!=files.end(); ++name) {
+ QString path = directory.absoluteFilePath(*name);
+ reader.setFileName(path);
+
+ if(reader.canRead()) {
+ KisImageItem* item = new KisImageItem(m_imgSize, path, m_loader);
+ m_loader->addPath(item, path);
+ layout->addItem(item);
+ ++m_numItems;
+ }
+ }
+
+ QGraphicsWidget* widget = new QGraphicsWidget();
+ widget->setLayout(layout);
+ widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ addItem(widget);
+ setSceneRect(widget->boundingRect());
+
+ m_loader->start(QThread::LowPriority);
+ return true;
+ }
+
+ return false;
+}
+
+void KisImageStripScene::slotItemContentChanged(KisImageItem* item)
+{
+ QMutexLocker locker(&m_mutex);
+ item->update();
+}
+
+void KisImageStripScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
+{
+ KisImageItem* item = static_cast<KisImageItem*>(itemAt(event->scenePos()));
+
+ if(item)
+ emit sigImageActivated(item->path());
+}
diff --git a/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.h \
b/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.h new file mode \
100644 index 0000000..d9dc8b9
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/kis_image_strip_scene.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef H_IMAGE_STRIP_SCENE_H_
+#define H_IMAGE_STRIP_SCENE_H_
+
+#include <QGraphicsScene>
+#include <QGraphicsWidget>
+#include <QImageReader>
+#include <QThread>
+#include <QAtomicInt>
+#include <QMutex>
+
+class KisImageItem;
+
+class KisImageLoader: public QThread
+{
+ Q_OBJECT
+
+ struct Data
+ {
+ Data() { }
+ Data(const QString& p):
+ path(p), isLoaded(false) { };
+ Data(const Data& d):
+ image(d.image), path(d.path), isLoaded(d.isLoaded) { };
+
+ QImage image;
+ QString path;
+ QAtomicInt isLoaded;
+ };
+
+signals:
+ void sigItemContentChanged(KisImageItem* item);
+
+public:
+ KisImageLoader(float size): m_size(size), m_run(true) { }
+
+ void addPath(KisImageItem* item, const QString& path) {
+ m_data[item] = Data(path);
+ }
+
+ bool isImageLoaded(KisImageItem* item) const {
+ return m_data[item].isLoaded != false;
+ }
+
+ QImage getImage(KisImageItem* item) const {
+ return m_data[item].image;
+ }
+
+ void stopExecution() {
+ m_run = false;
+ }
+
+ virtual void run();
+
+private:
+ float m_size;
+ QHash<KisImageItem*,Data> m_data;
+ QAtomicInt m_run;
+};
+
+class KisImageItem: public QGraphicsWidget
+{
+public:
+ KisImageItem(float size, const QString& path, KisImageLoader* loader):
+ m_size(size), m_loader(loader), m_path(path)
+ {
+ setFlag(QGraphicsItem::ItemIsSelectable, true);
+ }
+
+ const QString& path() const { return m_path; }
+
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint=QSizeF()) \
const; + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* \
option, QWidget* widget=0); +
+private:
+ float m_size;
+ KisImageLoader* m_loader;
+ QString m_path;
+};
+
+class KisImageStripScene: public QGraphicsScene
+{
+ Q_OBJECT
+
+public:
+ KisImageStripScene();
+ bool setCurrentDirectory(const QString& path);
+
+signals:
+ void sigImageActivated(const QString& path);
+
+private:
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
+
+private slots:
+ void slotItemContentChanged(KisImageItem* item);
+
+private:
+ float m_imgSize;
+ quint32 m_numItems;
+ KisImageLoader* m_loader;
+ QMutex m_mutex;
+};
+
+#endif // H_IMAGE_STRIP_SCENE_H_
diff --git a/krita/plugins/extensions/dockers/imagedocker/kis_image_view.cpp \
b/krita/plugins/extensions/dockers/imagedocker/kis_image_view.cpp new file mode \
100644 index 0000000..c138fca
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/kis_image_view.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_image_view.h"
+
+#include <QPaintEvent>
+#include <QMouseEvent>
+#include <QResizeEvent>
+#include <QPainter>
+#include <QScrollBar>
+
+//////////////////////////////////////////////////////////////////////////////
+// -------- KisImageViewport ---------------------------------------------- //
+
+KisImageViewport::KisImageViewport():
+ m_scale(1.0f),
+ m_mousePressed(false),
+ m_rubberBand(QRubberBand::Rectangle, this)
+{
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+}
+
+void KisImageViewport::paintEvent(QPaintEvent* event)
+{
+ Q_UNUSED(event);
+ QPainter painter(this);
+ painter.drawPixmap(imageRect().topLeft(), m_cachedPixmap);
+}
+
+void KisImageViewport::setImage(const QPixmap& pixmap, qreal scale)
+{
+ m_scale = scale;
+ m_pixmap = pixmap;
+ m_cachedPixmap = pixmap.scaled(imageRect().size(), Qt::IgnoreAspectRatio, \
Qt::FastTransformation); +}
+
+void KisImageViewport::setScale(qreal scale)
+{
+ if(!qFuzzyCompare(scale, m_scale)) {
+ m_scale = scale;
+ m_cachedPixmap = m_pixmap.scaled(imageRect().size(), Qt::IgnoreAspectRatio, \
Qt::FastTransformation); + }
+}
+
+QColor KisImageViewport::imageColor(const QPoint& pos) const
+{
+ return m_cachedPixmap.copy(pos.x(), pos.y(), 1, 1).toImage().pixel(0,0);
+}
+
+QSize KisImageViewport::sizeHint() const
+{
+ return imageRect().size();
+}
+
+QRect KisImageViewport::imageRect() const
+{
+ int w = int(m_scale * m_pixmap.width());
+ int h = int(m_scale * m_pixmap.height());
+ int x = (width() - w) / 2;
+ int y = (height() - h) / 2;
+ return QRect(x, y, w, h);
+}
+
+QSize KisImageViewport::imageSize() const
+{
+ return m_pixmap.size();
+}
+
+void KisImageViewport::mousePressEvent(QMouseEvent* event)
+{
+ m_mousePressed = true;
+ m_selection = QRect(event->pos(), QSize(0,0));
+ m_rubberBand.setGeometry(m_selection);
+ m_rubberBand.show();
+}
+
+void KisImageViewport::mouseMoveEvent(QMouseEvent* event)
+{
+ if(m_mousePressed) {
+ QPoint size = event->pos() - m_selection.topLeft();
+ m_selection.setSize(QSize(size.x(), size.y()));
+ m_rubberBand.setGeometry(m_selection.normalized());
+ }
+}
+
+void KisImageViewport::mouseReleaseEvent(QMouseEvent* event)
+{
+ m_selection = m_selection.normalized();
+
+ if(m_selection.width() > 5 && m_selection.height() > 5) {
+ QRect imgRect = imageRect();
+ QRect rect = \
imgRect.intersected(m_selection).translated(-imgRect.topLeft()); + emit \
sigRegionSelected(rect); + }
+ else if(imageRect().contains(event->pos(), true)) {
+ emit sigImageClicked(event->pos() - imageRect().topLeft());
+ }
+
+ m_mousePressed = false;
+ m_rubberBand.hide();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// -------- KisImageView -------------------------------------------------- //
+
+KisImageView::KisImageView(QWidget* parent):
+ QScrollArea(parent),
+ m_viewMode(VIEW_MODE_FIT),
+ m_minScale(0.05),
+ m_maxScale(5.00)
+{
+ m_imgViewport = new KisImageViewport();
+ QScrollArea::setWidgetResizable(true);
+ QScrollArea::setWidget(m_imgViewport);
+
+ connect(m_imgViewport, SIGNAL(sigImageClicked(const QPoint&)) , \
SLOT(slotImageClicked(const QPoint&))); + connect(m_imgViewport, \
SIGNAL(sigRegionSelected(const QRect&)), SLOT(slotRegionSelected(const QRect&))); +}
+
+void KisImageView::setPixmap(const QPixmap& pixmap, int viewMode, qreal scale)
+{
+ m_viewMode = viewMode;
+ m_scale = calcScale(scale, viewMode, pixmap.size());
+ m_imgViewport->setImage(pixmap, m_scale);
+ m_imgViewport->setMinimumSize(m_imgViewport->sizeHint());
+ m_imgViewport->adjustSize();
+
+ emit sigViewModeChanged(m_viewMode, m_scale);
+}
+
+void KisImageView::setViewMode(int viewMode, qreal scale)
+{
+ m_viewMode = viewMode;
+ m_scale = calcScale(scale, viewMode, m_imgViewport->imageSize());
+ m_imgViewport->setScale(m_scale);
+ m_imgViewport->setMinimumSize(m_imgViewport->sizeHint());
+ m_imgViewport->adjustSize();
+
+ emit sigViewModeChanged(m_viewMode, m_scale);
+}
+
+void KisImageView::setScrollPos(const QPoint& pos)
+{
+ horizontalScrollBar()->setValue(pos.x());
+ verticalScrollBar()->setValue(pos.y());
+}
+
+QPoint KisImageView::getScrollPos() const
+{
+ return QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value());
+}
+
+qreal KisImageView::getScale() const
+{
+ return m_scale;
+}
+
+qreal KisImageView::calcScale(qreal scale, int viewMode, const QSizeF& imgSize) \
const +{
+ QSizeF viewSize = viewportSize(viewMode == VIEW_MODE_ADJUST);
+ qreal wdgAspect = viewSize.width() / viewSize.height();
+ qreal imgAspect = imgSize.width() / imgSize.height();
+
+ switch(viewMode)
+ {
+ case VIEW_MODE_FIT:
+ if(wdgAspect > imgAspect) { scale = viewSize.height() / imgSize.height(); }
+ else { scale = viewSize.width() / imgSize.width(); }
+ break;
+
+ case VIEW_MODE_ADJUST:
+ if(wdgAspect > imgAspect) { scale = viewSize.width() / imgSize.width(); }
+ else { scale = viewSize.height() / imgSize.height(); }
+ break;
+ }
+
+ return qBound(m_minScale, scale, m_maxScale);
+}
+
+QSize KisImageView::viewportSize(bool withScrollbars) const
+{
+ int width = viewport()->width();
+ int height = viewport()->height();
+ int xAdd = verticalScrollBar()->width();
+ int yAdd = horizontalScrollBar()->height();
+
+ if(withScrollbars) {
+ width -= verticalScrollBar()->isVisible() ? 0 : xAdd;
+ height -= horizontalScrollBar()->isVisible() ? 0 : yAdd;
+ }
+ else {
+ width += verticalScrollBar()->isVisible() ? xAdd : 0;
+ height += horizontalScrollBar()->isVisible() ? yAdd : 0;
+ }
+
+ return QSize(width, height);
+}
+
+void KisImageView::slotImageClicked(const QPoint& pos)
+{
+ emit sigColorSelected(m_imgViewport->imageColor(pos));
+}
+
+void KisImageView::slotRegionSelected(const QRect& rect)
+{
+ QSizeF viewSize = viewportSize(true);
+ QSizeF imgSize = m_imgViewport->imageSize();
+ QRectF selRect = rect;
+
+ selRect = QRectF(selRect.topLeft() / m_scale, selRect.size() / m_scale);
+
+ qreal wdgAspect = viewSize.width() / viewSize.height();
+ qreal selAspect = selRect.width() / selRect.height();
+
+ if(wdgAspect > selAspect)
+ m_scale = viewSize.height() / selRect.height();
+ else
+ m_scale = viewSize.width() / selRect.width();
+
+ m_scale = qBound(m_minScale, m_scale, m_maxScale);
+ m_viewMode = VIEW_MODE_FREE;
+ m_imgViewport->setScale(m_scale);
+ m_imgViewport->setMinimumSize(m_imgViewport->sizeHint());
+ m_imgViewport->adjustSize();
+
+ selRect = QRectF(selRect.topLeft() * m_scale, selRect.size() * m_scale);
+
+ QSize offset = ((viewSize - selRect.size()) / 2.0).toSize();
+ QPoint scrollPos = selRect.topLeft().toPoint() - QPoint(offset.width(), \
offset.height()); + setScrollPos(scrollPos);
+
+ emit sigViewModeChanged(m_viewMode, m_scale);
+}
+
+void KisImageView::resizeEvent(QResizeEvent* event)
+{
+ QScrollArea::resizeEvent(event);
+
+ m_scale = calcScale(m_scale, m_viewMode, m_imgViewport->imageSize());
+ m_imgViewport->setScale(m_scale);
+ m_imgViewport->setMinimumSize(m_imgViewport->sizeHint());
+ m_imgViewport->adjustSize();
+
+ emit sigViewModeChanged(m_viewMode, m_scale);
+}
+
diff --git a/krita/plugins/extensions/dockers/imagedocker/kis_image_view.h \
b/krita/plugins/extensions/dockers/imagedocker/kis_image_view.h new file mode 100644
index 0000000..f55b7a2
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/kis_image_view.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef H_KIS_IMAGE_VIEW_H
+#define H_KIS_IMAGE_VIEW_H
+
+#include <QScrollArea>
+#include <QPixmap>
+#include <QRubberBand>
+
+class KisImageViewport: public QWidget
+{
+ Q_OBJECT
+
+public:
+ KisImageViewport();
+
+ QRect imageRect() const;
+ QColor imageColor(const QPoint& pos) const;
+ QSize imageSize() const;
+
+ void setImage(const QPixmap& pixmap, qreal scale);
+ void setScale(qreal scale);
+
+ virtual QSize sizeHint() const;
+ virtual void paintEvent(QPaintEvent* event);
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void mouseMoveEvent(QMouseEvent* event);
+ virtual void mouseReleaseEvent(QMouseEvent* event);
+
+private:
+ qreal m_scale;
+ QPixmap m_pixmap;
+ QPixmap m_cachedPixmap;
+ bool m_mousePressed;
+ QRubberBand m_rubberBand;
+ QRect m_selection;
+
+signals:
+ void sigImageClicked(const QPoint& pos);
+ void sigRegionSelected(const QRect& rect);
+};
+
+class KisImageView: public QScrollArea
+{
+ Q_OBJECT
+
+public:
+ enum { VIEW_MODE_FREE=0, VIEW_MODE_ADJUST=1, VIEW_MODE_FIT=2 };
+
+ KisImageView(QWidget* parent=0);
+
+ void setPixmap(const QPixmap& pixmap, int viewMode=VIEW_MODE_FIT, qreal \
scale=1.0); + void setViewMode(int viewMode, qreal scale=1.0);
+ void setScrollPos(const QPoint& pos);
+ QPoint getScrollPos() const;
+ qreal getScale() const;
+
+signals:
+ void sigColorSelected(const QColor& color);
+ void sigViewModeChanged(int viewMode, qreal scale);
+
+private slots:
+ void slotImageClicked(const QPoint& pos);
+ void slotRegionSelected(const QRect& rect);
+
+private:
+ qreal calcScale(qreal scale, int viewMode, const QSizeF& imgSize) const;
+ QSize viewportSize(bool withScrollbars) const;
+ virtual void resizeEvent(QResizeEvent* event);
+
+private:
+ qreal m_scale;
+ int m_viewMode;
+ qreal m_minScale;
+ qreal m_maxScale;
+ KisImageViewport* m_imgViewport;
+};
+
+#endif // H_KIS_IMAGE_VIEW_H
diff --git a/krita/plugins/extensions/dockers/imagedocker/kritaimagedocker.desktop \
b/krita/plugins/extensions/dockers/imagedocker/kritaimagedocker.desktop new file mode \
100644 index 0000000..d8ce40d
--- /dev/null
+++ b/krita/plugins/extensions/dockers/imagedocker/kritaimagedocker.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Image Docker
+Name[en_GB]=Image Docker
+Comment=Docker for reference images
+Comment[en_GB]=Docker for reference images
+X-KDE-ServiceTypes=Krita/Dock
+Type=Service
+X-KDE-Library=kritaimagedocker
+X-Krita-Version=4
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic