diff --git a/libs/ui/recorder/kis_recorded_filter_action_editor.cc b/libs/ui/recorder/kis_recorded_filter_action_editor.cc index 7866f18e76..782454dd83 100644 --- a/libs/ui/recorder/kis_recorded_filter_action_editor.cc +++ b/libs/ui/recorder/kis_recorded_filter_action_editor.cc @@ -1,94 +1,94 @@ /* * Copyright (c) 2009 Cyrille Berger * * 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_recorded_filter_action_editor.h" #include #include #include #include #include #include #include #include "kis_node_query_path_editor.h" #include KisRecordedFilterActionEditor::KisRecordedFilterActionEditor(QWidget* parent, KisRecordedAction* action) : QWidget(parent), m_action(dynamic_cast(action)), m_gridLayout(new QGridLayout(this)) { Q_ASSERT(m_action); // Create the node query path editor m_nodeQueryPathEditor = new KisNodeQueryPathEditor(this); m_nodeQueryPathEditor->setNodeQueryPath(m_action->nodeQueryPath()); connect(m_nodeQueryPathEditor, SIGNAL(nodeQueryPathChanged()), SLOT(nodeQueryPathChanged())); m_gridLayout->addWidget(m_nodeQueryPathEditor, 1, 0); // Create the filter editor m_configWidget = m_action->filter()->createConfigurationWidget(this, 0); if (m_configWidget) { m_gridLayout->addWidget(m_configWidget); // FIXME: pass the view object to the config widget //m_configWidget->setView(view); m_configWidget->setConfiguration(m_action->filterConfiguration()); connect(m_configWidget, SIGNAL(sigConfigurationItemChanged()), SLOT(configurationUpdated())); } else { - m_gridLayout->addWidget(new QLabel("No configuration option.", this)); + m_gridLayout->addWidget(new QLabel(i18n("No configuration option."), this)); } } KisRecordedFilterActionEditor::~KisRecordedFilterActionEditor() { } void KisRecordedFilterActionEditor::configurationUpdated() { KisFilterConfiguration* config = dynamic_cast(m_configWidget->configuration()); if (config) { m_action->setFilterConfiguration(config); emit(actionEdited()); } } void KisRecordedFilterActionEditor::nodeQueryPathChanged() { m_action->setNodeQueryPath(m_nodeQueryPathEditor->nodeQueryPath()); emit(actionEdited()); } KisRecordedFilterActionEditorFactory::KisRecordedFilterActionEditorFactory() { } KisRecordedFilterActionEditorFactory::~KisRecordedFilterActionEditorFactory() { } QWidget* KisRecordedFilterActionEditorFactory::createEditor(QWidget* parent, KisRecordedAction* action) const { return new KisRecordedFilterActionEditor(parent, action); } bool KisRecordedFilterActionEditorFactory::canEdit(const KisRecordedAction* action) const { return action->id() == "FilterAction"; } diff --git a/libs/ui/recorder/kis_recorded_paint_action_editor.cc b/libs/ui/recorder/kis_recorded_paint_action_editor.cc index 2b0023ff60..d336a2efd2 100644 --- a/libs/ui/recorder/kis_recorded_paint_action_editor.cc +++ b/libs/ui/recorder/kis_recorded_paint_action_editor.cc @@ -1,176 +1,176 @@ /* * Copyright (c) 2010 Cyrille Berger * * 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_recorded_paint_action_editor.h" #include #include #include #include #include "recorder/kis_recorded_paint_action.h" #include #include #include #include "ui_wdgpaintactioneditor.h" #include #include #include "kis_node_query_path_editor.h" #include KisRecordedPaintActionEditor::KisRecordedPaintActionEditor(QWidget* parent, KisRecordedAction* action) : QWidget(parent), m_action(dynamic_cast(action)), m_actionEditor(new Ui_WdgPaintActionEditor), m_configWidget(0) { Q_ASSERT(m_action); m_actionEditor->setupUi(this); // Setup paint color editor m_paintColorPopup = new KoColorPopupAction(this); m_paintColorPopup->setCurrentColor(m_action->paintColor()); m_actionEditor->paintColor->setDefaultAction(m_paintColorPopup); connect(m_paintColorPopup, SIGNAL(colorChanged(const KoColor &)), this, SLOT(configurationUpdated())); // Setup background color editor m_backgroundColorPopup = new KoColorPopupAction(this); m_backgroundColorPopup->setCurrentColor(m_action->backgroundColor()); m_actionEditor->backgroundColor->setDefaultAction(m_backgroundColorPopup); connect(m_backgroundColorPopup, SIGNAL(colorChanged(const KoColor &)), this, SLOT(configurationUpdated())); // Setup opacity m_actionEditor->opacity->setValue(m_action->opacity() * 100.0); connect(m_actionEditor->opacity, SIGNAL(valueChanged(int)), SLOT(configurationUpdated())); // Setup paint ops QList keys = KisPaintOpRegistry::instance()->listKeys(); Q_FOREACH (const KoID& paintopId, keys) { QString pixmapName = KisPaintOpRegistry::instance()->pixmap(paintopId); QPixmap pm; if (!pixmapName.isEmpty()) { QString fname = KoResourcePaths::findResource("kis_images", pixmapName); pm = QPixmap(fname); } if (pm.isNull()) { pm = QPixmap(16, 16); pm.fill(); } m_actionEditor->paintOps->addItem(QIcon(pm), paintopId.name()); m_paintops.append(paintopId.id()); } connect(m_actionEditor->paintOps, SIGNAL(activated(int)), SLOT(paintOpChanged(int))); // Setup configuration widget for paint op settings m_gridLayout = new QGridLayout(m_actionEditor->frmOptionWidgetContainer); setPaintOpPreset(); m_actionEditor->paintOps->setCurrentIndex(m_paintops.indexOf(m_action->paintOpPreset()->paintOp().id())); m_paintOpsToPreset[m_action->paintOpPreset()->paintOp().id()] = m_action->paintOpPreset(); connect(m_actionEditor->wdgPresetChooser, SIGNAL(resourceSelected(KoResource*)), SLOT(resourceSelected(KoResource*))); // Setup the query path editor m_actionEditor->nodeQueryPathEditor->setNodeQueryPath(m_action->nodeQueryPath()); connect(m_actionEditor->nodeQueryPathEditor, SIGNAL(nodeQueryPathChanged()), SLOT(nodeQueryPathChanged())); } KisRecordedPaintActionEditor::~KisRecordedPaintActionEditor() { delete m_actionEditor; } void KisRecordedPaintActionEditor::configurationUpdated() { m_configWidget->writeConfiguration(const_cast(m_action->paintOpPreset()->settings().data())); m_action->setPaintColor(m_paintColorPopup->currentKoColor()); m_action->setBackgroundColor(m_backgroundColorPopup->currentKoColor()); m_action->setOpacity(m_actionEditor->opacity->value() / qreal(100.0)); emit(actionEdited()); } void KisRecordedPaintActionEditor::paintOpChanged(int index) { QString id = m_paintops[index]; KisPaintOpPresetSP preset = m_paintOpsToPreset[id]; if (!preset) { preset = KisPaintOpRegistry::instance()->defaultPreset(KoID(id, "")); m_paintOpsToPreset[id] = preset; } m_action->setPaintOpPreset(preset); setPaintOpPreset(); } void KisRecordedPaintActionEditor::resourceSelected(KoResource* resource) { KisPaintOpPresetSP preset = static_cast(resource); m_paintOpsToPreset[preset->paintOp().id()] = preset; m_action->setPaintOpPreset(preset); setPaintOpPreset(); } void KisRecordedPaintActionEditor::nodeQueryPathChanged() { m_action->setNodeQueryPath(m_actionEditor->nodeQueryPathEditor->nodeQueryPath()); emit(actionEdited()); } void KisRecordedPaintActionEditor::setPaintOpPreset() { delete m_configWidget; m_configWidget = KisPaintOpRegistry::instance()->get(m_action->paintOpPreset()->paintOp().id())->createConfigWidget(m_actionEditor->frmOptionWidgetContainer); if (m_configWidget) { m_gridLayout->addWidget(m_configWidget); //TODO use default configuration instead? //m_configWidget->setConfiguration(m_action->paintOpPreset()->settings()); connect(m_configWidget, SIGNAL(sigConfigurationUpdated()), SLOT(configurationUpdated())); } else { - m_gridLayout->addWidget(new QLabel("No configuration option.", this)); + m_gridLayout->addWidget(new QLabel(i18n("No configuration option."), this)); } } KisRecordedPaintActionEditorFactory::KisRecordedPaintActionEditorFactory() { } KisRecordedPaintActionEditorFactory::~KisRecordedPaintActionEditorFactory() { } QWidget* KisRecordedPaintActionEditorFactory::createEditor(QWidget* parent, KisRecordedAction* action) const { return new KisRecordedPaintActionEditor(parent, action); } bool KisRecordedPaintActionEditorFactory::canEdit(const KisRecordedAction* action) const { return dynamic_cast(action); } diff --git a/plugins/dockers/animation/timeline_frames_view.cpp b/plugins/dockers/animation/timeline_frames_view.cpp index 0ce0e136df..815c10bd6d 100644 --- a/plugins/dockers/animation/timeline_frames_view.cpp +++ b/plugins/dockers/animation/timeline_frames_view.cpp @@ -1,878 +1,878 @@ /* * Copyright (c) 2015 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. */ #include "timeline_frames_view.h" #include "timeline_frames_model.h" #include "timeline_ruler_header.h" #include "timeline_layers_header.h" #include #include #include #include #include #include #include #include #include #include #include #include "kis_debug.h" #include "timeline_frames_item_delegate.h" #include "kis_draggable_tool_button.h" #include "kis_icon_utils.h" #include "kis_animation_utils.h" #include "kis_custom_modifiers_catcher.h" #include "kis_action.h" #include "kis_signal_compressor.h" #include "kis_time_range.h" typedef QPair QItemViewPaintPair; typedef QList QItemViewPaintPairs; struct TimelineFramesView::Private { Private(TimelineFramesView *_q) : q(_q), fps(1), zoom(1.0), initialDragZoomValue(1.0), zoomStillPointIndex(-1), zoomStillPointOriginalOffset(0), dragInProgress(false), dragWasSuccessful(false), modifiersCatcher(0), selectionChangedCompressor(300, KisSignalCompressor::FIRST_INACTIVE) {} TimelineFramesView *q; TimelineFramesModel *model; TimelineRulerHeader *horizontalRuler; TimelineLayersHeader *layersHeader; int fps; qreal zoom; qreal initialDragZoomValue; int zoomStillPointIndex; int zoomStillPointOriginalOffset; QPoint initialDragPanValue; QPoint startZoomPanDragPos; QToolButton *addLayersButton; KisAction *showHideLayerAction; QMenu *layerEditingMenu; QMenu *existingLayersMenu; QMenu *frameCreationMenu; QMenu *frameEditingMenu; QMenu *multipleFrameEditingMenu; QMap globalActions; KisDraggableToolButton *zoomDragButton; bool dragInProgress; bool dragWasSuccessful; KisCustomModifiersCatcher *modifiersCatcher; QPoint lastPressedPosition; KisSignalCompressor selectionChangedCompressor; QStyleOptionViewItemV4 viewOptionsV4() const; QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const; }; TimelineFramesView::TimelineFramesView(QWidget *parent) : QTableView(parent), m_d(new Private(this)) { m_d->modifiersCatcher = new KisCustomModifiersCatcher(this); m_d->modifiersCatcher->addModifier("pan-zoom", Qt::Key_Space); m_d->modifiersCatcher->addModifier("offset-frame", Qt::Key_Alt); setCornerButtonEnabled(false); setSelectionBehavior(QAbstractItemView::SelectItems); setSelectionMode(QAbstractItemView::ExtendedSelection); setItemDelegate(new TimelineFramesItemDelegate(this)); setDragEnabled(true); setDragDropMode(QAbstractItemView::DragDrop); setAcceptDrops(true); setDropIndicatorShown(true); setDefaultDropAction(Qt::MoveAction); m_d->horizontalRuler = new TimelineRulerHeader(this); m_d->horizontalRuler->setSectionResizeMode(QHeaderView::Fixed); m_d->horizontalRuler->setDefaultSectionSize(18); this->setHorizontalHeader(m_d->horizontalRuler); m_d->layersHeader = new TimelineLayersHeader(this); m_d->layersHeader->setSectionResizeMode(QHeaderView::Fixed); m_d->layersHeader->setDefaultSectionSize(24); m_d->layersHeader->setMinimumWidth(60); m_d->layersHeader->setHighlightSections(true); this->setVerticalHeader(m_d->layersHeader); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(slotUpdateInfiniteFramesCount())); connect(horizontalScrollBar(), SIGNAL(sliderReleased()), SLOT(slotUpdateInfiniteFramesCount())); m_d->addLayersButton = new QToolButton(this); m_d->addLayersButton->setAutoRaise(true); m_d->addLayersButton->setIcon(KisIconUtils::loadIcon("addlayer")); m_d->addLayersButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_d->addLayersButton->setPopupMode(QToolButton::InstantPopup); m_d->layerEditingMenu = new QMenu(this); m_d->layerEditingMenu->addAction(KisAnimationUtils::newLayerActionName, this, SLOT(slotAddNewLayer())); m_d->existingLayersMenu = m_d->layerEditingMenu->addMenu(KisAnimationUtils::addExistingLayerActionName); m_d->layerEditingMenu->addSeparator(); m_d->showHideLayerAction = new KisAction(KisAnimationUtils::showLayerActionName, this); m_d->showHideLayerAction->setActivationFlags(KisAction::ACTIVE_LAYER); connect(m_d->showHideLayerAction, SIGNAL(triggered()), SLOT(slotHideLayerFromTimeline())); m_d->showHideLayerAction->setCheckable(true); m_d->globalActions.insert("show_in_timeline", m_d->showHideLayerAction); m_d->layerEditingMenu->addAction(m_d->showHideLayerAction); m_d->layerEditingMenu->addAction(KisAnimationUtils::removeLayerActionName, this, SLOT(slotRemoveLayer())); connect(m_d->existingLayersMenu, SIGNAL(aboutToShow()), SLOT(slotUpdateLayersMenu())); connect(m_d->existingLayersMenu, SIGNAL(triggered(QAction*)), SLOT(slotAddExistingLayer(QAction*))); connect(m_d->layersHeader, SIGNAL(sigRequestContextMenu(const QPoint&)), SLOT(slotLayerContextMenuRequested(const QPoint&))); m_d->addLayersButton->setMenu(m_d->layerEditingMenu); m_d->frameCreationMenu = new QMenu(this); m_d->frameCreationMenu->addAction(KisAnimationUtils::addFrameActionName, this, SLOT(slotNewFrame())); m_d->frameCreationMenu->addAction(KisAnimationUtils::duplicateFrameActionName, this, SLOT(slotCopyFrame())); m_d->frameEditingMenu = new QMenu(this); m_d->frameEditingMenu->addAction(KisAnimationUtils::removeFrameActionName, this, SLOT(slotRemoveFrame())); m_d->multipleFrameEditingMenu = new QMenu(this); m_d->multipleFrameEditingMenu->addAction(KisAnimationUtils::removeFramesActionName, this, SLOT(slotRemoveFrame())); m_d->zoomDragButton = new KisDraggableToolButton(this); m_d->zoomDragButton->setAutoRaise(true); m_d->zoomDragButton->setIcon(KisIconUtils::loadIcon("zoom-in")); m_d->zoomDragButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - m_d->zoomDragButton->setToolTip("Zoom Timeline. Hold down and drag left or right."); + m_d->zoomDragButton->setToolTip(i18nc("@info:tooltip", "Zoom Timeline. Hold down and drag left or right.")); m_d->zoomDragButton->setPopupMode(QToolButton::InstantPopup); connect(m_d->zoomDragButton, SIGNAL(valueChanged(int)), SLOT(slotZoomButtonChanged(int))); connect(m_d->zoomDragButton, SIGNAL(pressed()), SLOT(slotZoomButtonPressed())); setFramesPerSecond(12); setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); connect(&m_d->selectionChangedCompressor, SIGNAL(timeout()), SLOT(slotSelectionChanged())); } TimelineFramesView::~TimelineFramesView() { } QMap TimelineFramesView::globalActions() const { return m_d->globalActions; } void resizeToMinimalSize(QAbstractButton *w, int minimalSize) { QSize buttonSize = w->sizeHint(); if (buttonSize.height() > minimalSize) { buttonSize = QSize(minimalSize, minimalSize); } w->resize(buttonSize); } void TimelineFramesView::updateGeometries() { QTableView::updateGeometries(); const int availableHeight = m_d->horizontalRuler->height(); const int margin = 2; const int minimalSize = availableHeight - 2 * margin; resizeToMinimalSize(m_d->addLayersButton, minimalSize); resizeToMinimalSize(m_d->zoomDragButton, minimalSize); int x = 2 * margin; int y = (availableHeight - minimalSize) / 2; m_d->addLayersButton->move(x, 2 * y); const int availableWidth = m_d->layersHeader->width(); x = availableWidth - margin - minimalSize; m_d->zoomDragButton->move(x, 2 * y); } void TimelineFramesView::setModel(QAbstractItemModel *model) { TimelineFramesModel *framesModel = qobject_cast(model); m_d->model = framesModel; QTableView::setModel(model); connect(m_d->model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), this, SLOT(slotHeaderDataChanged(Qt::Orientation, int, int))); connect(m_d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotDataChanged(QModelIndex,QModelIndex))); connect(m_d->model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(slotReselectCurrentIndex())); connect(m_d->model, SIGNAL(sigInfiniteTimelineUpdateNeeded()), this, SLOT(slotUpdateInfiniteFramesCount())); connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), &m_d->selectionChangedCompressor, SLOT(start())); } void TimelineFramesView::setFramesPerSecond(int fps) { m_d->fps = fps; m_d->horizontalRuler->setFramePerSecond(fps); // For some reason simple update sometimes doesn't work here, so // reset the whole header // // m_d->horizontalRuler->reset(); } qreal TimelineFramesView::zoom() const { return m_d->zoom; } void TimelineFramesView::setZoom(qreal zoom) { const int minSectionSize = 4; const int unitSectionSize = 18; int newSectionSize = zoom * unitSectionSize; if (newSectionSize < minSectionSize) { newSectionSize = minSectionSize; zoom = qreal(newSectionSize) / unitSectionSize; } if (!qFuzzyCompare(m_d->zoom, zoom)) { m_d->zoom = zoom; m_d->horizontalRuler->setDefaultSectionSize(newSectionSize); // For some reason simple update doesn't work here, // so reset the whole header QPersistentModelIndex index = currentIndex(); m_d->horizontalRuler->reset(); setCurrentIndex(index); slotUpdateInfiniteFramesCount(); } } void TimelineFramesView::setZoomDouble(double zoom) { setZoom(zoom); } void TimelineFramesView::slotZoomButtonPressed() { m_d->zoomStillPointIndex = currentIndex().column(); slotZoomButtonPressedImpl(); } void TimelineFramesView::slotZoomButtonPressedImpl() { const int w = m_d->horizontalRuler->defaultSectionSize(); m_d->zoomStillPointOriginalOffset = w * m_d->zoomStillPointIndex - horizontalScrollBar()->value(); m_d->initialDragZoomValue = zoom(); } void TimelineFramesView::slotZoomButtonChanged(int value) { qreal zoomCoeff = std::pow(2.0, qreal(value) / KisDraggableToolButton::unitRadius()); setZoom(m_d->initialDragZoomValue * zoomCoeff); const int w = m_d->horizontalRuler->defaultSectionSize(); horizontalScrollBar()->setValue(w * m_d->zoomStillPointIndex - m_d->zoomStillPointOriginalOffset); } void TimelineFramesView::slotUpdateInfiniteFramesCount() { if (horizontalScrollBar()->isSliderDown()) return; const int sectionWidth = m_d->horizontalRuler->defaultSectionSize(); const int calculatedIndex = (horizontalScrollBar()->value() + m_d->horizontalRuler->width() - 1) / sectionWidth; m_d->model->setLastVisibleFrame(calculatedIndex); } void TimelineFramesView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { QTableView::currentChanged(current, previous); if (previous.column() != current.column()) { m_d->model->setData(previous, false, TimelineFramesModel::ActiveFrameRole); m_d->model->setData(current, true, TimelineFramesModel::ActiveFrameRole); } } QItemSelectionModel::SelectionFlags TimelineFramesView::selectionCommand(const QModelIndex &index, const QEvent *event) const { // WARNING: Copy-pasted from KisNodeView! Please keep in sync! /** * Qt has a bug: when we Ctrl+click on an item, the item's * selections gets toggled on mouse *press*, whereas usually it is * done on mouse *release*. Therefore the user cannot do a * Ctrl+D&D with the default configuration. This code fixes the * problem by manually returning QItemSelectionModel::NoUpdate * flag when the user clicks on an item and returning * QItemSelectionModel::Toggle on release. */ if (event && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) && index.isValid()) { const QMouseEvent *mevent = static_cast(event); if (mevent->button() == Qt::RightButton && selectionModel()->selectedIndexes().contains(index)) { // Allow calling context menu for multiple layers return QItemSelectionModel::NoUpdate; } if (event->type() == QEvent::MouseButtonPress && (mevent->modifiers() & Qt::ControlModifier)) { return QItemSelectionModel::NoUpdate; } if (event->type() == QEvent::MouseButtonRelease && (mevent->modifiers() & Qt::ControlModifier)) { return QItemSelectionModel::Toggle; } } return QAbstractItemView::selectionCommand(index, event); } void TimelineFramesView::slotSelectionChanged() { int minColumn = std::numeric_limits::max(); int maxColumn = std::numeric_limits::min(); foreach (const QModelIndex &idx, selectedIndexes()) { if (idx.column() > maxColumn) { maxColumn = idx.column(); } if (idx.column() < minColumn) { minColumn = idx.column(); } } KisTimeRange range; if (maxColumn > minColumn) { range = KisTimeRange(minColumn, maxColumn - minColumn + 1); } m_d->model->setPlaybackRange(range); } void TimelineFramesView::slotReselectCurrentIndex() { QModelIndex index = currentIndex(); currentChanged(index, index); } void TimelineFramesView::slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (m_d->model->isPlaybackActive()) return; int selectedColumn = -1; for (int j = topLeft.column(); j <= bottomRight.column(); j++) { QVariant value = m_d->model->data( m_d->model->index(topLeft.row(), j), TimelineFramesModel::ActiveFrameRole); if (value.isValid() && value.toBool()) { selectedColumn = j; break; } } QModelIndex index = currentIndex(); if (!index.isValid() && selectedColumn < 0) { return; } if (selectedColumn == -1) { selectedColumn = index.column(); } if (selectedColumn != index.column() && !m_d->dragInProgress) { int row= index.isValid() ? index.row() : 0; setCurrentIndex(m_d->model->index(row, selectedColumn)); } } void TimelineFramesView::slotHeaderDataChanged(Qt::Orientation orientation, int first, int last) { Q_UNUSED(first); Q_UNUSED(last); if (orientation == Qt::Horizontal) { const int newFps = m_d->model->headerData(0, Qt::Horizontal, TimelineFramesModel::FramesPerSecondRole).toInt(); if (newFps != m_d->fps) { setFramesPerSecond(newFps); } } else /* if (orientation == Qt::Vertical) */ { updateShowInTimeline(); } } void TimelineFramesView::rowsInserted(const QModelIndex& parent, int start, int end) { QTableView::rowsInserted(parent, start, end); updateShowInTimeline(); } inline bool isIndexDragEnabled(QAbstractItemModel *model, const QModelIndex &index) { return (model->flags(index) & Qt::ItemIsDragEnabled); } QStyleOptionViewItemV4 TimelineFramesView::Private::viewOptionsV4() const { QStyleOptionViewItemV4 option = q->viewOptions(); option.locale = q->locale(); option.locale.setNumberOptions(QLocale::OmitGroupSeparator); option.widget = q; return option; } QItemViewPaintPairs TimelineFramesView::Private::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const { Q_ASSERT(r); QRect &rect = *r; const QRect viewportRect = q->viewport()->rect(); QItemViewPaintPairs ret; for (int i = 0; i < indexes.count(); ++i) { const QModelIndex &index = indexes.at(i); const QRect current = q->visualRect(index); if (current.intersects(viewportRect)) { ret += qMakePair(current, index); rect |= current; } } rect &= viewportRect; return ret; } QPixmap TimelineFramesView::Private::renderToPixmap(const QModelIndexList &indexes, QRect *r) const { Q_ASSERT(r); QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); if (paintPairs.isEmpty()) return QPixmap(); QPixmap pixmap(r->size()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); QStyleOptionViewItemV4 option = viewOptionsV4(); option.state |= QStyle::State_Selected; for (int j = 0; j < paintPairs.count(); ++j) { option.rect = paintPairs.at(j).first.translated(-r->topLeft()); const QModelIndex ¤t = paintPairs.at(j).second; //adjustViewOptionsForIndex(&option, current); q->itemDelegate(current)->paint(&painter, option, current); } return pixmap; } void TimelineFramesView::startDrag(Qt::DropActions supportedActions) { QModelIndexList indexes = selectionModel()->selectedIndexes(); if (!indexes.isEmpty() && m_d->modifiersCatcher->modifierPressed("offset-frame")) { QVector rows; int leftmostColumn = std::numeric_limits::max(); Q_FOREACH (const QModelIndex &index, indexes) { leftmostColumn = qMin(leftmostColumn, index.column()); if (!rows.contains(index.row())) { rows.append(index.row()); } } const int lastColumn = m_d->model->columnCount() - 1; selectionModel()->clear(); Q_FOREACH (const int row, rows) { QItemSelection sel(m_d->model->index(row, leftmostColumn), m_d->model->index(row, lastColumn)); selectionModel()->select(sel, QItemSelectionModel::Select); } supportedActions = Qt::MoveAction; { QModelIndexList indexes = selectedIndexes(); for(int i = indexes.count() - 1 ; i >= 0; --i) { if (!isIndexDragEnabled(m_d->model, indexes.at(i))) indexes.removeAt(i); } selectionModel()->clear(); if (indexes.count() > 0) { QMimeData *data = m_d->model->mimeData(indexes); if (!data) return; QRect rect; QPixmap pixmap = m_d->renderToPixmap(indexes, &rect); rect.adjust(horizontalOffset(), verticalOffset(), 0, 0); QDrag *drag = new QDrag(this); drag->setPixmap(pixmap); drag->setMimeData(data); drag->setHotSpot(m_d->lastPressedPosition - rect.topLeft()); drag->exec(supportedActions, Qt::MoveAction); setCurrentIndex(currentIndex()); } } } else { /** * Workaround for Qt5's bugs: * * 1) Qt doesn't treat selection the selection on D&D * correctly, so we save it in advance and restore * afterwards. * * 2) There is a private variable in QAbstractItemView: * QAbstractItemView::Private::currentSelectionStartIndex. * It is initialized *only* when the setCurrentIndex() is called * explicitly on the view object, not on the selection model. * Therefore we should explicitly call setCurrentIndex() after * D&D, even if it already has *correct* value! * * 2) We should also call selectionModel()->select() * explicitly. There are two reasons for it: 1) Qt doesn't * maintain selection over D&D; 2) when reselecting single * element after D&D, Qt goes crazy, because it tries to * read *global* keyboard modifiers. Therefore if we are * dragging with Shift or Ctrl pressed it'll get crazy. So * just reset it explicitly. */ QModelIndexList selectionBefore = selectionModel()->selectedIndexes(); QModelIndex currentBefore = selectionModel()->currentIndex(); // initialize a global status variable m_d->dragWasSuccessful = false; QAbstractItemView::startDrag(supportedActions); QModelIndex newCurrent; QPoint selectionOffset; if (m_d->dragWasSuccessful) { newCurrent = currentIndex(); selectionOffset = QPoint(newCurrent.column() - currentBefore.column(), newCurrent.row() - currentBefore.row()); } else { newCurrent = currentBefore; selectionOffset = QPoint(); } setCurrentIndex(newCurrent); selectionModel()->clearSelection(); Q_FOREACH (const QModelIndex &idx, selectionBefore) { QModelIndex newIndex = model()->index(idx.row() + selectionOffset.y(), idx.column() + selectionOffset.x()); selectionModel()->select(newIndex, QItemSelectionModel::Select); } } } void TimelineFramesView::dragEnterEvent(QDragEnterEvent *event) { m_d->dragInProgress = true; m_d->model->setScrubState(true); QTableView::dragEnterEvent(event); } void TimelineFramesView::dragMoveEvent(QDragMoveEvent *event) { m_d->dragInProgress = true; m_d->model->setScrubState(true); QTableView::dragMoveEvent(event); if (event->isAccepted()) { QModelIndex index = indexAt(event->pos()); if (!m_d->model->canDropFrameData(event->mimeData(), index)) { event->ignore(); } else { selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } } void TimelineFramesView::dropEvent(QDropEvent *event) { m_d->dragInProgress = false; m_d->model->setScrubState(false); QAbstractItemView::dropEvent(event); m_d->dragWasSuccessful = event->isAccepted(); } void TimelineFramesView::dragLeaveEvent(QDragLeaveEvent *event) { m_d->dragInProgress = false; m_d->model->setScrubState(false); QAbstractItemView::dragLeaveEvent(event); } void TimelineFramesView::mousePressEvent(QMouseEvent *event) { QPersistentModelIndex index = indexAt(event->pos()); if (m_d->modifiersCatcher->modifierPressed("pan-zoom")) { m_d->startZoomPanDragPos = event->pos(); if (event->button() == Qt::RightButton) { // TODO: try calculate index under mouse cursor even when // it is outside any visible row m_d->zoomStillPointIndex = index.isValid() ? index.column() : currentIndex().column(); slotZoomButtonPressedImpl(); } else if (event->button() == Qt::LeftButton) { m_d->initialDragPanValue = QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()); } event->accept(); } else if (event->button() == Qt::RightButton) { int numSelectedItems = selectionModel()->selectedIndexes().size(); if (index.isValid() && numSelectedItems <= 1 && m_d->model->data(index, TimelineFramesModel::FrameEditableRole).toBool()) { model()->setData(index, true, TimelineFramesModel::ActiveLayerRole); model()->setData(index, true, TimelineFramesModel::ActiveFrameRole); setCurrentIndex(index); if (model()->data(index, TimelineFramesModel::FrameExistsRole).toBool()) { m_d->frameEditingMenu->exec(event->globalPos()); } else { m_d->frameCreationMenu->exec(event->globalPos()); } } else if (numSelectedItems > 1) { m_d->multipleFrameEditingMenu->exec(event->globalPos()); } } else { if (index.isValid()) { m_d->model->setLastClickedIndex(index); } m_d->lastPressedPosition = QPoint(horizontalOffset(), verticalOffset()) + event->pos(); QAbstractItemView::mousePressEvent(event); } } void TimelineFramesView::mouseMoveEvent(QMouseEvent *e) { if (m_d->modifiersCatcher->modifierPressed("pan-zoom")) { QPoint diff = e->pos() - m_d->startZoomPanDragPos; if (e->buttons() & Qt::RightButton) { slotZoomButtonChanged(m_d->zoomDragButton->calculateValue(diff)); } else if (e->buttons() & Qt::LeftButton) { QPoint offset = QPoint(m_d->initialDragPanValue.x() - diff.x(), m_d->initialDragPanValue.y() - diff.y()); const int height = m_d->layersHeader->defaultSectionSize(); horizontalScrollBar()->setValue(offset.x()); verticalScrollBar()->setValue(offset.y() / height); } e->accept(); } else { m_d->model->setScrubState(true); QTableView::mouseMoveEvent(e); } } void TimelineFramesView::mouseReleaseEvent(QMouseEvent *e) { if (m_d->modifiersCatcher->modifierPressed("pan-zoom")) { e->accept(); } else { m_d->model->setScrubState(false); QTableView::mouseReleaseEvent(e); } } void TimelineFramesView::slotUpdateLayersMenu() { QAction *action = 0; m_d->existingLayersMenu->clear(); QVariant value = model()->headerData(0, Qt::Vertical, TimelineFramesModel::OtherLayersRole); if (value.isValid()) { TimelineFramesModel::OtherLayersList list = value.value(); int i = 0; Q_FOREACH (const TimelineFramesModel::OtherLayer &l, list) { action = m_d->existingLayersMenu->addAction(l.name); action->setData(i++); } } } void TimelineFramesView::slotLayerContextMenuRequested(const QPoint &globalPos) { m_d->layerEditingMenu->exec(globalPos); } void TimelineFramesView::updateShowInTimeline() { const int row = m_d->model->activeLayerRow(); const bool status = m_d->model->headerData(row, Qt::Vertical, TimelineFramesModel::LayerUsedInTimelineRole).toBool(); m_d->showHideLayerAction->setChecked(status); } void TimelineFramesView::slotAddNewLayer() { QModelIndex index = currentIndex(); const int newRow = index.isValid() ? index.row() : 0; model()->insertRow(newRow); } void TimelineFramesView::slotAddExistingLayer(QAction *action) { QVariant value = action->data(); if (value.isValid()) { QModelIndex index = currentIndex(); const int newRow = index.isValid() ? index.row() + 1 : 0; m_d->model->insertOtherLayer(value.toInt(), newRow); } } void TimelineFramesView::slotRemoveLayer() { QModelIndex index = currentIndex(); if (!index.isValid()) return; model()->removeRow(index.row()); } void TimelineFramesView::slotHideLayerFromTimeline() { const int row = m_d->model->activeLayerRow(); const bool status = m_d->model->headerData(row, Qt::Vertical, TimelineFramesModel::LayerUsedInTimelineRole).toBool(); m_d->model->setHeaderData(row, Qt::Vertical, !status, TimelineFramesModel::LayerUsedInTimelineRole); } void TimelineFramesView::slotNewFrame() { QModelIndex index = currentIndex(); if (!index.isValid() || !m_d->model->data(index, TimelineFramesModel::FrameEditableRole).toBool()) { return; } m_d->model->createFrame(index); } void TimelineFramesView::slotCopyFrame() { QModelIndex index = currentIndex(); if (!index.isValid() || !m_d->model->data(index, TimelineFramesModel::FrameEditableRole).toBool()) { return; } m_d->model->copyFrame(index); } void TimelineFramesView::slotRemoveFrame() { QModelIndexList indexes = selectionModel()->selectedIndexes(); for (auto it = indexes.begin(); it != indexes.end(); /*noop*/) { if (!m_d->model->data(*it, TimelineFramesModel::FrameEditableRole).toBool()) { it = indexes.erase(it); } else { ++it; } } if (!indexes.isEmpty()) { m_d->model->removeFrames(indexes); } } diff --git a/plugins/dockers/historydocker/KisUndoView.cpp b/plugins/dockers/historydocker/KisUndoView.cpp index 1a37dd4059..7ce2fb4e79 100644 --- a/plugins/dockers/historydocker/KisUndoView.cpp +++ b/plugins/dockers/historydocker/KisUndoView.cpp @@ -1,391 +1,391 @@ /* This file is part of the KDE project * Copyright (C) 2010 Matus Talcik * * 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. */ /**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "KisUndoView.h" #include "KisUndoModel.h" #ifndef QT_NO_UNDOVIEW #include #include #include #include #include #include #include #include #include #include /*! \class KisUndoView \brief The KisUndoView class displays the contents of a KUndo2QStack. \since 4.2 \ingroup advanced KisUndoView is a QListView which displays the list of commands pushed on an undo stack. The most recently executed command is always selected. Selecting a different command results in a call to KUndo2QStack::setIndex(), rolling the state of the document backwards or forward to the new command. The stack can be set explicitly with setStack(). Alternatively, a KUndo2Group object can be set with setGroup(). The view will then update itself automatically whenever the active stack of the group changes. \image KisUndoView.png */ class KisUndoViewPrivate { public: KisUndoViewPrivate() : #ifndef QT_NO_UNDOGROUP group(0), #endif model(0) {} #ifndef QT_NO_UNDOGROUP QPointer group; #endif KisUndoModel *model; KisUndoView* q; void init(KisUndoView* view); }; void KisUndoViewPrivate::init(KisUndoView* view) { q = view; model = new KisUndoModel(q); q->setModel(model); q->setSelectionModel(model->selectionModel()); } /*! Constructs a new view with parent \a parent. */ KisUndoView::KisUndoView(QWidget *parent) : QListView(parent) , d(new KisUndoViewPrivate) { d->init(this); } /*! Constructs a new view with parent \a parent and sets the observed stack to \a stack. */ KisUndoView::KisUndoView(KUndo2QStack *stack, QWidget *parent) : QListView(parent) , d(new KisUndoViewPrivate) { d->init(this); setStack(stack); } #ifndef QT_NO_UNDOGROUP /*! Constructs a new view with parent \a parent and sets the observed group to \a group. The view will update itself automatically whenever the active stack of the group changes. */ KisUndoView::KisUndoView(KUndo2Group *group, QWidget *parent) : QListView(parent) , d(new KisUndoViewPrivate) { d->init(this); setGroup(group); } #endif // QT_NO_UNDOGROUP /*! Destroys this view. */ KisUndoView::~KisUndoView() { delete d; } /*! Returns the stack currently displayed by this view. If the view is looking at a KUndo2Group, this the group's active stack. \sa setStack() setGroup() */ KUndo2QStack *KisUndoView::stack() const { return d->model->stack(); } /*! Sets the stack displayed by this view to \a stack. If \a stack is 0, the view will be empty. If the view was previously looking at a KUndo2Group, the group is set to 0. \sa stack() setGroup() */ void KisUndoView::setStack(KUndo2QStack *stack) { #ifndef QT_NO_UNDOGROUP setGroup(0); #endif d->model->setStack(stack); } #ifndef QT_NO_UNDOGROUP /*! Sets the group displayed by this view to \a group. If \a group is 0, the view will be empty. The view will update itself autmiatically whenever the active stack of the group changes. \sa group() setStack() */ void KisUndoView::setGroup(KUndo2Group *group) { if (d->group == group) return; if (d->group != 0) { disconnect(d->group, SIGNAL(activeStackChanged(KUndo2QStack*)), d->model, SLOT(setStack(KUndo2QStack*))); } d->group = group; if (d->group != 0) { connect(d->group, SIGNAL(activeStackChanged(KUndo2QStack*)), d->model, SLOT(setStack(KUndo2QStack*))); d->model->setStack(d->group->activeStack()); } else { d->model->setStack(0); } } /*! Returns the group displayed by this view. If the view is not looking at group, this function returns 0. \sa setGroup() setStack() */ KUndo2Group *KisUndoView::group() const { return d->group; } #endif // QT_NO_UNDOGROUP /*! \property KisUndoView::emptyLabel \brief the label used for the empty state. The empty label is the topmost element in the list of commands, which represents the state of the document before any commands were pushed on the stack. The default is the string "". */ void KisUndoView::setEmptyLabel(const QString &label) { d->model->setEmptyLabel(label); } QString KisUndoView::emptyLabel() const { return d->model->emptyLabel(); } /*! \property KisUndoView::cleanIcon \brief the icon used to represent the clean state. A stack may have a clean state set with KUndo2QStack::setClean(). This is usually the state of the document at the point it was saved. KisUndoView can display an icon in the list of commands to show the clean state. If this property is a null icon, no icon is shown. The default value is the null icon. */ void KisUndoView::setCleanIcon(const QIcon &icon) { d->model->setCleanIcon(icon); } QIcon KisUndoView::cleanIcon() const { return d->model->cleanIcon(); } void KisUndoView::setCanvas(KisCanvas2 *canvas) { d->model->setCanvas(canvas); } void KisUndoView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::RightButton) { QMenu menu(this); QAction* action1 = menu.addAction(KisIconUtils::loadIcon("link"),stack()->useCumulativeUndoRedo()?i18n("Disable Cumulative Undo"):i18n("Enable Cumulative Undo")); connect(action1, SIGNAL(triggered()), this, SLOT(toggleCumulativeUndoRedo())); - QLabel *l = new QLabel("Start merging time"); + QLabel *l = new QLabel(i18n("Start merging time")); QDoubleSpinBox *s = new QDoubleSpinBox(); - s->setToolTip("The amount of time after a merged stroke before merging again"); + s->setToolTip(i18nc("@info:tooltip", "The amount of time after a merged stroke before merging again")); s->setRange(3,10); s->setValue(stack()->timeT1()); QGridLayout *g = new QGridLayout(); g->addWidget(l); g->addWidget(s); QWidget *w = new QWidget(); w->setLayout(g); w->setVisible(stack()->useCumulativeUndoRedo()); QWidgetAction* action2 = new QWidgetAction(s); action2->setDefaultWidget(w); connect(s,SIGNAL(valueChanged(double)),SLOT(setStackT1(double))); - QLabel *l1 = new QLabel("Group time"); + QLabel *l1 = new QLabel(i18n("Group time")); QDoubleSpinBox *s1 = new QDoubleSpinBox(); - s1->setToolTip("The amount of time every stroke should be \napart from its previous stroke\nto be classified in one group"); + s1->setToolTip(i18nc("@info:tooltip", "The amount of time every stroke should be \napart from its previous stroke\nto be classified in one group")); s1->setRange(0.3,s->value()); s1->setValue(stack()->timeT2()); QGridLayout *g1 = new QGridLayout(); g1->addWidget(l1); g1->addWidget(s1); QWidget *w1 = new QWidget(); w1->setLayout(g1); w1->setVisible(stack()->useCumulativeUndoRedo()); QWidgetAction* action3 = new QWidgetAction(s1); action3->setDefaultWidget(w1); connect(s1,SIGNAL(valueChanged(double)),SLOT(setStackT2(double))); - QLabel *l2 = new QLabel("Split Strokes"); + QLabel *l2 = new QLabel(i18n("Split Strokes")); QSpinBox *s2 = new QSpinBox(); - s2->setToolTip("The number of last strokes which Krita should store separately"); + s2->setToolTip(i18nc("@info:tooltip", "The number of last strokes which Krita should store separately")); s2->setRange(1,stack()->undoLimit()); s2->setValue(stack()->strokesN()); QGridLayout *g2 = new QGridLayout(); g1->addWidget(l2); g1->addWidget(s2); QWidget *w2 = new QWidget(); w2->setLayout(g2); w2->setVisible(stack()->useCumulativeUndoRedo()); QWidgetAction* action4 = new QWidgetAction(s2); action4->setDefaultWidget(w2); connect(s2,SIGNAL(valueChanged(int)),SLOT(setStackN(int))); menu.addAction(action2); menu.addAction(action3); menu.addAction(action4); menu.exec(event->globalPos()); } else{ QListView::mousePressEvent(event); } } void KisUndoView::toggleCumulativeUndoRedo() { stack()->setUseCumulativeUndoRedo(!stack()->useCumulativeUndoRedo() ); KisConfig cfg; cfg.setCumulativeUndoRedo(stack()->useCumulativeUndoRedo()); } void KisUndoView::setStackT1(double value) { stack()->setTimeT1(value); KisConfig cfg; cfg.setStackT1(value); } void KisUndoView::setStackT2(double value) { stack()->setTimeT2(value); KisConfig cfg; cfg.setStackT2(value); } void KisUndoView::setStackN(int value) { stack()->setStrokesN(value); KisConfig cfg; cfg.setStackN(value); } #endif // QT_NO_UNDOVIEW diff --git a/plugins/extensions/gmic/kis_gmic_widget.cpp b/plugins/extensions/gmic/kis_gmic_widget.cpp index 6add8cde2d..4e9fec9e58 100644 --- a/plugins/extensions/gmic/kis_gmic_widget.cpp +++ b/plugins/extensions/gmic/kis_gmic_widget.cpp @@ -1,432 +1,430 @@ /* * Copyright (c) 2013-2015 Lukáš Tvrdý * * 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 #include "kis_gmic_settings_widget.h" #include #include #include "kis_gmic_updater.h" static const QString maximizeStr = i18n("Maximize"); static const QString selectFilterStr = i18n("Select a filter..."); KisGmicWidget::KisGmicWidget(KisGmicFilterModel * filters, const QString &updateUrl) : m_filterModel(filters) ,m_updateUrl(updateUrl) { dbgPlugins << "Constructor:" << this; setupUi(this); m_filterOptions = new QWidget(this); m_filterScrollArea->setWidget(m_filterOptions); m_filterOptions->show(); createMainLayout(); setAttribute(Qt::WA_DeleteOnClose, true); m_filterApplied = false; m_onCanvasPreviewActivated = false; m_onCanvasPreviewRequested = false; } KisGmicWidget::~KisGmicWidget() { dbgPlugins << "Destructor:" << this; delete m_filterModel; } void KisGmicWidget::createMainLayout() { connect(m_inputOutputOptions->previewCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotPreviewChanged(bool))); connect(m_inputOutputOptions->previewSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPreviewSizeChanged())); connect(m_inputOutputOptions->previewSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotConfigurationChanged())); connect(m_inputOutputOptions->zoomInButton, SIGNAL(clicked(bool)), this, SLOT(slotNotImplemented())); connect(m_inputOutputOptions->zoomOutButton, SIGNAL(clicked(bool)), this, SLOT(slotNotImplemented())); KisGmicFilterProxyModel *proxyModel = new KisGmicFilterProxyModel(this); proxyModel->setSourceModel(m_filterModel); proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_filterTree->setModel(proxyModel); m_filterTree->setItemDelegate(new HtmlDelegate()); connect(m_filterTree->selectionModel(), SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT(slotSelectedFilterChanged(const QItemSelection &, const QItemSelection &))); - if (!m_updateUrl.isEmpty()) - { - updateBtn->setToolTip("Fetching definitions from : " + m_updateUrl); + if (!m_updateUrl.isEmpty()) { + updateBtn->setToolTip(i18nc("@info:tooltip", "Fetching definitions from: " + m_updateUrl)); } - else - { + else { updateBtn->setEnabled(false); } expandCollapseBtn->setIcon(KisIconUtils::loadIcon("zoom-in")); connect(expandCollapseBtn, SIGNAL(clicked()), this, SLOT(slotExpandCollapse())); connect(updateBtn, SIGNAL(clicked(bool)), this, SLOT(startUpdate())); connect(searchBox, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString))); QPushButton * maximize = new QPushButton(maximizeStr); controlButtonBox->addButton(maximize, QDialogButtonBox::ActionRole); connect(maximize, SIGNAL(clicked(bool)), this, SLOT(slotMaximizeClicked())); connect(controlButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(slotOkClicked())); connect(controlButtonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked(bool)), this, SLOT(slotApplyClicked())); connect(controlButtonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked(bool)), this, SLOT(slotCancelClicked())); connect(controlButtonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked(bool)), this, SLOT(slotResetClicked())); switchOptionsWidgetFor(new QLabel(selectFilterStr)); } void KisGmicWidget::slotSelectedFilterChanged(const QItemSelection & /*newSelection*/, const QItemSelection & /*oldSelection*/) { //get the text of the selected item const QModelIndex index = m_filterTree->selectionModel()->currentIndex(); QString selectedText = index.data(Qt::DisplayRole).toString(); QVariant var = index.data(CommandRole); Command *gmicCommand(0); if (!var.isValid()) { gmicCommand = 0; dbgPlugins << "Invalid QVariant, invalid command? : ';' "; } else { gmicCommand = var.value(); } if (gmicCommand) { KisGmicSettingsWidget * filterOptions = new KisGmicSettingsWidget(gmicCommand); QObject::connect(filterOptions, SIGNAL(sigConfigurationUpdated()), this, SLOT(slotConfigurationChanged())); switchOptionsWidgetFor(filterOptions); } else { switchOptionsWidgetFor(new QLabel(selectFilterStr)); emit sigPreviewActiveLayer(); } #ifdef DEBUG_MODEL //find out the hierarchy level of the selected item int hierarchyLevel = 1; QModelIndex seekRoot = index; while(seekRoot.parent() != QModelIndex()) { seekRoot = seekRoot.parent(); hierarchyLevel++; } QString showString = QString("%1, Level %2").arg(selectedText) .arg(hierarchyLevel); setWindowTitle(showString); #endif } void KisGmicWidget::slotCancelClicked() { if (m_onCanvasPreviewRequested) { emit sigCancelOnCanvasPreview(); } close(); } void KisGmicWidget::slotOkClicked() { if (m_inputOutputOptions->previewSize() == ON_CANVAS) { emit sigAcceptOnCanvasPreview(); } else { if (!m_filterApplied) { KisGmicFilterSetting * filterSettings = currentFilterSettings(); if (filterSettings) { emit sigFilterCurrentImage(filterSettings); } m_filterApplied = true; } } emit sigRequestFinishAndClose(); hide(); } void KisGmicWidget::closeEvent(QCloseEvent *event) { event->accept(); emit sigClose(); } void KisGmicWidget::slotResetClicked() { const QModelIndex index = m_filterTree->selectionModel()->currentIndex(); QVariant var = index.data(CommandRole); Command * gmicCommand(0); if (!var.isValid()) { gmicCommand = 0; dbgPlugins << "Filter not selected!"; return; } else { gmicCommand = var.value(); } gmicCommand->reset(); KisGmicSettingsWidget * currentSettingsWidget = qobject_cast(m_filterOptions); if (currentSettingsWidget) { currentSettingsWidget->reload(); } } void KisGmicWidget::slotMaximizeClicked() { QPushButton * maximizeButton = qobject_cast(sender()); if (!maximizeButton) { return; } if (isMaximized()) { // restore clicked showNormal(); maximizeButton->setText(maximizeStr); } else { showMaximized(); maximizeButton->setText(i18n("Restore")); } } void KisGmicWidget::startUpdate() { m_updater = new KisGmicUpdater(m_updateUrl); connect(m_updater, SIGNAL(updated()), this, SLOT(finishUpdate())); m_updater->start(); QApplication::setOverrideCursor(Qt::WaitCursor); } void KisGmicWidget::finishUpdate() { QApplication::restoreOverrideCursor(); m_updater->deleteLater(); QString msg = i18nc("@info", "Update filters done. " "Restart G'MIC dialog to finish updating! "); QMessageBox::information(this, i18nc("@title:window", "Updated"), msg); } void KisGmicWidget::slotPreviewChanged(bool enabling) { if (enabling) { requestComputePreview(); } else { if (m_inputOutputOptions->previewSize() == ON_CANVAS) { emit sigCancelOnCanvasPreview(); m_onCanvasPreviewRequested = false; // cancelled } else { emit sigPreviewActiveLayer(); } } } void KisGmicWidget::slotPreviewSizeChanged() { if (m_inputOutputOptions->previewSize() == ON_CANVAS) { m_onCanvasPreviewActivated = true; } else { if (m_onCanvasPreviewActivated) { emit sigCancelOnCanvasPreview(); m_onCanvasPreviewActivated = false; m_onCanvasPreviewRequested = false; } } } void KisGmicWidget::slotConfigurationChanged() { if (m_inputOutputOptions->previewCheckBox->isChecked()) { requestComputePreview(); } else { emit sigPreviewActiveLayer(); } } void KisGmicWidget::slotApplyClicked() { if (m_inputOutputOptions->previewSize() == ON_CANVAS) { KisGmicFilterSetting * filterSettings = currentFilterSettings(); if (!filterSettings) { return; } if (m_inputOutputOptions->previewCheckBox->isChecked()) { emit sigAcceptOnCanvasPreview(); emit sigPreviewFilterCommand(filterSettings); } else { emit sigFilterCurrentImage(filterSettings); m_filterApplied = true; } } else // Tiny, Small, Medium, Large preview { KisGmicFilterSetting * filterSettings = currentFilterSettings(); if (filterSettings) { emit sigFilterCurrentImage(filterSettings); m_filterApplied = true; requestComputePreview(); } } } KisGmicFilterSetting* KisGmicWidget::currentFilterSettings() { KisGmicFilterSetting * filterSettings = 0; QVariant settings = m_filterTree->selectionModel()->currentIndex().data(FilterSettingsRole); if (settings.isValid()) { dbgPlugins << "Valid settings!"; filterSettings = settings.value(); filterSettings->setInputLayerMode(m_inputOutputOptions->inputMode()); filterSettings->setOutputMode(m_inputOutputOptions->outputMode()); filterSettings->setPreviewMode(m_inputOutputOptions->previewMode()); filterSettings->setPreviewSize(m_inputOutputOptions->previewSize()); dbgPlugins << "GMIC command : " << filterSettings->gmicCommand(); dbgPlugins << "GMIC preview command : " << filterSettings->previewGmicCommand(); } else { dbgPlugins << "Filter is not selected!"; } return filterSettings; } void KisGmicWidget::requestComputePreview() { KisGmicFilterSetting * filterSettings = currentFilterSettings(); if (filterSettings) { emit sigPreviewFilterCommand(filterSettings); if (m_onCanvasPreviewActivated) { m_onCanvasPreviewRequested = true; } } else { emit sigPreviewActiveLayer(); } } void KisGmicWidget::switchOptionsWidgetFor(QWidget* widget) { m_filterOptions = m_filterScrollArea->takeWidget(); delete m_filterOptions; m_filterOptions = widget; m_filterScrollArea->setWidget(m_filterOptions); m_filterOptions->show(); } KisFilterPreviewWidget * KisGmicWidget::previewWidget() { if (m_inputOutputOptions) { return m_inputOutputOptions->previewWidget(); } return 0; } void KisGmicWidget::slotNotImplemented() { QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("Sorry, support not implemented yet.")); } void KisGmicWidget::slotExpandCollapse() { const QString &iconName = expandCollapseBtn->icon().name(); if (iconName == "zoom-in") { m_filterTree->expandAll(); expandCollapseBtn->setIcon(KisIconUtils::loadIcon("zoom-out")); } else if (iconName == "zoom-out") { m_filterTree->collapseAll(); expandCollapseBtn->setIcon(KisIconUtils::loadIcon("zoom-in")); } } diff --git a/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.cpp b/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.cpp index 66f25eaa41..ec5db98f7d 100644 --- a/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.cpp +++ b/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.cpp @@ -1,82 +1,82 @@ /* This file is part of the KDE project * Copyright (C) 2007 Rob Buis * * 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 "SpiralShapeConfigWidget.h" #include "SpiralShapeConfigCommand.h" #include SpiralShapeConfigWidget::SpiralShapeConfigWidget() { widget.setupUi(this); widget.spiralType->clear(); widget.spiralType->addItem(i18n("Curve")); widget.spiralType->addItem(i18n("Line")); widget.fade->setMinimum(0.0); widget.fade->setMaximum(1.0); widget.clockWise->clear(); - widget.clockWise->addItem("ClockWise"); - widget.clockWise->addItem("Anti-ClockWise"); + widget.clockWise->addItem(i18n("ClockWise")); + widget.clockWise->addItem(i18n("Anti-ClockWise")); connect(widget.spiralType, SIGNAL(currentIndexChanged(int)), this, SIGNAL(propertyChanged())); connect(widget.clockWise, SIGNAL(currentIndexChanged(int)), this, SIGNAL(propertyChanged())); connect(widget.fade, SIGNAL(editingFinished()), this, SIGNAL(propertyChanged())); } void SpiralShapeConfigWidget::open(KoShape *shape) { m_spiral = dynamic_cast(shape); if (!m_spiral) { return; } widget.spiralType->blockSignals(true); widget.clockWise->blockSignals(true); widget.fade->blockSignals(true); widget.spiralType->setCurrentIndex(m_spiral->type()); widget.clockWise->setCurrentIndex(m_spiral->clockWise() ? 0 : 1); widget.fade->setValue(m_spiral->fade()); widget.spiralType->blockSignals(false); widget.clockWise->blockSignals(false); widget.fade->blockSignals(false); } void SpiralShapeConfigWidget::save() { if (!m_spiral) { return; } m_spiral->setType(static_cast(widget.spiralType->currentIndex())); m_spiral->setClockWise(widget.clockWise->currentIndex() == 0); m_spiral->setFade(widget.fade->value()); } KUndo2Command *SpiralShapeConfigWidget::createCommand() { if (!m_spiral) { return 0; } SpiralShape::SpiralType type = static_cast(widget.spiralType->currentIndex()); return new SpiralShapeConfigCommand(m_spiral, type, (widget.clockWise->currentIndex() == 0), widget.fade->value()); } diff --git a/plugins/tools/basictools/kis_tool_measure.cc b/plugins/tools/basictools/kis_tool_measure.cc index 30e3b42a95..4fd9401fe0 100644 --- a/plugins/tools/basictools/kis_tool_measure.cc +++ b/plugins/tools/basictools/kis_tool_measure.cc @@ -1,221 +1,221 @@ /* * * Copyright (c) 2007 Sven Langkamp * * 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_tool_measure.h" #include #include #include #include #include #include #include #include #include "kis_image.h" #include "kis_cursor.h" #include "KoPointerEvent.h" #include "KoCanvasBase.h" #include #define INNER_RADIUS 50 KisToolMeasureOptionsWidget::KisToolMeasureOptionsWidget(QWidget* parent, double resolution) : QWidget(parent), m_resolution(resolution), m_unit(KoUnit::Pixel) { m_distance = 0.0; QGridLayout* optionLayout = new QGridLayout(this); Q_CHECK_PTR(optionLayout); optionLayout->setMargin(0); - optionLayout->addWidget(new QLabel(i18n("Distance: "), this), 0, 0); - optionLayout->addWidget(new QLabel(i18n("Angle: "), this), 1, 0); + optionLayout->addWidget(new QLabel(i18n("Distance:"), this), 0, 0); + optionLayout->addWidget(new QLabel(i18n("Angle:"), this), 1, 0); m_distanceLabel = new QLabel(this); m_distanceLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); optionLayout->addWidget(m_distanceLabel, 0, 1); m_angleLabel = new QLabel(this); m_angleLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); optionLayout->addWidget(m_angleLabel, 1, 1); KComboBox* unitBox = new KComboBox(this); unitBox->addItems(KoUnit::listOfUnitNameForUi(KoUnit::ListAll)); connect(unitBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUnitChanged(int))); unitBox->setCurrentIndex(m_unit.indexInListForUi(KoUnit::ListAll)); optionLayout->addWidget(unitBox, 0, 2); - optionLayout->addWidget(new QLabel("deg", this), 1, 2); + optionLayout->addWidget(new QLabel(i18n("degree:"), this), 1, 2); optionLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), 2, 0, 1, 2); } void KisToolMeasureOptionsWidget::slotSetDistance(double distance) { m_distance = distance / m_resolution; updateDistance(); } void KisToolMeasureOptionsWidget::slotSetAngle(double angle) { m_angleLabel->setText(QString("%1").arg(angle, 5, 'f', 1)); } void KisToolMeasureOptionsWidget::slotUnitChanged(int index) { m_unit = KoUnit::fromListForUi(index, KoUnit::ListAll, m_resolution); updateDistance(); } void KisToolMeasureOptionsWidget::updateDistance() { m_distanceLabel->setText(QString("%1").arg(m_unit.toUserValue(m_distance), 5, 'f', 1)); } KisToolMeasure::KisToolMeasure(KoCanvasBase * canvas) : KisTool(canvas, KisCursor::crossCursor()) { m_startPos = QPointF(0, 0); m_endPos = QPointF(0, 0); } KisToolMeasure::~KisToolMeasure() { } void KisToolMeasure::paint(QPainter& gc, const KoViewConverter &converter) { qreal sx, sy; converter.zoom(&sx, &sy); gc.scale(sx / currentImage()->xRes(), sy / currentImage()->yRes()); QPen old = gc.pen(); QPen pen(Qt::SolidLine); gc.setPen(pen); gc.drawLine(m_startPos, m_endPos); if (deltaX() >= 0) gc.drawLine(QPointF(m_startPos.x(), m_startPos.y()), QPointF(m_startPos.x() + INNER_RADIUS, m_startPos.y())); else gc.drawLine(QPointF(m_startPos.x(), m_startPos.y()), QPointF(m_startPos.x() - INNER_RADIUS, m_startPos.y())); if (distance() >= INNER_RADIUS) { QRectF rectangle(m_startPos.x() - INNER_RADIUS, m_startPos.y() - INNER_RADIUS, 2*INNER_RADIUS, 2*INNER_RADIUS); int startAngle = (deltaX() >= 0) ? 0 : 180 * 16; int spanAngle; if ((deltaY() >= 0 && deltaX() >= 0) || (deltaY() < 0 && deltaX() < 0)) spanAngle = static_cast(angle() * 16); else spanAngle = static_cast(-angle() * 16); gc.drawArc(rectangle, startAngle, spanAngle); } gc.setPen(old); } void KisToolMeasure::beginPrimaryAction(KoPointerEvent *event) { setMode(KisTool::PAINT_MODE); // Erase old temporary lines canvas()->updateCanvas(convertToPt(boundingRect())); m_startPos = convertToPixelCoord(event); m_endPos = m_startPos; emit sigDistanceChanged(0.0); emit sigAngleChanged(0.0); } void KisToolMeasure::continuePrimaryAction(KoPointerEvent *event) { CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE); // Erase old temporary lines canvas()->updateCanvas(convertToPt(boundingRect())); QPointF pos = convertToPixelCoord(event); if (event->modifiers() == Qt::AltModifier) { QPointF trans = pos - m_endPos; m_startPos += trans; m_endPos += trans; } else { m_endPos = pos; } canvas()->updateCanvas(convertToPt(boundingRect())); emit sigDistanceChanged(distance()); emit sigAngleChanged(angle()); } void KisToolMeasure::endPrimaryAction(KoPointerEvent *event) { CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE); Q_UNUSED(event); setMode(KisTool::HOVER_MODE); } QWidget* KisToolMeasure::createOptionWidget() { if (!currentImage()) return 0; m_optionsWidget = new KisToolMeasureOptionsWidget(0, currentImage()->xRes()); // See https://bugs.kde.org/show_bug.cgi?id=316896 QWidget *specialSpacer = new QWidget(m_optionsWidget); specialSpacer->setObjectName("SpecialSpacer"); specialSpacer->setFixedSize(0, 0); m_optionsWidget->layout()->addWidget(specialSpacer); m_optionsWidget->setObjectName(toolId() + " option widget"); connect(this, SIGNAL(sigDistanceChanged(double)), m_optionsWidget, SLOT(slotSetDistance(double))); connect(this, SIGNAL(sigAngleChanged(double)), m_optionsWidget, SLOT(slotSetAngle(double))); m_optionsWidget->setFixedHeight(m_optionsWidget->sizeHint().height()); return m_optionsWidget; } double KisToolMeasure::angle() { return atan(qAbs(deltaY()) / qAbs(deltaX())) / (2*M_PI)*360; } double KisToolMeasure::distance() { return sqrt(deltaX()*deltaX() + deltaY()*deltaY()); } QRectF KisToolMeasure::boundingRect() { QRectF bound; bound.setTopLeft(m_startPos); bound.setBottomRight(m_endPos); bound = bound.united(QRectF(m_startPos.x() - INNER_RADIUS, m_startPos.y() - INNER_RADIUS, 2 * INNER_RADIUS, 2 * INNER_RADIUS)); return bound.normalized(); } diff --git a/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp index dbc241bfd4..1d06225d79 100644 --- a/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp @@ -1,107 +1,107 @@ /* 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 "CompositeEffectConfigWidget.h" #include "CompositeEffect.h" #include "KoFilterEffect.h" #include #include #include #include #include CompositeEffectConfigWidget::CompositeEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent) , m_effect(0) { QGridLayout *g = new QGridLayout(this); g->addWidget(new QLabel(i18n("Operation"), this), 0, 0); m_operation = new KComboBox(this); - m_operation->addItem("Over"); - m_operation->addItem("In"); - m_operation->addItem("Out"); - m_operation->addItem("Atop"); - m_operation->addItem("Xor"); - m_operation->addItem("Arithmetic"); + m_operation->addItem(i18n("Over")); + m_operation->addItem(i18n("In")); + m_operation->addItem(i18n("Out")); + m_operation->addItem(i18n("Atop")); + m_operation->addItem(i18n("Xor")); + m_operation->addItem(i18n("Arithmetic")); g->addWidget(m_operation, 0, 1); m_arithmeticWidget = new QWidget(this); QGridLayout *arithmeticLayout = new QGridLayout(m_arithmeticWidget); for (int i = 0; i < 4; ++i) { m_k[i] = new QDoubleSpinBox(m_arithmeticWidget); arithmeticLayout->addWidget(new QLabel(QString("k%1").arg(i + 1)), i / 2, (2 * i) % 4); arithmeticLayout->addWidget(m_k[i], i / 2, (2 * i + 1) % 4); connect(m_k[i], SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); } m_arithmeticWidget->setContentsMargins(0, 0, 0, 0); g->addWidget(m_arithmeticWidget, 1, 0, 1, 2); g->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 2, 0); connect(m_operation, SIGNAL(currentIndexChanged(int)), this, SLOT(operationChanged(int))); } bool CompositeEffectConfigWidget::editFilterEffect(KoFilterEffect *filterEffect) { m_effect = dynamic_cast(filterEffect); if (!m_effect) { return false; } m_operation->blockSignals(true); m_operation->setCurrentIndex(m_effect->operation()); m_operation->blockSignals(false); const qreal *k = m_effect->arithmeticValues(); for (int i = 0; i < 4; ++i) { m_k[i]->blockSignals(true); m_k[i]->setValue(k[i]); m_k[i]->blockSignals(false); } m_arithmeticWidget->setVisible(m_effect->operation() == CompositeEffect::Arithmetic); return true; } void CompositeEffectConfigWidget::operationChanged(int index) { m_arithmeticWidget->setVisible(index == 6); if (m_effect) { m_effect->setOperation(static_cast(index)); emit filterChanged(); } } void CompositeEffectConfigWidget::valueChanged() { if (!m_effect) { return; } qreal k[4] = {0}; for (int i = 0; i < 4; ++i) { k[i] = m_k[i]->value(); } m_effect->setArithmeticValues(k); emit filterChanged(); }