File indexing completed on 2024-04-28 04:37:20
0001 /* 0002 SPDX-FileCopyrightText: 2007 Alexander Dymo <adymo@kdevelop.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "partdocument.h" 0008 0009 #include <QMimeDatabase> 0010 0011 #include <KMessageBox> 0012 #include <KMessageBox_KDevCompat> 0013 #include <KLocalizedString> 0014 #include <KTextEditor/Cursor> 0015 0016 #include <sublime/area.h> 0017 #include <sublime/view.h> 0018 #include <sublime/mainwindow.h> 0019 0020 #include "core.h" 0021 #include "uicontroller.h" 0022 #include "partcontroller.h" 0023 0024 namespace KDevelop { 0025 0026 class PartDocumentPrivate { 0027 public: 0028 explicit PartDocumentPrivate(const QString& preferredPart) 0029 : preferredPart(preferredPart) 0030 {} 0031 0032 QMap<QWidget*, KParts::Part*> partForView; 0033 const QString preferredPart; 0034 }; 0035 0036 PartDocument::PartDocument(const QUrl& url, KDevelop::ICore* core, const QString& preferredPart) 0037 : Sublime::UrlDocument(core->uiController()->controller(), url) 0038 , KDevelop::IDocument(core) 0039 , d_ptr(new PartDocumentPrivate(preferredPart)) 0040 { 0041 } 0042 0043 PartDocument::~PartDocument() = default; 0044 0045 QWidget *PartDocument::createViewWidget(QWidget* /*parent*/) 0046 { 0047 Q_D(PartDocument); 0048 0049 KParts::Part *part = Core::self()->partControllerInternal()->createPart(url(), d->preferredPart); 0050 if( part ) 0051 { 0052 Core::self()->partController()->addPart(part); 0053 QWidget *w = part->widget(); 0054 d->partForView[w] = part; 0055 return w; 0056 } 0057 return nullptr; 0058 } 0059 0060 KParts::Part *PartDocument::partForView(QWidget *view) const 0061 { 0062 Q_D(const PartDocument); 0063 0064 return d->partForView[view]; 0065 } 0066 0067 0068 0069 //KDevelop::IDocument implementation 0070 0071 0072 QMimeType PartDocument::mimeType() const 0073 { 0074 return QMimeDatabase().mimeTypeForUrl(url()); 0075 } 0076 0077 KTextEditor::Document *PartDocument::textDocument() const 0078 { 0079 return nullptr; 0080 } 0081 0082 bool PartDocument::isActive() const 0083 { 0084 const auto activeView = Core::self()->uiControllerInternal()->activeSublimeWindow()->activeView(); 0085 if (!activeView) { 0086 return false; 0087 } 0088 0089 return activeView->document() == this; 0090 } 0091 0092 bool PartDocument::save(DocumentSaveMode /*mode*/) 0093 { 0094 //part document is read-only so do nothing here 0095 return true; 0096 } 0097 0098 bool PartDocument::askForCloseFeedback() 0099 { 0100 int code = -1; 0101 if (state() == IDocument::Modified) { 0102 code = KMessageBox::warningTwoActionsCancel( 0103 Core::self()->uiController()->activeMainWindow(), 0104 i18n("The document \"%1\" has unsaved changes. Would you like to save them?", url().toLocalFile()), 0105 i18nc("@title:window", "Close Document"), KStandardGuiItem::save(), KStandardGuiItem::discard()); 0106 0107 /// @todo Is this behavior right? 0108 } else if (state() == IDocument::DirtyAndModified) { 0109 code = KMessageBox::warningTwoActionsCancel( 0110 Core::self()->uiController()->activeMainWindow(), 0111 i18n("The document \"%1\" has unsaved changes and was modified by an external process.\n" 0112 "Do you want to overwrite the external changes?", 0113 url().toLocalFile()), 0114 i18nc("@title:window", "Close Document"), 0115 KGuiItem(i18nc("@action:button", "Overwrite External Changes"), QStringLiteral("document-save")), 0116 KStandardGuiItem::discard()); 0117 } 0118 0119 if (code >= 0) { 0120 if (code == KMessageBox::PrimaryAction) { 0121 if (!save(Default)) 0122 return false; 0123 0124 } else if (code == KMessageBox::Cancel) { 0125 return false; 0126 } 0127 } 0128 0129 return true; 0130 } 0131 0132 bool PartDocument::close(DocumentSaveMode mode) 0133 { 0134 Q_D(PartDocument); 0135 0136 if (!(mode & Discard)) { 0137 if (mode & Silent) { 0138 if (!save(mode)) 0139 return false; 0140 } else { 0141 if( !askForCloseFeedback() ) 0142 return false; 0143 } 0144 } 0145 0146 //close all views and then delete ourself 0147 closeViews(); 0148 0149 for (KParts::Part* part : qAsConst(d->partForView)) { 0150 part->deleteLater(); 0151 } 0152 0153 // The document will be deleted automatically if there are no views left 0154 0155 return true; 0156 } 0157 0158 bool PartDocument::closeDocument(bool silent) { 0159 return close(silent ? Silent : Default); 0160 } 0161 0162 void PartDocument::reload() 0163 { 0164 //part document is read-only so do nothing here 0165 } 0166 0167 IDocument::DocumentState PartDocument::state() const 0168 { 0169 return Clean; 0170 } 0171 0172 void PartDocument::activate(Sublime::View *activeView, KParts::MainWindow *mainWindow) 0173 { 0174 Q_UNUSED(mainWindow); 0175 KParts::Part *part = partForView(activeView->widget()); 0176 if (Core::self()->partController()->activePart() != part) 0177 Core::self()->partController()->setActivePart(part); 0178 notifyActivated(); 0179 } 0180 0181 KTextEditor::Cursor KDevelop::PartDocument::cursorPosition() const 0182 { 0183 return KTextEditor::Cursor::invalid(); 0184 } 0185 0186 void PartDocument::setCursorPosition(const KTextEditor::Cursor &cursor) 0187 { 0188 //do nothing here 0189 Q_UNUSED(cursor); 0190 } 0191 0192 void PartDocument::setTextSelection(const KTextEditor::Range &range) 0193 { 0194 Q_UNUSED(range); 0195 } 0196 0197 QUrl PartDocument::url() const 0198 { 0199 return Sublime::UrlDocument::url(); 0200 } 0201 0202 void PartDocument::setUrl(const QUrl& newUrl) 0203 { 0204 const auto previousUrl = Sublime::UrlDocument::url(); 0205 Sublime::UrlDocument::setUrl(newUrl); 0206 if(!prettyName().isEmpty()) 0207 setTitle(prettyName()); 0208 notifyUrlChanged(previousUrl); 0209 } 0210 0211 void PartDocument::setPrettyName(const QString& name) 0212 { 0213 KDevelop::IDocument::setPrettyName(name); 0214 // Re-set the url, to trigger the whole chain 0215 if(!name.isEmpty()) 0216 setTitle(name); 0217 else 0218 setTitle(url().fileName()); 0219 } 0220 0221 QMap<QWidget*, KParts::Part*> PartDocument::partForView() const 0222 { 0223 Q_D(const PartDocument); 0224 0225 return d->partForView; 0226 } 0227 0228 void PartDocument::addPartForView(QWidget* w, KParts::Part* p) 0229 { 0230 Q_D(PartDocument); 0231 0232 d->partForView[w]=p; 0233 } 0234 0235 } 0236 0237 #include "moc_partdocument.cpp"