diff --git a/plugins/execute/CMakeLists.txt b/plugins/execute/CMakeLists.txt index 00feea6144..8d0e2b24cd 100644 --- a/plugins/execute/CMakeLists.txt +++ b/plugins/execute/CMakeLists.txt @@ -1,31 +1,33 @@ ########### next target ############### set(kdevexecute_PART_UIS nativeappconfig.ui ) set(kdevexecute_PART_SRCS projecttargetscombobox.cpp executeplugin.cpp nativeappconfig.cpp nativeappjob.cpp ) ki18n_wrap_ui( kdevexecute_PART_SRCS ${kdevexecute_PART_UIS} ) add_library(kdevexecute MODULE ${kdevexecute_PART_SRCS}) target_link_libraries(kdevexecute KF5::KCMUtils KDev::Interfaces KDev::Util KDev::Project - KDev::OutputView) + KDev::OutputView + KDev::Shell +) install(TARGETS kdevexecute DESTINATION ${PLUGIN_INSTALL_DIR}/kdevplatform/${KDEV_PLUGIN_VERSION}) ########### install files ############### install(FILES iexecuteplugin.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/execute COMPONENT Devel) configure_file(kdevexecute.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/kdevexecute.desktop) kcoreaddons_desktop_to_json(kdevexecute ${CMAKE_CURRENT_BINARY_DIR}/kdevexecute.desktop) diff --git a/plugins/execute/nativeappconfig.ui b/plugins/execute/nativeappconfig.ui index c7a3540047..bb8b46179d 100644 --- a/plugins/execute/nativeappconfig.ui +++ b/plugins/execute/nativeappconfig.ui @@ -1,551 +1,551 @@ NativeAppPage 0 0 511 580 Executable Project Target: projectTargetRadio 0 0 true 0 0 Executable: executableRadio true false Enter the executable name or absolute path to an executable file Behavior Arguments: arguments <html><head/><body><p>Enter arguments to give to the executable.<br/>You can pass arguments containing space characters by putting them in double-quotes.</p></body></html> Enter arguments to give to the executable Working Directory: workingDirectory Select a working directory for the executable Select a working directory for the executable Environment: environment 0 0 Select an environment to be used Qt::Horizontal 12 20 <p>By default applications will be run in the background and only their output will be displayed in a toolview. This makes it impossible to interact with applications requiring user input from a terminal emulator. To run such applications, you should use an external terminal.</p> Use External Terminal: false 0 0 <p>Defines the command to execute the external terminal emulator. Use the following placeholders:</p> <dl> <dt><code>%exe</code></dt> <dd>The path to the executable selected above.</dd> <dt><code>%workdir</code></dt> <dd>The path to the working directory selected above.</dd> </dl> <p>The arguments defined above will get appended to this command.</p> true konsole --noclose --workdir %workdir -e %exe xterm -hold -e %exe gnome-terminal -e %exe Dependencies Action: dependencyAction Specifies the action to take for the dependencies before starting the executable. The selected action will be run before the executable is started. This allows there to be parts of a project, upon which the executable does not directly depend, to be built and/or installed before running the application. true Do Nothing Build Build and Install Targets: targetDependency false Enter a dependency to add to the list Enter a dependency to add to the list true false false Adds the listed target to the dependency list. false List of indirect dependent targets. This list should contain targets that the application does not directly depend on, but for which an action needs to be taken before running the application. true true false Removes the selected dependencies from the list. false Move a dependency up in the list. false Moves the selected dependency down in the list. Qt::Vertical 20 40 KComboBox QComboBox
kcombobox.h
QLineEdit QLineEdit
klineedit.h
QListWidget QListWidget
klistwidget.h
KUrlRequester QFrame
kurlrequester.h
KDevelop::EnvironmentSelectionWidget KComboBox
util/environmentselectionwidget.h
ProjectItemLineEdit QLineEdit
project/projectitemlineedit.h
ProjectTargetsComboBox QComboBox
projecttargetscombobox.h
KDevelop::EnvironmentConfigureButton QToolButton -
util/environmentconfigurebutton.h
+
shell/environmentconfigurebutton.h
executablePath arguments workingDirectory environment targetDependency addDependency dependencies removeDependency moveDepUp moveDepDown projectTargetRadio toggled(bool) executablePath setDisabled(bool) 124 55 497 85 executableRadio toggled(bool) executablePath setEnabled(bool) 124 83 497 85 runInTerminal toggled(bool) terminal setEnabled(bool) 136 227 206 226 projectTargetRadio toggled(bool) projectTarget setEnabled(bool) 108 34 152 38 executableRadio toggled(bool) projectTarget setDisabled(bool) 106 73 310 45
diff --git a/project/interfaces/iprojectbuilder.h b/project/interfaces/iprojectbuilder.h index c47573a686..6c8c0d2ccd 100644 --- a/project/interfaces/iprojectbuilder.h +++ b/project/interfaces/iprojectbuilder.h @@ -1,124 +1,124 @@ /* This file is part of KDevelop Copyright 2004 Roberto Raggi Copyright 2007 Andreas Pakulat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. */ #ifndef KDEVPLATFORM_IPROJECTBUILDER_H #define KDEVPLATFORM_IPROJECTBUILDER_H #include #include class KJob; namespace KDevelop { class IProject; class ProjectBaseItem; /** @author Roberto Raggi @short IProjectBuilder Base class for the Project Builders Describes a Project Builder to KDevelop's Project Manager. */ class KDEVPLATFORMPROJECT_EXPORT IProjectBuilder { public: virtual ~IProjectBuilder(); /** * Installs the given project item, exact behaviour depends * on the implementation */ virtual KJob* install(ProjectBaseItem* item) = 0; /** * Builds the given project item, exact behaviour depends * on the implementation */ virtual KJob* build(ProjectBaseItem *dom) = 0; /** * Cleans the given project item, exact behaviour depends * on the implementation. The cleaning should only include * output files, like C/C++ object files, binaries, files * that the builder needs shouldn't be removed. */ virtual KJob* clean(ProjectBaseItem *dom) = 0; /** * Configures the given project, exact behaviour depends * on the implementation. After calling this a build() call should * succeed (given the code doesn't have errors). * * This function is optional, the default implementation does nothing. */ virtual KJob* configure(IProject*); /** * Prunes the given project, exact behaviour depends * on the implementation. Additionally to what clean() does this may * also remove files used for the builder (or a "subbuilder"), for example * generated Makefiles in QMake/CMake/Automake projects * * This function is optional, the default implementation does nothing. */ virtual KJob* prune(IProject*); /** * Provide access to the builders related to this one. - * The list returned by this method is used to select the appropriate KCMs for a project. + * The list returned by this method is used to select the appropriate config pages for a project. * This method may safely return an empty list, as does the default implementation. */ virtual QList additionalBuilderPlugins( IProject* project ) const; Q_SIGNALS: /** * Emitted when the build for the given item was finished */ void built(ProjectBaseItem *dom); /** * Emitted when the install for the given item was finished */ void installed(ProjectBaseItem*); /** * Emitted when the clean for the given item was finished */ void cleaned(ProjectBaseItem*); /** * Emitted when any of the scheduled actions for the given item was failed */ void failed(ProjectBaseItem *dom); /** * Emitted when the configure for the given item was finished */ void configured(IProject*); /** * Emitted when the pruning for the given item was finished */ void pruned(IProject*); }; } Q_DECLARE_INTERFACE( KDevelop::IProjectBuilder, "org.kdevelop.IProjectBuilder" ) #endif diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt index e874ed41f7..bf602e6a1a 100644 --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -1,168 +1,170 @@ add_subdirectory(tests) set(KDevPlatformShell_LIB_SRCS workingsetcontroller.cpp workingsets/workingset.cpp workingsets/workingsetfilelabel.cpp workingsets/workingsettoolbutton.cpp workingsets/workingsettooltipwidget.cpp workingsets/workingsetwidget.cpp workingsets/closedworkingsetswidget.cpp workingsets/workingsethelpers.cpp assistantpopup.cpp mainwindow.cpp mainwindow_p.cpp plugincontroller.cpp shellextension.cpp core.cpp uicontroller.cpp projectcontroller.cpp project.cpp partcontroller.cpp #document.cpp partdocument.cpp textdocument.cpp documentcontroller.cpp languagecontroller.cpp language.cpp statusbar.cpp runcontroller.cpp sessioncontroller.cpp session.cpp sessionlock.cpp sessionchooserdialog.cpp savedialog.cpp sessiondialog.cpp sourceformattercontroller.cpp completionsettings.cpp openprojectpage.cpp openprojectdialog.cpp projectinfopage.cpp selectioncontroller.cpp documentationcontroller.cpp debugcontroller.cpp launchconfiguration.cpp launchconfigurationdialog.cpp loadedpluginsdialog.cpp testcontroller.cpp projectsourcepage.cpp debug.cpp configdialog.cpp editorconfigpage.cpp + environmentconfigurebutton.cpp progresswidget/progressmanager.cpp progresswidget/statusbarprogresswidget.cpp progresswidget/overlaywidget.cpp progresswidget/progressdialog.cpp areadisplay.cpp settings/uipreferences.cpp settings/pluginpreferences.cpp settings/sourceformattersettings.cpp settings/editstyledialog.cpp settings/projectpreferences.cpp settings/environmentwidget.cpp settings/environmentgroupmodel.cpp settings/environmentpreferences.cpp settings/ccpreferences.cpp settings/bgpreferences.cpp settings/templateconfig.cpp settings/templatepage.cpp ) kconfig_add_kcfg_files(KDevPlatformShell_LIB_SRCS settings/uiconfig.kcfgc settings/projectconfig.kcfgc settings/ccconfig.kcfgc settings/bgconfig.kcfgc ) ki18n_wrap_ui(KDevPlatformShell_LIB_SRCS sessiondialog.ui projectinfopage.ui launchconfigurationdialog.ui projectsourcepage.ui settings/uiconfig.ui settings/editstyledialog.ui settings/sourceformattersettings.ui settings/projectsettings.ui settings/environmentwidget.ui settings/ccsettings.ui settings/bgsettings.ui settings/templateconfig.ui settings/templatepage.ui ) add_library(KDevPlatformShell ${KDevPlatformShell_LIB_SRCS}) add_library(KDev::Shell ALIAS KDevPlatformShell) generate_export_header(KDevPlatformShell EXPORT_FILE_NAME shellexport.h) target_link_libraries(KDevPlatformShell LINK_PUBLIC KF5::XmlGui KDev::Sublime KDev::OutputView KDev::Debugger KDev::Interfaces LINK_PRIVATE Qt5::Declarative KF5::GuiAddons KF5::IconThemes KF5::KIOFileWidgets KF5::KIOWidgets KF5::Parts KF5::Notifications KF5::NotifyConfig KF5::TextEditor KF5::ThreadWeaver KF5::JobWidgets KF5::ItemViews KF5::WindowSystem KF5::KCMUtils #for KPluginSelector, not sure why it is in kcmutils KF5::NewStuff # template config page KF5::Archive # template config page KDev::Project KDev::Vcs KDev::Language KDev::Util KDev::Documentation ) set_target_properties(KDevPlatformShell PROPERTIES VERSION ${KDEVPLATFORM_LIB_VERSION} SOVERSION ${KDEVPLATFORM_LIB_SOVERSION} EXPORT_NAME Shell) install(FILES mainwindow.h plugincontroller.h shellextension.h core.h uicontroller.h projectcontroller.h project.h partcontroller.h partdocument.h textdocument.h documentcontroller.h languagecontroller.h session.h sessioncontroller.h sessionlock.h sourceformattercontroller.h language.h selectioncontroller.h runcontroller.h launchconfiguration.h + environmentconfigurebutton.h ${CMAKE_CURRENT_BINARY_DIR}/shellexport.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/shell COMPONENT Devel ) install(TARGETS KDevPlatformShell EXPORT KDevPlatformTargets ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( FILES debugger/kdevdebuggershellui.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/kdevdebugger ) install( FILES kdevsessionui.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/kdevsession ) install( FILES kdevsourceformatter.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/kdevsourceformatter ) install( FILES AssistantButton.qml assistantpopup.qml DESTINATION ${DATA_INSTALL_DIR}/kdevelop ) diff --git a/util/environmentconfigurebutton.cpp b/shell/environmentconfigurebutton.cpp similarity index 87% rename from util/environmentconfigurebutton.cpp rename to shell/environmentconfigurebutton.cpp index 9abbd033c2..9572177eec 100644 --- a/util/environmentconfigurebutton.cpp +++ b/shell/environmentconfigurebutton.cpp @@ -1,108 +1,108 @@ /* This file is part of KDevelop Copyright 2010 Milian Wolff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 "environmentconfigurebutton.h" -#include "environmentselectionwidget.h" -#include "environmentgrouplist.h" +#include +#include +#include "settings/environmentpreferences.h" #include #include #include #include #include #include #include #include #include #include namespace KDevelop { class EnvironmentConfigureButtonPrivate { public: EnvironmentConfigureButtonPrivate(EnvironmentConfigureButton* _q) : q(_q), selectionWidget(0) { } void showDialog() { QDialog dlg(qApp->activeWindow()); - QStringList selected; + QString selected; if (selectionWidget) { - selected << selectionWidget->effectiveProfileName(); + selected = selectionWidget->effectiveProfileName(); } - KCModuleProxy proxy("kcm_kdev_envsettings", 0, selected); - + EnvironmentPreferences prefs(selected, q); auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QObject::connect(buttonBox, SIGNAL(accepted()), &dlg, SLOT(accept())); QObject::connect(buttonBox, SIGNAL(rejected()), &dlg, SLOT(reject())); auto layout = new QVBoxLayout; - layout->addWidget(&proxy); + layout->addWidget(&prefs); layout->addWidget(buttonBox); dlg.setLayout(layout); - dlg.setWindowTitle(proxy.moduleInfo().moduleName()); - dlg.setWindowIcon(QIcon::fromTheme(proxy.moduleInfo().icon())); + dlg.setWindowTitle(prefs.fullName()); + dlg.setWindowIcon(prefs.icon()); dlg.resize(480, 320); if (dlg.exec() == QDialog::Accepted) { - proxy.save(); + prefs.apply(); emit q->environmentConfigured(); } } EnvironmentConfigureButton *q; EnvironmentSelectionWidget *selectionWidget; }; EnvironmentConfigureButton::EnvironmentConfigureButton(QWidget* parent) : QPushButton(parent), d(new EnvironmentConfigureButtonPrivate(this)) { setText(QString()); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setIcon(QIcon::fromTheme("configure")); setToolTip(i18n("Configure environment variables")); connect(this, &EnvironmentConfigureButton::clicked, this, [&] { d->showDialog(); }); } EnvironmentConfigureButton::~EnvironmentConfigureButton() { delete d; } void EnvironmentConfigureButton::setSelectionWidget(EnvironmentSelectionWidget* widget) { connect(this, &EnvironmentConfigureButton::environmentConfigured, widget, &EnvironmentSelectionWidget::reconfigure); d->selectionWidget = widget; } } #include "moc_environmentconfigurebutton.cpp" diff --git a/util/environmentconfigurebutton.h b/shell/environmentconfigurebutton.h similarity index 92% rename from util/environmentconfigurebutton.h rename to shell/environmentconfigurebutton.h index 9a6503801c..ff063fcee7 100644 --- a/util/environmentconfigurebutton.h +++ b/shell/environmentconfigurebutton.h @@ -1,63 +1,61 @@ /* This file is part of KDevelop Copyright 2010 Milian Wolff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. */ #ifndef KDEVPLATFORM_ENVIRONMENTCONFIGUREBUTTON_H #define KDEVPLATFORM_ENVIRONMENTCONFIGUREBUTTON_H -#include "utilexport.h" +#include "shellexport.h" #include namespace KDevelop { class EnvironmentSelectionWidget; /** * A tool button that shows a dialog to configure the environment settings. * You want to place that next to an @c EnvironmentSelectionWidget and pass * that one along. This button will automatically update the selection widget * if required then. */ -class KDEVPLATFORMUTIL_EXPORT EnvironmentConfigureButton : public QPushButton +class KDEVPLATFORMSHELL_EXPORT EnvironmentConfigureButton : public QPushButton { Q_OBJECT public: explicit EnvironmentConfigureButton(QWidget* parent = 0); ~EnvironmentConfigureButton(); void setSelectionWidget(EnvironmentSelectionWidget* widget); signals: /** * Gets emitted whenever the dialog was acceppted * and the env settings might have changed. */ void environmentConfigured(); private: class EnvironmentConfigureButtonPrivate* const d; friend class EnvironmentConfigureButtonPrivate; - - Q_PRIVATE_SLOT(d, void showDialog()) }; } #endif // KDEVPLATFORM_ENVIRONMENTCONFIGUREBUTTON_H diff --git a/shell/settings/environmentpreferences.cpp b/shell/settings/environmentpreferences.cpp index 0a06e5b195..8a8756eb7d 100644 --- a/shell/settings/environmentpreferences.cpp +++ b/shell/settings/environmentpreferences.cpp @@ -1,103 +1,98 @@ /* This file is part of KDevelop Copyright 2006 Adam Treat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 "environmentpreferences.h" #include #include #include #include #include #include "environmentwidget.h" namespace KDevelop { class EnvironmentPreferencesPrivate { public: EnvironmentWidget *preferencesDialog; KConfigSkeleton* skel; QString activeGroup; }; -EnvironmentPreferences::EnvironmentPreferences(QWidget* parent) +EnvironmentPreferences::EnvironmentPreferences(const QString& activeGroup, QWidget* parent) : ConfigPage(nullptr, nullptr, parent), d(new EnvironmentPreferencesPrivate) { QVBoxLayout * l = new QVBoxLayout( this ); d->preferencesDialog = new EnvironmentWidget( this ); l->addWidget( d->preferencesDialog ); connect(d->preferencesDialog, &EnvironmentWidget::changed, this, &EnvironmentPreferences::changed); d->skel = new KConfigSkeleton(KSharedConfig::openConfig()); setConfigSkeleton(d->skel); -#pragma message("TODO: what is this doing? how to port?") -#if 0 - if (!args.isEmpty() && args.first().canConvert()) { - d->activeGroup = args.first().toString(); - } -#endif + d->activeGroup = activeGroup; } EnvironmentPreferences::~EnvironmentPreferences( ) { delete d; } void EnvironmentPreferences::apply() { d->preferencesDialog->saveSettings(d->skel->config()); ConfigPage::apply(); } void EnvironmentPreferences::reset() { d->preferencesDialog->loadSettings(d->skel->config()); d->preferencesDialog->setActiveGroup(d->activeGroup); ConfigPage::reset(); } void EnvironmentPreferences::defaults() { d->preferencesDialog->defaults(d->skel->config()); ConfigPage::defaults(); } QString EnvironmentPreferences::name() const { return i18n("Environment"); } QString EnvironmentPreferences::fullName() const { return i18n("Configure Environment Variables"); } QIcon EnvironmentPreferences::icon() const { return QIcon::fromTheme(QStringLiteral("utilities-terminal")); } } #include "environmentpreferences.moc" diff --git a/shell/settings/environmentpreferences.h b/shell/settings/environmentpreferences.h index 68373494fa..e5d950b59e 100644 --- a/shell/settings/environmentpreferences.h +++ b/shell/settings/environmentpreferences.h @@ -1,50 +1,50 @@ /* This file is part of KDevelop Copyright 2006 Adam Treat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. */ #ifndef KDEVPLATFORM_ENVIRONMENTPREFERENCES_H #define KDEVPLATFORM_ENVIRONMENTPREFERENCES_H #include namespace KDevelop { class EnvironmentPreferences : public ConfigPage { Q_OBJECT public: - explicit EnvironmentPreferences(QWidget* parent); + explicit EnvironmentPreferences(const QString& activeGroup = QString(), QWidget* parent = nullptr); virtual ~EnvironmentPreferences(); virtual QString name() const override; virtual QString fullName() const override; virtual QIcon icon() const override; virtual void apply() override; virtual void reset() override; virtual void defaults() override; private: class EnvironmentPreferencesPrivate *const d; }; } #endif diff --git a/shell/uicontroller.cpp b/shell/uicontroller.cpp index 2ce162adf6..33cb91232c 100644 --- a/shell/uicontroller.cpp +++ b/shell/uicontroller.cpp @@ -1,724 +1,724 @@ /*************************************************************************** * Copyright 2007 Alexander Dymo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "uicontroller.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" #include "configpage.h" #include "configdialog.h" #include "debug.h" #include "editorconfigpage.h" #include "shellextension.h" #include "partcontroller.h" #include "plugincontroller.h" #include "mainwindow.h" #include "partdocument.h" #include "textdocument.h" #include "documentcontroller.h" #include "assistantpopup.h" #include #include #include "workingsetcontroller.h" #include "workingsets/workingset.h" #include "settings/bgpreferences.h" #include "settings/ccpreferences.h" #include "settings/environmentpreferences.h" #include "settings/pluginpreferences.h" #include "settings/projectpreferences.h" #include "settings/sourceformattersettings.h" #include "settings/uipreferences.h" #include "settings/templateconfig.h" namespace KDevelop { class UiControllerPrivate { public: UiControllerPrivate(UiController *controller) : areasRestored(false), m_controller(controller) { if (Core::self()->workingSetControllerInternal()) Core::self()->workingSetControllerInternal()->initializeController(m_controller); QMap desired; desired["org.kdevelop.ClassBrowserView"] = Sublime::Left; desired["org.kdevelop.DocumentsView"] = Sublime::Left; desired["org.kdevelop.ProjectsView"] = Sublime::Left; desired["org.kdevelop.FileManagerView"] = Sublime::Left; desired["org.kdevelop.ProblemReporterView"] = Sublime::Bottom; desired["org.kdevelop.OutputView"] = Sublime::Bottom; desired["org.kdevelop.ContextBrowser"] = Sublime::Bottom; desired["org.kdevelop.KonsoleView"] = Sublime::Bottom; desired["org.kdevelop.SnippetView"] = Sublime::Right; desired["org.kdevelop.ExternalScriptView"] = Sublime::Right; Sublime::Area* a = new Sublime::Area(m_controller, "code", i18n("Code")); a->setDesiredToolViews(desired); a->setIconName("document-edit"); m_controller->addDefaultArea(a); desired.clear(); desired["org.kdevelop.debugger.VariablesView"] = Sublime::Left; desired["org.kdevelop.debugger.BreakpointsView"] = Sublime::Bottom; desired["org.kdevelop.debugger.StackView"] = Sublime::Bottom; desired["org.kdevelop.debugger.ConsoleView"] = Sublime::Bottom; desired["org.kdevelop.KonsoleView"] = Sublime::Bottom; a = new Sublime::Area(m_controller, "debug", i18n("Debug")); a->setDesiredToolViews(desired); a->setIconName("tools-report-bug"); m_controller->addDefaultArea(a); desired.clear(); desired["org.kdevelop.ProjectsView"] = Sublime::Left; desired["org.kdevelop.PatchReview"] = Sublime::Bottom; a = new Sublime::Area(m_controller, "review", i18n("Review")); a->setDesiredToolViews(desired); a->setIconName("applications-engineering"); m_controller->addDefaultArea(a); if(!(Core::self()->setupFlags() & Core::NoUi)) { defaultMainWindow = new MainWindow(m_controller); m_controller->addMainWindow(defaultMainWindow); activeSublimeWindow = defaultMainWindow; } else { activeSublimeWindow = defaultMainWindow = 0; } m_assistantTimer.setSingleShot(true); m_assistantTimer.setInterval(100); } void widgetChanged(QWidget*, QWidget* now) { if (now) { Sublime::MainWindow* win = qobject_cast(now->window()); if( win ) { activeSublimeWindow = win; } } } Core *core; MainWindow* defaultMainWindow; QMap factoryDocuments; Sublime::MainWindow* activeSublimeWindow; bool areasRestored; //Currently shown assistant popup. QPointer currentShownAssistant; QTimer m_assistantTimer; private: UiController *m_controller; }; class UiToolViewFactory: public Sublime::ToolFactory { public: UiToolViewFactory(IToolViewFactory *factory): m_factory(factory) {} ~UiToolViewFactory() { delete m_factory; } virtual QWidget* create(Sublime::ToolDocument *doc, QWidget *parent = 0) { Q_UNUSED( doc ); return m_factory->create(parent); } virtual QList< QAction* > contextMenuActions(QWidget* viewWidget) const { return m_factory->contextMenuActions( viewWidget ); } QList toolBarActions( QWidget* viewWidget ) const { return m_factory->toolBarActions( viewWidget ); } QString id() const { return m_factory->id(); } private: IToolViewFactory *m_factory; }; class ViewSelectorItem: public QListWidgetItem { public: ViewSelectorItem(const QString &text, QListWidget *parent = 0, int type = Type) :QListWidgetItem(text, parent, type) {} IToolViewFactory *factory; }; class NewToolViewListWidget: public QListWidget { Q_OBJECT public: NewToolViewListWidget(MainWindow *mw, QWidget* parent = 0) :QListWidget(parent), m_mw(mw) { connect(this, &NewToolViewListWidget::doubleClicked, this, &NewToolViewListWidget::addNewToolViewByDoubleClick); } Q_SIGNALS: void addNewToolView(MainWindow *mw, QListWidgetItem *item); private Q_SLOTS: void addNewToolViewByDoubleClick(QModelIndex index) { QListWidgetItem *item = itemFromIndex(index); // Disable item so that the toolview can not be added again. item->setFlags(item->flags() & ~Qt::ItemIsEnabled); emit addNewToolView(m_mw, item); } private: MainWindow *m_mw; }; UiController::UiController(Core *core) :Sublime::Controller(0), IUiController(), d(new UiControllerPrivate(this)) { setObjectName("UiController"); d->core = core; if (!defaultMainWindow() || (Core::self()->setupFlags() & Core::NoUi)) return; connect(qApp, &QApplication::focusChanged, this, [&] (QWidget* old, QWidget* now) { d->widgetChanged(old, now); } ); setupActions(); } UiController::~UiController() { delete d; } void UiController::setupActions() { } void UiController::mainWindowDeleted(MainWindow* mw) { if (d->defaultMainWindow == mw) d->defaultMainWindow = 0L; if (d->activeSublimeWindow == mw) d->activeSublimeWindow = 0L; } // FIXME: currently, this always create new window. Probably, // should just rename it. void UiController::switchToArea(const QString &areaName, SwitchMode switchMode) { if (switchMode == ThisWindow) { showArea(areaName, activeSublimeWindow()); return; } MainWindow *main = new MainWindow(this); addMainWindow(main); showArea(areaName, main); main->initialize(); // WTF? First, enabling this code causes crashes since we // try to disconnect some already-deleted action, or something. // Second, this code will disconnection the clients from guiFactory // of the previous main window. Ick! #if 0 //we need to add all existing guiclients to the new mainwindow //@todo adymo: add only ones that belong to the area (when the area code is there) foreach (KXMLGUIClient *client, oldMain->guiFactory()->clients()) main->guiFactory()->addClient(client); #endif main->show(); } QWidget* UiController::findToolView(const QString& name, IToolViewFactory *factory, FindFlags flags) { if(!d->areasRestored || !activeArea()) return 0; QList< Sublime::View* > views = activeArea()->toolViews(); foreach(Sublime::View* view, views) { Sublime::ToolDocument *doc = dynamic_cast(view->document()); if(doc && doc->title() == name && view->widget()) { if(flags & Raise) view->requestRaise(); return view->widget(); } } QWidget* ret = 0; if(flags & Create) { if(!d->factoryDocuments.contains(factory)) d->factoryDocuments[factory] = new Sublime::ToolDocument(name, this, new UiToolViewFactory(factory)); Sublime::ToolDocument *doc = d->factoryDocuments[factory]; Sublime::View* view = addToolViewToArea(factory, doc, activeArea()); if(view) ret = view->widget(); if(flags & Raise) findToolView(name, factory, Raise); } return ret; } void UiController::raiseToolView(QWidget* toolViewWidget) { if(!d->areasRestored) return; QList< Sublime::View* > views = activeArea()->toolViews(); foreach(Sublime::View* view, views) { if(view->widget() == toolViewWidget) { view->requestRaise(); return; } } } void UiController::addToolView(const QString & name, IToolViewFactory *factory) { if (!factory) return; qCDebug(SHELL) ; Sublime::ToolDocument *doc = new Sublime::ToolDocument(name, this, new UiToolViewFactory(factory)); d->factoryDocuments[factory] = doc; /* Until areas are restored, we don't know which views should be really added, and which not, so we just record view availability. */ if (d->areasRestored) { foreach (Sublime::Area* area, allAreas()) { addToolViewToArea(factory, doc, area); } } } void KDevelop::UiController::raiseToolView(Sublime::View * view) { foreach( Sublime::Area* area, allAreas() ) { if( area->toolViews().contains( view ) ) area->raiseToolView( view ); } } void KDevelop::UiController::removeToolView(IToolViewFactory *factory) { if (!factory) return; qCDebug(SHELL) ; //delete the tooldocument Sublime::ToolDocument *doc = d->factoryDocuments[factory]; ///@todo adymo: on document deletion all its views shall be also deleted foreach (Sublime::View *view, doc->views()) { foreach (Sublime::Area *area, allAreas()) if (area->removeToolView(view)) view->deleteLater(); } d->factoryDocuments.remove(factory); delete doc; } Sublime::Area *UiController::activeArea() { Sublime::MainWindow *m = activeSublimeWindow(); if (m) return activeSublimeWindow()->area(); return 0; } Sublime::MainWindow *UiController::activeSublimeWindow() { return d->activeSublimeWindow; } MainWindow *UiController::defaultMainWindow() { return d->defaultMainWindow; } void UiController::initialize() { defaultMainWindow()->initialize(); } void UiController::cleanup() { foreach (Sublime::MainWindow* w, mainWindows()) w->saveSettings(); saveAllAreas(KSharedConfig::openConfig()); } void UiController::selectNewToolViewToAdd(MainWindow *mw) { if (!mw || !mw->area()) return; QDialog *dia = new QDialog(mw); dia->setWindowTitle(i18n("Select Tool View to Add")); auto mainLayout = new QVBoxLayout(dia); NewToolViewListWidget *list = new NewToolViewListWidget(mw, dia); list->setSelectionMode(QAbstractItemView::ExtendedSelection); list->setSortingEnabled(true); for (QMap::const_iterator it = d->factoryDocuments.constBegin(); it != d->factoryDocuments.constEnd(); ++it) { ViewSelectorItem *item = new ViewSelectorItem(it.value()->title(), list); item->factory = it.key(); if (!item->factory->allowMultiple() && toolViewPresent(it.value(), mw->area())) { // Disable item if the toolview is already present. item->setFlags(item->flags() & ~Qt::ItemIsEnabled); } list->addItem(item); } list->setFocus(); connect(list, &NewToolViewListWidget::addNewToolView, this, &UiController::addNewToolView); mainLayout->addWidget(list); auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); auto okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); dia->connect(buttonBox, SIGNAL(accepted()), dia, SLOT(accept())); dia->connect(buttonBox, SIGNAL(rejected()), dia, SLOT(reject())); mainLayout->addWidget(buttonBox); if (dia->exec() == QDialog::Accepted) { foreach (QListWidgetItem* item, list->selectedItems()) { addNewToolView(mw, item); } } delete dia; } void UiController::addNewToolView(MainWindow *mw, QListWidgetItem* item) { ViewSelectorItem *current = static_cast(item); Sublime::ToolDocument *doc = d->factoryDocuments[current->factory]; Sublime::View *view = doc->createView(); mw->area()->addToolView(view, Sublime::dockAreaToPosition(current->factory->defaultPosition())); current->factory->viewCreated(view); } void UiController::showSettingsDialog() { auto editorConfigPage = new EditorConfigPage(activeMainWindow()); auto configPages = QList() << new UiPreferences(activeMainWindow()) << new PluginPreferences(activeMainWindow()) << new SourceFormatterSettings(activeMainWindow()) << new ProjectPreferences(activeMainWindow()) - << new EnvironmentPreferences(activeMainWindow()) + << new EnvironmentPreferences(QString(), activeMainWindow()) << new CCPreferences(activeMainWindow()) << new BGPreferences(activeMainWindow()) << new TemplateConfig(activeMainWindow()) << editorConfigPage; ConfigDialog cfgDlg(configPages, activeMainWindow()); auto addPluginPages = [&](IPlugin* plugin) { for (int i = 0, numPages = plugin->configPages(); i < numPages; ++i) { // insert them before the editor config page cfgDlg.addConfigPage(plugin->configPage(i, &cfgDlg), editorConfigPage); } }; for (IPlugin* plugin : ICore::self()->pluginController()->loadedPlugins()) { addPluginPages(plugin); } // TODO: only load settings if a UI related page was changed? connect(&cfgDlg, &ConfigDialog::configSaved, activeSublimeWindow(), &Sublime::MainWindow::loadSettings); // make sure that pages get added whenever a new plugin is loaded (probably from the plugin selection dialog) // removal on plugin unload is already handled in ConfigDialog connect(ICore::self()->pluginController(), &IPluginController::pluginLoaded, &cfgDlg, addPluginPages); cfgDlg.exec(); } Sublime::Controller* UiController::controller() { return this; } KParts::MainWindow *UiController::activeMainWindow() { return activeSublimeWindow(); } void UiController::saveArea(Sublime::Area * area, KConfigGroup & group) { area->save(group); if (!area->workingSet().isEmpty()) { WorkingSet* set = Core::self()->workingSetControllerInternal()->getWorkingSet(area->workingSet()); set->saveFromArea(area, area->rootIndex()); } } void UiController::loadArea(Sublime::Area * area, const KConfigGroup & group) { area->load(group); if (!area->workingSet().isEmpty()) { WorkingSet* set = Core::self()->workingSetControllerInternal()->getWorkingSet(area->workingSet()); Q_ASSERT(set->isConnected(area)); Q_UNUSED(set); } } void UiController::saveAllAreas(KSharedConfigPtr config) { KConfigGroup uiConfig(config, "User Interface"); int wc = mainWindows().size(); uiConfig.writeEntry("Main Windows Count", wc); for (int w = 0; w < wc; ++w) { KConfigGroup mainWindowConfig(&uiConfig, QString("Main Window %1").arg(w)); foreach (Sublime::Area* defaultArea, defaultAreas()) { // FIXME: using object name seems ugly. QString type = defaultArea->objectName(); Sublime::Area* area = this->area(w, type); KConfigGroup areaConfig(&mainWindowConfig, "Area " + type); areaConfig.deleteGroup(); areaConfig.writeEntry("id", type); saveArea(area, areaConfig); areaConfig.sync(); } } uiConfig.sync(); } void UiController::loadAllAreas(KSharedConfigPtr config) { KConfigGroup uiConfig(config, "User Interface"); int wc = uiConfig.readEntry("Main Windows Count", 1); /* It is expected the main windows are restored before restoring areas. */ if (wc > mainWindows().size()) wc = mainWindows().size(); QList changedAreas; /* Offer all toolviews to the default areas. */ foreach (Sublime::Area *area, defaultAreas()) { QMap::const_iterator i, e; for (i = d->factoryDocuments.constBegin(), e = d->factoryDocuments.constEnd(); i != e; ++i) { addToolViewIfWanted(i.key(), i.value(), area); } } /* Restore per-windows areas. */ for (int w = 0; w < wc; ++w) { KConfigGroup mainWindowConfig(&uiConfig, QString("Main Window %1").arg(w)); Sublime::MainWindow *mw = mainWindows()[w]; /* We loop over default areas. This means that if the config file has an area of some type that is not in default set, we'd just ignore it. I think it's fine -- the model were a given mainwindow can has it's own area types not represented in the default set is way too complex. */ foreach (Sublime::Area* defaultArea, defaultAreas()) { QString type = defaultArea->objectName(); Sublime::Area* area = this->area(w, type); KConfigGroup areaConfig(&mainWindowConfig, "Area " + type); qCDebug(SHELL) << "Trying to restore area " << type; /* This is just an easy check that a group exists, to avoid "restoring" area from empty config group, wiping away programmatically installed defaults. */ if (areaConfig.readEntry("id", "") == type) { qCDebug(SHELL) << "Restoring area " << type; loadArea(area, areaConfig); } // At this point we know which toolviews the area wants. // Tender all tool views we have. QMap::const_iterator i, e; for (i = d->factoryDocuments.constBegin(), e = d->factoryDocuments.constEnd(); i != e; ++i) { addToolViewIfWanted(i.key(), i.value(), area); } } // Force reload of the changes. showAreaInternal(mw->area(), mw); mw->enableAreaSettingsSave(); } d->areasRestored = true; } void UiController::addToolViewToDockArea(IToolViewFactory* factory, Qt::DockWidgetArea area) { addToolViewToArea(factory, d->factoryDocuments[factory], activeArea(), Sublime::dockAreaToPosition(area)); } bool UiController::toolViewPresent(Sublime::ToolDocument* doc, Sublime::Area* area) { foreach (Sublime::View *view, doc->views()) { if( area->toolViews().contains( view ) ) return true; } return false; } void UiController::addToolViewIfWanted(IToolViewFactory* factory, Sublime::ToolDocument* doc, Sublime::Area* area) { if (area->wantToolView(factory->id())) { addToolViewToArea(factory, doc, area); } } Sublime::View* UiController::addToolViewToArea(IToolViewFactory* factory, Sublime::ToolDocument* doc, Sublime::Area* area, Sublime::Position p) { Sublime::View* view = doc->createView(); area->addToolView( view, p == Sublime::AllPositions ? Sublime::dockAreaToPosition(factory->defaultPosition()) : p); connect(view, &Sublime::View::raise, this, static_cast(&UiController::raiseToolView)); factory->viewCreated(view); return view; } void UiController::registerStatus(QObject* status) { Sublime::MainWindow* w = activeSublimeWindow(); if (!w) return; MainWindow* mw = qobject_cast(w); if (!mw) return; mw->registerStatus(status); } void UiController::showErrorMessage(const QString& message, int timeout) { Sublime::MainWindow* w = activeSublimeWindow(); if (!w) return; MainWindow* mw = qobject_cast(w); if (!mw) return; QMetaObject::invokeMethod(mw, "showErrorMessage", Q_ARG(QString, message), Q_ARG(int, timeout)); } void UiController::hideAssistant() { if (d->currentShownAssistant) { d->currentShownAssistant->hide(); } } void UiController::popUpAssistant(const KDevelop::IAssistant::Ptr& assistant) { if(!assistant) return; Sublime::View* view = d->activeSublimeWindow->activeView(); if( !view ) { qCDebug(SHELL) << "no active view in mainwindow"; return; } auto editorView = qobject_cast(view->widget()); Q_ASSERT(editorView); if (editorView) { if ( !d->currentShownAssistant ) { d->currentShownAssistant = new AssistantPopup; } d->currentShownAssistant->reset(editorView, assistant); } } const QMap< IToolViewFactory*, Sublime::ToolDocument* >& UiController::factoryDocuments() const { return d->factoryDocuments; } } #include "uicontroller.moc" #include "moc_uicontroller.cpp" diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index 9903178297..9268768840 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,93 +1,91 @@ ########### next target ############### set(KDevPlatformUtil_LIB_SRCS autoorientedsplitter.cpp foregroundlock.cpp formattinghelpers.cpp richtextpushbutton.cpp kdevstringhandler.cpp focusedtreeview.cpp processlinemaker.cpp commandexecutor.cpp - environmentconfigurebutton.cpp environmentselectionwidget.cpp environmentselectionmodel.cpp environmentgrouplist.cpp activetooltip.cpp executecompositejob.cpp fileutils.cpp shellutils.cpp mimetype.cpp multilevellistview.cpp objectlist.cpp placeholderitemproxymodel.cpp projecttestjob.cpp path.cpp debug.cpp ) set (KDevPlatformUtil_LIB_UI runoptions.ui ) if(NOT WIN32) add_subdirectory(dbus_socket_transformer) endif() add_subdirectory(duchainify) add_subdirectory(tests) ki18n_wrap_ui(KDevPlatformUtil_LIB_SRCS ${KDevPlatformUtil_LIB_US}) add_library(KDevPlatformUtil ${KDevPlatformUtil_LIB_SRCS}) add_library(KDev::Util ALIAS KDevPlatformUtil) generate_export_header(KDevPlatformUtil EXPORT_FILE_NAME utilexport.h) target_link_libraries(KDevPlatformUtil LINK_PUBLIC KF5::ConfigWidgets KF5::ItemModels LINK_PRIVATE KF5::KCMUtils KDev::Interfaces ) target_include_directories(KDevPlatformUtil INTERFACE "$") set_target_properties(KDevPlatformUtil PROPERTIES VERSION ${KDEVPLATFORM_LIB_VERSION} SOVERSION ${KDEVPLATFORM_LIB_SOVERSION} EXPORT_NAME Util) install(TARGETS KDevPlatformUtil EXPORT KDevPlatformTargets ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( FILES kdevplatform_shell_environment.sh DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) install( FILES kdev_format_source DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) ########### install files ############### install( FILES autoorientedsplitter.h foregroundlock.h formattinghelpers.h richtextpushbutton.h kdevstringhandler.h ksharedobject.h focusedtreeview.h activetooltip.h processlinemaker.h commandexecutor.h - environmentconfigurebutton.h environmentselectionwidget.h environmentgrouplist.h pushvalue.h kdevvarlengtharray.h embeddedfreetree.h executecompositejob.h convenientfreelist.h spinlock.h fileutils.h mimetype.h multilevellistview.h objectlist.h placeholderitemproxymodel.h projecttestjob.h path.h ${CMAKE_CURRENT_BINARY_DIR}/utilexport.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/util COMPONENT Devel)