1 /*
2 * Copyright (c) 2011 Sven Langkamp <sven.langkamp@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "tasksetdocker_dock.h"
20
21 #include <QGridLayout>
22 #include <QListView>
23 #include <QHeaderView>
24 #include <QStyledItemDelegate>
25 #include <QPainter>
26 #include <QInputDialog>
27 #include <QAction>
28
29 #include <klocalizedstring.h>
30 #include <kactioncollection.h>
31
32 #include <kis_icon.h>
33
34 #include <KoCanvasBase.h>
35 #include <KoResourceItemChooser.h>
36 #include <KoResourceServerAdapter.h>
37 #include <KoResourceServerProvider.h>
38
39 #include <KisResourceServerProvider.h>
40 #include <KisViewManager.h>
41 #include <kis_canvas2.h>
42 #include <KisMainWindow.h>
43 #include "tasksetmodel.h"
44
45
46 class KisTasksetDelegate : public QStyledItemDelegate
47 {
48 public:
KisTasksetDelegate(QObject * parent=0)49 KisTasksetDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {}
~KisTasksetDelegate()50 ~KisTasksetDelegate() override {}
51 /// reimplemented
sizeHint(const QStyleOptionViewItem & option,const QModelIndex & index) const52 QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const override {
53 return QSize(QStyledItemDelegate::sizeHint(option, index).width(),
54 qMin(QStyledItemDelegate::sizeHint(option, index).width(), 25));
55 }
56 };
57
58 class KisTasksetResourceDelegate : public QStyledItemDelegate
59 {
60 public:
KisTasksetResourceDelegate(QObject * parent=0)61 KisTasksetResourceDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {}
~KisTasksetResourceDelegate()62 ~KisTasksetResourceDelegate() override {}
63 /// reimplemented
64 void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
65 };
66
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const67 void KisTasksetResourceDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
68 {
69 if (! index.isValid())
70 return;
71
72 TasksetResource* taskset = static_cast<TasksetResource*>(index.internalPointer());
73
74 if (option.state & QStyle::State_Selected) {
75 painter->setPen(QPen(option.palette.highlight(), 2.0));
76 painter->fillRect(option.rect, option.palette.highlight());
77 painter->setBrush(option.palette.highlightedText());
78 }
79 else {
80 painter->setBrush(option.palette.text());
81 }
82
83 painter->drawText(option.rect.x() + 5, option.rect.y() + painter->fontMetrics().ascent() + 5, taskset->name());
84
85 }
86
TasksetDockerDock()87 TasksetDockerDock::TasksetDockerDock( ) : QDockWidget(i18n("Task Sets")), m_canvas(0), m_blocked(false)
88 {
89 QWidget* widget = new QWidget(this);
90 setupUi(widget);
91 m_model = new TasksetModel(this);
92 tasksetView->setModel(m_model);
93 tasksetView->setItemDelegate(new KisTasksetDelegate(this));
94 recordButton->setIcon(KisIconUtils::loadIcon("media-record"));
95 recordButton->setCheckable(true);
96 clearButton->setIcon(KisIconUtils::loadIcon("edit-delete"));
97 saveButton->setIcon(KisIconUtils::loadIcon("document-save"));
98 saveButton->setEnabled(false);
99
100 chooserButton->setIcon(KisIconUtils::loadIcon("edit-copy"));
101
102 m_rserver = new KoResourceServerSimpleConstruction<TasksetResource>("kis_taskset", "*.kts");
103 if (!QFileInfo(m_rserver->saveLocation()).exists()) {
104 QDir().mkpath(m_rserver->saveLocation());
105 }
106 QSharedPointer<KoAbstractResourceServerAdapter> adapter (new KoResourceServerAdapter<TasksetResource>(m_rserver));
107 m_rserver->loadResources(KoResourceServerProvider::blacklistFileNames(m_rserver->fileNames(), m_rserver->blackListedFiles()));
108 m_rserver->loadTags();
109
110 KoResourceItemChooser* itemChooser = new KoResourceItemChooser(adapter, this);
111 itemChooser->setItemDelegate(new KisTasksetResourceDelegate(this));
112 itemChooser->setFixedSize(500, 250);
113 itemChooser->setRowHeight(30);
114 itemChooser->setColumnCount(1);
115 itemChooser->showTaggingBar(true);
116 chooserButton->setPopupWidget(itemChooser);
117
118 connect(itemChooser, SIGNAL(resourceSelected(KoResource*)), this, SLOT(resourceSelected(KoResource*)));
119
120 setWidget(widget);
121
122 connect( tasksetView, SIGNAL(clicked(QModelIndex)),
123 this, SLOT(activated(QModelIndex)) );
124
125 connect( recordButton, SIGNAL(toggled(bool)), this, SLOT(recordClicked()));
126 connect( clearButton, SIGNAL(clicked(bool)), this, SLOT(clearClicked()));
127 connect( saveButton, SIGNAL(clicked(bool)), this, SLOT(saveClicked()));
128 }
129
~TasksetDockerDock()130 TasksetDockerDock::~TasksetDockerDock()
131 {
132 delete m_rserver;
133 }
134
setCanvas(KoCanvasBase * canvas)135 void TasksetDockerDock::setCanvas(KoCanvasBase * canvas)
136 {
137 if (m_canvas && m_canvas->viewManager()) {
138 m_canvas->viewManager()->actionCollection()->disconnect(this);
139 Q_FOREACH (KXMLGUIClient* client, m_canvas->viewManager()->mainWindow()->childClients()) {
140 client->actionCollection()->disconnect(this);
141 }
142 }
143 m_canvas = dynamic_cast<KisCanvas2*>(canvas);
144 }
145
unsetCanvas()146 void TasksetDockerDock::unsetCanvas()
147 {
148 m_canvas = 0;
149 m_model->clear();
150 }
151
actionTriggered(QAction * action)152 void TasksetDockerDock::actionTriggered(QAction* action)
153 {
154 if(action && !action->objectName().isEmpty() &&
155 !m_blocked && recordButton->isChecked()) {
156 m_model->addAction(action);
157 saveButton->setEnabled(true);
158 }
159 }
160
activated(const QModelIndex & index)161 void TasksetDockerDock::activated(const QModelIndex& index)
162 {
163 QAction* action = m_model->actionFromIndex(index);
164 m_blocked = true;
165 action->trigger();
166 m_blocked = false;
167 }
168
recordClicked()169 void TasksetDockerDock::recordClicked()
170 {
171 if(m_canvas) {
172 KisViewManager* view = m_canvas->viewManager();
173 connect(view->actionCollection(), SIGNAL(actionTriggered(QAction*)),
174 this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection);
175 Q_FOREACH (KXMLGUIClient* client, view->mainWindow()->childClients()) {
176 connect(client->actionCollection(), SIGNAL(actionTriggered(QAction*)),
177 this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection);
178 }
179 }
180 }
181
saveClicked()182 void TasksetDockerDock::saveClicked()
183 {
184 bool ok;
185 QString name = QInputDialog::getText(this, i18n("Taskset Name"),
186 i18n("Name:"), QLineEdit::Normal,
187 QString(), &ok);
188 if (!ok) {
189 return;
190 }
191
192 TasksetResource* taskset = new TasksetResource(QString());
193
194 QStringList actionNames;
195 Q_FOREACH (QAction* action, m_model->actions()) {
196 actionNames.append(action->objectName());
197 }
198 taskset->setActionList(actionNames);
199 taskset->setValid(true);
200 QString saveLocation = m_rserver->saveLocation();
201
202 bool newName = false;
203 if(name.isEmpty()) {
204 newName = true;
205 name = i18n("Taskset");
206 }
207 QFileInfo fileInfo(saveLocation + name + taskset->defaultFileExtension());
208
209 int i = 1;
210 while (fileInfo.exists()) {
211 fileInfo.setFile(saveLocation + name + QString("%1").arg(i) + taskset->defaultFileExtension());
212 i++;
213 }
214 taskset->setFilename(fileInfo.filePath());
215 if(newName) {
216 name = i18n("Taskset %1", i);
217 }
218 taskset->setName(name);
219 m_rserver->addResource(taskset);
220 }
221
clearClicked()222 void TasksetDockerDock::clearClicked()
223 {
224 saveButton->setEnabled(false);
225 m_model->clear();
226 }
227
resourceSelected(KoResource * resource)228 void TasksetDockerDock::resourceSelected(KoResource* resource)
229 {
230 if(!m_canvas) {
231 return;
232 }
233 m_model->clear();
234 saveButton->setEnabled(true);
235 Q_FOREACH (const QString& actionName, static_cast<TasksetResource*>(resource)->actionList()) {
236 QAction* action = m_canvas->viewManager()->actionCollection()->action(actionName);
237 if(action) {
238 m_model->addAction(action);
239 }
240 }
241 }
242
243