diff --git a/addons/filebrowser/katefilebrowserconfig.cpp b/addons/filebrowser/katefilebrowserconfig.cpp index 2d12801df..11755988a 100644 --- a/addons/filebrowser/katefilebrowserconfig.cpp +++ b/addons/filebrowser/katefilebrowserconfig.cpp @@ -1,191 +1,192 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2001 Joseph Wenninger Copyright (C) 2001 Anders Lund Copyright (C) 2007 Mirko Stocker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "katefilebrowserconfig.h" #include "katefilebrowser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //BEGIN ACtionLBItem /* QListboxItem that can store and return a string, used for the toolbar action selector. */ class ActionLBItem : public QListWidgetItem { public: ActionLBItem( QListWidget *lb = nullptr, const QIcon &pm = QIcon(), const QString &text = QString(), const QString &str = QString() ) : QListWidgetItem(pm, text, lb, 0 ), _str(str) {} QString idstring() { return _str; } private: QString _str; }; //END ActionLBItem //BEGIN KateFileBrowserConfigPage KateFileBrowserConfigPage::KateFileBrowserConfigPage( QWidget *parent, KateFileBrowser *kfb ) : KTextEditor::ConfigPage( parent ), fileBrowser( kfb ), m_changed( false ) { QVBoxLayout *lo = new QVBoxLayout( this ); int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); lo->setSpacing( spacing ); + lo->setMargin(0); // Toolbar - a lot for a little... QGroupBox *gbToolbar = new QGroupBox(i18n("Toolbar"), this ); acSel = new KActionSelector( gbToolbar ); acSel->setAvailableLabel( i18n("A&vailable actions:") ); acSel->setSelectedLabel( i18n("S&elected actions:") ); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(acSel); gbToolbar->setLayout(vbox); lo->addWidget( gbToolbar ); connect(acSel, &KActionSelector::added, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::removed, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::movedUp, this, &KateFileBrowserConfigPage::slotMyChanged); connect(acSel, &KActionSelector::movedDown, this, &KateFileBrowserConfigPage::slotMyChanged); // make it look nice lo->addStretch( 1 ); init(); } QString KateFileBrowserConfigPage::name() const { return i18n("Filesystem Browser"); } QString KateFileBrowserConfigPage::fullName() const { return i18n("Filesystem Browser Settings"); } QIcon KateFileBrowserConfigPage::icon() const { return QIcon::fromTheme(QStringLiteral("document-open")); } void KateFileBrowserConfigPage::apply() { if ( ! m_changed ) return; m_changed = false; KConfigGroup config(KSharedConfig::openConfig(), "filebrowser"); QStringList l; ActionLBItem *aItem; QList list = acSel->selectedListWidget()->findItems(QStringLiteral("*"), Qt::MatchWildcard); foreach(QListWidgetItem *item, list) { aItem = static_cast(item); l << aItem->idstring(); } config.writeEntry( "toolbar actions", l ); fileBrowser->setupToolbar(); } void KateFileBrowserConfigPage::reset() { // hmm, what is this supposed to do, actually?? init(); m_changed = false; } void KateFileBrowserConfigPage::init() { KConfigGroup config(KSharedConfig::openConfig(), "filebrowser"); // toolbar QStringList l = config.readEntry( "toolbar actions", QStringList() ); if ( l.isEmpty() ) // default toolbar l << QStringLiteral("back") << QStringLiteral("forward") << QStringLiteral("bookmarks") << QStringLiteral("sync_dir") << QStringLiteral("configure"); // actions from diroperator + two of our own QStringList allActions; allActions << QStringLiteral("up") << QStringLiteral("back") << QStringLiteral("forward") << QStringLiteral("home") << QStringLiteral("reload") << QStringLiteral("mkdir") << QStringLiteral("delete") << QStringLiteral("short view") << QStringLiteral("detailed view") << QStringLiteral("tree view") << QStringLiteral("detailed tree view") << QStringLiteral("show hidden") /*<< QStringLiteral("view menu") << QStringLiteral("properties")*/ << QStringLiteral("bookmarks") << QStringLiteral("sync_dir") << QStringLiteral("configure"); QRegExp re(QStringLiteral ("&(?=[^&])")); QAction *ac = nullptr; QListWidget *lb; for ( QStringList::Iterator it = allActions.begin(); it != allActions.end(); ++it ) { lb = l.contains( *it ) ? acSel->selectedListWidget() : acSel->availableListWidget(); if ( *it == QStringLiteral ("bookmarks") || *it == QStringLiteral ("sync_dir") || *it == QStringLiteral ("configure") ) ac = fileBrowser->actionCollection()->action( *it ); else ac = fileBrowser->dirOperator()->actionCollection()->action( *it ); if ( ac ) { QString text = ac->text().remove( re ); // CJK languages need a filtering message for action texts in lists, // to remove special accelerators that they use. // The exact same filtering message exists in kdelibs; hence, // avoid extraction here and let it be sourced from kdelibs. #define i18ncX i18nc text = i18ncX( "@item:intable Action name in toolbar editor", "%1", text ); new ActionLBItem( lb, ac->icon(), text, *it ); } } } void KateFileBrowserConfigPage::slotMyChanged() { m_changed = true; emit changed(); } //END KateFileBrowserConfigPage // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/addons/konsole/kateconsole.cpp b/addons/konsole/kateconsole.cpp index e44da709f..ed9935622 100644 --- a/addons/konsole/kateconsole.cpp +++ b/addons/konsole/kateconsole.cpp @@ -1,502 +1,503 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2002 Joseph Wenninger Copyright (C) 2002 Anders Lund Copyright (C) 2007 Anders Lund Copyright (C) 2017 Ederag This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kateconsole.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON (KateKonsolePluginFactory, "katekonsoleplugin.json", registerPlugin();) KateKonsolePlugin::KateKonsolePlugin( QObject* parent, const QList& ): KTextEditor::Plugin ( parent ) { m_previousEditorEnv=qgetenv("EDITOR"); if (!KAuthorized::authorize(QStringLiteral("shell_access"))) { KMessageBox::sorry(nullptr, i18n ("You do not have enough karma to access a shell or terminal emulation")); } } KateKonsolePlugin::~KateKonsolePlugin() { qputenv("EDITOR", m_previousEditorEnv.data()); } QObject *KateKonsolePlugin::createView (KTextEditor::MainWindow *mainWindow) { KateKonsolePluginView *view = new KateKonsolePluginView (this, mainWindow); return view; } KTextEditor::ConfigPage *KateKonsolePlugin::configPage (int number, QWidget *parent) { if (number != 0) return nullptr; return new KateKonsoleConfigPage(parent, this); } void KateKonsolePlugin::readConfig() { foreach ( KateKonsolePluginView *view, mViews ) view->readConfig(); } KateKonsolePluginView::KateKonsolePluginView (KateKonsolePlugin* plugin, KTextEditor::MainWindow *mainWindow) : QObject(mainWindow),m_plugin(plugin) { // init console QWidget *toolview = mainWindow->createToolView (plugin, QStringLiteral("kate_private_plugin_katekonsoleplugin"), KTextEditor::MainWindow::Bottom, QIcon::fromTheme(QStringLiteral("utilities-terminal")), i18n("Terminal")); m_console = new KateConsole(m_plugin, mainWindow, toolview); // register this view m_plugin->mViews.append ( this ); } KateKonsolePluginView::~KateKonsolePluginView () { // unregister this view m_plugin->mViews.removeAll (this); // cleanup, kill toolview + console QWidget *toolview = m_console->parentWidget(); delete m_console; delete toolview; } void KateKonsolePluginView::readConfig() { m_console->readConfig(); } KateConsole::KateConsole (KateKonsolePlugin* plugin, KTextEditor::MainWindow *mw, QWidget *parent) : QWidget (parent) , m_part (nullptr) , m_mw (mw) , m_toolView (parent) , m_plugin(plugin) { KXMLGUIClient::setComponentName (QStringLiteral("katekonsole"), i18n ("Kate Terminal")); setXMLFile( QStringLiteral("ui.rc") ); // make sure we have a vertical layout new QVBoxLayout(this); layout()->setContentsMargins(0, 0, 0, 0); QAction* a = actionCollection()->addAction(QStringLiteral("katekonsole_tools_pipe_to_terminal")); a->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal"))); a->setText(i18nc("@action", "&Pipe to Terminal")); connect(a, &QAction::triggered, this, &KateConsole::slotPipeToConsole); a = actionCollection()->addAction(QStringLiteral("katekonsole_tools_sync")); a->setText(i18nc("@action", "S&ynchronize Terminal with Current Document")); connect(a, &QAction::triggered, this, &KateConsole::slotManualSync); a = actionCollection()->addAction(QStringLiteral("katekonsole_tools_run")); a->setText(i18nc("@action", "Run Current Document")); connect(a, &QAction::triggered, this, &KateConsole::slotRun); a = actionCollection()->addAction(QStringLiteral("katekonsole_tools_toggle_focus")); a->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal"))); a->setText(i18nc("@action", "&Focus Terminal")); actionCollection()->setDefaultShortcut(a, QKeySequence(Qt::Key_F4)); connect(a, &QAction::triggered, this, &KateConsole::slotToggleFocus); m_mw->guiFactory()->addClient (this); readConfig(); } KateConsole::~KateConsole () { m_mw->guiFactory()->removeClient (this); if (m_part) disconnect(m_part, &KParts::ReadOnlyPart::destroyed, this, &KateConsole::slotDestroyed); } void KateConsole::loadConsoleIfNeeded() { if (m_part) return; if (!window() || !parentWidget()) return; if (!window() || !isVisibleTo(window())) return; /** * get konsole part factory */ KPluginFactory *factory = KPluginLoader(QStringLiteral("konsolepart")).factory(); if (!factory) return; m_part = factory->create(this, this); if (!m_part) return; layout()->addWidget(m_part->widget()); // start the terminal qobject_cast(m_part)->showShellInDir( QString() ); // KGlobal::locale()->insertCatalog("konsole"); // FIXME KF5: insert catalog setFocusProxy(m_part->widget()); m_part->widget()->show(); connect(m_part, &KParts::ReadOnlyPart::destroyed, this, &KateConsole::slotDestroyed); connect ( m_part, SIGNAL(overrideShortcut(QKeyEvent*,bool&)), this, SLOT(overrideShortcut(QKeyEvent*,bool&))); slotSync(); } void KateConsole::slotDestroyed () { m_part = nullptr; m_currentPath.clear (); // hide the dockwidget if (parentWidget()) { m_mw->hideToolView (m_toolView); } } void KateConsole::overrideShortcut (QKeyEvent *, bool &override) { /** * let konsole handle all shortcuts */ override = true; } void KateConsole::showEvent(QShowEvent *) { if (m_part) return; loadConsoleIfNeeded(); } void KateConsole::cd (const QString & path) { if (m_currentPath == path) return; if (!m_part) return; m_currentPath = path; QString command = QStringLiteral(" cd ") + KShell::quoteArg(m_currentPath) + QLatin1Char('\n'); // special handling for some interpreters TerminalInterface *t = qobject_cast(m_part); if (t) { // ghci doesn't allow \space dir names, does allow spaces in dir names // irb can take spaces or \space but doesn't allow " 'path' " if (t->foregroundProcessName() == QStringLiteral("irb") ) { command = QStringLiteral("Dir.chdir(\"") + path + QStringLiteral("\") \n") ; } else if(t->foregroundProcessName() == QStringLiteral("ghc")) { command = QStringLiteral(":cd ") + path + QStringLiteral("\n"); } } sendInput(command); } void KateConsole::sendInput( const QString& text ) { loadConsoleIfNeeded(); if (!m_part) return; TerminalInterface *t = qobject_cast(m_part); if (!t) return; t->sendInput (text); } void KateConsole::slotPipeToConsole () { if (KMessageBox::warningContinueCancel (m_mw->window() , i18n ("Do you really want to pipe the text to the console? This will execute any contained commands with your user rights.") , i18n ("Pipe to Terminal?") , KGuiItem(i18n("Pipe to Terminal")), KStandardGuiItem::cancel(), QStringLiteral("Pipe To Terminal Warning")) != KMessageBox::Continue) return; KTextEditor::View *v = m_mw->activeView(); if (!v) return; if (v->selection()) sendInput (v->selectionText()); else sendInput (v->document()->text()); } void KateConsole::slotSync(KTextEditor::View *) { if (m_mw->activeView()) { QUrl u = m_mw->activeView()->document()->url(); if (u.isValid() && u.isLocalFile()) { QFileInfo fi(u.toLocalFile()); cd(fi.absolutePath()); } else if (!u.isEmpty()) { sendInput( QStringLiteral("### ") + i18n("Sorry, cannot cd into '%1'", u.toLocalFile() ) + QLatin1Char('\n') ); } } } void KateConsole::slotManualSync() { m_currentPath.clear (); slotSync(); if ( ! m_part || ! m_part->widget()->isVisible() ) m_mw->showToolView( parentWidget() ); } void KateConsole::slotRun() { if ( m_mw->activeView() ) { KTextEditor::Document *document = m_mw->activeView()->document(); QUrl u = document->url(); if ( ! u.isLocalFile() ) { QPointer message = new KTextEditor::Message( i18n("Not a local file: '%1'", u.path()), KTextEditor::Message::Error ); // auto hide is enabled and set to a sane default value of several seconds. message->setAutoHide(2000); message->setAutoHideMode( KTextEditor::Message::Immediate ); document->postMessage( message ); return; } // ensure that file is saved if ( document->isModified() ) { document->save(); } // The string that should be output to terminal, upon acceptance QString output_str; // prefix first output_str += KConfigGroup( KSharedConfig::openConfig(), "Konsole" ).readEntry("RunPrefix", ""); // then filename if ( KConfigGroup(KSharedConfig::openConfig(), "Konsole" ).readEntry("RemoveExtension", true) ) { // append filename without extension (i.e. keep only the basename) output_str += QFileInfo( u.path() ).baseName() + QLatin1Char('\n'); } else { // append filename to the terminal output_str += QFileInfo( u.path() ).fileName() + QLatin1Char('\n'); } if ( KMessageBox::Continue != KMessageBox::warningContinueCancel( m_mw->window(), i18n("Do you really want to Run the document ?\n" "This will execute the following command,\n" "with your user rights, in the terminal:\n" "'%1'", output_str), i18n("Run in Terminal?"), KGuiItem( i18n("Run") ), KStandardGuiItem::cancel(), QStringLiteral("Konsole: Run in Terminal Warning") ) ) { return; } // echo to terminal sendInput( output_str ); } } void KateConsole::slotToggleFocus() { QAction *action = actionCollection()->action(QStringLiteral("katekonsole_tools_toggle_focus")); if ( ! m_part ) { m_mw->showToolView( parentWidget() ); action->setText( i18n("Defocus Terminal") ); return; // this shows and focuses the konsole } if ( ! m_part ) return; if (m_part->widget()->hasFocus()) { if (m_mw->activeView()) m_mw->activeView()->setFocus(); action->setText( i18n("Focus Terminal") ); } else { // show the view if it is hidden if (parentWidget()->isHidden()) m_mw->showToolView( parentWidget() ); else // should focus the widget too! m_part->widget()->setFocus( Qt::OtherFocusReason ); action->setText( i18n("Defocus Terminal") ); } } void KateConsole::readConfig() { disconnect(m_mw, &KTextEditor::MainWindow::viewChanged, this, &KateConsole::slotSync); if ( KConfigGroup(KSharedConfig::openConfig(), "Konsole").readEntry("AutoSyncronize", true) ) { connect(m_mw, &KTextEditor::MainWindow::viewChanged, this, &KateConsole::slotSync); } if ( KConfigGroup(KSharedConfig::openConfig(), "Konsole").readEntry("SetEditor", false) ) qputenv( "EDITOR", "kate -b"); else qputenv( "EDITOR", m_plugin->previousEditorEnv().data()); } KateKonsoleConfigPage::KateKonsoleConfigPage( QWidget* parent, KateKonsolePlugin *plugin ) : KTextEditor::ConfigPage( parent ) , mPlugin( plugin ) { QVBoxLayout *lo = new QVBoxLayout( this ); lo->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing)); + lo->setMargin(0); cbAutoSyncronize = new QCheckBox( i18n("&Automatically synchronize the terminal with the current document when possible"), this ); lo->addWidget( cbAutoSyncronize ); QVBoxLayout *vboxRun = new QVBoxLayout; QGroupBox *groupRun = new QGroupBox( i18n("Run in terminal"), this ); // Remove extension cbRemoveExtension = new QCheckBox( i18n("&Remove extension"), this ); vboxRun->addWidget( cbRemoveExtension ); // Prefix QFrame *framePrefix = new QFrame( this ); QHBoxLayout *hboxPrefix = new QHBoxLayout( framePrefix ); QLabel *label = new QLabel( i18n("Prefix:"), framePrefix ); hboxPrefix->addWidget( label ); lePrefix = new QLineEdit( framePrefix ); hboxPrefix->addWidget( lePrefix ); vboxRun->addWidget( framePrefix ); // show warning next time QFrame *frameWarn = new QFrame( this ); QHBoxLayout *hboxWarn = new QHBoxLayout( frameWarn ); QPushButton *buttonWarn = new QPushButton( i18n("&Show warning next time"), frameWarn); buttonWarn->setWhatsThis ( i18n ( "The next time '%1' is executed, " "make sure a warning window will pop up, " "displaying the command to be sent to terminal, " "for review.", i18n ("Run in terminal") ) ); connect( buttonWarn, &QPushButton::pressed, this, &KateKonsoleConfigPage::slotEnableRunWarning ); hboxWarn->addWidget( buttonWarn ); vboxRun->addWidget( frameWarn ); groupRun->setLayout( vboxRun ); lo->addWidget( groupRun ); cbSetEditor = new QCheckBox( i18n("Set &EDITOR environment variable to 'kate -b'"), this ); lo->addWidget( cbSetEditor ); QLabel *tmp = new QLabel(this); tmp->setText(i18n("Important: The document has to be closed to make the console application continue")); lo->addWidget(tmp); reset(); lo->addStretch(); connect(cbAutoSyncronize, &QCheckBox::stateChanged, this, &KateKonsoleConfigPage::changed); connect( cbRemoveExtension, &QCheckBox::stateChanged, this, &KTextEditor::ConfigPage::changed ); connect( lePrefix, &QLineEdit::textChanged, this, &KateKonsoleConfigPage::changed ); connect(cbSetEditor, &QCheckBox::stateChanged, this, &KateKonsoleConfigPage::changed); } void KateKonsoleConfigPage::slotEnableRunWarning () { KMessageBox::enableMessage(QStringLiteral("Konsole: Run in Terminal Warning")); } QString KateKonsoleConfigPage::name() const { return i18n("Terminal"); } QString KateKonsoleConfigPage::fullName() const { return i18n("Terminal Settings"); } QIcon KateKonsoleConfigPage::icon() const { return QIcon::fromTheme(QStringLiteral("utilities-terminal")); } void KateKonsoleConfigPage::apply() { KConfigGroup config(KSharedConfig::openConfig(), "Konsole"); config.writeEntry("AutoSyncronize", cbAutoSyncronize->isChecked()); config.writeEntry("RemoveExtension", cbRemoveExtension->isChecked()); config.writeEntry("RunPrefix", lePrefix->text()); config.writeEntry("SetEditor", cbSetEditor->isChecked()); config.sync(); mPlugin->readConfig(); } void KateKonsoleConfigPage::reset() { KConfigGroup config(KSharedConfig::openConfig(), "Konsole"); cbAutoSyncronize->setChecked(config.readEntry("AutoSyncronize", true)); cbRemoveExtension->setChecked(config.readEntry("RemoveExtension", false)); lePrefix->setText(config.readEntry("RunPrefix", "")); cbSetEditor->setChecked(config.readEntry("SetEditor", false)); } #include "kateconsole.moc" // kate: space-indent on; indent-width 2; replace-tabs on;