File indexing completed on 2025-01-19 04:56:40
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 0003 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 0007 #include "applicationcomponents.h" 0008 0009 #include <memory> 0010 0011 #include <QBoxLayout> 0012 #include <QLabel> 0013 #include <QMimeData> 0014 #include <QVariant> 0015 #include <QWidget> 0016 #include <QWidgetAction> 0017 0018 #include <KLocalizedString> 0019 #include <KWindowSystem> 0020 0021 #include "availablepagesview.h" 0022 #include "availablesourcesview.h" 0023 #include "editorview.h" 0024 #include "pageview.h" 0025 #include "pageviewerrorhandler.h" 0026 #include "quickselectdialog.h" 0027 #include "runningtaskwidget.h" 0028 0029 #include "presentation/runningtaskmodelinterface.h" 0030 0031 using namespace Widgets; 0032 0033 ApplicationComponents::ApplicationComponents(QWidget *parent) 0034 : QObject(parent), 0035 m_parent(parent), 0036 m_availableSourcesView(nullptr), 0037 m_availablePagesView(nullptr), 0038 m_pageView(nullptr), 0039 m_editorView(nullptr), 0040 m_errorHandler(new PageViewErrorHandler) 0041 { 0042 m_quickSelectDialogFactory = [] (QWidget *parent) { 0043 return QuickSelectDialogPtr(new QuickSelectDialog(parent)); 0044 }; 0045 0046 auto moveItemAction = new QAction(this); 0047 moveItemAction->setObjectName(QLatin1StringView("moveItemAction")); 0048 moveItemAction->setText(i18n("Move Task")); 0049 moveItemAction->setShortcut(Qt::Key_M); 0050 connect(moveItemAction, &QAction::triggered, this, &ApplicationComponents::onMoveItemsRequested); 0051 0052 m_actions.insert(QStringLiteral("page_view_move"), moveItemAction); 0053 } 0054 0055 ApplicationComponents::~ApplicationComponents() 0056 { 0057 setModel({}); 0058 } 0059 0060 QHash<QString, QAction*> ApplicationComponents::globalActions() const 0061 { 0062 auto actions = QHash<QString, QAction*>(); 0063 actions.insert(availableSourcesView()->globalActions()); 0064 actions.insert(availablePagesView()->globalActions()); 0065 actions.insert(pageView()->globalActions()); 0066 actions.insert(m_actions); 0067 0068 return actions; 0069 } 0070 0071 QObjectPtr ApplicationComponents::model() const 0072 { 0073 return m_model; 0074 } 0075 0076 AvailableSourcesView *ApplicationComponents::availableSourcesView() const 0077 { 0078 if (!m_availableSourcesView) { 0079 auto view = new AvailableSourcesView(m_parent); 0080 if (m_model) { 0081 view->setModel(m_model->property("availableSources").value<QObject*>()); 0082 } 0083 0084 ApplicationComponents *self = const_cast<ApplicationComponents*>(this); 0085 self->m_availableSourcesView = view; 0086 } 0087 0088 return m_availableSourcesView; 0089 } 0090 0091 AvailablePagesView *ApplicationComponents::availablePagesView() const 0092 { 0093 if (!m_availablePagesView) { 0094 auto availablePagesView = new AvailablePagesView(m_parent); 0095 if (m_model) { 0096 availablePagesView->setModel(m_model->property("availablePages").value<QObject*>()); 0097 auto availableSources = m_model->property("availableSources").value<QObject*>(); 0098 if (availableSources) 0099 availablePagesView->setProjectSourcesModel(availableSources->property("sourceListModel").value<QAbstractItemModel*>()); 0100 } 0101 0102 ApplicationComponents *self = const_cast<ApplicationComponents*>(this); 0103 self->m_availablePagesView = availablePagesView; 0104 0105 connect(self->m_availablePagesView, &AvailablePagesView::currentPageChanged, self, &ApplicationComponents::onCurrentPageChanged); 0106 } 0107 0108 return m_availablePagesView; 0109 } 0110 0111 PageView *ApplicationComponents::pageView() const 0112 { 0113 if (!m_pageView) { 0114 auto pageView = new PageView(m_parent); 0115 if (m_model) { 0116 pageView->setModel(m_model->property("currentPage").value<QObject*>()); 0117 pageView->setRunningTaskModel(m_model->property("runningTaskModel").value<Presentation::RunningTaskModelInterface*>()); 0118 connect(m_model.data(), SIGNAL(currentPageChanged(QObject*)), 0119 pageView, SLOT(setModel(QObject*))); 0120 } 0121 0122 ApplicationComponents *self = const_cast<ApplicationComponents*>(this); 0123 self->m_pageView = pageView; 0124 self->m_errorHandler->setPageView(pageView); 0125 0126 connect(self->m_pageView, &PageView::currentTaskChanged, self, &ApplicationComponents::onCurrentTaskChanged); 0127 } 0128 0129 return m_pageView; 0130 } 0131 0132 EditorView *ApplicationComponents::editorView() const 0133 { 0134 if (!m_editorView) { 0135 auto editorView = new EditorView(m_parent); 0136 if (m_model) { 0137 editorView->setModel(m_model->property("editor").value<QObject*>()); 0138 } 0139 0140 auto self = const_cast<ApplicationComponents*>(this); 0141 self->m_editorView = editorView; 0142 } 0143 0144 return m_editorView; 0145 } 0146 0147 RunningTaskWidget *ApplicationComponents::runningTaskView() const 0148 { 0149 if (!m_runningTaskView) { 0150 auto runningTaskView = new RunningTaskWidget(m_parent); 0151 if (m_model) { 0152 runningTaskView->setModel(m_model->property("runningTaskModel").value<Presentation::RunningTaskModelInterface*>()); 0153 } 0154 0155 auto self = const_cast<ApplicationComponents*>(this); 0156 self->m_runningTaskView = runningTaskView; 0157 } 0158 0159 return m_runningTaskView; 0160 } 0161 0162 ApplicationComponents::QuickSelectDialogFactory ApplicationComponents::quickSelectDialogFactory() const 0163 { 0164 return m_quickSelectDialogFactory; 0165 } 0166 0167 void ApplicationComponents::setModel(const QObjectPtr &model) 0168 { 0169 if (m_model == model) 0170 return; 0171 0172 if (m_model) { 0173 if (m_pageView) 0174 disconnect(m_model.data(), 0, m_pageView, 0); 0175 m_model->setProperty("errorHandler", 0); 0176 } 0177 0178 // Delay deletion of the old model until we're out of scope 0179 auto tmp = m_model; 0180 Q_UNUSED(tmp); 0181 0182 m_model = model; 0183 0184 if (m_model) { 0185 m_model->setProperty("errorHandler", QVariant::fromValue(errorHandler())); 0186 } 0187 0188 if (m_availableSourcesView) { 0189 m_availableSourcesView->setModel(m_model ? m_model->property("availableSources").value<QObject*>() 0190 : nullptr); 0191 } 0192 0193 if (m_availablePagesView) { 0194 m_availablePagesView->setModel(m_model ? m_model->property("availablePages").value<QObject*>() 0195 : nullptr); 0196 m_availablePagesView->setProjectSourcesModel(m_model ? m_model->property("dataSourcesModel").value<QAbstractItemModel*>() 0197 : nullptr); 0198 } 0199 0200 if (m_pageView) { 0201 m_pageView->setModel(m_model ? m_model->property("currentPage").value<QObject*>() 0202 : nullptr); 0203 m_pageView->setRunningTaskModel(m_model ? m_model->property("runningTaskModel").value<Presentation::RunningTaskModelInterface*>() 0204 : nullptr); 0205 0206 if (m_model) { 0207 connect(m_model.data(), SIGNAL(currentPageChanged(QObject*)), 0208 m_pageView, SLOT(setModel(QObject*))); 0209 } 0210 } 0211 0212 if (m_editorView) { 0213 m_editorView->setModel(m_model ? m_model->property("editor").value<QObject*>() 0214 : nullptr); 0215 } 0216 0217 if (m_runningTaskView) { 0218 m_runningTaskView->setModel(m_model ? m_model->property("runningTaskModel").value<Presentation::RunningTaskModelInterface*>() 0219 : nullptr); 0220 } else if (m_model) { 0221 if (!KWindowSystem::isPlatformWayland()) { 0222 runningTaskView(); // We got a model so make sure this view exists now 0223 } 0224 } 0225 } 0226 0227 void ApplicationComponents::setQuickSelectDialogFactory(const QuickSelectDialogFactory &factory) 0228 { 0229 m_quickSelectDialogFactory = factory; 0230 } 0231 0232 void ApplicationComponents::onCurrentPageChanged(QObject *page) 0233 { 0234 if (!m_model) 0235 return; 0236 0237 m_model->setProperty("currentPage", QVariant::fromValue(page)); 0238 0239 QObject *editorModel = m_model->property("editor").value<QObject*>(); 0240 if (editorModel) 0241 editorModel->setProperty("task", QVariant::fromValue(Domain::Task::Ptr())); 0242 } 0243 0244 void ApplicationComponents::onCurrentTaskChanged(const Domain::Task::Ptr &task) 0245 { 0246 if (!m_model) 0247 return; 0248 0249 auto editorModel = m_model->property("editor").value<QObject*>(); 0250 if (editorModel) 0251 editorModel->setProperty("task", QVariant::fromValue(task)); 0252 } 0253 0254 void ApplicationComponents::onMoveItemsRequested() 0255 { 0256 if (!m_model) 0257 return; 0258 0259 if (m_pageView->selectedIndexes().size() == 0) 0260 return; 0261 0262 auto pageListModel = m_availablePagesView->model()->property("pageListModel").value<QAbstractItemModel*>(); 0263 Q_ASSERT(pageListModel); 0264 0265 QuickSelectDialogInterface::Ptr dlg = m_quickSelectDialogFactory(m_pageView); 0266 dlg->setModel(pageListModel); 0267 if (dlg->exec() == QDialog::Accepted) 0268 moveItems(dlg->selectedIndex(), m_pageView->selectedIndexes()); 0269 } 0270 0271 Presentation::ErrorHandler *ApplicationComponents::errorHandler() const 0272 { 0273 return m_errorHandler.data(); 0274 } 0275 0276 void ApplicationComponents::moveItems(const QModelIndex &destination, const QModelIndexList &droppedItems) 0277 { 0278 Q_ASSERT(destination.isValid()); 0279 Q_ASSERT(!droppedItems.isEmpty()); 0280 0281 auto centralListModel = droppedItems.first().model(); 0282 auto availablePagesModel = const_cast<QAbstractItemModel*>(destination.model()); 0283 0284 // drag 0285 const auto data = std::unique_ptr<QMimeData>(centralListModel->mimeData(droppedItems)); 0286 0287 // drop 0288 availablePagesModel->dropMimeData(data.get(), Qt::MoveAction, -1, -1, destination); 0289 } 0290 0291 0292 #include "moc_applicationcomponents.cpp"