diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt index ce18a41b9b..485f6852d2 100644 --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -1,160 +1,162 @@ -add_subdirectory(settings) 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 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 ) 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 ) 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 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 ${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/shell/settings/CMakeLists.txt b/shell/settings/CMakeLists.txt deleted file mode 100644 index dd5b4250f6..0000000000 --- a/shell/settings/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ - -include_directories( - ${KDevPlatform_SOURCE_DIR} -) - -########### Background Parser - -set( bgsettings_cfg_SRCS - bgpreferences.cpp -) - -set( bgsettings_cfg_UI - bgsettings.ui -) - -ki18n_wrap_ui( bgsettings_cfg_SRCS ${bgsettings_cfg_UI} ) -kconfig_add_kcfg_files( bgsettings_cfg_SRCS bgconfig.kcfgc ) -add_library( kcm_kdev_bgsettings MODULE ${bgsettings_cfg_SRCS} ) -target_link_libraries( kcm_kdev_bgsettings KF5::KCMUtils KDev::Shell KDev::Language) - -########## Install TARGETS/Files - -install( TARGETS - kcm_kdev_bgsettings - DESTINATION ${PLUGIN_INSTALL_DIR}/kdevplatform/${KDEV_PLUGIN_VERSION}/kcm) -configure_file(kcm_kdev_bgsettings.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/kcm_kdev_bgsettings.desktop) -kcoreaddons_desktop_to_json(kcm_kdev_bgsettings ${CMAKE_CURRENT_BINARY_DIR}/kcm_kdev_bgsettings.desktop) - -install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/kcm_kdev_bgsettings.desktop - DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/shell/settings/bgconfig.kcfgc b/shell/settings/bgconfig.kcfgc index 8dfe6e314a..089cb48510 100644 --- a/shell/settings/bgconfig.kcfgc +++ b/shell/settings/bgconfig.kcfgc @@ -1,8 +1,8 @@ File=bgconfig.kcfg ClassName=BGSettings Singleton=true UseEnumTypes=true SetUserTexts=true ItemAccessors=true Inherits=KDevelop::SessionConfigSkeleton -IncludeFiles=sessionconfigskeleton.h +IncludeFiles=settings/sessionconfigskeleton.h diff --git a/shell/settings/bgpreferences.cpp b/shell/settings/bgpreferences.cpp index a74acf445e..8c1fa8fd22 100644 --- a/shell/settings/bgpreferences.cpp +++ b/shell/settings/bgpreferences.cpp @@ -1,96 +1,101 @@ /* KDevelop Project Settings * * Copyright 2006 Matt Rogers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 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 "bgpreferences.h" #include -#include -#include - #include #include #include "../core.h" #include "bgconfig.h" #include "ui_bgsettings.h" namespace KDevelop { -K_PLUGIN_FACTORY_WITH_JSON(BGPreferencesFactory, "kcm_kdev_bgsettings.json", registerPlugin();) - -BGPreferences::BGPreferences( QWidget *parent, const QVariantList &args ) - : KCModule( KAboutData::pluginData("kcm_kdev_bgsettings"), parent, args ) +BGPreferences::BGPreferences(QWidget* parent) + : ConfigPage(nullptr, BGSettings::self(), parent) { - QVBoxLayout * l = new QVBoxLayout( this ); QWidget* w = new QWidget; preferencesDialog = new Ui::BGSettings; preferencesDialog->setupUi( w ); l->addWidget( w ); - - addConfig( BGSettings::self(), w ); - - load(); } -void BGPreferences::load() +void BGPreferences::reset() { - KCModule::load(); + ConfigPage::reset(); // stay backwards compatible Q_ASSERT(ICore::self()->activeSession()); KConfigGroup config(ICore::self()->activeSession()->config(), "Background Parser"); KConfigGroup oldConfig(KSharedConfig::openConfig(), "Background Parser"); #define BACKWARDS_COMPATIBLE_ENTRY(entry, default) \ config.readEntry(entry, oldConfig.readEntry(entry, default)) preferencesDialog->kcfg_delay->setValue( BACKWARDS_COMPATIBLE_ENTRY("Delay", 500) ); preferencesDialog->kcfg_threads->setValue( BACKWARDS_COMPATIBLE_ENTRY("Number of Threads", 2) ); preferencesDialog->kcfg_enable->setChecked( BACKWARDS_COMPATIBLE_ENTRY("Enabled", true) ); } BGPreferences::~BGPreferences( ) { delete preferencesDialog; } -void BGPreferences::save() +void BGPreferences::apply() { - KCModule::save(); + ConfigPage::apply(); if ( preferencesDialog->kcfg_enable->isChecked() ) Core::self()->languageController()->backgroundParser()->enableProcessing(); else Core::self()->languageController()->backgroundParser()->disableProcessing(); Core::self()->languageController()->backgroundParser()->setDelay( preferencesDialog->kcfg_delay->value() ); Core::self()->languageController()->backgroundParser()->setThreadCount( preferencesDialog->kcfg_threads->value() ); } +QString BGPreferences::name() const +{ + return i18n("Background Parser"); +} + +QString BGPreferences::fullName() const +{ + return i18n("Configure Background Parser"); +} + +QIcon BGPreferences::icon() const +{ + return QIcon::fromTheme(QStringLiteral("code-context")); +} + } #include "bgpreferences.moc" diff --git a/shell/settings/bgpreferences.h b/shell/settings/bgpreferences.h index e516b6395b..036e1d79f2 100644 --- a/shell/settings/bgpreferences.h +++ b/shell/settings/bgpreferences.h @@ -1,51 +1,55 @@ /* KDevelop Project Settings * * Copyright 2006 Matt Rogers * Copyright 2007 Hamish Rodda * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 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. */ #ifndef KDEVPLATFORM_BGPREFERENCES_H #define KDEVPLATFORM_BGPREFERENCES_H -#include +#include namespace Ui { class BGSettings; } namespace KDevelop { -class BGPreferences : public KCModule +class BGPreferences : public ConfigPage { Q_OBJECT public: - BGPreferences( QWidget *parent, const QVariantList &args ); + explicit BGPreferences(QWidget* parent); virtual ~BGPreferences(); - virtual void save(); - virtual void load(); + virtual QString name() const override; + virtual QString fullName() const override; + virtual QIcon icon() const override; + + virtual void apply() override; + virtual void reset() override; private: Ui::BGSettings *preferencesDialog; }; } #endif diff --git a/shell/settings/ccpreferences.h b/shell/settings/ccpreferences.h index 721cda2d00..c5c6bd8250 100644 --- a/shell/settings/ccpreferences.h +++ b/shell/settings/ccpreferences.h @@ -1,55 +1,55 @@ /* KDevelop Project Settings * * Copyright 2006 Matt Rogers * Copyright 2007 Hamish Rodda * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 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. */ #ifndef KDEVPLATFORM_CCPREFERENCES_H #define KDEVPLATFORM_CCPREFERENCES_H #include namespace Ui { class CCSettings; } namespace KDevelop { class CCPreferences : public ConfigPage { Q_OBJECT public: - CCPreferences(QWidget* parent); + explicit CCPreferences(QWidget* parent); virtual ~CCPreferences(); virtual QString name() const override; virtual QString fullName() const override; virtual QIcon icon() const override; virtual void apply() override; void notifySettingsChanged(); private: Ui::CCSettings *preferencesDialog; }; } #endif diff --git a/shell/settings/kcm_kdev_bgsettings.desktop.cmake b/shell/settings/kcm_kdev_bgsettings.desktop.cmake deleted file mode 100644 index 374e041f35..0000000000 --- a/shell/settings/kcm_kdev_bgsettings.desktop.cmake +++ /dev/null @@ -1,82 +0,0 @@ -[Desktop Entry] -Icon=code-context -Type=Service -ServiceTypes=KCModule - -X-KDE-ModuleType=Library -X-KDE-Library=kdevplatform/@KDEV_PLUGIN_VERSION@/kcm/kcm_kdev_bgsettings -X-KDE-FactoryName=kcm_kdev_bgsettings -X-KDE-ParentApp=kdevplatform -X-KDE-ParentComponents=kdevplatform -X-KDE-CfgDlgHierarchy=GENERAL -X-KDE-Weight=4 - -Name=Background Parser -Name[bg]=Фонов анализатор на синтаксиса -Name[bs]=Pozadniski parser -Name[ca]=Analitzador en segon pla -Name[ca@valencia]=Analitzador en segon pla -Name[da]=Baggrundsfortolker -Name[de]=Hintergrund-Parser -Name[el]=Αναλυτής παρασκηνίου -Name[en_GB]=Background Parser -Name[es]=Analizador en segundo plano -Name[et]=Taustaparser -Name[fi]=Taustajäsennin -Name[fr]=Analyseur syntaxique d'arrière-plan -Name[gl]=Analizador sintáctico en segundo plano -Name[hu]=Háttérfeldolgozó -Name[it]=Analizzatore in background -Name[ja]=バックグラウンドパーサ -Name[kk]=Қатар істейтін синтаксис талдағышы -Name[nb]=Bakgrunnstolker -Name[nds]=Achtergrund-Inleser -Name[nl]=Achtergrond ontleder -Name[pl]=Przetwarzanie w tle -Name[pt]=Processamento em Segundo Plano -Name[pt_BR]=Analisador em plano de fundo -Name[ru]=Фоновый анализ кода -Name[sk]=Analyzátor na pozadí -Name[sl]=Razčlenjevalnik v ozadju -Name[sv]=Bakgrundstolk -Name[tr]=Arkaplan Ayrıştırıcı -Name[ug]=تەگلىك تەھلىل قىلغۇچ -Name[uk]=Інструмент фонової обробки -Name[x-test]=xxBackground Parserxx -Name[zh_CN]=后台解析 -Name[zh_TW]=背景剖析器 -Comment=Configure Background Parser -Comment[bg]=Настройки на фонов анализатор на синтаксиса -Comment[bs]=Konfiguriši kontroler pozadine -Comment[ca]=Configura l'analitzador en segon pla -Comment[ca@valencia]=Configura l'analitzador en segon pla -Comment[da]=Indstil baggrundsfortolker -Comment[de]=Hintergrund-Parser einrichten -Comment[el]=Διαμόρφωση συντακτικού αναλυτή παρασκηνίου -Comment[en_GB]=Configure Background Parser -Comment[es]=Configurar el analizador en segundo plano -Comment[et]=Taustaparseri seadistamine -Comment[fi]=Taustajäsentimen asetukset -Comment[fr]=Configurer l'analyseur syntaxique d'arrière-plan -Comment[gl]=Configurar o analizador en segundo plano -Comment[hu]=Háttérfeldolgozó beállítása -Comment[it]=Configura l'analizzatore in background -Comment[ja]=バックグラウンドパーサを設定します -Comment[kk]=Қатар істейтін талдағышын баптау -Comment[nb]=Sett opp bakgrunnstolker -Comment[nds]=Achtergrund-Inleser instellen -Comment[nl]=Achtergrondontleder instellen -Comment[pl]=Ustawienia analizatora składni w tle -Comment[pt]=Configurar o Processamento em Segundo Plano -Comment[pt_BR]=Configurar o processamento em segundo plano -Comment[ru]=Настройка фонового анализа кода -Comment[sk]=Nastaviť analyzátor na pozadí -Comment[sl]=Nastavite razhroščevalnik v ozadju -Comment[sv]=Anpassa bakgrundstolk -Comment[tr]=Arkaplan Ayrıştırıcısını Yapılandır -Comment[ug]=تەگلىك تەھلىل قىلغۇچنى سەپلەش -Comment[uk]=Налаштування інструмента фонової обробки -Comment[x-test]=xxConfigure Background Parserxx -Comment[zh_CN]=配置后台解析 -Comment[zh_TW]=設定背景剖析器 - diff --git a/shell/settings/projectpreferences.h b/shell/settings/projectpreferences.h index d30e26bad4..715bf7a72e 100644 --- a/shell/settings/projectpreferences.h +++ b/shell/settings/projectpreferences.h @@ -1,56 +1,56 @@ /* KDevelop Project Settings * * Copyright 2006 Matt Rogers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 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. */ #ifndef KDEVPLATFORM_PROJECTPREFERENCES_H #define KDEVPLATFORM_PROJECTPREFERENCES_H #include namespace Ui { class ProjectSettings; } namespace KDevelop { class ProjectPreferences : public ConfigPage { Q_OBJECT public: - ProjectPreferences(QWidget *parent); + explicit ProjectPreferences(QWidget *parent); virtual ~ProjectPreferences(); virtual QString name() const override; virtual QString fullName() const override; virtual QIcon icon() const override; virtual void apply() override; private slots: void slotSettingsChanged(); private: Ui::ProjectSettings *preferencesDialog; }; } #endif diff --git a/shell/uicontroller.cpp b/shell/uicontroller.cpp index e6d1ac3f3f..041092d707 100644 --- a/shell/uicontroller.cpp +++ b/shell/uicontroller.cpp @@ -1,720 +1,722 @@ /*************************************************************************** * 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" 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 CCPreferences(activeMainWindow()) + << new BGPreferences(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"