File indexing completed on 2024-04-21 05:54:01
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 #include <Kasten/UiColorSchemeControllerFactory> 0085 #include <Kasten/QuitControllerFactory> 0086 // Kasten gui 0087 #include <Kasten/MultiDocumentStrategy> 0088 #include <Kasten/ModelCodecViewManager> 0089 #include <Kasten/ViewManager> 0090 #include <Kasten/MultiViewAreas> 0091 #include <Kasten/StatusBar> 0092 // Kasten core 0093 #include <Kasten/ModelCodecManager> 0094 #include <Kasten/DocumentCreateManager> 0095 #include <Kasten/DocumentSyncManager> 0096 #include <Kasten/DocumentManager> 0097 // KF 0098 #include <KConfigGroup> 0099 #include <KSharedConfig> 0100 // Qt 0101 #include <QUrl> 0102 #include <QMimeData> 0103 0104 namespace Kasten { 0105 0106 static constexpr char LoadedUrlsKey[] = "LoadedUrls"; 0107 0108 OktetaMainWindow::OktetaMainWindow(OktetaProgram* program) 0109 : ShellWindow(program->viewManager()) 0110 , mProgram(program) 0111 { 0112 setObjectName(QStringLiteral("Shell")); 0113 0114 // there is only one mainwindow, so have this show the document if requested 0115 connect(mProgram->documentManager(), &DocumentManager::focusRequested, 0116 this, &OktetaMainWindow::showDocument); 0117 connect(viewArea(), &MultiViewAreas::dataOffered, 0118 this, &OktetaMainWindow::onDataOffered); 0119 connect(viewArea(), &MultiViewAreas::dataDropped, 0120 this, &OktetaMainWindow::onDataDropped); 0121 connect(viewArea(), &MultiViewAreas::newDocumentRequested, 0122 this, &OktetaMainWindow::onNewDocumentRequested); 0123 connect(viewArea(), &AbstractGroupedViews::closeRequest, 0124 this, &OktetaMainWindow::onCloseRequest); 0125 0126 // Using State value as generated with Qt 5.15.11-KDE 0127 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 11) 0128 // XXX: Workaround for Qt 4.4's lacking of proper handling of the initial layout of dock widgets 0129 // This state is taken from an oktetarc where the docker constellation was configured by hand. 0130 // Setting this state if none is present seems to work, but there's 0131 // still the versioning problem to be accounted for. 0132 // Hack borrowed from trunk/koffice/krita/ui/kis_view2.cpp: 0133 const QString mainWindowState = QStringLiteral( 0134 "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=="); 0135 const char mainWindowStateKey[] = "State"; 0136 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("MainWindow")); 0137 if (!group.hasKey(mainWindowStateKey)) { 0138 group.writeEntry(mainWindowStateKey, mainWindowState); 0139 } 0140 #endif 0141 0142 setStatusBar(new Kasten::StatusBar(this)); 0143 0144 setupControllers(); 0145 setupGUI(); 0146 0147 // all controllers which use plugActionList have to do so after(!) setupGUI() or their entries will be removed 0148 // TODO: why is this so? 0149 // tmp 0150 addXmlGuiControllerFromFactory(ToolListMenuControllerFactory(this)); 0151 addXmlGuiControllerFromFactory(ViewListMenuControllerFactory(viewManager(), viewArea())); 0152 } 0153 0154 OktetaMainWindow::~OktetaMainWindow() = default; 0155 0156 void OktetaMainWindow::setupControllers() 0157 { 0158 MultiDocumentStrategy* const documentStrategy = mProgram->documentStrategy(); 0159 ViewManager* const viewManager = this->viewManager(); 0160 MultiViewAreas* const viewArea = this->viewArea(); 0161 ModelCodecViewManager* const codecViewManager = viewManager->codecViewManager(); 0162 DocumentManager* const documentManager = mProgram->documentManager(); 0163 ModelCodecManager* const codecManager = documentManager->codecManager(); 0164 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0165 // tmp 0166 ByteArrayViewProfileManager* const byteArrayViewProfileManager = mProgram->byteArrayViewProfileManager(); 0167 0168 // general, part of Kasten 0169 addXmlGuiControllerFromFactory(CreatorControllerFactory(codecManager, documentStrategy)); 0170 addXmlGuiControllerFromFactory(LoaderControllerFactory(documentStrategy)); 0171 addXmlGuiControllerFromFactory(SetRemoteControllerFactory(syncManager)); 0172 addXmlGuiControllerFromFactory(SynchronizeControllerFactory(syncManager)); 0173 addXmlGuiControllerFromFactory(ExportControllerFactory(codecViewManager, codecManager)); 0174 addXmlGuiControllerFromFactory(CloseControllerFactory(documentStrategy)); 0175 addXmlGuiControllerFromFactory(VersionControllerFactory()); 0176 addXmlGuiControllerFromFactory(ReadOnlyControllerFactory()); 0177 addXmlGuiControllerFromFactory(ViewAreaContextMenuControllerFactory(viewArea, syncManager)); 0178 addXmlGuiControllerFromFactory(SwitchViewControllerFactory(viewArea)); 0179 addXmlGuiControllerFromFactory(ViewAreaSplitControllerFactory(viewManager, viewArea)); 0180 addXmlGuiControllerFromFactory(FullScreenControllerFactory(this)); 0181 addXmlGuiControllerFromFactory(UiColorSchemeControllerFactory(this)); 0182 addXmlGuiControllerFromFactory(QuitControllerFactory(this)); 0183 0184 addXmlGuiControllerFromFactory(ZoomControllerFactory()); 0185 addXmlGuiControllerFromFactory(SelectControllerFactory()); 0186 addXmlGuiControllerFromFactory(ClipboardControllerFactory()); 0187 addXmlGuiControllerFromFactory(InsertControllerFactory(codecViewManager, codecManager)); 0188 addXmlGuiControllerFromFactory(CopyAsControllerFactory(codecViewManager, codecManager)); 0189 0190 addToolFromFactory(FileSystemBrowserToolViewFactory(), FileSystemBrowserToolFactory(syncManager)); 0191 addToolFromFactory(DocumentsToolViewFactory(), DocumentsToolFactory(documentManager)); 0192 addToolFromFactory(TerminalToolViewFactory(), TerminalToolFactory(syncManager)); 0193 #ifndef NDEBUG 0194 addToolFromFactory(VersionViewToolViewFactory(), VersionViewToolFactory()); 0195 #endif 0196 0197 // Okteta specific 0198 // addXmlGuiControllerFromFactory(OverwriteOnlyControllerFactory() ); 0199 addXmlGuiControllerFromFactory(OverwriteModeControllerFactory()); 0200 addXmlGuiControllerFromFactory(SearchControllerFactory(this)); 0201 addXmlGuiControllerFromFactory(ReplaceControllerFactory(this)); 0202 addXmlGuiControllerFromFactory(GotoOffsetControllerFactory(viewArea)); 0203 addXmlGuiControllerFromFactory(SelectRangeControllerFactory(viewArea)); 0204 addXmlGuiControllerFromFactory(BookmarksControllerFactory()); 0205 addXmlGuiControllerFromFactory(PrintControllerFactory()); 0206 addXmlGuiControllerFromFactory(ViewConfigControllerFactory()); 0207 addXmlGuiControllerFromFactory(ViewModeControllerFactory()); 0208 addXmlGuiControllerFromFactory(ViewContextMenuControllerFactory()); 0209 addXmlGuiControllerFromFactory(ViewProfileControllerFactory(byteArrayViewProfileManager, this)); 0210 addXmlGuiControllerFromFactory(ViewProfilesManageControllerFactory(byteArrayViewProfileManager, this)); 0211 0212 auto* const bottomBar = static_cast<Kasten::StatusBar*>(statusBar()); 0213 addXmlGuiControllerFromFactory(ViewStatusControllerFactory(bottomBar)); 0214 addXmlGuiControllerFromFactory(ModifiedBarControllerFactory(bottomBar)); 0215 addXmlGuiControllerFromFactory(ReadOnlyBarControllerFactory(bottomBar)); 0216 addXmlGuiControllerFromFactory(ZoomBarControllerFactory(bottomBar)); 0217 0218 addToolFromFactory(DocumentInfoToolViewFactory(), DocumentInfoToolFactory(syncManager)); 0219 addToolFromFactory(ChecksumToolViewFactory(), ChecksumToolFactory()); 0220 addToolFromFactory(FilterToolViewFactory(), FilterToolFactory()); 0221 addToolFromFactory(CharsetConversionToolViewFactory(), CharsetConversionToolFactory()); 0222 addToolFromFactory(StringsExtractToolViewFactory(), StringsExtractToolFactory()); 0223 addToolFromFactory(ByteTableToolViewFactory(), ByteTableToolFactory()); 0224 addToolFromFactory(InfoToolViewFactory(), InfoToolFactory()); 0225 addToolFromFactory(PodDecoderToolViewFactory(), PodDecoderToolFactory()); 0226 addToolFromFactory(StructuresToolViewFactory(), StructuresToolFactory()); 0227 addToolFromFactory(BookmarksToolViewFactory(), BookmarksToolFactory()); 0228 } 0229 0230 void OktetaMainWindow::addToolFromFactory(const AbstractToolViewFactory& toolViewFactory, 0231 const AbstractToolFactory& toolFactory) 0232 { 0233 AbstractTool* tool = toolFactory.create(); 0234 AbstractToolView* toolView = toolViewFactory.create(tool); 0235 0236 addTool(toolView); 0237 } 0238 0239 void OktetaMainWindow::addXmlGuiControllerFromFactory(const AbstractXmlGuiControllerFactory& factory) 0240 { 0241 AbstractXmlGuiController* controller = factory.create(this); 0242 addXmlGuiController(controller); 0243 } 0244 0245 0246 bool OktetaMainWindow::queryClose() 0247 { 0248 // TODO: query the document manager or query the view manager? 0249 return mProgram->documentManager()->canCloseAll(); 0250 } 0251 0252 void OktetaMainWindow::saveProperties(KConfigGroup& configGroup) 0253 { 0254 DocumentManager* const documentManager = mProgram->documentManager(); 0255 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0256 const QVector<AbstractDocument*> documents = documentManager->documents(); 0257 0258 QStringList urls; 0259 urls.reserve(documents.size()); 0260 for (AbstractDocument* document : documents) { 0261 urls.append(syncManager->urlOf(document).url()); 0262 } 0263 0264 configGroup.writePathEntry(LoadedUrlsKey, urls); 0265 } 0266 0267 void OktetaMainWindow::readProperties(const KConfigGroup& configGroup) 0268 { 0269 const QStringList urls = configGroup.readPathEntry(LoadedUrlsKey, QStringList()); 0270 0271 DocumentManager* const documentManager = mProgram->documentManager(); 0272 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0273 DocumentCreateManager* const createManager = documentManager->createManager(); 0274 for (const QString& url : urls) { 0275 if (url.isEmpty()) { 0276 createManager->createNew(); 0277 } else { 0278 syncManager->load(QUrl(url, QUrl::TolerantMode)); 0279 } 0280 // TODO: set view to offset 0281 // if( offset != -1 ) 0282 } 0283 } 0284 0285 void OktetaMainWindow::onDataOffered(const QMimeData* mimeData, bool& accept) 0286 { 0287 accept = mimeData->hasUrls() 0288 || mProgram->documentManager()->createManager()->canCreateNewFromData(mimeData); 0289 } 0290 0291 void OktetaMainWindow::onDataDropped(const QMimeData* mimeData) 0292 { 0293 const QList<QUrl> urls = mimeData->urls(); 0294 0295 DocumentManager* const documentManager = mProgram->documentManager(); 0296 if (!urls.isEmpty()) { 0297 DocumentSyncManager* const syncManager = documentManager->syncManager(); 0298 0299 for (const QUrl& url : urls) { 0300 syncManager->load(url); 0301 } 0302 } else { 0303 documentManager->createManager()->createNewFromData(mimeData, true); 0304 } 0305 } 0306 0307 void OktetaMainWindow::onNewDocumentRequested() 0308 { 0309 mProgram->documentManager()->createManager()->createNew(); 0310 } 0311 0312 void OktetaMainWindow::onCloseRequest(const QVector<Kasten::AbstractView*>& views) 0313 { 0314 // group views per document 0315 QHash<AbstractDocument*, QVector<AbstractView*>> viewsToClosePerDocument; 0316 for (AbstractView* view : views) { 0317 auto* document = view->findBaseModel<AbstractDocument*>(); 0318 viewsToClosePerDocument[document].append(view); 0319 } 0320 0321 // find documents which lose all views 0322 const QVector<AbstractView*> allViews = viewManager()->views(); 0323 for (AbstractView* view : allViews) { 0324 auto* document = view->findBaseModel<AbstractDocument*>(); 0325 QHash<AbstractDocument*, QVector<AbstractView*>>::Iterator it = 0326 viewsToClosePerDocument.find(document); 0327 0328 if (it != viewsToClosePerDocument.end()) { 0329 const QVector<AbstractView*>& viewsOfDocument = it.value(); 0330 const bool isAnotherView = !viewsOfDocument.contains(view); 0331 if (isAnotherView) { 0332 viewsToClosePerDocument.erase(it); 0333 } 0334 } 0335 } 0336 0337 const QVector<AbstractDocument*> documentsWithoutViews = viewsToClosePerDocument.keys().toVector(); 0338 0339 DocumentManager* const documentManager = mProgram->documentManager(); 0340 if (documentManager->canClose(documentsWithoutViews)) { 0341 viewManager()->removeViews(views); 0342 documentManager->closeDocuments(documentsWithoutViews); 0343 } 0344 } 0345 0346 } 0347 0348 #include "moc_mainwindow.cpp"