File indexing completed on 2024-04-28 04:37:20

0001 /*
0002     SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org>
0003     SPDX-FileCopyrightText: 2007 Alexander Dymo <adymo@kdevelop.org>
0004     SPDX-FileCopyrightText: 2015 Kevin Funk <kfunk@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "partcontroller.h"
0010 
0011 #include <QAction>
0012 #include <QMimeDatabase>
0013 #include <QMimeType>
0014 
0015 #include <KActionCollection>
0016 #include <KToggleAction>
0017 #include <KLocalizedString>
0018 
0019 #include <KParts/Part>
0020 #include <KParts/PartLoader>
0021 
0022 #include <KTextEditor/View>
0023 #include <KTextEditor/Editor>
0024 #include <KTextEditor/Document>
0025 
0026 #include "core.h"
0027 #include "textdocument.h"
0028 #include "debug.h"
0029 #include "uicontroller.h"
0030 #include "mainwindow.h"
0031 #include <interfaces/isession.h>
0032 #include <interfaces/iuicontroller.h>
0033 #include <interfaces/idocumentcontroller.h>
0034 #include <sublime/area.h>
0035 
0036 namespace KDevelop
0037 {
0038 namespace {
0039 QString mimeTypeForUrl(const QUrl& url)
0040 {
0041     Q_ASSERT(url.isValid());
0042     Q_ASSERT(!url.isEmpty());
0043     return QMimeDatabase().mimeTypeForUrl(url).name();
0044 }
0045 }
0046 
0047 class PartControllerPrivate
0048 {
0049 public:
0050     explicit PartControllerPrivate(Core* core)
0051         : m_core(core)
0052     {}
0053 
0054     bool m_showTextEditorStatusBar = false;
0055     QString m_editor;
0056     QStringList m_textTypes;
0057 
0058     Core* const m_core;
0059 };
0060 
0061 PartController::PartController(Core *core, QWidget *toplevel)
0062     : IPartController(toplevel)
0063     , d_ptr(new PartControllerPrivate(core))
0064 
0065 {
0066     setObjectName(QStringLiteral("PartController"));
0067 
0068     //Cache this as it is too expensive when creating parts
0069     //     KConfig * config = Config::standard();
0070     //     config->setGroup( "General" );
0071     //
0072     //     d->m_textTypes = config->readEntry( "TextTypes", QStringList() );
0073     //
0074     //     config ->setGroup( "Editor" );
0075     //     d->m_editor = config->readPathEntry( "EmbeddedKTextEditor", QString() );
0076 
0077     // required early because some actions are checkable and need to be initialized
0078     loadSettings(false);
0079 
0080     if (!(Core::self()->setupFlags() & Core::NoUi))
0081         setupActions();
0082 }
0083 
0084 PartController::~PartController() = default;
0085 
0086 bool PartController::showTextEditorStatusBar() const
0087 {
0088     Q_D(const PartController);
0089 
0090     return d->m_showTextEditorStatusBar;
0091 }
0092 
0093 void PartController::setShowTextEditorStatusBar(bool show)
0094 {
0095     Q_D(PartController);
0096 
0097     if (d->m_showTextEditorStatusBar == show)
0098         return;
0099 
0100     d->m_showTextEditorStatusBar = show;
0101 
0102     // update
0103     const auto areas = Core::self()->uiControllerInternal()->allAreas();
0104     for (Sublime::Area* area : areas) {
0105         const auto views = area->views();
0106         for (Sublime::View* view : views) {
0107             if (!view->hasWidget())
0108                 continue;
0109 
0110             auto textView = qobject_cast<KTextEditor::View*>(view->widget());
0111             if (textView) {
0112                 textView->setStatusBarEnabled(show);
0113             }
0114         }
0115     }
0116 
0117     // also notify active view that it should update the "view status"
0118     auto* textView = qobject_cast<TextView*>(Core::self()->uiControllerInternal()->activeSublimeWindow()->activeView());
0119     if (textView) {
0120         emit textView->statusChanged(textView);
0121     }
0122 }
0123 
0124 //MOVE BACK TO DOCUMENTCONTROLLER OR MULTIBUFFER EVENTUALLY
0125 bool PartController::isTextType(const QMimeType& mimeType)
0126 {
0127     Q_D(PartController);
0128 
0129     bool isTextType = false;
0130     if (d->m_textTypes.contains(mimeType.name()))
0131     {
0132         isTextType = true;
0133     }
0134 
0135     // is this regular text - open in editor
0136     return ( isTextType
0137              || mimeType.inherits(QStringLiteral("text/plain"))
0138              || mimeType.inherits(QStringLiteral("text/html"))
0139              || mimeType.inherits(QStringLiteral("application/x-zerosize")));
0140 }
0141 
0142 KTextEditor::Editor* PartController::editorPart() const
0143 {
0144     return KTextEditor::Editor::instance();
0145 }
0146 
0147 KTextEditor::Document* PartController::createTextPart()
0148 {
0149     return editorPart()->createDocument(this);
0150 }
0151 
0152 bool PartController::canCreatePart(const QUrl& url)
0153 {
0154     if (!url.isValid()) {
0155         return false;
0156     }
0157 
0158     return !KParts::PartLoader::partsForMimeType(mimeTypeForUrl(url)).isEmpty();
0159 }
0160 
0161 KParts::Part* PartController::createPart( const QUrl & url, const QString& preferredPart )
0162 {
0163     if (!url.isValid()) {
0164         return nullptr;
0165     }
0166 
0167     qCDebug(SHELL) << "creating part with url" << url << "and pref part:" << preferredPart;
0168     KParts::Part* part = createPart(mimeTypeForUrl(url), preferredPart);
0169     if (!part) {
0170         return nullptr;
0171     }
0172 
0173     // only ReadOnlyParts are supported by PartController
0174     static_cast<KParts::ReadOnlyPart*>(part)->openUrl(url);
0175 
0176     // restrict keyboard shortcuts to the KParts view
0177     const auto actions = part->actionCollection()->actions();
0178     for (auto* action : actions) {
0179         if (action->shortcutContext() != Qt::WidgetShortcut) {
0180             action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
0181         }
0182     }
0183 
0184     return part;
0185 }
0186 
0187 void PartController::loadSettings( bool projectIsLoaded )
0188 {
0189     Q_D(PartController);
0190 
0191     Q_UNUSED( projectIsLoaded );
0192 
0193     KConfigGroup cg(KSharedConfig::openConfig(), "UiSettings");
0194     d->m_showTextEditorStatusBar = cg.readEntry("ShowTextEditorStatusBar", false);
0195 }
0196 
0197 void PartController::saveSettings( bool projectIsLoaded )
0198 {
0199     Q_D(PartController);
0200 
0201     Q_UNUSED( projectIsLoaded );
0202 
0203     KConfigGroup cg(KSharedConfig::openConfig(), "UiSettings");
0204     cg.writeEntry("ShowTextEditorStatusBar", d->m_showTextEditorStatusBar);
0205 }
0206 
0207 void PartController::initialize()
0208 {
0209 }
0210 
0211 void PartController::cleanup()
0212 {
0213     saveSettings(false);
0214 }
0215 
0216 void PartController::setupActions()
0217 {
0218     Q_D(PartController);
0219 
0220     KActionCollection* actionCollection =
0221         d->m_core->uiControllerInternal()->defaultMainWindow()->actionCollection();
0222 
0223     QAction* action;
0224 
0225     action = KStandardAction::showStatusbar(this, SLOT(setShowTextEditorStatusBar(bool)), actionCollection);
0226     action->setWhatsThis(i18nc("@info:whatsthis", "Use this command to show or hide the view's statusbar."));
0227     action->setChecked(showTextEditorStatusBar());
0228 }
0229 
0230 }
0231 
0232 #include "moc_partcontroller.cpp"