1 /***************************************************************************************************
2     begin                : Wed Jun 6 2001
3     copyright            : (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
4                            (C) 2005-2007  by Holger Danielsson (holger.danielsson@versanet.de)
5                            (C) 2007-2016 by Michel Ludwig (michel.ludwig@kdemail.net)
6  ***************************************************************************************************/
7 
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 
17 #include "dialogs/configurationdialog.h"
18 
19 #include <QDialogButtonBox>
20 #include <QPushButton>
21 #include <QScreen>
22 #include <QTextCodec>
23 #include <QTimer>
24 #include <QVBoxLayout>
25 #include <QWindow>
26 
27 #include <KConfigGroup>
28 #include <KLocalizedString>
29 #include <KWindowConfig>
30 #include <KTextEditor/ConfigPage>
31 
32 #include "editorextension.h"
33 #include "errorhandler.h"
34 #include "kileconfig.h"
35 #include "kiledebug.h"
36 #include "kiledocmanager.h"
37 #include "kileinfo.h"
38 #include "kiletoolmanager.h"
39 #include "kileviewmanager.h"
40 
41 #include "widgets/appearanceconfigwidget.h"
42 #include "widgets/generalconfigwidget.h"
43 #include "widgets/helpconfigwidget.h"
44 #include "widgets/latexconfigwidget.h"
45 #include "widgets/livepreviewconfigwidget.h"
46 #include "widgets/previewconfigwidget.h"
47 #include "widgets/scriptingconfigwidget.h"
48 #include "widgets/scrollwidget.h"
49 #include "widgets/toolconfigwidget.h"
50 #include "widgets/usermenuconfigwidget.h"
51 
52 namespace KileDialog
53 {
Config(KConfig * config,KileInfo * ki,QWidget * parent)54 Config::Config(KConfig *config, KileInfo *ki, QWidget* parent)
55     : KPageDialog(parent),
56       m_config(config),
57       m_ki(ki)
58 {
59     setWindowTitle(i18n("Configure"));
60     setModal(true);
61     setObjectName("kileconfiguration");
62     setFaceType(Tree);
63 
64     m_config->sync();
65 
66     // we need a dialog manager
67     m_manager = new KConfigDialogManager(this,KileConfig::self());
68 
69     KPageWidgetItem* kilePageWidgetItem = addConfigFolder(i18n("Kile"), "kile");
70     KPageWidgetItem* latexPageWidgetItem = addConfigFolder(i18n("LaTeX"), "latex-config");
71     KPageWidgetItem* toolsPageWidgetItem = addConfigFolder(i18n("Tools"), "system-run");
72     KPageWidgetItem* editorPageWidgetItem = addConfigFolder(i18n("Editor"), "accessories-text-editor");
73 
74     // setup all configuration pages
75     setupGeneralOptions(kilePageWidgetItem);
76     setupAppearance(kilePageWidgetItem);
77     setupCodeCompletion(kilePageWidgetItem);   // complete configuration (dani)
78     setupHelp(kilePageWidgetItem);
79     setupScripting(kilePageWidgetItem);
80     setupUsermenu(kilePageWidgetItem);
81     setupLivePreview(kilePageWidgetItem);
82 
83     setupLatex(latexPageWidgetItem);
84     setupEnvironment(latexPageWidgetItem);
85     setupGraphics(latexPageWidgetItem);
86     setupStructure(latexPageWidgetItem);
87     setupSymbolView(latexPageWidgetItem);
88 
89     setupTools(toolsPageWidgetItem);
90     setupQuickPreview(toolsPageWidgetItem);     // QuickPreview (dani)
91 
92     setupEditor(editorPageWidgetItem);
93 
94     {
95         // every config page is added to a KileWidget::ScrollWidget, but all the scroll widgets should have
96         // the same size; first we find the maximal page size
97         QSize maximumSizeHint;
98         for(KPageWidgetItem *item : const_cast<const QList<KPageWidgetItem*>&>(m_pageWidgetItemList)) { // use 'qAsConst' later
99             QScrollArea *scrollArea = dynamic_cast<QScrollArea*>(item->widget());
100             if(!scrollArea) {
101                 qWarning() << "One scroll area not a KileWidget::ScrollWidget!";
102                 continue;
103             }
104             maximumSizeHint = maximumSizeHint.expandedTo(scrollArea->widget()->sizeHint());
105         }
106         // and then we set the size of all the scroll widgets to the maximal page size
107         for(KPageWidgetItem *item : const_cast<const QList<KPageWidgetItem*>&>(m_pageWidgetItemList)) { // use 'qAsConst' later
108             KileWidget::ScrollWidget *scrollWidget = dynamic_cast<KileWidget::ScrollWidget*>(item->widget());
109             if(!scrollWidget) {
110                 continue;
111             }
112             scrollWidget->setPreferredSize(maximumSizeHint);
113         }
114     }
115 
116     m_configDialogSize = m_config->group("KileConfigDialog");
117 
118     resize(sizeHint());
119     // as of October 2016, 'restoreWindowSize' has no effect when called directly from here
120     QTimer::singleShot(0, this, [=] () {
121         KWindowConfig::restoreWindowSize(windowHandle(), m_configDialogSize);
122     });
123     // setup connections
124     //connect(m_manager, SIGNAL(widgetModified()), this, SLOT(slotWidgetModified()));
125     connect(this, &KPageDialog::accepted, this, &Config::slotAcceptChanges);
126     connect(this, &KPageDialog::accepted, m_manager, &KConfigDialogManager::updateSettings);
127     connect(this, &KPageDialog::rejected, this, [=] () {
128         m_config->markAsClean();
129     });
130 }
131 
~Config()132 Config::~Config()
133 {
134     KWindowConfig::saveWindowSize(windowHandle(), m_configDialogSize);
135 
136     delete m_manager;
137 }
138 
show()139 void Config::show()
140 {
141     m_manager->updateWidgets();
142     QDialog::show();
143 }
144 
145 //////////////////// add a new folder ////////////////////
146 
addConfigFolder(const QString & section,const QString & icon)147 KPageWidgetItem* Config::addConfigFolder(const QString &section, const QString &icon)
148 {
149     KPageWidgetItem *toReturn = addPage(new QWidget(this), section);
150     toReturn->setIcon(QIcon::fromTheme(icon));
151 
152     return toReturn;
153 }
154 
155 //////////////////// add a new page ////////////////////
156 
addConfigPage(KPageWidgetItem * parent,QWidget * page,const QString & itemName,const QString & pixmapName,const QString & header)157 KPageWidgetItem* Config::addConfigPage(KPageWidgetItem* parent, QWidget *page, const QString &itemName,
158                                        const QString &pixmapName, const QString &header)
159 {
160     return addConfigPage(parent, page, itemName, QIcon::fromTheme(pixmapName), header);
161 }
162 
addConfigPage(KPageWidgetItem * parent,QWidget * page,const QString & itemName,const QIcon & icon,const QString & header)163 KPageWidgetItem* Config::addConfigPage(KPageWidgetItem* parent, QWidget *page,
164                                        const QString &itemName, const QIcon& icon,
165                                        const QString &header)
166 {
167     KILE_DEBUG_MAIN << "slot: add config page item=" << itemName;
168 
169     // Create scroll widget for the page
170     KileWidget::ScrollWidget *scrollWidget = new KileWidget::ScrollWidget(this);
171     scrollWidget->setFrameShape(QFrame::NoFrame);
172     scrollWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
173     scrollWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
174     scrollWidget->setWidget(page);
175     scrollWidget->setWidgetResizable(true);
176     page->setMinimumSize(page->sizeHint());
177     page->resize(page->sizeHint());
178 
179     // add page
180     KPageWidgetItem *pageWidgetItem = new KPageWidgetItem(scrollWidget, itemName);
181     pageWidgetItem->setIcon(icon);
182     pageWidgetItem->setHeader(header);
183 
184     addSubPage(parent, pageWidgetItem);
185 
186     // add to the dialog manager
187     m_manager->addWidget(page);
188 
189     m_pageWidgetItemList << pageWidgetItem;
190 
191     return pageWidgetItem;
192 }
193 
194 //////////////////// General Options ////////////////////
195 
setupGeneralOptions(KPageWidgetItem * parent)196 void Config::setupGeneralOptions(KPageWidgetItem* parent)
197 {
198     generalPage = new KileWidgetGeneralConfig(this);
199     generalPage->setObjectName("LaTeX");
200     KPageWidgetItem *item = addConfigPage(parent, generalPage, i18n("General"), "configure", i18n("General Settings"));
201     setCurrentPage(item);
202 }
203 
204 //////////////////// Tools Configuration ////////////////////
205 
setupTools(KPageWidgetItem * parent)206 void Config::setupTools(KPageWidgetItem* parent)
207 {
208     toolPage = new KileWidget::ToolConfig(m_ki->toolManager(), this);
209     addConfigPage(parent, toolPage, i18n("Build"), "application-x-executable", i18n("Build"));
210 }
211 
212 //////////////////// Scripting  ////////////////////
213 
setupScripting(KPageWidgetItem * parent)214 void Config::setupScripting(KPageWidgetItem* parent)
215 {
216     scriptingPage = new KileWidgetScriptingConfig(this);
217     scriptingPage->setObjectName("Scripting");
218     // we hide this now as the feature is not implemented currently
219     scriptingPage->executionTimeLimitGroupBox->setHidden(true);
220     addConfigPage(parent, scriptingPage, i18n("Scripting"), "application-x-executable-script", i18n("Scripting Support"));
221 }
222 
223 //////////////////// Usermenu  ////////////////////
224 
setupUsermenu(KPageWidgetItem * parent)225 void Config::setupUsermenu(KPageWidgetItem *parent)
226 {
227     usermenuPage = new KileWidgetUsermenuConfig(m_ki->userMenu(), this);
228     usermenuPage->setObjectName("Usermenu");
229     addConfigPage(parent, usermenuPage, i18n("User Menu"), "usermenu-install", i18n("User Menu"));
230 }
231 
232 //////////////////// LaTeX specific editing options ////////////////////
233 
234 //////////////////// Complete configuration (dani) ////////////////////
235 
setupCodeCompletion(KPageWidgetItem * parent)236 void Config::setupCodeCompletion(KPageWidgetItem* parent)
237 {
238     completePage = new CodeCompletionConfigWidget(m_config, m_ki->errorHandler());
239     completePage->readConfig();
240 
241     addConfigPage(parent, completePage, i18n("Complete"), "text-x-tex", i18n("Code Completion"));
242 }
243 
244 //////////////////// QuickPreview (dani) ////////////////////
245 
setupQuickPreview(KPageWidgetItem * parent)246 void Config::setupQuickPreview(KPageWidgetItem* parent)
247 {
248     previewPage = new KileWidgetPreviewConfig(m_config,m_ki->quickPreview(),this);
249     previewPage->readConfig();
250 
251     addConfigPage(parent, previewPage, i18n("Preview"), "preview", i18n("Quick Preview"));
252 }
253 
setupHelp(KPageWidgetItem * parent)254 void Config::setupHelp(KPageWidgetItem* parent)
255 {
256     helpPage = new KileWidgetHelpConfig(this);
257     helpPage->setHelp(m_ki->help());
258 
259     addConfigPage(parent, helpPage, i18n("Help"),"help-browser");
260 }
261 
setupLivePreview(KPageWidgetItem * parent)262 void Config::setupLivePreview(KPageWidgetItem* parent)
263 {
264     livePreviewPage = new KileWidgetLivePreviewConfig(m_config, this);
265     livePreviewPage->readConfig();
266 
267     addConfigPage(parent, livePreviewPage, i18n("Live Preview"), "preview", i18n("Live Preview"));
268 }
269 
setupAppearance(KPageWidgetItem * parent)270 void Config::setupAppearance(KPageWidgetItem* parent)
271 {
272     appearancePage = new KileWidgetAppearanceConfig(m_config, this);
273     appearancePage->readConfig();
274 
275     addConfigPage(parent, appearancePage, i18n("Appearance"), "preview", i18n("Appearance"));
276 }
277 
278 //////////////////// LaTeX environments ////////////////////
279 
setupLatex(KPageWidgetItem * parent)280 void Config::setupLatex(KPageWidgetItem* parent)
281 {
282     latexPage = new KileWidgetLatexConfig(this);
283     latexPage->setObjectName("LaTeX");
284     latexPage->kcfg_DoubleQuotes->addItems(m_ki->editorExtension()->doubleQuotesListI18N());
285     latexPage->setLatexCommands(m_config,m_ki->latexCommands());
286 
287     addConfigPage(parent, latexPage, i18n("General"), "configure");
288 }
289 
setupEnvironment(KPageWidgetItem * parent)290 void Config::setupEnvironment(KPageWidgetItem* parent)
291 {
292     envPage = new KileWidgetEnvironmentConfig(this);
293     envPage->setObjectName("LaTeX");
294     addConfigPage(parent, envPage, i18n("Environments"), "environment");
295 }
296 
setupGraphics(KPageWidgetItem * parent)297 void Config::setupGraphics(KPageWidgetItem* parent)
298 {
299     graphicsPage = new KileWidgetGraphicsConfig(this);
300     graphicsPage->setObjectName("Graphics");
301     graphicsPage->m_lbImagemagick->setText( ( KileConfig::imagemagick() ) ? i18n("installed") : i18n("not installed") );
302     addConfigPage(parent, graphicsPage, i18n("Graphics"), "graphicspage");
303 }
304 
setupStructure(KPageWidgetItem * parent)305 void Config::setupStructure(KPageWidgetItem* parent)
306 {
307     structurePage = new KileWidgetStructureViewConfig(this);
308     structurePage->setObjectName("StructureView");
309     addConfigPage(parent, structurePage, i18n("Structure View"), "view-list-tree");
310 }
311 
setupSymbolView(KPageWidgetItem * parent)312 void Config::setupSymbolView(KPageWidgetItem* parent)
313 {
314     symbolViewPage = new KileWidgetSymbolViewConfig(this);
315     symbolViewPage->setObjectName("SymbolView");
316     addConfigPage(parent, symbolViewPage, i18n("Symbol View"), "math0");
317 }
318 
319 //////////////////// Editor ////////////////////
320 
setupEditor(KPageWidgetItem * parent)321 void Config::setupEditor(KPageWidgetItem* parent)
322 {
323     m_editorSettingsChanged = false;
324     m_editorPages.clear();
325 
326     KTextEditor::Editor* editor = m_ki->docManager()->getEditor();
327     if(!editor) {
328         return;
329     }
330     for(int i = 0; i < editor->configPages(); ++i) {
331         KTextEditor::ConfigPage *configPage = editor->configPage(i, parent->widget());
332         KPageWidgetItem *pageWidgetItem = addConfigPage(parent, configPage, configPage->name(),
333                                           configPage->icon(),
334                                           configPage->fullName());
335         connect(configPage, &KTextEditor::ConfigPage::changed, this, [=] {
336             m_editorSettingsChanged = true;
337         });
338         m_editorPages.insert(pageWidgetItem, configPage);
339     }
340 }
341 
342 //////////////////// slots ////////////////////
343 
slotAcceptChanges()344 void Config::slotAcceptChanges()
345 {
346     KILE_DEBUG_MAIN << "   slot acceptChanges (" << m_manager->hasChanged() << ","  << m_editorSettingsChanged << ")";
347 
348     // editor settings are only available, when at least one document is opened
349     if(m_editorSettingsChanged) {
350         QMapIterator<KPageWidgetItem*, KTextEditor::ConfigPage*> i(m_editorPages);
351         while (i.hasNext()) {
352             i.next();
353             i.value()->apply();
354         }
355     }
356 
357     // Kile settings
358     toolPage->writeConfig();      // config all tools
359     completePage->writeConfig();  // Complete configuration (dani)
360     previewPage->writeConfig();   // Quick Preview (dani)
361     usermenuPage->writeConfig();
362     livePreviewPage->writeConfig();
363 
364     m_config->sync();
365 }
366 }
367 
368