diff --git a/plugins/dockers/storyboarddocker/CMakeLists.txt b/plugins/dockers/storyboarddocker/CMakeLists.txt index ccda2768b7..8bf71f781b 100644 --- a/plugins/dockers/storyboarddocker/CMakeLists.txt +++ b/plugins/dockers/storyboarddocker/CMakeLists.txt @@ -1,28 +1,30 @@ #add_subdirectory(tests) set(KRITA_STORYBOARDDOCKER_SOURCES commentModel.cpp storyboarddocker.cpp storyboarddocker_dock.cpp commentDelegate.cpp -# storyboardModel.cpp + storyboardModel.cpp + storyboardItem.cpp ) set(KRITA_STORYBOARDDOCKER_PART_HEADERS commentModel.h storyboarddocker.h storyboarddocker_dock.h commentDelegate.h -# storyboardModel.h + storyboardModel.h + storyboardItem.h ) ki18n_wrap_ui(KRITA_STORYBOARDDOCKER_SOURCES wdgstoryboarddock.ui wdgarrangemenu.ui wdgcommentmenu.ui ) add_library(kritastoryboarddocker MODULE ${KRITA_STORYBOARDDOCKER_SOURCES} ${KRITA_STORYBOARDDOCKER_PART_HEADERS} ) target_link_libraries(kritastoryboarddocker kritaui) install(TARGETS kritastoryboarddocker DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/dockers/storyboarddocker/storyboardItem.cpp b/plugins/dockers/storyboarddocker/storyboardItem.cpp index 4b0ebc816f..e8aeb96590 100644 --- a/plugins/dockers/storyboarddocker/storyboardItem.cpp +++ b/plugins/dockers/storyboarddocker/storyboardItem.cpp @@ -1,57 +1,61 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 "storyboardItem.h" //create 3 rows by default StoryboardItem::StoryboardItem() -{} +{ + insertChild(childCount(), 1); + insertChild(childCount(), QString("scene 1")); + insertChild(childCount(), 100); +} StoryboardItem::~StoryboardItem() { qDeleteAll(m_childData); } -void StoryboardItem::appendChild(QVariant &data) +void StoryboardItem::appendChild(QVariant data) { StoryboardChild* child = new StoryboardChild(data, this); m_childData.append(child); } -void StoryboardItem::insertChild(int row, QVariant &data) +void StoryboardItem::insertChild(int row, QVariant data) { StoryboardChild* child = new StoryboardChild(data, this); m_childData.insert(row, child); } void StoryboardItem::removeChild(int row) { m_childData.removeAt(row); } int StoryboardItem::childCount() const { return m_childData.count(); } StoryboardChild* StoryboardItem::child(int row) { if (row < 0 || row >= m_childData.size()) return nullptr; return m_childData.at(row); } diff --git a/plugins/dockers/storyboarddocker/storyboardItem.h b/plugins/dockers/storyboarddocker/storyboardItem.h index 348c58892e..55dc0978c0 100644 --- a/plugins/dockers/storyboarddocker/storyboardItem.h +++ b/plugins/dockers/storyboarddocker/storyboardItem.h @@ -1,71 +1,71 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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. */ #ifndef STORYBOARD_ITEM #define STORYBOARD_ITEM #include #include //each storyboardItem contains pointer to child data class StoryboardItem; class StoryboardChild { public: - StoryboardChild(QVariant &data, StoryboardItem *parent) + StoryboardChild(QVariant data, StoryboardItem *parent) : m_data(data) , m_parentItem(parent) {} - StoryboardItem parent(){ return *m_parentItem;} + StoryboardItem *parent(){ return m_parentItem;} QVariant data(){ return m_data;} //returns the row number of this child relative to its parent - int row() const{ + /*int row() const{ if (m_parentItem) return m_parentItem->m_childData.indexOf(const_cast(this)); return 0; } - void setData(QVariant &value){ + */ + void setData(QVariant value){ m_data = value; } private: - StoryboardItem *m_parentItem; QVariant m_data; + StoryboardItem *m_parentItem; }; class StoryboardItem { public: //see later if the constructor needs data explicit StoryboardItem(/*const QVector &data*/); ~StoryboardItem(); - void appendChild(int row, QVariant &data); - void insertChild(int row, QVariant &data); + void appendChild(QVariant data); + void insertChild(int row, QVariant data); void removeChild(int row); - void childCount() const; + int childCount() const; StoryboardChild *child(int row); - QPointer parent(){ - return nullptr; - } private: QVector m_childData; }; + +#endif diff --git a/plugins/dockers/storyboarddocker/storyboardModel.cpp b/plugins/dockers/storyboarddocker/storyboardModel.cpp index a6f3890336..5548be0df3 100644 --- a/plugins/dockers/storyboarddocker/storyboardModel.cpp +++ b/plugins/dockers/storyboarddocker/storyboardModel.cpp @@ -1,221 +1,225 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 "storyboardModel.h" #include #include StoryboardModel::StoryboardModel(QObject *parent) - : QAbstractTableModel(parent) + : QAbstractItemModel(parent) {} QModelIndex StoryboardModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (row < 0 || row >= rowCount()) return QModelIndex(); if (column !=0) return QModelIndex(); - //top level node has invalid parent - if (!parent.isValid) + //1st level node has invalid parent + if (!parent.isValid()){ return createIndex(row, column, m_items.at(row)); - else + } + else if (!parent.parent().isValid()){ StoryboardItem *parentItem = static_cast(parent.internalPointer()); - - TreeItem *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); + StoryboardChild *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + } return QModelIndex(); } QModelIndex StoryboardModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); - //return parent only for 2nd level nodes - StoryboardChild *childItem = dynamic_cast(index.internalPointer()); - if(childItem){ - StoryboardItem *parentItem = childItem->parent(); - int indexOfParent = m_items.indexOf(const_cast(parentItem)); - return createIndex(indexOfParent, 0, parentItem); + { + //no parent for 1st level node + StoryboardItem *childItem = static_cast(index.internalPointer()); + if (m_items.contains(childItem)){ + return QModelIndex(); + } } - return QModelIndex(); + + //return parent only for 2nd level nodes + StoryboardChild *childItem = static_cast(index.internalPointer()); + StoryboardItem *parentItem = childItem->parent(); + int indexOfParent = m_items.indexOf(const_cast(parentItem)); + return createIndex(indexOfParent, 0, parentItem); } int StoryboardModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) return m_items.count(); - else if (dynamic_cast(parent.internalPointer())){ - StoryboardItem parentItem = dynamic_cast(parent.internalPointer()); + else if (!parent.parent().isValid()){ + StoryboardItem *parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } return 0; //2nd level nodes have no child } int StoryboardModel::columnCount(const QModelIndex &parent) const { - //2nd level nodes have no child - if (dynamic_cast(parent.internalPointer())){ - return 0; + if (!parent.isValid()){ + return 1; } - return 1; + //1st level nodes have 1 column + if (!parent.parent().isValid()){ + return 1; + } + //end level nodes have no child + return 0; } QVariant StoryboardModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() >= m_items.size()) return QVariant(); //return data only for the storyboardChild i.e. 2nd level nodes - if (dynamic_cast(index.internalPointer())) + if (!index.parent().isValid()) return QVariant(); if (role == Qt::DisplayRole || role == Qt::EditRole) { StoryboardChild *child = static_cast(index.internalPointer()); - child->data().toS - if (child){ - switch (index.row()): + switch (index.row()){ case 0: //frame number return child->data().toInt(); case 1: //item name return child->data().toString(); case 2: //duration return child->data().toInt(); default: //comment(would it be string or a custom struct) return child->data().toInt(); } } return QVariant(); } bool StoryboardModel::setData(const QModelIndex & index, const QVariant & value, int role) { //qDebug()<<"attempting data set"<(index.internalPointer())) - return false; - if (index.isValid() && (role == Qt::EditRole || role == Qt::DisplayRole)) { + if (!index.parent().isValid()) + return false; + StoryboardChild *child = static_cast(index.internalPointer()); if (child){ child->setData(value); emit dataChanged(index, index); return true; } } return false; } Qt::ItemFlags StoryboardModel::flags(const QModelIndex & index) const { //qDebug()<<"flags requested"; if(!index.isValid()) return Qt::ItemIsDropEnabled; //1st level nodes - if (dynamic_cast(index.internalPointer())) - return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable ; + if (!index.parent().isValid()) + return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; //2nd level nodes return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool StoryboardModel::insertRows(int position, int rows, const QModelIndex &parent) { - //we can't insert to 2nd level nodes as they are leaf nodes - if (dynamic_cast(parent.internalPointer())){ - return false; - } - //insert 1st level nodes + qDebug()<<"row inserted"; if (!parent.isValid()){ beginInsertRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { - StoryboardItem newItem = new StoryboardItem(); + StoryboardItem *newItem = new StoryboardItem(); m_items.insert(position, newItem); } endInsertRows(); return true; } //insert 2nd level nodes - StoryboardItem *item = dynamic_cast(index.internalPointer()); - if (item){ + if (!parent.parent().isValid()){ + StoryboardItem *item = static_cast(parent.internalPointer()); beginInsertRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { item->insertChild(position, QVariant()); } endInsertRows(); return true; } + //we can't insert to 2nd level nodes as they are leaf nodes return false; } bool StoryboardModel::removeRows(int position, int rows, const QModelIndex &parent) { qDebug()<<"row removed"; - //2nd level node has no child - if (dynamic_cast(parent.internalPointer())){ - return false; - } //remove 1st level nodes if (!parent.isValid()){ beginRemoveRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { delete m_items.at(row); m_items.removeAt(position); } endRemoveRows(); return true; } //remove 2nd level nodes - StoryboardItem *item = dynamic_cast(index.internalPointer()); - if (item){ - beginRemoveRows(QModelIndex(), position, position+rows-1); - for (int row = 0; row < rows; ++row) { - item->removeChild(position); + if (!parent.parent().isValid()){ + StoryboardItem *item = static_cast(parent.internalPointer()); + if (m_items.contains(item)){ + beginRemoveRows(QModelIndex(), position, position+rows-1); + for (int row = 0; row < rows; ++row) { + item->removeChild(position); + } + endRemoveRows(); + return true; } - endRemoveRows(); - return true; } + //2nd level node has no child return false; } Qt::DropActions StoryboardModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions StoryboardModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } diff --git a/plugins/dockers/storyboarddocker/storyboardModel.h b/plugins/dockers/storyboarddocker/storyboardModel.h index 43ffa71eef..1aa55f8045 100644 --- a/plugins/dockers/storyboarddocker/storyboardModel.h +++ b/plugins/dockers/storyboarddocker/storyboardModel.h @@ -1,64 +1,64 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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. */ #ifndef STORYBOARD_MODEL #define STORYBOARD_MODEL #include #include #include "storyboardItem.h" /* The main storyboard model. */ class StoryboardModel : public QAbstractItemModel { Q_OBJECT public: //if we don't need this constructor change it StoryboardModel(QObject *parent = nullptr); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex StoryboardModel::parent(const QModelIndex &index) const override; + QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex &index) const override; //for removing and inserting rows bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); //for drag and drop Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDragActions() const override; //this function accesses the value from the comment model int commentCount(); private: QVector m_items; - int commentCount = 0; + int m_commentCount = 0; }; #endif \ No newline at end of file diff --git a/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp b/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp index d20755c574..6d670a7c76 100644 --- a/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp +++ b/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp @@ -1,227 +1,232 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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; 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 Lesser General Public License for more details. * * 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 "storyboarddocker_dock.h" #include "commentDelegate.h" #include "commentModel.h" +#include "storyboardModel.h" #include #include #include #include #include #include #include #include #include #include #include "ui_wdgstoryboarddock.h" #include "ui_wdgcommentmenu.h" #include "ui_wdgarrangemenu.h" class CommentMenu: public QMenu { Q_OBJECT public: CommentMenu(QWidget *parent) : QMenu(parent) , m_menuUI(new Ui_WdgCommentMenu()) , model(new CommentModel(this)) , delegate(new CommentDelegate(this)) { QWidget* commentWidget = new QWidget(this); m_menuUI->setupUi(commentWidget); m_menuUI->fieldListView->setDragEnabled(true); m_menuUI->fieldListView->setAcceptDrops(true); m_menuUI->fieldListView->setDropIndicatorShown(true); m_menuUI->fieldListView->setDragDropMode(QAbstractItemView::InternalMove); m_menuUI->fieldListView->setModel(model); m_menuUI->fieldListView->setItemDelegate(delegate); m_menuUI->fieldListView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked ); m_menuUI->btnAddField->setIcon(KisIconUtils::loadIcon("list-add")); m_menuUI->btnDeleteField->setIcon(KisIconUtils::loadIcon("trash-empty")); m_menuUI->btnAddField->setIconSize(QSize(22, 22)); m_menuUI->btnDeleteField->setIconSize(QSize(22, 22)); connect(m_menuUI->btnAddField, SIGNAL(clicked()), this, SLOT(slotaddItem())); connect(m_menuUI->btnDeleteField, SIGNAL(clicked()), this, SLOT(slotdeleteItem())); KisAction *commentAction = new KisAction(commentWidget); commentAction->setDefaultWidget(commentWidget); this->addAction(commentAction); } private Q_SLOTS: void slotaddItem() { int row = m_menuUI->fieldListView->currentIndex().row()+1; model->insertRows(row, 1); QModelIndex index = model->index(row); m_menuUI->fieldListView->setCurrentIndex(index); m_menuUI->fieldListView->edit(index); } void slotdeleteItem() { model->removeRows(m_menuUI->fieldListView->currentIndex().row(), 1); } private: QScopedPointer m_menuUI; CommentModel *model; CommentDelegate *delegate; }; class ArrangeMenu: public QMenu { public: ArrangeMenu(QWidget *parent) : QMenu(parent) , m_menuUI(new Ui_WdgArrangeMenu()) , modeGroup(new QButtonGroup(this)) , viewGroup(new QButtonGroup(this)) { QWidget* arrangeWidget = new QWidget(this); m_menuUI->setupUi(arrangeWidget); modeGroup->addButton(m_menuUI->btnColumnMode, Qt::FlatCap); modeGroup->addButton(m_menuUI->btnRowMode, Qt::FlatCap); modeGroup->addButton(m_menuUI->btnGridMode, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnAllView, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnThumbnailsView, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnCommentsView, Qt::FlatCap); KisAction *arrangeAction = new KisAction(arrangeWidget); arrangeAction->setDefaultWidget(arrangeWidget); this->addAction(arrangeAction); } QButtonGroup* getModeGroup(){ return modeGroup;} QButtonGroup* getViewGroup(){ return viewGroup;} private: QScopedPointer m_menuUI; QButtonGroup *modeGroup; QButtonGroup *viewGroup; }; StoryboardDockerDock::StoryboardDockerDock( ) : QDockWidget(i18n("Storyboard")) , m_ui(new Ui_WdgStoryboardDock()) { QWidget* mainWidget = new QWidget(this); setWidget(mainWidget); m_ui->setupUi(mainWidget); m_exportMenu = new QMenu(this); m_ui->btnExport->setMenu(m_exportMenu); m_ui->btnExport->setPopupMode(QToolButton::MenuButtonPopup); m_exportAsPdfAction = new KisAction("Export as PDF", m_exportMenu); m_exportMenu->addAction(m_exportAsPdfAction); m_exportAsSvgAction = new KisAction("Export as SVG"); m_exportMenu->addAction(m_exportAsSvgAction); connect(m_exportAsPdfAction, SIGNAL(triggered()), this, SLOT(slotExportAsPdf())); connect(m_exportAsSvgAction, SIGNAL(triggered()), this, SLOT(slotExportAsSvg())); m_commentMenu = new CommentMenu(this); m_ui->btnComment->setMenu(m_commentMenu); m_ui->btnComment->setPopupMode(QToolButton::MenuButtonPopup); m_lockAction = new KisAction(KisIconUtils::loadIcon("unlocked"), "Lock", m_ui->btnLock); m_lockAction->setCheckable(true); m_ui->btnLock->setDefaultAction(m_lockAction); m_ui->btnLock->setIconSize(QSize(22, 22)); connect(m_lockAction, SIGNAL(toggled(bool)), this, SLOT(slotLockClicked(bool))); m_arrangeMenu = new ArrangeMenu(this); m_ui->btnArrange->setMenu(m_arrangeMenu); m_ui->btnArrange->setPopupMode(QToolButton::InstantPopup); m_ui->btnArrange->setIcon(KisIconUtils::loadIcon("view-choose")); m_ui->btnArrange->setIconSize(QSize(22, 22)); m_modeGroup = m_arrangeMenu->getModeGroup(); m_viewGroup = m_arrangeMenu->getViewGroup(); connect(m_modeGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(slotModeChanged(QAbstractButton*))); connect(m_viewGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(slotViewChanged(QAbstractButton*))); + + StoryboardModel *model = new StoryboardModel(this); + m_ui->treeView->setModel(model); + model->insertRows(0, 10); } StoryboardDockerDock::~StoryboardDockerDock() { } void StoryboardDockerDock::setCanvas(KoCanvasBase *canvas) { } void StoryboardDockerDock::setViewManager(KisViewManager* kisview) { } void StoryboardDockerDock::slotExportAsPdf() { qDebug()<<"export as pdf"; slotExport("pdf"); } void StoryboardDockerDock::slotExportAsSvg() { qDebug()<<"export as svg"; slotExport("svg"); } void StoryboardDockerDock::slotExport(QString mode) { qDebug()<<"mode is "<setIcon(KisIconUtils::loadIcon("locked")); } else{ m_lockAction->setIcon(KisIconUtils::loadIcon("unlocked")); } } void StoryboardDockerDock::slotModeChanged(QAbstractButton* button) { qDebug()<<"Mode changed to "<text(); } void StoryboardDockerDock::slotViewChanged(QAbstractButton* button) { qDebug()<<"View changed to "<text(); } #include "storyboarddocker_dock.moc" \ No newline at end of file diff --git a/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui b/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui index cebeafaba5..2ca830c316 100644 --- a/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui +++ b/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui @@ -1,118 +1,104 @@ WdgStoryboardDock 0 0 604 561 Form Export true Comments true Qt::Horizontal 40 20 true Lock false false Qt::ToolButtonIconOnly true Mode true Qt::NoArrow - - - - - - Qt::Vertical - - + - - - - Qt::Horizontal - - -