File indexing completed on 2024-04-28 17:08:12
0001 /* 0002 This file is part of the Okteta program, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2006-2011 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #include "mainwindow.hpp" 0010 0011 // program 0012 #include "program.hpp" 0013 // tmp 0014 #include <Kasten/Okteta/ByteArrayViewProfileManager> 0015 // tools 0016 #include <Kasten/Okteta/StringsExtractToolViewFactory> 0017 #include <Kasten/Okteta/StringsExtractToolFactory> 0018 #include <Kasten/Okteta/InfoToolViewFactory> 0019 #include <Kasten/Okteta/InfoToolFactory> 0020 #include <Kasten/Okteta/FilterToolViewFactory> 0021 #include <Kasten/Okteta/FilterToolFactory> 0022 #include <Kasten/Okteta/CharsetConversionToolViewFactory> 0023 #include <Kasten/Okteta/CharsetConversionToolFactory> 0024 #include <Kasten/Okteta/ChecksumToolViewFactory> 0025 #include <Kasten/Okteta/ChecksumToolFactory> 0026 #include <Kasten/Okteta/DocumentInfoToolViewFactory> 0027 #include <Kasten/Okteta/DocumentInfoToolFactory> 0028 #include <Kasten/Okteta/PODDecoderToolViewFactory> 0029 #include <Kasten/Okteta/PODDecoderToolFactory> 0030 #include <Kasten/Okteta/ByteTableToolViewFactory> 0031 #include <Kasten/Okteta/ByteTableToolFactory> 0032 #include <Kasten/Okteta/BookmarksToolViewFactory> 0033 #include <Kasten/Okteta/BookmarksToolFactory> 0034 #include <Kasten/Okteta/StructuresToolViewFactory> 0035 #include <Kasten/Okteta/StructuresToolFactory> 0036 0037 // Kasten tools 0038 #include <Kasten/VersionViewToolViewFactory> 0039 #include <Kasten/VersionViewToolFactory> 0040 #include <Kasten/FileSystemBrowserToolViewFactory> 0041 #include <Kasten/FileSystemBrowserToolFactory> 0042 #include <Kasten/DocumentsToolViewFactory> 0043 #include <Kasten/DocumentsToolFactory> 0044 #include <Kasten/TerminalToolViewFactory> 0045 #include <Kasten/TerminalToolFactory> 0046 // controllers 0047 // #include <Kasten/Okteta/OverwriteOnlyControllerFactory> 0048 #include <Kasten/Okteta/OverwriteModeControllerFactory> 0049 #include <Kasten/Okteta/GotoOffsetControllerFactory> 0050 #include <Kasten/Okteta/SelectRangeControllerFactory> 0051 #include <Kasten/Okteta/SearchControllerFactory> 0052 #include <Kasten/Okteta/ReplaceControllerFactory> 0053 #include <Kasten/Okteta/BookmarksControllerFactory> 0054 #include <Kasten/Okteta/PrintControllerFactory> 0055 #include <Kasten/Okteta/ViewConfigControllerFactory> 0056 #include <Kasten/Okteta/ViewModeControllerFactory> 0057 #include <Kasten/Okteta/ViewContextMenuControllerFactory> 0058 #include <Kasten/Okteta/ViewStatusControllerFactory> 0059 #include <Kasten/Okteta/ViewProfileControllerFactory> 0060 #include <Kasten/Okteta/ViewProfilesManageControllerFactory> 0061 // Kasten controllers 0062 #include <Kasten/ModifiedBarControllerFactory> 0063 #include <Kasten/ReadOnlyControllerFactory> 0064 #include <Kasten/ReadOnlyBarControllerFactory> 0065 #include <Kasten/CreatorControllerFactory> 0066 #include <Kasten/LoaderControllerFactory> 0067 #include <Kasten/CloseControllerFactory> 0068 #include <Kasten/SetRemoteControllerFactory> 0069 #include <Kasten/SynchronizeControllerFactory> 0070 #include <Kasten/ClipboardControllerFactory> 0071 #include <Kasten/InsertControllerFactory> 0072 #include <Kasten/CopyAsControllerFactory> 0073 #include <Kasten/ExportControllerFactory> 0074 #include <Kasten/VersionControllerFactory> 0075 #include <Kasten/ZoomControllerFactory> 0076 #include <Kasten/ZoomBarControllerFactory> 0077 #include <Kasten/SelectControllerFactory> 0078 #include <Kasten/ViewAreaContextMenuControllerFactory> 0079 #include <Kasten/SwitchViewControllerFactory> 0080 #include <Kasten/ViewListMenuControllerFactory> 0081 #include <Kasten/ViewAreaSplitControllerFactory> 0082 #include <Kasten/ToolListMenuControllerFactory> 0083 #include <Kasten/FullScreenControllerFactory> 0084 #ifndef KASTEN_NO_UICOLORSCHEMECONTROLLER 0085 #include <Kasten/UiColorSchemeControllerFactory> 0086 #endif 0087 #include <Kasten/QuitControllerFactory> 0088 // Kasten gui 0089 #include <Kasten/MultiDocumentStrategy> 0090 #include <Kasten/ModelCodecViewManager> 0091 #include <Kasten/ViewManager> 0092 #include <Kasten/MultiViewAreas> 0093 #include <Kasten/StatusBar> 0094 // Kasten core 0095 #include <Kasten/ModelCodecManager> 0096 #include <Kasten/DocumentCreateManager> 0097 #include <Kasten/DocumentSyncManager> 0098 #include <Kasten/DocumentManager> 0099 // KF 0100 #include <KConfigGroup> 0101 #include <KSharedConfig> 0102 // Qt 0103 #include <QUrl> 0104 #include <QMimeData> 0105 0106 namespace Kasten { 0107 0108 static constexpr char LoadedUrlsKey[] = "LoadedUrls"; 0109 0110 OktetaMainWindow::OktetaMainWindow(OktetaProgram* program) 0111 : ShellWindow(program->viewManager()) 0112 , mProgram(program) 0113 { 0114 setObjectName(QStringLiteral("Shell")); 0115 0116 // there is only one mainwindow, so have this show the document if requested 0117 connect(mProgram->documentManager(), &DocumentManager::focusRequested, 0118 this, &OktetaMainWindow::showDocument); 0119 connect(viewArea(), &MultiViewAreas::dataOffered, 0120 this, &OktetaMainWindow::onDataOffered); 0121 connect(viewArea(), &MultiViewAreas::dataDropped, 0122 this, &OktetaMainWindow::onDataDropped); 0123 connect(viewArea(), &MultiViewAreas::newDocumentRequested, 0124 this, &OktetaMainWindow::onNewDocumentRequested); 0125 connect(viewArea(), &AbstractGroupedViews::closeRequest, 0126 this, &OktetaMainWindow::onCloseRequest); 0127 0128 // Using State value as generated with Qt 5.15.11-KDE 0129 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 11) 0130 // XXX: Workaround for Qt 4.4's lacking of proper handling of the initial layout of dock widgets 0131 // This state is taken from an oktetarc where the docker constellation was configured by hand. 0132 // Setting this state if none is present seems to work, but there's 0133 // still the versioning problem to be accounted for. 0134 // Hack borrowed from trunk/koffice/krita/ui/kis_view2.cpp: 0135 const QString mainWindowState = QStringLiteral( 0136 "AAAA/wAAAAD9AAAAAwAAAAAAAAEVAAACLvwCAAAAAfwAAABLAAACLgAAAI8BAAAd+gAAAAABAAAAAvsAAAAiAEYAaQBsAGUAUwB5AHMAdABlAG0AQgByAG8AdwBzAGUAcgEAAAAA/////wAAAGQA////+wAAABIARABvAGMAdQBtAGUAbgB0AHMBAAAAAP////8AAABcAP///wAAAAEAAAHhAAACLvwCAAAABfsAAAAUAFMAdAByAHUAYwB0AFQAbwBvAGwDAAACjQAAAPwAAAIyAAABT/sAAAAQAFYAZQByAHMAaQBvAG4AcwAAAAA2AAAAiQAAAAAAAAAA/AAAAEsAAAEqAAABKgEAAB36AAAAAQEAAAAH+wAAABgARABvAGMAdQBtAGUAbgB0AEkAbgBmAG8BAAAAAP////8AAACMAP////sAAAASAEIAeQB0AGUAVABhAGIAbABlAQAAAAD/////AAAAXAD////7AAAADgBTAHQAcgBpAG4AZwBzAQAAAAD/////AAAAiQD////7AAAAEABDAGgAZQBjAGsAcwB1AG0BAAAAAP////8AAAEFAP////sAAAAcAFMAdAByAHUAYwB0AHUAcgBlAHMAVABvAG8AbAEAAAAA/////wAAAJkA////+wAAABQAUwB0AHIAdQBjAHQAVABvAG8AbAMAAAKNAAAA/AAAAjIAAAFP+wAAABQAUABPAEQARABlAGMAbwBkAGUAcgEAAAAA/////wAAAJQA/////AAAAQsAAADsAAAAAAD////6AAAAAAEAAAAB+wAAABAAQwBoAGUAYwBrAFMAdQBtAQAAAAD/////AAAAAAAAAAD8AAABdgAAAQMAAAEDAQAAHfoAAAAAAQAAAAT7AAAAGABCAGkAbgBhAHIAeQBGAGkAbAB0AGUAcgEAAAAA/////wAAAVMA////+wAAACIAQwBoAGEAcgBzAGUAdABDAG8AbgB2AGUAcgBzAGkAbwBuAQAAAAD/////AAABRAD////7AAAACABJAG4AZgBvAQAAAAD/////AAAAiQD////7AAAAEgBCAG8AbwBrAG0AYQByAGsAcwEAAAAA/////wAAAFwA////AAAAAwAABVYAAABC/AEAAAAB+wAAABAAVABlAHIAbQBpAG4AYQBsAAAAAAAAAAVWAAAAXAD///8AAADlAAACLgAAAAQAAAAEAAAACAAAAAj8AAAAAQAAAAIAAAABAAAAFgBtAGEAaQBuAFQAbwBvAGwAQgBhAHIBAAAAAAAABAYAAAAAAAAAAA=="); 0137 const char mainWindowStateKey[] = "State"; 0138 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("MainWindow")); 0139 if (!group.hasKey(mainWindowStateKey)) { 0140 group.writeEntry(mainWindowStateKey, mainWindowState); 0141 } 0142 #endif 0143 0144 setStatusBar(new Kasten::StatusBar(this)); 0145 0146 setupControllers(); 0147 setupGUI(); 0148 0149 // all controllers which use plugActionList have to do so after(!) setupGUI() or their entries will be removed 0150 // TODO: why is this so? 0151 // tmp 0152 addXmlGuiControllerFromFactory(ToolListMenuControllerFactory(this)); 0153 addXmlGuiControllerFromFactory(ViewListMenuControllerFactory(viewManager(), viewArea())); 0154 } 0155 0156 OktetaMainWindow::~OktetaMainWindow() = default; 0157 0158 void OktetaMainWindow::setupControllers() 0159 { 0160 MultiDocumentStrategy* const documentStrategy = mProgram->documentStrategy(); 0161 ViewManager* const viewManager = this->viewManager(); 0162 MultiViewAreas* const viewArea = this->viewArea(); 0163 ModelCodecViewManager* const codecViewManager = viewManager->codecViewManager(); 0164 DocumentManager* const documentManager = mProgram->documentManager(); 0165 ModelCodecManager* const codecManager = documentManager->codecManager(); 0166 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0167 // tmp 0168 ByteArrayViewProfileManager* const byteArrayViewProfileManager = mProgram->byteArrayViewProfileManager(); 0169 0170 // general, part of Kasten 0171 addXmlGuiControllerFromFactory(CreatorControllerFactory(codecManager, documentStrategy)); 0172 addXmlGuiControllerFromFactory(LoaderControllerFactory(documentStrategy)); 0173 addXmlGuiControllerFromFactory(SetRemoteControllerFactory(syncManager)); 0174 addXmlGuiControllerFromFactory(SynchronizeControllerFactory(syncManager)); 0175 addXmlGuiControllerFromFactory(ExportControllerFactory(codecViewManager, codecManager)); 0176 addXmlGuiControllerFromFactory(CloseControllerFactory(documentStrategy)); 0177 addXmlGuiControllerFromFactory(VersionControllerFactory()); 0178 addXmlGuiControllerFromFactory(ReadOnlyControllerFactory()); 0179 addXmlGuiControllerFromFactory(ViewAreaContextMenuControllerFactory(viewArea, syncManager)); 0180 addXmlGuiControllerFromFactory(SwitchViewControllerFactory(viewArea)); 0181 addXmlGuiControllerFromFactory(ViewAreaSplitControllerFactory(viewManager, viewArea)); 0182 addXmlGuiControllerFromFactory(FullScreenControllerFactory(this)); 0183 #ifndef KASTEN_NO_UICOLORSCHEMECONTROLLER 0184 addXmlGuiControllerFromFactory(UiColorSchemeControllerFactory(this)); 0185 #endif 0186 addXmlGuiControllerFromFactory(QuitControllerFactory(this)); 0187 0188 addXmlGuiControllerFromFactory(ZoomControllerFactory()); 0189 addXmlGuiControllerFromFactory(SelectControllerFactory()); 0190 addXmlGuiControllerFromFactory(ClipboardControllerFactory()); 0191 addXmlGuiControllerFromFactory(InsertControllerFactory(codecViewManager, codecManager)); 0192 addXmlGuiControllerFromFactory(CopyAsControllerFactory(codecViewManager, codecManager)); 0193 0194 addToolFromFactory(FileSystemBrowserToolViewFactory(), FileSystemBrowserToolFactory(syncManager)); 0195 addToolFromFactory(DocumentsToolViewFactory(), DocumentsToolFactory(documentManager)); 0196 addToolFromFactory(TerminalToolViewFactory(), TerminalToolFactory(syncManager)); 0197 #ifndef NDEBUG 0198 addToolFromFactory(VersionViewToolViewFactory(), VersionViewToolFactory()); 0199 #endif 0200 0201 // Okteta specific 0202 // addXmlGuiControllerFromFactory(OverwriteOnlyControllerFactory() ); 0203 addXmlGuiControllerFromFactory(OverwriteModeControllerFactory()); 0204 addXmlGuiControllerFromFactory(SearchControllerFactory(this)); 0205 addXmlGuiControllerFromFactory(ReplaceControllerFactory(this)); 0206 addXmlGuiControllerFromFactory(GotoOffsetControllerFactory(viewArea)); 0207 addXmlGuiControllerFromFactory(SelectRangeControllerFactory(viewArea)); 0208 addXmlGuiControllerFromFactory(BookmarksControllerFactory()); 0209 addXmlGuiControllerFromFactory(PrintControllerFactory()); 0210 addXmlGuiControllerFromFactory(ViewConfigControllerFactory()); 0211 addXmlGuiControllerFromFactory(ViewModeControllerFactory()); 0212 addXmlGuiControllerFromFactory(ViewContextMenuControllerFactory()); 0213 addXmlGuiControllerFromFactory(ViewProfileControllerFactory(byteArrayViewProfileManager, this)); 0214 addXmlGuiControllerFromFactory(ViewProfilesManageControllerFactory(byteArrayViewProfileManager, this)); 0215 0216 auto* const bottomBar = static_cast<Kasten::StatusBar*>(statusBar()); 0217 addXmlGuiControllerFromFactory(ViewStatusControllerFactory(bottomBar)); 0218 addXmlGuiControllerFromFactory(ModifiedBarControllerFactory(bottomBar)); 0219 addXmlGuiControllerFromFactory(ReadOnlyBarControllerFactory(bottomBar)); 0220 addXmlGuiControllerFromFactory(ZoomBarControllerFactory(bottomBar)); 0221 0222 addToolFromFactory(DocumentInfoToolViewFactory(), DocumentInfoToolFactory(syncManager)); 0223 addToolFromFactory(ChecksumToolViewFactory(), ChecksumToolFactory()); 0224 addToolFromFactory(FilterToolViewFactory(), FilterToolFactory()); 0225 addToolFromFactory(CharsetConversionToolViewFactory(), CharsetConversionToolFactory()); 0226 addToolFromFactory(StringsExtractToolViewFactory(), StringsExtractToolFactory()); 0227 addToolFromFactory(ByteTableToolViewFactory(), ByteTableToolFactory()); 0228 addToolFromFactory(InfoToolViewFactory(), InfoToolFactory()); 0229 addToolFromFactory(PodDecoderToolViewFactory(), PodDecoderToolFactory()); 0230 addToolFromFactory(StructuresToolViewFactory(), StructuresToolFactory()); 0231 addToolFromFactory(BookmarksToolViewFactory(), BookmarksToolFactory()); 0232 } 0233 0234 void OktetaMainWindow::addToolFromFactory(const AbstractToolViewFactory& toolViewFactory, 0235 const AbstractToolFactory& toolFactory) 0236 { 0237 AbstractTool* tool = toolFactory.create(); 0238 AbstractToolView* toolView = toolViewFactory.create(tool); 0239 0240 addTool(toolView); 0241 } 0242 0243 void OktetaMainWindow::addXmlGuiControllerFromFactory(const AbstractXmlGuiControllerFactory& factory) 0244 { 0245 AbstractXmlGuiController* controller = factory.create(this); 0246 addXmlGuiController(controller); 0247 } 0248 0249 0250 bool OktetaMainWindow::queryClose() 0251 { 0252 // TODO: query the document manager or query the view manager? 0253 return mProgram->documentManager()->canCloseAll(); 0254 } 0255 0256 void OktetaMainWindow::saveProperties(KConfigGroup& configGroup) 0257 { 0258 DocumentManager* const documentManager = mProgram->documentManager(); 0259 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0260 const QVector<AbstractDocument*> documents = documentManager->documents(); 0261 0262 QStringList urls; 0263 urls.reserve(documents.size()); 0264 for (AbstractDocument* document : documents) { 0265 urls.append(syncManager->urlOf(document).url()); 0266 } 0267 0268 configGroup.writePathEntry(LoadedUrlsKey, urls); 0269 } 0270 0271 void OktetaMainWindow::readProperties(const KConfigGroup& configGroup) 0272 { 0273 const QStringList urls = configGroup.readPathEntry(LoadedUrlsKey, QStringList()); 0274 0275 DocumentManager* const documentManager = mProgram->documentManager(); 0276 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0277 DocumentCreateManager* const createManager = documentManager->createManager(); 0278 for (const QString& url : urls) { 0279 if (url.isEmpty()) { 0280 createManager->createNew(); 0281 } else { 0282 syncManager->load(QUrl(url, QUrl::TolerantMode)); 0283 } 0284 // TODO: set view to offset 0285 // if( offset != -1 ) 0286 } 0287 } 0288 0289 void OktetaMainWindow::onDataOffered(const QMimeData* mimeData, bool& accept) 0290 { 0291 accept = mimeData->hasUrls() 0292 || mProgram->documentManager()->createManager()->canCreateNewFromData(mimeData); 0293 } 0294 0295 void OktetaMainWindow::onDataDropped(const QMimeData* mimeData) 0296 { 0297 const QList<QUrl> urls = mimeData->urls(); 0298 0299 DocumentManager* const documentManager = mProgram->documentManager(); 0300 if (!urls.isEmpty()) { 0301 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0302 0303 for (const QUrl& url : urls) { 0304 syncManager->load(url); 0305 } 0306 } else { 0307 documentManager->createManager()->createNewFromData(mimeData, true); 0308 } 0309 } 0310 0311 void OktetaMainWindow::onNewDocumentRequested() 0312 { 0313 mProgram->documentManager()->createManager()->createNew(); 0314 } 0315 0316 void OktetaMainWindow::onCloseRequest(const QVector<Kasten::AbstractView*>& views) 0317 { 0318 // group views per document 0319 QHash<AbstractDocument*, QVector<AbstractView*>> viewsToClosePerDocument; 0320 for (AbstractView* view : views) { 0321 auto* document = view->findBaseModel<AbstractDocument*>(); 0322 viewsToClosePerDocument[document].append(view); 0323 } 0324 0325 // find documents which lose all views 0326 const QVector<AbstractView*> allViews = viewManager()->views(); 0327 for (AbstractView* view : allViews) { 0328 auto* document = view->findBaseModel<AbstractDocument*>(); 0329 QHash<AbstractDocument*, QVector<AbstractView*>>::Iterator it = 0330 viewsToClosePerDocument.find(document); 0331 0332 if (it != viewsToClosePerDocument.end()) { 0333 const QVector<AbstractView*>& viewsOfDocument = it.value(); 0334 const bool isAnotherView = !viewsOfDocument.contains(view); 0335 if (isAnotherView) { 0336 viewsToClosePerDocument.erase(it); 0337 } 0338 } 0339 } 0340 0341 const QVector<AbstractDocument*> documentsWithoutViews = viewsToClosePerDocument.keys().toVector(); 0342 0343 DocumentManager* const documentManager = mProgram->documentManager(); 0344 if (documentManager->canClose(documentsWithoutViews)) { 0345 viewManager()->removeViews(views); 0346 documentManager->closeDocuments(documentsWithoutViews); 0347 } 0348 } 0349 0350 } 0351 0352 #include "moc_mainwindow.cpp"