File indexing completed on 2024-12-22 04:15:01

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Sven Langkamp <sven.langkamp@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "tasksetdocker_dock.h"
0008 
0009 #include <QGridLayout>
0010 #include <QListView>
0011 #include <QHeaderView>
0012 #include <QStyledItemDelegate>
0013 #include <QPainter>
0014 #include <QInputDialog>
0015 #include <QAction>
0016 #include <QMessageBox>
0017 
0018 #include <klocalizedstring.h>
0019 #include <kactioncollection.h>
0020 
0021 #include <kis_icon.h>
0022 
0023 #include <KoCanvasBase.h>
0024 #include <KisResourceItemChooser.h>
0025 #include <KisResourceLoader.h>
0026 #include <KisResourceItemListView.h>
0027 #include <KisResourceLoaderRegistry.h>
0028 #include <KisViewManager.h>
0029 #include <kis_canvas2.h>
0030 #include <KisMainWindow.h>
0031 #include <KisResourceUserOperations.h>
0032 
0033 #include "tasksetmodel.h"
0034 
0035 
0036 class KisTasksetDelegate : public QStyledItemDelegate
0037 {
0038 public:
0039     KisTasksetDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {}
0040     ~KisTasksetDelegate() override {}
0041     /// reimplemented
0042     QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const override {
0043         return QSize(QStyledItemDelegate::sizeHint(option, index).width(),
0044                      qMin(QStyledItemDelegate::sizeHint(option, index).width(), 25));
0045     }
0046 };
0047 
0048 class KisTasksetResourceDelegate : public QStyledItemDelegate
0049 {
0050 public:
0051     KisTasksetResourceDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {}
0052     ~KisTasksetResourceDelegate() override {}
0053     /// reimplemented
0054     void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
0055 };
0056 
0057 void KisTasksetResourceDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
0058 {
0059     if (! index.isValid())
0060         return;
0061 
0062     QString name = index.data(Qt::UserRole + KisAbstractResourceModel::Name).toString();
0063 
0064     if (option.state & QStyle::State_Selected) {
0065         painter->setPen(QPen(option.palette.highlight(), 2.0));
0066         painter->fillRect(option.rect, option.palette.highlight());
0067         painter->setPen(option.palette.highlightedText().color());
0068     }
0069     else {
0070         painter->setPen(option.palette.text().color());
0071     }
0072     int margin = option.rect.height() - painter->fontMetrics().height();
0073     margin = floor(margin/2);
0074     painter->drawText(option.rect.x() + 5, option.rect.y() + painter->fontMetrics().ascent() + margin, name);
0075 }
0076 
0077 TasksetDockerDock::TasksetDockerDock( )
0078     : QDockWidget(i18n("Task Sets"))
0079     , m_canvas(0)
0080     , m_blocked(false)
0081 {
0082     QWidget* widget = new QWidget(this);
0083     setupUi(widget);
0084     m_model = new TasksetModel(this);
0085     tasksetView->setModel(m_model);
0086     tasksetView->setItemDelegate(new KisTasksetDelegate(this));
0087     recordButton->setIcon(KisIconUtils::loadIcon("media-record"));
0088     recordButton->setCheckable(true);
0089 
0090     clearButton->setIcon(KisIconUtils::loadIcon("edit-delete"));
0091 
0092     saveButton->setIcon(KisIconUtils::loadIcon("document-save-16"));
0093     saveButton->setEnabled(false);
0094 
0095     chooserButton->setIcon(KisIconUtils::loadIcon("folder"));
0096     chooserButton->setAutoRaise(true);
0097 
0098     m_rserver = new KoResourceServer<TasksetResource>(ResourceType::TaskSets);
0099     KisResourceItemChooser *itemChooser = new KisResourceItemChooser(ResourceType::TaskSets, false, this);
0100     itemChooser->setItemDelegate(new KisTasksetResourceDelegate(this));
0101     itemChooser->setFixedSize(500, 250);
0102     itemChooser->setRowHeight(30);
0103     itemChooser->setListViewMode(ListViewMode::Detail);
0104     itemChooser->showTaggingBar(true);
0105     chooserButton->setPopupWidget(itemChooser);
0106 
0107     connect(itemChooser, SIGNAL(resourceSelected(KoResourceSP )), this, SLOT(resourceSelected(KoResourceSP )));
0108 
0109     setWidget(widget);
0110     setEnabled(false);
0111 
0112     connect( tasksetView, SIGNAL(clicked(QModelIndex)),
0113             this, SLOT(activated(QModelIndex)) );
0114 
0115     connect( recordButton, SIGNAL(toggled(bool)), this, SLOT(recordClicked()));
0116     connect( clearButton, SIGNAL(clicked(bool)), this, SLOT(clearClicked()));
0117     connect( saveButton, SIGNAL(clicked(bool)), this, SLOT(saveClicked()));
0118 }
0119 
0120 TasksetDockerDock::~TasksetDockerDock()
0121 {
0122     delete m_rserver;
0123 }
0124 
0125 void TasksetDockerDock::setCanvas(KoCanvasBase * canvas)
0126 {
0127     if (m_canvas && m_canvas->viewManager()) {
0128          m_canvas->viewManager()->actionCollection()->disconnect(this);
0129          Q_FOREACH (KisKXMLGUIClient* client, m_canvas->viewManager()->mainWindow()->childClients()) {
0130             client->actionCollection()->disconnect(this);
0131         }
0132     }
0133     m_canvas = dynamic_cast<KisCanvas2*>(canvas);
0134     setEnabled(canvas != 0);
0135 }
0136 
0137 void TasksetDockerDock::unsetCanvas()
0138 {
0139     m_canvas = 0;
0140     m_model->clear();
0141     setCanvas(0);
0142 }
0143 
0144 void TasksetDockerDock::actionTriggered(QAction* action)
0145 {
0146     if(action && !action->objectName().isEmpty() &&
0147        !m_blocked && recordButton->isChecked()) {
0148         m_model->addAction(action);
0149         saveButton->setEnabled(true);
0150     }
0151 }
0152 
0153 void TasksetDockerDock::activated(const QModelIndex& index)
0154 {
0155     QAction* action = m_model->actionFromIndex(index);
0156     m_blocked = true;
0157     if (action && action->isEnabled()) {
0158         action->trigger();
0159     }
0160     m_blocked = false;
0161 }
0162 
0163 void TasksetDockerDock::recordClicked()
0164 {
0165     if(m_canvas) {
0166         KisViewManager* view = m_canvas->viewManager();
0167         connect(view->actionCollection(), SIGNAL(actionTriggered(QAction*)),
0168                 this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection);
0169         Q_FOREACH (KisKXMLGUIClient* client, view->mainWindow()->childClients()) {
0170             connect(client->actionCollection(), SIGNAL(actionTriggered(QAction*)),
0171                     this, SLOT(actionTriggered(QAction*)), Qt::UniqueConnection);
0172         }
0173     }
0174 }
0175 
0176 void TasksetDockerDock::saveClicked()
0177 {
0178     QString name;
0179 
0180     TasksetResourceSP taskset(new TasksetResource(QString()));
0181 
0182     QStringList actionNames;
0183     Q_FOREACH (QAction* action, m_model->actions()) {
0184         actionNames.append(action->objectName());
0185     }
0186     taskset->setActionList(actionNames);
0187     taskset->setValid(true);
0188     QString saveLocation = m_rserver->saveLocation();
0189 
0190     if (name.isEmpty()) {
0191         name = i18n("Taskset");
0192     }
0193     QFileInfo fileInfo(saveLocation + name + taskset->defaultFileExtension());
0194 
0195     bool fileOverwriteAccepted = false;
0196     bool ok = false;
0197 
0198     while(!fileOverwriteAccepted) {
0199         name = QInputDialog::getText(this, i18n("Taskset Name"),
0200                                      i18n("Name:"), QLineEdit::Normal,
0201                                      QString(), &ok);
0202         if (name.isNull() || name.isEmpty()) {
0203             return;
0204         } else {
0205             fileInfo = QFileInfo(saveLocation + name.split(" ").join("_") + taskset->defaultFileExtension());
0206             if (fileInfo.exists()) {
0207                 int res = QMessageBox::warning(this, i18nc("@title:window", "Name Already Exists")
0208                                                         , i18n("The name '%1' already exists, do you wish to overwrite it?", name)
0209                                                         , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
0210                 if (res == QMessageBox::Yes) fileOverwriteAccepted = true;
0211             } else {
0212                 fileOverwriteAccepted = true;
0213             }
0214         }
0215     }
0216 
0217     taskset->setName(name);
0218     taskset->setFilename(fileInfo.fileName());
0219     KisResourceUserOperations::addResourceWithUserInput(this, taskset);
0220 }
0221 
0222 void TasksetDockerDock::clearClicked()
0223 {
0224     saveButton->setEnabled(false);
0225     m_model->clear();
0226 }
0227 
0228 void TasksetDockerDock::resourceSelected(KoResourceSP resource)
0229 {
0230     if(!m_canvas) {
0231         return;
0232     }
0233     m_model->clear();
0234     saveButton->setEnabled(true);
0235     Q_FOREACH (const QString& actionName, resource.staticCast<TasksetResource>()->actionList()) {
0236         QAction* action = m_canvas->viewManager()->actionCollection()->action(actionName);
0237         if(action) {
0238             m_model->addAction(action);
0239         }
0240     }
0241 }
0242 
0243 static void addResourceLoader()
0244 {
0245     KisResourceLoaderRegistry::instance()->registerLoader(new KisResourceLoader<TasksetResource>(ResourceType::TaskSets, ResourceType::TaskSets, i18n("Task sets"), QStringList() << "application/x-krita-taskset"));
0246 }
0247 
0248 Q_COREAPP_STARTUP_FUNCTION(addResourceLoader)