diff --git a/libs/resourcewidgets/KisResourceItemChooser.cpp b/libs/resourcewidgets/KisResourceItemChooser.cpp index d787eb1043..9d0802f8df 100644 --- a/libs/resourcewidgets/KisResourceItemChooser.cpp +++ b/libs/resourcewidgets/KisResourceItemChooser.cpp @@ -1,586 +1,544 @@ /* This file is part of the KDE project Copyright (c) 2002 Patrick Julien Copyright (c) 2007 Jan Hambrecht Copyright (c) 2007 Sven Langkamp Copyright (C) 2011 Srikanth Tiyyagura Copyright (c) 2011 José Luis Vergara Copyright (c) 2013 Sascha Suelzer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisResourceItemChooser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include "KisResourceItemView.h" +#include "KisResourceItemListView.h" #include "KisResourceItemDelegate.h" #include "KisTagFilterWidget.h" #include "KisTagChooserWidget.h" #include "KisResourceItemChooserSync.h" #include "KisResourceTaggingManager.h" #include "kis_assert.h" class Q_DECL_HIDDEN KisResourceItemChooser::Private { public: Private(QString _resourceType) : resourceType(_resourceType) {} QString resourceType; KisResourceModel *resourceModel {0}; - KisResourceGridProxyModel *resourceGridProxyModel {0}; KisTagFilterResourceProxyModel *tagFilterProxyModel {0}; QSortFilterProxyModel *extraFilterModel {0}; KisResourceTaggingManager *tagManager {0}; - KisResourceItemView *view {0}; + KisResourceItemListView *view {0}; QButtonGroup *buttonGroup {0}; QToolButton *viewModeButton {0}; QScrollArea *previewScroller {0}; QLabel *previewLabel {0}; QSplitter *splitter {0}; QGridLayout *buttonLayout {0}; QPushButton *importButton {0}; QPushButton *deleteButton {0}; bool usePreview {false}; bool tiledPreview {false}; bool grayscalePreview {false}; bool synced {false}; bool updatesBlocked {false}; QModelIndex savedResourceWhileReset; // Indexes on the proxyModel, not the source resource model QList customButtons; }; KisResourceItemChooser::KisResourceItemChooser(const QString &resourceType, bool usePreview, QWidget *parent, QSortFilterProxyModel *extraFilterProxy) : QWidget(parent) , d(new Private(resourceType)) { - d->extraFilterModel = extraFilterProxy; - if (d->extraFilterModel) { - d->extraFilterModel->setParent(this); - } + //d->extraFilterModel = extraFilterProxy; + //if (d->extraFilterModel) { + // d->extraFilterModel->setParent(this); + //} d->splitter = new QSplitter(this); d->resourceModel = KisResourceModelProvider::resourceModel(resourceType); d->tagFilterProxyModel = new KisTagFilterResourceProxyModel(this); d->tagFilterProxyModel->setSourceModel(d->resourceModel); - d->resourceGridProxyModel = new KisResourceGridProxyModel(this); - - if (d->extraFilterModel) { - d->extraFilterModel->setSourceModel(d->resourceModel); - d->resourceGridProxyModel->setSourceModel(d->extraFilterModel); - } - else { - d->resourceGridProxyModel->setSourceModel(d->tagFilterProxyModel); - } - - d->resourceGridProxyModel->setRowStride(10); - connect(d->resourceModel, SIGNAL(beforeResourcesLayoutReset(QModelIndex)), SLOT(slotBeforeResourcesLayoutReset(QModelIndex))); connect(d->resourceModel, SIGNAL(afterResourcesLayoutReset()), SLOT(slotAfterResourcesLayoutReset())); - d->view = new KisResourceItemView(this); + d->view = new KisResourceItemListView(this); d->view->setObjectName("ResourceItemview"); - d->view->setModel(d->resourceGridProxyModel); + //if (d->extraFilterModel) { + // d->extraFilterModel->setSourceModel(d->resourceModel); + // d->view->setModel(d->extraFilterModel); + //} + //else { + d->view->setModel(d->tagFilterProxyModel); + //} d->view->setItemDelegate(new KisResourceItemDelegate(this)); d->view->setSelectionMode(QAbstractItemView::SingleSelection); d->view->viewport()->installEventFilter(this); connect(d->view, SIGNAL(currentResourceChanged(QModelIndex)), this, SLOT(activated(QModelIndex))); connect(d->view, SIGNAL(currentResourceClicked(QModelIndex)), this, SLOT(clicked(QModelIndex))); connect(d->view, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); connect(d->view, SIGNAL(sigSizeChanged()), this, SLOT(updateView())); d->splitter->addWidget(d->view); d->splitter->setStretchFactor(0, 2); d->usePreview = usePreview; if (d->usePreview) { d->previewScroller = new QScrollArea(this); d->previewScroller->setWidgetResizable(true); d->previewScroller->setBackgroundRole(QPalette::Dark); d->previewScroller->setVisible(true); d->previewScroller->setAlignment(Qt::AlignCenter); d->previewLabel = new QLabel(this); d->previewScroller->setWidget(d->previewLabel); d->splitter->addWidget(d->previewScroller); if (d->splitter->count() == 2) { d->splitter->setSizes(QList() << 280 << 160); } QScroller* scroller = KisKineticScroller::createPreconfiguredScroller(d->previewScroller); if (scroller) { connect(scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChanged(QScroller::State))); } } d->splitter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); connect(d->splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterMoved())); d->buttonGroup = new QButtonGroup(this); d->buttonGroup->setExclusive(false); QGridLayout *layout = new QGridLayout(this); d->buttonLayout = new QGridLayout(); d->importButton = new QPushButton(this); d->importButton->setToolTip(i18nc("@info:tooltip", "Import resource")); d->importButton->setEnabled(true); d->buttonGroup->addButton(d->importButton, Button_Import); d->buttonLayout->addWidget(d->importButton, 0, 0); d->deleteButton = new QPushButton(this); d->deleteButton->setToolTip(i18nc("@info:tooltip", "Delete resource")); d->deleteButton->setEnabled(false); d->buttonGroup->addButton(d->deleteButton, Button_Remove); d->buttonLayout->addWidget(d->deleteButton, 0, 1); connect(d->buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotButtonClicked(int))); d->buttonLayout->setColumnStretch(0, 1); d->buttonLayout->setColumnStretch(1, 1); d->buttonLayout->setColumnStretch(2, 2); d->buttonLayout->setSpacing(0); d->buttonLayout->setMargin(0); d->viewModeButton = new QToolButton(this); d->viewModeButton->setPopupMode(QToolButton::InstantPopup); d->viewModeButton->setVisible(false); d->tagManager = new KisResourceTaggingManager(d->tagFilterProxyModel, this); connect(d->tagManager, SIGNAL(updateView()), this, SLOT(updateView())); layout->addWidget(d->tagManager->tagChooserWidget(), 0, 0); layout->addWidget(d->viewModeButton, 0, 1); layout->addWidget(d->splitter, 1, 0, 1, 2); layout->addWidget(d->tagManager->tagFilterWidget(), 2, 0, 1, 2); layout->addLayout(d->buttonLayout, 3, 0, 1, 2); layout->setMargin(0); layout->setSpacing(0); updateView(); updateButtonState(); showTaggingBar(false); - activated(d->resourceGridProxyModel->index(0, 0)); + activated(d->view->model()->index(0, 0)); } KisResourceItemChooser::~KisResourceItemChooser() { disconnect(); delete d; } void KisResourceItemChooser::slotButtonClicked(int button) { if (button == Button_Import) { QStringList mimeTypes = KisResourceLoaderRegistry::instance()->mimeTypes(d->resourceType); KoFileDialog dialog(0, KoFileDialog::OpenFiles, "OpenDocument"); dialog.setMimeTypeFilters(mimeTypes); dialog.setCaption(i18nc("@title:window", "Choose File to Add")); Q_FOREACH(const QString &filename, dialog.filenames()) { if (QFileInfo(filename).exists() && QFileInfo(filename).isReadable()) { - d->resourceGridProxyModel->importResourceFile(filename); + d->tagFilterProxyModel->importResourceFile(filename); } } } else if (button == Button_Remove) { QModelIndex index = d->view->currentIndex(); if (index.isValid()) { - d->resourceGridProxyModel->removeResource(index); + d->tagFilterProxyModel->removeResource(index); } int row = index.row(); - int column = index.column(); - - if (column == 0) { - int rowMin = --row; - row = qBound(0, rowMin, row); - } - int columnMin = --column; - column = qBound(0, columnMin, column); - setCurrentItem(row, column); - activated(d->resourceGridProxyModel->index(row, column)); + int rowMin = --row; + row = qBound(0, rowMin, row); + setCurrentItem(row); + activated(d->tagFilterProxyModel->index(row, index.column())); } updateButtonState(); } void KisResourceItemChooser::showButtons(bool show) { foreach (QAbstractButton * button, d->buttonGroup->buttons()) { show ? button->show() : button->hide(); } Q_FOREACH (QAbstractButton *button, d->customButtons) { show ? button->show() : button->hide(); } } void KisResourceItemChooser::addCustomButton(QAbstractButton *button, int cell) { d->buttonLayout->addWidget(button, 0, cell); d->buttonLayout->setColumnStretch(2, 1); d->buttonLayout->setColumnStretch(3, 1); } void KisResourceItemChooser::showTaggingBar(bool show) { d->tagManager->showTaggingBar(show); } -void KisResourceItemChooser::setRowCount(int rowCount) -{ - int resourceCount = d->resourceModel->rowCount(); - d->resourceGridProxyModel->setRowStride(static_cast(resourceCount) / rowCount); - //Force an update to get the right row height (in theory) - QRect geometry = d->view->geometry(); - d->view->setViewMode(KisResourceItemView::FIXED_ROWS); - d->view->setGeometry(geometry.adjusted(0, 0, 0, 1)); - d->view->setGeometry(geometry); -} - -void KisResourceItemChooser::setColumnCount(int columnCount) -{ - d->resourceGridProxyModel->setRowStride(columnCount); -} - int KisResourceItemChooser::rowCount() const { - return d->resourceGridProxyModel->rowCount(); + return d->view->model()->rowCount(); } void KisResourceItemChooser::setRowHeight(int rowHeight) { - d->view->verticalHeader()->setDefaultSectionSize(rowHeight); + d->view->setItemSize(QSize(d->view->gridSize().width(), rowHeight)); } void KisResourceItemChooser::setColumnWidth(int columnWidth) { - d->view->horizontalHeader()->setDefaultSectionSize(columnWidth); + d->view->setItemSize(QSize(columnWidth, d->view->gridSize().height())); } void KisResourceItemChooser::setItemDelegate(QAbstractItemDelegate *delegate) { d->view->setItemDelegate(delegate); } KoResourceSP KisResourceItemChooser::currentResource() const { QModelIndex index = d->view->currentIndex(); if (index.isValid()) { return resourceFromModelIndex(index); } return 0; } void KisResourceItemChooser::setCurrentResource(KoResourceSP resource) { // don't update if the change came from the same chooser if (d->updatesBlocked) { return; } QModelIndex index = d->resourceModel->indexFromResource(resource); d->view->setCurrentIndex(index); updatePreview(index); } void KisResourceItemChooser::slotBeforeResourcesLayoutReset(QModelIndex activateAfterReset) { - QModelIndex proxyIndex = d->resourceGridProxyModel->mapFromSource(d->tagFilterProxyModel->mapFromSource(activateAfterReset)); + QModelIndex proxyIndex = d->tagFilterProxyModel->mapFromSource(d->tagFilterProxyModel->mapFromSource(activateAfterReset)); d->savedResourceWhileReset = proxyIndex.isValid() ? proxyIndex : d->view->currentIndex(); } void KisResourceItemChooser::slotAfterResourcesLayoutReset() { if (d->savedResourceWhileReset.isValid()) { this->blockSignals(true); - setCurrentItem(d->savedResourceWhileReset.row(), d->savedResourceWhileReset.column()); + setCurrentItem(d->savedResourceWhileReset.row()); this->blockSignals(false); } d->savedResourceWhileReset = QModelIndex(); } void KisResourceItemChooser::setPreviewOrientation(Qt::Orientation orientation) { d->splitter->setOrientation(orientation); } void KisResourceItemChooser::setPreviewTiled(bool tiled) { d->tiledPreview = tiled; } void KisResourceItemChooser::setGrayscalePreview(bool grayscale) { d->grayscalePreview = grayscale; } -void KisResourceItemChooser::setCurrentItem(int row, int column) +void KisResourceItemChooser::setCurrentItem(int row) { - QModelIndex index = d->resourceModel->index(row, column); + QModelIndex index = d->view->model()->index(row, 0); if (!index.isValid()) return; d->view->setCurrentIndex(index); if (index.isValid()) { updatePreview(index); } } void KisResourceItemChooser::activated(const QModelIndex &index) { if (!index.isValid()) return; KoResourceSP resource = 0; if (index.isValid()) { resource = resourceFromModelIndex(index); } if (resource && resource->valid()) { d->updatesBlocked = true; emit resourceSelected(resource); d->updatesBlocked = false; updatePreview(index); updateButtonState(); } } void KisResourceItemChooser::clicked(const QModelIndex &index) { Q_UNUSED(index); KoResourceSP resource = currentResource(); if (resource) { emit resourceClicked(resource); } } void KisResourceItemChooser::updateButtonState() { QAbstractButton *removeButton = d->buttonGroup->button(Button_Remove); if (! removeButton) return; KoResourceSP resource = currentResource(); if (resource) { removeButton->setEnabled(!resource->permanent()); return; } removeButton->setEnabled(false); } void KisResourceItemChooser::updatePreview(const QModelIndex &idx) { if (!d->usePreview) return; if (!idx.isValid()) { d->previewLabel->setPixmap(QPixmap()); return; } QImage image = idx.data(Qt::UserRole + KisResourceModel::Image).value(); if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_ARGB32 && image.format() != QImage::Format_ARGB32_Premultiplied) { image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); } if (d->tiledPreview) { int width = d->previewScroller->width() * 4; int height = d->previewScroller->height() * 4; QImage img(width, height, image.format()); QPainter gc(&img); gc.fillRect(img.rect(), Qt::white); gc.setPen(Qt::NoPen); gc.setBrush(QBrush(image)); gc.drawRect(img.rect()); image = img; } // Only convert to grayscale if it is rgb. Otherwise, it's gray already. if (d->grayscalePreview && !image.isGrayscale()) { QRgb *pixel = reinterpret_cast(image.bits()); for (int row = 0; row < image.height(); ++row) { for (int col = 0; col < image.width(); ++col) { const QRgb currentPixel = pixel[row * image.width() + col]; const int red = qRed(currentPixel); const int green = qGreen(currentPixel); const int blue = qBlue(currentPixel); const int grayValue = (red * 11 + green * 16 + blue * 5) / 32; pixel[row * image.width() + col] = qRgb(grayValue, grayValue, grayValue); } } } d->previewLabel->setPixmap(QPixmap::fromImage(image)); } KoResourceSP KisResourceItemChooser::resourceFromModelIndex(const QModelIndex &index) const { if (!index.isValid()) { return 0; } - KoResourceSP r = d->resourceGridProxyModel->resourceForIndex(index); + KoResourceSP r = d->tagFilterProxyModel->resourceForIndex(index); return r; } QSize KisResourceItemChooser::viewSize() const { return d->view->size(); } -KisResourceItemView *KisResourceItemChooser::itemView() const +KisResourceItemListView *KisResourceItemChooser::itemView() const { return d->view; } void KisResourceItemChooser::contextMenuRequested(const QPoint &pos) { d->tagManager->contextMenuRequested(currentResource(), pos); } void KisResourceItemChooser::setViewModeButtonVisible(bool visible) { d->viewModeButton->setVisible(visible); } QToolButton *KisResourceItemChooser::viewModeButton() const { return d->viewModeButton; } void KisResourceItemChooser::setSynced(bool sync) { if (d->synced == sync) return; d->synced = sync; KisResourceItemChooserSync *chooserSync = KisResourceItemChooserSync::instance(); if (sync) { connect(chooserSync, SIGNAL(baseLengthChanged(int)), SLOT(baseLengthChanged(int))); baseLengthChanged(chooserSync->baseLength()); } else { chooserSync->disconnect(this); } } void KisResourceItemChooser::baseLengthChanged(int length) { if (d->synced) { - int resourceCount = d->resourceModel->rowCount(); - int width = d->view->width(); - int maxColumns = width / length; - int cols = width / (2 * length) + 1; - while (cols <= maxColumns) { - int size = width / cols; - int rows = ceil(resourceCount / (double)cols); - if (rows * size < (d->view->height())) { - break; - } - cols++; - } - setColumnCount(cols); + d->view->setItemSize(QSize(length, length)); } - d->view->updateView(); } bool KisResourceItemChooser::eventFilter(QObject *object, QEvent *event) { if (d->synced && event->type() == QEvent::Wheel) { KisResourceItemChooserSync *chooserSync = KisResourceItemChooserSync::instance(); QWheelEvent *qwheel = static_cast(event); if (qwheel->modifiers() & Qt::ControlModifier) { int degrees = qwheel->delta() / 8; int newBaseLength = chooserSync->baseLength() + degrees / 15 * 10; chooserSync->setBaseLength(newBaseLength); return true; } } return QObject::eventFilter(object, event); } void KisResourceItemChooser::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); updateView(); } void KisResourceItemChooser::showEvent(QShowEvent *event) { QWidget::showEvent(event); updateView(); } void KisResourceItemChooser::updateView() { if (d->synced) { KisResourceItemChooserSync *chooserSync = KisResourceItemChooserSync::instance(); baseLengthChanged(chooserSync->baseLength()); } /// helps to set icons here in case the theme is changed d->viewModeButton->setIcon(koIcon("view-choose")); d->importButton->setIcon(koIcon("document-open")); d->deleteButton->setIcon(koIcon("trash-empty")); } diff --git a/libs/resourcewidgets/KisResourceItemChooser.h b/libs/resourcewidgets/KisResourceItemChooser.h index 7dcbee599b..61bd21d4a9 100644 --- a/libs/resourcewidgets/KisResourceItemChooser.h +++ b/libs/resourcewidgets/KisResourceItemChooser.h @@ -1,159 +1,153 @@ /* This file is part of the KDE project Copyright (c) 2002 Patrick Julien Copyright (c) 2007 Jan Hambrecht Copyright (c) 2007 Sven Langkamp Copyright (c) 2010 Boudewijn Rempt Copyright (C) 2011 Srikanth Tiyyagura Copyright (c) 2011 José Luis Vergara Copyright (c) 2013 Sascha Suelzer Copyright (c) 2019 Boudewijn Rempt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KIS_RESOURCE_ITEM_CHOOSER #define KIS_RESOURCE_ITEM_CHOOSER #include #include #include #include #include class QAbstractProxyModel; class QAbstractItemDelegate; class QAbstractButton; class QToolButton; class QSortFilterProxyModel; -class KisResourceItemView; +class KisResourceItemListView; #include "kritaresourcewidgets_export.h" /** * A widget that contains a KoResourceChooser as well * as an import/export button */ class KRITARESOURCEWIDGETS_EXPORT KisResourceItemChooser : public QWidget { Q_OBJECT public: enum Buttons { Button_Import, Button_Remove }; /// \p usePreview shows the aside preview with the resource's image /// \p extraFilterProxy is an extra filter proxy model for additional filtering. KisResourceItemChooser will take over ownership explicit KisResourceItemChooser(const QString &resourceType, bool usePreview = false, QWidget *parent = 0, QSortFilterProxyModel *extraFilterProxy = 0); ~KisResourceItemChooser() override; - /// Sets number of columns in the view and causes the number of rows to be calculated accordingly - void setColumnCount(int columnCount); - /// return the number of rows in the view int rowCount() const; - /// Sets number of rows in the view and causes the number of columns to be calculated accordingly - void setRowCount(int rowCount); - /// Sets the height of the view rows void setRowHeight(int rowHeight); /// Sets the width of the view columns void setColumnWidth(int columnWidth); /// Sets a custom delegate for the view void setItemDelegate(QAbstractItemDelegate *delegate); /// Gets the currently selected resource /// @returns the selected resource, 0 is no resource is selected KoResourceSP currentResource() const; /// Sets the item representing the resource as selected void setCurrentResource(KoResourceSP resource); /** * Sets the selected resource, does nothing if there is no valid item * @param row row of the item * @param column column of the item */ - void setCurrentItem(int row, int column); + void setCurrentItem(int row); void showButtons(bool show); void addCustomButton(QAbstractButton *button, int cell); /// determines whether the preview right or below the splitter void setPreviewOrientation(Qt::Orientation orientation); /// determines whether the preview should tile the resource's image or not void setPreviewTiled(bool tiled); /// shows the preview converted to grayscale void setGrayscalePreview(bool grayscale); /// sets the visibility of tagging KlineEdits. void showTaggingBar(bool show); QSize viewSize() const; - KisResourceItemView *itemView() const; + KisResourceItemListView *itemView() const; void setViewModeButtonVisible(bool visible); QToolButton *viewModeButton() const; void setSynced(bool sync); bool eventFilter(QObject *object, QEvent *event) override; Q_SIGNALS: /// Emitted when a resource was selected void resourceSelected(KoResourceSP resource); /// Emitted when an *already selected* resource is clicked /// again void resourceClicked(KoResourceSP resource); void splitterMoved(); public Q_SLOTS: void slotButtonClicked(int button); void slotScrollerStateChanged(QScroller::State state){ KisKineticScroller::updateCursor(this, state); } private Q_SLOTS: void activated(const QModelIndex &index); void clicked(const QModelIndex &index); void contextMenuRequested(const QPoint &pos); void baseLengthChanged(int length); void updateView(); void slotBeforeResourcesLayoutReset(QModelIndex activateAfterReset); void slotAfterResourcesLayoutReset(); protected: void showEvent(QShowEvent *event) override; void resizeEvent(QResizeEvent *event) override; private: void updateButtonState(); void updatePreview(const QModelIndex &idx); /// Resource for a given model index /// @returns the resource pointer, 0 is index not valid KoResourceSP resourceFromModelIndex(const QModelIndex &index) const; class Private; Private *const d; }; #endif // KO_RESOURCE_ITEM_CHOOSER diff --git a/libs/resourcewidgets/KisResourceItemListView.cpp b/libs/resourcewidgets/KisResourceItemListView.cpp index 3279da81a3..0f6c10524f 100644 --- a/libs/resourcewidgets/KisResourceItemListView.cpp +++ b/libs/resourcewidgets/KisResourceItemListView.cpp @@ -1,44 +1,84 @@ /* This file is part of the KDE project * Copyright (C) 2019 Wolthera van Hövell tot Westerflier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisResourceItemListView.h" +#include +#include +#include +#include +#include + KisResourceItemListView::KisResourceItemListView(QWidget *parent): QListView(parent) { setSelectionMode(QAbstractItemView::SingleSelection); setContextMenuPolicy(Qt::DefaultContextMenu); setViewMode(QListView::IconMode); setGridSize(QSize(64, 64)); setIconSize(QSize(64, 64)); setResizeMode(QListView::Adjust); setUniformItemSizes(true); QScroller *scroller = KisKineticScroller::createPreconfiguredScroller(this); if (scroller) { connect(scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChange(QScroller::State))); } connect(this, SIGNAL(clicked(QModelIndex)), SIGNAL(currentResourceClicked(const QModelIndex &))); } void KisResourceItemListView::setItemSize(QSize size) { setGridSize(size); setIconSize(size); } + +void KisResourceItemListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + if (selected.isEmpty()) { + emit currentResourceChanged(QModelIndex()); + } + else { + emit currentResourceChanged(selected.indexes().first()); + } +} + +void KisResourceItemListView::contextMenuEvent(QContextMenuEvent *event) +{ + QListView::contextMenuEvent(event); + emit contextMenuRequested(event->globalPos()); +} + +bool KisResourceItemListView::viewportEvent(QEvent *event) +{ + if (!model()) return true; + + if (event->type() == QEvent::ToolTip) { + QHelpEvent *he = static_cast(event); + QStyleOptionViewItem option = viewOptions(); + QModelIndex index = model()->buddy(indexAt(he->pos())); + if (index.isValid()) { + option.rect = visualRect(index); + m_tip.showTip(this, he->pos(), option, index); + return true; + } + } + + return QListView::viewportEvent(event); +} diff --git a/libs/resourcewidgets/KisResourceItemListView.h b/libs/resourcewidgets/KisResourceItemListView.h index 879b3f2629..2794844e48 100644 --- a/libs/resourcewidgets/KisResourceItemListView.h +++ b/libs/resourcewidgets/KisResourceItemListView.h @@ -1,60 +1,71 @@ /* This file is part of the KDE project * Copyright (C) 2019 Wolthera van Hövell tot Westerflier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KISRESOURCEITEMLISTVIEW_H #define KISRESOURCEITEMLISTVIEW_H #include #include #include +#include "KisIconToolTip.h" + #include "kritaresourcewidgets_export.h" class KRITARESOURCEWIDGETS_EXPORT KisResourceItemListView : public QListView { Q_OBJECT public: KisResourceItemListView(QWidget *parent = nullptr); /** * @brief setItemSize * convenience function which sets both the icon and the grid size * to the same value. * @param size - the size you wish either to be. */ void setItemSize(QSize size); public Q_SLOTS: void slotScrollerStateChange(QScroller::State state){ KisKineticScroller::updateCursor(this, state); } Q_SIGNALS: void sigSizeChanged(); -Q_SIGNALS: - void currentResourceChanged(const QModelIndex &); void currentResourceClicked(const QModelIndex &); void contextMenuRequested(const QPoint &); + +protected: + friend class KisResourceItemChooser; + + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; + void contextMenuEvent(QContextMenuEvent *event) override; + + bool viewportEvent(QEvent *event) override; + +private: + KisIconToolTip m_tip; }; #endif // KISRESOURCEITEMLISTVIEW_H diff --git a/libs/ui/kis_control_frame.cpp b/libs/ui/kis_control_frame.cpp index 005df94ce1..acad0eff94 100644 --- a/libs/ui/kis_control_frame.cpp +++ b/libs/ui/kis_control_frame.cpp @@ -1,246 +1,246 @@ /* * kis_control_frame.cc - part of Krita * * Copyright (c) 1999 Matthias Elter * Copyright (c) 2003 Patrick Julien * Copyright (c) 2004 Sven Langkamp * Copyright (c) 2006 Boudewijn Rempt * * 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.g * * 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, Boston, MA 02110-1301, USA. */ #include "kis_control_frame.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisResourceServerProvider.h" #include "kis_canvas_resource_provider.h" #include "widgets/kis_iconwidget.h" #include "widgets/kis_gradient_chooser.h" #include "KisViewManager.h" #include "kis_config.h" #include "kis_paintop_box.h" #include "kis_custom_pattern.h" #include "widgets/kis_pattern_chooser.h" #include "kis_favorite_resource_manager.h" #include "kis_display_color_converter.h" #include KisControlFrame::KisControlFrame(KisViewManager *view, QWidget *parent, const char* name) : QObject(view) , m_viewManager(view) , m_patternWidget(0) , m_gradientWidget(0) , m_patternChooserPopup(0) , m_gradientChooserPopup(0) , m_paintopBox(0) { setObjectName(name); m_font = QFontDatabase::systemFont(QFontDatabase::GeneralFont); m_patternWidget = new KisIconWidget(parent, ResourceType::Patterns); m_patternWidget->setToolTip(i18n("Fill Patterns")); m_patternWidget->setFixedSize(32, 32); m_gradientWidget = new KisIconWidget(parent, ResourceType::Gradients); m_gradientWidget->setToolTip(i18n("Fill Gradients")); m_gradientWidget->setFixedSize(32, 32); } void KisControlFrame::setup(QWidget *parent) { createPatternsChooser(m_viewManager); createGradientsChooser(m_viewManager); QWidgetAction *action = new QWidgetAction(this); action->setText(i18n("&Patterns")); m_viewManager->actionCollection()->addAction(ResourceType::Patterns, action); action->setDefaultWidget(m_patternWidget); action = new QWidgetAction(this); action->setText(i18n("&Gradients")); m_viewManager->actionCollection()->addAction(ResourceType::Gradients, action); action->setDefaultWidget(m_gradientWidget); // XXX: KOMVC we don't have a canvas here yet, needs a setImageView const KoColorDisplayRendererInterface *displayRenderer = \ KisDisplayColorConverter::dumbConverterInstance()->displayRendererInterface(); m_dual = new KoDualColorButton(m_viewManager->canvasResourceProvider()->fgColor(), m_viewManager->canvasResourceProvider()->bgColor(), displayRenderer, m_viewManager->mainWindow(), m_viewManager->mainWindow()); m_dual->setPopDialog(true); action = new QWidgetAction(this); action->setText(i18n("&Color")); m_viewManager->actionCollection()->addAction("dual", action); action->setDefaultWidget(m_dual); connect(m_dual, SIGNAL(foregroundColorChanged(KoColor)), m_viewManager->canvasResourceProvider(), SLOT(slotSetFGColor(KoColor))); connect(m_dual, SIGNAL(backgroundColorChanged(KoColor)), m_viewManager->canvasResourceProvider(), SLOT(slotSetBGColor(KoColor))); connect(m_viewManager->canvasResourceProvider(), SIGNAL(sigFGColorChanged(KoColor)), m_dual, SLOT(setForegroundColor(KoColor))); connect(m_viewManager->canvasResourceProvider(), SIGNAL(sigBGColorChanged(KoColor)), m_dual, SLOT(setBackgroundColor(KoColor))); connect(m_viewManager->canvasResourceProvider(), SIGNAL(sigFGColorChanged(KoColor)), m_gradientWidget, SLOT(update())); connect(m_viewManager->canvasResourceProvider(), SIGNAL(sigBGColorChanged(KoColor)), m_gradientWidget, SLOT(update())); m_dual->setFixedSize(28, 28); connect(m_viewManager, SIGNAL(viewChanged()), SLOT(slotUpdateDisplayRenderer())); m_paintopBox = new KisPaintopBox(m_viewManager, parent, "paintopbox"); action = new QWidgetAction(this); action->setText(i18n("&Painter's Tools")); m_viewManager->actionCollection()->addAction("paintops", action); action->setDefaultWidget(m_paintopBox); } void KisControlFrame::slotUpdateDisplayRenderer() { if (m_viewManager->canvasBase()){ m_dual->setDisplayRenderer(m_viewManager->canvasBase()->displayColorConverter()->displayRendererInterface()); m_dual->setColorSpace(m_viewManager->canvasBase()->image()->colorSpace()); m_viewManager->canvasBase()->image()->disconnect(m_dual); connect(m_viewManager->canvasBase()->image(), SIGNAL(sigColorSpaceChanged(const KoColorSpace*)), m_dual, SLOT(setColorSpace(const KoColorSpace*)), Qt::UniqueConnection); } else if (m_viewManager->viewCount()==0) { m_dual->setDisplayRenderer(); } } void KisControlFrame::slotSetPattern(KoPatternSP pattern) { m_patternWidget->setThumbnail(pattern->image()); m_patternChooser->setCurrentPattern(pattern); } void KisControlFrame::slotSetGradient(KoAbstractGradientSP gradient) { m_gradientWidget->setThumbnail(gradient->image()); } void KisControlFrame::createPatternsChooser(KisViewManager * view) { if (m_patternChooserPopup) delete m_patternChooserPopup; m_patternChooserPopup = new QWidget(m_patternWidget); m_patternChooserPopup->setObjectName("pattern_chooser_popup"); QHBoxLayout * l2 = new QHBoxLayout(m_patternChooserPopup); l2->setObjectName("patternpopuplayout"); m_patternsTab = new QTabWidget(m_patternChooserPopup); m_patternsTab->setObjectName("patternstab"); m_patternsTab->setFocusPolicy(Qt::NoFocus); m_patternsTab->setFont(m_font); l2->addWidget(m_patternsTab); m_patternChooser = new KisPatternChooser(m_patternChooserPopup); m_patternChooser->setFont(m_font); QWidget *patternChooserPage = new QWidget(m_patternChooserPopup); QHBoxLayout *patternChooserPageLayout = new QHBoxLayout(patternChooserPage); patternChooserPageLayout->addWidget(m_patternChooser); m_patternsTab->addTab(patternChooserPage, i18n("Patterns")); KisCustomPattern* customPatterns = new KisCustomPattern(0, "custompatterns", i18n("Custom Pattern"), m_viewManager); customPatterns->setFont(m_font); m_patternsTab->addTab(customPatterns, i18n("Custom Pattern")); connect(m_patternChooser, SIGNAL(resourceSelected(KoResourceSP )), view->canvasResourceProvider(), SLOT(slotPatternActivated(KoResourceSP ))); connect(customPatterns, SIGNAL(activatedResource(KoResourceSP )), view->canvasResourceProvider(), SLOT(slotPatternActivated(KoResourceSP ))); connect(view->canvasResourceProvider(), SIGNAL(sigPatternChanged(KoPatternSP)), this, SLOT(slotSetPattern(KoPatternSP))); - m_patternChooser->setCurrentItem(0, 0); + m_patternChooser->setCurrentItem(0); if (m_patternChooser->currentResource() && view->canvasResourceProvider()) { view->canvasResourceProvider()->slotPatternActivated(m_patternChooser->currentResource()); } m_patternWidget->setPopupWidget(m_patternChooserPopup); } void KisControlFrame::createGradientsChooser(KisViewManager * view) { if (m_gradientChooserPopup) { delete m_gradientChooserPopup; m_gradientChooserPopup = 0; } m_gradientChooserPopup = new QWidget(m_gradientWidget); m_gradientChooserPopup->setObjectName("gradient_chooser_popup"); QHBoxLayout * l2 = new QHBoxLayout(m_gradientChooserPopup); l2->setObjectName("gradientpopuplayout"); m_gradientTab = new QTabWidget(m_gradientChooserPopup); m_gradientTab->setObjectName("gradientstab"); m_gradientTab->setFocusPolicy(Qt::NoFocus); m_gradientTab->setFont(m_font); l2->addWidget(m_gradientTab); m_gradientChooser = new KisGradientChooser(m_gradientChooserPopup); m_gradientChooser->setFont(m_font); m_gradientTab->addTab(m_gradientChooser, i18n("Gradients")); connect(m_gradientChooser, SIGNAL(resourceSelected(KoResourceSP )), view->canvasResourceProvider(), SLOT(slotGradientActivated(KoResourceSP ))); connect (view->mainWindow(), SIGNAL(themeChanged()), m_gradientChooser, SLOT(slotUpdateIcons())); connect(view->canvasResourceProvider(), SIGNAL(sigGradientChanged(KoAbstractGradientSP)), this, SLOT(slotSetGradient(KoAbstractGradientSP))); connect(m_gradientChooser, SIGNAL(resourceSelected(KoResourceSP)), view->canvasResourceProvider(), SLOT(slotGradientActivated(KoResourceSP))); connect (view->mainWindow(), SIGNAL(themeChanged()), m_gradientChooser, SLOT(slotUpdateIcons())); connect(view->canvasResourceProvider(), SIGNAL(sigGradientChanged(KoAbstractGradientSP)), this, SLOT(slotSetGradient(KoAbstractGradientSP))); - m_gradientChooser->setCurrentItem(0, 0); + m_gradientChooser->setCurrentItem(0); if (m_gradientChooser->currentResource() && view->canvasResourceProvider()) view->canvasResourceProvider()->slotGradientActivated(m_gradientChooser->currentResource()); m_gradientWidget->setPopupWidget(m_gradientChooserPopup); } diff --git a/libs/ui/widgets/kis_gradient_chooser.cc b/libs/ui/widgets/kis_gradient_chooser.cc index 6e7fedb5f1..ef22b5ecc9 100644 --- a/libs/ui/widgets/kis_gradient_chooser.cc +++ b/libs/ui/widgets/kis_gradient_chooser.cc @@ -1,205 +1,205 @@ /* * Copyright (c) 2004 Adrian Page * Copyright (C) 2011 Srikanth Tiyyagura * * 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, Boston, MA 02110-1301, USA. */ #include "widgets/kis_gradient_chooser.h" #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include "KisViewManager.h" #include "kis_global.h" #include "kis_autogradient.h" #include "kis_canvas_resource_provider.h" #include "kis_stopgradient_editor.h" KisCustomGradientDialog::KisCustomGradientDialog(KoAbstractGradientSP gradient, QWidget *parent, const char *name) : KoDialog(parent, Qt::Dialog) { setButtons(Close); setDefaultButton(Close); setObjectName(name); setModal(false); KoStopGradientSP stopGradient = gradient.dynamicCast(); if (stopGradient) { m_page = new KisStopGradientEditor(stopGradient, this, "autogradient", i18n("Custom Stop Gradient")); } else { KoSegmentGradientSP segmentedGradient = gradient.dynamicCast(); if (segmentedGradient) { m_page = new KisAutogradientEditor(segmentedGradient, this, "autogradient", i18n("Custom Segmented Gradient")); } } setCaption(m_page->windowTitle()); setMainWidget(m_page); } KisGradientChooser::KisGradientChooser(QWidget *parent, const char *name) : QFrame(parent) { setObjectName(name); m_lbName = new QLabel(); m_itemChooser = new KisResourceItemChooser(ResourceType::Gradients, false, this); m_itemChooser->showTaggingBar(true); m_itemChooser->setFixedSize(250, 250); - m_itemChooser->setColumnCount(1); + m_itemChooser->itemView()->setViewMode(QListView::ListMode); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(update(KoResourceSP ))); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SIGNAL(resourceSelected(KoResourceSP ))); QWidget* buttonWidget = new QWidget(this); QHBoxLayout* buttonLayout = new QHBoxLayout(buttonWidget); m_addGradient = new QToolButton(this); m_addGradient->setText(i18n("Add...")); m_addGradient->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); connect(m_addGradient, SIGNAL(clicked()), this, SLOT(addStopGradient())); buttonLayout->addWidget(m_addGradient); QMenu *menuAddGradient = new QMenu(m_addGradient); QAction* addStopGradient = new QAction(i18n("Stop gradient"), this); connect(addStopGradient, SIGNAL(triggered(bool)), this, SLOT(addStopGradient())); menuAddGradient->addAction(addStopGradient); QAction* addSegmentedGradient = new QAction(i18n("Segmented gradient"), this); connect(addSegmentedGradient, SIGNAL(triggered(bool)), this, SLOT(addSegmentedGradient())); menuAddGradient->addAction(addSegmentedGradient); m_addGradient->setMenu(menuAddGradient); m_addGradient->setPopupMode(QToolButton::MenuButtonPopup); m_editGradient = new QPushButton(); m_editGradient->setText(i18n("Edit...")); m_editGradient->setEnabled(false); connect(m_editGradient, SIGNAL(clicked()), this, SLOT(editGradient())); buttonLayout->addWidget(m_editGradient); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setObjectName("main layout"); mainLayout->setMargin(2); mainLayout->addWidget(m_lbName); mainLayout->addWidget(m_itemChooser, 10); mainLayout->addWidget(buttonWidget); slotUpdateIcons(); setLayout(mainLayout); } KisGradientChooser::~KisGradientChooser() { } KoResourceSP KisGradientChooser::currentResource() { return m_itemChooser->currentResource(); } void KisGradientChooser::setCurrentResource(KoResourceSP resource) { m_itemChooser->setCurrentResource(resource); } -void KisGradientChooser::setCurrentItem(int row, int column) +void KisGradientChooser::setCurrentItem(int row) { - m_itemChooser->setCurrentItem(row, column); + m_itemChooser->setCurrentItem(row); if (currentResource()) update(currentResource()); } void KisGradientChooser::slotUpdateIcons() { if (m_addGradient && m_editGradient) { m_addGradient->setIcon(KisIconUtils::loadIcon("list-add")); m_editGradient->setIcon(KisIconUtils::loadIcon("configure")); } } void KisGradientChooser::update(KoResourceSP resource) { KoAbstractGradientSP gradient = resource.staticCast(); m_lbName->setText(gradient ? i18n(gradient->name().toUtf8().data()) : ""); m_editGradient->setEnabled(true); } void KisGradientChooser::addStopGradient() { KoStopGradientSP gradient(new KoStopGradient("")); QList stops; stops << KoGradientStop(0.0, KoColor(QColor(250, 250, 0), KoColorSpaceRegistry::instance()->rgb8())) << KoGradientStop(1.0, KoColor(QColor(255, 0, 0, 255), KoColorSpaceRegistry::instance()->rgb8())); gradient->setType(QGradient::LinearGradient); gradient->setName(i18n("unnamed")); gradient->setStops(stops); addGradient(gradient); } void KisGradientChooser::addSegmentedGradient() { KoSegmentGradientSP gradient(new KoSegmentGradient("")); gradient->createSegment(INTERP_LINEAR, COLOR_INTERP_RGB, 0.0, 1.0, 0.5, Qt::black, Qt::white); gradient->setName(i18n("unnamed")); addGradient(gradient); } void KisGradientChooser::addGradient(KoAbstractGradientSP gradient) { KoResourceServer * rserver = KoResourceServerProvider::instance()->gradientServer(); QString saveLocation = rserver->saveLocation(); KisCustomGradientDialog dialog(gradient, this, "KisCustomGradientDialog"); dialog.exec(); gradient->setFilename(gradient->name() + gradient->defaultFileExtension()); gradient->setValid(true); rserver->addResource(gradient); m_itemChooser->setCurrentResource(gradient); } void KisGradientChooser::editGradient() { KisCustomGradientDialog dialog(currentResource().staticCast(), this, "KisCustomGradientDialog"); dialog.exec(); } diff --git a/libs/ui/widgets/kis_gradient_chooser.h b/libs/ui/widgets/kis_gradient_chooser.h index 4d08090032..f417b456cb 100644 --- a/libs/ui/widgets/kis_gradient_chooser.h +++ b/libs/ui/widgets/kis_gradient_chooser.h @@ -1,94 +1,94 @@ /* * Copyright (c) 2004 Adrian Page * * 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, Boston, MA 02110-1301, USA. */ #ifndef KIS_GRADIENT_CHOOSER_H_ #define KIS_GRADIENT_CHOOSER_H_ #include #include #include #include #include #include #include #include class KisViewManager; class QLabel; class QPushButton; class KisResourceItemChooser; class KisAutogradientEditor; class KoResource; class KisCustomGradientDialog : public KoDialog { Q_OBJECT public: KisCustomGradientDialog(KoAbstractGradientSP gradient, QWidget *parent, const char *name); private: QWidget * m_page; }; class KRITAUI_EXPORT KisGradientChooser : public QFrame { Q_OBJECT public: KisGradientChooser(QWidget *parent = 0, const char *name = 0); ~KisGradientChooser() override; /// Gets the currently selected resource /// @returns the selected resource, 0 is no resource is selected KoResourceSP currentResource(); void setCurrentResource(KoResourceSP resource); - void setCurrentItem(int row, int column); + void setCurrentItem(int row); Q_SIGNALS: /// Emitted when a resource was selected void resourceSelected(KoResourceSP resource); public Q_SLOTS: void slotUpdateIcons(); private Q_SLOTS: virtual void update(KoResourceSP resource); void addStopGradient(); void addSegmentedGradient(); void editGradient(); private: void addGradient(KoAbstractGradientSP gradient); private: QLabel *m_lbName; KisResourceItemChooser * m_itemChooser; QToolButton* m_addGradient; QPushButton* m_editGradient; }; #endif // KIS_GRADIENT_CHOOSER_H_ diff --git a/libs/ui/widgets/kis_pattern_chooser.cc b/libs/ui/widgets/kis_pattern_chooser.cc index 322236956b..6b3ae4189f 100644 --- a/libs/ui/widgets/kis_pattern_chooser.cc +++ b/libs/ui/widgets/kis_pattern_chooser.cc @@ -1,114 +1,114 @@ /* * Copyright (c) 2004 Adrian Page * Copyright (C) 2011 Srikanth Tiyyagura * * 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, Boston, MA 02110-1301, USA. */ #include "widgets/kis_pattern_chooser.h" #include #include #include #include #include #include #include #include #include #include "kis_signals_blocker.h" #include "kis_global.h" #include #include #include KisPatternChooser::KisPatternChooser(QWidget *parent) : QFrame(parent) { m_lblName = new KSqueezedTextLabel(this); m_lblName->setTextElideMode(Qt::ElideLeft); m_itemChooser = new KisResourceItemChooser(ResourceType::Patterns, true, this); m_itemChooser->setPreviewTiled(true); m_itemChooser->setPreviewOrientation(Qt::Horizontal); m_itemChooser->showTaggingBar(true); m_itemChooser->setSynced(true); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(update(KoResourceSP ))); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SIGNAL(resourceSelected(KoResourceSP ))); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); mainLayout->setMargin(0); mainLayout->addWidget(m_lblName); mainLayout->addWidget(m_itemChooser, 10); setLayout(mainLayout); } KisPatternChooser::~KisPatternChooser() { } KoResourceSP KisPatternChooser::currentResource() { if (!m_itemChooser->currentResource()) { KoResourceServer * rserver = KoResourceServerProvider::instance()->patternServer(); if (rserver->resourceCount() > 0) { KisSignalsBlocker blocker(m_itemChooser); m_itemChooser->setCurrentResource(rserver->firstResource()); } } return m_itemChooser->currentResource(); } void KisPatternChooser::setCurrentPattern(KoResourceSP resource) { m_itemChooser->setCurrentResource(resource); } -void KisPatternChooser::setCurrentItem(int row, int column) +void KisPatternChooser::setCurrentItem(int row) { - m_itemChooser->setCurrentItem(row, column); + m_itemChooser->setCurrentItem(row); if (currentResource()) { update(currentResource()); } } void KisPatternChooser::setPreviewOrientation(Qt::Orientation orientation) { m_itemChooser->setPreviewOrientation(orientation); } void KisPatternChooser::update(KoResourceSP resource) { m_lblName->setFixedWidth(m_itemChooser->width()); KoPatternSP pattern = resource.staticCast(); m_lblName->setText(QString("%1 (%2 x %3)").arg(i18n(pattern->name().toUtf8().data())).arg(pattern->width()).arg(pattern->height())); } void KisPatternChooser::setGrayscalePreview(bool grayscale) { m_itemChooser->setGrayscalePreview(grayscale); } diff --git a/libs/ui/widgets/kis_pattern_chooser.h b/libs/ui/widgets/kis_pattern_chooser.h index a201e075e5..9ffc7e5f2f 100644 --- a/libs/ui/widgets/kis_pattern_chooser.h +++ b/libs/ui/widgets/kis_pattern_chooser.h @@ -1,66 +1,66 @@ /* * Copyright (c) 2004 Adrian Page * * 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, Boston, MA 02110-1301, USA. */ #ifndef KIS_PATTERN_CHOOSER_H_ #define KIS_PATTERN_CHOOSER_H_ #include #include #include class KSqueezedTextLabel; class KisResourceItemChooser; class KRITAUI_EXPORT KisPatternChooser : public QFrame { Q_OBJECT public: KisPatternChooser(QWidget *parent = 0); ~KisPatternChooser() override; /// Gets the currently selected resource /// @returns the selected resource, 0 is no resource is selected KoResourceSP currentResource(); void setCurrentPattern(KoResourceSP resource); - void setCurrentItem(int row, int column); + void setCurrentItem(int row); void setGrayscalePreview(bool grayscale); /// determines whether the preview right or below the splitter void setPreviewOrientation(Qt::Orientation orientation); Q_SIGNALS: /// Emitted when a resource was selected void resourceSelected(KoResourceSP resource); void updateItemSize(); private Q_SLOTS: void update(KoResourceSP resource); private: KSqueezedTextLabel *m_lblName; KisResourceItemChooser *m_itemChooser; }; #endif // KIS_PATTERN_CHOOSER_H_ diff --git a/libs/ui/widgets/kis_preset_chooser.cpp b/libs/ui/widgets/kis_preset_chooser.cpp index 3d4b321bdf..5cf21c7c01 100644 --- a/libs/ui/widgets/kis_preset_chooser.cpp +++ b/libs/ui/widgets/kis_preset_chooser.cpp @@ -1,448 +1,452 @@ /* * Copyright (c) 2002 Patrick Julien * Copyright (c) 2009 Sven Langkamp * Copyright (C) 2011 Silvio Heinrich * Copyright (C) 2011 Srikanth Tiyyagura * Copyright (c) 2011 José Luis Vergara * * 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, Boston, MA 02110-1301, USA. */ #include "kis_preset_chooser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include "KisResourceServerProvider.h" #include "kis_global.h" #include "kis_slider_spin_box.h" #include "kis_config_notifier.h" #include /// The resource item delegate for rendering the resource preview class KisPresetDelegate : public QAbstractItemDelegate { public: KisPresetDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent), m_showText(false), m_useDirtyPresets(false) {} ~KisPresetDelegate() override {} /// reimplemented void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const override { return option.decorationSize; } void setShowText(bool showText) { m_showText = showText; } void setUseDirtyPresets(bool value) { m_useDirtyPresets = value; } private: bool m_showText; bool m_useDirtyPresets; }; void KisPresetDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { painter->save(); painter->setRenderHint(QPainter::SmoothPixmapTransform, true); if (!index.isValid()) { qDebug() << "KisPresetDelegate::paint: index is invalid"; painter->restore(); return; } bool dirty = index.data(Qt::UserRole + KisResourceModel::Dirty).toBool(); QImage preview = index.data(Qt::DecorationRole).value(); + if (preview.isNull()) { + preview = index.data(Qt::UserRole + KisResourceModel::Image).value(); + } if (preview.isNull()) { qDebug() << "KisPresetDelegate::paint: Preview is null"; painter->restore(); return; } QMap metaData = index.data(Qt::UserRole + KisResourceModel::MetaData).value>(); QRect paintRect = option.rect.adjusted(1, 1, -1, -1); if (!m_showText) { painter->drawImage(paintRect.x(), paintRect.y(), preview.scaled(paintRect.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } else { QSize pixSize(paintRect.height(), paintRect.height()); painter->drawImage(paintRect.x(), paintRect.y(), preview.scaled(pixSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); // Put an asterisk after the preset if it is dirty. This will help in case the pixmap icon is too small QString dirtyPresetIndicator = QString(""); if (m_useDirtyPresets && dirty) { dirtyPresetIndicator = QString("*"); } // qreal brushSize = metaData["paintopSize"].toReal(); // QString brushSizeText; // // Disable displayed decimal precision beyond a certain brush size // if (brushSize < 100) { // brushSizeText = QString::number(brushSize, 'g', 3); // } else { // brushSizeText = QString::number(brushSize, 'f', 0); // } // painter->drawText(pixSize.width() + 10, option.rect.y() + option.rect.height() - 10, brushSizeText); // brush size QString presetDisplayName = index.data(Qt::UserRole + KisResourceModel::Name).toString().replace("_", " "); // don't need underscores that might be part of the file name painter->drawText(pixSize.width() + 40, option.rect.y() + option.rect.height() - 10, presetDisplayName.append(dirtyPresetIndicator)); } if (m_useDirtyPresets && dirty) { const QIcon icon = KisIconUtils::loadIcon(koIconName("dirty-preset")); QPixmap pixmap = icon.pixmap(QSize(15,15)); painter->drawPixmap(paintRect.x() + 3, paintRect.y() + 3, pixmap); } // if (!preset->settings() || !preset->settings()->isValid()) { // const QIcon icon = KisIconUtils::loadIcon("broken-preset"); // icon.paint(painter, QRect(paintRect.x() + paintRect.height() - 25, paintRect.y() + paintRect.height() - 25, 25, 25)); // } if (option.state & QStyle::State_Selected) { painter->setCompositionMode(QPainter::CompositionMode_HardLight); painter->setOpacity(1.0); painter->fillRect(option.rect, option.palette.highlight()); // highlight is not strong enough to pick out preset. draw border around it. painter->setCompositionMode(QPainter::CompositionMode_SourceOver); painter->setPen(QPen(option.palette.highlight(), 4, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); QRect selectedBorder = option.rect.adjusted(2 , 2, -2, -2); // constrict the rectangle so it doesn't bleed into other presets painter->drawRect(selectedBorder); } painter->restore(); } class KisPresetChooser::PaintOpFilterModel : public QSortFilterProxyModel, public KisAbstractResourceModel { Q_OBJECT public: PaintOpFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) { } ~PaintOpFilterModel() override { } void setPaintOpId(const QString &id) { m_id = id; } QString currentPaintOpId() const { return m_id; } // KisAbstractResourceModel interface public: KoResourceSP resourceForIndex(QModelIndex index) const override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->resourceForIndex(mapToSource(index)); } return 0; } QModelIndex indexFromResource(KoResourceSP resource) const override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return mapFromSource(source->indexFromResource(resource)); } return QModelIndex(); } bool removeResource(const QModelIndex &index) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->removeResource(mapToSource(index)); } return false; } bool importResourceFile(const QString &filename) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->importResourceFile(filename); } return false; } bool addResource(KoResourceSP resource, bool save) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->addResource(resource, save); } return false; } bool updateResource(KoResourceSP resource) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->updateResource(resource); } return false; } bool removeResource(KoResourceSP resource) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->removeResource(resource); } return false; } bool setResourceMetaData(KoResourceSP resource, QMap metadata) override { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->setResourceMetaData(resource, metadata); } return false; } // QSortFilterProxyModel interface protected: QVariant data(const QModelIndex &index, int role) const override { return sourceModel()->data(mapToSource(index), role); } bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override { if (m_id.isEmpty()) return true; QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); QMap metadata = sourceModel()->data(idx, Qt::UserRole + KisResourceModel::MetaData).toMap(); if (metadata.contains("paintopid")) { return (metadata["paintopid"].toString() == m_id); } return false; } bool filterAcceptsColumn(int /*source_column*/, const QModelIndex &/*source_parent*/) const override { return true; } bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override { QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisResourceModel::Name).toString(); QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisResourceModel::Name).toString(); return nameLeft < nameRight; } private: QString m_id; }; KisPresetChooser::KisPresetChooser(QWidget *parent, const char *name) : QWidget(parent) { setObjectName(name); QVBoxLayout * layout = new QVBoxLayout(this); layout->setMargin(0); m_paintOpFilterModel = new PaintOpFilterModel(); m_chooser = new KisResourceItemChooser(ResourceType::PaintOpPresets, false, this, m_paintOpFilterModel); m_chooser->setObjectName("ResourceChooser"); - m_chooser->setColumnCount(10); m_chooser->setRowHeight(50); m_delegate = new KisPresetDelegate(this); m_chooser->setItemDelegate(m_delegate); m_chooser->setSynced(true); layout->addWidget(m_chooser); { QScroller *scroller = KisKineticScroller::createPreconfiguredScroller(this->itemChooser()->itemView()); if (scroller) { connect(scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChanged(QScroller::State))); } } connect(m_chooser, SIGNAL(resourceSelected(KoResourceSP )), this, SIGNAL(resourceSelected(KoResourceSP ))); connect(m_chooser, SIGNAL(resourceClicked(KoResourceSP )), this, SIGNAL(resourceClicked(KoResourceSP ))); m_mode = THUMBNAIL; connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(notifyConfigChanged())); notifyConfigChanged(); } KisPresetChooser::~KisPresetChooser() { } void KisPresetChooser::showButtons(bool show) { m_chooser->showButtons(show); } void KisPresetChooser::setViewMode(KisPresetChooser::ViewMode mode) { m_mode = mode; updateViewSettings(); } void KisPresetChooser::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); updateViewSettings(); } void KisPresetChooser::notifyConfigChanged() { KisConfig cfg(true); m_delegate->setUseDirtyPresets(cfg.useDirtyPresets()); setIconSize(cfg.presetIconSize()); updateViewSettings(); } void KisPresetChooser::updateViewSettings() { if (m_mode == THUMBNAIL) { m_chooser->setSynced(true); m_delegate->setShowText(false); + m_chooser->itemView()->setViewMode(QListView::IconMode); + m_chooser->itemView()->setFlow(QListView::LeftToRight); } else if (m_mode == DETAIL) { m_chooser->setSynced(false); - m_chooser->setColumnCount(1); + m_chooser->itemView()->setViewMode(QListView::ListMode); + m_chooser->itemView()->setFlow(QListView::TopToBottom); m_chooser->setColumnWidth(m_chooser->width()); KisResourceItemChooserSync* chooserSync = KisResourceItemChooserSync::instance(); m_chooser->setRowHeight(chooserSync->baseLength()); m_delegate->setShowText(true); } else if (m_mode == STRIP) { m_chooser->setSynced(false); - m_chooser->setRowCount(1); - m_chooser->itemView()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_chooser->itemView()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_chooser->itemView()->setViewMode(QListView::ListMode); + m_chooser->itemView()->setFlow(QListView::LeftToRight); // An offset of 7 keeps the cell exactly square, TODO: use constants, not hardcoded numbers m_chooser->setColumnWidth(m_chooser->viewSize().height() - 7); m_delegate->setShowText(false); } } void KisPresetChooser::setCurrentResource(KoResourceSP resource) { m_chooser->setCurrentResource(resource); } KoResourceSP KisPresetChooser::currentResource() const { return m_chooser->currentResource(); } void KisPresetChooser::showTaggingBar(bool show) { m_chooser->showTaggingBar(show); } KisResourceItemChooser *KisPresetChooser::itemChooser() { return m_chooser; } void KisPresetChooser::setPresetFilter(const QString& paintOpId) { if (m_paintOpFilterModel && m_paintOpFilterModel->currentPaintOpId() != paintOpId) { m_paintOpFilterModel->setPaintOpId(paintOpId); updateViewSettings(); } } void KisPresetChooser::setIconSize(int newSize) { KisResourceItemChooserSync* chooserSync = KisResourceItemChooserSync::instance(); chooserSync->setBaseLength(newSize); updateViewSettings(); } int KisPresetChooser::iconSize() { KisResourceItemChooserSync* chooserSync = KisResourceItemChooserSync::instance(); return chooserSync->baseLength(); } void KisPresetChooser::saveIconSize() { // save icon size KisConfig cfg(false); cfg.setPresetIconSize(iconSize()); } void KisPresetChooser::slotScrollerStateChanged(QScroller::State state) { KisKineticScroller::updateCursor(this, state); } #include "kis_preset_chooser.moc" diff --git a/libs/ui/widgets/kis_preset_selector_strip.cpp b/libs/ui/widgets/kis_preset_selector_strip.cpp index 2462006438..c43b560949 100644 --- a/libs/ui/widgets/kis_preset_selector_strip.cpp +++ b/libs/ui/widgets/kis_preset_selector_strip.cpp @@ -1,108 +1,108 @@ /* * Copyright (c) 2011 José Luis Vergara * * 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, Boston, MA 02110-1301, USA. */ #include "kis_preset_selector_strip.h" -#include +#include #include #include #include "kis_config.h" #include #include #include KisPresetSelectorStrip::KisPresetSelectorStrip(QWidget* parent) : QWidget(parent) { setupUi(this); smallPresetChooser->showButtons(false); //loading and saving buttons. don't need these with the brush editor smallPresetChooser->setViewMode((KisPresetChooser::ViewMode)KisConfig(true).presetChooserViewMode()); smallPresetChooser->showTaggingBar(true); m_resourceItemView = smallPresetChooser->itemChooser()->itemView(); /* This is an heuristic to fill smallPresetChooser with only the presets * for the paintop that comes selected by default: Pixel Brush. */ const QString PIXEL_BRUSH_ID = "paintbrush"; m_currentPaintopID = PIXEL_BRUSH_ID; // hide the left and right arrows that are used by the "strip" view by default rightScrollBtn->hide(); leftScrollBtn->hide(); } KisPresetSelectorStrip::~KisPresetSelectorStrip() { } void KisPresetSelectorStrip::setPresetFilter(const QString& paintOpId) { smallPresetChooser->setPresetFilter(paintOpId); if (m_currentPaintopID != paintOpId) { m_resourceItemView->scrollTo(m_resourceItemView->model()->index(0, 0)); m_currentPaintopID = paintOpId; } } void KisPresetSelectorStrip::on_leftScrollBtn_pressed() { // Deciding how far beyond the left margin (10 pixels) was an arbitrary decision QPoint beyondLeftMargin(-10, 0); m_resourceItemView->scrollTo(m_resourceItemView->indexAt(beyondLeftMargin), QAbstractItemView::EnsureVisible); } void KisPresetSelectorStrip::on_rightScrollBtn_pressed() { // Deciding how far beyond the right margin to put the point (10 pixels) was an arbitrary decision QPoint beyondRightMargin(10 + m_resourceItemView->viewport()->width(), 0); m_resourceItemView->scrollTo(m_resourceItemView->indexAt(beyondRightMargin), QAbstractItemView::EnsureVisible); } void KisPresetSelectorStrip::slotThumbnailMode() { smallPresetChooser->setViewMode(KisPresetChooser::THUMBNAIL); // set to details view by default to see names m_resourceItemView = smallPresetChooser->itemChooser()->itemView(); } void KisPresetSelectorStrip::slotDetailMode() { smallPresetChooser->setViewMode(KisPresetChooser::DETAIL); // set to details view by default to see names m_resourceItemView = smallPresetChooser->itemChooser()->itemView(); } int KisPresetSelectorStrip::iconSize() { return smallPresetChooser->iconSize(); } void KisPresetSelectorStrip::slotSetIconSize(int size) { smallPresetChooser->setIconSize(size); } void KisPresetSelectorStrip::slotSaveIconSize() { smallPresetChooser->saveIconSize(); } diff --git a/libs/ui/widgets/kis_preset_selector_strip.h b/libs/ui/widgets/kis_preset_selector_strip.h index e29fa851c6..5869a7123a 100644 --- a/libs/ui/widgets/kis_preset_selector_strip.h +++ b/libs/ui/widgets/kis_preset_selector_strip.h @@ -1,84 +1,84 @@ /* * Copyright (c) 2011 José Luis Vergara * * 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, Boston, MA 02110-1301, USA. */ #ifndef KIS_PRESET_SELECTOR_STRIP_H #define KIS_PRESET_SELECTOR_STRIP_H #include #include "ui_wdgpresetselectorstrip.h" -class KisResourceItemView; +class KisResourceItemListView; /** * * KisPresetSelectorStrip is a composite widget around KisPresetChooser. It provides * a strip of icons with two scroll buttons at the sides and a small delete button * that appears when a user selects a preset icon. * * KisPresetSelectorStrip makes it possible to quickly select and modify presets. * * Note that KisPresetSelectorStrip uses the QObject tree to access properties of the contained * classes, and uses heuristics to approximate pixel offsets, times, and other * properties that cannot be accessed through the QObject tree. * */ class KisPresetSelectorStrip : public QWidget, public Ui::WdgPresetSelectorStrip { Q_OBJECT public: KisPresetSelectorStrip(QWidget *parent); ~KisPresetSelectorStrip() override; void setPresetFilter(const QString& paintOpId); int iconSize(); void setIconSize(int size); public Q_SLOTS: /// saving the icon base size. This affects all preset selectors /// outside UI elements adjusting icon size void slotSetIconSize(int size); /// saves the icon size to the config file /// when UI element is released, it is ok to save icon size to config void slotSaveIconSize(); private Q_SLOTS: /// Scrolls the strip's item view to the left void on_leftScrollBtn_pressed(); /// Scrolls the strip's item view to the right void on_rightScrollBtn_pressed(); /// Changes the preset list view type void slotThumbnailMode(); void slotDetailMode(); private: /** * This is a workaround to access members of KisPresetChooser using the QObject tree * instead of class methods */ - KisResourceItemView* m_resourceItemView; + KisResourceItemListView* m_resourceItemView; QString m_currentPaintopID; }; #endif // KIS_PRESET_SELECTOR_STRIP_H diff --git a/libs/ui/widgets/kis_workspace_chooser.cpp b/libs/ui/widgets/kis_workspace_chooser.cpp index 6c4e60bf96..7ac7fe2bec 100644 --- a/libs/ui/widgets/kis_workspace_chooser.cpp +++ b/libs/ui/widgets/kis_workspace_chooser.cpp @@ -1,229 +1,230 @@ /* This file is part of the KDE project * Copyright (C) 2011 Sven Langkamp * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_workspace_chooser.h" #include #include #include #include #include #include #include #include +#include #include #include #include -#include +#include #include #include #include #include "kis_workspace_resource.h" #include "KisViewManager.h" #include "kis_canvas_resource_provider.h" #include "KisMainWindow.h" #include "KisPart.h" #include "KisWindowLayoutManager.h" #include "dialogs/KisNewWindowLayoutDialog.h" #include "kis_config.h" #include class KisWorkspaceDelegate : public QAbstractItemDelegate { public: KisWorkspaceDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent) {} ~KisWorkspaceDelegate() override {} /// reimplemented void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const override { return option.decorationSize; } }; void KisWorkspaceDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { if (!index.isValid()) return; QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Active : QPalette::Disabled; QPalette::ColorRole cr = (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::Text; painter->setPen(option.palette.color(cg, cr)); if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); } else { painter->fillRect(option.rect, option.palette.base()); } QString name = index.data(Qt::UserRole + KisResourceModel::Name).toString(); painter->drawText(option.rect.x() + 5, option.rect.y() + painter->fontMetrics().ascent() + 5, name); } KisWorkspaceChooser::KisWorkspaceChooser(KisViewManager * view, QWidget* parent): QWidget(parent), m_view(view) { m_layout = new QGridLayout(this); m_workspaceWidgets = createChooserWidgets(ResourceType::Workspaces, i18n("Workspaces")); m_windowLayoutWidgets = createChooserWidgets(ResourceType::WindowLayouts, i18n("Window layouts")); connect(m_workspaceWidgets.itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(workspaceSelected(KoResourceSP ))); connect(m_workspaceWidgets.saveButton, SIGNAL(clicked(bool)), this, SLOT(slotSaveWorkspace())); connect(m_workspaceWidgets.nameEdit, SIGNAL(textEdited(const QString&)), this, SLOT(slotUpdateWorkspaceSaveButton())); connect(m_windowLayoutWidgets.itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(windowLayoutSelected(KoResourceSP ))); connect(m_windowLayoutWidgets.saveButton, SIGNAL(clicked(bool)), this, SLOT(slotSaveWindowLayout())); connect(m_windowLayoutWidgets.nameEdit, SIGNAL(textEdited(const QString&)), this, SLOT(slotUpdateWindowLayoutSaveButton())); } KisWorkspaceChooser::ChooserWidgets KisWorkspaceChooser::createChooserWidgets(const QString &resourceType, const QString &title) { ChooserWidgets widgets; QLabel *titleLabel = new QLabel(this); QFont titleFont; titleFont.setBold(true); titleLabel->setFont(titleFont); titleLabel->setText(title); m_workspaceSaveLocation = KisResourceServerProvider::instance()->workspaceServer()->saveLocation(); m_windowLayoutSaveLocation = KisResourceServerProvider::instance()->windowLayoutServer()->saveLocation(); widgets.itemChooser = new KisResourceItemChooser(resourceType, false, this); widgets.itemChooser->setItemDelegate(new KisWorkspaceDelegate(this)); widgets.itemChooser->setFixedSize(250, 250); widgets.itemChooser->setRowHeight(30); - widgets.itemChooser->setColumnCount(1); + widgets.itemChooser->itemView()->setViewMode(QListView::ListMode); widgets.itemChooser->showTaggingBar(false); widgets.saveButton = new QPushButton(i18n("Save")); widgets.nameEdit = new QLineEdit(this); widgets.nameEdit->setPlaceholderText(i18n("Insert name")); widgets.nameEdit->setClearButtonEnabled(true); int firstRow = m_layout->rowCount(); m_layout->addWidget(titleLabel, firstRow, 0, 1, 2); m_layout->addWidget(widgets.itemChooser, firstRow + 1, 0, 1, 2); m_layout->addWidget(widgets.nameEdit, firstRow + 2, 0, 1, 1); m_layout->addWidget(widgets.saveButton, firstRow + 2, 1, 1, 1); return widgets; } KisWorkspaceChooser::~KisWorkspaceChooser() { } void KisWorkspaceChooser::slotSaveWorkspace() { if (!m_view->qtMainWindow()) { return; } KisWorkspaceResourceSP workspace(new KisWorkspaceResource(QString())); workspace->setDockerState(m_view->qtMainWindow()->saveState()); m_view->canvasResourceProvider()->notifySavingWorkspace(workspace); workspace->setValid(true); QString name = m_workspaceWidgets.nameEdit->text(); workspace->setName(name); workspace->setFilename(name.split(" ").join("_")+workspace->defaultFileExtension()); KisResourceModelProvider::resourceModel(ResourceType::Workspaces)->addResource(workspace); } void KisWorkspaceChooser::slotUpdateWorkspaceSaveButton() { if (QFileInfo(m_workspaceSaveLocation + m_workspaceWidgets.nameEdit->text().split(" ").join("_") + ".kws").exists()) { m_workspaceWidgets.saveButton->setIcon(KisIconUtils::loadIcon("warning")); m_workspaceWidgets.saveButton->setToolTip(i18n("File name already in use. Saving will overwrite the original Workspace.")); //m_workspaceWidgets.saveButton->setText(i18n("Overwrite")); } else { m_workspaceWidgets.saveButton->setIcon(QIcon()); m_workspaceWidgets.saveButton->setToolTip(i18n("Save current workspace.")); //m_workspaceWidgets.saveButton->setText(i18n("Save")); } } void KisWorkspaceChooser::workspaceSelected(KoResourceSP resource) { if (!m_view->qtMainWindow()) { return; } KisConfig cfg(false); cfg.writeEntry("CurrentWorkspace", resource->name()); KisWorkspaceResourceSP workspace = resource.staticCast(); KisMainWindow *mainWindow = qobject_cast(m_view->qtMainWindow()); mainWindow->restoreWorkspace(workspace->resourceId()); } void KisWorkspaceChooser::slotSaveWindowLayout() { KisMainWindow *thisWindow = qobject_cast(m_view->qtMainWindow()); if (!thisWindow) return; KisNewWindowLayoutDialog dlg; dlg.setName(m_windowLayoutWidgets.nameEdit->text()); dlg.exec(); if (dlg.result() != QDialog::Accepted) return; QString name = dlg.name(); bool showImageInAllWindows = dlg.showImageInAllWindows(); bool primaryWorkspaceFollowsFocus = dlg.primaryWorkspaceFollowsFocus(); KisWindowLayoutResourceSP layout = KisWindowLayoutResource::fromCurrentWindows(name, KisPart::instance()->mainWindows(), showImageInAllWindows, primaryWorkspaceFollowsFocus, thisWindow); layout->setValid(true); KisWindowLayoutManager::instance()->setShowImageInAllWindowsEnabled(showImageInAllWindows); KisWindowLayoutManager::instance()->setPrimaryWorkspaceFollowsFocus(primaryWorkspaceFollowsFocus, thisWindow->id()); if (name.isEmpty()) { name = i18n("Window Layout"); } layout->setName(name); layout->setFilename(name.split(" ").join("_") + layout->defaultFileExtension()); KisResourceModelProvider::resourceModel(ResourceType::WindowLayouts)->addResource(layout); } void KisWorkspaceChooser::slotUpdateWindowLayoutSaveButton() { if (QFileInfo(m_windowLayoutSaveLocation + m_windowLayoutWidgets.nameEdit->text().split(" ").join("_") + ".kwl").exists()) { m_windowLayoutWidgets.saveButton->setIcon(KisIconUtils::loadIcon("warning")); m_workspaceWidgets.saveButton->setToolTip(i18n("File name already in use. Saving will overwrite the original window layout.")); } else { m_windowLayoutWidgets.saveButton->setIcon(QIcon()); m_workspaceWidgets.saveButton->setToolTip(i18n("Save current window layout.")); } } void KisWorkspaceChooser::windowLayoutSelected(KoResourceSP resource) { KisWindowLayoutResourceSP layout = resource.staticCast(); layout->applyLayout(); } diff --git a/libs/widgets/KisPaletteListWidget.cpp b/libs/widgets/KisPaletteListWidget.cpp index 09be08a030..ed0bd1a409 100644 --- a/libs/widgets/KisPaletteListWidget.cpp +++ b/libs/widgets/KisPaletteListWidget.cpp @@ -1,193 +1,194 @@ /* * Copyright (c) 2013 Sven Langkamp * Copyright (c) 2018 Michael Zhou * * 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, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include "KisPaletteListWidget.h" #include "KisPaletteListWidget_p.h" KisPaletteListWidget::KisPaletteListWidget(QWidget *parent) : QWidget(parent) , m_ui(new Ui_WdgPaletteListWidget) , m_d(new KisPaletteListWidgetPrivate(this)) { m_d->allowModification = false; m_d->actAdd.reset(new QAction(KisIconUtils::loadIcon("list-add"), i18n("Add a new palette"))); m_d->actRemove.reset(new QAction(KisIconUtils::loadIcon("list-remove"), i18n("Remove current palette"))); m_d->actImport.reset(new QAction(KisIconUtils::loadIcon("document-import"), i18n("Import a new palette from file"))); m_d->actExport.reset(new QAction(KisIconUtils::loadIcon("document-export"), i18n("Export current palette to file"))); m_ui->setupUi(this); m_ui->bnAdd->setDefaultAction(m_d->actAdd.data()); m_ui->bnRemove->setDefaultAction(m_d->actRemove.data()); m_ui->bnImport->setDefaultAction(m_d->actImport.data()); m_ui->bnExport->setDefaultAction(m_d->actExport.data()); m_ui->bnAdd->setEnabled(false); m_ui->bnRemove->setEnabled(false); m_ui->bnImport->setEnabled(false); m_ui->bnExport->setEnabled(false); connect(m_d->actAdd.data(), SIGNAL(triggered()), SLOT(slotAdd())); connect(m_d->actRemove.data(), SIGNAL(triggered()), SLOT(slotRemove())); connect(m_d->actImport.data(), SIGNAL(triggered()), SLOT(slotImport())); connect(m_d->actExport.data(), SIGNAL(triggered()), SLOT(slotExport())); m_d->itemChooser->setItemDelegate(m_d->delegate.data()); m_d->itemChooser->setRowHeight(40); - m_d->itemChooser->setColumnCount(1); + m_d->itemChooser->itemView()->setViewMode(QListView::ListMode); m_d->itemChooser->showButtons(false); m_d->itemChooser->showTaggingBar(true); m_ui->viewPalette->setLayout(new QHBoxLayout(m_ui->viewPalette)); m_ui->viewPalette->layout()->addWidget(m_d->itemChooser.data()); connect(m_d->itemChooser.data(), SIGNAL(resourceSelected(KoResourceSP )), SLOT(slotPaletteResourceSelected(KoResourceSP ))); } KisPaletteListWidget::~KisPaletteListWidget() { } void KisPaletteListWidget::slotPaletteResourceSelected(KoResourceSP r) { KoColorSetSP g = r.staticCast(); emit sigPaletteSelected(g); if (!m_d->allowModification) { return; } if (g->isEditable()) { m_ui->bnRemove->setEnabled(true); } else { m_ui->bnRemove->setEnabled(false); } } void KisPaletteListWidget::slotAdd() { if (!m_d->allowModification) { return; } emit sigAddPalette(); - m_d->itemChooser->setCurrentItem(m_d->itemChooser->rowCount() - 1, 0); + m_d->itemChooser->setCurrentItem(m_d->itemChooser->rowCount() - 1); } void KisPaletteListWidget::slotRemove() { if (!m_d->allowModification) { return; } if (m_d->itemChooser->currentResource()) { KoColorSetSP cs = m_d->itemChooser->currentResource().staticCast(); emit sigRemovePalette(cs); } - m_d->itemChooser->setCurrentItem(0, 0); + m_d->itemChooser->setCurrentItem(0); } void KisPaletteListWidget::slotImport() { if (!m_d->allowModification) { return; } emit sigImportPalette(); - m_d->itemChooser->setCurrentItem(m_d->itemChooser->rowCount() - 1, 0); + m_d->itemChooser->setCurrentItem(m_d->itemChooser->rowCount() - 1); } void KisPaletteListWidget::slotExport() { if (!m_d->allowModification) { return; } emit sigExportPalette(m_d->itemChooser->currentResource().staticCast()); } void KisPaletteListWidget::setAllowModification(bool allowModification) { m_d->allowModification = allowModification; m_ui->bnAdd->setEnabled(allowModification); m_ui->bnImport->setEnabled(allowModification); m_ui->bnExport->setEnabled(allowModification); KoColorSetSP cs = m_d->itemChooser->currentResource().staticCast(); m_ui->bnRemove->setEnabled(allowModification && cs && cs->isEditable()); } /************************* KisPaletteListWidgetPrivate **********************/ KisPaletteListWidgetPrivate::KisPaletteListWidgetPrivate(KisPaletteListWidget *a_c) : c(a_c) , itemChooser(new KisResourceItemChooser(ResourceType::Palettes, false, a_c)) , delegate(new Delegate(a_c)) { } KisPaletteListWidgetPrivate::~KisPaletteListWidgetPrivate() { } /******************* KisPaletteListWidgetPrivate::Delegate ******************/ KisPaletteListWidgetPrivate::Delegate::Delegate(QObject *parent) : QAbstractItemDelegate(parent) { } KisPaletteListWidgetPrivate::Delegate::~Delegate() { } void KisPaletteListWidgetPrivate::Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); if (!index.isValid()) return; QImage preview = index.data(Qt::DecorationRole).value(); QString name = index.data(Qt::UserRole + KisResourceModel::Name).toString(); QRect previewRect(option.rect.x() + 2, option.rect.y() + 2, option.rect.height() - 4, option.rect.height() - 4); painter->drawImage(previewRect, preview); if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); painter->drawImage(previewRect, preview); painter->setPen(option.palette.highlightedText().color()); } else { painter->setBrush(option.palette.text().color()); } painter->drawText(option.rect.x() + previewRect.width() + 10, option.rect.y() + painter->fontMetrics().ascent() + 5, name); painter->restore(); } inline QSize KisPaletteListWidgetPrivate::Delegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const { return option.decorationSize; } diff --git a/libs/widgets/KoResourcePopupAction.cpp b/libs/widgets/KoResourcePopupAction.cpp index e02658e134..bd684989dd 100644 --- a/libs/widgets/KoResourcePopupAction.cpp +++ b/libs/widgets/KoResourcePopupAction.cpp @@ -1,202 +1,205 @@ /* * Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) * Copyright (C) 2012 Jean-Nicolas Artaud * Copyright (C) 2019 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoResourcePopupAction.h" -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KoResourcePopupAction::Private { public: QMenu *menu = 0; KisResourceModel *model = 0; - KisResourceItemView *resourceList = 0; + KisResourceItemListView *resourceList = 0; QSharedPointer background; KoImageCollection *imageCollection = 0; KoCheckerBoardPainter checkerPainter {4}; }; KoResourcePopupAction::KoResourcePopupAction(const QString &resourceType, QObject *parent) : QAction(parent) , d(new Private()) { d->menu = new QMenu(); QWidget *widget = new QWidget(); QWidgetAction *wdgAction = new QWidgetAction(this); - d->resourceList = new KisResourceItemView(widget); + d->resourceList = new KisResourceItemListView(widget); d->model = KisResourceModelProvider::resourceModel(resourceType); d->resourceList->setModel(d->model); d->resourceList->setItemDelegate(new KisResourceItemDelegate(widget)); d->resourceList->setCurrentIndex(d->model->index(0, 0)); + if (resourceType==ResourceType::Gradients) { + d->resourceList->setViewMode(QListView::ListMode); + } indexChanged(d->resourceList->currentIndex()); QHBoxLayout *layout = new QHBoxLayout(widget); layout->addWidget(d->resourceList); widget->setLayout(layout); wdgAction->setDefaultWidget(widget); d->menu->addAction(wdgAction); setMenu(d->menu); new QHBoxLayout(d->menu); d->menu->layout()->addWidget(widget); d->menu->layout()->setMargin(0); connect(d->resourceList, SIGNAL(clicked(QModelIndex)), this, SLOT(indexChanged(QModelIndex))); updateIcon(); } KoResourcePopupAction::~KoResourcePopupAction() { /* Removing the actions here make them be deleted together with their default widget. * This happens only if the actions are QWidgetAction, and we know they are since * the only ones added are in KoResourcePopupAction constructor. */ int i = 0; while(d->menu->actions().size() > 0) { d->menu->removeAction(d->menu->actions()[i]); ++i; } delete d->menu; delete d->imageCollection; delete d; } QSharedPointer KoResourcePopupAction::currentBackground() const { return d->background; } void KoResourcePopupAction::setCurrentBackground(QSharedPointer background) { d->background = background; updateIcon(); } void KoResourcePopupAction::setCurrentResource(KoResourceSP resource) { QModelIndex index = d->model->indexFromResource(resource); if (index.isValid()) { d->resourceList->setCurrentIndex(index); indexChanged(index); } } KoResourceSP KoResourcePopupAction::currentResource() const { QModelIndex index = d->resourceList->currentIndex(); if (!index.isValid()) return 0; KoResourceSP resource = d->model->resourceForIndex(index); return resource; } void KoResourcePopupAction::indexChanged(const QModelIndex &modelIndex) { if (! modelIndex.isValid()) { return; } d->menu->hide(); KoResourceSP resource = d->model->resourceForIndex(modelIndex); if (resource) { KoAbstractGradientSP gradient = resource.dynamicCast(); KoPatternSP pattern = resource.dynamicCast(); if (gradient) { QGradient *qg = gradient->toQGradient(); qg->setCoordinateMode(QGradient::ObjectBoundingMode); d->background = QSharedPointer(new KoGradientBackground(qg)); } else if (pattern) { KoImageCollection *collection = new KoImageCollection(); d->background = QSharedPointer(new KoPatternBackground(collection)); qSharedPointerDynamicCast(d->background)->setPattern(pattern->pattern()); } emit resourceSelected(d->background); updateIcon(); } } void KoResourcePopupAction::updateIcon() { QSize iconSize; QToolButton *toolButton = dynamic_cast(parentWidget()); if (toolButton) { iconSize = QSize(toolButton->iconSize()); } else { iconSize = QSize(16, 16); } // This must be a QImage, as drawing to a QPixmap outside the // UI thread will cause sporadic crashes. QImage pm = QImage(iconSize, QImage::Format_ARGB32_Premultiplied); pm.fill(Qt::transparent); QPainter p(&pm); QSharedPointer gradientBackground = qSharedPointerDynamicCast(d->background); QSharedPointer patternBackground = qSharedPointerDynamicCast(d->background); if (gradientBackground) { QRect innerRect(0, 0, iconSize.width(), iconSize.height()); QLinearGradient paintGradient; paintGradient.setStops(gradientBackground->gradient()->stops()); paintGradient.setStart(innerRect.topLeft()); paintGradient.setFinalStop(innerRect.topRight()); d->checkerPainter.paint(p, innerRect); p.fillRect(innerRect, QBrush(paintGradient)); } else if (patternBackground) { d->checkerPainter.paint(p, QRect(QPoint(),iconSize)); p.fillRect(0, 0, iconSize.width(), iconSize.height(), patternBackground->pattern()); } p.end(); setIcon(QIcon(QPixmap::fromImage(pm))); } diff --git a/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp b/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp index 6da2261d77..cec68fae80 100644 --- a/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp +++ b/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp @@ -1,248 +1,248 @@ /* * Copyright (c) 2018 Anna Medonosova * * 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, Boston, MA 02110-1301, USA. */ #include "KisGamutMaskChooser.h" #include #include #include #include #include #include #include #include #include #include +#include #include #include /// The resource item delegate for rendering the resource preview class KisGamutMaskDelegate: public QAbstractItemDelegate { public: KisGamutMaskDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent) , m_mode(KisGamutMaskChooser::ViewMode::THUMBNAIL) {} ~KisGamutMaskDelegate() override {} /// reimplemented void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const override { return option.decorationSize; } void setViewMode(KisGamutMaskChooser::ViewMode mode) { m_mode = mode; } private: KisGamutMaskChooser::ViewMode m_mode; }; void KisGamutMaskDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { painter->save(); painter->setRenderHint(QPainter::SmoothPixmapTransform, true); if (!index.isValid()) return; KoResourceSP resource = KoResourceSP(static_cast(index.internalPointer())); KoGamutMaskSP mask = resource.staticCast(); if (!mask) { return; } QImage preview = mask->image(); if(preview.isNull()) { return; } QRect paintRect = option.rect.adjusted(1, 1, -1, -1); if (m_mode == KisGamutMaskChooser::ViewMode::THUMBNAIL) { painter->drawImage(paintRect.x(), paintRect.y(), preview.scaled(paintRect.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); if (option.state & QStyle::State_Selected) { painter->setCompositionMode(QPainter::CompositionMode_Overlay); painter->setOpacity(0.5); painter->fillRect(paintRect, Qt::white); painter->setCompositionMode(QPainter::CompositionMode_SourceOver); painter->setOpacity(1.0); painter->setPen(QPen(option.palette.highlight(), 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); QRect selectedBorder = option.rect.adjusted(1, 1, -1, -1); painter->drawRect(selectedBorder); } } else { QSize previewSize(paintRect.height(), paintRect.height()); painter->drawImage(paintRect.x(), paintRect.y(), preview.scaled(previewSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); int leftMargin = 8; int rightMargin = 7; int vertMargin = 4; int descOffset = 7; QFont font = option.font; font.setBold(true); painter->setFont(font); QRectF titleRect(QPointF(previewSize.width() + leftMargin, paintRect.y() + vertMargin), QPointF(paintRect.width() - rightMargin, paintRect.y() + descOffset + painter->fontMetrics().lineSpacing())); painter->drawText(titleRect, Qt::AlignLeft, painter->fontMetrics().elidedText( mask->title(), Qt::ElideRight, titleRect.width() ) ); if (!mask->description().isEmpty() && !mask->description().isNull()) { font.setPointSize(font.pointSize()-1); font.setBold(false); font.setStyle(QFont::StyleItalic); painter->setFont(font); QRectF descRect(QPointF(previewSize.width() + leftMargin, paintRect.y() + descOffset + painter->fontMetrics().lineSpacing()), QPointF(paintRect.right() - rightMargin, paintRect.bottom() - vertMargin)); int numLines = floor(((float)descRect.height() / (float)painter->fontMetrics().lineSpacing())); if (numLines > 0) { int elideWidth = 0; QTextLayout textLayout(mask->description()); textLayout.beginLayout(); for (int i = 0; i < numLines; i++) { QTextLine line = textLayout.createLine(); if (line.isValid()) { line.setLineWidth(descRect.width()); elideWidth += line.naturalTextWidth(); } } QString elidedText = painter->fontMetrics().elidedText(mask->description(), Qt::ElideRight, elideWidth); painter->drawText(descRect, Qt::AlignLeft|Qt::TextWordWrap, elidedText); } } } painter->restore(); } KisGamutMaskChooser::KisGamutMaskChooser(QWidget *parent) : QWidget(parent) { m_delegate = new KisGamutMaskDelegate(this); m_itemChooser = new KisResourceItemChooser(ResourceType::GamutMasks, false, this); m_itemChooser->setItemDelegate(m_delegate); m_itemChooser->showTaggingBar(true); m_itemChooser->showButtons(false); - m_itemChooser->setColumnCount(4); m_itemChooser->setSynced(true); QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0,0,0,0); // TODO: menu for view mode change QMenu* menu = new QMenu(this); menu->setStyleSheet("margin: 6px"); menu->addSection(i18nc("@title Which elements to display (e.g., thumbnails or details)", "Display")); QActionGroup *actionGroup = new QActionGroup(this); KisConfig cfg(true); m_mode = KisGamutMaskChooser::ViewMode(cfg.readEntry("GamutMasks.viewMode", KisGamutMaskChooser::THUMBNAIL)); QAction* action = menu->addAction(KisIconUtils::loadIcon("view-preview"), i18n("Thumbnails"), this, SLOT(slotSetModeThumbnail())); action->setCheckable(true); action->setChecked(m_mode == KisGamutMaskChooser::THUMBNAIL); action->setActionGroup(actionGroup); action = menu->addAction(KisIconUtils::loadIcon("view-list-details"), i18n("Details"), this, SLOT(slotSetModeDetail())); action->setCheckable(true); action->setChecked(m_mode == KisGamutMaskChooser::DETAIL); action->setActionGroup(actionGroup); // setting the view mode setViewMode(m_mode); m_itemChooser->setViewModeButtonVisible(true); QToolButton* viewModeButton = m_itemChooser->viewModeButton(); viewModeButton->setMenu(menu); layout->addWidget(m_itemChooser); setLayout(layout); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(resourceSelected(KoResourceSP ))); } KisGamutMaskChooser::~KisGamutMaskChooser() { } void KisGamutMaskChooser::setCurrentResource(KoResourceSP resource) { m_itemChooser->setCurrentResource(resource); } void KisGamutMaskChooser::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); updateViewSettings(); } void KisGamutMaskChooser::setViewMode(KisGamutMaskChooser::ViewMode mode) { m_mode = mode; updateViewSettings(); } void KisGamutMaskChooser::updateViewSettings() { KisConfig cfg(false); cfg.writeEntry("GamutMasks.viewMode", qint32(m_mode)); if (m_mode == KisGamutMaskChooser::THUMBNAIL) { m_itemChooser->setSynced(true); m_delegate->setViewMode(m_mode); } else if (m_mode == KisGamutMaskChooser::DETAIL) { m_itemChooser->setSynced(false); - m_itemChooser->setColumnCount(1); + m_itemChooser->itemView()->setViewMode(QListView::ListMode); m_itemChooser->setRowHeight(this->fontMetrics().lineSpacing()*4); m_itemChooser->setColumnWidth(m_itemChooser->width()); m_delegate->setViewMode(m_mode); } } void KisGamutMaskChooser::resourceSelected(KoResourceSP resource) { emit sigGamutMaskSelected(resource.staticCast()); } void KisGamutMaskChooser::slotSetModeThumbnail() { setViewMode(KisGamutMaskChooser::THUMBNAIL); } void KisGamutMaskChooser::slotSetModeDetail() { setViewMode(KisGamutMaskChooser::DETAIL); } diff --git a/plugins/dockers/patterndocker/patterndocker_dock.cpp b/plugins/dockers/patterndocker/patterndocker_dock.cpp index 2ddd60a1c3..ee28316094 100644 --- a/plugins/dockers/patterndocker/patterndocker_dock.cpp +++ b/plugins/dockers/patterndocker/patterndocker_dock.cpp @@ -1,70 +1,70 @@ /* * Copyright (c) 2009 Cyrille Berger * * This library 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, or * (at your option) any later version. * * This library 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 Lesser 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 "patterndocker_dock.h" #include #include #include #include #include #include #include PatternDockerDock::PatternDockerDock( ) : QDockWidget(i18n("Patterns")) { m_patternChooser = new KisPatternChooser(this); m_patternChooser->setPreviewOrientation(Qt::Vertical); - m_patternChooser->setCurrentItem(0,0); + m_patternChooser->setCurrentItem(0); m_patternChooser->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); m_patternChooser->setMinimumHeight(160); setWidget(m_patternChooser); } void PatternDockerDock::setViewManager(KisViewManager* kisview) { KisCanvasResourceProvider* resourceProvider = kisview->canvasResourceProvider(); connect(resourceProvider, SIGNAL(sigPatternChanged(KoPatternSP)), this, SLOT(patternChanged(KoPatternSP))); connect(m_patternChooser, SIGNAL(resourceSelected(KoResourceSP )), resourceProvider, SLOT(slotPatternActivated(KoResourceSP ))); } void PatternDockerDock::setCanvas(KoCanvasBase *canvas) { setEnabled(canvas != 0); } void PatternDockerDock::unsetCanvas() { setEnabled(false); } void PatternDockerDock::patternChanged(KoPatternSP pattern) { m_patternChooser->setCurrentPattern(pattern); } diff --git a/plugins/dockers/tasksetdocker/tasksetdocker_dock.cpp b/plugins/dockers/tasksetdocker/tasksetdocker_dock.cpp index 02489b3a39..2fbe0eaaa2 100644 --- a/plugins/dockers/tasksetdocker/tasksetdocker_dock.cpp +++ b/plugins/dockers/tasksetdocker/tasksetdocker_dock.cpp @@ -1,245 +1,246 @@ /* * Copyright (c) 2011 Sven Langkamp * * This library 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, or * (at your option) any later version. * * This library 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 Lesser 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 "tasksetdocker_dock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include "tasksetmodel.h" class KisTasksetDelegate : public QStyledItemDelegate { public: KisTasksetDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {} ~KisTasksetDelegate() override {} /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const override { return QSize(QStyledItemDelegate::sizeHint(option, index).width(), qMin(QStyledItemDelegate::sizeHint(option, index).width(), 25)); } }; class KisTasksetResourceDelegate : public QStyledItemDelegate { public: KisTasksetResourceDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {} ~KisTasksetResourceDelegate() override {} /// reimplemented void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; }; void KisTasksetResourceDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { if (! index.isValid()) return; QString name = index.data(Qt::UserRole + KisResourceModel::Name).toString(); if (option.state & QStyle::State_Selected) { painter->setPen(QPen(option.palette.highlight(), 2.0)); painter->fillRect(option.rect, option.palette.highlight()); painter->setBrush(option.palette.highlightedText()); } else { painter->setBrush(option.palette.text()); } painter->drawText(option.rect.x() + 5, option.rect.y() + painter->fontMetrics().ascent() + 5, name); } TasksetDockerDock::TasksetDockerDock( ) : QDockWidget(i18n("Task Sets")), m_canvas(0), m_blocked(false) { QWidget* widget = new QWidget(this); setupUi(widget); m_model = new TasksetModel(this); tasksetView->setModel(m_model); tasksetView->setItemDelegate(new KisTasksetDelegate(this)); recordButton->setIcon(KisIconUtils::loadIcon("media-record")); recordButton->setCheckable(true); clearButton->setIcon(KisIconUtils::loadIcon("edit-delete")); saveButton->setIcon(KisIconUtils::loadIcon("document-save")); saveButton->setEnabled(false); chooserButton->setIcon(KisIconUtils::loadIcon("edit-copy")); m_rserver = new KoResourceServer(ResourceType::TaskSets); KisResourceLoaderRegistry::instance()->add(new KisResourceLoader(ResourceType::TaskSets, ResourceType::TaskSets, i18n("Task sets"), QStringList() << "application/x-krita-taskset")); KisResourceItemChooser *itemChooser = new KisResourceItemChooser(ResourceType::TaskSets, false, this); itemChooser->setItemDelegate(new KisTasksetResourceDelegate(this)); itemChooser->setFixedSize(500, 250); itemChooser->setRowHeight(30); - itemChooser->setColumnCount(1); + itemChooser->itemView()->setViewMode(QListView::ListMode); itemChooser->showTaggingBar(true); chooserButton->setPopupWidget(itemChooser); connect(itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(resourceSelected(KoResourceSP ))); setWidget(widget); connect( tasksetView, SIGNAL(clicked(QModelIndex)), this, SLOT(activated(QModelIndex)) ); connect( recordButton, SIGNAL(toggled(bool)), this, SLOT(recordClicked())); connect( clearButton, SIGNAL(clicked(bool)), this, SLOT(clearClicked())); connect( saveButton, SIGNAL(clicked(bool)), this, SLOT(saveClicked())); } TasksetDockerDock::~TasksetDockerDock() { delete m_rserver; } void TasksetDockerDock::setCanvas(KoCanvasBase * canvas) { if (m_canvas && m_canvas->viewManager()) { m_canvas->viewManager()->actionCollection()->disconnect(this); Q_FOREACH (KXMLGUIClient* client, m_canvas->viewManager()->mainWindow()->childClients()) { client->actionCollection()->disconnect(this); } } m_canvas = dynamic_cast(canvas); } void TasksetDockerDock::unsetCanvas() { m_canvas = 0; m_model->clear(); } void TasksetDockerDock::actionTriggered(QAction* action) { if(action && !action->objectName().isEmpty() && !m_blocked && recordButton->isChecked()) { m_model->addAction(action); saveButton->setEnabled(true); } } void TasksetDockerDock::activated(const QModelIndex& index) { QAction* action = m_model->actionFromIndex(index); m_blocked = true; action->trigger(); m_blocked = false; } void TasksetDockerDock::recordClicked() { if(m_canvas) { KisViewManager* view = m_canvas->viewManager(); connect(view->actionCollection(), SIGNAL(actionTriggered(QAction*)), this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection); Q_FOREACH (KXMLGUIClient* client, view->mainWindow()->childClients()) { connect(client->actionCollection(), SIGNAL(actionTriggered(QAction*)), this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection); } } } void TasksetDockerDock::saveClicked() { bool ok; QString name; if (!ok) { return; } TasksetResourceSP taskset(new TasksetResource(QString())); QStringList actionNames; Q_FOREACH (QAction* action, m_model->actions()) { actionNames.append(action->objectName()); } taskset->setActionList(actionNames); taskset->setValid(true); QString saveLocation = m_rserver->saveLocation(); bool newName = false; if(name.isEmpty()) { newName = true; name = i18n("Taskset"); } QFileInfo fileInfo(saveLocation + name + taskset->defaultFileExtension()); bool fileOverwriteAccepted = false; while(!fileOverwriteAccepted) { name = QInputDialog::getText(this, i18n("Taskset Name"), i18n("Name:"), QLineEdit::Normal, QString(), &ok); if (name.isNull() || name.isEmpty()) { return; } else { fileInfo = QFileInfo(saveLocation + name.split(" ").join("_") + taskset->defaultFileExtension()); if (fileInfo.exists()) { int res = QMessageBox::warning(this, i18nc("@title:window", "Name Already Exists") , i18n("The name '%1' already exists, do you wish to overwrite it?", name) , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (res == QMessageBox::Yes) fileOverwriteAccepted = true; } else { fileOverwriteAccepted = true; } } } taskset->setName(name); taskset->setFilename(fileInfo.fileName()); m_rserver->addResource(taskset); } void TasksetDockerDock::clearClicked() { saveButton->setEnabled(false); m_model->clear(); } void TasksetDockerDock::resourceSelected(KoResourceSP resource) { if(!m_canvas) { return; } m_model->clear(); saveButton->setEnabled(true); Q_FOREACH (const QString& actionName, resource.staticCast()->actionList()) { QAction* action = m_canvas->viewManager()->actionCollection()->action(actionName); if(action) { m_model->addAction(action); } } } diff --git a/plugins/paintops/libpaintop/kis_brush_chooser.cpp b/plugins/paintops/libpaintop/kis_brush_chooser.cpp index 6bef82b3db..120a3f7b8f 100644 --- a/plugins/paintops/libpaintop/kis_brush_chooser.cpp +++ b/plugins/paintops/libpaintop/kis_brush_chooser.cpp @@ -1,417 +1,416 @@ /* * Copyright (c) 2004 Adrian Page * Copyright (c) 2009 Sven Langkamp * Copyright (c) 2010 Cyrille Berger * Copyright (c) 2010 Lukáš Tvrdý * Copyright (C) 2011 Srikanth Tiyyagura * * 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, Boston, MA 02110-1301, USA. */ #include "kis_brush_chooser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisBrushServerProvider.h" #include "widgets/kis_slider_spin_box.h" #include "widgets/kis_multipliers_double_slider_spinbox.h" #include "kis_spacing_selection_widget.h" #include "kis_signals_blocker.h" #include "kis_imagepipe_brush.h" #include "kis_custom_brush_widget.h" #include "kis_clipboard_brush_widget.h" #include #include "kis_global.h" #include "kis_gbr_brush.h" #include "kis_debug.h" #include "kis_image.h" /// The resource item delegate for rendering the resource preview class KisBrushDelegate : public QAbstractItemDelegate { public: KisBrushDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent) {} ~KisBrushDelegate() override {} /// reimplemented void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const override { return option.decorationSize; } }; void KisBrushDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { if (! index.isValid()) return; QImage thumbnail = index.data(Qt::DecorationRole).value(); QRect itemRect = option.rect; if (thumbnail.height() > itemRect.height() || thumbnail.width() > itemRect.width()) { thumbnail = thumbnail.scaled(itemRect.size() , Qt::KeepAspectRatio, Qt::SmoothTransformation); } painter->save(); int dx = (itemRect.width() - thumbnail.width()) / 2; int dy = (itemRect.height() - thumbnail.height()) / 2; painter->drawImage(itemRect.x() + dx, itemRect.y() + dy, thumbnail); if (option.state & QStyle::State_Selected) { painter->setPen(QPen(option.palette.highlight(), 2.0)); painter->drawRect(option.rect); painter->setCompositionMode(QPainter::CompositionMode_HardLight); painter->setOpacity(0.65); painter->fillRect(option.rect, option.palette.highlight()); } painter->restore(); } KisPredefinedBrushChooser::KisPredefinedBrushChooser(QWidget *parent, const char *name) : QWidget(parent), m_stampBrushWidget(0), m_clipboardBrushWidget(0) { setObjectName(name); setupUi(this); brushSizeSpinBox->setRange(0, KSharedConfig::openConfig()->group("").readEntry("maximumBrushSize", 1000), 2); brushSizeSpinBox->setValue(5); brushSizeSpinBox->setExponentRatio(3.0); brushSizeSpinBox->setSuffix(i18n(" px")); brushSizeSpinBox->setExponentRatio(3.0); QObject::connect(brushSizeSpinBox, SIGNAL(valueChanged(qreal)), this, SLOT(slotSetItemSize(qreal))); brushRotationSpinBox->setRange(0, 360, 0); brushRotationSpinBox->setValue(0); brushRotationSpinBox->setSuffix(QChar(Qt::Key_degree)); QObject::connect(brushRotationSpinBox, SIGNAL(valueChanged(qreal)), this, SLOT(slotSetItemRotation(qreal))); brushSpacingSelectionWidget->setSpacing(true, 1.0); connect(brushSpacingSelectionWidget, SIGNAL(sigSpacingChanged()), SLOT(slotSpacingChanged())); QObject::connect(useColorAsMaskCheckbox, SIGNAL(toggled(bool)), this, SLOT(slotSetItemUseColorAsMask(bool))); m_itemChooser = new KisResourceItemChooser(ResourceType::Brushes, false, this); m_itemChooser->setObjectName("brush_selector"); m_itemChooser->showTaggingBar(true); - m_itemChooser->setColumnCount(10); m_itemChooser->setRowHeight(30); m_itemChooser->setItemDelegate(new KisBrushDelegate(this)); - m_itemChooser->setCurrentItem(0, 0); + m_itemChooser->setCurrentItem(0); m_itemChooser->setSynced(true); m_itemChooser->setMinimumWidth(100); m_itemChooser->setMinimumHeight(150); m_itemChooser->showButtons(false); // turn the import and delete buttons since we want control over them addPresetButton->setIcon(KisIconUtils::loadIcon("list-add")); deleteBrushTipButton->setIcon(KisIconUtils::loadIcon("trash-empty")); connect(addPresetButton, SIGNAL(clicked(bool)), this, SLOT(slotImportNewBrushResource())); connect(deleteBrushTipButton, SIGNAL(clicked(bool)), this, SLOT(slotDeleteBrushResource())); presetsLayout->addWidget(m_itemChooser); connect(m_itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(updateBrushTip(KoResourceSP ))); stampButton->setIcon(KisIconUtils::loadIcon("list-add")); stampButton->setToolTip(i18n("Creates a brush tip from the current image selection." "\n If no selection is present the whole image will be used.")); clipboardButton->setIcon(KisIconUtils::loadIcon("list-add")); clipboardButton->setToolTip(i18n("Creates a brush tip from the image in the clipboard.")); connect(stampButton, SIGNAL(clicked()), this, SLOT(slotOpenStampBrush())); connect(clipboardButton, SIGNAL(clicked()), SLOT(slotOpenClipboardBrush())); QGridLayout *spacingLayout = new QGridLayout(); spacingLayout->setObjectName("spacing grid layout"); resetBrushButton->setToolTip(i18n("Reloads Spacing from file\nSets Scale to 1.0\nSets Rotation to 0.0")); connect(resetBrushButton, SIGNAL(clicked()), SLOT(slotResetBrush())); updateBrushTip(m_itemChooser->currentResource()); } KisPredefinedBrushChooser::~KisPredefinedBrushChooser() { } void KisPredefinedBrushChooser::setBrush(KisBrushSP brush) { /** * Warning: since the brushes are always cloned after loading from XML or * fetching from the server, we cannot just ask for that brush explicitly. * Instead, we should search for the brush with the same filename and/or name * and load it. Please take it into account that after selecting the brush * explicitly in the chooser, m_itemChooser->currentResource() might be * **not** the same as the value in m_brush. * * Ideally, if the resource is not found on the server, we should add it, but * it might lead to a set of weird consequences. So for now we just * select nothing. */ KoResourceServer* server = KisBrushServerProvider::instance()->brushServer(); KoResourceSP resource = server->resourceByFilename(brush->shortFilename()); if (!resource) { resource = server->resourceByName(brush->name()); } if (!resource) { resource = brush; } m_itemChooser->setCurrentResource(resource); updateBrushTip(brush, true); } void KisPredefinedBrushChooser::slotResetBrush() { /** * The slot also resets the brush on the server * * TODO: technically, after we refactored all the brushes to be forked, * we can just re-update the brush from the server without reloading. * But it needs testing. */ KisBrushSP brush = m_itemChooser->currentResource().dynamicCast(); if (brush) { brush->load(); brush->setScale(1.0); brush->setAngle(0.0); updateBrushTip(brush); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotSetItemSize(qreal sizeValue) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); if (m_brush) { int brushWidth = m_brush->width(); m_brush->setScale(sizeValue / qreal(brushWidth)); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotSetItemRotation(qreal rotationValue) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); if (m_brush) { m_brush->setAngle(rotationValue / 180.0 * M_PI); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotSpacingChanged() { KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); if (m_brush) { m_brush->setSpacing(brushSpacingSelectionWidget->spacing()); m_brush->setAutoSpacing(brushSpacingSelectionWidget->autoSpacingActive(), brushSpacingSelectionWidget->autoSpacingCoeff()); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotSetItemUseColorAsMask(bool useColorAsMask) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_brush); KisGbrBrush *brush = dynamic_cast(m_brush.data()); if (brush) { brush->setUseColorAsMask(useColorAsMask); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotOpenStampBrush() { if(!m_stampBrushWidget) { m_stampBrushWidget = new KisCustomBrushWidget(this, i18n("Stamp"), m_image); m_stampBrushWidget->setModal(false); connect(m_stampBrushWidget, SIGNAL(sigNewPredefinedBrush(KoResourceSP )), SLOT(slotNewPredefinedBrush(KoResourceSP ))); } else { m_stampBrushWidget->setImage(m_image); } QDialog::DialogCode result = (QDialog::DialogCode)m_stampBrushWidget->exec(); if(result) { updateBrushTip(m_itemChooser->currentResource()); } } void KisPredefinedBrushChooser::slotOpenClipboardBrush() { if(!m_clipboardBrushWidget) { m_clipboardBrushWidget = new KisClipboardBrushWidget(this, i18n("Clipboard"), m_image); m_clipboardBrushWidget->setModal(true); connect(m_clipboardBrushWidget, SIGNAL(sigNewPredefinedBrush(KoResourceSP )), SLOT(slotNewPredefinedBrush(KoResourceSP ))); } QDialog::DialogCode result = (QDialog::DialogCode)m_clipboardBrushWidget->exec(); if(result) { updateBrushTip(m_itemChooser->currentResource()); } } void KisPredefinedBrushChooser::updateBrushTip(KoResourceSP resource, bool isChangingBrushPresets) { QString animatedBrushTipSelectionMode; // incremental, random, etc { KisBrushSP brush = resource.dynamicCast(); m_brush = brush ? brush->clone() : 0; } if (m_brush) { brushTipNameLabel->setText(i18n(m_brush->name().toUtf8().data())); QString brushTypeString = ""; if (m_brush->brushType() == INVALID) { brushTypeString = i18n("Invalid"); } else if (m_brush->brushType() == MASK) { brushTypeString = i18n("Mask"); } else if (m_brush->brushType() == IMAGE) { brushTypeString = i18n("GBR"); } else if (m_brush->brushType() == PIPE_MASK ) { brushTypeString = i18n("Animated Mask"); // GIH brush // cast to GIH brush and grab parasite name //m_brush KisImagePipeBrushSP pipeBrush = resource.dynamicCast(); animatedBrushTipSelectionMode = pipeBrush->parasiteSelection(); } else if (m_brush->brushType() == PIPE_IMAGE ) { brushTypeString = i18n("Animated Image"); } QString brushDetailsText = QString("%1 (%2 x %3) %4") .arg(brushTypeString) .arg(m_brush->width()) .arg(m_brush->height()) .arg(animatedBrushTipSelectionMode); brushDetailsLabel->setText(brushDetailsText); // keep the current preset's tip settings if we are preserving it // this will set the brush's model data to keep what it currently has for size, spacing, etc. if (preserveBrushPresetSettings->isChecked() && !isChangingBrushPresets) { m_brush->setAutoSpacing(brushSpacingSelectionWidget->autoSpacingActive(), brushSpacingSelectionWidget->autoSpacingCoeff()); m_brush->setAngle(brushRotationSpinBox->value() * M_PI / 180); m_brush->setSpacing(brushSpacingSelectionWidget->spacing()); m_brush->setUserEffectiveSize(brushSizeSpinBox->value()); } brushSpacingSelectionWidget->setSpacing(m_brush->autoSpacingActive(), m_brush->autoSpacingActive() ? m_brush->autoSpacingCoeff() : m_brush->spacing()); brushRotationSpinBox->setValue(m_brush->angle() * 180 / M_PI); brushSizeSpinBox->setValue(m_brush->width() * m_brush->scale()); // useColorAsMask support is only in gimp brush so far bool prevColorAsMaskState = useColorAsMaskCheckbox->isChecked(); KisGbrBrush *gimpBrush = dynamic_cast(m_brush.data()); if (gimpBrush) { useColorAsMaskCheckbox->setChecked(gimpBrush->useColorAsMask() || prevColorAsMaskState); gimpBrush->setUseColorAsMask(prevColorAsMaskState); } useColorAsMaskCheckbox->setEnabled(m_brush->hasColor() && gimpBrush); emit sigBrushChanged(); } } void KisPredefinedBrushChooser::slotNewPredefinedBrush(KoResourceSP resource) { m_itemChooser->setCurrentResource(resource); updateBrushTip(resource); } void KisPredefinedBrushChooser::setBrushSize(qreal xPixels, qreal yPixels) { Q_UNUSED(yPixels); qreal oldWidth = m_brush->width() * m_brush->scale(); qreal newWidth = oldWidth + xPixels; newWidth = qMax(newWidth, qreal(0.1)); brushSizeSpinBox->setValue(newWidth); } void KisPredefinedBrushChooser::setImage(KisImageWSP image) { m_image = image; } void KisPredefinedBrushChooser::slotImportNewBrushResource() { m_itemChooser->slotButtonClicked(KisResourceItemChooser::Button_Import); } void KisPredefinedBrushChooser::slotDeleteBrushResource() { m_itemChooser->slotButtonClicked(KisResourceItemChooser::Button_Remove); } #include "moc_kis_brush_chooser.cpp" diff --git a/plugins/paintops/libpaintop/kis_texture_chooser.cpp b/plugins/paintops/libpaintop/kis_texture_chooser.cpp index e3dbc1562e..51342e7f67 100644 --- a/plugins/paintops/libpaintop/kis_texture_chooser.cpp +++ b/plugins/paintops/libpaintop/kis_texture_chooser.cpp @@ -1,69 +1,69 @@ /* * Copyright (c) 2017 Scott Petrovic * 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, Boston, MA 02110-1301, USA. */ #include "kis_texture_chooser.h" #include "kis_texture_option.h" KisTextureChooser::KisTextureChooser(QWidget *parent) : QWidget(parent) { setupUi(this); textureSelectorWidget->setGrayscalePreview(true); - textureSelectorWidget->setCurrentItem(0, 0); + textureSelectorWidget->setCurrentItem(0); scaleSlider->setRange(0.0, 2.0, 2); scaleSlider->setValue(1.0); scaleSlider->addMultiplier(0.1); scaleSlider->addMultiplier(2); scaleSlider->addMultiplier(10); brightnessSlider->setRange(-1.0, 1.0, 2); brightnessSlider->setValue(0.0); brightnessSlider->setToolTip(i18n("Makes texture lighter or darker")); contrastSlider->setRange(0.0, 2.0, 2); contrastSlider->setValue(1.0); offsetSliderX->setSuffix(i18n(" px")); offsetSliderY->setSuffix(i18n(" px")); QStringList texturingModes; texturingModes << i18n("Multiply") << i18n("Subtract"); cmbTexturingMode->addItems(texturingModes); cmbTexturingMode->setCurrentIndex(KisTextureProperties::SUBTRACT); QStringList cutOffPolicies; cutOffPolicies << i18n("Cut Off Disabled") << i18n("Cut Off Brush") << i18n("Cut Off Pattern"); cmbCutoffPolicy->addItems(cutOffPolicies); cutoffSlider->setMinimumSize(256, 30); cutoffSlider->enableGamma(false); cutoffSlider->setToolTip(i18n("When pattern texture values are outside the range specified" " by the slider, the cut-off policy will be applied.")); chkInvert->setChecked(false); } KisTextureChooser::~KisTextureChooser() { } diff --git a/plugins/tools/karbonplugins/tools/filterEffectTool/FilterEffectEditWidget.cpp b/plugins/tools/karbonplugins/tools/filterEffectTool/FilterEffectEditWidget.cpp index e1143aaadd..686d63955c 100644 --- a/plugins/tools/karbonplugins/tools/filterEffectTool/FilterEffectEditWidget.cpp +++ b/plugins/tools/karbonplugins/tools/filterEffectTool/FilterEffectEditWidget.cpp @@ -1,550 +1,550 @@ /* This file is part of the KDE project * Copyright (c) 2009 Jan Hambrecht * * This library 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; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FilterEffectEditWidget.h" #include "FilterEffectResource.h" #include "FilterResourceServerProvider.h" #include "FilterInputChangeCommand.h" #include "FilterAddCommand.h" #include "FilterRemoveCommand.h" #include "FilterStackSetCommand.h" #include #include #include #include #include #include #include #include #include #include #include #include #include FilterEffectEditWidget::FilterEffectEditWidget(QWidget *parent) : QWidget(parent) , m_scene(new FilterEffectScene(this)) , m_shape(0) , m_canvas(0) , m_effects(0) { setupUi(this); presets->setDisplayMode(KoResourceSelector::TextMode); - presets->setColumnCount(1); + presets->setSingleColumn(true); connect(presets, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(presetSelected(KoResourceSP ))); connect(presets, SIGNAL(resourceApplied(KoResourceSP )), this, SLOT(presetSelected(KoResourceSP ))); KoGenericRegistryModel *filterEffectModel = new KoGenericRegistryModel(KoFilterEffectRegistry::instance()); effectSelector->setModel(filterEffectModel); removeEffect->setIcon(koIcon("list-remove")); connect(removeEffect, SIGNAL(clicked()), this, SLOT(removeSelectedItem())); addEffect->setIcon(koIcon("list-add")); addEffect->setToolTip(i18n("Add effect to current filter stack")); connect(addEffect, SIGNAL(clicked()), this, SLOT(addSelectedEffect())); // TODO: make these buttons do something useful raiseEffect->setIcon(koIcon("arrow-up")); raiseEffect->hide(); lowerEffect->setIcon(koIcon("arrow-down")); lowerEffect->hide(); addPreset->setIcon(koIcon("list-add")); addPreset->setToolTip(i18n("Add to filter presets")); connect(addPreset, SIGNAL(clicked()), this, SLOT(addToPresets())); removePreset->setIcon(koIcon("list-remove")); removePreset->setToolTip(i18n("Remove filter preset")); connect(removePreset, SIGNAL(clicked()), this, SLOT(removeFromPresets())); view->setScene(m_scene); view->setRenderHint(QPainter::Antialiasing, true); view->setResizeAnchor(QGraphicsView::AnchorViewCenter); connect(m_scene, SIGNAL(connectionCreated(ConnectionSource,ConnectionTarget)), this, SLOT(connectionCreated(ConnectionSource,ConnectionTarget))); connect(m_scene, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged())); QSet inputs; inputs << ConnectionSource::SourceGraphic; inputs << ConnectionSource::SourceAlpha; inputs << ConnectionSource::BackgroundImage; inputs << ConnectionSource::BackgroundAlpha; inputs << ConnectionSource::FillPaint; inputs << ConnectionSource::StrokePaint; m_defaultSourceSelector = new KComboBox(this); Q_FOREACH (ConnectionSource::SourceType source, inputs) { m_defaultSourceSelector->addItem(ConnectionSource::typeToString(source)); } m_defaultSourceSelector->hide(); m_defaultSourceSelector->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); connect(m_defaultSourceSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(defaultSourceChanged(int))); } FilterEffectEditWidget::~FilterEffectEditWidget() { if (!m_shape) { delete m_effects; } } void FilterEffectEditWidget::editShape(KoShape *shape, KoCanvasBase *canvas) { if (!m_shape) { delete m_effects; m_effects = 0; } m_shape = shape; m_canvas = canvas; if (m_shape) { m_effects = m_shape->filterEffectStack(); } if (!m_effects) { m_effects = new KoFilterEffectStack(); } m_scene->initialize(m_effects); fitScene(); } void FilterEffectEditWidget::fitScene() { QRectF bbox = m_scene->itemsBoundingRect(); m_scene->setSceneRect(bbox); bbox.adjust(-25, -25, 25, 25); view->centerOn(bbox.center()); view->fitInView(bbox, Qt::KeepAspectRatio); } void FilterEffectEditWidget::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); fitScene(); } void FilterEffectEditWidget::showEvent(QShowEvent *event) { Q_UNUSED(event); fitScene(); } void FilterEffectEditWidget::addSelectedEffect() { KoFilterEffectRegistry *registry = KoFilterEffectRegistry::instance(); KoFilterEffectFactoryBase *factory = registry->values()[effectSelector->currentIndex()]; if (!factory) { return; } KoFilterEffect *effect = factory->createFilterEffect(); if (!effect) { return; } if (m_shape) { if (!m_shape->filterEffectStack()) { m_effects->appendFilterEffect(effect); m_canvas->addCommand(new FilterStackSetCommand(m_effects, m_shape)); } else { m_canvas->addCommand(new FilterAddCommand(effect, m_shape)); } } else { m_effects->appendFilterEffect(effect); } m_scene->initialize(m_effects); fitScene(); } void FilterEffectEditWidget::removeSelectedItem() { QList selectedItems = m_scene->selectedEffectItems(); if (!selectedItems.count()) { return; } QList changeData; QList filterEffects = m_effects->filterEffects(); int effectIndexToDelete = -1; const ConnectionSource &item = selectedItems.first(); KoFilterEffect *effect = item.effect(); if (item.type() == ConnectionSource::Effect) { int effectIndex = filterEffects.indexOf(effect); // adjust inputs of all following effects in the stack for (int i = effectIndex + 1; i < filterEffects.count(); ++i) { KoFilterEffect *nextEffect = filterEffects[i]; QList inputs = nextEffect->inputs(); int inputIndex = 0; Q_FOREACH (const QString &input, inputs) { if (input == effect->output()) { InputChangeData data(nextEffect, inputIndex, input, ""); changeData.append(data); } } // if one of the next effects has the same output name we stop if (nextEffect->output() == effect->output()) { break; } } effectIndexToDelete = effectIndex; } else { QString outputName = ConnectionSource::typeToString(item.type()); QList inputs = effect->inputs(); int inputIndex = 0; Q_FOREACH (const QString &input, inputs) { if (input == outputName) { InputChangeData data(effect, inputIndex, input, ""); changeData.append(data); } inputIndex++; } } KUndo2Command *cmd = new KUndo2Command(); if (changeData.count()) { KUndo2Command *subCmd = new FilterInputChangeCommand(changeData, m_shape, cmd); cmd->setText(subCmd->text()); } if (effectIndexToDelete >= 0) { KUndo2Command *subCmd = new FilterRemoveCommand(effectIndexToDelete, m_effects, m_shape, cmd); cmd->setText(subCmd->text()); } if (m_canvas && m_shape) { m_canvas->addCommand(cmd); } else { cmd->redo(); delete cmd; } m_scene->initialize(m_effects); fitScene(); } void FilterEffectEditWidget::connectionCreated(ConnectionSource source, ConnectionTarget target) { QList filterEffects = m_effects->filterEffects(); int targetEffectIndex = filterEffects.indexOf(target.effect()); if (targetEffectIndex < 0) { return; } QList changeData; QString sourceName; if (source.type() == ConnectionSource::Effect) { sourceName = source.effect()->output(); int sourceEffectIndex = filterEffects.indexOf(source.effect()); if (targetEffectIndex - sourceEffectIndex > 1) { // there are effects between source effect and target effect // so we have to take extra care bool renameOutput = false; if (sourceName.isEmpty()) { // output is not named so we have to rename the source output // and adjust the next effect in case it uses this output renameOutput = true; } else { // output is named but if there is an effect with the same // output name, we have to rename the source output for (int i = sourceEffectIndex + 1; i < targetEffectIndex; ++i) { KoFilterEffect *effect = filterEffects[i]; if (effect->output() == sourceName) { renameOutput = true; break; } } } if (renameOutput) { QSet uniqueOutputNames; Q_FOREACH (KoFilterEffect *effect, filterEffects) { uniqueOutputNames.insert(effect->output()); } int index = 0; QString newOutputName; do { newOutputName = QString("result%1").arg(index); } while (uniqueOutputNames.contains(newOutputName)); // rename source output source.effect()->setOutput(newOutputName); // adjust following effects for (int i = sourceEffectIndex + 1; i < targetEffectIndex; ++i) { KoFilterEffect *effect = filterEffects[i]; int inputIndex = 0; Q_FOREACH (const QString &input, effect->inputs()) { if (input.isEmpty() && (i == sourceEffectIndex + 1 || input == sourceName)) { InputChangeData data(effect, inputIndex, input, newOutputName); changeData.append(data); } inputIndex++; } if (sourceName.isEmpty() || effect->output() == sourceName) { break; } } sourceName = newOutputName; } } } else { // source is an predefined input image sourceName = ConnectionSource::typeToString(source.type()); } // finally set the input of the target if (target.inputIndex() >= target.effect()->inputs().count()) { // insert new input here target.effect()->addInput(sourceName); } else { QString oldInput = target.effect()->inputs()[target.inputIndex()]; InputChangeData data(target.effect(), target.inputIndex(), oldInput, sourceName); changeData.append(data); } if (changeData.count()) { KUndo2Command *cmd = new FilterInputChangeCommand(changeData, m_shape); if (m_canvas) { m_canvas->addCommand(cmd); } else { cmd->redo(); delete cmd; } } m_scene->initialize(m_effects); fitScene(); } void FilterEffectEditWidget::addToPresets() { if (!m_effects) { return; } bool ok = false; QString effectName = QInputDialog::getText(this, i18n("Effect name"), i18n("Please enter a name for the filter effect"), QLineEdit::Normal, QString(), &ok); if (!ok) { return; } QSharedPointer resource(FilterEffectResource::fromFilterEffectStack(m_effects)); if (!resource) { return; } resource->setName(effectName); FilterResourceServerProvider *serverProvider = FilterResourceServerProvider::instance(); KoResourceServer *server = serverProvider->filterEffectServer(); QString savePath = server->saveLocation(); int i = 1; QFileInfo fileInfo; do { fileInfo.setFile(savePath + QString("%1.svg").arg(i++, 4, 10, QChar('0'))); } while (fileInfo.exists()); resource->setFilename(fileInfo.filePath()); resource->setValid(true); } void FilterEffectEditWidget::removeFromPresets() { if (!presets->count()) { return; } FilterResourceServerProvider *serverProvider = FilterResourceServerProvider::instance(); if (!serverProvider) { return; } KoResourceServer *server = serverProvider->filterEffectServer(); if (!server) { return; } QSharedPointer resource = server->resources().at(presets->currentIndex()); if (!resource) { return; } server->removeResourceFromServer(resource); } void FilterEffectEditWidget::presetSelected(KoResourceSP resource) { QSharedPointer effectResource = resource.dynamicCast(); if (!effectResource) { return; } KoFilterEffectStack *filterStack = effectResource->toFilterStack(); if (!filterStack) { return; } if (m_shape) { KUndo2Command *cmd = new FilterStackSetCommand(filterStack, m_shape); if (m_canvas) { m_canvas->addCommand(cmd); } else { cmd->redo(); delete cmd; } } else { delete m_effects; } m_effects = filterStack; m_scene->initialize(m_effects); fitScene(); } void FilterEffectEditWidget::addWidgetForItem(ConnectionSource item) { // get the filter effect from the item KoFilterEffect *filterEffect = item.effect(); if (item.type() != ConnectionSource::Effect) { filterEffect = 0; } KoFilterEffect *currentEffect = m_currentItem.effect(); if (m_currentItem.type() != ConnectionSource::Effect) { currentEffect = 0; } m_defaultSourceSelector->hide(); // remove current widget if new effect is zero or effect type has changed if (!filterEffect || !currentEffect || (filterEffect->id() != currentEffect->id())) { while (configStack->count()) { configStack->removeWidget(configStack->widget(0)); } } m_currentItem = item; KoFilterEffectConfigWidgetBase *currentPanel = 0; if (!filterEffect) { if (item.type() != ConnectionSource::Effect) { configStack->insertWidget(0, m_defaultSourceSelector); m_defaultSourceSelector->blockSignals(true); m_defaultSourceSelector->setCurrentIndex(item.type() - 1); m_defaultSourceSelector->blockSignals(false); m_defaultSourceSelector->show(); } } else if (!currentEffect || currentEffect->id() != filterEffect->id()) { // when a shape is set and is differs from the previous one // get the config widget and insert it into the option widget KoFilterEffectRegistry *registry = KoFilterEffectRegistry::instance(); KoFilterEffectFactoryBase *factory = registry->value(filterEffect->id()); if (!factory) { return; } currentPanel = factory->createConfigWidget(); if (!currentPanel) { return; } configStack->insertWidget(0, currentPanel); connect(currentPanel, SIGNAL(filterChanged()), this, SLOT(filterChanged())); } currentPanel = qobject_cast(configStack->widget(0)); if (currentPanel) { currentPanel->editFilterEffect(filterEffect); } } void FilterEffectEditWidget::filterChanged() { if (m_shape) { m_shape->update(); } } void FilterEffectEditWidget::sceneSelectionChanged() { QList selectedItems = m_scene->selectedEffectItems(); if (!selectedItems.count()) { addWidgetForItem(ConnectionSource()); } else { addWidgetForItem(selectedItems.first()); } } void FilterEffectEditWidget::defaultSourceChanged(int index) { if (m_currentItem.type() == ConnectionSource::Effect) { return; } KoFilterEffect *filterEffect = m_currentItem.effect(); if (!filterEffect) { return; } QString oldInput = ConnectionSource::typeToString(m_currentItem.type()); QString newInput = m_defaultSourceSelector->itemText(index); const QString defInput = "SourceGraphic"; int effectIndex = m_effects->filterEffects().indexOf(filterEffect); InputChangeData data; int inputIndex = 0; Q_FOREACH (const QString &input, filterEffect->inputs()) { if (input == oldInput || (effectIndex == 0 && oldInput == defInput)) { data = InputChangeData(filterEffect, inputIndex, input, newInput); break; } inputIndex++; } KUndo2Command *cmd = new FilterInputChangeCommand(data, m_shape); if (m_canvas && m_shape) { m_canvas->addCommand(cmd); } else { cmd->redo(); delete cmd; } m_scene->initialize(m_effects); fitScene(); } diff --git a/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp b/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp index 416aebf973..f2192bac4a 100644 --- a/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp +++ b/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp @@ -1,551 +1,551 @@ /* This file is part of the KDE project * Copyright (c) 2009-2011 Jan Hambrecht * * This library 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; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonFilterEffectsTool.h" #include "KoFilterEffect.h" #include "KoFilterEffectStack.h" #include "KoFilterEffectFactoryBase.h" #include "KoFilterEffectRegistry.h" #include "KoFilterEffectConfigWidgetBase.h" #include "KoCanvasBase.h" #include "KoDocumentResourceManager.h" #include "KoSelectedShapesProxy.h" #include "KoViewConverter.h" #include "KoSelection.h" #include "FilterEffectEditWidget.h" #include "FilterEffectResource.h" #include "FilterResourceServerProvider.h" #include "FilterStackSetCommand.h" #include "FilterRegionChangeCommand.h" #include "FilterRegionEditStrategy.h" #include "KoResourceSelector.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_double_parse_spin_box.h" class KarbonFilterEffectsTool::Private { public: Private() : filterSelector(0) , configSelector(0) , configStack(0) , posX(0) , posY(0) , posW(0) , posH(0) , clearButton(0) , currentEffect(0) , currentPanel(0) , currentShape(0) { } void fillConfigSelector(KoShape *shape, KarbonFilterEffectsTool *tool) { if (!configSelector) { return; } configSelector->clear(); clearButton->setEnabled(false); if (!shape || !shape->filterEffectStack()) { addWidgetForEffect(0, tool); return; } configSelector->blockSignals(true); int index = 0; Q_FOREACH (KoFilterEffect *effect, shape->filterEffectStack()->filterEffects()) { configSelector->addItem(QString("%1 - ").arg(index) + effect->name()); index++; } configSelector->blockSignals(false); KoFilterEffect *effect = index > 0 ? shape->filterEffectStack()->filterEffects().first() : 0; addWidgetForEffect(effect, tool); clearButton->setEnabled(shape->filterEffectStack() != 0); } void addWidgetForEffect(KoFilterEffect *filterEffect, KarbonFilterEffectsTool *tool) { // remove current widget if new effect is zero or effect type has changed if (!filterEffect || (currentEffect && filterEffect->id() != currentEffect->id())) { while (configStack->count()) { configStack->removeWidget(configStack->widget(0)); } } if (!filterEffect) { currentEffect = 0; currentPanel = 0; } else if (!currentEffect || currentEffect->id() != filterEffect->id()) { // when a effect is set and is differs from the previous one // get the config widget and insert it into the option widget currentEffect = filterEffect; KoFilterEffectRegistry *registry = KoFilterEffectRegistry::instance(); KoFilterEffectFactoryBase *factory = registry->value(currentEffect->id()); if (!factory) { return; } currentPanel = factory->createConfigWidget(); if (!currentPanel) { return; } currentPanel->layout()->setContentsMargins(0, 0, 0, 0); configStack->insertWidget(0, currentPanel); configStack->layout()->setContentsMargins(0, 0, 0, 0); connect(currentPanel, SIGNAL(filterChanged()), tool, SLOT(filterChanged())); } if (currentPanel) { currentPanel->editFilterEffect(filterEffect); } updateFilterRegion(); } void updateFilterRegion() { QRectF region = currentEffect ? currentEffect->filterRect() : QRectF(0, 0, 0, 0); posX->blockSignals(true); posX->setValue(100.0 * region.x()); posX->blockSignals(false); posX->setEnabled(currentEffect != 0); posY->blockSignals(true); posY->setValue(100.0 * region.y()); posY->blockSignals(false); posY->setEnabled(currentEffect != 0); posW->blockSignals(true); posW->setValue(100.0 * region.width()); posW->blockSignals(false); posW->setEnabled(currentEffect != 0); posH->blockSignals(true); posH->setValue(100.0 * region.height()); posH->blockSignals(false); posH->setEnabled(currentEffect != 0); } EditMode editModeFromMousePosition(const QPointF &mousePosition, KarbonFilterEffectsTool *tool) { if (currentShape && currentShape->filterEffectStack() && currentEffect) { // get the size rect of the shape QRectF sizeRect(QPointF(), currentShape->size()); // get the filter rectangle in shape coordinates QRectF filterRect = currentEffect->filterRectForBoundingRect(sizeRect); // get the transformation from document to shape coordinates QTransform transform = currentShape->absoluteTransformation(0).inverted(); // adjust filter rectangle by grab sensitivity const int grabDistance = tool->grabSensitivity(); QPointF border = tool->canvas()->viewConverter()->viewToDocument(QPointF(grabDistance, grabDistance)); filterRect.adjust(-border.x(), -border.y(), border.x(), border.y()); // map event point from document to shape coordinates QPointF shapePoint = transform.map(mousePosition); // check if the mouse is inside/near our filter rect if (filterRect.contains(shapePoint)) { if (qAbs(shapePoint.x() - filterRect.left()) <= border.x()) { return MoveLeft; } else if (qAbs(shapePoint.x() - filterRect.right()) <= border.x()) { return MoveRight; } else if (qAbs(shapePoint.y() - filterRect.top()) <= border.y()) { return MoveTop; } else if (qAbs(shapePoint.y() - filterRect.bottom()) <= border.y()) { return MoveBottom; } else { return MoveAll; } } else { return None; } } return None; } KoResourceSelector *filterSelector; KComboBox *configSelector; QStackedWidget *configStack; QDoubleSpinBox *posX; QDoubleSpinBox *posY; QDoubleSpinBox *posW; QDoubleSpinBox *posH; QToolButton *clearButton; KoFilterEffect *currentEffect; KoFilterEffectConfigWidgetBase *currentPanel; KoShape *currentShape; }; KarbonFilterEffectsTool::KarbonFilterEffectsTool(KoCanvasBase *canvas) : KoInteractionTool(canvas) , d(new Private()) { connect(canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(canvas->selectedShapesProxy(), SIGNAL(selectionContentChanged()), this, SLOT(selectionChanged())); } KarbonFilterEffectsTool::~KarbonFilterEffectsTool() { delete d; } void KarbonFilterEffectsTool::paint(QPainter &painter, const KoViewConverter &converter) { if (d->currentShape && d->currentShape->filterEffectStack()) { painter.save(); // apply the shape transformation QTransform transform = d->currentShape->absoluteTransformation(&converter); painter.setTransform(transform, true); // apply the zoom transformation KoShape::applyConversion(painter, converter); // get the size rect of the shape QRectF sizeRect(QPointF(), d->currentShape->size()); // get the clipping rect of the filter stack KoFilterEffectStack *filterStack = d->currentShape->filterEffectStack(); QRectF clipRect = filterStack->clipRectForBoundingRect(sizeRect); // finally paint the clipping rect painter.setBrush(Qt::NoBrush); painter.setPen(Qt::blue); painter.drawRect(clipRect); if (currentStrategy()) { currentStrategy()->paint(painter, converter); } else if (d->currentEffect) { QRectF filterRect = d->currentEffect->filterRectForBoundingRect(sizeRect); // paint the filter subregion rect painter.setBrush(Qt::NoBrush); painter.setPen(Qt::red); painter.drawRect(filterRect); } painter.restore(); } } void KarbonFilterEffectsTool::repaintDecorations() { if (d->currentShape && d->currentShape->filterEffectStack()) { QRectF bb = d->currentShape->boundingRect(); const int radius = handleRadius(); canvas()->updateCanvas(bb.adjusted(-radius, -radius, radius, radius)); } } void KarbonFilterEffectsTool::activate(ToolActivation toolActivation, const QSet &shapes) { Q_UNUSED(toolActivation); if (shapes.isEmpty()) { emit done(); return; } d->currentShape = canvas()->selectedShapesProxy()->selection()->firstSelectedShape(); d->fillConfigSelector(d->currentShape, this); } void KarbonFilterEffectsTool::mouseMoveEvent(KoPointerEvent *event) { if (currentStrategy()) { KoInteractionTool::mouseMoveEvent(event); } else { EditMode mode = d->editModeFromMousePosition(event->point, this); switch (mode) { case MoveAll: useCursor(Qt::SizeAllCursor); break; case MoveLeft: case MoveRight: useCursor(Qt::SizeHorCursor); break; case MoveTop: case MoveBottom: useCursor(Qt::SizeVerCursor); break; case None: useCursor(Qt::ArrowCursor); break; } } } KoInteractionStrategy *KarbonFilterEffectsTool::createStrategy(KoPointerEvent *event) { EditMode mode = d->editModeFromMousePosition(event->point, this); if (mode == None) { return 0; } return new FilterRegionEditStrategy(this, d->currentShape, d->currentEffect, mode); } void KarbonFilterEffectsTool::presetSelected(KoResourceSP resource) { if (!d->currentShape) { return; } QSharedPointer effectResource = resource.dynamicCast(); if (!effectResource) { return; } KoFilterEffectStack *filterStack = effectResource->toFilterStack(); if (!filterStack) { return; } canvas()->addCommand(new FilterStackSetCommand(filterStack, d->currentShape)); d->fillConfigSelector(d->currentShape, this); } void KarbonFilterEffectsTool::editFilter() { QPointer dlg = new QDialog(); dlg->setWindowTitle(i18n("Filter Effect Editor")); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); QWidget *mainWidget = new QWidget(0); QVBoxLayout *mainLayout = new QVBoxLayout; dlg->setLayout(mainLayout); mainLayout->addWidget(mainWidget); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), dlg, SLOT(close())); FilterEffectEditWidget *editor = new FilterEffectEditWidget(dlg); editor->editShape(d->currentShape, canvas()); mainLayout->addWidget(editor); mainLayout->addWidget(buttonBox); dlg->exec(); delete dlg; d->fillConfigSelector(d->currentShape, this); } void KarbonFilterEffectsTool::clearFilter() { if (!d->currentShape) { return; } if (!d->currentShape->filterEffectStack()) { return; } canvas()->addCommand(new FilterStackSetCommand(0, d->currentShape)); d->fillConfigSelector(d->currentShape, this); } void KarbonFilterEffectsTool::filterChanged() { if (!d->currentShape) { return; } d->currentShape->update(); } void KarbonFilterEffectsTool::filterSelected(int index) { if (!d->currentShape || ! d->currentShape->filterEffectStack()) { return; } KoFilterEffect *effect = 0; QList filterEffects = d->currentShape->filterEffectStack()->filterEffects(); if (index >= 0 && index < filterEffects.count()) { effect = filterEffects[index]; } d->addWidgetForEffect(effect, this); repaintDecorations(); } void KarbonFilterEffectsTool::selectionChanged() { d->currentShape = canvas()->selectedShapesProxy()->selection()->firstSelectedShape(); d->fillConfigSelector(d->currentShape, this); } void KarbonFilterEffectsTool::regionXChanged(double x) { if (!d->currentEffect) { return; } QRectF region = d->currentEffect->filterRect(); region.setX(x / 100.0); canvas()->addCommand(new FilterRegionChangeCommand(d->currentEffect, region, d->currentShape)); } void KarbonFilterEffectsTool::regionYChanged(double y) { if (!d->currentEffect) { return; } QRectF region = d->currentEffect->filterRect(); region.setY(y / 100.0); canvas()->addCommand(new FilterRegionChangeCommand(d->currentEffect, region, d->currentShape)); } void KarbonFilterEffectsTool::regionWidthChanged(double width) { if (!d->currentEffect) { return; } QRectF region = d->currentEffect->filterRect(); region.setWidth(width / 100.0); canvas()->addCommand(new FilterRegionChangeCommand(d->currentEffect, region, d->currentShape)); } void KarbonFilterEffectsTool::regionHeightChanged(double height) { if (!d->currentEffect) { return; } QRectF region = d->currentEffect->filterRect(); region.setHeight(height / 100.0); canvas()->addCommand(new FilterRegionChangeCommand(d->currentEffect, region, d->currentShape)); } QList > KarbonFilterEffectsTool::createOptionWidgets() { QList > widgets; //--------------------------------------------------------------------- QWidget *addFilterWidget = new QWidget(); addFilterWidget->setObjectName("AddEffect"); QGridLayout *addFilterLayout = new QGridLayout(addFilterWidget); d->filterSelector = new KoResourceSelector(addFilterWidget); d->filterSelector->setDisplayMode(KoResourceSelector::TextMode); - d->filterSelector->setColumnCount(1); + d->filterSelector->setSingleColumn(true); addFilterLayout->addWidget(new QLabel(i18n("Effects"), addFilterWidget), 0, 0); addFilterLayout->addWidget(d->filterSelector, 0, 1); connect(d->filterSelector, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(presetSelected(KoResourceSP ))); connect(d->filterSelector, SIGNAL(resourceApplied(KoResourceSP )), this, SLOT(presetSelected(KoResourceSP ))); QToolButton *editButton = new QToolButton(addFilterWidget); editButton->setIcon(koIcon("view-filter")); editButton->setToolTip(i18n("View and edit filter")); addFilterLayout->addWidget(editButton, 0, 2); connect(editButton, SIGNAL(clicked()), this, SLOT(editFilter())); d->clearButton = new QToolButton(addFilterWidget); d->clearButton->setIcon(koIcon("edit-delete")); d->clearButton->setToolTip(i18n("Remove filter from object")); addFilterLayout->addWidget(d->clearButton, 0, 3); connect(d->clearButton, SIGNAL(clicked()), this, SLOT(clearFilter())); addFilterWidget->setWindowTitle(i18n("Add Filter")); widgets.append(addFilterWidget); //--------------------------------------------------------------------- QWidget *configFilterWidget = new QWidget(); configFilterWidget->setObjectName("ConfigEffect"); QGridLayout *configFilterLayout = new QGridLayout(configFilterWidget); d->configSelector = new KComboBox(configFilterWidget); configFilterLayout->addWidget(d->configSelector, 0, 0); connect(d->configSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); d->configStack = new QStackedWidget(configFilterWidget); configFilterLayout->addWidget(d->configStack, 1, 0); configFilterLayout->setContentsMargins(0, 0, 0, 0); configFilterWidget->setWindowTitle(i18n("Effect Properties")); widgets.append(configFilterWidget); //--------------------------------------------------------------------- QWidget *filterRegionWidget = new QWidget(); filterRegionWidget->setObjectName("EffectRegion"); QGridLayout *filterRegionLayout = new QGridLayout(filterRegionWidget); d->posX = new KisDoubleParseSpinBox(filterRegionWidget); d->posX->setSuffix(i18n("%")); connect(d->posX, SIGNAL(valueChanged(double)), this, SLOT(regionXChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("X:")), 0, 0); filterRegionLayout->addWidget(d->posX, 0, 1); d->posY = new KisDoubleParseSpinBox(filterRegionWidget); d->posY->setSuffix(i18n("%")); connect(d->posY, SIGNAL(valueChanged(double)), this, SLOT(regionYChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("Y:")), 1, 0); filterRegionLayout->addWidget(d->posY, 1, 1); d->posW = new KisDoubleParseSpinBox(filterRegionWidget); d->posW->setSuffix(i18n("%")); connect(d->posW, SIGNAL(valueChanged(double)), this, SLOT(regionWidthChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("W:")), 0, 2); filterRegionLayout->addWidget(d->posW, 0, 3); d->posH = new KisDoubleParseSpinBox(filterRegionWidget); d->posH->setSuffix(i18n("%")); connect(d->posH, SIGNAL(valueChanged(double)), this, SLOT(regionHeightChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("H:")), 1, 2); filterRegionLayout->addWidget(d->posH, 1, 3); filterRegionLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 2, 0); filterRegionLayout->setContentsMargins(0, 0, 0, 0); filterRegionWidget->setWindowTitle(i18n("Effect Region")); widgets.append(filterRegionWidget); //--------------------------------------------------------------------- d->fillConfigSelector(d->currentShape, this); return widgets; } diff --git a/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.cpp b/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.cpp index f5834aa983..43e767306f 100644 --- a/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.cpp +++ b/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.cpp @@ -1,184 +1,190 @@ /* This file is part of the KDE project * Copyright (C) 2008 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoResourceSelector.h" #include -#include #include -#include +#include #include #include #include #include #include #include #include #include class Q_DECL_HIDDEN KoResourceSelector::Private { public: Private() : displayMode(ImageMode) {} DisplayMode displayMode; KisResourceModel *model; - KisResourceGridProxyModel *proxyModel; void updateIndex( KoResourceSelector * me ) { KisResourceModel *resourceModel = qobject_cast(me->model()); if (!resourceModel) return; if (!resourceModel->rowCount()) return; int currentIndex = me->currentIndex(); QModelIndex currentModelIndex = me->view()->currentIndex(); if (currentIndex < 0 || !currentModelIndex.isValid()) { me->blockSignals(true); me->view()->setCurrentIndex( resourceModel->index( 0, 0 ) ); me->setCurrentIndex(0); me->blockSignals(false); me->update(); } } }; KoResourceSelector::KoResourceSelector(QWidget * parent ) : QComboBox(parent), d(new Private()) { - setView(new KisResourceItemView(this)); + setView(new KisResourceItemListView(this)); d->model = KisResourceModelProvider::resourceModel(ResourceType::FilterEffects); - d->proxyModel = new KisResourceGridProxyModel(this); - d->proxyModel->setSourceModel(d->model); - setModel(d->proxyModel); + setModel(d->model); setItemDelegate(new KisResourceItemDelegate(this)); setMouseTracking(true); d->updateIndex(this); connect( this, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) ); } KoResourceSelector::~KoResourceSelector() { delete d; } void KoResourceSelector::paintEvent( QPaintEvent *pe ) { QComboBox::paintEvent( pe ); if (d->displayMode == ImageMode) { QStyleOptionComboBox option; option.initFrom( this ); QRect r = style()->subControlRect( QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, this ); QStyleOptionViewItem viewOption; viewOption.initFrom( this ); viewOption.rect = r; QPainter painter( this ); itemDelegate()->paint( &painter, viewOption, view()->currentIndex() ); } } void KoResourceSelector::mousePressEvent( QMouseEvent * event ) { QStyleOptionComboBox opt; opt.initFrom( this ); opt.subControls = QStyle::SC_All; opt.activeSubControls = QStyle::SC_ComboBoxArrow; QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, mapFromGlobal(event->globalPos()), this); // only clicking on combobox arrow shows popup, // otherwise the resourceApplied signal is send with the current resource if (sc == QStyle::SC_ComboBoxArrow) QComboBox::mousePressEvent( event ); else { QModelIndex index = view()->currentIndex(); if( ! index.isValid() ) return; KoResourceSP resource = d->model->resourceForIndex(index); if (resource) { emit resourceApplied(resource); } } } void KoResourceSelector::mouseMoveEvent( QMouseEvent * event ) { QStyleOptionComboBox option; option.initFrom( this ); QRect r = style()->subControlRect( QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, this ); if (r.contains(event->pos())) setCursor(Qt::PointingHandCursor); else unsetCursor(); } void KoResourceSelector::setDisplayMode(DisplayMode mode) { if (mode == d->displayMode) return; switch(mode) { case ImageMode: setItemDelegate(new KisResourceItemDelegate(this)); - setView( new KisResourceItemView(this) ); + setView( new KisResourceItemListView(this) ); break; case TextMode: setItemDelegate(new QStyledItemDelegate(this)); setView(new QListView(this)); break; } d->displayMode = mode; d->updateIndex(this); } -void KoResourceSelector::setColumnCount( int columnCount ) -{ - d->proxyModel->setRowStride(columnCount); +void KoResourceSelector::setSingleColumn(bool singleColumn) { + qDebug() << "setting single column" << singleColumn; + KisResourceItemListView * listView = qobject_cast(view()); + if (!listView) return; + if (singleColumn) { + qDebug() << "resource item view exists and is set single column"; + listView->setViewMode(QListView::ListMode); + listView->setItemSize(QSize(listView->viewport()->width(),listView->iconSize().height())); + } else { + listView->setViewMode(QListView::IconMode); + listView->setItemSize(QSize(listView->iconSize().height(), listView->iconSize().height())); + } } void KoResourceSelector::setRowHeight( int rowHeight ) { - QTableView * tableView = qobject_cast(view()); - if (tableView) - tableView->verticalHeader()->setDefaultSectionSize( rowHeight ); + KisResourceItemListView * listView = qobject_cast(view()); + if (listView) { + listView->setItemSize(QSize(listView->iconSize().width(), rowHeight)); + } } void KoResourceSelector::indexChanged( int ) { QModelIndex index = view()->currentIndex(); if(!index.isValid()) { return; } - KoResourceSP resource = d->model->resourceForIndex(d->proxyModel->mapToSource(index)); + KoResourceSP resource = d->model->resourceForIndex(index); if (resource) { emit resourceSelected( resource ); } } diff --git a/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.h b/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.h index 20614720fb..78a5d38b33 100644 --- a/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.h +++ b/plugins/tools/karbonplugins/tools/filterEffectTool/KoResourceSelector.h @@ -1,81 +1,81 @@ /* This file is part of the KDE project * Copyright (C) 2008 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KORESOURCESELECTOR_H #define KORESOURCESELECTOR_H #include #include class QMouseEvent; class KoAbstractResourceServerAdapter; /** * A custom combobox widget for selecting resource items like gradients or patterns. */ class KoResourceSelector : public QComboBox { Q_OBJECT public: enum DisplayMode { ImageMode, ///< Displays image of resources (default) TextMode ///< Displays name of resources }; /** * Constructs a new resource selector. * @param parent the parent widget */ explicit KoResourceSelector(QWidget *parent = 0); /// Destroys the resource selector ~KoResourceSelector() override; /// Sets the display mode void setDisplayMode(DisplayMode mode); - /// Sets number of columns to display in the popup view - void setColumnCount( int columnCount ); + //Whether to use single column mode; + void setSingleColumn(bool singleColumn); /// Sets the height of the popup view rows void setRowHeight( int rowHeight ); Q_SIGNALS: /// Emitted when a resource was selected void resourceSelected( KoResourceSP resource ); /// Is emitted when the user has clicked on the current resource void resourceApplied( KoResourceSP resource ); protected: /// reimplemented void paintEvent( QPaintEvent * ) override; /// reimplemented void mousePressEvent( QMouseEvent * ) override; /// reimplemented void mouseMoveEvent( QMouseEvent * event ) override; private Q_SLOTS: void indexChanged( int index ); private: class Private; Private * const d; }; #endif // KORESOURCESELECTOR_H