ImagingTools Core SDK
TDocumentWorkspaceGuiCompBase.h
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ImtCore-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QFileInfo>
7#include <QtCore/QUrl>
8#include <QtCore/QMimeData>
9#include <QtGui/QDragEnterEvent>
10#include <QtGui/QDropEvent>
11#include <QtWidgets/QMessageBox>
12
13// ACF includes
14#include <imod/TModelWrap.h>
15#include <iprm/CNameParam.h>
16#include <idoc/IDocumentTemplate.h>
17#include <iqtgui/TDesignerGuiCompBase.h>
18#include <iqtgui/TRestorableGuiWrap.h>
19#include <iqtdoc/TQtDocumentManagerWrap.h>
20
21// ImtCore includes
22#include <imtbase/IObjectCollectionInfo.h>
23#include <imtgui/IDocumentViewDecorator.h>
24
25
26namespace imtgui
27{
28
29
30template <class DocumentManagerBase, class UI>
31class TDocumentWorkspaceGuiCompBase:
32 public iqtdoc::TQtDocumentManagerWrap<DocumentManagerBase, UI>
33{
34 Q_DECLARE_TR_FUNCTIONS(TDocumentWorkspaceGuiCompBase)
35public:
36 typedef iqtdoc::TQtDocumentManagerWrap<DocumentManagerBase, UI> BaseClass;
37 typedef typename DocumentManagerBase::SingleDocumentData SingleDocumentData;
38 typedef typename DocumentManagerBase::Views Views;
39 typedef typename Views::ConstIterator ConstIterator;
40 typedef typename DocumentManagerBase::ViewInfo ViewInfo;
41
42 I_BEGIN_BASE_COMPONENT(TDocumentWorkspaceGuiCompBase);
43 I_REGISTER_INTERFACE(idoc::IDocumentManager);
44 I_REGISTER_INTERFACE(idoc::IDocumentTypesInfo);
45 I_REGISTER_SUBELEMENT(CurrentDocumentName);
46 I_REGISTER_SUBELEMENT_INTERFACE(CurrentDocumentName, iprm::INameParam, ExtractCurrentDocumentName);
47 I_REGISTER_SUBELEMENT_INTERFACE(CurrentDocumentName, imod::IModel, ExtractCurrentDocumentName);
48 I_ASSIGN(m_documentTemplateCompPtr, "DocumentTemplate", "Document template", true, "DocumentTemplate");
49 I_ASSIGN(m_iconSizeAttrPtr, "IconSize", "Size of the icon used in the document command tool bar", true, 16);
50 I_ASSIGN(m_undoButtonsStyleAttrPtr, "UndoButtonsStyle", "Style of the command buttons for undo manager (See Qt::QToolButtonStyle for reference)", true, Qt::ToolButtonFollowStyle);
51 I_ASSIGN(m_fileButtonsStyleAttrPtr, "FileButtonsStyle", "Style of the command buttons for file operations (See Qt::QToolButtonStyle for reference)", true, Qt::ToolButtonFollowStyle);
52 I_ASSIGN(m_documentButtonsStyleAttrPtr, "DocumentButtonsStyle", "Style of the command buttons for document operations (See Qt::QToolButtonStyle for reference)", true, Qt::ToolButtonFollowStyle);
53 I_END_COMPONENT;
54
55 TDocumentWorkspaceGuiCompBase();
56
57 // reimplemented (iqtgui::IGuiObject)
58 virtual void OnTryClose(bool* ignoredPtr = nullptr) override;
59
60protected:
61 virtual void UpdateAllTitles() = 0;
62 virtual int GetDocumentIndexFromWidget(const QWidget& widget) const;
63 virtual void InitializeDocumentView(IDocumentViewDecorator* pageViewPtr, const SingleDocumentData& documentData) = 0;
64
65protected:
66 virtual void OnDragEnterEvent(QDragEnterEvent* dragEnterEventPtr);
67 virtual void OnDropEvent(QDropEvent* dropEventPtr);
68
69 // reimplemented (DocumentManagerBase)
70 virtual istd::IChangeableSharedPtr OpenSingleDocument(
71 const QString& filePath,
72 bool createView,
73 const QByteArray& viewTypeId,
74 QByteArray& documentTypeId,
75 bool beQuiet,
76 bool* ignoredPtr,
77 ibase::IProgressManager* progressManagerPtr) override;
78
79 // reimplemented (idoc::IDocumentManager)
80 virtual bool InsertNewDocument(
81 const QByteArray& documentTypeId,
82 bool createView = true,
83 const QByteArray& viewTypeId = "",
84 istd::IChangeableSharedPtr* newDocumentPtr = nullptr,
85 bool beQuiet = false,
86 bool* ignoredPtr = nullptr) override;
87
88 // reimplemented (DocumentManagerBase)
89 virtual QStringList GetOpenFilePaths(const QByteArray* documentTypeIdPtr = nullptr) const override;
90 virtual bool QueryDocumentSave(const SingleDocumentData& info, bool* ignoredPtr) override;
91
92 // reimplemented (iqt:CGuiComponentBase)
93 virtual void OnGuiCreated() override;
94 virtual void OnGuiDestroyed() override;
95 virtual void OnGuiRetranslate() override;
96
97 // reimplemented (icomp::CComponentBase)
98 virtual void OnComponentCreated() override;
99
100 // reimplemented (istd:IChangeable)
101 virtual void OnEndChanges(const istd::IChangeable::ChangeSet& changeSet) override;
102
103 // reimplemented (QObject)
104 virtual bool eventFilter(QObject* sourcePtr, QEvent* eventPtr) override;
105
106 // abstract methods
107 virtual IDocumentViewDecorator* CreateDocumentViewDecorator(
108 istd::IPolymorphic* viewPtr,
109 QWidget* parentWidgetPtr,
110 const ifile::IFilePersistence* persistencePtr) = 0;
111
112protected:
113 virtual void DoUndo();
114 virtual void DoRedo();
115 virtual void OpenDocumentForType(const QByteArray& documentTypeId);
116
117private:
118 // static template methods for subelement access
119 template <class InterfaceType>
120 static InterfaceType* ExtractCurrentDocumentName(TDocumentWorkspaceGuiCompBase& component)
121 {
122 return &component.m_currentDocumentName;
123 }
124
125protected:
126 imod::TModelWrap<iprm::CNameParam> m_currentDocumentName;
127
128 I_REF(idoc::IDocumentTemplate, m_documentTemplateCompPtr);
129 I_ATTR(int, m_iconSizeAttrPtr);
130 I_ATTR(int, m_undoButtonsStyleAttrPtr);
131 I_ATTR(int, m_fileButtonsStyleAttrPtr);
132 I_ATTR(int, m_documentButtonsStyleAttrPtr);
133};
134
135
136// public methods
137
138template <class DocumentManagerBase, class UI>
139TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::TDocumentWorkspaceGuiCompBase()
140{
141}
142
143
144// reimplemented (iqtgui::IGuiObject)
145
146template <class DocumentManagerBase, class UI>
147void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnTryClose(bool* ignoredPtr)
148{
149 if (BaseClass::SaveDirtyDocuments(false, ignoredPtr)){
150 int documentInfosCount = BaseClass::GetDocumentsCount();
151 for (int documentIndex = 0; documentIndex < documentInfosCount; ++documentIndex){
152 SingleDocumentData& documentData = BaseClass::GetSingleDocumentData(documentIndex);
153
154 documentData.isDirty = false;
155 }
156
157 this->CloseAllDocuments();
158 }
159
160 if (ignoredPtr != nullptr){
161 *ignoredPtr = (BaseClass::GetDocumentsCount() > 0);
162 }
163}
164
165
166// protected members
167
168template <class DocumentManagerBase, class UI>
169int TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::GetDocumentIndexFromWidget(const QWidget& widget) const
170{
171 int documentInfosCount = BaseClass::GetDocumentsCount();
172 for (int documentIndex = 0; documentIndex < documentInfosCount; ++documentIndex){
173 const SingleDocumentData& documentData = BaseClass::GetSingleDocumentData(documentIndex);
174
175 for ( ConstIterator viewIter = documentData.views.begin();
176 viewIter != documentData.views.end();
177 ++viewIter){
178 const ViewInfo& viewInfo = *viewIter;
179
180 iqtgui::IGuiObject* guiObjectPtr = CompCastPtr<iqtgui::IGuiObject>(const_cast<istd::IPolymorphic*>(viewInfo.viewPtr.GetPtr()));
181 if (guiObjectPtr != nullptr){
182 if (guiObjectPtr->GetWidget() == &widget){
183 return documentIndex;
184 }
185 }
186 }
187 }
188
189 return -1;
190}
191
192
193// protected methods
194
195template <class DocumentManagerBase, class UI>
196void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnDragEnterEvent(QDragEnterEvent* dragEnterEventPtr)
197{
198 if (dragEnterEventPtr->mimeData()->hasFormat("text/uri-list")){
199 dragEnterEventPtr->acceptProposedAction();
200 }
201}
202
203
204template <class DocumentManagerBase, class UI>
205void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnDropEvent(QDropEvent* dropEventPtr)
206{
207 const QMimeData* mimeData = dropEventPtr->mimeData();
208 if (mimeData->hasUrls()){
209 QList<QUrl> files = mimeData->urls();
210
211 for (int fileIndex = 0; fileIndex < files.count(); fileIndex++){
212 QString filePath = files.at(fileIndex).toLocalFile();
213
214 if (BaseClass::OpenDocument(nullptr, &filePath)){
215 dropEventPtr->setAccepted(true);
216
217 return;
218 }
219 }
220 }
221
222 dropEventPtr->setAccepted(false);
223}
224
225
226// reimplemented (DocumentManagerBase)
227
228template <class DocumentManagerBase, class UI>
229istd::IChangeableSharedPtr TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OpenSingleDocument(
230 const QString& filePath,
231 bool createView,
232 const QByteArray& viewTypeId,
233 QByteArray& documentTypeId,
234 bool beQuiet,
235 bool* ignoredPtr,
236 ibase::IProgressManager* progressManagerPtr)
237{
238 SingleDocumentData* documentInfoPtr = BaseClass::GetDocumentInfoFromPath(filePath);
239 bool isNewViewType = true;
240 if (documentInfoPtr != nullptr){
241 for (int i = 0; i < documentInfoPtr->views.count(); ++i){
242 if (documentInfoPtr->views[i].viewTypeId == viewTypeId){
243 isNewViewType = false;
244 break;
245 }
246 }
247 }
248
249 if (documentInfoPtr != nullptr && !isNewViewType){
250 createView = false;
251 }
252
253 return BaseClass::OpenSingleDocument(filePath, createView, viewTypeId, documentTypeId, beQuiet, ignoredPtr, progressManagerPtr);
254}
255
256
257// reimplemented (idoc::IDocumentManager)
258
259template <class DocumentManagerBase, class UI>
260bool TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::InsertNewDocument(
261 const QByteArray& documentTypeId,
262 bool createView,
263 const QByteArray& viewTypeId,
264 istd::IChangeableSharedPtr* newDocumentPtr,
265 bool beQuiet,
266 bool* ignoredPtr)
267{
268 bool retVal = BaseClass::InsertNewDocument(documentTypeId, createView, viewTypeId, newDocumentPtr, beQuiet, ignoredPtr);
269
270 if (retVal && (newDocumentPtr != nullptr) && newDocumentPtr->IsValid() && createView){
271 int documentsCount = BaseClass::GetDocumentsCount();
272 for (int i = 0; i < documentsCount; ++i){
273 if (&BaseClass::GetDocumentFromIndex(i) == newDocumentPtr->GetPtr()){
274 istd::IPolymorphic* viewPtr = BaseClass::GetViewFromIndex(i, 0);
275 if (viewPtr != nullptr){
276 BaseClass::SetActiveView(viewPtr);
277 }
278
279 break;
280 }
281 }
282 }
283
284 return retVal;
285}
286
287
288// reimplemented (DocumentManagerBase)
289
290template <class DocumentManagerBase, class UI>
291QStringList TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::GetOpenFilePaths(const QByteArray* documentTypeIdPtr) const
292{
293 QStringList files = BaseClass::GetOpenFilePathesFromDialog(documentTypeIdPtr);
294
295 if (!files.isEmpty()){
296 BaseClass::UpdateLastDirectory(files.at(0));
297 }
298
299 return files;
300}
301
302
303template <class DocumentManagerBase, class UI>
304bool TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::QueryDocumentSave(const SingleDocumentData& info, bool* ignoredPtr)
305{
306 QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No;
307
308 if (ignoredPtr != nullptr){
309 *ignoredPtr = false;
310
311 buttons |= QMessageBox::Cancel;
312 }
313
314 QFileInfo fileInfo(info.filePath);
315
316 int dialogResult = QMessageBox::information(
317 BaseClass::GetQtWidget(),
318 tr("Close document"),
319 tr("Do you want to save your changes made in document\n%1").arg(QDir::toNativeSeparators(fileInfo.completeBaseName())),
320 buttons,
321 QMessageBox::Yes);
322
323 if (dialogResult == QMessageBox::Yes){
324 return true;
325 }
326 else if ((ignoredPtr != nullptr) && (dialogResult == QMessageBox::Cancel)){
327 *ignoredPtr = true;
328 }
329
330 return false;
331}
332
333
334// reimplemented (iqt:CGuiObjectBase)
335
336template <class DocumentManagerBase, class UI>
337void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnGuiCreated()
338{
339 BaseClass::OnGuiCreated();
340
341 QWidget* mainWindowPtr = BaseClass::GetQtWidget();
342 if (mainWindowPtr != nullptr){
343 mainWindowPtr->setAcceptDrops(true);
344 }
345}
346
347
348template <class DocumentManagerBase, class UI>
349void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnGuiDestroyed()
350{
351 this->CloseAllDocuments();
352
353 BaseClass::OnGuiDestroyed();
354}
355
356
357template <class DocumentManagerBase, class UI>
358void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnGuiRetranslate()
359{
360 BaseClass::OnGuiRetranslate();
361
362 UpdateAllTitles();
363}
364
365
366// reimplemented (icomp::CComponentBase)
367
368template <class DocumentManagerBase, class UI>
369void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnComponentCreated()
370{
371 BaseClass::OnComponentCreated();
372
373 BaseClass::SetDocumentTemplate(m_documentTemplateCompPtr.GetPtr());
374}
375
376
377// reimplemented (istd:IChangeable)
378
379template <class DocumentManagerBase, class UI>
380void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OnEndChanges(const istd::IChangeable::ChangeSet& changeSet)
381{
382 BaseClass::OnEndChanges(changeSet);
383
384 if (BaseClass::IsGuiCreated()){
385 UpdateAllTitles();
386 }
387}
388
389
390// reimplemented (QObject)
391
392template <class DocumentManagerBase, class UI>
393bool TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::eventFilter(QObject* sourcePtr, QEvent* eventPtr)
394{
395 if (eventPtr->type() == QEvent::DragEnter){
396 QDragEnterEvent* dragEnterEventPtr = dynamic_cast<QDragEnterEvent*>(eventPtr);
397 Q_ASSERT(dragEnterEventPtr != nullptr);
398
399 OnDragEnterEvent(dragEnterEventPtr);
400
401 return true;
402 }
403 else if (eventPtr->type() == QEvent::Drop){
404 QDropEvent* dropEventPtr = dynamic_cast<QDropEvent*>(eventPtr);
405 Q_ASSERT(dropEventPtr != nullptr);
406
407 OnDropEvent(dropEventPtr);
408
409 return true;
410 }
411
412 return BaseClass::eventFilter(sourcePtr, eventPtr);
413}
414
415
416// protected methods
417
418template <class DocumentManagerBase, class UI>
419void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::DoUndo()
420{
421 SingleDocumentData* documentDataPtr = BaseClass::GetActiveDocumentInfo();
422 if ((documentDataPtr != nullptr) && documentDataPtr->undoManagerPtr.IsValid() && documentDataPtr->undoManagerPtr->GetAvailableUndoSteps() > 0){
423 documentDataPtr->undoManagerPtr->DoUndo();
424 }
425}
426
427
428template <class DocumentManagerBase, class UI>
429void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::DoRedo()
430{
431 SingleDocumentData* documentDataPtr = BaseClass::GetActiveDocumentInfo();
432 if ((documentDataPtr != nullptr) && documentDataPtr->undoManagerPtr.IsValid() && documentDataPtr->undoManagerPtr->GetAvailableRedoSteps() > 0){
433 documentDataPtr->undoManagerPtr->DoRedo();
434 }
435}
436
437
438template <class DocumentManagerBase, class UI>
439void TDocumentWorkspaceGuiCompBase<DocumentManagerBase, UI>::OpenDocumentForType(const QByteArray& documentTypeId)
440{
441 bool ignoredFlag = false;
442 if (!BaseClass::OpenDocument(&documentTypeId, nullptr, true, "", nullptr, nullptr, false, &ignoredFlag)){
443 if (!ignoredFlag){
444 QMessageBox::warning(nullptr, "", tr("Document could not be opened"));
445 }
446 }
447}
448
449
450} // namespace imtgui
451
452