File indexing completed on 2024-04-28 04:38:55
0001 /* 0002 SPDX-FileCopyrightText: 2003, 2006 Adam Treat <treat@kde.org> 0003 SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kdevkonsoleview.h" 0009 #include "debug.h" 0010 0011 #include <QFrame> 0012 #include <QIcon> 0013 #include <QKeyEvent> 0014 #include <QUuid> 0015 #include <QVBoxLayout> 0016 0017 #include <kde_terminal_interface.h> 0018 #include <KLocalizedString> 0019 #include <KPluginFactory> 0020 #include <KParts/ReadOnlyPart> 0021 0022 #include <interfaces/icore.h> 0023 #include <interfaces/isession.h> 0024 #include <interfaces/idocumentcontroller.h> 0025 #include <interfaces/iprojectcontroller.h> 0026 #include <interfaces/iproject.h> 0027 #include <util/path.h> 0028 0029 #include "kdevkonsoleviewplugin.h" 0030 0031 class KDevKonsoleViewPrivate 0032 { 0033 public: 0034 KDevKonsoleViewPlugin* mplugin; 0035 KDevKonsoleView* m_view; 0036 KParts::ReadOnlyPart *konsolepart; 0037 QVBoxLayout *m_vbox; 0038 // TODO: remove this once we can depend on a Qt version that includes https://codereview.qt-project.org/#/c/83800/ 0039 QMetaObject::Connection m_partDestroyedConnection; 0040 0041 void _k_slotTerminalClosed(); 0042 0043 void init( KPluginFactory* factory ) 0044 { 0045 Q_ASSERT( konsolepart == nullptr ); 0046 0047 Q_ASSERT( factory != nullptr ); 0048 0049 if ( ( konsolepart = factory->create<KParts::ReadOnlyPart>( m_view ) ) ) 0050 { 0051 QObject::disconnect(m_partDestroyedConnection); 0052 m_partDestroyedConnection = QObject::connect(konsolepart, &KParts::ReadOnlyPart::destroyed, 0053 m_view, [&] { _k_slotTerminalClosed(); }); 0054 0055 konsolepart->widget() ->setFocusPolicy( Qt::WheelFocus ); 0056 konsolepart->widget() ->setFocus(); 0057 konsolepart->widget() ->installEventFilter( m_view ); 0058 0059 if ( auto * frame = qobject_cast<QFrame*>( konsolepart->widget() ) ) 0060 frame->setFrameStyle( QFrame::Panel | QFrame::Sunken ); 0061 0062 m_vbox->addWidget( konsolepart->widget() ); 0063 m_view->setFocusProxy( konsolepart->widget() ); 0064 konsolepart->widget() ->show(); 0065 0066 TerminalInterface* interface = qobject_cast<TerminalInterface*>(konsolepart); 0067 Q_ASSERT(interface); 0068 0069 QString dir; 0070 if (KDevelop::IDocument* activeDocument = KDevelop::ICore::self()->documentController()->activeDocument()) 0071 { 0072 KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->findProjectForUrl(activeDocument->url()); 0073 if (project && project->path().isLocalFile()) 0074 dir = project->path().path(); 0075 else if (activeDocument->url().isLocalFile()) 0076 dir = activeDocument->url().adjusted(QUrl::RemoveFilename).path(QUrl::FullyDecoded); 0077 } 0078 interface->showShellInDir( dir ); 0079 0080 interface->sendInput(QLatin1String(" kdevelop! -s \"") + KDevelop::ICore::self()->activeSession()->id().toString() + QLatin1String("\"\n")); 0081 0082 }else 0083 { 0084 qCDebug(PLUGIN_KONSOLE) << "Couldn't create KParts::ReadOnlyPart from konsole factory!"; 0085 } 0086 } 0087 0088 ~KDevKonsoleViewPrivate() 0089 { 0090 QObject::disconnect(m_partDestroyedConnection); 0091 } 0092 }; 0093 0094 void KDevKonsoleViewPrivate::_k_slotTerminalClosed() 0095 { 0096 konsolepart = nullptr; 0097 init( mplugin->konsoleFactory() ); 0098 } 0099 0100 KDevKonsoleView::KDevKonsoleView( KDevKonsoleViewPlugin *plugin, QWidget* parent ) 0101 : QWidget( parent ), d(new KDevKonsoleViewPrivate) 0102 0103 { 0104 d->mplugin = plugin; 0105 d->m_view = this; 0106 d->konsolepart = nullptr; 0107 setObjectName( i18n( "Terminal" ) ); 0108 0109 setWindowIcon( QIcon::fromTheme( QStringLiteral( "utilities-terminal" ), windowIcon() ) ); 0110 setWindowTitle(i18nc("@title:window", "Terminal")); 0111 0112 d->m_vbox = new QVBoxLayout( this ); 0113 d->m_vbox->setContentsMargins(0, 0, 0, 0); 0114 d->m_vbox->setSpacing( 0 ); 0115 0116 d->init( d->mplugin->konsoleFactory() ); 0117 0118 //TODO Make this configurable in the future, 0119 // but by default the konsole shouldn't 0120 // automatically switch directories on you. 0121 0122 // connect( KDevelop::Core::documentController(), SIGNAL(documentActivated(KDevDocument*)), 0123 // this, SLOT(documentActivated(KDevDocument*)) ); 0124 } 0125 0126 KDevKonsoleView::~KDevKonsoleView() 0127 { 0128 delete d; 0129 } 0130 0131 void KDevKonsoleView::setDirectory( const QUrl &url ) 0132 { 0133 if ( !url.isValid() || !url.isLocalFile() ) 0134 return ; 0135 0136 if ( d->konsolepart && url != d->konsolepart->url() ) 0137 d->konsolepart->openUrl( url ); 0138 } 0139 0140 bool KDevKonsoleView::eventFilter( QObject* obj, QEvent *e ) 0141 { 0142 switch( e->type() ) { 0143 case QEvent::ShortcutOverride: { 0144 auto *k = static_cast<QKeyEvent *>(e); 0145 0146 // Don't propagate Esc to the top level, it should be used by konsole 0147 if (k->key() == Qt::Key_Escape) { 0148 if (d->konsolepart && d->konsolepart->widget()) { 0149 e->accept(); 0150 return true; 0151 } 0152 } 0153 break; 0154 } 0155 0156 default: 0157 break; 0158 } 0159 0160 return QWidget::eventFilter( obj, e ); 0161 } 0162 0163 #include "moc_kdevkonsoleview.cpp"