diff --git a/libs/ui/kis_categorized_list_model.h b/libs/ui/kis_categorized_list_model.h index 9213ca6225..9acdabae24 100644 --- a/libs/ui/kis_categorized_list_model.h +++ b/libs/ui/kis_categorized_list_model.h @@ -1,249 +1,257 @@ /* * Copyright (c) 2013 Dmitry Kazakov * * 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_CATEGORIZED_LIST_MODEL_H #define __KIS_CATEGORIZED_LIST_MODEL_H #include #include #include "kis_categories_mapper.h" class KRITAUI_EXPORT __CategorizedListModelBase : public QAbstractListModel { Q_OBJECT public: enum AdditionalRoles { IsHeaderRole = Qt::UserRole + 1, ExpandCategoryRole = Qt::UserRole + 2, SortRole = Qt::UserRole + 3, isLockedRole = Qt::UserRole + 4, isLockableRole = Qt::UserRole + 5, isToggledRole = Qt::UserRole + 6 }; public: __CategorizedListModelBase(QObject *parent); ~__CategorizedListModelBase() override; private Q_SLOTS: void slotRowChanged(int row) { QModelIndex changedIndex(index(row)); emit dataChanged(changedIndex, changedIndex); } void slotBeginInsertRow(int row) { beginInsertRows(QModelIndex(), row, row); } void slotEndInsertRow() { endInsertRows(); } void slotBeginRemoveRow(int row) { beginRemoveRows(QModelIndex(), row, row); } void slotEndRemoveRow() { endRemoveRows(); } }; template class KisCategorizedListModel : public __CategorizedListModelBase { public: typedef TEntry Entry_Type; typedef KisCategoriesMapper SpecificCategoriesMapper; typedef typename SpecificCategoriesMapper::DataItem DataItem; public: KisCategorizedListModel(QObject *parent = 0) : __CategorizedListModelBase(parent) { - connect(&m_mapper, SIGNAL(rowChanged(int)), SLOT(slotRowChanged(int))); + connect(&m_mapper, SIGNAL(rowChanged(int)), SLOT(slotRowChanged(int))); // helps with category expand menu connect(&m_mapper, SIGNAL(beginInsertRow(int)), SLOT(slotBeginInsertRow(int))); connect(&m_mapper, SIGNAL(endInsertRow()), SLOT(slotEndInsertRow())); connect(&m_mapper, SIGNAL(beginRemoveRow(int)), SLOT(slotBeginRemoveRow(int))); connect(&m_mapper, SIGNAL(endRemoveRow()), SLOT(slotEndRemoveRow())); + + + } int rowCount(const QModelIndex& parent) const override { Q_UNUSED(parent); return m_mapper.rowCount(); } QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const override { if (!idx.isValid()) return QVariant(); typename SpecificCategoriesMapper::DataItem *item = m_mapper.itemFromRow(idx.row()); Q_ASSERT(item); switch (role) { case IsHeaderRole: return item->isCategory(); case ExpandCategoryRole: return item->isCategory() ? item->isExpanded() : item->parentCategory()->isExpanded(); case Qt::ToolTipRole: case Qt::DisplayRole: return item->name(); case Qt::CheckStateRole: return item->isCheckable() ? item->isChecked() ? Qt::Checked : Qt::Unchecked : QVariant(); case SortRole: return item->isCategory() ? item->name() : item->parentCategory()->name() + item->name(); case isLockedRole: return item->isLocked(); case isLockableRole: return item->isLockable(); case isToggledRole: return item->isToggled(); } return QVariant(); } bool setData(const QModelIndex& idx, const QVariant& value, int role = Qt::EditRole) override { if (!idx.isValid()) return false; typename SpecificCategoriesMapper::DataItem *item = m_mapper.itemFromRow(idx.row()); Q_ASSERT(item); switch (role) { case ExpandCategoryRole: Q_ASSERT(item->isCategory()); item->setExpanded(value.toBool()); break; case Qt::CheckStateRole: Q_ASSERT(item->isCheckable()); - item->setChecked(value.toInt() == Qt::Checked); - break; + item->setChecked(value.toInt() == Qt::Checked); + break; } + // dataChanged() needs a QVector even though we are just passing one + QVector roles; + roles.append(role); + + emit dataChanged(idx, idx, roles); return true; } Qt::ItemFlags flags(const QModelIndex& idx) const override { if (!idx.isValid()) return Qt::NoItemFlags; typename SpecificCategoriesMapper::DataItem *item = m_mapper.itemFromRow(idx.row()); Q_ASSERT(item); Qt::ItemFlags flags = Qt::NoItemFlags; if (item->isEnabled()) { flags |= Qt::ItemIsEnabled; } if (!item->isCategory()) { flags |= Qt::ItemIsSelectable; if (item->isCheckable()) { flags |= Qt::ItemIsUserCheckable; } } return flags; } QModelIndex indexOf(const TEntry& entry) const { typename SpecificCategoriesMapper::DataItem *item = m_mapper.fetchOneEntry(entry); return index(m_mapper.rowFromItem(item)); } bool entryAt(TEntry& entry, QModelIndex index) const { int row = index.row(); if (row < 0 || row >= m_mapper.rowCount()) return false; typename SpecificCategoriesMapper::DataItem *item = m_mapper.itemFromRow(row); if (!item->isCategory()) { entry = *item->data(); return true; } return false; } SpecificCategoriesMapper* categoriesMapper() { return &m_mapper; } const SpecificCategoriesMapper* categoriesMapper() const { return &m_mapper; } private: SpecificCategoriesMapper m_mapper; }; template class KRITAUI_EXPORT KisSortedCategorizedListModel : public QSortFilterProxyModel { typedef typename TModel::Entry_Type Entry_Type; public: KisSortedCategorizedListModel(QObject *parent) : QSortFilterProxyModel(parent) { } QModelIndex indexOf(const Entry_Type& entry) const { QModelIndex srcIndex = m_model->indexOf(entry); return mapFromSource(srcIndex); } bool entryAt(Entry_Type &entry, QModelIndex index) const { QModelIndex srcIndex = mapToSource(index); return m_model->entryAt(entry, srcIndex); } protected: void initializeModel(TModel *model) { m_model = model; setSourceModel(model); setSortRole(TModel::SortRole); } bool lessThanPriority(const QModelIndex &left, const QModelIndex &right, const QString &priorityCategory) const { QString leftKey = sourceModel()->data(left, sortRole()).toString(); QString rightKey = sourceModel()->data(right, sortRole()).toString(); bool leftIsSpecial = leftKey.startsWith(priorityCategory); bool rightIsSpecial = rightKey.startsWith(priorityCategory); return leftIsSpecial != rightIsSpecial ? leftIsSpecial : leftKey < rightKey; } private: TModel *m_model; }; #endif /* __KIS_CATEGORIZED_LIST_MODEL_H */ diff --git a/libs/ui/kis_paintop_settings_widget.cpp b/libs/ui/kis_paintop_settings_widget.cpp index 3131a154b8..68281cbfcb 100644 --- a/libs/ui/kis_paintop_settings_widget.cpp +++ b/libs/ui/kis_paintop_settings_widget.cpp @@ -1,245 +1,247 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * Copyright (C) Silvio Heinrich , (C) 2011 * * 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_paintop_settings_widget.h" #include "kis_paintop_option.h" #include "kis_paintop_options_model.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct KisPaintOpSettingsWidget::Private { QList paintOpOptions; KisCategorizedListView* optionsList; KisPaintOpOptionListModel* model; QStackedWidget* optionsStack; }; KisPaintOpSettingsWidget::KisPaintOpSettingsWidget(QWidget * parent) : KisPaintOpConfigWidget(parent) , m_d(new Private()) { setObjectName("KisPaintOpPresetsWidget"); m_d->model = new KisPaintOpOptionListModel(this); - m_d->optionsList = new KisCategorizedListView(false, this); + m_d->optionsList = new KisCategorizedListView(this); m_d->optionsList->setModel(m_d->model); m_d->optionsList->setItemDelegate(new KisCategorizedItemDelegate(m_d->optionsList)); m_d->optionsList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); m_d->optionsList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QSizePolicy policy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); m_d->optionsList->setSizePolicy(policy); m_d->optionsList->setMinimumWidth(140); // this should be just big enough to show all of the setting names m_d->optionsStack = new QStackedWidget(this); policy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_d->optionsStack->setSizePolicy(policy); QHBoxLayout* layout = new QHBoxLayout(this); layout->addWidget(m_d->optionsList); layout->addWidget(m_d->optionsStack); layout->setStretch(0, 0); layout->setStretch(1, 1); m_saveLockedOption = false; connect(m_d->optionsList, SIGNAL(activated(const QModelIndex&)), this, SLOT(changePage(const QModelIndex&))); connect(m_d->optionsList, SIGNAL(clicked(QModelIndex)), this, SLOT(changePage(const QModelIndex&))); - connect(m_d->optionsList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(lockProperties(const QModelIndex&))); connect(m_d->optionsList, SIGNAL(rightClickedMenuDropSettingsTriggered()), this, SLOT(slotLockPropertiesDrop())); connect(m_d->optionsList, SIGNAL(rightClickedMenuSaveSettingsTriggered()), this, SLOT(slotLockPropertiesSave())); connect(m_d->optionsList, SIGNAL(sigEntryChecked(QModelIndex)), this, SLOT(slotEntryChecked(QModelIndex))); + connect (m_d->optionsList, SIGNAL(lockAreaTriggered(QModelIndex)), this, SLOT(lockProperties(const QModelIndex&))); } KisPaintOpSettingsWidget::~KisPaintOpSettingsWidget() { qDeleteAll(m_d->paintOpOptions); delete m_d; } void KisPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, const QString &label) { addPaintOpOption(option, label, option->category()); } void KisPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, const QString &label, KisPaintOpOption::PaintopCategory category) { if (!option->configurationPage()) return; m_d->model->addPaintOpOption(option, m_d->optionsStack->count(), label, category); connect(option, SIGNAL(sigSettingChanged()), SIGNAL(sigConfigurationItemChanged())); m_d->optionsStack->addWidget(option->configurationPage()); m_d->paintOpOptions << option; } void KisPaintOpSettingsWidget::setConfiguration(const KisPropertiesConfigurationSP config) { Q_ASSERT(!config->getString("paintop").isEmpty()); KisLockedPropertiesProxySP propertiesProxy = KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(config); int indexcount = 0; Q_FOREACH (KisPaintOpOption* option, m_d->paintOpOptions) { option->startReadOptionSetting(propertiesProxy); if (KisLockedPropertiesServer::instance()->propertiesFromLocked()) { option->setLocked(true); } else { option->setLocked(false); } KisLockedPropertiesServer::instance()->setPropertiesFromLocked(false); KisOptionInfo info; info.option = option; info.index = indexcount; m_d->model->categoriesMapper()->itemFromRow(m_d->model->indexOf(info).row())->setLocked(option->isLocked()); m_d->model->categoriesMapper()->itemFromRow(m_d->model->indexOf(info).row())->setLockable(true); m_d->model->signalDataChanged(m_d->model->indexOf(info)); indexcount++; } } void KisPaintOpSettingsWidget::writeConfiguration(KisPropertiesConfigurationSP config) const { KisLockedPropertiesProxySP propertiesProxy = KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(config); Q_FOREACH (const KisPaintOpOption* option, m_d->paintOpOptions) { option->startWriteOptionSetting(propertiesProxy); } } KisPaintopLodLimitations KisPaintOpSettingsWidget::lodLimitations() const { KisPaintopLodLimitations l; Q_FOREACH (const KisPaintOpOption* option, m_d->paintOpOptions) { if (option->isCheckable() && !option->isChecked()) continue; option->lodLimitations(&l); } return l; } void KisPaintOpSettingsWidget::setImage(KisImageWSP image) { Q_FOREACH (KisPaintOpOption* option, m_d->paintOpOptions) { option->setImage(image); } } void KisPaintOpSettingsWidget::setNode(KisNodeWSP node) { Q_FOREACH (KisPaintOpOption* option, m_d->paintOpOptions) { option->setNode(node); } } void KisPaintOpSettingsWidget::changePage(const QModelIndex& index) { KisOptionInfo info; QPalette palette; palette.setColor(QPalette::Base, QColor(255,200,200)); palette.setColor(QPalette::Text, Qt::black); if(m_d->model->entryAt(info, index)) { m_d->optionsStack->setCurrentIndex(info.index); // disable the widget if a setting area is not active and not being used if (info.option->isCheckable() ) { m_d->optionsStack->setEnabled(info.option->isChecked()); } else { m_d->optionsStack->setEnabled(true); // option is not checkable, so always enable } } notifyPageChanged(); } void KisPaintOpSettingsWidget::notifyPageChanged() { } void KisPaintOpSettingsWidget::lockProperties(const QModelIndex& index) { KisOptionInfo info; if (m_d->model->entryAt(info, index)) { m_d->optionsList->setCurrentIndex(index); KisPropertiesConfigurationSP p = new KisPropertiesConfiguration(); info.option->startWriteOptionSetting(p); if (!info.option->isLocked()){ KisLockedPropertiesServer::instance()->addToLockedProperties(p); info.option->setLocked(true); m_d->model->categoriesMapper()->itemFromRow(index.row())->setLocked(true); + } else { KisLockedPropertiesServer::instance()->removeFromLockedProperties(p); info.option->setLocked(false); m_d->model->categoriesMapper()->itemFromRow(index.row())->setLocked(false); + if (m_saveLockedOption){ emit sigSaveLockedConfig(p); } else { emit sigDropLockedConfig(p); } m_saveLockedOption = false; } m_d->model->signalDataChanged(index); } } void KisPaintOpSettingsWidget::slotLockPropertiesDrop() { m_saveLockedOption = false; lockProperties(m_d->optionsList->currentIndex()); } void KisPaintOpSettingsWidget::slotLockPropertiesSave() { m_saveLockedOption = true; lockProperties(m_d->optionsList->currentIndex()); } void KisPaintOpSettingsWidget::slotEntryChecked(const QModelIndex &index) { Q_UNUSED(index); emit sigConfigurationItemChanged(); } diff --git a/libs/ui/widgets/kis_categorized_list_view.cpp b/libs/ui/widgets/kis_categorized_list_view.cpp index 65311b4c3a..d2f9a94407 100644 --- a/libs/ui/widgets/kis_categorized_list_view.cpp +++ b/libs/ui/widgets/kis_categorized_list_view.cpp @@ -1,148 +1,142 @@ /* * Copyright (c) 2011 Silvio Heinrich * * 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_categorized_list_view.h" #include "kis_categorized_list_model.h" #include #include #include #include #include #include #include #include "kis_debug.h" -KisCategorizedListView::KisCategorizedListView(bool useCheckBoxHack, QWidget* parent): - QListView(parent), m_useCheckBoxHack(useCheckBoxHack) +KisCategorizedListView::KisCategorizedListView(QWidget* parent): + QListView(parent) { connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(slotIndexChanged(QModelIndex))); } KisCategorizedListView::~KisCategorizedListView() { } void KisCategorizedListView::setModel(QAbstractItemModel* model) { QListView::setModel(model); updateRows(0, model->rowCount()); model->sort(0); } QSize KisCategorizedListView::sizeHint() const { const QSize sh = QListView::sizeHint(); const int width = sizeHintForColumn(0); return QSize(width, sh.height()); } void KisCategorizedListView::updateRows(int begin, int end) { for(; begin!=end; ++begin) { QModelIndex index = model()->index(begin, 0); bool isHeader = model()->data(index, __CategorizedListModelBase::IsHeaderRole).toBool(); bool expanded = model()->data(index, __CategorizedListModelBase::ExpandCategoryRole).toBool(); setRowHidden(begin, !expanded && !isHeader); } } void KisCategorizedListView::slotIndexChanged(const QModelIndex& index) { if(model()->data(index, __CategorizedListModelBase::IsHeaderRole).toBool()) { bool expanded = model()->data(index, __CategorizedListModelBase::ExpandCategoryRole).toBool(); model()->setData(index, !expanded, __CategorizedListModelBase::ExpandCategoryRole); emit sigCategoryToggled(index, !expanded); } } -void KisCategorizedListView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector &/*roles*/) +void KisCategorizedListView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector &roles) { QListView::dataChanged(topLeft, bottomRight); updateRows(topLeft.row(), bottomRight.row()+1); + + // check to see if the data changed was a check box + // if it is a checkbox tell the brush edtor that the preset is now "dirty" + int i = 0; + for (QVector::const_iterator iterator = roles.begin(); iterator != roles.end(); ++iterator) { + + if (Qt::CheckStateRole == roles.at(i) ) { + int row = topLeft.row(); + int column = topLeft.column(); + + emit sigEntryChecked(model()->index(row, column)); + } else if (__CategorizedListModelBase::ExpandCategoryRole == roles.at(i)) { + // logic to target the expand/contract menus if needed + } + + i++; + } } void KisCategorizedListView::rowsInserted(const QModelIndex& parent, int start, int end) { QListView::rowsInserted(parent, start, end); updateRows(0, model()->rowCount()); model()->sort(0); } void KisCategorizedListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { QListView::rowsAboutToBeRemoved(parent, start, end); model()->sort(0); } void KisCategorizedListView::mousePressEvent(QMouseEvent* event) { - if (m_useCheckBoxHack) { - QModelIndex index = QListView::indexAt(event->pos()); - if (index.isValid() && (event->pos().x() < 25) && (model()->flags(index) & Qt::ItemIsUserCheckable)) { - QListView::mousePressEvent(event); - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, - event->pos(), - event->globalPos(), - event->button(), - event->button() | event->buttons(), - event->modifiers()); - - QListView::mouseReleaseEvent(&releaseEvent); - emit sigEntryChecked(index); - return; - } - - } - QListView::mousePressEvent(event); if(event->button() == Qt::RightButton){ QModelIndex index = QListView::indexAt(event->pos()); QMenu menu(this); if(index.data(__CategorizedListModelBase::isLockableRole).toBool() && index.isValid()) { bool locked = index.data(__CategorizedListModelBase::isLockedRole).toBool(); QIcon icon = locked ? KisIconUtils::loadIcon("locked") : KisIconUtils::loadIcon("unlocked"); QAction* action1 = menu.addAction(icon, locked ? i18n("Unlock (restore settings from preset)") : i18n("Lock")); connect(action1, SIGNAL(triggered()), this, SIGNAL(rightClickedMenuDropSettingsTriggered())); if (locked){ QAction* action2 = menu.addAction(icon, i18n("Unlock (keep current settings)")); connect(action2, SIGNAL(triggered()), this, SIGNAL(rightClickedMenuSaveSettingsTriggered())); } menu.exec(event->globalPos()); } } } void KisCategorizedListView::mouseReleaseEvent(QMouseEvent* event) { QListView::mouseReleaseEvent(event); - - QModelIndex index = QListView::indexAt(event->pos()); - if(index.data(__CategorizedListModelBase::isToggledRole).toBool() && index.isValid()){ - emit sigEntryChecked(index); - } } diff --git a/libs/ui/widgets/kis_categorized_list_view.h b/libs/ui/widgets/kis_categorized_list_view.h index 4c71591774..bcc7a51e5b 100644 --- a/libs/ui/widgets/kis_categorized_list_view.h +++ b/libs/ui/widgets/kis_categorized_list_view.h @@ -1,63 +1,59 @@ /* * Copyright (c) 2011 Silvio Heinrich * * 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_CATEGORIZED_LIST_VIEW_H_ #define KIS_CATEGORIZED_LIST_VIEW_H_ #include #include #include class KRITAUI_EXPORT KisCategorizedListView: public QListView { Q_OBJECT public: - KisCategorizedListView(bool useCheckBoxHack=false, QWidget* parent=0); + KisCategorizedListView(QWidget* parent=0); ~KisCategorizedListView() override; void setModel(QAbstractItemModel* model) override; QSize sizeHint() const override; Q_SIGNALS: void sigCategoryToggled(const QModelIndex& index, bool toggled); void sigEntryChecked(const QModelIndex& index); void rightClickedMenuDropSettingsTriggered(); void rightClickedMenuSaveSettingsTriggered(); - + void lockAreaTriggered(const QModelIndex& index); protected Q_SLOTS: void slotIndexChanged(const QModelIndex& index); void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector &roles = QVector()) override; void rowsInserted(const QModelIndex& parent, int start, int end) override; void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; private: void updateRows(int begin, int end); - -private: - bool m_useCheckBoxHack; - }; #endif // KIS_CATEGORIZED_LIST_VIEW_H_ diff --git a/libs/ui/widgets/kis_cmb_composite.cc b/libs/ui/widgets/kis_cmb_composite.cc index 4b243b0c7f..985ce4f995 100644 --- a/libs/ui/widgets/kis_cmb_composite.cc +++ b/libs/ui/widgets/kis_cmb_composite.cc @@ -1,481 +1,481 @@ /* * kis_cmb_composite.cc - part of KImageShop/Krayon/Krita * * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) * Copyright (c) 2011 Silvio Heinrich * * 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_cmb_composite.h" #include #include #include "kis_composite_ops_model.h" #include "kis_categorized_item_delegate.h" #include ////////////////////////////////////////////////////////////////////////////////////////// // ---- KisCompositeOpListWidget ------------------------------------------------------ // KisCompositeOpListWidget::KisCompositeOpListWidget(QWidget* parent): - KisCategorizedListView(false, parent), + KisCategorizedListView(parent), m_model(new KisSortedCompositeOpListModel(this)) { setModel(m_model); setItemDelegate(new KisCategorizedItemDelegate(this)); } KisCompositeOpListWidget::~KisCompositeOpListWidget() { } KoID KisCompositeOpListWidget::selectedCompositeOp() const { KoID op; if (m_model->entryAt(op, currentIndex())) { return op; } return KoCompositeOpRegistry::instance().getDefaultCompositeOp(); } ////////////////////////////////////////////////////////////////////////////////////////// // ---- KisCompositeOpComboBox -------------------------------------------------------- // KisCompositeOpComboBox::KisCompositeOpComboBox(QWidget* parent): QComboBox(parent), m_model(new KisSortedCompositeOpListModel(this)), m_allowToHidePopup(true) { - m_view = new KisCategorizedListView(true); + m_view = new KisCategorizedListView(); setMaxVisibleItems(100); setSizeAdjustPolicy(AdjustToContents); m_view->setResizeMode(QListView::Adjust); setToolTip(i18n("Blending Mode")); setModel(m_model); setView(m_view); setItemDelegate(new KisCategorizedItemDelegate(this)); connect(m_view, SIGNAL(sigCategoryToggled(const QModelIndex&, bool)), SLOT(slotCategoryToggled(const QModelIndex&, bool))); connect(m_view, SIGNAL(sigEntryChecked(const QModelIndex&)), SLOT(slotEntryChecked(const QModelIndex&))); selectCompositeOp(KoCompositeOpRegistry::instance().getDefaultCompositeOp()); KisAction *action = 0; // // Cycle through blending modes // // Shift + + (plus) or – (minus) // KisAction *action = new KisAction(i18n("Next Blending Mode"), this); // action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Plus)); // connect(action, SIGNAL(triggered()), SLOT(slotNextBlendingMode())); // m_actions << action; // action = new KisAction(i18n("Previous Blending Mode"), this); // action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Minus)); // connect(action, SIGNAL(triggered()), SLOT(slotPreviousBlendingMode())); // m_actions << action; // Normal // Shift + Alt + N action = new KisAction(i18n("Select Normal Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_N)); connect(action, SIGNAL(triggered()), SLOT(slotNormal())); m_actions << action; // Dissolve // Shift + Alt + I action = new KisAction(i18n("Select Dissolve Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_I)); connect(action, SIGNAL(triggered()), SLOT(slotDissolve())); m_actions << action; // Behind (Brush tool only) // Shift + Alt + Q action = new KisAction(i18n("Select Behind Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Q)); connect(action, SIGNAL(triggered()), SLOT(slotBehind())); m_actions << action; // Clear (Brush tool only) // Shift + Alt + R action = new KisAction(i18n("Select Clear Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_R)); connect(action, SIGNAL(triggered()), SLOT(slotClear())); m_actions << action; // Darken // Shift + Alt + K action = new KisAction(i18n("Select Darken Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_K)); connect(action, SIGNAL(triggered()), SLOT(slotDarken())); m_actions << action; // Multiply // Shift + Alt + M action = new KisAction(i18n("Select Multiply Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_M)); connect(action, SIGNAL(triggered()), SLOT(slotMultiply())); m_actions << action; // Color Burn // Shift + Alt + B action = new KisAction(i18n("Select Color Burn Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_B)); connect(action, SIGNAL(triggered()), SLOT(slotColorBurn())); m_actions << action; // Linear Burn // Shift + Alt + A action = new KisAction(i18n("Select Linear Burn Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_A)); connect(action, SIGNAL(triggered()), SLOT(slotLinearBurn())); m_actions << action; // Lighten // Shift + Alt + G action = new KisAction(i18n("Select Lighten Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_G)); connect(action, SIGNAL(triggered()), SLOT(slotLighten())); m_actions << action; // Screen // Shift + Alt + S action = new KisAction(i18n("Select Screen Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_S)); connect(action, SIGNAL(triggered()), SLOT(slotScreen())); m_actions << action; // Color Dodge // Shift + Alt + D action = new KisAction(i18n("Select Color Dodge Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_D)); connect(action, SIGNAL(triggered()), SLOT(slotColorDodge())); m_actions << action; // Linear Dodge // Shift + Alt + W action = new KisAction(i18n("Select Linear Dodge Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_W)); connect(action, SIGNAL(triggered()), SLOT(slotLinearDodge())); m_actions << action; // Overlay // Shift + Alt + O action = new KisAction(i18n("Select Overlay Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_O)); connect(action, SIGNAL(triggered()), SLOT(slotOverlay())); m_actions << action; // Hard Overlay // Shift + Alt + P action = new KisAction(i18n("Select Hard Overlay Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_P)); connect(action, SIGNAL(triggered()), SLOT(slotHardOverlay())); m_actions << action; // Soft Light // Shift + Alt + F action = new KisAction(i18n("Select Soft Light Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_F)); connect(action, SIGNAL(triggered()), SLOT(slotSoftLight())); m_actions << action; // Hard Light // Shift + Alt + H action = new KisAction(i18n("Select Hard Light Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_H)); connect(action, SIGNAL(triggered()), SLOT(slotHardLight())); m_actions << action; // Vivid Light // Shift + Alt + V action = new KisAction(i18n("Select Vivid Light Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_V)); connect(action, SIGNAL(triggered()), SLOT(slotVividLight())); m_actions << action; // Linear Light // Shift + Alt + J action = new KisAction(i18n("Select Linear Light Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_J)); connect(action, SIGNAL(triggered()), SLOT(slotLinearLight())); m_actions << action; // Pin Light // Shift + Alt + Z action = new KisAction(i18n("Select Pin Light Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Z)); connect(action, SIGNAL(triggered()), SLOT(slotPinLight())); m_actions << action; // Hard Mix // Shift + Alt + L action = new KisAction(i18n("Select Hard Mix Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_L)); connect(action, SIGNAL(triggered()), SLOT(slotHardMix())); m_actions << action; // Difference // Shift + Alt + E action = new KisAction(i18n("Select Difference Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_E)); connect(action, SIGNAL(triggered()), SLOT(slotDifference())); m_actions << action; // Exclusion // Shift + Alt + X action = new KisAction(i18n("Select Exclusion Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_X)); connect(action, SIGNAL(triggered()), SLOT(slotExclusion())); m_actions << action; // Hue // Shift + Alt + U action = new KisAction(i18n("Select Hue Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_U)); connect(action, SIGNAL(triggered()), SLOT(slotHue())); m_actions << action; // Saturation // Shift + Alt + T action = new KisAction(i18n("Select Saturation Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_T)); connect(action, SIGNAL(triggered()), SLOT(slotSaturation())); m_actions << action; // Color // Shift + Alt + C action = new KisAction(i18n("Select Color Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_C)); connect(action, SIGNAL(triggered()), SLOT(slotColor())); m_actions << action; // Luminosity // Shift + Alt + Y action = new KisAction(i18n("Select Luminosity Blending Mode"), this); action->setDefaultShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Y)); connect(action, SIGNAL(triggered()), SLOT(slotLuminosity())); m_actions << action; } KisCompositeOpComboBox::~KisCompositeOpComboBox() { delete m_view; } void KisCompositeOpComboBox::validate(const KoColorSpace *cs) { m_model->validate(cs); } void KisCompositeOpComboBox::selectCompositeOp(const KoID &op) { QModelIndex index = m_model->indexOf(op); setCurrentIndex(index.row()); } KoID KisCompositeOpComboBox::selectedCompositeOp() const { KoID op; if (m_model->entryAt(op, m_model->index(currentIndex(), 0))) { return op; } return KoCompositeOpRegistry::instance().getDefaultCompositeOp(); } QList KisCompositeOpComboBox::blendmodeActions() const { return m_actions; } void KisCompositeOpComboBox::slotCategoryToggled(const QModelIndex& index, bool toggled) { Q_UNUSED(index); Q_UNUSED(toggled); //NOTE: this will (should) fit the size of the // popup widget to the view // don't know if this is expected behaviour // on all supported platforms. // Thre is nothing written about this in the docs. showPopup(); } void KisCompositeOpComboBox::slotEntryChecked(const QModelIndex& index) { Q_UNUSED(index); m_allowToHidePopup = false; } void KisCompositeOpComboBox::hidePopup() { if (m_allowToHidePopup) { QComboBox::hidePopup(); } else { QComboBox::showPopup(); } m_allowToHidePopup = true; } void KisCompositeOpComboBox::slotNextBlendingMode() { if (currentIndex() < count()) { setCurrentIndex(currentIndex() + 1); } } void KisCompositeOpComboBox::slotPreviousBlendingMode() { if (currentIndex() > 0) { setCurrentIndex(currentIndex() - 1); } } void KisCompositeOpComboBox::slotNormal() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_OVER)); } void KisCompositeOpComboBox::slotDissolve() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_DISSOLVE)); } void KisCompositeOpComboBox::slotBehind() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_BEHIND)); } void KisCompositeOpComboBox::slotClear() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_CLEAR)); } void KisCompositeOpComboBox::slotDarken() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_DARKEN)); } void KisCompositeOpComboBox::slotMultiply() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_MULT)); } void KisCompositeOpComboBox::slotColorBurn() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_BURN)); } void KisCompositeOpComboBox::slotLinearBurn() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_LINEAR_BURN)); } void KisCompositeOpComboBox::slotLighten() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_LIGHTEN)); } void KisCompositeOpComboBox::slotScreen() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_SCREEN)); } void KisCompositeOpComboBox::slotColorDodge() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_DODGE)); } void KisCompositeOpComboBox::slotLinearDodge() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_LINEAR_DODGE)); } void KisCompositeOpComboBox::slotOverlay() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_OVERLAY)); } void KisCompositeOpComboBox::slotHardOverlay() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HARD_OVERLAY)); } void KisCompositeOpComboBox::slotSoftLight() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_SOFT_LIGHT_PHOTOSHOP)); } void KisCompositeOpComboBox::slotHardLight() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HARD_LIGHT)); } void KisCompositeOpComboBox::slotVividLight() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_VIVID_LIGHT)); } void KisCompositeOpComboBox::slotLinearLight() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_LINEAR_LIGHT)); } void KisCompositeOpComboBox::slotPinLight() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_PIN_LIGHT)); } void KisCompositeOpComboBox::slotHardMix() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HARD_MIX_PHOTOSHOP)); } void KisCompositeOpComboBox::slotDifference() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_DIFF)); } void KisCompositeOpComboBox::slotExclusion() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_EXCLUSION)); } void KisCompositeOpComboBox::slotHue() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HUE)); } void KisCompositeOpComboBox::slotSaturation() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_SATURATION)); } void KisCompositeOpComboBox::slotColor() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_COLOR)); } void KisCompositeOpComboBox::slotLuminosity() { selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_LUMINIZE)); } diff --git a/libs/ui/widgets/kis_paintop_list_widget.cpp b/libs/ui/widgets/kis_paintop_list_widget.cpp index 6b3ef970f8..e63a0ebcf9 100644 --- a/libs/ui/widgets/kis_paintop_list_widget.cpp +++ b/libs/ui/widgets/kis_paintop_list_widget.cpp @@ -1,80 +1,80 @@ /* * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) * Copyright (c) 2010 Lukáš Tvrdý * Copyright (c) 2011 Silvio Heinrich * * 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_paintop_list_widget.h" #include #include #include #include "../kis_paint_ops_model.h" #include "../kis_categorized_item_delegate.h" #include KisPaintOpListWidget::KisPaintOpListWidget(QWidget* parent, const char* name): - KisCategorizedListView(false, parent), + KisCategorizedListView(parent), m_model(new KisSortedPaintOpListModel(this)) { setObjectName(name); connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(slotOpActivated(QModelIndex))); setModel(m_model); setItemDelegate(new KisCategorizedItemDelegate(this)); } KisPaintOpListWidget::~KisPaintOpListWidget() { } void KisPaintOpListWidget::setPaintOpList(const QList& list) { m_model->fill(list); } QString KisPaintOpListWidget::itemAt(int idx) const { KisPaintOpInfo info; if(m_model->entryAt(info, m_model->index(idx, 0))) return info.id; return ""; } QString KisPaintOpListWidget::currentItem() const { return itemAt(currentIndex().row()); } void KisPaintOpListWidget::setCurrent(const KisPaintOpFactory* op) { setCurrentIndex(m_model->indexOf(KisPaintOpInfo(op->id()))); } void KisPaintOpListWidget::setCurrent(const QString& paintOpId) { setCurrentIndex(m_model->indexOf(KisPaintOpInfo(paintOpId))); } void KisPaintOpListWidget::slotOpActivated(const QModelIndex& index) { emit activated(itemAt(index.row())); }