kis_paintop_box.cc 53.9 KB
Newer Older
1 2 3 4
/*
 *  kis_paintop_box.cc - part of KImageShop/Krayon/Krita
 *
 *  Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
Sven Langkamp's avatar
Sven Langkamp committed
5
 *  Copyright (c) 2009-2011 Sven Langkamp (sven.langkamp@gmail.com)
6
 *  Copyright (c) 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
7
 *  Copyright (C) 2011 Silvio Heinrich <plassy@web.de>
8
 *  Copyright (C) 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com>
9
 *  Copyright (c) 2014 Mohit Goyal <mohit.bits2011@gmail.com>
10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 *  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
23
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
 */
25 26

#include "kis_paintop_box.h"
27

28
#include <QHBoxLayout>
29
#include <QLabel>
30
#include <QToolButton>
31
#include <QPixmap>
32
#include <QWidgetAction>
33
#include <QApplication>
34
#include <QMenu>
35
#include <QTime>
36

37
#include <kis_debug.h>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
38 39

#include <kactioncollection.h>
Laurent Montel's avatar
Laurent Montel committed
40
#include <kacceleratormanager.h>
41
#include <QKeySequence>
42

43

44
#include <kis_icon.h>
45
#include <KoColorSpace.h>
46
#include <KoCompositeOpRegistry.h>
Sven Langkamp's avatar
Sven Langkamp committed
47
#include <KoResourceServerAdapter.h>
48
#include <KoToolManager.h>
49
#include <KoColorSpaceRegistry.h>
50

51
#include <kis_paint_device.h>
52 53 54
#include <brushengine/kis_paintop_registry.h>
#include <brushengine/kis_paintop_preset.h>
#include <brushengine/kis_paintop_settings.h>
55
#include <brushengine/kis_paintop_settings_update_proxy.h>
56
#include <kis_config_widget.h>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
57
#include <kis_image.h>
58
#include <kis_node.h>
59
#include <brushengine/kis_paintop_config_widget.h>
60
#include <kis_action.h>
61

62
#include "kis_canvas2.h"
63
#include "kis_node_manager.h"
64
#include "KisViewManager.h"
65
#include "kis_canvas_resource_provider.h"
66
#include "KisResourceServerProvider.h"
67
#include "kis_favorite_resource_manager.h"
68
#include "kis_config.h"
69

70
#include "kis_popup_button.h"
71
#include "widgets/kis_iconwidget.h"
72
#include "widgets/kis_tool_options_popup.h"
73
#include "widgets/kis_paintop_presets_popup.h"
74
#include "widgets/kis_paintop_presets_chooser_popup.h"
Sven Langkamp's avatar
Sven Langkamp committed
75
#include "widgets/kis_workspace_chooser.h"
76 77
#include "widgets/kis_paintop_list_widget.h"
#include "widgets/kis_slider_spin_box.h"
78
#include "widgets/kis_cmb_composite.h"
79 80
#include "widgets/kis_widget_chooser.h"
#include "tool/kis_tool.h"
81
#include "kis_signals_blocker.h"
82
#include "kis_action_manager.h"
83
#include "KisHighlightedToolButton.h"
84

85 86
typedef KoResourceServerSimpleConstruction<KisPaintOpPreset, SharedPointerStoragePolicy<KisPaintOpPresetSP> > KisPaintOpPresetResourceServer;
typedef KoResourceServerAdapter<KisPaintOpPreset, SharedPointerStoragePolicy<KisPaintOpPresetSP> > KisPaintOpPresetResourceServerAdapter;
87

88
KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *name)
89
    : QWidget(parent)
90
    , m_resourceProvider(view->canvasResourceProvider())
91
    , m_optionWidget(0)
92 93 94 95
    , m_toolOptionsPopupButton(0)
    , m_brushEditorPopupButton(0)
    , m_presetSelectorPopupButton(0)
    , m_toolOptionsPopup(0)
Boudewijn Rempt's avatar
Boudewijn Rempt committed
96
    , m_viewManager(view)
97
    , m_previousNode(0)
98
    , m_currTabletToolID(KoInputDevice::invalid())
99
    , m_presetsEnabled(true)
100
    , m_blockUpdate(false)
101
    , m_dirtyPresetsEnabled(false)
102
    , m_eraserBrushSizeEnabled(false)
103
    , m_eraserBrushOpacityEnabled(false)
104
{
105
    Q_ASSERT(view != 0);
106 107


108
    setObjectName(name);
109
    KisConfig cfg(true);
110
    m_dirtyPresetsEnabled = cfg.useDirtyPresets();
111
    m_eraserBrushSizeEnabled = cfg.useEraserBrushSize();
112
    m_eraserBrushOpacityEnabled = cfg.useEraserBrushOpacity();
113

114 115
    KAcceleratorManager::setNoAccel(this);

116
    setWindowTitle(i18n("Painter's Toolchest"));
117

118 119 120
    m_favoriteResourceManager = new KisFavoriteResourceManager(this);


121
    KConfigGroup grp =  KSharedConfig::openConfig()->group("krita").group("Toolbar BrushesAndStuff");
122
    int iconsize = grp.readEntry("IconSize", 32);
123

124 125
    if (!cfg.toolOptionsInDocker()) {
        m_toolOptionsPopupButton = new KisPopupButton(this);
126
        m_toolOptionsPopupButton->setIcon(KisIconUtils::loadIcon("configure"));
127 128 129 130
        m_toolOptionsPopupButton->setToolTip(i18n("Tool Settings"));
        m_toolOptionsPopupButton->setFixedSize(iconsize, iconsize);
    }

131
    m_brushEditorPopupButton = new KisIconWidget(this);
132
    m_brushEditorPopupButton->setIcon(KisIconUtils::loadIcon("paintop_settings_02"));
133 134 135 136
    m_brushEditorPopupButton->setToolTip(i18n("Edit brush settings"));
    m_brushEditorPopupButton->setFixedSize(iconsize, iconsize);

    m_presetSelectorPopupButton = new KisPopupButton(this);
137
    m_presetSelectorPopupButton->setIcon(KisIconUtils::loadIcon("paintop_settings_01"));
138 139
    m_presetSelectorPopupButton->setToolTip(i18n("Choose brush preset"));
    m_presetSelectorPopupButton->setFixedSize(iconsize, iconsize);
140

141
    m_eraseModeButton = new KisHighlightedToolButton(this);
142
    m_eraseModeButton->setFixedSize(iconsize, iconsize);
143
    m_eraseModeButton->setCheckable(true);
144

145
    m_eraseAction = m_viewManager->actionManager()->createAction("erase_action");
146
    m_eraseModeButton->setDefaultAction(m_eraseAction);
147

148
    m_reloadButton = new QToolButton(this);
149
    m_reloadButton->setFixedSize(iconsize, iconsize);
150

151
    m_reloadAction = m_viewManager->actionManager()->createAction("reload_preset_action");
152
    m_reloadButton->setDefaultAction(m_reloadAction);
153

154
    m_alphaLockButton = new KisHighlightedToolButton(this);
155
    m_alphaLockButton->setFixedSize(iconsize, iconsize);
156
    m_alphaLockButton->setCheckable(true);
157 158

    KisAction* alphaLockAction = m_viewManager->actionManager()->createAction("preserve_alpha");
159 160
    m_alphaLockButton->setDefaultAction(alphaLockAction);

161 162 163 164 165
    // horizontal and vertical mirror toolbar buttons

    // mirror tool options for the X Mirror
    QMenu *toolbarMenuXMirror = new QMenu();

166
    hideCanvasDecorationsX = m_viewManager->actionManager()->createAction("mirrorX-hideDecorations");
167 168
    toolbarMenuXMirror->addAction(hideCanvasDecorationsX);

169
    lockActionX = m_viewManager->actionManager()->createAction("mirrorX-lock");
170 171
    toolbarMenuXMirror->addAction(lockActionX);

172
    moveToCenterActionX = m_viewManager->actionManager()->createAction("mirrorX-moveToCenter");
173 174 175 176 177 178
    toolbarMenuXMirror->addAction(moveToCenterActionX);


    // mirror tool options for the Y Mirror
    QMenu *toolbarMenuYMirror = new QMenu();

179
    hideCanvasDecorationsY = m_viewManager->actionManager()->createAction("mirrorY-hideDecorations");
180 181 182
    toolbarMenuYMirror->addAction(hideCanvasDecorationsY);


183
    lockActionY = m_viewManager->actionManager()->createAction("mirrorY-lock");
184 185
    toolbarMenuYMirror->addAction(lockActionY);

186
    moveToCenterActionY = m_viewManager->actionManager()->createAction("mirrorY-moveToCenter");
187 188 189 190 191 192
    toolbarMenuYMirror->addAction(moveToCenterActionY);



    // create horizontal and vertical mirror buttons

193
    m_hMirrorButton = new KisHighlightedToolButton(this);
194 195
    int menuPadding = 10;
    m_hMirrorButton->setFixedSize(iconsize + menuPadding, iconsize);
196
    m_hMirrorButton->setCheckable(true);
197
    m_hMirrorAction = m_viewManager->actionManager()->createAction("hmirror_action");
198
    m_hMirrorButton->setDefaultAction(m_hMirrorAction);
199 200
    m_hMirrorButton->setMenu(toolbarMenuXMirror);
    m_hMirrorButton->setPopupMode(QToolButton::MenuButtonPopup);
201

202
    m_vMirrorButton = new KisHighlightedToolButton(this);
203
    m_vMirrorButton->setFixedSize(iconsize + menuPadding, iconsize);
204
    m_vMirrorButton->setCheckable(true);
205
    m_vMirrorAction = m_viewManager->actionManager()->createAction("vmirror_action");
206
    m_vMirrorButton->setDefaultAction(m_vMirrorAction);
207 208 209 210 211 212 213 214
    m_vMirrorButton->setMenu(toolbarMenuYMirror);
    m_vMirrorButton->setPopupMode(QToolButton::MenuButtonPopup);


    // add connections for horizontal and mirrror buttons
    connect(lockActionX, SIGNAL(toggled(bool)), this, SLOT(slotLockXMirrorToggle(bool)));
    connect(lockActionY, SIGNAL(toggled(bool)), this, SLOT(slotLockYMirrorToggle(bool)));

215 216
    connect(moveToCenterActionX, SIGNAL(triggered(bool)), this, SLOT(slotMoveToCenterMirrorX()));
    connect(moveToCenterActionY, SIGNAL(triggered(bool)), this, SLOT(slotMoveToCenterMirrorY()));
217 218 219

    connect(hideCanvasDecorationsX, SIGNAL(toggled(bool)), this, SLOT(slotHideDecorationMirrorX(bool)));
    connect(hideCanvasDecorationsY, SIGNAL(toggled(bool)), this, SLOT(slotHideDecorationMirrorY(bool)));
220

221 222 223 224 225 226 227 228 229
    const bool sliderLabels = cfg.sliderLabels();
    int sliderWidth;

    if (sliderLabels) {
        sliderWidth = 150 * logicalDpiX() / 96;
    }
    else {
        sliderWidth = 120 * logicalDpiX() / 96;
    }
230 231

    for (int i = 0; i < 3; ++i) {
232
        m_sliderChooser[i] = new KisWidgetChooser(i + 1);
233

234 235 236 237 238 239 240
        KisDoubleSliderSpinBox* slOpacity;
        KisDoubleSliderSpinBox* slFlow;
        KisDoubleSliderSpinBox* slSize;
        if (sliderLabels) {
            slOpacity = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("opacity");
            slFlow    = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("flow");
            slSize    = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("size");
241 242 243
            slOpacity->setPrefix(QString("%1 ").arg(i18n("Opacity:")));
            slFlow->setPrefix(QString("%1 ").arg(i18n("Flow:")));
            slSize->setPrefix(QString("%1 ").arg(i18n("Size:")));
244 245 246 247 248 249
        }
        else {
            slOpacity = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("opacity", i18n("Opacity:"));
            slFlow    = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("flow", i18n("Flow:"));
            slSize    = m_sliderChooser[i]->addWidget<KisDoubleSliderSpinBox>("size", i18n("Size:"));
        }
250

251 252 253
        slOpacity->setRange(0, 100, 0);
        slOpacity->setValue(100);
        slOpacity->setSingleStep(5);
254
        slOpacity->setSuffix(i18n("%"));
Moritz Molch's avatar
Moritz Molch committed
255
        slOpacity->setMinimumWidth(qMax(sliderWidth, slOpacity->sizeHint().width()));
256
        slOpacity->setFixedHeight(iconsize);
257
        slOpacity->setBlockUpdateSignalOnDrag(true);
258

259 260 261
        slFlow->setRange(0, 100, 0);
        slFlow->setValue(100);
        slFlow->setSingleStep(5);
262
        slFlow->setSuffix(i18n("%"));
Moritz Molch's avatar
Moritz Molch committed
263
        slFlow->setMinimumWidth(qMax(sliderWidth, slFlow->sizeHint().width()));
264
        slFlow->setFixedHeight(iconsize);
265
        slFlow->setBlockUpdateSignalOnDrag(true);
266

267
        slSize->setRange(0.01, cfg.readEntry("maximumBrushSize", 1000), 2);
268
        slSize->setValue(100);
269

270
        slSize->setSingleStep(1);
271
        slSize->setExponentRatio(3.0);
272
        slSize->setSuffix(i18n(" px"));
Moritz Molch's avatar
Moritz Molch committed
273
        slSize->setMinimumWidth(qMax(sliderWidth, slSize->sizeHint().width()));
274
        slSize->setFixedHeight(iconsize);
275
        slSize->setBlockUpdateSignalOnDrag(true);
276 277

        m_sliderChooser[i]->chooseWidget(cfg.toolbarSlider(i + 1));
278
    }
279

280
    m_cmbCompositeOp = new KisCompositeOpComboBox();
281
    m_cmbCompositeOp->setFixedHeight(iconsize);
282
    Q_FOREACH (KisAction * a, m_cmbCompositeOp->blendmodeActions()) {
283
        m_viewManager->actionManager()->addAction(a->text(), a);
284
    }
285

286
    m_workspaceWidget = new KisPopupButton(this);
287
    m_workspaceWidget->setIcon(KisIconUtils::loadIcon("view-choose"));
Sven Langkamp's avatar
Sven Langkamp committed
288
    m_workspaceWidget->setToolTip(i18n("Choose workspace"));
289
    m_workspaceWidget->setFixedSize(iconsize, iconsize);
Sven Langkamp's avatar
Sven Langkamp committed
290
    m_workspaceWidget->setPopupWidget(new KisWorkspaceChooser(view));
291

292 293 294
    QHBoxLayout* baseLayout = new QHBoxLayout(this);
    m_paintopWidget = new QWidget(this);
    baseLayout->addWidget(m_paintopWidget);
295
    baseLayout->setSpacing(4);
296
    baseLayout->setContentsMargins(0, 0, 0, 0);
297

298
    m_layout = new QHBoxLayout(m_paintopWidget);
299 300 301 302 303
    if (!cfg.toolOptionsInDocker()) {
        m_layout->addWidget(m_toolOptionsPopupButton);
    }
    m_layout->addWidget(m_brushEditorPopupButton);
    m_layout->addWidget(m_presetSelectorPopupButton);
304
    m_layout->setSpacing(4);
305
    m_layout->setContentsMargins(0, 0, 0, 0);
306

307 308 309 310
    QWidget* compositeActions = new QWidget(this);
    QHBoxLayout* compositeLayout = new QHBoxLayout(compositeActions);
    compositeLayout->addWidget(m_cmbCompositeOp);
    compositeLayout->addWidget(m_eraseModeButton);
311
    compositeLayout->addWidget(m_alphaLockButton);
312

313 314
    compositeLayout->setSpacing(4);
    compositeLayout->setContentsMargins(0, 0, 0, 0);
315

316 317
    compositeLayout->addWidget(m_reloadButton);

318
    QWidgetAction * action;
319

320
    action = new QWidgetAction(this);
321
    view->actionCollection()->addAction("composite_actions", action);
322
    action->setText(i18n("Brush composite"));
323 324
    action->setDefaultWidget(compositeActions);

325
    action = new QWidgetAction(this);
326
    KisActionRegistry::instance()->propertizeAction("brushslider1", action);
327
    view->actionCollection()->addAction("brushslider1", action);
328
    action->setDefaultWidget(m_sliderChooser[0]);
329
    connect(action, SIGNAL(triggered()), m_sliderChooser[0], SLOT(showPopupWidget()));
330
    connect(m_viewManager->mainWindow(), SIGNAL(themeChanged()), m_sliderChooser[0], SLOT(updateThemedIcons()));
331

332
    action = new QWidgetAction(this);
333
    KisActionRegistry::instance()->propertizeAction("brushslider2", action);
334 335
    view->actionCollection()->addAction("brushslider2", action);
    action->setDefaultWidget(m_sliderChooser[1]);
336
    connect(action, SIGNAL(triggered()), m_sliderChooser[1], SLOT(showPopupWidget()));
337
    connect(m_viewManager->mainWindow(), SIGNAL(themeChanged()), m_sliderChooser[1], SLOT(updateThemedIcons()));
338

339
    action = new QWidgetAction(this);
340
    KisActionRegistry::instance()->propertizeAction("brushslider3", action);
341 342 343
    view->actionCollection()->addAction("brushslider3", action);
    action->setDefaultWidget(m_sliderChooser[2]);
    connect(action, SIGNAL(triggered()), m_sliderChooser[2], SLOT(showPopupWidget()));
344
        connect(m_viewManager->mainWindow(), SIGNAL(themeChanged()), m_sliderChooser[2], SLOT(updateThemedIcons()));
345

346
    action = new QWidgetAction(this);
347
    KisActionRegistry::instance()->propertizeAction("next_favorite_preset", action);
348
    view->actionCollection()->addAction("next_favorite_preset", action);
349 350
    connect(action, SIGNAL(triggered()), this, SLOT(slotNextFavoritePreset()));

351
    action = new QWidgetAction(this);
352
    KisActionRegistry::instance()->propertizeAction("previous_favorite_preset", action);
353
    view->actionCollection()->addAction("previous_favorite_preset", action);
354 355
    connect(action, SIGNAL(triggered()), this, SLOT(slotPreviousFavoritePreset()));

356
    action = new QWidgetAction(this);
357
    KisActionRegistry::instance()->propertizeAction("previous_preset", action);
358
    view->actionCollection()->addAction("previous_preset", action);
359 360
    connect(action, SIGNAL(triggered()), this, SLOT(slotSwitchToPreviousPreset()));

361
    if (!cfg.toolOptionsInDocker()) {
362
        action = new QWidgetAction(this);
363
        KisActionRegistry::instance()->propertizeAction("show_tool_options", action);
364
        view->actionCollection()->addAction("show_tool_options", action);
365 366 367
        connect(action, SIGNAL(triggered()), m_toolOptionsPopupButton, SLOT(showPopupWidget()));
    }

368
    action = new QWidgetAction(this);
369
    KisActionRegistry::instance()->propertizeAction("show_brush_editor", action);
370
    view->actionCollection()->addAction("show_brush_editor", action);
371 372
    connect(action, SIGNAL(triggered()), m_brushEditorPopupButton, SLOT(showPopupWidget()));

373
    action = new QWidgetAction(this);
374
    KisActionRegistry::instance()->propertizeAction("show_brush_presets", action);
375
    view->actionCollection()->addAction("show_brush_presets", action);
376 377
    connect(action, SIGNAL(triggered()), m_presetSelectorPopupButton, SLOT(showPopupWidget()));

378 379
    QWidget* mirrorActions = new QWidget(this);
    QHBoxLayout* mirrorLayout = new QHBoxLayout(mirrorActions);
380 381
    mirrorLayout->addWidget(m_hMirrorButton);
    mirrorLayout->addWidget(m_vMirrorButton);
382
    mirrorLayout->setSpacing(4);
383
    mirrorLayout->setContentsMargins(0, 0, 0, 0);
384 385

    action = new QWidgetAction(this);
386
    KisActionRegistry::instance()->propertizeAction("mirror_actions", action);
387
    action->setDefaultWidget(mirrorActions);
388
    view->actionCollection()->addAction("mirror_actions", action);
389

390
    action = new QWidgetAction(this);
391
    KisActionRegistry::instance()->propertizeAction("workspaces", action);
392 393
    view->actionCollection()->addAction("workspaces", action);
    action->setDefaultWidget(m_workspaceWidget);
394

395 396 397 398 399 400
    if (!cfg.toolOptionsInDocker()) {
        m_toolOptionsPopup = new KisToolOptionsPopup();
        m_toolOptionsPopupButton->setPopupWidget(m_toolOptionsPopup);
        m_toolOptionsPopup->switchDetached(false);
    }

401

402 403 404
    m_savePresetWidget = new KisPresetSaveWidget(this);

    m_presetsPopup = new KisPaintOpPresetsPopup(m_resourceProvider, m_favoriteResourceManager, m_savePresetWidget);
405
    m_brushEditorPopupButton->setPopupWidget(m_presetsPopup);
406 407
    m_presetsPopup->parentWidget()->setWindowTitle(i18n("Brush Editor"));

408

409
    connect(m_presetsPopup, SIGNAL(brushEditorShown()), SLOT(slotUpdateOptionsWidgetPopup()));
410
    connect(m_viewManager->mainWindow(), SIGNAL(themeChanged()), m_presetsPopup, SLOT(updateThemedIcons()));
411

412
    m_presetsChooserPopup = new KisPaintOpPresetsChooserPopup();
413 414
    m_presetsChooserPopup->setMinimumHeight(550);
    m_presetsChooserPopup->setMinimumWidth(450);
415
    m_presetSelectorPopupButton->setPopupWidget(m_presetsChooserPopup);
416

417
    m_currCompositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
418

419
    slotNodeChanged(view->activeNode());
420 421 422 423
    // Get all the paintops
    QList<QString> keys = KisPaintOpRegistry::instance()->keys();
    QList<KisPaintOpFactory*> factoryList;

424
    Q_FOREACH (const QString & paintopId, keys) {
425 426 427 428
        factoryList.append(KisPaintOpRegistry::instance()->get(paintopId));
    }
    m_presetsPopup->setPaintOpList(factoryList);

429 430 431
    connect(m_presetsPopup       , SIGNAL(paintopActivated(QString))          , SLOT(slotSetPaintop(QString)));
    connect(m_presetsPopup       , SIGNAL(defaultPresetClicked())             , SLOT(slotSetupDefaultPreset()));
    connect(m_presetsPopup       , SIGNAL(signalResourceSelected(KoResource*)), SLOT(resourceSelected(KoResource*)));
432 433
    connect(m_presetsPopup       , SIGNAL(reloadPresetClicked())              , SLOT(slotReloadPreset()));
    connect(m_presetsPopup       , SIGNAL(dirtyPresetToggled(bool))           , SLOT(slotDirtyPresetToggled(bool)));
434
    connect(m_presetsPopup       , SIGNAL(eraserBrushSizeToggled(bool))       , SLOT(slotEraserBrushSizeToggled(bool)));
435
    connect(m_presetsPopup       , SIGNAL(eraserBrushOpacityToggled(bool))       , SLOT(slotEraserBrushOpacityToggled(bool)));
436

437 438
    connect(m_presetsPopup, SIGNAL(createPresetFromScratch(QString)), this, SLOT(slotCreatePresetFromScratch(QString)));

439
    connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*))      , SLOT(resourceSelected(KoResource*)));
440 441
    connect(m_presetsChooserPopup, SIGNAL(resourceClicked(KoResource*))      , SLOT(resourceSelected(KoResource*)));

442
    connect(m_resourceProvider   , SIGNAL(sigNodeChanged(KisNodeSP))    , SLOT(slotNodeChanged(KisNodeSP)));
443
    connect(m_cmbCompositeOp     , SIGNAL(currentIndexChanged(int))           , SLOT(slotSetCompositeMode(int)));
444 445
    connect(m_eraseAction          , SIGNAL(toggled(bool))                    , SLOT(slotToggleEraseMode(bool)));
    connect(alphaLockAction      , SIGNAL(toggled(bool))                    , SLOT(slotToggleAlphaLockMode(bool)));
446

447 448
    m_disablePressureAction = m_viewManager->actionManager()->createAction("disable_pressure");
    connect(m_disablePressureAction  , SIGNAL(toggled(bool))                    , SLOT(slotDisablePressureMode(bool)));
449
    m_disablePressureAction->setChecked(true);
450

451 452
    connect(m_hMirrorAction        , SIGNAL(toggled(bool))                    , SLOT(slotHorizontalMirrorChanged(bool)));
    connect(m_vMirrorAction        , SIGNAL(toggled(bool))                    , SLOT(slotVerticalMirrorChanged(bool)));
453
    connect(m_reloadAction         , SIGNAL(triggered())                        , SLOT(slotReloadPreset()));
454

455 456
    connect(m_sliderChooser[0]->getWidget<KisDoubleSliderSpinBox>("opacity"), SIGNAL(valueChanged(qreal)), SLOT(slotSlider1Changed()));
    connect(m_sliderChooser[0]->getWidget<KisDoubleSliderSpinBox>("flow")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider1Changed()));
457
    connect(m_sliderChooser[0]->getWidget<KisDoubleSliderSpinBox>("size")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider1Changed()));
458 459
    connect(m_sliderChooser[1]->getWidget<KisDoubleSliderSpinBox>("opacity"), SIGNAL(valueChanged(qreal)), SLOT(slotSlider2Changed()));
    connect(m_sliderChooser[1]->getWidget<KisDoubleSliderSpinBox>("flow")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider2Changed()));
460
    connect(m_sliderChooser[1]->getWidget<KisDoubleSliderSpinBox>("size")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider2Changed()));
461 462 463
    connect(m_sliderChooser[2]->getWidget<KisDoubleSliderSpinBox>("opacity"), SIGNAL(valueChanged(qreal)), SLOT(slotSlider3Changed()));
    connect(m_sliderChooser[2]->getWidget<KisDoubleSliderSpinBox>("flow")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider3Changed()));
    connect(m_sliderChooser[2]->getWidget<KisDoubleSliderSpinBox>("size")   , SIGNAL(valueChanged(qreal)), SLOT(slotSlider3Changed()));
Sven Langkamp's avatar
Sven Langkamp committed
464

465
    //Needed to connect canvas to favorite resource manager
466
    connect(m_viewManager->canvasResourceProvider(), SIGNAL(sigFGColorChanged(KoColor)), SLOT(slotUnsetEraseMode()));
467

468

469
    connect(m_resourceProvider, SIGNAL(sigFGColorUsed(KoColor)), m_favoriteResourceManager, SLOT(slotAddRecentColor(KoColor)));
470

471
    connect(m_resourceProvider, SIGNAL(sigFGColorChanged(KoColor)), m_favoriteResourceManager, SLOT(slotChangeFGColorSelector(KoColor)));
472
    connect(m_resourceProvider, SIGNAL(sigBGColorChanged(KoColor)), m_favoriteResourceManager, SLOT(slotSetBGColor(KoColor)));
473 474 475 476
    // cold initialization
    m_favoriteResourceManager->slotChangeFGColorSelector(m_resourceProvider->fgColor());
    m_favoriteResourceManager->slotSetBGColor(m_resourceProvider->bgColor());

477
    connect(m_favoriteResourceManager, SIGNAL(sigSetFGColor(KoColor)), m_resourceProvider, SLOT(slotSetFGColor(KoColor)));
478
    connect(m_favoriteResourceManager, SIGNAL(sigSetBGColor(KoColor)), m_resourceProvider, SLOT(slotSetBGColor(KoColor)));
479
    connect(m_favoriteResourceManager, SIGNAL(sigEnableChangeColor(bool)), m_resourceProvider, SLOT(slotResetEnableFGChange(bool)));
480 481

    connect(view->mainWindow(), SIGNAL(themeChanged()), this, SLOT(slotUpdateSelectionIcon()));
482 483
    connect(m_resourceProvider->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)),
            this, SLOT(slotCanvasResourceChanged(int,QVariant)));
484

485
    slotInputDeviceChanged(KoToolManager::instance()->currentInputDevice());
486

487
    KisPaintOpPresetResourceServer *rserver = KisResourceServerProvider::instance()->paintOpPresetServer();
488 489 490 491 492 493
    m_eraserName = "eraser_circle";
    m_defaultPresetName = "basic_tip_default";
    bool foundEraser = false;
    bool foundTip = false;
    for (int i=0; i<rserver->resourceCount(); i++) {
        KisPaintOpPresetSP resource = rserver->resources().at(i);
494
        if (resource->name().toLower().contains("eraser_circle")) {
495 496 497 498 499 500 501
            m_eraserName = resource->name();
            foundEraser = true;
        } else if (foundEraser == false && (resource->name().toLower().contains("eraser") ||
                                            resource->filename().toLower().contains("eraser"))) {
            m_eraserName = resource->name();
            foundEraser = true;
        }
502
        if (resource->name().toLower().contains("basic_tip_default")) {
503 504 505 506 507 508 509 510
            m_defaultPresetName = resource->name();
            foundTip = true;
        } else if (foundTip == false && (resource->name().toLower().contains("default") ||
                                         resource->filename().toLower().contains("default"))) {
            m_defaultPresetName = resource->name();
            foundTip = true;
        }
    }
511
}
512

513 514
KisPaintopBox::~KisPaintopBox()
{
515
    KisConfig cfg(false);
516 517 518 519
    QMapIterator<TabletToolID, TabletToolData> iter(m_tabletToolMap);
    while (iter.hasNext()) {
        iter.next();
        if ((iter.key().pointer) == QTabletEvent::Eraser) {
520
            cfg.writeEntry(QString("LastEraser") , iter.value().preset->name());
521 522
        }
        else {
523
            cfg.writeEntry(QString("LastPreset"), iter.value().preset->name());
524 525
        }
    }
luz paz's avatar
luz paz committed
526
    // Do not delete the widget, since it is global to the application, not owned by the view
527
    m_presetsPopup->setPaintOpSettingsWidget(0);
528
    qDeleteAll(m_paintopOptionWidgets);
529
    delete m_favoriteResourceManager;
530 531 532 533

    for (int i = 0; i < 3; ++i) {
        delete m_sliderChooser[i];
    }
534
}
Boudewijn Rempt's avatar
Boudewijn Rempt committed
535

536 537 538
void KisPaintopBox::restoreResource(KoResource* resource)
{
    KisPaintOpPreset* preset = dynamic_cast<KisPaintOpPreset*>(resource);
539

540
    if (preset) {
541
        setCurrentPaintop(preset);
542 543 544 545 546 547

        m_presetsPopup->setPresetImage(preset->image());
        m_presetsPopup->resourceSelected(resource);
    }
}

548 549 550 551 552 553 554
void KisPaintopBox::newOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList)
{
    if (m_toolOptionsPopup) {
        m_toolOptionsPopup->newOptionWidgets(optionWidgetList);
    }
}

555 556
void KisPaintopBox::resourceSelected(KoResource* resource)
{
557 558
    KIS_SAFE_ASSERT_RECOVER_RETURN(m_optionWidget);

559 560
    m_presetsPopup->setCreatingBrushFromScratch(false); // show normal UI elements when we are not creating

561
    KisPaintOpPreset* preset = dynamic_cast<KisPaintOpPreset*>(resource);
562
    if (preset && preset != m_resourceProvider->currentPreset()) {
563
        if (!preset->settings()->isLoadable())
564
            return;
565

566 567 568 569 570 571
        if (!m_dirtyPresetsEnabled) {
            KisSignalsBlocker blocker(m_optionWidget);
            if (!preset->load()) {
                warnKrita << "failed to load the preset.";
            }
        }
572
        //qDebug() << "resourceSelected" << resource->name();
573 574
        setCurrentPaintop(preset);

575 576 577
        m_presetsPopup->setPresetImage(preset->image());
        m_presetsPopup->resourceSelected(resource);
    }
578 579


580 581
}

582
void KisPaintopBox::setCurrentPaintop(const KoID& paintop)
583
{
584 585
    KisPaintOpPresetSP preset = activePreset(paintop);
    Q_ASSERT(preset && preset->settings());
586
    //qDebug() << "setCurrentPaintop();" << paintop << preset;
587
    setCurrentPaintop(preset);
588 589
}

590
void KisPaintopBox::setCurrentPaintop(KisPaintOpPresetSP preset)
591
{
592 593 594

    //qDebug() << "setCurrentPaintop(); " << preset->name();

595
    if (preset == m_resourceProvider->currentPreset()) {
596 597 598 599

        if (preset == m_tabletToolMap[m_currTabletToolID].preset) {
            return;
        }
600 601 602
    }
    Q_ASSERT(preset);
    const KoID& paintop = preset->paintOp();
603 604
    m_presetConnections.clear();

605
    if (m_resourceProvider->currentPreset()) {
606

607
        m_resourceProvider->setPreviousPaintOpPreset(m_resourceProvider->currentPreset());
608 609

        if (m_optionWidget) {
610 611
            m_optionWidget->hide();
        }
612

613 614
    }

615
    if (!m_paintopOptionWidgets.contains(paintop))
616
        m_paintopOptionWidgets[paintop] = KisPaintOpRegistry::instance()->get(paintop.id())->createConfigWidget(this);
617

618
    m_optionWidget = m_paintopOptionWidgets[paintop];
619

620 621
    KisSignalsBlocker b(m_optionWidget);

622
    preset->setOptionsWidget(m_optionWidget);
623

Boudewijn Rempt's avatar
Boudewijn Rempt committed
624 625
    m_optionWidget->setImage(m_viewManager->image());
    m_optionWidget->setNode(m_viewManager->activeNode());
626

627
    m_presetsPopup->setPaintOpSettingsWidget(m_optionWidget);
628

629 630
    m_resourceProvider->setPaintOpPreset(preset);

631
    Q_ASSERT(m_optionWidget && m_presetSelectorPopupButton);
632

633
    m_presetConnections.addConnection(m_optionWidget, SIGNAL(sigConfigurationUpdated()), this, SLOT(slotGuiChangedCurrentPreset()));
634 635
    m_presetConnections.addConnection(m_optionWidget, SIGNAL(sigSaveLockedConfig(KisPropertiesConfigurationSP)), this, SLOT(slotSaveLockedOptionToPreset(KisPropertiesConfigurationSP)));
    m_presetConnections.addConnection(m_optionWidget, SIGNAL(sigDropLockedConfig(KisPropertiesConfigurationSP)), this, SLOT(slotDropLockedOption(KisPropertiesConfigurationSP)));
636

637

638
    // load the current brush engine icon for the brush editor toolbar button
639

640
    m_brushEditorPopupButton->setResource(preset.data());
641 642
    m_presetsPopup->setCurrentPaintOpId(paintop.id());

643

644 645 646 647 648 649
    ////qDebug() << "\tsetting the new preset for" << m_currTabletToolID.uniqueID << "to" << preset->name();
    m_paintOpPresetMap[m_resourceProvider->currentPreset()->paintOp()] = preset;
    m_tabletToolMap[m_currTabletToolID].preset = preset;
    m_tabletToolMap[m_currTabletToolID].paintOpID = preset->paintOp();


650
    if (m_presetsPopup->currentPaintOpId() != paintop.id()) {
651 652
        // Must change the paintop as the current one is not supported
        // by the new colorspace.
653
        dbgKrita << "current paintop " << paintop.name() << " was not set, not supported by colorspace";
654
    }
655 656 657

    m_currCompositeOpID = preset->settings()->paintOpCompositeOp();
    updateCompositeOp(m_currCompositeOpID);
658 659
}

660
void KisPaintopBox::slotUpdateOptionsWidgetPopup()
661 662 663 664 665
{
    KisPaintOpPresetSP preset = m_resourceProvider->currentPreset();
    KIS_SAFE_ASSERT_RECOVER_RETURN(preset);
    KIS_SAFE_ASSERT_RECOVER_RETURN(m_optionWidget);

666
    m_optionWidget->setConfigurationSafe(preset->settings());
667

668 669
    m_presetsPopup->resourceSelected(preset.data());
    m_presetsPopup->updateViewSettings();
670 671 672 673

    // the m_viewManager->image() is set earlier, but the reference will be missing when the stamp button is pressed
    // need to later do some research on how and when we should be using weak shared pointers (WSP) that creates this situation
    m_optionWidget->setImage(m_viewManager->image());
674 675
}

676
KisPaintOpPresetSP KisPaintopBox::defaultPreset(const KoID& paintOp)
677
{
678
    QString defaultName = paintOp.id() + ".kpp";
679
    QString path = KoResourcePaths::findResource("kis_defaultpresets", defaultName);
680

681
    KisPaintOpPresetSP preset = new KisPaintOpPreset(path);
682

683
    if (!preset->load()) {
684
        preset = KisPaintOpRegistry::instance()->defaultPreset(paintOp);
685 686 687 688
    }

    Q_ASSERT(preset);
    Q_ASSERT(preset->valid());
689

690 691
    return preset;
}
692

693 694
KisPaintOpPresetSP KisPaintopBox::activePreset(const KoID& paintOp)
{
695
    if (m_paintOpPresetMap[paintOp] == 0) {
696
        m_paintOpPresetMap[paintOp] = defaultPreset(paintOp);
697
    }
698

699
    return m_paintOpPresetMap[paintOp];
700 701
}

702
void KisPaintopBox::updateCompositeOp(QString compositeOpID)
703
{
704 705 706
    if (!m_optionWidget) return;
    KisSignalsBlocker blocker(m_optionWidget);

707
    KisNodeSP node = m_resourceProvider->currentNode();
708 709 710

    if (node && node->paintDevice()) {
        if (!node->paintDevice()->colorSpace()->hasCompositeOp(compositeOpID))
711
            compositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
712

713 714 715 716
        {
            KisSignalsBlocker b1(m_cmbCompositeOp);
            m_cmbCompositeOp->selectCompositeOp(KoID(compositeOpID));
        }
717
        if (compositeOpID != m_currCompositeOpID) {
718 719
            m_currCompositeOpID = compositeOpID;
        }
720
        if (compositeOpID == COMPOSITE_ERASE || m_resourceProvider->eraserMode()) {
721 722 723 724 725
            m_eraseModeButton->setChecked(true);
        }
        else {
            m_eraseModeButton->setChecked(false);
        }
726
    }
727 728 729 730 731 732
    else if (!node) {
        KisSignalsBlocker b1(m_cmbCompositeOp);
        m_cmbCompositeOp->selectCompositeOp(KoID(compositeOpID));
        m_currCompositeOpID = compositeOpID;

    }
733 734 735 736
}

void KisPaintopBox::setWidgetState(int flags)
{
737
    if (flags & (ENABLE_COMPOSITEOP | DISABLE_COMPOSITEOP)) {
738 739 740
        m_cmbCompositeOp->setEnabled(flags & ENABLE_COMPOSITEOP);
        m_eraseModeButton->setEnabled(flags & ENABLE_COMPOSITEOP);
    }
741 742

    if (flags & (ENABLE_PRESETS | DISABLE_PRESETS)) {
743 744
        m_presetSelectorPopupButton->setEnabled(flags & ENABLE_PRESETS);
        m_brushEditorPopupButton->setEnabled(flags & ENABLE_PRESETS);
745
    }
746 747 748

    for (int i = 0; i < 3; ++i) {
        if (flags & (ENABLE_OPACITY | DISABLE_OPACITY))
749
            m_sliderChooser[i]->getWidget("opacity")->setEnabled(flags & ENABLE_OPACITY);
750 751

        if (flags & (ENABLE_FLOW | DISABLE_FLOW))
752
            m_sliderChooser[i]->getWidget("flow")->setEnabled(flags & ENABLE_FLOW);
753 754

        if (flags & (ENABLE_SIZE | DISABLE_SIZE))
755
            m_sliderChooser[i]->getWidget("size")->setEnabled(flags & ENABLE_SIZE);
756 757 758 759 760
    }
}

void KisPaintopBox::setSliderValue(const QString& sliderID, qreal value)
{
761
    for (int i = 0; i < 3; ++i) {
762
        KisDoubleSliderSpinBox* slider = m_sliderChooser[i]->getWidget<KisDoubleSliderSpinBox>(sliderID);
763
        KisSignalsBlocker b(slider);
764 765 766 767 768 769 770 771

        if (sliderID == "opacity" || sliderID == "flow") { // opacity and flows UI stored at 0-100%
            slider->setValue(value*100);
        } else {
            slider->setValue(value); // brush size
        }


772 773 774 775 776
    }
}

void KisPaintopBox::slotSetPaintop(const QString& paintOpId)
{
777
    if (KisPaintOpRegistry::instance()->get(paintOpId) != 0) {
778
        KoID id(paintOpId, KisPaintOpRegistry::instance()->get(paintOpId)->name());
779
        //qDebug() << "slotsetpaintop" << id;
780 781 782 783 784 785 786
        setCurrentPaintop(id);
    }
}

void KisPaintopBox::slotInputDeviceChanged(const KoInputDevice& inputDevice)
{
    TabletToolMap::iterator toolData = m_tabletToolMap.find(inputDevice);
787

788 789
    //qDebug() << "slotInputDeviceChanged()" << inputDevice.device() << inputDevice.uniqueTabletId();

790 791
    m_currTabletToolID = TabletToolID(inputDevice);

792
    if (toolData == m_tabletToolMap.end()) {
793
        KisConfig cfg(true);
794
        KisPaintOpPresetResourceServer *rserver = KisResourceServerProvider::instance()->paintOpPresetServer();
795 796
        KisPaintOpPresetSP preset;
        if (inputDevice.pointer() == QTabletEvent::Eraser) {
797
            preset = rserver->resourceByName(cfg.readEntry<QString>(QString("LastEraser_%1").arg(inputDevice.uniqueTabletId()), m_eraserName));
798
        }
799
        else {
800
            preset = rserver->resourceByName(cfg.readEntry<QString>(QString("LastPreset_%1").arg(inputDevice.uniqueTabletId()), m_defaultPresetName));
801 802 803
            //if (preset)
                //qDebug() << "found stored preset " << preset->name() << "for" << inputDevice.uniqueTabletId();
            //else
804
                //qDebug() << "no preset found for" << inputDevice.uniqueTabletId();
805 806
        }
        if (!preset) {
807
            preset = rserver->resourceByName(m_defaultPresetName);
808
        }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
809
        if (preset) {
810
            //qDebug() << "inputdevicechanged 1" << preset;
811
            setCurrentPaintop(preset);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
812
        }
813 814
    }
    else {
815
        if (toolData->preset) {
816
            //qDebug() << "inputdevicechanged 2" << toolData->preset;
817 818 819
            setCurrentPaintop(toolData->preset);
        }
        else {
820
            //qDebug() << "inputdevicechanged 3" << toolData->paintOpID;
821 822
            setCurrentPaintop(toolData->paintOpID);
        }
823
    }
824 825
}

826 827
void KisPaintopBox::slotCreatePresetFromScratch(QString paintop)
{
828 829 830 831
    //First try to select an available default preset for that engine. If it doesn't exist, then
    //manually set the engine to use a new preset.
    KoID id(paintop, KisPaintOpRegistry::instance()->get(paintop)->name());
    KisPaintOpPresetSP preset = defaultPreset(id);
832 833 834

    slotSetPaintop(paintop);  // change the paintop settings area and update the UI

835 836 837 838 839 840 841
    if (!preset) {
        m_presetsPopup->setCreatingBrushFromScratch(true); // disable UI elements while creating from scratch
        preset = m_resourceProvider->currentPreset();
    } else {
        m_resourceProvider->setPaintOpPreset(preset);
        preset->setOptionsWidget(m_optionWidget);
    }
842 843 844
    m_presetsPopup->resourceSelected(preset.data());  // this helps update the UI on the brush editor
}

845
void KisPaintopBox::slotCanvasResourceChanged(int key, const QVariant &value)
846
{
Boudewijn Rempt's avatar
Boudewijn Rempt committed
847
    if (m_viewManager) {
848
        sender()->blockSignals(true);
849
        KisPaintOpPresetSP preset = m_viewManager->canvasResourceProvider()->resourceManager()->resource(KisCanvasResourceProvider::CurrentPaintOpPreset).value<KisPaintOpPresetSP>();
850
        if (preset && m_resourceProvider->currentPreset()->name() != preset->name()) {
851 852 853 854
            QString compositeOp = preset->settings()->getString("CompositeOp");
            updateCompositeOp(compositeOp);
            resourceSelected(preset.data());
        }
855 856 857 858 859

        /**
         * Update currently selected preset in both the popup widgets
         */
        m_presetsChooserPopup->canvasResourceChanged(preset);
860

861
        m_presetsPopup->currentPresetChanged(preset);
862

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
        if (key == KisCanvasResourceProvider::CurrentCompositeOp) {
            if (m_resourceProvider->currentCompositeOp() != m_currCompositeOpID) {
                updateCompositeOp(m_resourceProvider->currentCompositeOp());
            }
        }

        if (key == KisCanvasResourceProvider::Size) {
            setSliderValue("size", m_resourceProvider->size());
        }

        if (key == KisCanvasResourceProvider::Opacity) {
            setSliderValue("opacity", m_resourceProvider->opacity());
        }

        if (key == KisCanvasResourceProvider::Flow) {
            setSliderValue("flow", m_resourceProvider->flow());
879
        }
880 881 882 883 884

        if (key == KisCanvasResourceProvider::EraserMode) {
            m_eraseAction->setChecked(value.toBool());
        }

885 886 887 888
        if (key == KisCanvasResourceProvider::DisablePressure) {
            m_disablePressureAction->setChecked(value.toBool());
        }

889 890 891 892 893 894 895 896
        if (key == KisCanvasResourceProvider::MirrorHorizontal) {
            m_hMirrorAction->setChecked(value.toBool());
        }

        if (key == KisCanvasResourceProvider::MirrorVertical) {
            m_vMirrorAction->setChecked(value.toBool());
        }

897 898 899 900
        sender()->blockSignals(false);
    }
}

901 902
void KisPaintopBox::slotSetupDefaultPreset()
{
903
    KisPaintOpPresetSP preset = defaultPreset(m_resourceProvider->currentPreset()->paintOp());
904 905
    preset->setOptionsWidget(m_optionWidget);
    m_resourceProvider->setPaintOpPreset(preset);
906 907 908 909

    // tell the brush editor that the resource has changed
    // so it can update everything
    m_presetsPopup->resourceSelected(preset.data());
910 911
}

912
void KisPaintopBox::slotNodeChanged(const KisNodeSP node)
913
{
914
    if (m_previousNode.isValid() && m_previousNode->paintDevice())
915
        disconnect(m_previousNode->paintDevice().data(), SIGNAL(colorSpaceChanged(const KoColorSpace*)), this, SLOT(slotColorSpaceChanged(const KoColorSpace*)));
916

917
    // Reconnect colorspace change of node
918
    if (node && node->paintDevice()) {
919 920 921 922
        connect(node->paintDevice().data(), SIGNAL(colorSpaceChanged(const KoColorSpace*)), this, SLOT(slotColorSpaceChanged(const KoColorSpace*)));
        m_resourceProvider->setCurrentCompositeOp(m_currCompositeOpID);
        m_previousNode = node;
        slotColorSpaceChanged(node->colorSpace());
923
    }
924

925 926
    if (m_optionWidget) {
        m_optionWidget->setNode(node);
927
    }
928 929
}

930
void KisPaintopBox::slotColorSpaceChanged(const KoColorSpace* colorSpace)
931
{
932
    m_cmbCompositeOp->validate(colorSpace);
933 934
}

935
void KisPaintopBox::slotToggleEraseMode(bool checked)
936
{
937
    const bool oldEraserMode = m_resourceProvider->eraserMode();
938
    m_resourceProvider->setEraserMode(checked);
939

940
    if (oldEraserMode != checked && m_eraserBrushSizeEnabled) {
941 942 943
        const qreal currentSize = m_resourceProvider->size();

        KisPaintOpSettingsSP settings = m_resourceProvider->currentPreset()->settings();
944

945 946 947 948 949 950 951 952 953 954 955
        // remember brush size. set the eraser size to the normal brush size if not set
        if (checked) {
            settings->setSavedBrushSize(currentSize);
            if (qFuzzyIsNull(settings->savedEraserSize())) {
                settings->setSavedEraserSize(currentSize);
            }
        } else {
            settings->setSavedEraserSize(currentSize);
            if (qFuzzyIsNull(settings->savedBrushSize())) {
                settings->setSavedBrushSize(currentSize);
            }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
956
        }
957

958
        //update value in UI (this is the main place the value is 'stored' in memory)
959 960
        qreal newSize = checked ? settings->savedEraserSize() : settings->savedBrushSize();
        m_resourceProvider->setSize(newSize);
961
    }
Timothée Giet's avatar
Timothée Giet committed
962
   if (oldEraserMode != checked && m_eraserBrushOpacityEnabled) {
963 964 965 966
        const qreal currentOpacity = m_resourceProvider->opacity();

        KisPaintOpSettingsSP settings = m_resourceProvider->currentPreset()->settings();

Timothée Giet's avatar
Timothée Giet committed