File indexing completed on 2024-04-14 15:17:33

0001 /****************************************************************************************
0002   Copyright (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
0003             (C) 2007-2022 by Michel Ludwig (michel.ludwig@kdemail.net)
0004             (C) 2007 Holger Danielsson (holger.danielsson@versanet.de)
0005             (C) 2009 Thomas Braun (thomas.braun@virtuell-zuhause.de)
0006  ****************************************************************************************/
0007 
0008 /***************************************************************************
0009  *                                                                         *
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  ***************************************************************************/
0016 
0017 // 2007-03-12 dani
0018 //  - use KileDocument::Extensions
0019 
0020 #include "kile.h"
0021 
0022 #include <config.h>
0023 
0024 #include <QAction>
0025 #include <QHideEvent>
0026 #include <QMenuBar>
0027 #include <QPointer>
0028 #include <QShowEvent>
0029 #include <QSplashScreen>
0030 #include <QStandardPaths>
0031 #include <QStatusBar>
0032 #include <QXmlStreamWriter>
0033 
0034 #include <KAboutApplicationDialog>
0035 #include <KAboutData>
0036 #include <KActionMenu>
0037 #include <KConfigGroup>
0038 #include <KEditToolBar>
0039 #include <KHelpMenu>
0040 #include <KIconLoader>
0041 #include <KIO/DesktopExecParser>
0042 #include <KLocalizedString>
0043 #include <KMessageBox>
0044 #include <KRecentFilesAction>
0045 #include <KShortcutsDialog>
0046 #include <KToggleAction>
0047 #include <KXMLGUIFactory>
0048 #include <KXmlGuiWindow>
0049 #include <KSelectAction>
0050 #include <KWindowSystem>
0051 #if __has_include(<kx11extras.h>)
0052 #include <kx11extras.h>
0053 #endif
0054 
0055 #include "abbreviationmanager.h"
0056 #include "configurationmanager.h"
0057 #include "documentinfo.h"
0058 #include "errorhandler.h"
0059 #include "kileactions.h"
0060 #include "kiledebug.h"
0061 #include "kilestdactions.h"
0062 #include "widgets/statusbar.h"
0063 #include "dialogs/configurationdialog.h"
0064 #include "kileproject.h"
0065 #include "widgets/projectview.h"
0066 #include "dialogs/projectdialogs.h"
0067 #include "kilelyxserver.h"
0068 #include "dialogs/findfilesdialog.h"
0069 #include "kiletool_enums.h"
0070 #include "kiletool.h"
0071 #include "kiletoolmanager.h"
0072 #include "kilestdtools.h"
0073 #include "widgets/outputview.h"
0074 #include "widgets/konsolewidget.h"
0075 #include "dialogs/quickdocumentdialog.h"
0076 #include "dialogs/tabbingdialog.h"
0077 #include "widgets/structurewidget.h"
0078 #include "convert.h"
0079 #include "dialogs/includegraphicsdialog.h"
0080 #include "kiledocmanager.h"
0081 #include "kileversion.h"
0082 #include "kileviewmanager.h"
0083 #include "kileconfig.h"
0084 #include "dialogs/configcheckerdialog.h"
0085 #include "widgets/sidebar.h"
0086 #include "dialogs/floatdialog.h"
0087 #include "dialogs/mathenvironmentdialog.h"
0088 #include "dialogs/tabular/newtabulardialog.h"
0089 #include "dialogs/postscriptdialog.h"
0090 #include "dialogs/pdf-wizard/pdfdialog.h"
0091 #include "latexcmd.h"
0092 #include "mainadaptor.h"
0093 #include "dialogs/statisticsdialog.h"
0094 #include "widgets/scriptsmanagementwidget.h"
0095 #include "scriptmanager.h"
0096 #include "widgets/previewwidget.h"
0097 #include "symbolviewclasses.h"
0098 #include "livepreview.h"
0099 #include "parser/parsermanager.h"
0100 #include "scripting/script.h"
0101 
0102 #include "dialogs/usermenu/usermenudialog.h"
0103 #include "usermenu/usermenudata.h"
0104 #include "usermenu/usermenu.h"
0105 #include "utilities.h"
0106 
0107 #define LOG_TAB     0
0108 #define OUTPUT_TAB  1
0109 #define KONSOLE_TAB 2
0110 #define PREVIEW_TAB 3
0111 
0112 /*
0113  * Class Kile.
0114  */
0115 
0116 Kile::Kile(bool allowRestore, QWidget *parent)
0117     : KParts::MainWindow(),
0118       KileInfo(this),
0119       m_toolsToolBar(Q_NULLPTR),       // we have to set all of these to null as the constructor
0120       m_userHelpActionMenu(Q_NULLPTR), // might return early
0121       m_bibTagSettings(Q_NULLPTR),
0122       m_compilerActions(Q_NULLPTR),
0123       m_viewActions(Q_NULLPTR),
0124       m_convertActions(Q_NULLPTR),
0125       m_quickActions(Q_NULLPTR),
0126       m_bibTagActionMenu(Q_NULLPTR),
0127       ModeAction(Q_NULLPTR),
0128       WatchFileAction(Q_NULLPTR),
0129       m_actionMessageView(Q_NULLPTR),
0130       m_actionShowMenuBar(Q_NULLPTR),
0131       m_actRecentFiles(Q_NULLPTR),
0132       m_pFullScreen(Q_NULLPTR),
0133       m_sideBar(Q_NULLPTR),
0134       m_kileAbbrevView(Q_NULLPTR),
0135       m_topWidgetStack(Q_NULLPTR),
0136       m_horizontalSplitter(Q_NULLPTR),
0137       m_verticalSplitter(Q_NULLPTR),
0138       m_toolBox(Q_NULLPTR),
0139       m_commandViewToolBox(Q_NULLPTR),
0140       m_symbolViewMFUS(Q_NULLPTR),
0141       m_symbolViewRelation(Q_NULLPTR),
0142       m_symbolViewArrows(Q_NULLPTR),
0143       m_symbolViewMiscMath(Q_NULLPTR),
0144       m_symbolViewMiscText(Q_NULLPTR),
0145       m_symbolViewOperators(Q_NULLPTR),
0146       m_symbolViewUser(Q_NULLPTR),
0147       m_symbolViewDelimiters(Q_NULLPTR),
0148       m_symbolViewGreek(Q_NULLPTR),
0149       m_symbolViewSpecial(Q_NULLPTR),
0150       m_symbolViewCyrillic(Q_NULLPTR),
0151       m_commandView(Q_NULLPTR),
0152       m_latexOutputErrorToolBar(Q_NULLPTR),
0153       m_buildMenuTopLevel(Q_NULLPTR),
0154       m_buildMenuCompile(Q_NULLPTR),
0155       m_buildMenuConvert(Q_NULLPTR),
0156       m_buildMenuViewer(Q_NULLPTR),
0157       m_buildMenuOther(Q_NULLPTR),
0158       m_buildMenuQuickPreview(Q_NULLPTR),
0159       m_actRecentProjects(Q_NULLPTR),
0160       m_lyxserver(Q_NULLPTR)
0161 {
0162     setObjectName("Kile");
0163 
0164     m_config = KSharedConfig::openConfig();
0165 
0166     setStandardToolBarMenuEnabled(true);
0167 
0168     m_singlemode = true;
0169 
0170     m_viewManager= new KileView::Manager(this, actionCollection(), parent, "KileView::Manager");
0171     viewManager()->setClient(this);
0172 
0173     // fail gracefully if we cannot instantiate Okular part correctly
0174     if(!m_viewManager->viewerPart()) {
0175         return;
0176     }
0177 
0178     QSplashScreen splashScreen(QPixmap(KileUtilities::locate(QStandardPaths::AppDataLocation, "pics/kile_splash.png")), Qt::WindowStaysOnTopHint);
0179     if(KileConfig::showSplashScreen()) {
0180         splashScreen.show();
0181         qApp->processEvents();
0182     }
0183 
0184     m_codeCompletionManager = new KileCodeCompletion::Manager(this, parent);
0185 
0186     // process events for correctly displaying the splash screen
0187     qApp->processEvents();
0188 
0189     m_latexCommands = new KileDocument::LatexCommands(m_config.data(), this);  // at first (dani)
0190     m_edit = new KileDocument::EditorExtension(this);
0191     m_help = new KileHelp::Help(m_edit, this);
0192     m_errorHandler = new KileErrorHandler(this, this, actionCollection());
0193     m_quickPreview = new KileTool::QuickPreview(this);
0194     m_extensions = new KileDocument::Extensions();
0195     m_jScriptManager = new KileScript::Manager(this, m_config.data(), actionCollection(), parent, "KileScript::Manager");
0196 
0197     // do initializations first
0198     m_bWatchFile = false;
0199 
0200     setStatusBar(new KileWidget::StatusBar(m_errorHandler, parent));
0201 
0202     // process events for correctly displaying the splash screen
0203     qApp->processEvents();
0204 
0205     connect(viewManager(), &KileView::Manager::currentViewChanged, this, &Kile::newCaption);
0206     connect(viewManager(), &KileView::Manager::currentViewChanged, this, [this](QWidget* view) { activateView(view); });
0207     connect(viewManager(), &KileView::Manager::currentViewChanged, this, &Kile::updateModeStatus);
0208     connect(viewManager(), &KileView::Manager::updateCaption, this, &Kile::newCaption);
0209     connect(viewManager(), &KileView::Manager::updateModeStatus, this, &Kile::updateModeStatus);
0210     connect(viewManager(), &KileView::Manager::cursorPositionChanged, this, &Kile::updateStatusBarCursorPosition);
0211     connect(viewManager(), &KileView::Manager::viewModeChanged,
0212             this, &Kile::updateStatusBarViewMode);
0213     connect(viewManager(), &KileView::Manager::informationMessage,
0214             this, &Kile::updateStatusBarInformationMessage);
0215     connect(viewManager(), &KileView::Manager::selectionChanged,
0216             this, &Kile::updateStatusBarSelection);
0217 
0218     connect(docManager(), &KileDocument::Manager::documentNameChanged, this, &Kile::newCaption);
0219     connect(docManager(), &KileDocument::Manager::documentUrlChanged, this, &Kile::newCaption);
0220     connect(docManager(), &KileDocument::Manager::documentReadWriteStateChanged, this, &Kile::newCaption);
0221 
0222     m_topWidgetStack = new QStackedWidget();
0223     m_topWidgetStack->setFocusPolicy(Qt::NoFocus);
0224 
0225     m_horizontalSplitter = new QSplitter(Qt::Horizontal);
0226 
0227     setupSideBar();
0228     m_horizontalSplitter->addWidget(m_sideBar);
0229 
0230     m_verticalSplitter = new QSplitter(Qt::Vertical);
0231     m_horizontalSplitter->addWidget(m_verticalSplitter);
0232     viewManager()->createTabs(m_verticalSplitter);
0233 
0234     connect(viewManager(), &KileView::Manager::activateView, this, &Kile::activateView);
0235     connect(viewManager(), &KileView::Manager::startQuickPreview, this, &Kile::slotQuickPreview);
0236 
0237     connect(parserManager(), &KileParser::Manager::documentParsingStarted, this, &Kile::handleDocumentParsingStarted);
0238     connect(parserManager(), &KileParser::Manager::documentParsingComplete, this, &Kile::handleDocumentParsingComplete);
0239 
0240     // process events for correctly displaying the splash screen
0241     qApp->processEvents();
0242 
0243     setupBottomBar();
0244     m_verticalSplitter->addWidget(m_bottomBar);
0245     m_topWidgetStack->addWidget(m_horizontalSplitter);
0246     setCentralWidget(m_topWidgetStack);
0247 
0248     // Parser manager and view manager must be created before the tool manager!
0249     m_manager = new KileTool::Manager(this, m_config.data(), m_outputWidget, m_topWidgetStack, 10000, actionCollection()); //FIXME make timeout configurable
0250     connect(m_manager, &KileTool::Manager::jumpToFirstError, m_errorHandler, &KileErrorHandler::jumpToFirstError);
0251     connect(m_manager, &KileTool::Manager::previewDone, this, &Kile::focusPreview);
0252 
0253     m_latexOutputErrorToolBar->addAction(actionCollection()->action(QLatin1String("Stop")));
0254     errorHandler()->setErrorHandlerToolBar(m_latexOutputErrorToolBar); // add the remaining actions to m_latexOutputErrorToolBar
0255 
0256     m_bottomBar->addExtraWidget(viewManager()->getViewerControlToolBar());
0257 
0258     m_livePreviewManager = new KileTool::LivePreviewManager(this, actionCollection());
0259     connect(this, &Kile::masterDocumentChanged, m_livePreviewManager, &KileTool::LivePreviewManager::handleMasterDocumentChanged);
0260 
0261     m_toolFactory = new KileTool::Factory(m_manager, m_config.data(), actionCollection());
0262     m_manager->setFactory(m_toolFactory);
0263 
0264     setupGraphicTools();
0265     setupPreviewTools();
0266     setupActions();
0267 
0268     initSelectActions();
0269 
0270     newCaption();
0271 
0272     m_help->setUserhelp(m_manager, m_userHelpActionMenu);     // kile user help (dani)
0273 
0274     // process events for correctly displaying the splash screen
0275     qApp->processEvents();
0276     connect(docManager(), &KileDocument::Manager::updateModeStatus, this, &Kile::updateModeStatus);
0277     connect(docManager(), &KileDocument::Manager::updateStructure, viewManager(), &KileView::Manager::updateStructure);
0278     connect(docManager(), &KileDocument::Manager::closingDocument,
0279             m_kwStructure, &KileWidget::StructureWidget::closeDocumentInfo);
0280     connect(docManager(), &KileDocument::Manager::documentInfoCreated,
0281             m_kwStructure, &KileWidget::StructureWidget::addDocumentInfo);
0282     connect(docManager(), &KileDocument::Manager::updateReferences,
0283             m_kwStructure, &KileWidget::StructureWidget::updateReferences);
0284     connect(docManager(), &KileDocument::Manager::documentModificationStatusChanged,
0285             viewManager(), &KileView::Manager::reflectDocumentModificationStatus);
0286 
0287     if(KileConfig::rCVersion() < 8) {
0288         transformOldUserSettings();
0289         transformOldUserTags();
0290 
0291         // before Kile 2.1 shortcuts were stored in a "Shortcuts" group inside
0292         // Kile's configuration file, but this led to problems with the way of how shortcuts
0293         // are generally stored in kdelibs; we now delete the "Shortcuts" group if it
0294         // still present in Kile's configuration file.
0295         if(m_config->hasGroup("Shortcuts")) {
0296             KConfigGroup shortcutGroup = m_config->group("Shortcuts");
0297             actionCollection()->readSettings(&shortcutGroup);
0298             m_config->deleteGroup("Shortcuts");
0299         }
0300 
0301         if(m_config->hasGroup("Complete")) {
0302             KConfigGroup completionGroup = m_config->group("Complete");
0303             completionGroup.deleteEntry("maxCwlFiles"); // in Kile 3.0 the UI has been changed so that this setting is no longer
0304             // needed
0305         }
0306     }
0307     if(KileConfig::rCVersion() < 9) {
0308         // in Kile 3.0 beta 4, the user help was updated, some old config settings were no longer needed
0309         if(m_config->hasGroup("Help")) {
0310             KConfigGroup helpGroup = m_config->group("Help");
0311             helpGroup.deleteEntry("location");
0312             helpGroup.deleteEntry("texrefs");
0313             helpGroup.deleteEntry("external");
0314             helpGroup.deleteEntry("embedded");
0315         }
0316     }
0317 
0318     readGUISettings();
0319     readRecentFileSettings();
0320     readConfig();
0321 
0322     createToolActions(); // this creates the actions for the tools and user tags, which is required before 'activePartGUI' is called
0323 
0324     setupGUI(KXmlGuiWindow::StatusBar | KXmlGuiWindow::Save, "kileui.rc");
0325     createShellGUI(true); // do not call guiFactory()->refreshActionProperties() after this! (bug 314580)
0326 
0327     m_userMenu = new KileMenu::UserMenu(this, this);
0328     connect(m_userMenu, &KileMenu::UserMenu::sendText, this, static_cast<void (Kile::*)(const QString &)>(&Kile::insertText));
0329     connect(m_userMenu, &KileMenu::UserMenu::updateStatus, this, &Kile::slotUpdateUserMenuStatus);
0330 
0331     updateUserDefinedMenus();
0332 
0333     // we can only do this here after the main GUI has been set up
0334     {
0335         guiFactory()->addClient(viewManager()->viewerPart());
0336 
0337         QMenu *documentViewerMenu = static_cast<QMenu*>(guiFactory()->container("menu_document_viewer", this));
0338         QMenu *popup = static_cast<QMenu*>(guiFactory()->container("menu_okular_part_viewer", viewManager()->viewerPart()));
0339         if(documentViewerMenu && popup) {
0340             // we populate our menu with the actions from the part's menu
0341             documentViewerMenu->addActions(popup->actions());
0342             documentViewerMenu->setEnabled(false);
0343             connect(viewManager()->viewerPart(), SIGNAL(viewerMenuStateChange(bool)), documentViewerMenu, SLOT(setEnabled(bool)));
0344         }
0345         else {
0346             if(documentViewerMenu) {
0347                 documentViewerMenu->setVisible(false);
0348             }
0349             delete popup;
0350         }
0351     }
0352 
0353     resize(KileConfig::mainwindowWidth(), KileConfig::mainwindowHeight());
0354     applyMainWindowSettings(m_config->group("KileMainWindow"));
0355 
0356     restoreLastSelectedAction(); // don't call this inside 'setupTools' as it is not compatible with KParts switching!
0357     QList<int> sizes;
0358     int verSplitTop = KileConfig::verticalSplitterTop();
0359     int verSplitBottom = KileConfig::verticalSplitterBottom();
0360     sizes << verSplitTop << verSplitBottom;
0361     m_verticalSplitter->setSizes(sizes);
0362     sizes.clear();
0363     int horSplitLeft = KileConfig::horizontalSplitterLeft();
0364     int horSplitRight = KileConfig::horizontalSplitterRight();
0365     if(horSplitLeft <= 0 && horSplitRight <= 0) { // compute default values
0366         horSplitLeft = m_sideBar->width();
0367         horSplitRight = width() / 2; // leave some room for the viewer part
0368     }
0369     // the size of the third widget is computed from the sizes of the two other widgets
0370     sizes << horSplitLeft << horSplitRight << width() - (horSplitLeft + horSplitRight);
0371     m_horizontalSplitter->setSizes(sizes);
0372 
0373     show();
0374     if(KileConfig::showSplashScreen()) {
0375         splashScreen.finish(this);
0376     }
0377 
0378     // Due to 'processEvents' being called earlier we only create the DBUS adaptor and
0379     // the LyX server when all of Kile's structures have been set up.
0380     // publish the D-Bus interfaces
0381     new MainAdaptor(this);
0382     QDBusConnection dbus = QDBusConnection::sessionBus();
0383     dbus.registerObject("/main", this);
0384     dbus.registerService("net.sourceforge.kile"); // register under a constant name
0385 
0386     m_lyxserver = new KileLyxServer(KileConfig::runLyxServer());
0387     connect(m_lyxserver, &KileLyxServer::insert, this, [this](const KileAction::TagData &data) { insertTag(data); });
0388 
0389     if(m_listUserTools.count() > 0) {
0390         KMessageBox::information(0, i18n("You have defined some tools in the User menu. From now on these tools will be available from the Build->Other menu and can be configured in the configuration dialog (go to the Settings menu and choose Configure Kile). This has some advantages; your own tools can now be used in a QuickBuild command if you wish."), i18n("User Tools Detected"));
0391         m_listUserTools.clear();
0392     }
0393 
0394     if(KileConfig::rCVersion() < 8) {
0395         // if KileConfig::rCVersion() <= 0, then 'kilerc' is (most likely) fresh or empty,
0396         // otherwise, we have to ask the user if she wants to reset the tools
0397         if ((KileConfig::rCVersion() <= 0) ||
0398             (KMessageBox::questionTwoActions(mainWindow(),
0399                                              i18n("<p>The tool settings need to be reset for this version of Kile to function properly.<br/>"
0400                                                   "This will overwrite any changes you have made.</p>"
0401                                                   "<p>Do you want to reset the tools now?</p>"),
0402                                              i18n("Tools need to be reset"),
0403                                              KStandardGuiItem::reset(), KStandardGuiItem::cancel())  == KMessageBox::PrimaryAction)) {
0404             m_toolFactory->resetToolConfigurations();
0405         }
0406     }
0407 
0408     restoreFilesAndProjects(allowRestore);
0409     initMenu();
0410     updateModeStatus();
0411 
0412     // finally init all actions for the ScriptManager
0413     m_jScriptManager->initScriptActions();
0414 
0415     setUpdatesEnabled(false);
0416     setAutoSaveSettings(QLatin1String("KileMainWindow"),true);
0417 
0418     m_userMenu->refreshActionProperties();
0419     setUpdatesEnabled(true);
0420 
0421     // finally, we check whether the system check assistant should be run, which is important for
0422     // version 3.0 regarding the newly introduced live preview feature
0423     const QString& lastVersionRunFor = KileConfig::systemCheckLastVersionRunForAtStartUp();
0424     if(lastVersionRunFor.isEmpty() || compareVersionStrings(lastVersionRunFor, "2.9.91") < 0) {
0425 #ifdef Q_OS_WIN
0426         // work around the problem that Sonnet's language auto-detection feature doesn't work
0427         // together with KatePart (as of 08 November 2019)
0428         QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet"));
0429         settings.setValue(QStringLiteral("autodetectLanguage"), false);
0430 #endif
0431         slotPerformCheck();
0432         KileConfig::setSystemCheckLastVersionRunForAtStartUp(kileFullVersion);
0433     }
0434 
0435     if(m_livePreviewManager) {
0436         m_livePreviewManager->buildLivePreviewMenu(m_config.data());
0437         m_livePreviewManager->disableBootUpMode();
0438     }
0439 
0440     menuBar()->show();
0441 }
0442 
0443 Kile::~Kile()
0444 {
0445     KILE_DEBUG_MAIN << "cleaning up..." << Qt::endl;
0446 
0447     guiFactory()->removeClient(viewManager()->viewerPart());
0448 
0449     delete m_userMenu;
0450     delete m_livePreviewManager;
0451     delete m_toolFactory;
0452     delete m_manager;
0453     delete m_quickPreview;
0454     delete m_edit;
0455     delete m_help;
0456     delete m_lyxserver; //QObject without parent, have to delete it ourselves
0457     delete m_latexCommands;
0458     delete m_extensions;
0459     delete m_viewManager;
0460 }
0461 
0462 // currently not usable due to https://bugs.kde.org/show_bug.cgi?id=194732
0463 // void Kile::plugActionList(const QString& name, const QList<QAction*>& actionList)
0464 // {
0465 //  plugActionList(name, actionList);
0466 // }
0467 //
0468 // void Kile::unplugActionList(const QString& name)
0469 // {
0470 //  unplugActionList(name);
0471 // }
0472 
0473 void Kile::setupSideBar()
0474 {
0475     m_sideBar = new KileWidget::SideBar(m_horizontalSplitter);
0476 
0477     m_fileBrowserWidget = new KileWidget::FileBrowserWidget(m_extensions, m_sideBar);
0478     m_sideBar->addPage(m_fileBrowserWidget, QIcon::fromTheme("document-open"), i18n("Open File"));
0479     connect(m_fileBrowserWidget, &KileWidget::FileBrowserWidget::fileSelected,
0480             docManager(), [this](const KFileItem& item) { docManager()->fileSelected(item); });
0481 
0482     setupProjectView();
0483     setupStructureView();
0484     setupSymbolViews();
0485     setupScriptsManagementView();
0486     setupCommandViewToolbox();
0487     setupAbbreviationView();
0488 
0489     m_sideBar->switchToTab(KileConfig::selectedLeftView());
0490     m_sideBar->setVisible(KileConfig::sideBar());
0491     m_sideBar->setDirectionalSize(KileConfig::sideBarSize());
0492 }
0493 
0494 void Kile::setupProjectView()
0495 {
0496     KileWidget::ProjectView *projectView = new KileWidget::ProjectView(m_sideBar, this);
0497 //  viewManager()->setProjectView(projectView);
0498     m_sideBar->addPage(projectView, QIcon::fromTheme("relation"), i18n("Files and Projects"));
0499     connect(projectView, QOverload<const KileProjectItem*>::of(&KileWidget::ProjectView::fileSelected),
0500             docManager(), QOverload<const KileProjectItem*>::of(&KileDocument::Manager::fileSelected));
0501 
0502     connect(projectView, QOverload<const QUrl&>::of(&KileWidget::ProjectView::fileSelected),
0503             docManager(), QOverload<const QUrl&>::of(&KileDocument::Manager::fileSelected));
0504 
0505     connect(projectView, &KileWidget::ProjectView::closeURL,
0506             docManager(), [this](const QUrl& url) { docManager()->fileClose(url); });
0507 
0508     connect(projectView, &KileWidget::ProjectView::closeProject,
0509             docManager(), [this](const QUrl& url) { docManager()->projectClose(url); });
0510 
0511     connect(projectView, &KileWidget::ProjectView::projectOptions,
0512             docManager(), [this](const QUrl& url) { docManager()->projectOptions(url); });
0513 
0514     connect(projectView, &KileWidget::ProjectView::projectArchive,
0515             this, [this](const QUrl& url) { runArchiveTool(url); });
0516 
0517     connect(projectView, &KileWidget::ProjectView::removeFromProject,
0518             docManager(), &KileDocument::Manager::removeFromProject);
0519 
0520     connect(projectView, &KileWidget::ProjectView::addFiles,
0521             docManager(), [this](const QUrl &url) { docManager()->projectAddFiles(url); });
0522 
0523     connect(projectView, &KileWidget::ProjectView::openAllFiles,
0524             docManager(), [this](const QUrl &url) { docManager()->projectOpenAllFiles(url); });
0525 
0526     connect(projectView, &KileWidget::ProjectView::toggleArchive,
0527             docManager(), &KileDocument::Manager::toggleArchive);
0528 
0529     connect(projectView, &KileWidget::ProjectView::addToProject,
0530             docManager(), [this](const QUrl &url) { docManager()->addToProject(url); });
0531 
0532     connect(projectView, &KileWidget::ProjectView::saveURL,
0533             docManager(), &KileDocument::Manager::saveURL);
0534 
0535     connect(projectView, &KileWidget::ProjectView::buildProjectTree,
0536             docManager(), [this](const QUrl &url) { docManager()->buildProjectTree(url); });
0537 
0538     connect(docManager(), &KileDocument::Manager::projectTreeChanged,
0539             projectView, &KileWidget::ProjectView::refreshProjectTree);
0540 
0541     connect(docManager(), QOverload<const QUrl&>::of(&KileDocument::Manager::removeFromProjectView),
0542             projectView, QOverload<const QUrl&>::of(&KileWidget::ProjectView::remove));
0543 
0544     connect(docManager(), QOverload<const KileProject*>::of(&KileDocument::Manager::removeFromProjectView),
0545             projectView, QOverload<const KileProject*>::of(&KileWidget::ProjectView::remove));
0546 
0547     connect(docManager(), QOverload<const QUrl&>::of(&KileDocument::Manager::addToProjectView),
0548             projectView, QOverload<const QUrl&>::of(&KileWidget::ProjectView::add));
0549 
0550     connect(docManager(), QOverload<const KileProject*>::of(&KileDocument::Manager::addToProjectView),
0551             projectView, QOverload<const KileProject*>::of(&KileWidget::ProjectView::add));
0552 
0553     connect(docManager(), &KileDocument::Manager::removeItemFromProjectView,
0554             projectView, &KileWidget::ProjectView::removeItem);
0555 
0556     connect(docManager(), QOverload<KileProjectItem*>::of(&KileDocument::Manager::addToProjectView),
0557             projectView, [projectView](KileProjectItem *item) { projectView->add(item); });
0558 }
0559 
0560 void Kile::setupStructureView()
0561 {
0562     m_kwStructure = new KileWidget::StructureWidget(this, m_sideBar);
0563     m_sideBar->addPage(m_kwStructure, QIcon::fromTheme("view-list-tree"), i18n("Structure"));
0564     m_kwStructure->setFocusPolicy(Qt::ClickFocus);
0565     connect(configurationManager(), &KileConfiguration::Manager::configChanged,
0566             m_kwStructure, &KileWidget::StructureWidget::configChanged);
0567 
0568     connect(m_kwStructure, &KileWidget::StructureWidget::setCursor, this, &Kile::setCursor);
0569 
0570     connect(m_kwStructure, &KileWidget::StructureWidget::fileOpen,
0571             docManager(), [this](const QUrl &url, const QString &encoding) { docManager()->fileOpen(url, encoding); });
0572 
0573     connect(m_kwStructure, &KileWidget::StructureWidget::fileNew,
0574             docManager(), [this](const QUrl &url) { docManager()->fileNew(url); });
0575 
0576     connect(m_kwStructure, &KileWidget::StructureWidget::sendText,
0577             this, [this](const QString &text) { insertText(text); });
0578 
0579     connect(m_kwStructure, &KileWidget::StructureWidget::sectioningPopup,
0580             m_edit, &KileDocument::EditorExtension::sectioningCommand);
0581 }
0582 
0583 void Kile::setupScriptsManagementView()
0584 {
0585     m_scriptsManagementWidget = new KileWidget::ScriptsManagement(this, m_sideBar);
0586     m_sideBar->addPage(m_scriptsManagementWidget, QIcon::fromTheme("preferences-plugin-script"), i18n("Scripts"));
0587 }
0588 
0589 void Kile::enableSymbolViewMFUS()
0590 {
0591     m_toolBox->setItemEnabled(m_toolBox->indexOf(m_symbolViewMFUS),true);
0592 
0593     connect(m_symbolViewRelation, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0594     connect(m_symbolViewOperators, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0595     connect(m_symbolViewArrows, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0596     connect(m_symbolViewMiscMath, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0597     connect(m_symbolViewMiscText, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0598     connect(m_symbolViewDelimiters, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0599     connect(m_symbolViewGreek, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0600     connect(m_symbolViewSpecial, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0601     connect(m_symbolViewCyrillic, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0602     connect(m_symbolViewUser, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0603 }
0604 
0605 void Kile::disableSymbolViewMFUS()
0606 {
0607     m_toolBox->setItemEnabled(m_toolBox->indexOf(m_symbolViewMFUS),false);
0608     m_toolBox->setItemToolTip(m_toolBox->indexOf(m_symbolViewMFUS),QString());
0609 
0610     disconnect(m_symbolViewRelation, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0611     disconnect(m_symbolViewOperators, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0612     disconnect(m_symbolViewArrows, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0613     disconnect(m_symbolViewMiscMath, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0614     disconnect(m_symbolViewMiscText, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0615     disconnect(m_symbolViewDelimiters, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0616     disconnect(m_symbolViewGreek, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0617     disconnect(m_symbolViewSpecial, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0618     disconnect(m_symbolViewCyrillic, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0619     disconnect(m_symbolViewUser, &KileWidget::SymbolView::addToList, m_symbolViewMFUS, &KileWidget::SymbolView::slotAddToList);
0620 }
0621 
0622 void Kile::setupSymbolViews()
0623 {
0624     m_toolBox = new QToolBox(m_sideBar);
0625     m_sideBar->addPage(m_toolBox,QIcon::fromTheme("math0"),i18n("Symbols"));
0626 
0627     m_symbolViewMFUS = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::MFUS);
0628     m_toolBox->addItem(m_symbolViewMFUS,i18n("Most Frequently Used"));
0629     m_toolBox->setItemEnabled(m_toolBox->indexOf(m_symbolViewMFUS),false);
0630     connect(m_symbolViewMFUS, &KileWidget::SymbolView::insertText,
0631             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0632 
0633     m_symbolViewRelation = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Relation);
0634     m_toolBox->addItem(m_symbolViewRelation,QIcon::fromTheme("math1"),i18n("Relation"));
0635     connect(m_symbolViewRelation, &KileWidget::SymbolView::insertText,
0636             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0637 
0638     m_symbolViewOperators = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Operator);
0639     m_toolBox->addItem(m_symbolViewOperators,QIcon::fromTheme("math2"),i18n("Operators"));
0640     connect(m_symbolViewOperators, &KileWidget::SymbolView::insertText,
0641             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0642 
0643     m_symbolViewArrows = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Arrow);
0644     m_toolBox->addItem(m_symbolViewArrows,QIcon::fromTheme("math3"),i18n("Arrows"));
0645     connect(m_symbolViewArrows, &KileWidget::SymbolView::insertText,
0646             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0647 
0648     m_symbolViewMiscMath = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::MiscMath);
0649     m_toolBox->addItem(m_symbolViewMiscMath,QIcon::fromTheme("math4"),i18n("Miscellaneous Math"));
0650     connect(m_symbolViewMiscMath, &KileWidget::SymbolView::insertText,
0651             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0652 
0653     m_symbolViewMiscText = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::MiscText);
0654     m_toolBox->addItem(m_symbolViewMiscText,QIcon::fromTheme("math5"),i18n("Miscellaneous Text"));
0655     connect(m_symbolViewMiscText, &KileWidget::SymbolView::insertText,
0656             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0657 
0658     m_symbolViewDelimiters= new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Delimiters);
0659     m_toolBox->addItem(m_symbolViewDelimiters,QIcon::fromTheme("math6"),i18n("Delimiters"));
0660     connect(m_symbolViewDelimiters, &KileWidget::SymbolView::insertText,
0661             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0662 
0663     m_symbolViewGreek = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Greek);
0664     m_toolBox->addItem(m_symbolViewGreek,QIcon::fromTheme("math7"),i18n("Greek"));
0665     connect(m_symbolViewGreek, &KileWidget::SymbolView::insertText,
0666             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0667 
0668     m_symbolViewSpecial = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Special);
0669     m_toolBox->addItem(m_symbolViewSpecial,QIcon::fromTheme("math8"),i18n("Special Characters"));
0670     connect(m_symbolViewSpecial, &KileWidget::SymbolView::insertText,
0671             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0672 
0673     m_symbolViewCyrillic = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::Cyrillic);
0674     m_toolBox->addItem(m_symbolViewCyrillic,QIcon::fromTheme("math10"),i18n("Cyrillic Characters"));
0675     connect(m_symbolViewCyrillic, &KileWidget::SymbolView::insertText,
0676             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0677 
0678     m_symbolViewUser = new KileWidget::SymbolView(this, m_toolBox, KileWidget::SymbolView::User);
0679     m_toolBox->addItem(m_symbolViewUser,QIcon::fromTheme("math9"),i18n("User Defined"));
0680     connect(m_symbolViewUser, &KileWidget::SymbolView::insertText,
0681             this, static_cast<void (Kile::*)(const QString&, const QList<Package>&)>(&Kile::insertText));
0682 
0683     for(int i = 0; i < m_toolBox->count(); ++i) {
0684         m_toolBox->setItemToolTip(i, i18n("<p>Move the mouse over the icons to see the corresponding LaTeX commands.<br/>"
0685                                           "Click on an image to insert the corresponding command, additionally pressing \"Shift\" inserts "
0686                                           "it in math mode, pressing \"Ctrl\" in curly brackets.</p>"));
0687     }
0688 }
0689 
0690 void Kile::setupCommandViewToolbox()
0691 {
0692     m_commandViewToolBox = new KileWidget::CommandViewToolBox(this, m_sideBar);
0693     m_sideBar->addPage(m_commandViewToolBox, QIcon::fromTheme("texlion"), i18n("LaTeX"));
0694 
0695     connect(m_commandViewToolBox, &KileWidget::CommandViewToolBox::sendText,
0696             this, QOverload<const QString&>::of(&Kile::insertText));
0697 }
0698 
0699 void Kile::setupAbbreviationView()
0700 {
0701     m_kileAbbrevView = new KileWidget::AbbreviationView(abbreviationManager(), m_sideBar);
0702     connect(abbreviationManager(), &KileAbbreviation::Manager::abbreviationsChanged,
0703             m_kileAbbrevView, &KileWidget::AbbreviationView::updateAbbreviations);
0704     m_sideBar->addPage(m_kileAbbrevView, QIcon::fromTheme("complete3"), i18n("Abbreviation"));
0705 
0706     connect(m_kileAbbrevView, &KileWidget::AbbreviationView::sendText,
0707             this, QOverload<const QString&>::of(&Kile::insertText));
0708 }
0709 
0710 void Kile::setupBottomBar()
0711 {
0712     m_bottomBar = new KileWidget::BottomBar(this);
0713     m_bottomBar->setFocusPolicy(Qt::ClickFocus);
0714 
0715     connect(errorHandler(), &KileErrorHandler::showingErrorMessage, this, &Kile::focusLog);
0716 
0717     QWidget *widget = new QWidget(this);
0718     QHBoxLayout *layout = new QHBoxLayout(widget);
0719     layout->setContentsMargins(0, 0, 0, 0);
0720     widget->setLayout(layout);
0721 
0722     m_latexOutputErrorToolBar = new KToolBar(widget);
0723     m_latexOutputErrorToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
0724     m_latexOutputErrorToolBar->setIconDimensions(KIconLoader::SizeSmall);
0725     m_latexOutputErrorToolBar->setOrientation(Qt::Vertical);
0726 
0727     layout->addWidget(errorHandler()->outputWidget());
0728     layout->addWidget(m_latexOutputErrorToolBar);
0729     m_bottomBar->addPage(widget, QIcon::fromTheme("utilities-log-viewer"), i18n("Log and Messages"));
0730 
0731     m_outputWidget = new KileWidget::OutputView(this);
0732     m_outputWidget->setFocusPolicy(Qt::ClickFocus);
0733     m_outputWidget->setMinimumHeight(40);
0734     m_outputWidget->setReadOnly(true);
0735     m_bottomBar->addPage(m_outputWidget, QIcon::fromTheme("output_win"), i18n("Output"));
0736 
0737     m_texKonsole = new KileWidget::Konsole(this, this);
0738     m_bottomBar->addPage(m_texKonsole, QIcon::fromTheme("utilities-terminal"),i18n("Konsole"));
0739     connect(viewManager(), static_cast<void (KileView::Manager::*)(QWidget*)>(&KileView::Manager::currentViewChanged),
0740             m_texKonsole, static_cast<void (KileWidget::Konsole::*)(void)>(&KileWidget::Konsole::sync));
0741 
0742     m_previewWidget = new KileWidget::PreviewWidget(this, m_bottomBar);
0743     m_bottomBar->addPage(m_previewWidget, QIcon::fromTheme ("document-preview"), i18n ("Preview"));
0744 
0745     m_bottomBar->setVisible(true);
0746     m_bottomBar->switchToTab(KileConfig::bottomBarIndex());
0747     m_bottomBar->setDirectionalSize(KileConfig::bottomBarSize());
0748 }
0749 
0750 void Kile::setupGraphicTools()
0751 {
0752     KileConfig::setImagemagick(!(QStandardPaths::findExecutable("identify").isNull()));
0753 }
0754 
0755 void Kile::setupPreviewTools()
0756 {
0757     // search for tools
0758     bool dvipng = !(QStandardPaths::findExecutable("dvipng").isNull());
0759     bool convert = !(QStandardPaths::findExecutable("convert").isNull());
0760 
0761     KileConfig::setDvipng(dvipng);
0762     KileConfig::setConvert(convert);
0763 
0764     // disable some previews, if tools are missing
0765     if ( ! dvipng )
0766     {
0767         KileConfig::setMathgroupPreviewInWidget(false);  // no mathgroup preview in bottom bar
0768         if ( ! convert )
0769         {
0770             KileConfig::setEnvPreviewInWidget(false);     // no preview in bottom bar at all
0771             KileConfig::setSelPreviewInWidget(false);
0772         }
0773     }
0774 }
0775 
0776 template<class ContextType, class Func>
0777 QAction* Kile::createAction(const QString &text, const QString &actionName, const QString& iconName, const QKeySequence& shortcut,
0778                             const ContextType* context, Func function)
0779 {
0780     QAction *action = new QAction(this);
0781     action->setText(text);
0782 
0783     connect(action, &QAction::triggered, context, function);
0784     actionCollection()->addAction(actionName, action);
0785 
0786     if(!shortcut.isEmpty()) {
0787         actionCollection()->setDefaultShortcut(action, shortcut);
0788     }
0789     if(!iconName.isEmpty()) {
0790         action->setIcon(QIcon::fromTheme(iconName));
0791     }
0792 
0793     return action;
0794 }
0795 
0796 template<class ContextType, class Func>
0797 QAction* Kile::createAction(const QString &text, const QString &actionName, const QString& iconName, const QList<QKeySequence>& shortcut, const ContextType* context, Func function)
0798 {
0799     QAction *action = new QAction(this);
0800     action->setText(text);
0801 
0802     connect(action, &QAction::triggered, context, function);
0803     actionCollection()->addAction(actionName, action);
0804 
0805     if(!shortcut.isEmpty()) {
0806         actionCollection()->setDefaultShortcuts(action, shortcut);
0807     }
0808     if(!iconName.isEmpty()) {
0809         action->setIcon(QIcon::fromTheme(iconName));
0810     }
0811 
0812     return action;
0813 }
0814 
0815 template<class ContextType, class Func>
0816 QAction* Kile::createAction(KStandardAction::StandardAction actionType, const QString &actionName, const ContextType* context, Func function)
0817 {
0818     QAction *action = KStandardAction::create(actionType, context, function, this);
0819     if(!actionName.isEmpty()) {
0820         action->setObjectName(actionName);
0821     }
0822     actionCollection()->addAction(actionName, action);
0823 
0824     return action;
0825 }
0826 
0827 void Kile::setupActions()
0828 {
0829     QAction *act;
0830 
0831     createAction(KStandardAction::New, "file_new", docManager(), [this]() { docManager()->fileNew(); });
0832     createAction(KStandardAction::Open, "file_open", docManager(), [this]() { docManager()->fileOpen(); });
0833 
0834     m_actRecentFiles = KStandardAction::openRecent(docManager(), [this](const QUrl& url) { docManager()->fileOpen(url); }, this);
0835     m_actRecentFiles->setObjectName("file_open_recent");
0836     actionCollection()->addAction("file_open_recent", m_actRecentFiles);
0837     connect(docManager(), &KileDocument::Manager::addToRecentFiles, this, &Kile::addRecentFile);
0838     m_actRecentFiles->loadEntries(m_config->group("Recent Files"));
0839 
0840     createAction(i18n("Save All"), "file_save_all", "document-save-all", docManager(), &KileDocument::Manager::fileSaveAll);
0841 
0842     createAction(i18n("Create Template From Document..."), "template_create", docManager(), &KileDocument::Manager::createTemplate);
0843     createAction(i18n("&Remove Template..."), "template_remove", docManager(), &KileDocument::Manager::removeTemplate);
0844     createAction(KStandardAction::Close, "file_close", docManager(), [this]() { docManager()->fileClose();} );
0845     createAction(i18n("Close All"), "file_close_all", docManager(), &KileDocument::Manager::fileCloseAll);
0846     createAction(i18n("Close All Ot&hers"), "file_close_all_others", docManager(), [this]() { docManager()->fileCloseAllOthers(); });
0847     createAction(i18n("S&tatistics"), "Statistics", this, [this]() { showDocInfo(); });
0848     createAction(i18n("&ASCII"), "file_export_ascii", this, [this]() { convertToASCII(); });
0849     createAction(i18n("Latin-&1 (iso 8859-1)"), "file_export_latin1", this, [this]() { convertToEnc(); });
0850     createAction(i18n("Latin-&2 (iso 8859-2)"), "file_export_latin2", this, [this]() { convertToEnc(); });
0851     createAction(i18n("Latin-&3 (iso 8859-3)"), "file_export_latin3", this, [this]() { convertToEnc(); });
0852     createAction(i18n("Latin-&4 (iso 8859-4)"), "file_export_latin4", this, [this]() { convertToEnc(); });
0853     createAction(i18n("Latin-&5 (iso 8859-5)"), "file_export_latin5", this, [this]() { convertToEnc(); });
0854     createAction(i18n("Latin-&9 (iso 8859-9)"), "file_export_latin9", this, [this]() { convertToEnc(); });
0855     createAction(i18n("&Central European (cp-1250)"), "file_export_cp1250", this, [this]() { convertToEnc(); });
0856     createAction(i18n("&Western European (cp-1252)"), "file_export_cp1252", this, [this]() { convertToEnc(); });
0857     createAction(KStandardAction::Quit, "file_quit", this, &Kile::close);
0858 
0859     createAction(i18n("Move Tab Left"), "move_view_tab_left", "arrow-left", viewManager(), [this]() { viewManager()->moveTabLeft(); });
0860     createAction(i18n("Move Tab Right"), "move_view_tab_right", "arrow-right", viewManager(), [this]() { viewManager()->moveTabRight(); });
0861 
0862     createAction(i18n("Next section"), "edit_next_section", "nextsection", QKeySequence(Qt::ALT + Qt::Key_Down),
0863                  m_edit, &KileDocument::EditorExtension::gotoNextSectioning);
0864     createAction(i18n("Prev section"), "edit_prev_section", "prevsection", QKeySequence(Qt::ALT + Qt::Key_Up),
0865                  m_edit, &KileDocument::EditorExtension::gotoPrevSectioning);
0866     createAction(i18n("Next paragraph"), "edit_next_paragraph", "nextparagraph", QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Down),
0867                  m_edit, [this]() { m_edit->gotoNextParagraph(); });
0868     createAction(i18n("Prev paragraph"), "edit_prev_paragraph", "prevparagraph", QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Up),
0869                  m_edit, [this]() { m_edit->gotoPrevParagraph(); });
0870 
0871     createAction(i18n("Find &in Files..."), "FindInFiles", "filegrep", this, &Kile::findInFiles);
0872 
0873     createAction(i18n("Refresh Str&ucture"), "RefreshStructure", "refreshstructure", QKeySequence(Qt::Key_F12), this, &Kile::refreshStructure);
0874 
0875     //project actions
0876     createAction(i18n("&New Project..."), "project_new", "window-new", docManager(), &KileDocument::Manager::projectNew);
0877     createAction(i18n("&Open Project..."), "project_open", "project-open", docManager(), [this]() { docManager()->projectOpen(); });
0878 
0879     m_actRecentProjects = new KRecentFilesAction(i18n("Open &Recent Project"), actionCollection());
0880     actionCollection()->addAction("project_openrecent", m_actRecentProjects);
0881     connect(m_actRecentProjects, &KRecentFilesAction::urlSelected, docManager(), [this](const QUrl& url) { docManager()->projectOpen(url); });
0882     connect(docManager(), &KileDocument::Manager::removeFromRecentProjects, this, &Kile::removeRecentProject);
0883     connect(docManager(), &KileDocument::Manager::addToRecentProjects, this, &Kile::addRecentProject);
0884     m_actRecentProjects->loadEntries(m_config->group("Projects"));
0885 
0886     createAction(i18n("A&dd Files to Project..."), "project_add", "project_add", docManager(), [this]() { m_docManager->projectAddFiles(); });
0887     createAction(i18n("Refresh Project &Tree"), "project_buildtree", "project_rebuild", docManager(), [this]() { m_docManager->buildProjectTree(); });
0888     createAction(i18n("&Archive"), "project_archive", "project_archive", this, [this]() { runArchiveTool(); });
0889     createAction(i18n("Project &Options"), "project_options", "configure_project", docManager(), [this]() { m_docManager->projectOptions(); });
0890     createAction(i18n("&Close Project"), "project_close", "project-development-close", docManager(), [this]() { m_docManager->projectClose(); });
0891 
0892     // new project actions (dani)
0893     createAction(i18n("&Show Projects..."), "project_show", docManager(), &KileDocument::Manager::projectShow);
0894     createAction(i18n("Re&move Files From Project..."), "project_remove", "project_remove", docManager(), &KileDocument::Manager::projectRemoveFiles);
0895     createAction(i18n("Show Project &Files..."), "project_showfiles", "project_show", docManager(), &KileDocument::Manager::projectShowFiles);
0896     // tbraun
0897     createAction(i18n("Open All &Project Files"), "project_openallfiles", docManager(), [this]() { docManager()->projectOpenAllFiles(); });
0898     createAction(i18n("Find in &Project..."), "project_findfiles", "projectgrep", this, &Kile::findInProjects);
0899 
0900     //build actions
0901     act = createAction(i18n("Clean"), "CleanAll", "user-trash", this, [this]() { cleanAll(); });
0902 
0903     QList<QKeySequence> nextTabShorcuts;
0904     nextTabShorcuts.append(QKeySequence(Qt::ALT + Qt::Key_Right));
0905     nextTabShorcuts.append(KStandardShortcut::tabNext());
0906     createAction(i18n("Next Document"), "gotoNextDocument", "go-next-view-page",
0907                  nextTabShorcuts, viewManager(), &KileView::Manager::gotoNextView);
0908 
0909     QList<QKeySequence> prevTabShorcuts;
0910     prevTabShorcuts.append(QKeySequence(Qt::ALT + Qt::Key_Left));
0911     prevTabShorcuts.append(KStandardShortcut::tabPrev());
0912     createAction(i18n("Previous Document"), "gotoPrevDocument", "go-previous-view-page",
0913                  prevTabShorcuts, viewManager(), &KileView::Manager::gotoPrevView);
0914 
0915     createAction(i18n("Focus Log/Messages View"), "focus_log", QKeySequence("CTRL+Alt+M"), this, &Kile::focusLog);
0916     createAction(i18n("Focus Output View"), "focus_output", QKeySequence("CTRL+Alt+O"), this, &Kile::focusOutput);
0917     createAction(i18n("Focus Konsole View"), "focus_konsole", QKeySequence("CTRL+Alt+K"), this, &Kile::focusKonsole);
0918     createAction(i18n("Focus Editor View"), "focus_editor", QKeySequence("CTRL+Alt+F"), this, &Kile::focusEditor);
0919 
0920     createAction(i18nc("@action: Starts the completion of the current LaTeX command", "Complete (La)TeX Command"), "edit_complete_word", "complete1",
0921                  QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_Space), codeCompletionManager(), [this]() { codeCompletionManager()->startLaTeXCompletion(); });
0922     createAction(i18nc("@action: Starts the input (and completion) of a LaTeX environment", "Complete LaTeX Environment"), "edit_complete_env", "complete2",
0923                  QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_Space), codeCompletionManager(), [this]() { codeCompletionManager()->startLaTeXEnvironment(); });
0924     createAction(i18nc("@action: Starts the completion of the current abbreviation", "Complete Abbreviation"), "edit_complete_abbrev", "complete3",
0925                  QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Space), codeCompletionManager(), [this]() { codeCompletionManager()->startAbbreviationCompletion(); });
0926 
0927     createAction(i18n("Next Bullet"), "edit_next_bullet", "nextbullet", QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Right),
0928                  m_edit, [this]() { m_edit->nextBullet(); });
0929     createAction(i18n("Prev Bullet"), "edit_prev_bullet", "prevbullet", QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Left),
0930                  m_edit, [this]() { m_edit->prevBullet(); });
0931 
0932 // advanced editor (dani)
0933     createAction(i18n("Environment (inside)"), "edit_select_inside_env", "selenv_i", QKeySequence("CTRL+Alt+S, E"),
0934                  m_edit, &KileDocument::EditorExtension::selectEnvInside);
0935     createAction(i18n("Environment (outside)"), "edit_select_outside_env", "selenv_o", QKeySequence("CTRL+Alt+S, F"),
0936                  m_edit, &KileDocument::EditorExtension::selectEnvOutside);
0937     createAction(i18n("TeX Group (inside)"), "edit_select_inside_group", "selgroup_i", QKeySequence("CTRL+Alt+S, T"),
0938                  m_edit, &KileDocument::EditorExtension::selectTexgroupInside);
0939     createAction(i18n("TeX Group (outside)"), "edit_select_outside_group", "selgroup_o", QKeySequence("CTRL+Alt+S, U"),
0940                  m_edit, &KileDocument::EditorExtension::selectTexgroupOutside);
0941     createAction(i18n("Math Group"), "edit_select_mathgroup", "selmath", QKeySequence("CTRL+Alt+S, M"),
0942                  m_edit, [this]() { m_edit->selectMathgroup(); });
0943     createAction(i18n("Paragraph"), "edit_select_paragraph", "selpar", QKeySequence("CTRL+Alt+S, P"),
0944                  m_edit, [this]() { m_edit->selectParagraph(); });
0945     createAction(i18n("Line"), "edit_select_line", "selline", QKeySequence("CTRL+Alt+S, L"),
0946                  m_edit, [this]() { m_edit->selectLine(); });
0947     createAction(i18n("TeX Word"), "edit_select_word", "selword", QKeySequence("CTRL+Alt+S, W"),
0948                  m_edit, [this]() { m_edit->selectWord(); });
0949 
0950     createAction(i18n("Environment (inside)"), "edit_delete_inside_env", "delenv_i", QKeySequence("CTRL+Alt+T, E"),
0951                  m_edit, &KileDocument::EditorExtension::deleteEnvInside);
0952     createAction(i18n("Environment (outside)"), "edit_delete_outside_env", "delenv_o", QKeySequence("CTRL+Alt+T, F"),
0953                  m_edit, &KileDocument::EditorExtension::deleteEnvOutside);
0954     createAction(i18n("TeX Group (inside)"), "edit_delete_inside_group", "delgroup_i", QKeySequence("CTRL+Alt+T, T"),
0955                  m_edit, &KileDocument::EditorExtension::deleteTexgroupInside);
0956     createAction(i18n("TeX Group (outside)"), "edit_delete_outside_group", "delgroup_o",QKeySequence("CTRL+Alt+T, U"),
0957                  m_edit, &KileDocument::EditorExtension::deleteTexgroupInside);
0958     createAction(i18n("Math Group"), "edit_delete_mathgroup", "delmath", QKeySequence("CTRL+Alt+T, M"),
0959                  m_edit, [this]() { m_edit->deleteMathgroup(); });
0960     createAction(i18n("Paragraph"), "edit_delete_paragraph", "delpar", QKeySequence("CTRL+Alt+T, P"),
0961                  m_edit, [this]() { m_edit->deleteParagraph(); });
0962     createAction(i18n("To End of Line"), "edit_delete_eol", "deleol", QKeySequence("CTRL+Alt+T, L"),
0963                  m_edit, [this]() { m_edit->deleteEndOfLine(); });
0964     createAction(i18n("TeX Word"), "edit_delete_word", "delword", QKeySequence("CTRL+Alt+T, W"),
0965                  m_edit, [this]() { m_edit->deleteWord(); });
0966 
0967     createAction(i18n("Go to Begin"), "edit_begin_env", "gotobeginenv", QKeySequence("CTRL+Alt+E, B"),
0968                  m_edit, &KileDocument::EditorExtension::gotoBeginEnv);
0969     createAction(i18n("Go to End"), "edit_end_env", "gotoendenv", QKeySequence("CTRL+Alt+E, E"),
0970                  m_edit, &KileDocument::EditorExtension::gotoEndEnv);
0971     createAction(i18n("Match"), "edit_match_env", "matchenv", QKeySequence("CTRL+Alt+E, M"),
0972                  m_edit, &KileDocument::EditorExtension::matchEnv);
0973     createAction(i18n("Close"), "edit_close_env", "closeenv", QKeySequence("CTRL+Alt+E, C"),
0974                  m_edit, &KileDocument::EditorExtension::closeEnv);
0975     createAction(i18n("Close All"), "edit_closeall_env", "closeallenv", QKeySequence("CTRL+Alt+E, A"),
0976                  m_edit, &KileDocument::EditorExtension::closeAllEnv);
0977 
0978     createAction(i18n("Go to Begin"), "edit_begin_group", "gotobegingroup", QKeySequence("CTRL+Alt+G, B"),
0979                  m_edit, &KileDocument::EditorExtension::gotoBeginTexgroup);
0980     createAction(i18n("Go to End"), "edit_end_group", "gotoendgroup", QKeySequence("CTRL+Alt+G, E"),
0981                  m_edit, &KileDocument::EditorExtension::gotoEndTexgroup);
0982     createAction(i18n("Match"), "edit_match_group", "matchgroup", QKeySequence("CTRL+Alt+G, M"),
0983                  m_edit, [this]() { m_edit->matchTexgroup(); });
0984     createAction(i18n("Close"), "edit_close_group", "closegroup", QKeySequence("CTRL+Alt+G, C"),
0985                  m_edit, [this]() { m_edit->closeTexgroup(); });
0986 
0987     createAction(i18n("Selection"), "quickpreview_selection", "preview_sel", QKeySequence("CTRL+Alt+P, S"), this, &Kile::quickPreviewSelection);
0988     createAction(i18n("Environment"), "quickpreview_environment", "preview_env",QKeySequence("CTRL+Alt+P, E"), this, &Kile::quickPreviewEnvironment);
0989     createAction(i18n("Subdocument"), "quickpreview_subdocument", "preview_subdoc",QKeySequence("CTRL+Alt+P, D"), this, &Kile::quickPreviewSubdocument);
0990     createAction(i18n("Mathgroup"), "quickpreview_math", "preview_math", QKeySequence("CTRL+Alt+P, M"), this, &Kile::quickPreviewMathgroup);
0991 
0992     KileStdActions::setupStdTags(this, this, actionCollection(), this);
0993     KileStdActions::setupMathTags(this, actionCollection());
0994 
0995     m_bibTagActionMenu = new KActionMenu(i18n("&Bibliography"), actionCollection());
0996     m_bibTagActionMenu->setPopupMode(QToolButton::InstantPopup);
0997     actionCollection()->addAction("menu_bibliography", m_bibTagActionMenu);
0998 
0999     createAction(i18n("Clean"), "CleanBib", this, &Kile::cleanBib);
1000 
1001     m_bibTagSettings = new KSelectAction(i18n("&Settings"),actionCollection());
1002     actionCollection()->addAction("settings_menu_bibliography", m_bibTagSettings);
1003 
1004     act = createAction(i18n("Settings for BibTeX"), "setting_bibtex", this, &Kile::rebuildBibliographyMenu);
1005     act->setCheckable(true);
1006     m_bibTagSettings->addAction(act);
1007 
1008     act = createAction(i18n("Settings for Biblatex"), "setting_biblatex", this, &Kile::rebuildBibliographyMenu);
1009     act->setCheckable(true);
1010     m_bibTagSettings->addAction(act);
1011     m_bibTagSettings->setCurrentAction(action((QString("setting_") + KileConfig::bibliographyType()).toLatin1()));
1012 
1013     rebuildBibliographyMenu();
1014 
1015     createAction(i18n("Quick Start"), "wizard_document", "quickwizard", this, &Kile::quickDocument);
1016     connect(docManager(), &KileDocument::Manager::startWizard, this, &Kile::quickDocument);
1017     createAction(i18n("Tabular"), "wizard_tabular", "wizard_tabular", this, &Kile::quickTabular);
1018     createAction(i18n("Array"), "wizard_array", "wizard_array", this, &Kile::quickArray);
1019     createAction(i18n("Tabbing"), "wizard_tabbing", "wizard_tabbing", this, &Kile::quickTabbing);
1020     createAction(i18n("Floats"), "wizard_float", "wizard_float", this, &Kile::quickFloat);
1021     createAction(i18n("Math"), "wizard_mathenv", "wizard_math", this, &Kile::quickMathenv);
1022     createAction(i18n("Postscript Tools"), "wizard_postscript", "wizard_pstools", this, &Kile::quickPostscript);
1023     createAction(i18n("PDF Tools"), "wizard_pdf", "wizard_pdftools", this, &Kile::quickPdf);
1024 
1025     ModeAction = new KToggleAction(i18n("Define Current Document as '&Master Document'"), actionCollection());
1026     actionCollection()->addAction("Mode", ModeAction);
1027     ModeAction->setIcon(QIcon::fromTheme("master"));
1028     connect(ModeAction, &KToggleAction::triggered, this, &Kile::toggleMasterDocumentMode);
1029 
1030     KToggleAction *showDocumentViewer = new KToggleAction(i18n("Show Document Viewer"), actionCollection());
1031     actionCollection()->addAction("ShowDocumentViewer", showDocumentViewer);
1032     showDocumentViewer->setChecked(KileConfig::showDocumentViewer());
1033     connect(showDocumentViewer, &KToggleAction::toggled, viewManager(), &KileView::Manager::setDocumentViewerVisible);
1034     connect(viewManager(), &KileView::Manager::documentViewerWindowVisibilityChanged,
1035             showDocumentViewer, &KToggleAction::setChecked);
1036 
1037     KToggleAction *tact = new KToggleAction(i18n("Show S&ide Bar"), actionCollection());
1038     actionCollection()->addAction("StructureView", tact);
1039     tact->setChecked(KileConfig::sideBar());
1040     connect(tact, &KToggleAction::toggled, m_sideBar, &Kile::setVisible);
1041     connect(m_sideBar, &KileWidget::SideBar::visibilityChanged, this, &Kile::sideOrBottomBarChanged);
1042 
1043     m_actionMessageView = new KToggleAction(i18n("Show Mess&ages Bar"), actionCollection());
1044     actionCollection()->addAction("MessageView", m_actionMessageView);
1045     m_actionMessageView->setChecked(true);
1046     connect(m_actionMessageView, &KToggleAction::toggled, m_bottomBar, &Kile::setVisible);
1047     connect(m_bottomBar, &KileWidget::SideBar::visibilityChanged, this, &Kile::sideOrBottomBarChanged);
1048     if(m_singlemode) {
1049         ModeAction->setChecked(false);
1050     }
1051     else {
1052         ModeAction->setChecked(true);
1053     }
1054 
1055     WatchFileAction = new KToggleAction(i18n("Watch File Mode"), actionCollection());
1056     actionCollection()->addAction("WatchFile", WatchFileAction);
1057     WatchFileAction->setIcon(QIcon::fromTheme("watchfile"));
1058     connect(WatchFileAction, &KToggleAction::toggled, this, &Kile::toggleWatchFile);
1059     if(m_bWatchFile) {
1060         WatchFileAction->setChecked(true);
1061     }
1062     else {
1063         WatchFileAction->setChecked(false);
1064     }
1065 
1066     createAction(i18n("LaTeX"), "help_latex_index", QKeySequence("CTRL+Alt+H, L"), m_help, &KileHelp::Help::helpLatexIndex);
1067     createAction(i18n("LaTeX Commands"), "help_latex_command", QKeySequence("CTRL+Alt+H, C"), m_help, &KileHelp::Help::helpLatexCommand);
1068     createAction(i18n("LaTeX Environments"), "help_latex_env", QKeySequence("CTRL+Alt+H, E"), m_help, &KileHelp::Help::helpLatexEnvironment);
1069     createAction(i18n("Context Help"), "help_context", QKeySequence("CTRL+Alt+H, K"), m_help, [this]() { m_help->helpKeyword(); });
1070     createAction(i18n("Documentation Browser"), "help_docbrowser", QKeySequence("CTRL+Alt+H, B"), m_help, &KileHelp::Help::helpDocBrowser);
1071 
1072     createAction(i18n("&About Editor Component"), "help_about_editor", this, &Kile::aboutEditorComponent);
1073 
1074     QAction *kileconfig = KStandardAction::preferences(this, &Kile::generalOptions, actionCollection());
1075     kileconfig->setIcon(QIcon::fromTheme("configure-kile"));
1076 
1077     createAction(KStandardAction::KeyBindings, this, &Kile::configureKeys);
1078     createAction(KStandardAction::ConfigureToolbars, this, &Kile::configureToolbars);
1079 
1080     createAction(i18n("&System Check..."), "settings_perform_check", this, &Kile::slotPerformCheck);
1081 
1082     m_userHelpActionMenu = new KActionMenu(i18n("User Help"), actionCollection());
1083     actionCollection()->addAction("help_userhelp", m_userHelpActionMenu);
1084 
1085     m_pFullScreen = KStandardAction::fullScreen(this, &Kile::slotToggleFullScreen, this, actionCollection());
1086     m_actionShowMenuBar = KStandardAction::showMenubar(this,
1087                                                        [this]() { toggleShowMenuBar(true); },
1088                                                        actionCollection());
1089 }
1090 
1091 void Kile::rebuildBibliographyMenu() {
1092 
1093     KILE_DEBUG_MAIN << " current is " << m_bibTagSettings->currentText();
1094 
1095     QString currentItem = m_bibTagSettings->currentText();
1096     QString name;
1097 
1098     if( currentItem == i18n("BibTeX") ) { // avoid writing i18n'ed strings to config file
1099         name = QString("bibtex");
1100     }
1101     else if ( currentItem == i18n("Biblatex") ) {
1102         name = QString("biblatex");
1103     }
1104     else {
1105         KILE_DEBUG_MAIN << "wrong currentItem in bibliography settings menu";
1106         name = QString("bibtex");
1107     }
1108 
1109     KileConfig::setBibliographyType(name);
1110     m_bibTagActionMenu->menu()->clear();
1111 
1112     KileStdActions::setupBibTags(this, actionCollection(),m_bibTagActionMenu);
1113     m_bibTagActionMenu->addSeparator();
1114     m_bibTagActionMenu->addAction(action("CleanBib"));
1115     m_bibTagActionMenu->addSeparator();
1116     m_bibTagActionMenu->addAction(action("settings_menu_bibliography"));
1117 }
1118 
1119 QAction* Kile::createToolAction(const QString& toolName)
1120 {
1121     return createAction(toolName, "tool_" + toolName,
1122                         KileTool::iconFor(toolName, m_config.data()), this, [this, toolName]() { runTool(toolName); });
1123 }
1124 
1125 void Kile::createToolActions()
1126 {
1127     QStringList tools = KileTool::toolList(m_config.data());
1128     for (QStringList::iterator i = tools.begin(); i != tools.end(); ++i) {
1129         QString toolName = *i;
1130         if(!actionCollection()->action("tool_" + toolName)) {
1131             KILE_DEBUG_MAIN << "Creating action for tool" << toolName;
1132             createToolAction(toolName);
1133         }
1134     }
1135 }
1136 
1137 void Kile::setupTools()
1138 {
1139     KILE_DEBUG_MAIN << "==Kile::setupTools()===================" << Qt::endl;
1140 
1141     if(!m_buildMenuCompile || !m_buildMenuConvert ||  !m_buildMenuTopLevel || !m_buildMenuQuickPreview || !m_buildMenuViewer || !m_buildMenuOther) {
1142         KILE_DEBUG_MAIN << "BUG, menu pointers are Q_NULLPTR"
1143                         << (m_buildMenuCompile == Q_NULLPTR)
1144                         << (m_buildMenuConvert == Q_NULLPTR)
1145                         << (m_buildMenuTopLevel == Q_NULLPTR)
1146                         << (m_buildMenuQuickPreview == Q_NULLPTR)
1147                         << (m_buildMenuViewer == Q_NULLPTR)
1148                         << (m_buildMenuOther == Q_NULLPTR);
1149         return;
1150     }
1151 
1152     QStringList tools = KileTool::toolList(m_config.data());
1153     QList<QAction*> *pl;
1154     QAction *act;
1155     ToolbarSelectAction *pSelectAction = Q_NULLPTR;
1156 
1157     m_compilerActions->saveCurrentAction();
1158     m_viewActions->saveCurrentAction();
1159     m_convertActions->saveCurrentAction();
1160     m_quickActions->saveCurrentAction();
1161 
1162     // do plugActionList by hand ...
1163     foreach(act, m_listQuickActions) {
1164         m_buildMenuTopLevel->removeAction(act);
1165     }
1166 
1167     m_buildMenuCompile->clear();
1168     m_buildMenuConvert->clear();
1169     m_buildMenuViewer->clear();
1170     m_buildMenuOther->clear();
1171 
1172     m_compilerActions->removeAllActions();
1173     m_viewActions->removeAllActions();
1174     m_convertActions->removeAllActions();
1175     m_quickActions->removeAllActions();
1176 
1177     for (int i = 0; i < tools.count(); ++i) {
1178         QString grp = KileTool::groupFor(tools[i], m_config.data());
1179         QString toolMenu = KileTool::menuFor(tools[i], m_config.data());
1180 
1181         KILE_DEBUG_MAIN << tools[i] << " is using group: " << grp << " and menu: "<< toolMenu;
1182         if(toolMenu == "none") {
1183             continue;
1184         }
1185 
1186         if ( toolMenu == "Compile" ) {
1187             pl = &m_listCompilerActions;
1188             pSelectAction = m_compilerActions;
1189         }
1190         else if ( toolMenu == "View" ) {
1191             pl = &m_listViewerActions;
1192             pSelectAction = m_viewActions;
1193         }
1194         else if ( toolMenu == "Convert" ) {
1195             pl = &m_listConverterActions;
1196             pSelectAction = m_convertActions;
1197         }
1198         else if ( toolMenu == "Quick" ) {
1199             pl = &m_listQuickActions;
1200             pSelectAction = m_quickActions;
1201         }
1202         else {
1203             pl = &m_listOtherActions;
1204             pSelectAction = Q_NULLPTR;
1205         }
1206 
1207         KILE_DEBUG_MAIN << "\tadding " << tools[i] << " " << toolMenu << " #" << pl->count() << Qt::endl;
1208 
1209         act = actionCollection()->action("tool_" + tools[i]);
1210         if(!act) {
1211             KILE_DEBUG_MAIN << "no tool for " << tools[i];
1212             createToolAction(tools[i]);
1213         }
1214         pl->append(act);
1215 
1216         if(pSelectAction) {
1217             pSelectAction->addAction(actionCollection()->action("tool_" + tools[i]));
1218         }
1219     }
1220 
1221     m_quickActions->addSeparator();
1222     m_quickActions->addAction(action("quickpreview_selection"));
1223     m_quickActions->addAction(action("quickpreview_environment"));
1224     m_quickActions->addAction(action("quickpreview_subdocument"));
1225     m_quickActions->addSeparator();
1226     m_quickActions->addAction(action("quickpreview_math"));
1227 
1228     cleanUpActionList(m_listCompilerActions, tools);
1229     cleanUpActionList(m_listViewerActions, tools);
1230     cleanUpActionList(m_listConverterActions, tools);
1231     cleanUpActionList(m_listQuickActions, tools);
1232     cleanUpActionList(m_listOtherActions, tools);
1233 
1234     m_buildMenuTopLevel->insertActions(m_buildMenuQuickPreview->menuAction(),m_listQuickActions);
1235     m_buildMenuCompile->addActions(m_listCompilerActions);
1236     m_buildMenuConvert->addActions(m_listConverterActions);
1237     m_buildMenuViewer->addActions(m_listViewerActions);
1238     m_buildMenuOther->addActions(m_listOtherActions);
1239 
1240     m_compilerActions->restoreCurrentAction();
1241     m_viewActions->restoreCurrentAction();
1242     m_convertActions->restoreCurrentAction();
1243     m_quickActions->restoreCurrentAction();
1244 }
1245 
1246 void Kile::initSelectActions() {
1247 
1248     m_compilerActions = new ToolbarSelectAction(i18n("Compile"), this);
1249     m_viewActions = new ToolbarSelectAction(i18n("View"), this);
1250     m_convertActions = new ToolbarSelectAction(i18n("Convert"), this);
1251     m_quickActions = new ToolbarSelectAction(i18n("Quick"), this);
1252 
1253     actionCollection()->setShortcutsConfigurable(m_compilerActions, false);
1254     actionCollection()->setShortcutsConfigurable(m_viewActions, false);
1255     actionCollection()->setShortcutsConfigurable(m_convertActions, false);
1256     actionCollection()->setShortcutsConfigurable(m_quickActions, false);
1257 
1258     actionCollection()->addAction("list_compiler_select", m_compilerActions);
1259     actionCollection()->addAction("list_convert_select", m_convertActions);
1260     actionCollection()->addAction("list_view_select", m_viewActions);
1261     actionCollection()->addAction("list_quick_select", m_quickActions);
1262 }
1263 
1264 void Kile::saveLastSelectedAction() {
1265 
1266     KILE_DEBUG_MAIN << "Kile::saveLastSelectedAction()" << Qt::endl;
1267     QStringList list;
1268     list << "Compile" << "Convert" << "View" << "Quick";
1269 
1270     ToolbarSelectAction *pSelectAction = Q_NULLPTR ;
1271 
1272     KConfigGroup grp = m_config->group("ToolSelectAction");
1273 
1274     for(QStringList::Iterator it = list.begin(); it != list.end() ; ++it) {
1275         if ( *it == "Compile" ) {
1276             pSelectAction = m_compilerActions;
1277         }
1278         else if ( *it == "View" ) {
1279             pSelectAction = m_viewActions;
1280         }
1281         else if ( *it == "Convert" ) {
1282             pSelectAction = m_convertActions;
1283         }
1284         else if ( *it == "Quick" ) {
1285             pSelectAction = m_quickActions;
1286         }
1287 
1288         KILE_DEBUG_MAIN << "current item is " << pSelectAction->currentItem();
1289 
1290         grp.writeEntry(*it, pSelectAction->currentItem());
1291     }
1292 }
1293 
1294 void Kile::restoreLastSelectedAction() {
1295 
1296     QStringList list;
1297     list << "Compile" << "Convert" << "View" << "Quick";
1298 
1299     ToolbarSelectAction *pSelectAction = Q_NULLPTR;
1300     int defaultAction = 0;
1301 
1302     KConfigGroup grp = m_config->group("ToolSelectAction");
1303 
1304     for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
1305         if ( *it == "Compile" ) {
1306             pSelectAction = m_compilerActions;
1307             defaultAction = 9; // PDFLatex
1308         }
1309         else if ( *it == "View" ) {
1310             pSelectAction = m_viewActions;
1311             defaultAction = 4; // ViewPDF
1312         }
1313         else if ( *it == "Convert" ) {
1314             pSelectAction = m_convertActions;
1315             defaultAction = 0;
1316         }
1317         else if ( *it == "Quick" ) {
1318             pSelectAction = m_quickActions;
1319             defaultAction = 0;
1320         }
1321 
1322         int actIndex = grp.readEntry(*it, defaultAction);
1323         KILE_DEBUG_MAIN << "selecting" << actIndex << "for" << *it;
1324         pSelectAction->setCurrentItem(actIndex);
1325     }
1326 }
1327 
1328 void Kile::cleanUpActionList(QList<QAction*> &list, const QStringList &tools)
1329 {
1330 //      KILE_DEBUG_MAIN << "cleanUpActionList tools are" << tools.join("; ");
1331     QList<QAction*>::iterator it, testIt;
1332     for ( it= list.begin(); it != list.end(); ++it) {
1333         QAction *act = *it;
1334         if ( act != Q_NULLPTR && !act->objectName().isEmpty() && !tools.contains(act->objectName().mid(5)) ) {
1335             if (act->associatedWidgets().contains(toolBar("toolsToolBar"))) {
1336                 toolBar("toolsToolBar")->removeAction(act);
1337             }
1338 //             KILE_DEBUG_MAIN << "about to delete action: " << act->objectName();
1339             testIt = list.erase(it);
1340             if( testIt == list.end()) {
1341                 break;
1342             }
1343         }
1344     }
1345 }
1346 
1347 void Kile::restoreFilesAndProjects(bool allowRestore)
1348 {
1349     if (!(allowRestore && KileConfig::restore())) {
1350         return;
1351     }
1352 
1353     QUrl url;
1354     for (int i=0; i < m_listProjectsOpenOnStart.count(); ++i) {
1355         // don't open project files as they will be opened later in this method
1356         docManager()->projectOpen(QUrl::fromUserInput(m_listProjectsOpenOnStart[i]), i, m_listProjectsOpenOnStart.count(), false);
1357     }
1358 
1359     for (int i = 0; i < m_listDocsOpenOnStart.count(); ++i) {
1360         docManager()->fileOpen(QUrl::fromUserInput(m_listDocsOpenOnStart[i]), m_listEncodingsOfDocsOpenOnStart[i]);
1361     }
1362 
1363     if (ModeAction) {
1364         ModeAction->setChecked(!m_singlemode);
1365     }
1366     updateModeStatus();
1367 
1368     m_listProjectsOpenOnStart.clear();
1369     m_listDocsOpenOnStart.clear();
1370     m_listEncodingsOfDocsOpenOnStart.clear();
1371 
1372     KILE_DEBUG_MAIN << "lastDocument=" << KileConfig::lastDocument() << Qt::endl;
1373     KTextEditor::Document *doc = docManager()->docFor(QUrl::fromUserInput(KileConfig::lastDocument()));
1374     if (doc) {
1375         viewManager()->switchToTextView(doc->url(), true); // request the focus on the view
1376     }
1377     setMasterDocumentFileName(KileConfig::singleFileMasterDocument());
1378 }
1379 
1380 void Kile::setActive()
1381 {
1382     KILE_DEBUG_MAIN << "Activating" << Qt::endl;
1383     raise();
1384     activateWindow();
1385     show();
1386 }
1387 
1388 void Kile::setLine(const QString &line)
1389 {
1390     bool ok;
1391     uint l = line.toUInt(&ok, 10);
1392     KTextEditor::View *view = viewManager()->currentTextView();
1393     if (view && ok) {
1394         show();
1395         raise();
1396         activateWindow();
1397         // be very aggressive when it comes to raising the main window to the top
1398 #if __has_include(<kx11extras.h>)
1399         KX11Extras::forceActiveWindow(winId());
1400 #else
1401         KWindowSystem::forceActiveWindow(winId());
1402 #endif
1403         focusTextView(view);
1404         editorExtension()->goToLine(l - 1, view);
1405     }
1406 }
1407 
1408 void Kile::setCursor(const QUrl &url, int parag, int index)
1409 {
1410     KTextEditor::Document *doc = docManager()->docFor(url);
1411     if(doc) {
1412         KTextEditor::View *view = (KTextEditor::View*)doc->views().first();
1413         if(view) {
1414             view->setCursorPosition(KTextEditor::Cursor(parag, index));
1415             focusTextView(view);
1416         }
1417     }
1418 }
1419 
1420 void Kile::runArchiveTool()
1421 {
1422     runArchiveTool(QUrl());
1423 }
1424 
1425 void Kile::runArchiveTool(const QUrl &url)
1426 {
1427     KileTool::Archive *tool = dynamic_cast<KileTool::Archive*>(m_manager->createTool("Archive", QString(), false));
1428     if(!tool) {
1429         KMessageBox::error(mainWindow(), i18n("It was impossible to create the \"Archive\" tool.\n\n"
1430                                               "Please check and repair your installation of Kile."),
1431                            i18n("Unable to Create Archive Tool"));
1432         return;
1433     }
1434     if(url.isValid()) {
1435         tool->setSource(url.toLocalFile());
1436     }
1437     tool->prepareToRun();
1438     m_manager->run(tool);
1439 }
1440 
1441 //TODO: move to KileView::Manager
1442 void Kile::activateView(QWidget* w, bool updateStruct /* = true */ )  //Needs to be QWidget because of QTabWidget::currentChanged
1443 {
1444     //KILE_DEBUG_MAIN << "==Kile::activateView==========================" << Qt::endl;
1445     if (!w || !w->inherits("KTextEditor::View")) {
1446         return;
1447     }
1448 
1449     //disable gui updates to avoid flickering of toolbars
1450     setUpdatesEnabled(false);
1451 
1452     QList<KToolBar*> toolBarsList = toolBars();
1453     QHash<KToolBar*, bool> toolBarVisibilityHash;
1454 
1455     for(QList<KToolBar*>::iterator i = toolBarsList.begin();
1456             i != toolBarsList.end(); ++i) {
1457         KToolBar *toolBar = *i;
1458         toolBarVisibilityHash[toolBar] = toolBar->isVisible();
1459     }
1460 
1461     KTextEditor::View* view = dynamic_cast<KTextEditor::View*>(w);
1462     Q_ASSERT(view);
1463 
1464     for(int i = 0; i < viewManager()->textViewCount(); ++i) {
1465         KTextEditor::View *view2 = viewManager()->textView(i);
1466         if(view == view2) {
1467             continue;
1468         }
1469         guiFactory()->removeClient(view2);
1470         view2->clearFocus();
1471     }
1472 
1473     guiFactory()->addClient(view);
1474 
1475     for(QList<KToolBar*>::iterator i = toolBarsList.begin();
1476             i != toolBarsList.end(); ++i) {
1477         KToolBar *toolBar = *i;
1478         toolBar->setVisible(toolBarVisibilityHash[*i]);
1479     }
1480 
1481     setUpdatesEnabled(true);
1482 
1483     if(updateStruct) {
1484         viewManager()->updateStructure();
1485     }
1486 
1487     focusTextView(view);
1488 }
1489 
1490 void Kile::updateModeStatus()
1491 {
1492     KILE_DEBUG_MAIN << "==Kile::updateModeStatus()==========";
1493     KileProject *project = docManager()->activeProject();
1494     QString shortName = m_masterDocumentFileName;
1495     int pos = shortName.lastIndexOf('/');
1496     shortName.remove(0, pos + 1);
1497 
1498     if(project) {
1499         if (m_singlemode) {
1500             statusBar()->setHintText(i18n("Project: %1", project->name()));
1501         }
1502         else {
1503             statusBar()->setHintText(i18n("Project: %1 (Master document: %2)", project->name(), shortName));
1504         }
1505     }
1506     else {
1507         if (m_singlemode) {
1508             statusBar()->setHintText(i18n("Normal mode"));
1509         }
1510         else {
1511             statusBar()->setHintText(i18n("Master document: %1", shortName));
1512         }
1513     }
1514 
1515     if(m_singlemode) {
1516         ModeAction->setText(i18n("Define Current Document as 'Master Document'"));
1517         ModeAction->setChecked(false);
1518     }
1519     else {
1520         ModeAction->setText(i18n("Normal mode (current master document: %1)", shortName));
1521         ModeAction->setChecked(true);
1522     }
1523 
1524     // enable or disable entries in Kile'S menu
1525     updateMenu();
1526 
1527     KTextEditor::View *view = viewManager()->currentTextView();
1528     // Passing Q_NULLPTR is ok
1529     updateStatusBarCursorPosition(view, (view ? view->cursorPosition() : KTextEditor::Cursor()));
1530     updateStatusBarViewMode(view);
1531     updateStatusBarSelection(view);
1532 }
1533 
1534 void Kile::openDocument(const QUrl &url)
1535 {
1536     docManager()->fileSelected(url);
1537 }
1538 
1539 void Kile::openDocument(const QString& s)
1540 {
1541     openDocument(QUrl::fromUserInput(s));
1542 }
1543 
1544 void Kile::closeDocument()
1545 {
1546     docManager()->fileClose();
1547 }
1548 
1549 void Kile::openProject(const QUrl &url)
1550 {
1551     docManager()->projectOpen(url);
1552 }
1553 
1554 void Kile::openProject(const QString& proj)
1555 {
1556     openProject(QUrl::fromUserInput(proj));
1557 }
1558 
1559 void Kile::focusPreview()
1560 {
1561     m_bottomBar->switchToTab(PREVIEW_TAB);
1562 }
1563 
1564 void Kile::focusLog()
1565 {
1566     m_bottomBar->switchToTab(LOG_TAB);
1567 }
1568 
1569 void Kile::focusOutput()
1570 {
1571     m_bottomBar->switchToTab(OUTPUT_TAB);
1572 }
1573 
1574 void Kile::focusKonsole()
1575 {
1576     m_bottomBar->switchToTab(KONSOLE_TAB);
1577 }
1578 
1579 void Kile::focusEditor()
1580 {
1581     KTextEditor::View *view = viewManager()->currentTextView();
1582     if(view) {
1583         focusTextView(view);
1584     }
1585 }
1586 
1587 void Kile::sideOrBottomBarChanged(bool visible)
1588 {
1589     if ( ! visible )
1590     {
1591         focusEditor();
1592     }
1593 }
1594 
1595 //FIXME: documents probably shouldn't be closed in this method yet (also see API doc of 'queryClose')
1596 bool Kile::queryClose()
1597 {
1598     KTextEditor::View *view = viewManager()->currentTextView();
1599     if(view) {
1600         KileConfig::setLastDocument(view->document()->url().toLocalFile());
1601     }
1602     else {
1603         KileConfig::setLastDocument("");
1604     }
1605 
1606     //don't close Kile if embedded viewers are present
1607     KILE_DEBUG_MAIN << "==bool Kile::queryClose==========" << Qt::endl;
1608 
1609     m_listProjectsOpenOnStart.clear();
1610     m_listDocsOpenOnStart.clear();
1611     m_listEncodingsOfDocsOpenOnStart.clear();
1612 
1613     for(int i = 0; i < viewManager()->textViewCount(); ++i) {
1614         KTextEditor::Document *doc = viewManager()->textView(i)->document();
1615         const QUrl url = doc->url();
1616         if(url.isEmpty()) {
1617             continue;
1618         }
1619         m_listDocsOpenOnStart.append(url.toLocalFile());
1620         m_listEncodingsOfDocsOpenOnStart.append(doc->encoding());
1621     }
1622 
1623     KILE_DEBUG_MAIN << "#projects = " << docManager()->projects().count() << Qt::endl;
1624     QList<KileProject*> projectList = docManager()->projects();
1625     for(QList<KileProject*>::iterator i = projectList.begin(); i != projectList.end(); ++i) {
1626         const QUrl url = (*i)->url();
1627         if(url.isEmpty()) { // shouldn't happen, but just in case...
1628             continue;
1629         }
1630         m_listProjectsOpenOnStart.append(url.toLocalFile());
1631     }
1632 
1633     bool stage1 = docManager()->projectCloseAll();
1634     bool stage2 = true;
1635 
1636     if(stage1) {
1637         stage2 = docManager()->fileCloseAll();
1638     }
1639 
1640     bool close = stage1 && stage2;
1641     if(close) {
1642         saveSettings();
1643     }
1644 
1645     return close;
1646 }
1647 
1648 void Kile::showDocInfo(KTextEditor::View *view)
1649 {
1650     if(!view) {
1651         view = viewManager()->currentTextView();
1652     }
1653 
1654     if(!view) {
1655         return;
1656     }
1657 
1658     KileDocument::TextInfo *docinfo = docManager()->textInfoFor(view->document());
1659     KileProject *project = KileInfo::docManager()->activeProject();
1660     if(docinfo) { // we have to ensure that we always get a _valid_ docinfo object
1661         KileDialog::StatisticsDialog *dlg = new KileDialog::StatisticsDialog(project,
1662                 docinfo,
1663                 this,
1664                 view);
1665         dlg->exec();
1666         delete dlg;
1667     }
1668     else {
1669         qWarning() << "There is no KileDocument::Info object belonging to this document!";
1670     }
1671 }
1672 
1673 void Kile::convertToASCII(KTextEditor::Document *doc)
1674 {
1675     if(!doc) {
1676         KTextEditor::View *view = viewManager()->currentTextView();
1677 
1678         if(view) {
1679             doc = view->document();
1680         }
1681         else {
1682             return;
1683         }
1684     }
1685 
1686     ConvertIO io(doc);
1687     ConvertEncToASCII conv = ConvertEncToASCII(doc->encoding(), &io);
1688     doc->setEncoding("ISO 8859-1");
1689     conv.convert();
1690 }
1691 
1692 void Kile::convertToEnc(KTextEditor::Document *doc)
1693 {
1694     if(!doc) {
1695         KTextEditor::View *view = viewManager()->currentTextView();
1696 
1697         if (view) doc = view->document();
1698         else return;
1699     }
1700 
1701     if(sender()) {
1702         ConvertIO io(doc);
1703         QString name = QString(sender()->objectName()).section('_', -1);
1704         ConvertASCIIToEnc conv = ConvertASCIIToEnc(name, &io);
1705         conv.convert();
1706         doc->setEncoding(ConvertMap::encodingNameFor(name));
1707     }
1708 }
1709 
1710 KileWidget::StatusBar * Kile::statusBar()
1711 {
1712     return static_cast<KileWidget::StatusBar *>(KXmlGuiWindow::statusBar());
1713 }
1714 
1715 ////////////////// GENERAL SLOTS //////////////
1716 int Kile::lineNumber()
1717 {
1718     KTextEditor::View *view = viewManager()->currentTextView();
1719 
1720     int para = 0;
1721 
1722     if (view) {
1723         para = view->cursorPosition().line();
1724     }
1725 
1726     return para;
1727 }
1728 
1729 void Kile::newCaption()
1730 {
1731     KTextEditor::View *view = viewManager()->currentTextView();
1732     if(view) {
1733         const bool showFullPath = KileConfig::showFullPathInWindowTitle();
1734 
1735         KTextEditor::Document *doc = view->document();
1736         const QString caption = (doc->isReadWrite() ? getName(doc, !showFullPath)
1737                                  : i18nc("Window caption in read-only mode: <file name> [Read-Only]",
1738                                          "%1 [Read-Only]", getName(doc, !showFullPath)));
1739         setWindowTitle(caption);
1740         if (m_bottomBar->currentPage() && m_bottomBar->currentPage()->inherits("KileWidget::Konsole")) {
1741             m_texKonsole->sync();
1742         }
1743     }
1744     else {
1745         setWindowTitle("");
1746     }
1747 }
1748 
1749 void Kile::grepItemSelected(const QString &abs_filename, int line)
1750 {
1751     KILE_DEBUG_MAIN << "Open file: "
1752                     << abs_filename << " (" << line << ")" << Qt::endl;
1753     docManager()->fileOpen(QUrl::fromUserInput(abs_filename));
1754     setLine(QString::number(line));
1755 }
1756 
1757 void Kile::findInFiles()
1758 {
1759     static QPointer<KileDialog::FindFilesDialog> dlg = 0;
1760 
1761     if (!dlg) {
1762         KILE_DEBUG_MAIN << "grep guard: create findInFiles dlg" << Qt::endl;
1763         dlg = new KileDialog::FindFilesDialog(mainWindow(), this, KileGrep::Directory);
1764         dlg->show();
1765         connect(dlg, &KileDialog::FindFilesDialog::itemSelected, this, &Kile::grepItemSelected);
1766     }
1767     else {
1768         KILE_DEBUG_MAIN << "grep guard: show findInFiles dlg" << Qt::endl;
1769         dlg->activateWindow();
1770         dlg->raise();
1771     }
1772 }
1773 
1774 void Kile::findInProjects()
1775 {
1776     static QPointer<KileDialog::FindFilesDialog> project_dlg = Q_NULLPTR;
1777 
1778     if(!project_dlg) {
1779         KILE_DEBUG_MAIN << "grep guard: create findInProjects dlg" << Qt::endl;
1780         project_dlg = new KileDialog::FindFilesDialog(mainWindow(), this, KileGrep::Project);
1781         project_dlg->show();
1782         connect(project_dlg, &KileDialog::FindFilesDialog::itemSelected, this, &Kile::grepItemSelected);
1783     }
1784     else {
1785         KILE_DEBUG_MAIN << "grep guard: show findInProjects dlg" << Qt::endl;
1786         project_dlg->activateWindow();
1787         project_dlg->raise();
1788     }
1789 }
1790 
1791 /////////////////// PART & EDITOR WIDGET //////////
1792 bool Kile::resetPart()
1793 {
1794     KILE_DEBUG_MAIN << "==Kile::resetPart()=============================" << Qt::endl;
1795 
1796     statusBar()->reset();
1797     updateModeStatus();
1798     newCaption();
1799 
1800     KTextEditor::View *view = viewManager()->currentTextView();
1801     if (view) {
1802         activateView(view);
1803     }
1804 
1805     return true;
1806 }
1807 
1808 void Kile::updateUserDefinedMenus()
1809 {
1810     m_buildMenuTopLevel = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("menu_build", m_mainWindow));
1811     m_buildMenuCompile  = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("menu_compile", m_mainWindow));
1812     m_buildMenuConvert  = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("menu_convert", m_mainWindow));
1813     m_buildMenuViewer  = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("menu_viewer", m_mainWindow));
1814     m_buildMenuOther   = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("menu_other", m_mainWindow));
1815     m_buildMenuQuickPreview   = dynamic_cast<QMenu*>(m_mainWindow->guiFactory()->container("quickpreview", m_mainWindow));
1816 
1817     m_userMenu->updateGUI();
1818 
1819     setupTools();
1820 }
1821 
1822 void Kile::enableGUI(bool enable)
1823 {
1824     // update action lists
1825     QList<QAction *> actions = actionCollection()->actions();
1826     for(QList<QAction *>::iterator itact = actions.begin(); itact != actions.end(); ++itact) {
1827         if (m_dictMenuAction.contains((*itact)->objectName())
1828                 || m_dictMenuFile.contains((*itact)->objectName())) {
1829             (*itact)->setEnabled(enable);
1830         }
1831     }
1832 
1833     // update latex usermenu actions
1834     if ( m_userMenu ) {
1835         QList<QAction *> useractions = m_userMenu->menuActions();
1836         foreach ( QAction *action, useractions ) {
1837             action->setEnabled(enable);
1838         }
1839     }
1840 
1841     // enable or disable userhelp entries
1842     m_help->enableUserhelpEntries(enable);
1843 
1844     QList<QAction*> actionList;
1845     actionList << m_listQuickActions
1846                << m_listCompilerActions
1847                << m_listConverterActions
1848                << m_listViewerActions
1849                << m_listOtherActions;
1850     // enable or disable list actions
1851     for(QList<QAction*>::iterator i = actionList.begin(); i != actionList.end(); ++i) {
1852         (*i)->setEnabled(enable);
1853     }
1854 
1855     // enable or disable bibliography menu entries
1856     actionList = m_bibTagActionMenu->menu()->actions();
1857     for(QList<QAction*>::iterator it = actionList.begin(); it != actionList.end(); ++it) {
1858         (*it)->setEnabled(enable);
1859     }
1860 
1861     QStringList menuList;
1862     menuList << "file" << "edit" << "view" << "menu_build" << "menu_project" << "menu_latex" << "wizard" << "tools";
1863     for(QStringList::iterator it = menuList.begin(); it != menuList.end(); ++it) {
1864         QMenu *menu = dynamic_cast<QMenu*>(guiFactory()->container(*it, this));
1865         if(menu) {
1866             updateMenuActivationStatus(menu);
1867         }
1868     }
1869 
1870     updateUserMenuStatus(enable);
1871 }
1872 
1873 // adds action names to their lists
1874 
1875 void Kile::initMenu()
1876 {
1877     QStringList projectlist,filelist,actionlist;
1878 
1879     projectlist
1880             << "project_add" << "project_remove"
1881             << "project_showfiles"
1882             << "project_buildtree" << "project_options" << "project_findfiles"
1883             << "project_archive" << "project_close" << "project_openallfiles"
1884             ;
1885 
1886     filelist
1887     // file
1888             << "convert"
1889             // edit
1890             << "goto_menu" << "complete" << "bullet" << "select"
1891             << "delete" << "environment" << "texgroup"
1892             // build
1893             << "quickpreview" << "menu_compile" << "menu_convert"
1894             << "menu_viewers" << "menu_other"
1895             // latex
1896             << "menu_preamble" << "menu_lists" << "menu_sectioning" << "references"
1897             << "menu_environment" << "menu_listenv" << "menu_tabularenv" << "menu_floatenv"
1898             << "menu_code" << "menu_math" << "menu_mathenv" << "menu_mathamsenv"
1899             << "menu_bibliography" << "menu_fontstyles" << "menu_spacing"
1900             ;
1901 
1902     actionlist
1903     // file
1904             << "file_save_copy_as" << "file_save_all" << "template_create" << "Statistics"
1905             << "file_close" << "file_close_all" << "file_close_all_others"
1906             // edit
1907             << "RefreshStructure"
1908             // view
1909             << "gotoPrevDocument" << "gotoNextDocument"
1910             // build
1911             << "quickpreview_selection" << "quickpreview_environment"
1912             << "quickpreview_subdocument" << "quickpreview_math"
1913             << "WatchFile" << "CleanAll"
1914             // latex
1915             << "tag_documentclass" << "tag_usepackage" << "tag_amspackages" << "tag_env_document"
1916             << "tag_author" << "tag_title" << "tag_maketitle" << "tag_titlepage" << "tag_env_abstract"
1917             << "tag_tableofcontents" << "tag_listoffigures" << "tag_listoftables"
1918             << "tag_makeindex" << "tag_printindex" << "tag_makeglossary" << "tag_env_thebibliography"
1919             << "tag_part" << "tag_chapter" << "tag_section" << "tag_subsection" << "tag_subsubsection"
1920             << "tag_paragraph" << "tag_subparagraph" << "tag_label"
1921             << "tag_ref" << "tag_pageref" << "tag_index" << "tag_footnote" << "tag_cite"
1922             << "tag_center" << "tag_flushleft" << "tag_flushright"
1923             << "tag_env_minipage" << "tag_quote" << "tag_quotation" << "tag_verse"
1924             << "tag_env_itemize" << "tag_env_enumerate" << "tag_env_description" << "tag_item"
1925             << "tag_env_tabular" << "tag_env_tabular*" << "tag_env_tabbing"
1926             << "tag_multicolumn" << "tag_hline" << "tag_vline" << "tag_cline"
1927             << "tag_figure" << "tag_table"
1928             << "tag_verbatim" << "tag_env_verbatim*" << "tag_verb" << "tag_verb*"
1929             << "tag_mathmode" << "tag_equation" << "tag_subscript" << "tag_superscript"
1930             << "tag_sqrt" << "tag_nroot" << "tag_left" << "tag_right" << "tag_leftright"
1931             << "tag_bigl" << "tag_bigr" << "tag_Bigl" << "tag_Bigr"
1932             << "tag_biggl" << "tag_biggr" << "tag_Biggl" << "tag_Biggr"
1933             << "tag_text" << "tag_intertext" << "tag_boxed"
1934             << "tag_frac" << "tag_dfrac" << "tag_tfrac"
1935             << "tag_binom" << "tag_dbinom" << "tag_tbinom"
1936             << "tag_xleftarrow" << "tag_xrightarrow"
1937             << "tag_mathrm" << "tag_mathit" << "tag_mathbf" << "tag_mathsf"
1938             << "tag_mathtt" << "tag_mathcal" << "tag_mathbb" << "tag_mathfrak"
1939             << "tag_acute" << "tag_grave" << "tag_tilde" << "tag_bar" << "tag_vec"
1940             << "tag_hat" << "tag_check" << "tag_breve" << "tag_dot" << "tag_ddot"
1941             << "tag_space_small" << "tag_space_medium" << "tag_space_large"
1942             << "tag_quad" << "tag_qquad" << "tag_enskip"
1943             << "tag_env_displaymath" << "tag_env_equation" << "tag_env_equation*"
1944             << "tag_env_array"
1945             << "tag_env_multline" << "tag_env_multline*" << "tag_env_split"
1946             << "tag_env_gather" << "tag_env_gather*" << "tag_env_align" << "tag_env_align*"
1947             << "tag_env_flalign" << "tag_env_flalign*" << "tag_env_alignat" << "tag_env_alignat*"
1948             << "tag_env_aligned" << "tag_env_gathered" << "tag_env_alignedat" << "tag_env_cases"
1949             << "tag_env_matrix" << "tag_env_pmatrix" << "tag_env_vmatrix"
1950             << "tag_env_VVmatrix" << "tag_env_bmatrix" << "tag_env_BBmatrix"
1951             // bibliography stuff
1952             << "menu_bibliography"
1953             << "setting_bibtex" << "setting_biblatex"
1954             << "tag_textit" << "tag_textsl" << "tag_textbf" << "tag_underline"
1955             << "tag_texttt" << "tag_textsc" << "tag_emph" << "tag_strong"
1956             << "tag_rmfamily" << "tag_sffamily" << "tag_ttfamily"
1957             << "tag_mdseries" << "tag_bfseries" << "tag_upshape"
1958             << "tag_itshape" << "tag_slshape" << "tag_scshape"
1959             << "tag_newline" << "tag_newpage" << "tag_linebreak" << "tag_pagebreak"
1960             << "tag_bigskip" << "tag_medskip" << "tag_smallskip"
1961             << "tag_hspace" << "tag_hspace*" << "tag_vspace" << "tag_vspace*"
1962             << "tag_hfill" << "tag_hrulefill" << "tag_dotfill" << "tag_vfill"
1963             << "tag_includegraphics" << "tag_include" << "tag_input"
1964             // wizard
1965             << "wizard_tabular" << "wizard_array" << "wizard_tabbing"
1966             << "wizard_float" << "wizard_mathenv"
1967             << "wizard_usermenu" << "wizard_usermenu2"
1968             // settings
1969             << "Mode"
1970             // help
1971             << "help_context"
1972             // action lists
1973             << "structure_list" << "size_list" << "other_list"
1974             << "left_list" << "right_list"
1975             // tool lists
1976             << "list_compiler_select" << "list_convert_select" << "list_view_select" << "list_quick_select"
1977             // user help
1978             << "help_userhelp"
1979             << "edit_next_bullet" << "edit_prev_bullet"
1980             << "edit_next_section" << "edit_prev_section" << "edit_next_paragraph" << "edit_prev_paragraph"
1981 
1982             << "edit_select_inside_env" << "edit_select_outside_env" << "edit_select_inside_group"
1983             << "edit_select_outside_group" << "edit_select_mathgroup" << "edit_select_paragraph"
1984             << "edit_select_line" << "edit_select_word"
1985 
1986             << "edit_delete_inside_env" << "edit_delete_outside_env" << "edit_delete_inside_group"
1987             << "edit_delete_outside_group" << "edit_delete_mathgroup" << "edit_delete_paragraph"
1988             << "edit_delete_eol" << "edit_delete_word"
1989 
1990             << "edit_complete_word" << "edit_complete_env" << "edit_complete_abbrev"
1991 
1992             << "edit_begin_env" << "edit_end_env" << "edit_match_env" << "edit_close_env" << "edit_closeall_env"
1993 
1994             << "edit_begin_group" << "edit_end_group" << "edit_match_group" << "edit_close_group"
1995 
1996             << "file_export_ascii" << "file_export_latin1" << "file_export_latin2" << "file_export_latin3"
1997             << "file_export_latin4" << "file_export_latin5" << "file_export_latin9" << "file_export_cp1250"
1998             << "file_export_cp1252"
1999             ;
2000 
2001     setMenuItems(projectlist,m_dictMenuProject);
2002     setMenuItems(filelist,m_dictMenuFile);
2003     setMenuItems(actionlist,m_dictMenuAction);
2004 }
2005 
2006 void Kile::setMenuItems(QStringList &list, QMap<QString,bool> &dict)
2007 {
2008     for ( QStringList::Iterator it=list.begin(); it!=list.end(); ++it ) {
2009         dict[(*it)] = true;
2010     }
2011 }
2012 
2013 void Kile::updateMenu()
2014 {
2015     KILE_DEBUG_MAIN << "==Kile::updateMenu()====================" << Qt::endl;
2016     QAction *a;
2017     QMap<QString,bool>::Iterator it;
2018 
2019     // update project menus
2020     m_actRecentProjects->setEnabled( m_actRecentProjects->items().count() > 0 );
2021     bool project_open = ( docManager()->isProjectOpen() ) ;
2022 
2023     for ( it=m_dictMenuProject.begin(); it!=m_dictMenuProject.end(); ++it ) {
2024         a = actionCollection()->action(it.key());
2025         if(a) {
2026             a->setEnabled(project_open);
2027         }
2028     }
2029 
2030     // project_show is only enabled, when more than 1 project is opened
2031     a = actionCollection()->action("project_show");
2032     if(a) {
2033         a->setEnabled(project_open && docManager()->projects().count() > 1);
2034     }
2035 
2036     // update file menus
2037     m_actRecentFiles->setEnabled( m_actRecentFiles->items().count() > 0 );
2038     bool file_open = ( viewManager()->currentTextView() );
2039     KILE_DEBUG_MAIN << "\tprojectopen=" << project_open << " fileopen=" << file_open << Qt::endl;
2040 
2041     enableGUI(file_open);
2042 }
2043 
2044 bool Kile::updateMenuActivationStatus(QMenu *menu)
2045 {
2046     return updateMenuActivationStatus(menu, QSet<QMenu*>());
2047 }
2048 
2049 
2050 bool Kile::updateMenuActivationStatus(QMenu *menu, const QSet<QMenu*>& visited)
2051 {
2052     if(visited.contains(menu)) {
2053         qWarning() << "Recursive menu structure detected - aborting!";
2054         return true;
2055     }
2056     if(menu->objectName() == "usermenu-submenu") {
2057         menu->setEnabled(true);
2058         return true;
2059     }
2060 
2061     bool enabled = false;
2062     QList<QAction*> actionList = menu->actions();
2063 
2064     for(QList<QAction*>::iterator it = actionList.begin(); it != actionList.end(); ++it) {
2065         QAction *action = *it;
2066         QMenu *subMenu = action->menu();
2067         if(subMenu) {
2068             QSet<QMenu*> newVisited(visited);
2069             newVisited.insert(menu);
2070             if(updateMenuActivationStatus(subMenu, newVisited)) {
2071                 enabled = true;
2072             }
2073         }
2074         else if(!action->isSeparator() && action->isEnabled()) {
2075             enabled = true;
2076         }
2077     }
2078     menu->setEnabled(enabled);
2079     return enabled;
2080 }
2081 
2082 void Kile::updateLatexenuActivationStatus(QMenu *menu, bool state)
2083 {
2084     if ( menu->isEmpty() || !viewManager()->currentTextView() ) {
2085         state = false;
2086     }
2087     menu->menuAction()->setVisible(state);
2088 }
2089 
2090 void Kile::runTool(const QString& tool)
2091 {
2092     runToolWithConfig(tool, QString());
2093 }
2094 
2095 void Kile::runToolWithConfig(const QString &toolName, const QString &config)
2096 {
2097     KILE_DEBUG_MAIN << toolName << config;
2098 
2099     focusLog();
2100     KileTool::Base *tool = m_manager->createTool(toolName, config);
2101 
2102     if(!tool || (tool->requestSaveAll() && !m_docManager->fileSaveAll())) {
2103         delete tool;
2104         return;
2105     }
2106 
2107     return m_manager->run(tool);
2108 }
2109 
2110 void Kile::cleanAll(KileDocument::TextInfo *docinfo)
2111 {
2112     const QString noactivedoc = i18n("There is no active document or it is not saved.");
2113     if(!docinfo) {
2114         KTextEditor::Document *doc = activeTextDocument();
2115         if (doc) {
2116             docinfo = docManager()->textInfoFor(doc);
2117         }
2118         else {
2119             errorHandler()->printMessage(KileTool::Error, noactivedoc, i18n("Clean"));
2120             return;
2121         }
2122     }
2123 
2124     if (docinfo) {
2125         docManager()->cleanUpTempFiles(docinfo->url(), false);
2126     }
2127 }
2128 
2129 void Kile::refreshStructure()
2130 {
2131     viewManager()->updateStructure(true);
2132 }
2133 
2134 void Kile::insertTag(const KileAction::TagData& data)
2135 {
2136     errorHandler()->clearMessages();
2137 
2138     if(data.description.length() > 0) {
2139         focusLog();
2140         errorHandler()->printMessage(data.description);
2141     }
2142 
2143     KTextEditor::View *view = viewManager()->currentTextView();
2144 
2145     if(!view) {
2146         return;
2147     }
2148 
2149     focusTextView(view);
2150 
2151     editorExtension()->insertTag(data, view);
2152 }
2153 
2154 void Kile::insertTag(const QString& tagB, const QString& tagE, int dx, int dy)
2155 {
2156     insertTag(KileAction::TagData(QString(), tagB, tagE, dx, dy));
2157 }
2158 
2159 void Kile::insertAmsTag(const KileAction::TagData& data)
2160 {
2161     insertTag(data, QStringList("amsmath"));
2162 }
2163 
2164 void Kile::insertTag(const KileAction::TagData& data,const QList<Package> &pkgs) {
2165 
2166     QStringList packages;
2167 
2168     for(const Package& pkg : pkgs) {
2169         if(!pkg.name.isEmpty()) {
2170             packages.append(pkg.name);
2171         }
2172     }
2173 
2174     insertTag(data,packages);
2175 }
2176 
2177 void Kile::insertTag(const KileAction::TagData& data,const QStringList &pkgs)
2178 {
2179     KILE_DEBUG_MAIN << "void Kile::insertTag(const KileAction::TagData& data,const QStringList " << pkgs.join(",") << ")" << Qt::endl;
2180     insertTag(data);
2181 
2182     KileDocument::TextInfo *docinfo = docManager()->textInfoFor(getCompileName());
2183     if(docinfo) {
2184         QStringList packagelist = allPackages(docinfo);
2185         QStringList::const_iterator it;
2186         QStringList warnPkgs;
2187 
2188         for ( it = pkgs.begin(); it != pkgs.end(); ++it) {
2189             if(!packagelist.contains(*it)) {
2190                 warnPkgs.append(*it);
2191             }
2192         }
2193 
2194         if(warnPkgs.count() > 0) {
2195             if(warnPkgs.count() == 1) {
2196                 errorHandler()->printMessage(KileTool::Error, i18n("You have to include the package %1.", warnPkgs.join(",")), i18n("Insert text"));
2197             }
2198             else {
2199                 errorHandler()->printMessage(KileTool::Error, i18n("You have to include the packages %1.", warnPkgs.join(",")), i18n("Insert text"));
2200             }
2201         }
2202     }
2203 }
2204 
2205 void Kile::insertText(const QString &text)
2206 {
2207     if(text.indexOf("%C")>=0)
2208         insertTag(KileAction::TagData(QString(), text, QString(), 0, 0));
2209     else
2210         insertTag(KileAction::TagData(QString(), text, "%C", 0, 0));
2211 }
2212 
2213 void Kile::insertText(const QString &text, const QStringList &pkgs)
2214 {
2215     insertTag(KileAction::TagData(QString(), text, "%C", 0, 0), pkgs);
2216 }
2217 
2218 void Kile::insertText(const QString &text, const QList<Package> &pkgs)
2219 {
2220     insertTag(KileAction::TagData(QString(), text, "%C", 0, 0), pkgs);
2221 }
2222 
2223 void Kile::quickDocument()
2224 {
2225     KileDialog::QuickDocument *dlg = new KileDialog::QuickDocument(m_config.data(), this, "Quick Start", i18n("Quick Start"));
2226 
2227     if(dlg->exec()) {
2228         if(!viewManager()->currentTextView()) {
2229             docManager()->createNewLaTeXDocument();
2230         }
2231         insertTag( dlg->tagData() );
2232         viewManager()->updateStructure(true);
2233     }
2234     delete dlg;
2235 }
2236 
2237 void Kile::quickArray()
2238 {
2239     quickTabulardialog(false);
2240 }
2241 
2242 void Kile::quickTabular()
2243 {
2244     quickTabulardialog(true);
2245 }
2246 
2247 void Kile::quickTabulardialog(bool tabularenv)
2248 {
2249     if(!viewManager()->currentTextView()) {
2250         return;
2251     }
2252 
2253     QString env;
2254     if(tabularenv) {
2255         KConfigGroup group = m_config->group("Wizard");
2256         env = group.readEntry("TabularEnvironment", "tabular");
2257     } else {
2258         env = "array";
2259     }
2260 
2261     KileDialog::NewTabularDialog dlg(env, m_latexCommands, m_config.data(), this);
2262     if(dlg.exec()) {
2263         insertTag(dlg.tagData(), dlg.requiredPackages());
2264         if(tabularenv) {
2265             KConfigGroup group = m_config->group("Wizard");
2266             group.writeEntry("TabularEnvironment", dlg.environment());
2267             m_config->sync();
2268         }
2269     }
2270 }
2271 
2272 void Kile::quickTabbing()
2273 {
2274     if(!viewManager()->currentTextView()) {
2275         return;
2276     }
2277     KileDialog::QuickTabbing *dlg = new KileDialog::QuickTabbing(m_config.data(), this, this, "Tabbing", i18n("Tabbing"));
2278     if(dlg->exec()) {
2279         insertTag(dlg->tagData());
2280     }
2281     delete dlg;
2282 }
2283 
2284 void Kile::quickFloat()
2285 {
2286     if(!viewManager()->currentTextView()) {
2287         return;
2288     }
2289 
2290     KileDialog::FloatEnvironmentDialog *dlg = new KileDialog::FloatEnvironmentDialog(m_config.data(), this, this);
2291     if(dlg->exec()) {
2292         insertTag(dlg->tagData());
2293     }
2294     delete dlg;
2295 }
2296 
2297 void Kile::quickMathenv()
2298 {
2299     if(!viewManager()->currentTextView()) {
2300         return;
2301     }
2302 
2303     KileDialog::MathEnvironmentDialog *dlg = new KileDialog::MathEnvironmentDialog(this, m_config.data(), this, m_latexCommands);
2304     if(dlg->exec()) {
2305         insertTag(dlg->tagData());
2306     }
2307     delete dlg;
2308 }
2309 
2310 void Kile::quickPostscript()
2311 {
2312     QString startdir = QDir::homePath();
2313     QString texfilename;
2314 
2315     KTextEditor::View *view = viewManager()->currentTextView();
2316     if(view) {
2317         startdir = QFileInfo(view->document()->url().toLocalFile()).path();
2318         texfilename = getCompileName();
2319     }
2320 
2321     KileDialog::PostscriptDialog *dlg = new KileDialog::PostscriptDialog(this, texfilename, startdir, m_extensions->latexDocuments(), errorHandler(), m_outputWidget);
2322     dlg->exec();
2323     delete dlg;
2324 }
2325 
2326 void Kile::quickPdf()
2327 {
2328     QString startDir = QDir::homePath();
2329     QString texFileName;
2330 
2331     KTextEditor::View *view = viewManager()->currentTextView();
2332     if(view) {
2333         startDir = QFileInfo(view->document()->url().toLocalFile()).path();
2334         texFileName = getCompileName();
2335     }
2336 
2337     KileDialog::PdfDialog *dlg = new KileDialog::PdfDialog(m_mainWindow, texFileName, startDir, m_extensions->latexDocuments(), m_manager, errorHandler(), m_outputWidget);
2338     connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
2339 
2340     dlg->open();
2341 }
2342 
2343 void Kile::quickUserMenuDialog()
2344 {
2345     m_userMenu->removeShortcuts();
2346     QPointer<KileMenu::UserMenuDialog> dlg = new KileMenu::UserMenuDialog(m_config.data(), this, m_userMenu, m_userMenu->xmlFile(), m_mainWindow);
2347 
2348     dlg->exec();
2349 
2350     connect(dlg, &QDialog::finished, this, [this] (int result) {
2351         Q_UNUSED(result);
2352 
2353         // tell all the documents and views to update their action shortcuts (bug 247646)
2354         docManager()->reloadXMLOnAllDocumentsAndViews();
2355 
2356         // a new usermenu could have been installed, even if the return value is QDialog::Rejected
2357         m_userMenu->refreshActionProperties();
2358     });
2359 
2360     delete dlg;
2361 }
2362 
2363 void Kile::slotUpdateUserMenuStatus()
2364 {
2365     KILE_DEBUG_MAIN << "slot update usermenu status";
2366     updateUserMenuStatus(true);
2367 }
2368 
2369 void Kile::updateUserMenuStatus(bool state)
2370 {
2371     KILE_DEBUG_MAIN << "update usermenu status";
2372 
2373     if(m_userMenu) {
2374         QMenu *menu = m_userMenu->getMenuItem();
2375         if(menu) {
2376             updateLatexenuActivationStatus(menu,state);
2377         }
2378     }
2379 }
2380 
2381 void Kile::readGUISettings()
2382 {
2383 }
2384 
2385 // transform old user tags to xml file
2386 void Kile::transformOldUserTags()
2387 {
2388     KILE_DEBUG_MAIN << "Convert old user tags";
2389     QString xmldir = KileUtilities::writableLocation(QStandardPaths::AppDataLocation) + "/usermenu/";
2390     // create dir if not existing
2391     QDir testDir(xmldir);
2392     if (!testDir.exists()) {
2393         testDir.mkpath(xmldir);
2394     }
2395 
2396     KConfigGroup userGroup = m_config->group("User");
2397     int len = userGroup.readEntry("nUserTags", 0);
2398 
2399     if ( len > 0) {
2400         QString usertagfile = "usertags.xml";
2401         QString  filename = xmldir + usertagfile;
2402         KILE_DEBUG_MAIN << "-convert user tags " << filename;
2403 
2404         QFile file(filename);
2405         if ( !file.open(QFile::WriteOnly | QFile::Text) ) {
2406             KILE_DEBUG_MAIN << "-Error - could not open file to write: " << filename;
2407             return;
2408         }
2409 
2410         KILE_DEBUG_MAIN << "Write xml: " << filename;
2411         QXmlStreamWriter xml(&file);
2412         xml.setAutoFormatting(true);
2413         xml.setAutoFormattingIndent(2) ;
2414 
2415         xml.writeStartDocument();
2416         xml.writeStartElement("UserMenu");
2417 
2418         for (int i = 0; i < len; ++i) {
2419             const QString tagNameConfigKey = "userTagName" + QString::number(i);
2420             const QString tagname = userGroup.readEntry(tagNameConfigKey, i18n("No Name"));
2421             const QString tagConfigKey = "userTag" + QString::number(i);
2422             QString tag = userGroup.readEntry(tagConfigKey, "");
2423             tag = tag.replace('\n',"\\n");
2424 
2425             xml.writeStartElement("menu");
2426             xml.writeAttribute("type", "text");
2427             xml.writeTextElement(KileMenu::UserMenuData::xmlMenuTagName(KileMenu::UserMenuData::XML_TITLE), tagname);
2428             xml.writeTextElement(KileMenu::UserMenuData::xmlMenuTagName(KileMenu::UserMenuData::XML_PLAINTEXT), tag);
2429             xml.writeTextElement(KileMenu::UserMenuData::xmlMenuTagName(KileMenu::UserMenuData::XML_SHORTCUT), QString("Ctrl+Shift+%1").arg(i+1));
2430             xml.writeEndElement();
2431 
2432             userGroup.deleteEntry(tagNameConfigKey);
2433             userGroup.deleteEntry(tagConfigKey);
2434         }
2435         xml.writeEndDocument();
2436         file.close();
2437 
2438         // save current xml file
2439         KileConfig::setUserMenuFile(usertagfile);
2440     }
2441     userGroup.deleteEntry("nUserTags");
2442 }
2443 
2444 void Kile::transformOldUserSettings()
2445 {
2446     //delete old editor key
2447     if(m_config->hasGroup("Editor")) {
2448         m_config->deleteGroup("Editor");
2449     }
2450 
2451     //convert user tools to new KileTool classes
2452     KConfigGroup userGroup = m_config->group("User");
2453     userItem tempItem;
2454     int len = userGroup.readEntry("nUserTools", 0);
2455     for (int i=0; i< len; ++i) {
2456         tempItem.name = userGroup.readEntry("userToolName" + QString::number(i), i18n("no name"));
2457         tempItem.tag = userGroup.readEntry("userTool" + QString::number(i), "");
2458         m_listUserTools.append(tempItem);
2459     }
2460     if(len > 0) {
2461         //move the tools
2462         userGroup.writeEntry("nUserTools", 0);
2463         for(int i = 0; i < len; ++i) {
2464             tempItem = m_listUserTools[i];
2465             KConfigGroup toolsGroup = m_config->group("Tools");
2466             toolsGroup.writeEntry(tempItem.name, "Default");
2467 
2468             KileTool::setGUIOptions(tempItem.name, "Other", "preferences-other", m_config.data());
2469 
2470             KConfigGroup group = m_config->group(KileTool::groupFor(tempItem.name, "Default"));
2471             QString bin = KIO::DesktopExecParser::executablePath(tempItem.tag);
2472             group.writeEntry("command", bin);
2473             group.writeEntry("options", tempItem.tag.mid(bin.length()));
2474             group.writeEntry("class", "Base");
2475             group.writeEntry("type", "Process");
2476             group.writeEntry("from", "");
2477             group.writeEntry("to", "");
2478 
2479             if(i < 10) {
2480                 QAction *toolAction = static_cast<QAction*>(actionCollection()->action("tool_" + tempItem.name));
2481                 actionCollection()->setDefaultShortcut(toolAction, "Alt+Shift+" + QString::number(i + 1)); //should be alt+shift+
2482             }
2483         }
2484     }
2485 }
2486 
2487 void Kile::readRecentFileSettings()
2488 {
2489     KConfigGroup group = m_config->group("FilesOpenOnStart");
2490     int n = group.readEntry("NoDOOS", 0);
2491     for (int i = 0; i < n; ++i) {
2492         const QString urlString = group.readPathEntry("DocsOpenOnStart" + QString::number(i), "");
2493         if(urlString.isEmpty()) {
2494             continue;
2495         }
2496         m_listDocsOpenOnStart.append(urlString);
2497         m_listEncodingsOfDocsOpenOnStart.append(group.readPathEntry("EncodingsOfDocsOpenOnStart" + QString::number(i), ""));
2498     }
2499 
2500     n = group.readEntry("NoPOOS", 0);
2501     for(int i = 0; i < n; ++i) {
2502         const QString urlString = group.readPathEntry("ProjectsOpenOnStart" + QString::number(i), "");
2503         if(urlString.isEmpty()) {
2504             continue;
2505         }
2506         m_listProjectsOpenOnStart.append(urlString);
2507     }
2508 }
2509 
2510 void Kile::readConfig()
2511 {
2512     m_codeCompletionManager->readConfig(m_config.data());
2513 
2514     if(m_livePreviewManager) {
2515         m_livePreviewManager->readConfig(m_config.data());
2516     }
2517 
2518     //m_edit->initDoubleQuotes();
2519     m_edit->readConfig();
2520     docManager()->updateInfos();
2521     m_jScriptManager->readConfig();
2522     docManager()->readConfig();
2523     viewManager()->readConfig(m_horizontalSplitter);
2524 
2525     // set visible views in sidebar
2526     m_sideBar->setPageVisible(m_scriptsManagementWidget, KileConfig::scriptingEnabled());
2527     m_sideBar->setPageVisible(m_commandViewToolBox, KileConfig::showCwlCommands());
2528     m_sideBar->setPageVisible(m_kileAbbrevView, KileConfig::completeShowAbbrev());
2529 
2530     m_scriptsManagementWidget->setScriptNameColumnWidth(KileConfig::scriptNameColumnWidth());
2531 
2532     if(KileConfig::displayMFUS()) {
2533         enableSymbolViewMFUS();
2534     }
2535     else {
2536         disableSymbolViewMFUS();
2537     }
2538     m_commandViewToolBox->readCommandViewFiles();
2539     abbreviationManager()->readAbbreviationFiles();
2540 }
2541 
2542 void Kile::saveSettings()
2543 {
2544     m_fileBrowserWidget->writeConfig();
2545 
2546     if(m_livePreviewManager) {
2547         m_livePreviewManager->writeConfig();
2548     }
2549 
2550     m_symbolViewMFUS->writeConfig();
2551     saveLastSelectedAction();
2552     // Store recent files
2553     m_actRecentFiles->saveEntries(m_config->group("Recent Files"));
2554     m_actRecentProjects->saveEntries(m_config->group("Projects"));
2555 
2556     m_config->deleteGroup("FilesOpenOnStart");
2557     if (KileConfig::restore())
2558     {
2559         KConfigGroup configGroup = m_config->group("FilesOpenOnStart");
2560         KileConfig::setSingleFileMasterDocument(getMasterDocumentFileName());
2561         configGroup.writeEntry("NoDOOS", m_listDocsOpenOnStart.count());
2562         for (int i = 0; i < m_listDocsOpenOnStart.count(); ++i) {
2563             configGroup.writePathEntry("DocsOpenOnStart" + QString::number(i), m_listDocsOpenOnStart[i]);
2564             configGroup.writePathEntry("EncodingsOfDocsOpenOnStart" + QString::number(i), m_listEncodingsOfDocsOpenOnStart[i]);
2565         }
2566 
2567         configGroup.writeEntry("NoPOOS", m_listProjectsOpenOnStart.count());
2568         for (int i = 0; i < m_listProjectsOpenOnStart.count(); ++i) {
2569             configGroup.writePathEntry("ProjectsOpenOnStart"+QString::number(i), m_listProjectsOpenOnStart[i]);
2570         }
2571     }
2572 
2573     KConfigGroup configGroup = KSharedConfig::openConfig()->group("KileMainWindow");
2574     saveMainWindowSettings(configGroup);
2575 
2576     docManager()->writeConfig();
2577     viewManager()->writeConfig();
2578 
2579     scriptManager()->writeConfig();
2580     KileConfig::setScriptNameColumnWidth(m_scriptsManagementWidget->scriptNameColumnWidth());
2581 
2582     KileConfig::setRCVersion(KILERC_VERSION);
2583     KileConfig::setMainwindowWidth(width());
2584     KileConfig::setMainwindowHeight(height());
2585 
2586     QList<int> sizes;
2587     QList<int>::Iterator it;
2588     sizes = m_horizontalSplitter->sizes();
2589     it = sizes.begin();
2590     KileConfig::setHorizontalSplitterLeft(*it);
2591     ++it;
2592     KileConfig::setHorizontalSplitterRight(*it);
2593     sizes.clear();
2594     sizes = m_verticalSplitter->sizes();
2595     it = sizes.begin();
2596     KileConfig::setVerticalSplitterTop(*it);
2597     ++it;
2598     KileConfig::setVerticalSplitterBottom(*it);
2599 
2600     KileConfig::setSideBar(!m_sideBar->isHidden()); // do not use 'isVisible()'!
2601     KileConfig::setSideBarSize(m_sideBar->directionalSize());
2602     KileConfig::setBottomBar(!m_bottomBar->isHidden()); // do not use 'isVisible()'!
2603     KileConfig::setBottomBarSize(m_bottomBar->directionalSize());
2604     KileConfig::setBottomBarIndex(m_bottomBar->currentTab());
2605 
2606     KileConfig::setSelectedLeftView(m_sideBar->currentTab());
2607 
2608     abbreviationManager()->saveLocalAbbreviations();
2609 
2610     KileConfig::self()->save();
2611     m_config->sync();
2612 }
2613 
2614 /////////////////  OPTIONS ////////////////////
2615 void Kile::setMasterDocumentFileName(const QString& fileName)
2616 {
2617     if(fileName.isEmpty() || !viewManager()->viewForLocalFilePresent(fileName)) {
2618         return;
2619     }
2620 
2621     m_masterDocumentFileName = fileName;
2622 
2623     QString shortName = QFileInfo(m_masterDocumentFileName).fileName();
2624 
2625     ModeAction->setText(i18n("Normal mode (current master document: %1)", shortName));
2626     ModeAction->setChecked(true);
2627     m_singlemode = false;
2628     updateModeStatus();
2629     emit masterDocumentChanged();
2630     KILE_DEBUG_MAIN << "SETTING master to " << m_masterDocumentFileName << " singlemode = " << m_singlemode << Qt::endl;
2631 }
2632 
2633 void Kile::clearMasterDocument()
2634 {
2635     ModeAction->setText(i18n("Define Current Document as 'Master Document'"));
2636     ModeAction->setChecked(false);
2637     m_singlemode = true;
2638     m_masterDocumentFileName.clear();
2639     updateModeStatus();
2640     emit masterDocumentChanged();
2641     KILE_DEBUG_MAIN << "CLEARING master document";
2642 }
2643 
2644 void Kile::toggleMasterDocumentMode()
2645 {
2646     if (!m_singlemode) {
2647         clearMasterDocument();
2648     }
2649     else if (m_singlemode && viewManager()->currentTextView()) {
2650         QString name = getName();
2651         if(name.isEmpty()) {
2652             ModeAction->setChecked(false);
2653             KMessageBox::error(this, i18n("In order to define the current document as a master document, it has to be saved first."));
2654             return;
2655         }
2656         setMasterDocumentFileName(name);
2657     }
2658     else {
2659         ModeAction->setChecked(false);
2660         updateModeStatus();
2661     }
2662 }
2663 
2664 void Kile::toggleWatchFile()
2665 {
2666     m_bWatchFile=!m_bWatchFile;
2667 
2668     if (m_bWatchFile) {
2669         WatchFileAction->setChecked(true);
2670     }
2671     else {
2672         WatchFileAction->setChecked(false);
2673     }
2674 }
2675 
2676 // execute configuration dialog
2677 
2678 void Kile::generalOptions()
2679 {
2680     KileDialog::Config *dlg = new KileDialog::Config(m_config.data(), this, this);
2681     KileUtilities::scheduleCenteringOfWidget(dlg);
2682 
2683     if (dlg->exec()) {
2684         // update new settings
2685         readConfig();
2686         saveLastSelectedAction(); // save the old current tools before calling setupTools() which calls restoreLastSelectedActions()
2687         setupTools();
2688         m_help->update();
2689         newCaption(); // for the 'showFullPathInWindowTitle' setting
2690 
2691         configurationManager()->emitConfigChanged();
2692 
2693         //stop/restart LyX server if necessary
2694         if(KileConfig::runLyxServer() && !m_lyxserver->isRunning()) {
2695             m_lyxserver->start();
2696         }
2697 
2698         if(!KileConfig::runLyxServer() && m_lyxserver->isRunning()) {
2699             m_lyxserver->stop();
2700         }
2701     }
2702 
2703     delete dlg;
2704 }
2705 
2706 void Kile::slotPerformCheck()
2707 {
2708     // first we have to disable the live preview that may be running, and clear the master document
2709     const bool livePreviewEnabledForFreshlyOpenedDocuments = KileConfig::previewEnabledForFreshlyOpenedDocuments();
2710     const bool livePreviewEnabledForCurrentDocument = livePreviewManager() && livePreviewManager()->isLivePreviewEnabledForCurrentDocument();
2711     if (livePreviewManager()) {
2712         KileConfig::setPreviewEnabledForFreshlyOpenedDocuments(false);
2713         livePreviewManager()->setLivePreviewEnabledForCurrentDocument(false);
2714     }
2715 
2716     // we show the message output widget in the bottom bar and shrink the side bar
2717     int sideBarTab = m_sideBar->currentTab();
2718     int bottomBarTab = m_bottomBar->currentTab();
2719 
2720     m_sideBar->shrink();
2721     m_bottomBar->switchToTab(0); // show the log widget
2722 
2723     int outputTab = m_errorHandler->currentOutputTabIndex();
2724     m_errorHandler->showMessagesOutput();
2725 
2726     QString currentMasterDocument = m_masterDocumentFileName;
2727     if(!m_singlemode) {
2728         clearMasterDocument();
2729     }
2730     // we hide the editor pane and tabs
2731     m_viewManager->setTabsAndEditorVisible(false);
2732 
2733     // now, we can run the tests
2734     KileDialog::ConfigChecker *dlg = new KileDialog::ConfigChecker(this);
2735     dlg->exec();
2736     delete dlg;
2737 
2738     m_errorHandler->clearMessages();
2739     m_errorHandler->clearErrorOutput();
2740 
2741     // finally, we restore the rest to what it was before launching the tests
2742     m_viewManager->setTabsAndEditorVisible(true);
2743     if(!currentMasterDocument.isEmpty()) {
2744         setMasterDocumentFileName(currentMasterDocument);
2745     }
2746 
2747     m_errorHandler->setCurrentOutputTab(outputTab);
2748 
2749     if(sideBarTab >= 0) {
2750         m_sideBar->switchToTab(sideBarTab);
2751     }
2752     if(bottomBarTab < 0) {
2753         m_bottomBar->shrink();
2754     }
2755     else {
2756         m_bottomBar->switchToTab(bottomBarTab);
2757     }
2758 
2759     if (livePreviewManager()) {
2760         KileConfig::setPreviewEnabledForFreshlyOpenedDocuments(livePreviewEnabledForFreshlyOpenedDocuments);
2761         if(livePreviewEnabledForCurrentDocument) {
2762             livePreviewManager()->setLivePreviewEnabledForCurrentDocument(true);
2763         }
2764     }
2765 }
2766 
2767 void Kile::aboutEditorComponent()
2768 {
2769     KTextEditor::Editor *editor = m_docManager->getEditor();
2770     if(!editor) {
2771         return;
2772     }
2773     KAboutApplicationDialog dialog(editor->aboutData(), this);
2774     dialog.exec();
2775 }
2776 
2777 /////////////// KEYS - TOOLBARS CONFIGURATION ////////////////
2778 void Kile::configureKeys()
2779 {
2780     KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this);
2781 // due to bug 280988, we can't add all the clients...
2782 //  QList<KXMLGUIClient*> clients = guiFactory()->clients();
2783 //  for(QList<KXMLGUIClient*>::iterator it = clients.begin(); it != clients.end(); ++it) {
2784 //      dlg.addCollection((*it)->actionCollection());
2785 //  }
2786     dlg.addCollection(mainWindow()->actionCollection());
2787     KTextEditor::View *view = m_viewManager->currentTextView();
2788     if(view) {
2789         dlg.addCollection(view->actionCollection());
2790     }
2791     KParts::ReadOnlyPart *part = viewManager()->viewerPart();
2792     if(part) {
2793         dlg.addCollection(part->actionCollection());
2794     }
2795     connect(&dlg, &KShortcutsDialog::saved, this, [this]() {
2796         // tell all the documents and views to update their action shortcuts (bug 247646)
2797         docManager()->reloadXMLOnAllDocumentsAndViews();
2798 
2799         // tell m_userMenu that key bindings may have been changed
2800         m_userMenu->updateKeyBindings();
2801 
2802         // transfer the shortcuts to the scripts
2803         const QList<KileScript::Script*> scripts = scriptManager()->getScripts();
2804         for(KileScript::Script *script : scripts) {
2805             QAction *action = script->getActionObject();
2806 
2807             if(action && !action->shortcut().isEmpty()) {
2808                 scriptManager()->setShortcut(script, action->shortcut());
2809             }
2810         }
2811 
2812         scriptManager()->writeConfig();
2813         m_scriptsManagementWidget->update();
2814     });
2815     dlg.configure();
2816 }
2817 
2818 void Kile::configureToolbars()
2819 {
2820     {
2821         KConfigGroup configGroup = KSharedConfig::openConfig()->group("KileMainWindow");
2822         saveMainWindowSettings(configGroup);
2823     }
2824 
2825     KEditToolBar dlg(factory());
2826     connect(&dlg, &KEditToolBar::newToolBarConfig, this, [this] () {
2827         setUpdatesEnabled(false);
2828         applyMainWindowSettings(m_config->group("KileMainWindow"));
2829 
2830         updateUserDefinedMenus();
2831         setUpdatesEnabled(true);
2832     });
2833     dlg.exec();
2834 }
2835 
2836 //////////////////// CLEAN BIB /////////////////////
2837 void Kile::cleanBib()
2838 {
2839     KTextEditor::View *view = viewManager()->currentTextView();
2840     if ( ! view )
2841         return;
2842 
2843     QRegExp reOptional( "(ALT|OPT)(\\w+)\\s*=\\s*(\\S.*)" );
2844     QRegExp reNonEmptyEntry( ".*\\w.*" );
2845 
2846     QString s;
2847     int i = 0;
2848     while(i < view->document()->lines()) {
2849         s = view->document()->line(i);
2850 
2851         // do we have a line that starts with ALT or OPT?
2852         if(reOptional.indexIn(s) >= 0) {
2853             // yes! capture type and entry
2854             QString type = reOptional.cap( 2 );
2855             QString entry = reOptional.cap( 3 );
2856             view->document()->removeLine( i );
2857             view->document()->setModified(true);
2858             if(reNonEmptyEntry.indexIn(entry) >= 0) {
2859                 type.append(" = ");
2860                 type.append(entry);
2861                 view->document()->insertLine(i, type);
2862                 ++i;
2863             }
2864         }
2865         else {
2866             ++i;
2867         }
2868     }
2869 
2870     for (i = 0; i < view->document()->lines(); ++i) {
2871         int j = i+1;
2872         if(j < view->document()->lines() && view->document()->line(j).contains(QRegExp("^\\s*\\}\\s*$"))) {
2873             s =  view->document()->line(i);
2874             view->document()->removeLine(i);
2875             s.remove(QRegExp(",\\s*$"));
2876             view->document()->setModified(true);
2877             view->document()->insertLine(i, s);
2878         }
2879     }
2880 }
2881 
2882 void Kile::includeGraphics()
2883 {
2884     KTextEditor::View *view = viewManager()->currentTextView();
2885     if ( !view ) return;
2886 
2887     QFileInfo fi( view->document()->url().toLocalFile() );
2888     KileDialog::IncludeGraphics *dialog = new KileDialog::IncludeGraphics(this, fi.path(), this);
2889 
2890     if ( dialog->exec() == QDialog::Accepted )
2891     {
2892         insertTag(dialog->getTemplate(), "%C", 0,0);
2893         docManager()->projectAddFile( dialog->getFilename(),true );
2894     }
2895 
2896     delete dialog;
2897 }
2898 
2899 void Kile::slotToggleFullScreen()
2900 {
2901     if (!m_pFullScreen->isChecked()) {
2902         setWindowState( windowState() & ~Qt::WindowFullScreen );
2903     }
2904     else {
2905         setWindowState( windowState() | Qt::WindowFullScreen );
2906     }
2907 }
2908 
2909 /////////////// QuickPreview (dani) ////////////////
2910 
2911 // all calls of QuickPreview will get here, so we can decide what to do
2912 // rewritten Sep 05 2006 to work together with preview in the bottom bar
2913 
2914 void Kile::slotQuickPreview(int type)
2915 {
2916     KILE_DEBUG_MAIN << "==Kile::slotQuickPreview()=========================="  << Qt::endl;
2917 
2918     KTextEditor::View *view = viewManager()->currentTextView();
2919     if ( ! view) return;
2920 
2921     KTextEditor::Document *doc = view->document();
2922     if ( ! doc )
2923         return;
2924 
2925     switch ( type )
2926     {
2927     case KileTool::qpSelection:
2928         m_quickPreview->previewSelection(view);
2929         break;
2930     case KileTool::qpEnvironment:
2931         m_quickPreview->previewEnvironment(doc);
2932         break;
2933     case KileTool::qpSubdocument:
2934         m_quickPreview->previewSubdocument(doc);
2935         break;
2936     case KileTool::qpMathgroup:
2937         m_quickPreview->previewMathgroup(doc);
2938         break;
2939     }
2940 }
2941 
2942 void Kile::addRecentFile(const QUrl &url)
2943 {
2944     m_actRecentFiles->addUrl(url);
2945 }
2946 
2947 void Kile::removeRecentFile(const QUrl &url)
2948 {
2949     m_actRecentFiles->removeUrl(url);
2950 }
2951 
2952 void Kile::addRecentProject(const QUrl &url)
2953 {
2954     m_actRecentProjects->addUrl(url);
2955 }
2956 
2957 void Kile::removeRecentProject(const QUrl &url)
2958 {
2959     m_actRecentProjects->removeUrl(url);
2960 }
2961 
2962 void Kile::updateStatusBarCursorPosition(KTextEditor::View *view,
2963         const KTextEditor::Cursor &newPosition)
2964 {
2965     if(!view) {
2966         statusBar()->clearLineColumn();
2967     }
2968     else {
2969         statusBar()->setLineColumn(newPosition.line() + 1, newPosition.column() + 1);
2970     }
2971 }
2972 
2973 void Kile::updateStatusBarViewMode(KTextEditor::View *view)
2974 {
2975     if(!view) {
2976         statusBar()->clearViewMode();
2977     }
2978     else {
2979         statusBar()->setViewMode(view->viewModeHuman());
2980     }
2981 }
2982 
2983 void Kile::updateStatusBarInformationMessage(KTextEditor::View * /* view */, const QString &message)
2984 {
2985     statusBar()->showMessage(message, 5000);
2986 }
2987 
2988 void Kile::updateStatusBarSelection(KTextEditor::View *view)
2989 {
2990     if(!view) {
2991         statusBar()->clearSelectionMode();
2992     }
2993     else {
2994         const QString text = view->blockSelection() ?
2995                              i18nc("@info:status status bar label for block selection mode", "BLOCK") + ' ' :
2996                              i18nc("@info:status status bar label for line selection mode", "LINE") + ' ';
2997         statusBar()->setSelectionMode(text);
2998     }
2999 }
3000 
3001 void Kile::handleDocumentParsingStarted()
3002 {
3003     statusBar()->setParserStatus(i18n("Refreshing structure..."));
3004 }
3005 
3006 void Kile::handleDocumentParsingComplete()
3007 {
3008     statusBar()->clearParserStatus();
3009 }
3010 
3011 void Kile::toggleShowMenuBar(bool showMessage)
3012 {
3013     if (m_actionShowMenuBar->isChecked()) {
3014         menuBar()->show();
3015         return;
3016     }
3017     
3018     if (showMessage) {
3019         const QString accel = m_actionShowMenuBar->shortcut().toString(QKeySequence::NativeText);
3020         KMessageBox::information(this,
3021                                     i18n("This will hide the menu bar completely."
3022                                         " You can show it again by typing %1.",
3023                                         accel),
3024                                     i18n("Hide menu bar"),
3025                                     QStringLiteral("HideMenuBarWarning"));
3026     }
3027     menuBar()->hide();
3028 }