File indexing completed on 2024-04-28 04:39:03
0001 /* 0002 SPDX-FileCopyrightText: 2010-2011 Friedrich W. H. Kossebau <kossebau@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "oktetadocument.h" 0008 0009 // plugin 0010 #include "oktetaplugin.h" 0011 #include "oktetaview.h" 0012 // Okteta 0013 #include <Kasten/Okteta/ByteArrayViewProfileManager> 0014 #include <Kasten/Okteta/ByteArrayViewProfileSynchronizer> 0015 #include <Kasten/Okteta/ByteArrayRawFileSynchronizerFactory> 0016 #include <Kasten/Okteta/ByteArrayDocument> 0017 // Kasten 0018 #include <Kasten/JobManager> 0019 #include <Kasten/AbstractLoadJob> 0020 #include <Kasten/AbstractSyncToRemoteJob> 0021 #include <Kasten/AbstractSyncFromRemoteJob> 0022 #include <Kasten/AbstractModelSynchronizer> 0023 // KDevelop 0024 #include <shell/core.h> 0025 #include <shell/uicontroller.h> 0026 #include <interfaces/icore.h> 0027 #include <interfaces/iuicontroller.h> 0028 // Sublime 0029 #include <sublime/mainwindow.h> 0030 #include <sublime/view.h> 0031 #include <sublime/area.h> 0032 #include <sublime/controller.h> 0033 // KF 0034 #include <KMessageBox> 0035 #include <KMessageBox_KDevCompat> 0036 #include <KLocalizedString> 0037 #include <KTextEditor/Cursor> 0038 // Qt 0039 #include <QApplication> 0040 #include <QMimeDatabase> 0041 0042 0043 namespace KDevelop 0044 { 0045 0046 OktetaDocument::OktetaDocument( const QUrl &url , ICore* core ) 0047 : Sublime::UrlDocument( core->uiController()->controller(), url ) 0048 , IDocument( core ) 0049 , mPlugin( nullptr ) 0050 , mByteArrayDocument( nullptr ) 0051 { 0052 } 0053 0054 QUrl OktetaDocument::url() const { return Sublime::UrlDocument::url(); } 0055 0056 // TODO: use fromContentAndUrl(ByteArrayIODevice) if document loaded 0057 QMimeType OktetaDocument::mimeType() const { return QMimeDatabase().mimeTypeForUrl( url() ); } 0058 0059 KParts::Part* OktetaDocument::partForView( QWidget* ) const { return nullptr; } 0060 KTextEditor::Document* OktetaDocument::textDocument() const { return nullptr; } 0061 KTextEditor::Cursor OktetaDocument::cursorPosition() const { return KTextEditor::Cursor(); } 0062 0063 IDocument::DocumentState OktetaDocument::state() const 0064 { 0065 return mByteArrayDocument ? 0066 ( mByteArrayDocument->synchronizer()->localSyncState() == Kasten::LocalHasChanges ? 0067 IDocument::Modified : 0068 IDocument::Clean ) : 0069 IDocument::Clean; 0070 } 0071 0072 0073 bool OktetaDocument::save( IDocument::DocumentSaveMode mode ) 0074 { 0075 if( mode & Discard ) 0076 return true; 0077 0078 if( state() == IDocument::Clean ) 0079 return false; 0080 0081 Kasten::AbstractModelSynchronizer* synchronizer = mByteArrayDocument->synchronizer(); 0082 0083 Kasten::AbstractSyncToRemoteJob* syncJob = synchronizer->startSyncToRemote(); 0084 const bool syncSucceeded = Kasten::JobManager::executeJob( syncJob ); 0085 0086 if( syncSucceeded ) 0087 { 0088 notifySaved(); 0089 notifyStateChanged(); 0090 } 0091 0092 return syncSucceeded; 0093 } 0094 0095 0096 void OktetaDocument::reload() 0097 { 0098 Kasten::AbstractModelSynchronizer* synchronizer = mByteArrayDocument->synchronizer(); 0099 0100 Kasten::AbstractSyncFromRemoteJob* syncJob = synchronizer->startSyncFromRemote(); 0101 const bool syncSucceeded = Kasten::JobManager::executeJob( syncJob ); 0102 0103 if( syncSucceeded ) 0104 notifyStateChanged(); 0105 } 0106 0107 bool OktetaDocument::close( IDocument::DocumentSaveMode mode ) 0108 { 0109 bool isCanceled = false; 0110 if( !(mode & Discard) ) 0111 { 0112 if (mode & Silent) 0113 { 0114 if (!save(mode)) 0115 isCanceled = true; 0116 0117 } 0118 else 0119 { 0120 if( state() == IDocument::Modified ) 0121 { 0122 // TODO: use Kasten::*Manager 0123 int code = KMessageBox::warningTwoActionsCancel( 0124 qApp->activeWindow(), 0125 i18n("The document \"%1\" has unsaved changes. Would you like to save them?", url().toLocalFile()), 0126 i18nc("@title:window", "Close Document"), KStandardGuiItem::save(), KStandardGuiItem::cancel()); 0127 0128 if (code == KMessageBox::PrimaryAction) { 0129 if (!save(mode)) 0130 isCanceled = true; 0131 0132 } else if (code == KMessageBox::Cancel) 0133 isCanceled = true; 0134 0135 } 0136 else if( state() == IDocument::DirtyAndModified ) 0137 { 0138 if( !save(mode) ) 0139 isCanceled = true; 0140 } 0141 } 0142 } 0143 0144 if( isCanceled ) 0145 return false; 0146 0147 //close all views and then delete ourself 0148 ///@todo test this 0149 const QList<Sublime::Area*>& allAreas = 0150 ICore::self()->uiController()->controller()->allAreas(); 0151 for (Sublime::Area* area : allAreas ) { 0152 const QList<Sublime::View*> areaViews = area->views(); 0153 for (Sublime::View* view : areaViews) { 0154 if (views().contains(view)) 0155 { 0156 area->removeView(view); 0157 delete view; 0158 } 0159 } 0160 } 0161 0162 // The document is deleted automatically when there are no views left 0163 0164 return true; 0165 } 0166 0167 bool OktetaDocument::isActive() const 0168 { 0169 return Core::self()->uiControllerInternal()->activeSublimeWindow()->activeView()->document() == this; 0170 } 0171 0172 0173 void OktetaDocument::setCursorPosition( const KTextEditor::Cursor& ) {} 0174 void OktetaDocument::setTextSelection( const KTextEditor::Range& ) {} 0175 0176 void OktetaDocument::activate( Sublime::View* /* view */, KParts::MainWindow* /* mainWindow */ ) 0177 { 0178 notifyActivated(); 0179 } 0180 0181 void OktetaDocument::setPlugin( OktetaPlugin* plugin ) 0182 { 0183 mPlugin = plugin; 0184 } 0185 0186 Sublime::View* OktetaDocument::newView( Sublime::Document* /* document */ ) 0187 { 0188 if( mByteArrayDocument == nullptr ) 0189 { 0190 auto* synchronizerFactory = 0191 new Kasten::ByteArrayRawFileSynchronizerFactory(); 0192 Kasten::AbstractModelSynchronizer* synchronizer = synchronizerFactory->createSynchronizer(); 0193 0194 Kasten::AbstractLoadJob* loadJob = synchronizer->startLoad( url() ); 0195 connect( loadJob, &Kasten::AbstractLoadJob::documentLoaded, 0196 this, &OktetaDocument::onByteArrayDocumentLoaded ); 0197 Kasten::JobManager::executeJob( loadJob ); 0198 0199 delete synchronizerFactory; 0200 } 0201 0202 Kasten::ByteArrayViewProfileManager* const viewProfileManager = mPlugin->viewProfileManager(); 0203 auto* viewProfileSynchronizer = 0204 new Kasten::ByteArrayViewProfileSynchronizer( viewProfileManager ); 0205 viewProfileSynchronizer->setViewProfileId( viewProfileManager->defaultViewProfileId() ); 0206 return new OktetaView( this, viewProfileSynchronizer ); 0207 } 0208 0209 bool OktetaDocument::closeDocument(bool silent) 0210 { 0211 return close(silent ? Silent : Default); 0212 } 0213 0214 void OktetaDocument::onByteArrayDocumentLoaded( Kasten::AbstractDocument* document ) 0215 { 0216 if( document ) 0217 { 0218 mByteArrayDocument = static_cast<Kasten::ByteArrayDocument*>( document ); 0219 connect( mByteArrayDocument->synchronizer(), &Kasten::AbstractModelSynchronizer::localSyncStateChanged, 0220 this, &OktetaDocument::onByteArrayDocumentChanged ); 0221 } 0222 } 0223 0224 void OktetaDocument::onByteArrayDocumentChanged() 0225 { 0226 notifyStateChanged(); 0227 } 0228 0229 OktetaDocument::~OktetaDocument() 0230 { 0231 delete mByteArrayDocument; 0232 } 0233 0234 } 0235 0236 #include "moc_oktetadocument.cpp"