File indexing completed on 2024-04-28 16:24:40

0001 /* This file is part of the KDE project
0002   Copyright (C) 2007 -2010 Dag Andersen <danders@get2net.dk>
0003 
0004   This library is free software; you can redistribute it and/or
0005   modify it under the terms of the GNU Library General Public
0006   License as published by the Free Software Foundation; either
0007   version 2 of the License, or (at your option) any later version.
0008 
0009   This library is distributed in the hope that it will be useful,
0010   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012   Library General Public License for more details.
0013 
0014   You should have received a copy of the GNU Library General Public License
0015   along with this library; see the file COPYING.LIB.  If not, write to
0016   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017 * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 // clazy:excludeall=qstring-arg
0021 #include "kptviewlist.h"
0022 
0023 #include <QString>
0024 #include <QStringList>
0025 #include <QItemDelegate>
0026 #include <QStyle>
0027 #include <QBrush>
0028 #include <QContextMenuEvent>
0029 #include <QHeaderView>
0030 #include <QMenu>
0031 
0032 #include <kmessagebox.h>
0033 #include <kcombobox.h>
0034 
0035 #include <KoIcon.h>
0036 #include "KoDocument.h"
0037 
0038 #include "kptviewbase.h"
0039 #include "kptmaindocument.h"
0040 #include "kptviewlistdialog.h"
0041 #include "kptviewlistdocker.h"
0042 #include "kptschedulemodel.h"
0043 #include "Help.h"
0044 #include <kptdebug.h>
0045 
0046 #include <assert.h>
0047 
0048 
0049 namespace KPlato
0050 {
0051 
0052 // <Code mostly nicked from qt designer ;)>
0053 class ViewCategoryDelegate : public QItemDelegate
0054 {
0055     public:
0056         ViewCategoryDelegate(QObject *parent, QTreeView *view)
0057         : QItemDelegate(parent),
0058         m_view(view)
0059         {}
0060 
0061         QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const override;
0062         void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
0063 
0064     private:
0065         QTreeView *m_view;
0066 };
0067 
0068 QSize ViewCategoryDelegate::sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const
0069 {
0070     const QAbstractItemModel * model = index.model();
0071     Q_ASSERT(model);
0072     if (model->parent(index).isValid()) {
0073         return QItemDelegate::sizeHint(option, index);
0074     }
0075     return QItemDelegate::sizeHint(option, index).expandedTo(QSize(0, 16));
0076 }
0077 
0078 void ViewCategoryDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
0079 {
0080     const QAbstractItemModel * model = index.model();
0081     Q_ASSERT(model);
0082 
0083     if (!model->parent(index).isValid()) {
0084         // this is a top-level item.
0085         QStyleOptionButton buttonOption;
0086         buttonOption.state = option.state;
0087 
0088         buttonOption.rect = option.rect;
0089         buttonOption.palette = option.palette;
0090         buttonOption.features = QStyleOptionButton::None;
0091         m_view->style() ->drawControl(QStyle::CE_PushButton, &buttonOption, painter, m_view);
0092 
0093         QStyleOption branchOption;
0094         static const int i = 9; // ### hardcoded in qcommonstyle.cpp
0095         QRect r = option.rect;
0096         branchOption.rect = QRect(r.left() + i / 2, r.top() + (r.height() - i) / 2, i, i);
0097         branchOption.palette = option.palette;
0098         branchOption.state = QStyle::State_Children;
0099 
0100         if (m_view->isExpanded(index))
0101             branchOption.state |= QStyle::State_Open;
0102 
0103         m_view->style() ->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, m_view);
0104 
0105         // draw text
0106         QRect textrect = QRect(r.left() + i * 2, r.top(), r.width() - ((5 * i) / 2), r.height());
0107         QString text = elidedText(option.fontMetrics, textrect.width(), Qt::ElideMiddle,
0108                                 model->data(index, Qt::DisplayRole).toString());
0109         m_view->style() ->drawItemText(painter, textrect, Qt::AlignLeft|Qt::AlignVCenter,
0110         option.palette, m_view->isEnabled(), text);
0111 
0112     } else {
0113         QItemDelegate::paint(painter, option, index);
0114     }
0115 
0116 }
0117 
0118 ViewListItem::ViewListItem(const QString &tag, const QStringList &strings, int type)
0119     : QTreeWidgetItem(strings, type),
0120     m_tag(tag)
0121 {
0122 }
0123 
0124 ViewListItem::ViewListItem(QTreeWidget *parent, const QString &tag, const QStringList &strings, int type)
0125     : QTreeWidgetItem(parent, strings, type),
0126     m_tag(tag)
0127 {
0128 }
0129 
0130 ViewListItem::ViewListItem(QTreeWidgetItem *parent, const QString &tag, const QStringList &strings, int type)
0131     : QTreeWidgetItem(parent, strings, type),
0132     m_tag(tag)
0133 {
0134 }
0135 
0136 void ViewListItem::setReadWrite(bool rw)
0137 {
0138     if (type() == ItemType_SubView) {
0139         static_cast<ViewBase*>(view())->updateReadWrite(rw);
0140     }
0141 }
0142 
0143 void ViewListItem::setView(ViewBase *view)
0144 {
0145     setData(0, ViewListItem::DataRole_View,  qVariantFromValue(static_cast<QObject*>(view)));
0146 }
0147 
0148 ViewBase *ViewListItem::view() const
0149 {
0150     if (data(0, ViewListItem::DataRole_View).isValid()) {
0151         return static_cast<ViewBase*>(data(0, ViewListItem::DataRole_View).value<QObject*>());
0152     }
0153     return 0;
0154 }
0155 
0156 void ViewListItem::setDocument(KoDocument *doc)
0157 {
0158     setData(0, ViewListItem::DataRole_Document,  qVariantFromValue(static_cast<QObject*>(doc)));
0159 }
0160 
0161 KoDocument *ViewListItem::document() const
0162 {
0163     if (data(0, ViewListItem::DataRole_Document).isValid()) {
0164         return static_cast<KoDocument*>(data(0, ViewListItem::DataRole_Document).value<QObject*>());
0165     }
0166     return 0;
0167 }
0168 
0169 QString ViewListItem::viewType() const
0170 {
0171     if (type() != ItemType_SubView) {
0172         return QString();
0173     }
0174     QString name = view()->metaObject()->className();
0175     if (name.contains(':')) {
0176         name = name.remove(0, name.lastIndexOf(':') + 1);
0177     }
0178     return name;
0179 }
0180 
0181 void ViewListItem::save(QDomElement &element) const
0182 {
0183     element.setAttribute("itemtype", QString::number(type()));
0184     element.setAttribute("tag", tag());
0185 
0186     if (type() == ItemType_SubView) {
0187         element.setAttribute("viewtype", viewType());
0188         element.setAttribute("name", m_viewinfo.name == text(0) ? "" : text(0));
0189         element.setAttribute("tooltip", m_viewinfo.tip == toolTip(0) ? TIP_USE_DEFAULT_TEXT : toolTip(0));
0190     } else if (type() == ItemType_Category) {
0191         debugPlan<<text(0)<<m_viewinfo.name;
0192         element.setAttribute("name", text(0) == m_viewinfo.name ? "" : text(0));
0193         element.setAttribute("tooltip", toolTip(0).isEmpty() ? TIP_USE_DEFAULT_TEXT : toolTip(0));
0194     }
0195 }
0196 
0197 ViewListTreeWidget::ViewListTreeWidget(QWidget *parent)
0198     : QTreeWidget(parent)
0199 {
0200     header() ->hide();
0201     setRootIsDecorated(false);
0202     setItemDelegate(new ViewCategoryDelegate(this, this));
0203     setItemsExpandable(true);
0204     setSelectionMode(QAbstractItemView::SingleSelection);
0205 
0206     setDragDropMode(QAbstractItemView::InternalMove);
0207 
0208     //setContextMenuPolicy(Qt::ActionsContextMenu);
0209 
0210     connect(this, &QTreeWidget::itemPressed, this, &ViewListTreeWidget::handleMousePress);
0211 }
0212 
0213 void ViewListTreeWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0214 {
0215     QTreeWidget::drawRow(painter, option, index);
0216 }
0217 
0218 void ViewListTreeWidget::handleMousePress(QTreeWidgetItem *item)
0219 {
0220     //debugPlan;
0221     if (item == 0)
0222         return ;
0223 
0224     if (item->parent() == 0) {
0225         setItemExpanded(item, !isItemExpanded(item));
0226         return ;
0227     }
0228 }
0229 void ViewListTreeWidget::mousePressEvent (QMouseEvent *event)
0230 {
0231     if (event->button() == Qt::RightButton) {
0232         QTreeWidgetItem *item = itemAt(event->pos());
0233         if (item && item->type() == ViewListItem::ItemType_Category) {
0234             setCurrentItem(item);
0235             emit customContextMenuRequested(event->pos());
0236             event->accept();
0237             return;
0238         }
0239     }
0240     QTreeWidget::mousePressEvent(event);
0241 }
0242 
0243 void ViewListTreeWidget::save(QDomElement &element) const
0244 {
0245     int cnt = topLevelItemCount();
0246     if (cnt == 0) {
0247         return;
0248     }
0249     QDomElement cs = element.ownerDocument().createElement("categories");
0250     element.appendChild(cs);
0251     for (int i = 0; i < cnt; ++i) {
0252         ViewListItem *itm = static_cast<ViewListItem*>(topLevelItem(i));
0253         if (itm->type() != ViewListItem::ItemType_Category) {
0254             continue;
0255         }
0256         QDomElement c = cs.ownerDocument().createElement("category");
0257         cs.appendChild(c);
0258         emit const_cast<ViewListTreeWidget*>(this)->updateViewInfo(itm);
0259         itm->save(c);
0260         for (int j = 0; j < itm->childCount(); ++j) {
0261             ViewListItem *vi = static_cast<ViewListItem*>(itm->child(j));
0262             if (vi->type() != ViewListItem::ItemType_SubView) {
0263                 continue;
0264             }
0265             QDomElement el = c.ownerDocument().createElement("view");
0266             c.appendChild(el);
0267             emit const_cast<ViewListTreeWidget*>(this)->updateViewInfo(vi);
0268             vi->save(el);
0269             QDomElement elm = el.ownerDocument().createElement("settings");
0270             el.appendChild(elm);
0271             static_cast<ViewBase*>(vi->view())->saveContext(elm);
0272         }
0273     }
0274 }
0275 
0276 
0277 // </Code mostly nicked from qt designer ;)>
0278 
0279 void ViewListTreeWidget::startDrag(Qt::DropActions supportedActions)
0280 {
0281     QModelIndexList indexes = selectedIndexes();
0282     if (indexes.count() == 1) {
0283         ViewListItem *item = static_cast<ViewListItem*>(itemFromIndex(indexes.at(0)));
0284         Q_ASSERT(item);
0285         QTreeWidgetItem *root = invisibleRootItem();
0286         int count = root->childCount();
0287         if (item && item->type() == ViewListItem::ItemType_Category) {
0288             root->setFlags(root->flags() | Qt::ItemIsDropEnabled);
0289             for (int i = 0; i < count; ++i) {
0290                 QTreeWidgetItem * ch = root->child(i);
0291                 ch->setFlags(ch->flags() & ~Qt::ItemIsDropEnabled);
0292             }
0293         } else if (item) {
0294             root->setFlags(root->flags() & ~Qt::ItemIsDropEnabled);
0295             for (int i = 0; i < count; ++i) {
0296                 QTreeWidgetItem * ch = root->child(i);
0297                 ch->setFlags(ch->flags() | Qt::ItemIsDropEnabled);
0298             }
0299         }
0300     }
0301     QTreeWidget::startDrag(supportedActions);
0302 }
0303 
0304 void ViewListTreeWidget::dropEvent(QDropEvent *event)
0305 {
0306     QTreeWidget::dropEvent(event);
0307     if (event->isAccepted()) {
0308         emit modified();
0309     }
0310 }
0311 
0312 ViewListItem *ViewListTreeWidget::findCategory(const QString &cat)
0313 {
0314     QTreeWidgetItem * item;
0315     int cnt = topLevelItemCount();
0316     for (int i = 0; i < cnt; ++i) {
0317         item = topLevelItem(i);
0318         if (static_cast<ViewListItem*>(item)->tag() == cat)
0319             return static_cast<ViewListItem*>(item);
0320     }
0321     return 0;
0322 }
0323 
0324 ViewListItem *ViewListTreeWidget::category(const KoView *view) const
0325 {
0326     QTreeWidgetItem * item;
0327     int cnt = topLevelItemCount();
0328     for (int i = 0; i < cnt; ++i) {
0329         item = topLevelItem(i);
0330         for (int c = 0; c < item->childCount(); ++c) {
0331             if (view == static_cast<ViewListItem*>(item->child(c))->view()) {
0332                 return static_cast<ViewListItem*>(item);
0333             }
0334         }
0335     }
0336     return 0;
0337 }
0338 
0339 //-----------------------
0340 ViewListWidget::ViewListWidget(MainDocument *part, QWidget *parent)//QString name, KXmlGuiWindow *parent)
0341     : QWidget(parent),
0342     m_part(part),
0343     m_prev(0),
0344     m_temp(0)
0345 {
0346     setObjectName("ViewListWidget");
0347     Help::add(this,
0348               xi18nc("@info:whatsthis",
0349                      "<title>View Selector</title>"
0350                      "<para>This is the list of views and editors.</para>"
0351                      "<para>You can configure the list by using the context menu:"
0352                      "<list>"
0353                      "<item>Rename categories or views</item>"
0354                      "<item>Configure. Move, remove, rename or edit tool tip for categories or views</item>"
0355                      "<item>Insert categories and views</item>"
0356                      "</list>"
0357                      "<nl/><link url='%1'>More...</link>"
0358                      "</para>", Help::page("The_View_Selector")));
0359     
0360     m_viewlist = new ViewListTreeWidget(this);
0361     m_viewlist->setEditTriggers(QAbstractItemView::NoEditTriggers);
0362     connect(m_viewlist, &ViewListTreeWidget::modified, this, &ViewListWidget::modified);
0363 
0364     m_currentSchedule = new KComboBox(this);
0365     m_model.setFlat(true);
0366 
0367     m_sfModel.setSourceModel(&m_model);
0368     m_currentSchedule->setModel(&m_sfModel);
0369     Help::add(m_currentSchedule,
0370               xi18nc("@info:whatsthis",
0371                      "<title>Schedule selector</title>"
0372                      "<para>"
0373                      "Selects the schedule to be used when displaying schedule dependent data."
0374                      "<nl/><note>Unscheduled tasks are only shown in editors.</note>"
0375                      "<nl/><link url='%1'>More...</link>"
0376                      "</para>", Help::page("Main_Work_Space#Schedule_Selector")));
0377     
0378 
0379     QVBoxLayout *l = new QVBoxLayout(this);
0380     l->setMargin(0);
0381     l->addWidget(m_viewlist);
0382     l->addWidget(m_currentSchedule);
0383 
0384     connect(m_viewlist, &QTreeWidget::currentItemChanged, this, &ViewListWidget::slotActivated);
0385 
0386     connect(m_viewlist, &QTreeWidget::itemChanged, this, &ViewListWidget::slotItemChanged);
0387 
0388     setupContextMenus();
0389 
0390     connect(m_currentSchedule, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &ViewListWidget::slotCurrentScheduleChanged);
0391 
0392     connect(&m_model, &ScheduleItemModel::scheduleManagerAdded, this, &ViewListWidget::slotScheduleManagerAdded);
0393 
0394     connect(m_viewlist, &ViewListTreeWidget::updateViewInfo, this, &ViewListWidget::updateViewInfo);
0395 }
0396 
0397 ViewListWidget::~ViewListWidget()
0398 {
0399 }
0400 
0401 void ViewListWidget::setReadWrite(bool rw)
0402 {
0403     foreach (ViewListItem *c, categories()) {
0404         for (int i = 0; i < c->childCount(); ++i) {
0405             static_cast<ViewListItem*>(c->child(i))->setReadWrite(rw);
0406         }
0407     }
0408 }
0409 
0410 void ViewListWidget::slotItemChanged(QTreeWidgetItem */*item*/, int /*col */)
0411 {
0412     //debugPlan;
0413 }
0414 
0415 void ViewListWidget::slotActivated(QTreeWidgetItem *item, QTreeWidgetItem *prev)
0416 {
0417     if (m_prev) {
0418         m_prev->setData(0, Qt::BackgroundRole, QVariant());
0419     }
0420     if (item && item->type() == ViewListItem::ItemType_Category) {
0421         return ;
0422     }
0423     emit activated(static_cast<ViewListItem*>(item), static_cast<ViewListItem*>(prev));
0424     if (item) {
0425         QVariant v = QBrush(QColor(Qt::yellow));
0426         item->setData(0, Qt::BackgroundRole, v);
0427         m_prev = static_cast<ViewListItem*>(item);
0428     }
0429 }
0430 
0431 ViewListItem *ViewListWidget::addCategory(const QString &tag, const QString& name)
0432 {
0433     //debugPlan ;
0434     ViewListItem *item = m_viewlist->findCategory(tag);
0435     if (item == 0) {
0436         item = new ViewListItem(m_viewlist, tag, QStringList(name), ViewListItem::ItemType_Category);
0437         item->setExpanded(true);
0438         item->setFlags(item->flags() | Qt::ItemIsEditable);
0439     }
0440     return item;
0441 }
0442 
0443 QList<ViewListItem*> ViewListWidget::categories() const
0444 {
0445     QList<ViewListItem*> lst;
0446     QTreeWidgetItem *item;
0447     int cnt = m_viewlist->topLevelItemCount();
0448     for (int i = 0; i < cnt; ++i) {
0449         item = m_viewlist->topLevelItem(i);
0450         if (item->type() == ViewListItem::ItemType_Category)
0451             lst << static_cast<ViewListItem*>(item);
0452     }
0453     return lst;
0454 }
0455 
0456 ViewListItem *ViewListWidget::findCategory(const QString &tag) const
0457 {
0458     return m_viewlist->findCategory(tag);
0459 }
0460 
0461 ViewListItem *ViewListWidget::category(const KoView *view) const
0462 {
0463     return m_viewlist->category(view);
0464 }
0465 
0466 QString ViewListWidget::uniqueTag(const QString &seed) const
0467 {
0468     QString tag = seed;
0469     for (int i = 1; findItem(tag); ++i) {
0470         tag = QString("%1-%2").arg(seed).arg(i);
0471     }
0472     return tag;
0473 }
0474 
0475 ViewListItem *ViewListWidget::addView(QTreeWidgetItem *category, const QString &tag, const QString &name, ViewBase *view, KoDocument *doc, const QString &iconName, int index)
0476 {
0477     ViewListItem * item = new ViewListItem(uniqueTag(tag), QStringList(name), ViewListItem::ItemType_SubView);
0478     item->setView(view);
0479     item->setDocument(doc);
0480     if (! iconName.isEmpty()) {
0481         item->setData(0, Qt::DecorationRole, QIcon::fromTheme(iconName));
0482     }
0483     item->setFlags((item->flags() | Qt::ItemIsEditable) & ~Qt::ItemIsDropEnabled);
0484     insertViewListItem(item, category, index);
0485 
0486     connect(view, &ViewBase::optionsModified, this, &ViewListWidget::setModified);
0487 
0488     return item;
0489 }
0490 
0491 void ViewListWidget::setSelected(QTreeWidgetItem *item)
0492 {
0493     //debugPlan<<item<<","<<m_viewlist->currentItem();
0494     if (item == 0 && m_viewlist->currentItem()) {
0495         m_viewlist->currentItem()->setSelected(false);
0496         if (m_prev) {
0497             m_prev->setData(0, Qt::BackgroundRole, QVariant());
0498         }
0499     }
0500     m_viewlist->setCurrentItem(item);
0501     //debugPlan<<item<<","<<m_viewlist->currentItem();
0502 }
0503 
0504 void ViewListWidget::setCurrentItem(QTreeWidgetItem *item)
0505 {
0506     m_viewlist->setCurrentItem(item);
0507     //debugPlan<<item<<","<<m_viewlist->currentItem();
0508 }
0509 
0510 ViewListItem *ViewListWidget::currentItem() const
0511 {
0512     return static_cast<ViewListItem*>(m_viewlist->currentItem());
0513 }
0514 
0515 ViewListItem *ViewListWidget::currentCategory() const
0516 {
0517     ViewListItem *item = static_cast<ViewListItem*>(m_viewlist->currentItem());
0518     if (item == 0) {
0519         return 0;
0520     }
0521     if (item->type() == ViewListItem::ItemType_Category) {
0522         return item;
0523     }
0524     return static_cast<ViewListItem*>(item->parent());
0525 }
0526 
0527 KoView *ViewListWidget::findView(const QString &tag) const
0528 {
0529     ViewListItem *i = findItem(tag);
0530     if (i == 0) {
0531         return 0;
0532     }
0533     return i->view();
0534 }
0535 
0536 ViewListItem *ViewListWidget::findItem(const QString &tag) const
0537 {
0538     ViewListItem *item = findItem(tag, m_viewlist->invisibleRootItem());
0539     if (item == 0) {
0540         QTreeWidgetItem *parent = m_viewlist->invisibleRootItem();
0541         for (int i = 0; i < parent->childCount(); ++i) {
0542             item = findItem(tag, parent->child(i));
0543             if (item != 0) {
0544                 break;
0545             }
0546         }
0547     }
0548     return item;
0549 }
0550 
0551 ViewListItem *ViewListWidget::findItem(const QString &tag, QTreeWidgetItem *parent) const
0552 {
0553     if (parent == 0) {
0554         return findItem(tag, m_viewlist->invisibleRootItem());
0555     }
0556     for (int i = 0; i < parent->childCount(); ++i) {
0557         ViewListItem * ch = static_cast<ViewListItem*>(parent->child(i));
0558         if (ch->tag() == tag) {
0559             //debugPlan<<ch<<","<<view;
0560             return ch;
0561         }
0562         ch = findItem(tag, ch);
0563         if (ch) {
0564             return ch;
0565         }
0566     }
0567     return 0;
0568 }
0569 
0570 ViewListItem *ViewListWidget::findItem(const ViewBase *view, QTreeWidgetItem *parent) const
0571 {
0572     if (parent == 0) {
0573         return findItem(view, m_viewlist->invisibleRootItem());
0574     }
0575     for (int i = 0; i < parent->childCount(); ++i) {
0576         ViewListItem * ch = static_cast<ViewListItem*>(parent->child(i));
0577         if (ch->view() == view) {
0578             //debugPlan<<ch<<","<<view;
0579             return ch;
0580         }
0581         ch = findItem(view, ch);
0582         if (ch) {
0583             return ch;
0584         }
0585     }
0586     return 0;
0587 }
0588 
0589 void ViewListWidget::slotAddView()
0590 {
0591     emit createView();
0592 }
0593 
0594 void ViewListWidget::slotRemoveCategory()
0595 {
0596     if (m_contextitem == 0) {
0597         return;
0598     }
0599     if (m_contextitem->type() != ViewListItem::ItemType_Category) {
0600         return;
0601     }
0602     debugPlan<<m_contextitem<<":"<<m_contextitem->type();
0603     if (m_contextitem->childCount() > 0) {
0604         if (KMessageBox::warningContinueCancel(this, i18n("Removing this category will also remove all its views.")) == KMessageBox::Cancel) {
0605             return;
0606         }
0607     }
0608     // first remove all views in this category
0609     while (m_contextitem->childCount() > 0) {
0610         ViewListItem *itm = static_cast<ViewListItem*>(m_contextitem->child(0));
0611         takeViewListItem(itm);
0612         delete itm->view();
0613         delete itm;
0614     }
0615     takeViewListItem(m_contextitem);
0616     delete m_contextitem;
0617     m_contextitem = 0;
0618     emit modified();
0619 }
0620 
0621 void ViewListWidget::slotRemoveView()
0622 {
0623     if (m_contextitem) {
0624         takeViewListItem(m_contextitem);
0625         delete m_contextitem->view();
0626         delete m_contextitem;
0627         emit modified();
0628     }
0629 }
0630 
0631 void ViewListWidget::slotEditViewTitle()
0632 {
0633     //QTreeWidgetItem *item = m_viewlist->currentItem();
0634     if (m_contextitem) {
0635         debugPlan<<m_contextitem<<":"<<m_contextitem->type();
0636         QString title = m_contextitem->text(0);
0637         m_viewlist->editItem(m_contextitem);
0638         if (title != m_contextitem->text(0)) {
0639             emit modified();
0640         }
0641     }
0642 }
0643 
0644 void ViewListWidget::slotConfigureItem()
0645 {
0646     if (m_contextitem == 0) {
0647         return;
0648     }
0649     KoDialog *dlg = 0;
0650     if (m_contextitem->type() == ViewListItem::ItemType_Category) {
0651         debugPlan<<m_contextitem<<":"<<m_contextitem->type();
0652         dlg = new ViewListEditCategoryDialog(*this, m_contextitem, this);
0653     } else if (m_contextitem->type() == ViewListItem::ItemType_SubView) {
0654         dlg = new ViewListEditViewDialog(*this, m_contextitem, this);
0655     }
0656     if (dlg) {
0657         connect(dlg, &QDialog::finished, this, &ViewListWidget::slotDialogFinished);
0658         dlg->open();
0659     }
0660 }
0661 
0662 void ViewListWidget::slotDialogFinished(int result)
0663 {
0664     if (result == QDialog::Accepted) {
0665         emit modified();
0666     }
0667     if (sender()) {
0668         sender()->deleteLater();
0669     }
0670 }
0671 
0672 void ViewListWidget::slotEditDocumentTitle()
0673 {
0674     //QTreeWidgetItem *item = m_viewlist->currentItem();
0675     if (m_contextitem) {
0676         debugPlan<<m_contextitem<<":"<<m_contextitem->type();
0677         QString title = m_contextitem->text(0);
0678         m_viewlist->editItem(m_contextitem);
0679     }
0680 }
0681 
0682 int ViewListWidget::removeViewListItem(ViewListItem *item)
0683 {
0684     QTreeWidgetItem *p = item->parent();
0685     if (p == 0) {
0686         p = m_viewlist->invisibleRootItem();
0687     }
0688     int i = p->indexOfChild(item);
0689     if (i != -1) {
0690         p->takeChild(i);
0691         emit modified();
0692     }
0693     return i;
0694 }
0695 
0696 void ViewListWidget::addViewListItem(ViewListItem *item, QTreeWidgetItem *parent, int index)
0697 {
0698     QTreeWidgetItem *p = parent;
0699     if (p == 0) {
0700         p = m_viewlist->invisibleRootItem();
0701     }
0702     if (index == -1) {
0703         index = p->childCount();
0704     }
0705     p->insertChild(index, item);
0706     emit modified();
0707 }
0708 
0709 int ViewListWidget::takeViewListItem(ViewListItem *item)
0710 {
0711     while (item->childCount() > 0) {
0712         takeViewListItem(static_cast<ViewListItem*>(item->child(0)));
0713     }
0714     int pos = removeViewListItem(item);
0715     if (pos != -1) {
0716         emit viewListItemRemoved(item);
0717         if (item == m_prev) {
0718             m_prev = 0;
0719         }
0720         if (m_prev) {
0721             setCurrentItem(m_prev);
0722         }
0723     }
0724     return pos;
0725 }
0726 
0727 void ViewListWidget::insertViewListItem(ViewListItem *item, QTreeWidgetItem *parent, int index)
0728 {
0729     addViewListItem(item, parent, index);
0730     emit viewListItemInserted(item, static_cast<ViewListItem*>(parent), index);
0731 }
0732 
0733 void ViewListWidget::setupContextMenus()
0734 {
0735     // NOTE: can't use xml file as there may not be a factory()
0736     QAction *action;
0737     // view actions
0738     action = new QAction(koIcon("edit-rename"), xi18nc("@action:inmenu rename view", "Rename"), this);
0739     connect(action, &QAction::triggered, this, &ViewListWidget::slotEditViewTitle);
0740     m_viewactions.append(action);
0741 
0742     action = new QAction(koIcon("configure"), xi18nc("@action:inmenu configure view", "Configure..."), this);
0743     connect(action, &QAction::triggered, this, &ViewListWidget::slotConfigureItem);
0744     m_viewactions.append(action);
0745 
0746     action = new QAction(koIcon("list-remove"), xi18nc("@action:inmenu remove view", "Remove"), this);
0747     connect(action, &QAction::triggered, this, &ViewListWidget::slotRemoveView);
0748     m_viewactions.append(action);
0749 
0750     action = new QAction(this);
0751     action->setSeparator(true);
0752     m_viewactions.append(action);
0753 
0754     // Category actions
0755     action = new QAction(koIcon("edit-rename"), xi18nc("@action:inmenu rename view category", "Rename"), this);
0756     connect(action, &QAction::triggered, this, &ViewListWidget::renameCategory);
0757     m_categoryactions.append(action);
0758 
0759     action = new QAction(koIcon("configure"), xi18nc("@action:inmenu configure view category", "Configure..."), this);
0760     connect(action, &QAction::triggered, this, &ViewListWidget::slotConfigureItem);
0761     m_categoryactions.append(action);
0762 
0763     action = new QAction(koIcon("list-remove"), xi18nc("@action:inmenu Remove view category", "Remove"),this);
0764     connect(action, &QAction::triggered, this, &ViewListWidget::slotRemoveCategory);
0765     m_categoryactions.append(action);
0766 
0767     action = new QAction(this);
0768     action->setSeparator(true);
0769     m_categoryactions.append(action);
0770 
0771     // list actions
0772     action = new QAction(koIcon("list-add"), xi18nc("@action:inmenu Insert View", "Insert..."), this);
0773     connect(action, &QAction::triggered, this, &ViewListWidget::slotAddView);
0774     m_listactions.append(action);
0775 }
0776 
0777 void ViewListWidget::renameCategory()
0778 {
0779     if (m_contextitem) {
0780         QString title = m_contextitem->text(0);
0781         m_viewlist->editItem(m_contextitem, 0);
0782     }
0783 }
0784 
0785 void ViewListWidget::contextMenuEvent (QContextMenuEvent *event)
0786 {
0787     QMenu menu;
0788     QList<QAction*> lst;
0789     m_contextitem = static_cast<ViewListItem*>(m_viewlist->itemAt(event->pos()));
0790     if (m_contextitem == 0) {
0791         lst += m_listactions;
0792     } else {
0793         if (m_contextitem->type() == ViewListItem::ItemType_Category) {
0794             lst += m_categoryactions;
0795         } else if (m_contextitem->type() == ViewListItem::ItemType_SubView) {
0796             lst += m_viewactions;
0797             ViewBase *v = dynamic_cast<ViewBase*>(m_contextitem->view());
0798             if (v) {
0799                 // TODO: review
0800                 //lst += v->viewlistActionList();
0801             }
0802         }
0803         lst += m_listactions;
0804     }
0805     if (! lst.isEmpty()) {
0806         //menu.addTitle(i18n("Edit"));
0807         foreach (QAction *a, lst) {
0808             menu.addAction(a);
0809         }
0810     }
0811     if (! menu.actions().isEmpty()) {
0812         menu.exec(event->globalPos());
0813     }
0814 }
0815 
0816 void ViewListWidget::save(QDomElement &element) const
0817 {
0818     m_viewlist->save(element);
0819 }
0820 
0821 void ViewListWidget::setProject(Project *project)
0822 {
0823     debugPlan<<project;
0824     m_model.setProject(project);
0825 }
0826 
0827 void ViewListWidget::slotCurrentScheduleChanged(int idx)
0828 {
0829     debugPlan<<idx<<selectedSchedule();
0830     emit selectionChanged(selectedSchedule());
0831 }
0832 
0833 ScheduleManager *ViewListWidget::selectedSchedule() const
0834 {
0835     QModelIndex idx = m_sfModel.index(m_currentSchedule->currentIndex(), m_currentSchedule->modelColumn());
0836     debugPlan<<idx;
0837     return m_sfModel.manager(idx);
0838 }
0839 
0840 void ViewListWidget::setSelectedSchedule(ScheduleManager *sm)
0841 {
0842     debugPlan<<sm<<m_model.index(sm);
0843     QModelIndex idx = m_sfModel.mapFromSource(m_model.index(sm));
0844     if (sm && ! idx.isValid()) {
0845         m_temp = sm;
0846         return;
0847     }
0848     m_currentSchedule->setCurrentIndex(idx.row());
0849     debugPlan<<sm<<idx;
0850     m_temp = 0;
0851 }
0852 
0853 void ViewListWidget::slotScheduleManagerAdded(ScheduleManager *sm)
0854 {
0855     if (m_temp && m_temp == sm) {
0856         setSelectedSchedule(sm);
0857         m_temp = 0;
0858     }
0859 }
0860 
0861 void ViewListWidget::setModified()
0862 {
0863     emit modified();
0864 }
0865 
0866 }  //KPlato namespace