compositiondocker_dock.cpp 9.91 KB
Newer Older
Sven Langkamp's avatar
Sven Langkamp committed
1
2
3
/*
 *  Copyright (c) 2012 Sven Langkamp <sven.langkamp@gmail.com>
 *
4
 *  This library is free software; you can redistribute it and/or modify
Sven Langkamp's avatar
Sven Langkamp committed
5
 *  it under the terms of the GNU Lesser General Public License as published by
6
 *  the Free Software Foundation; version 2.1 of the License.
Sven Langkamp's avatar
Sven Langkamp committed
7
 *
8
 *  This library is distributed in the hope that it will be useful,
Sven Langkamp's avatar
Sven Langkamp committed
9
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU Lesser General Public License for more details.
Sven Langkamp's avatar
Sven Langkamp committed
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "compositiondocker_dock.h"

#include <QGridLayout>
#include <QListView>
#include <QHeaderView>
#include <QStyledItemDelegate>
#include <QPainter>
#include <QInputDialog>
#include <QThread>
#include <QAction>
28
#include <QDesktopServices>
29
#include <QMenu>
Sven Langkamp's avatar
Sven Langkamp committed
30

31
#include <klocalizedstring.h>
Halla Rempt's avatar
Halla Rempt committed
32
#include <kactioncollection.h>
Sven Langkamp's avatar
Sven Langkamp committed
33

34
#include <kis_icon.h>
Sven Langkamp's avatar
Sven Langkamp committed
35
#include <KoCanvasBase.h>
Yue Liu's avatar
Yue Liu committed
36
#include <KoFileDialog.h>
37

38
39
#include <KisPart.h>
#include <KisViewManager.h>
Sven Langkamp's avatar
Sven Langkamp committed
40
#include <kis_canvas2.h>
41
#include <KisDocument.h>
42
#include <kis_group_layer.h>
43
44
#include <kis_painter.h>
#include <kis_paint_layer.h>
45
46
#include <kis_action.h>
#include <kis_action_manager.h>
47
#include <kis_action_registry.h>
48
49
50

#include "compositionmodel.h"

Sven Langkamp's avatar
Sven Langkamp committed
51
52
53
54
55
56
57

CompositionDockerDock::CompositionDockerDock( ) : QDockWidget(i18n("Compositions")), m_canvas(0)
{
    QWidget* widget = new QWidget(this);
    setupUi(widget);
    m_model = new CompositionModel(this);
    compositionView->setModel(m_model);
58
    compositionView->installEventFilter(this);
59
60
61
    deleteButton->setIcon(KisIconUtils::loadIcon("edit-delete"));
    saveButton->setIcon(KisIconUtils::loadIcon("list-add"));
    exportButton->setIcon(KisIconUtils::loadIcon("document-export"));
Sven Langkamp's avatar
Sven Langkamp committed
62

63
64
65
66
67
    deleteButton->setToolTip(i18n("Delete Composition"));
    saveButton->setToolTip(i18n("New Composition"));
    exportButton->setToolTip(i18n("Export Composition"));


Sven Langkamp's avatar
Sven Langkamp committed
68
69
    setWidget(widget);

70
    connect( compositionView, SIGNAL(doubleClicked(QModelIndex)),
71
             this, SLOT(activated ( const QModelIndex & ) ) );
Sven Langkamp's avatar
Sven Langkamp committed
72

73
74
75
76
    compositionView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect( compositionView, SIGNAL(customContextMenuRequested(QPoint)),
             this, SLOT(customContextMenuRequested(QPoint)));

Sven Langkamp's avatar
Sven Langkamp committed
77
78
    connect( deleteButton, SIGNAL(clicked(bool)), this, SLOT(deleteClicked()));
    connect( saveButton, SIGNAL(clicked(bool)), this, SLOT(saveClicked()));
79
    connect( exportButton, SIGNAL(clicked(bool)), this, SLOT(exportClicked()));
80
    saveNameEdit->setPlaceholderText(i18n("Insert Name"));
81

Sven Langkamp's avatar
Sven Langkamp committed
82

Sven Langkamp's avatar
Sven Langkamp committed
83
84
85
86
}

CompositionDockerDock::~CompositionDockerDock()
{
87

Sven Langkamp's avatar
Sven Langkamp committed
88
89
90
91
}

void CompositionDockerDock::setCanvas(KoCanvasBase * canvas)
{
92
    if (m_canvas && m_canvas->viewManager()) {
93
        Q_FOREACH (KisAction *action, m_actions) {
94
95
96
97
            m_canvas->viewManager()->actionManager()->takeAction(action);
        }
    }

98
    unsetCanvas();
99
    setEnabled(canvas != 0);
100

Sven Langkamp's avatar
Sven Langkamp committed
101
    m_canvas = dynamic_cast<KisCanvas2*>(canvas);
102
    if (m_canvas && m_canvas->viewManager()) {
103
104
105
106
107
108
109
110
        if (m_actions.isEmpty()) {
            KisAction *updateAction = m_canvas->viewManager()->actionManager()->createAction("update_composition");
            connect(updateAction, SIGNAL(triggered()), this, SLOT(updateComposition()));
            m_actions.append(updateAction);

            KisAction *renameAction = m_canvas->viewManager()->actionManager()->createAction("rename_composition");
            connect(renameAction, SIGNAL(triggered()), this, SLOT(renameComposition()));
            m_actions.append(renameAction);
111
112
113
114
        } else {
            Q_FOREACH (KisAction *action, m_actions) {
                m_canvas->viewManager()->actionManager()->addAction(action->objectName(), action);
            }
115
116
        }
        updateModel();
117
    }
Sven Langkamp's avatar
Sven Langkamp committed
118
119
120
121
}

void CompositionDockerDock::unsetCanvas()
{
122
    setEnabled(false);
Sven Langkamp's avatar
Sven Langkamp committed
123
    m_canvas = 0;
124
    m_model->setCompositions(QList<KisLayerCompositionSP>());
Sven Langkamp's avatar
Sven Langkamp committed
125
126
127
128
}

void CompositionDockerDock::activated(const QModelIndex& index)
{
129
    KisLayerCompositionSP composition = m_model->compositionFromIndex(index);
Sven Langkamp's avatar
Sven Langkamp committed
130
131
132
133
134
135
    composition->apply();
}

void CompositionDockerDock::deleteClicked()
{
    QModelIndex index = compositionView->currentIndex();
136
    if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->image() && index.isValid()) {
137
        KisLayerCompositionSP composition = m_model->compositionFromIndex(index);
138
        m_canvas->viewManager()->image()->removeComposition(composition);
Sven Langkamp's avatar
Sven Langkamp committed
139
140
141
142
143
144
        updateModel();
    }
}

void CompositionDockerDock::saveClicked()
{
145
    KisImageWSP image = m_canvas->viewManager()->image();
146
147
    if (!image) return;

148
149
150
151
152
153
154
155
    // format as 001, 002 ...
    QString name = saveNameEdit->text();
    if (name.isEmpty()) {
        bool found = false;
        int i = 1;
        do {
            name = QString("%1").arg(i, 3, 10, QChar('0'));
            found = false;
156
            Q_FOREACH (KisLayerCompositionSP composition, m_canvas->viewManager()->image()->compositions()) {
157
158
159
160
161
162
163
164
                if (composition->name() == name) {
                    found = true;
                    break;
                }
            }
            i++;
        } while(found && i < 1000);
    }
165
    KisLayerCompositionSP composition(new KisLayerComposition(image, name));
Sven Langkamp's avatar
Sven Langkamp committed
166
167
168
169
    composition->store();
    image->addComposition(composition);
    saveNameEdit->clear();
    updateModel();
170
    compositionView->setCurrentIndex(m_model->index(image->compositions().count()-1, 0));
171
    image->setModified();
Sven Langkamp's avatar
Sven Langkamp committed
172
173
174
175
}

void CompositionDockerDock::updateModel()
{
176
177
178
    if (m_model && m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->image()) {
        m_model->setCompositions(m_canvas->viewManager()->image()->compositions());
    }
Sven Langkamp's avatar
Sven Langkamp committed
179
180
}

181
182
void CompositionDockerDock::exportClicked()
{
183
184
    if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->image()) {
        QString path;
185

186
        KoFileDialog dialog(0, KoFileDialog::OpenDirectory, "compositiondockerdock");
187
188
189
        dialog.setCaption(i18n("Select a Directory"));
        dialog.setDefaultDir(QDesktopServices::storageLocation(QDesktopServices::HomeLocation));
        path = dialog.filename();
190
191


192
        if (path.isNull()) return;
193

194
195
196
        if (!path.endsWith('/')) {
            path.append('/');
        }
197

198
199
200
201
202
        KisImageWSP image = m_canvas->viewManager()->image();
        QString filename = m_canvas->viewManager()->document()->localFilePath();
        if (!filename.isEmpty()) {
            QFileInfo info(filename);
            path += info.baseName() + '_';
203
204
        }

205
        Q_FOREACH (KisLayerCompositionSP composition, m_canvas->viewManager()->image()->compositions()) {
206
207
208
209
210
211
212
            if (!composition->isExportEnabled()) {
                continue;
            }

            composition->apply();
            image->refreshGraph();
            image->lock();
213
#if 0
214
            image->rootLayer()->projection()->convertToQImage(0, 0, 0, image->width(), image->height()).save(path + composition->name() + ".png");
215
#else
216
            QRect r = image->bounds();
217

218
            KisDocument *d = KisPart::instance()->createDocument();
219

220
221
222
223
224
225
226
            KisImageWSP dst = new KisImage(d->createUndoStore(), r.width(), r.height(), image->colorSpace(), composition->name());
            dst->setResolution(image->xRes(), image->yRes());
            d->setCurrentImage(dst);
            KisPaintLayer* paintLayer = new KisPaintLayer(dst, "projection", OPACITY_OPAQUE_U8);
            KisPainter gc(paintLayer->paintDevice());
            gc.bitBlt(QPoint(0, 0), image->rootLayer()->projection(), r);
            dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
227

228
            dst->refreshGraph();
229

230
            d->setOutputMimeType("image/png");
231
            d->setFileBatchMode(true);
232

233
            d->exportDocument(QUrl::fromLocalFile(path + composition->name() + ".png"));
234

235
            delete d;
236
237

#endif
238
239
            image->unlock();
        }
240
241
    }
}
Sven Langkamp's avatar
Sven Langkamp committed
242

243
244
bool CompositionDockerDock::eventFilter(QObject* obj, QEvent* event)
{
245
246
247
248
249
250
251
252
253
254
    if (event->type() == QEvent::KeyPress ) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) {
            // new index will be set after the method is called
            QTimer::singleShot(0, this, SLOT(activateCurrentIndex()));
        }
        return false;
    } else {
        return QObject::eventFilter(obj, event);
    }
255
256
257
258
259
260
261
262
263
264
}

void CompositionDockerDock::activateCurrentIndex()
{
    QModelIndex index = compositionView->currentIndex();
    if (index.isValid()) {
        activated(index);
    }
}

265
266
void CompositionDockerDock::customContextMenuRequested(QPoint pos)
{
267
268
    if (m_actions.isEmpty()) return;

269
    QMenu menu;
270
271
272
273
    Q_FOREACH (KisAction *action, m_actions) {
        menu.addAction(action);

    }
274
275
276
277
278
279
    menu.exec(compositionView->mapToGlobal(pos));
}

void CompositionDockerDock::updateComposition()
{
    QModelIndex index = compositionView->currentIndex();
280
    if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->image() && index.isValid()) {
281
        KisLayerCompositionSP composition = m_model->compositionFromIndex(index);
282
        composition->store();
283
        m_canvas->image()->setModified();
284
285
286
    }
}

Sven Langkamp's avatar
Sven Langkamp committed
287
288
void CompositionDockerDock::renameComposition()
{
Halla Rempt's avatar
Halla Rempt committed
289
    dbgKrita << "rename";
Sven Langkamp's avatar
Sven Langkamp committed
290
    QModelIndex index = compositionView->currentIndex();
291
    if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->image() && index.isValid()) {
292
        KisLayerCompositionSP composition = m_model->compositionFromIndex(index);
Sven Langkamp's avatar
Sven Langkamp committed
293
294
295
296
297
298
        bool ok;
        QString name = QInputDialog::getText(this, i18n("Rename Composition"),
                                             i18n("New Name:"), QLineEdit::Normal,
                                             composition->name(), &ok);
        if (ok && !name.isEmpty()) {
            composition->setName(name);
299
            m_canvas->image()->setModified();
Sven Langkamp's avatar
Sven Langkamp committed
300
301
302
        }
    }
}
303
304