File indexing completed on 2025-02-09 07:11:32
0001 /* 0002 This file is part of the Kasten Framework, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2011-2012 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "singleviewwindow_p.hpp" 0010 0011 // this lib 0012 #include "singleviewarea.hpp" 0013 #include <abstractxmlguicontroller.hpp> 0014 #include <toolviewdockwidget.hpp> 0015 #include <abstracttoolview.hpp> 0016 #include <abstractview.hpp> 0017 // Kasten core 0018 #include <Kasten/AbstractTool> 0019 #include <Kasten/AbstractModelSynchronizer> 0020 // Std 0021 #include <utility> 0022 0023 namespace Kasten { 0024 0025 SingleViewWindowPrivate::SingleViewWindowPrivate(SingleViewWindow* parent, 0026 AbstractView* view) 0027 : q_ptr(parent) 0028 , mViewArea(new SingleViewArea()) 0029 { 0030 parent->setCentralWidget(mViewArea->widget()); 0031 0032 setView(view); 0033 } 0034 0035 SingleViewWindowPrivate::~SingleViewWindowPrivate() 0036 { 0037 // we have to explicitly reset any inline tool view before first deleting all tools 0038 // and then the view area, because on destruction of the inline tool view it 0039 // operates on the tool, which then has been no longer ->crash 0040 // The other option would be to first delete the view, but for reasons if do not 0041 // remember currently I prefer the destruction in this order 0042 // TODO: make this call unneeded 0043 mViewArea->setCurrentToolInlineView(nullptr); 0044 0045 qDeleteAll(mControllers); 0046 qDeleteAll(mDockWidgets); 0047 qDeleteAll(mTools); 0048 0049 delete mViewArea; 0050 } 0051 0052 void SingleViewWindowPrivate::setView(AbstractView* view) 0053 { 0054 Q_Q(SingleViewWindow); 0055 0056 if (mView == view) { 0057 return; 0058 } 0059 0060 if (mView) { 0061 mView->disconnect(q); 0062 } 0063 0064 // TODO: what to do with the old one if existing? 0065 mView = view; 0066 mViewArea->setView(view); 0067 0068 for (AbstractXmlGuiController* controller : std::as_const(mControllers)) { 0069 controller->setTargetModel(view); 0070 } 0071 0072 for (ToolViewDockWidget* dockWidget : std::as_const(mDockWidgets)) { 0073 if (dockWidget->isShown()) { 0074 dockWidget->toolView()->tool()->setTargetModel(view); 0075 } 0076 } 0077 0078 AbstractDocument* oldDocument = mDocument; 0079 mDocument = view ? view->findBaseModel<AbstractDocument*>() : nullptr; 0080 const bool isNewDocument = (mDocument != oldDocument); 0081 0082 AbstractModelSynchronizer* oldSynchronizer = mSynchronizer; 0083 mSynchronizer = mDocument ? mDocument->synchronizer() : nullptr; 0084 const bool isNewSynchronizer = (mSynchronizer != oldSynchronizer); 0085 0086 if (oldSynchronizer) { 0087 if (isNewSynchronizer) { 0088 oldSynchronizer->disconnect(q); 0089 } 0090 } else { 0091 if (oldDocument && isNewDocument) { 0092 oldDocument->disconnect(q); 0093 } 0094 } 0095 0096 const QString title = view ? view->title() : QString(); 0097 const bool hasChanges = 0098 mSynchronizer ? (mSynchronizer->localSyncState() == LocalHasChanges) : 0099 mDocument ? mDocument->contentFlags().testFlag(ContentHasUnstoredChanges) : 0100 false; 0101 q->setCaption(title, hasChanges); 0102 0103 if (view) { 0104 QObject::connect(view, &AbstractModel::titleChanged, 0105 q, [&](const QString& Title) { onTitleChanged(Title); }); 0106 } 0107 0108 if (mSynchronizer) { 0109 if (isNewSynchronizer) { 0110 QObject::connect(mSynchronizer, &AbstractModelSynchronizer::localSyncStateChanged, 0111 q, [&](LocalSyncState localSyncState) { onLocalSyncStateChanged(localSyncState); }); 0112 QObject::connect(mSynchronizer, &QObject::destroyed, 0113 q, [&](QObject* object) { onSynchronizerDeleted(object); }); 0114 } 0115 } else if (mDocument) { 0116 if (isNewDocument) { 0117 QObject::connect(mDocument, &AbstractDocument::contentFlagsChanged, 0118 q, [&](ContentFlags contentFlags) { onContentFlagsChanged(contentFlags); }); 0119 } 0120 } 0121 } 0122 0123 void SingleViewWindowPrivate::addXmlGuiController(AbstractXmlGuiController* controller) 0124 { 0125 mControllers.append(controller); 0126 } 0127 0128 void SingleViewWindowPrivate::addTool(AbstractToolView* toolView) 0129 { 0130 Q_Q(SingleViewWindow); 0131 0132 auto* dockWidget = new ToolViewDockWidget(toolView, q); 0133 // TODO: where to set the initial area? 0134 q->addDockWidget(Qt::RightDockWidgetArea, dockWidget); 0135 0136 mTools.append(toolView->tool()); 0137 mDockWidgets.append(dockWidget); 0138 0139 if (dockWidget->isVisible() && mView) { 0140 toolView->tool()->setTargetModel(mView); 0141 } 0142 0143 QObject::connect(dockWidget, &QDockWidget::visibilityChanged, 0144 q, [&](bool visible) { onToolVisibilityChanged(visible); }); 0145 } 0146 0147 void SingleViewWindowPrivate::onTitleChanged(const QString& newTitle) 0148 { 0149 Q_Q(SingleViewWindow); 0150 0151 if (mView) { 0152 auto* document = mView->findBaseModel<AbstractDocument*>(); 0153 AbstractModelSynchronizer* synchronizer = document->synchronizer(); 0154 const bool hasChanges = 0155 synchronizer ? (synchronizer->localSyncState() == LocalHasChanges) : 0156 document ? document->contentFlags().testFlag(ContentHasUnstoredChanges) : 0157 false; 0158 q->setCaption(newTitle, hasChanges); 0159 } 0160 } 0161 0162 void SingleViewWindowPrivate::onContentFlagsChanged(ContentFlags contentFlags) 0163 { 0164 Q_Q(SingleViewWindow); 0165 0166 if (mView) { 0167 const bool hasChanges = (contentFlags & ContentHasUnstoredChanges); 0168 q->setCaption(mView->title(), hasChanges); 0169 } 0170 } 0171 0172 void SingleViewWindowPrivate::onLocalSyncStateChanged(LocalSyncState newState) 0173 { 0174 Q_Q(SingleViewWindow); 0175 0176 if (mView) { 0177 const bool hasChanges = (newState == LocalHasChanges); 0178 q->setCaption(mView->title(), hasChanges); 0179 } 0180 } 0181 0182 void SingleViewWindowPrivate::onSynchronizerDeleted(QObject* synchronizer) 0183 { 0184 Q_Q(SingleViewWindow); 0185 0186 if (synchronizer != mSynchronizer) { 0187 return; 0188 } 0189 0190 mSynchronizer = nullptr; 0191 0192 // switch to document state 0193 QObject::connect(mDocument, &AbstractDocument::contentFlagsChanged, 0194 q, [&](ContentFlags contentFlags) { onContentFlagsChanged(contentFlags); }); 0195 0196 onContentFlagsChanged(mDocument->contentFlags()); 0197 } 0198 0199 void SingleViewWindowPrivate::onToolVisibilityChanged(bool isVisible) 0200 { 0201 Q_Q(SingleViewWindow); 0202 0203 auto* dockWidget = qobject_cast<ToolViewDockWidget*>(q->sender()); 0204 if (dockWidget) { 0205 AbstractView* view = isVisible ? mView : nullptr; 0206 dockWidget->toolView()->tool()->setTargetModel(view); 0207 } 0208 } 0209 0210 }