1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "highlightersettingspage.h"
27 #include "highlightersettings.h"
28 #include "highlighter.h"
29 #include "ui_highlightersettingspage.h"
30 
31 #include <coreplugin/icore.h>
32 
33 #include <QDir>
34 #include <QMessageBox>
35 #include <QPointer>
36 
37 using namespace TextEditor;
38 using namespace Internal;
39 
40 struct HighlighterSettingsPage::HighlighterSettingsPagePrivate
41 {
42     Q_DECLARE_TR_FUNCTIONS(TextEditor::Internal::HighlighterSettingsPage)
43 
44 public:
45     HighlighterSettingsPagePrivate();
46     void ensureInitialized();
47     void migrateGenericHighlighterFiles();
48 
49     bool m_initialized = false;
50     const QString m_settingsPrefix;
51 
52     HighlighterSettings m_settings;
53 
54     QPointer<QWidget> m_widget;
55     Ui::HighlighterSettingsPage *m_page = nullptr;
56 };
57 
HighlighterSettingsPagePrivate()58 HighlighterSettingsPage::HighlighterSettingsPagePrivate::HighlighterSettingsPagePrivate()
59     : m_settingsPrefix("Text")
60 {}
61 
migrateGenericHighlighterFiles()62 void HighlighterSettingsPage::HighlighterSettingsPagePrivate::migrateGenericHighlighterFiles()
63 {
64     QDir userDefinitionPath(m_settings.definitionFilesPath());
65     if (userDefinitionPath.mkdir("syntax")) {
66         const auto link = Utils::HostOsInfo::isAnyUnixHost()
67                               ? static_cast<bool(*)(const QString &, const QString &)>(&QFile::link)
68                               : static_cast<bool(*)(const QString &, const QString &)>(&QFile::copy);
69 
70         for (const QFileInfo &file : userDefinitionPath.entryInfoList({"*.xml"}, QDir::Files))
71             link(file.filePath(), file.absolutePath() + "/syntax/" + file.fileName());
72     }
73 }
74 
ensureInitialized()75 void HighlighterSettingsPage::HighlighterSettingsPagePrivate::ensureInitialized()
76 {
77     if (m_initialized)
78         return;
79     m_initialized = true;
80     m_settings.fromSettings(m_settingsPrefix, Core::ICore::settings());
81     migrateGenericHighlighterFiles();
82 }
83 
HighlighterSettingsPage()84 HighlighterSettingsPage::HighlighterSettingsPage()
85     : m_d(new HighlighterSettingsPagePrivate)
86 {
87     setId(Constants::TEXT_EDITOR_HIGHLIGHTER_SETTINGS);
88     setDisplayName(HighlighterSettingsPagePrivate::tr("Generic Highlighter"));
89     setCategory(TextEditor::Constants::TEXT_EDITOR_SETTINGS_CATEGORY);
90     setDisplayCategory(QCoreApplication::translate("TextEditor", "Text Editor"));
91     setCategoryIconPath(TextEditor::Constants::TEXT_EDITOR_SETTINGS_CATEGORY_ICON_PATH);
92 }
93 
~HighlighterSettingsPage()94 HighlighterSettingsPage::~HighlighterSettingsPage()
95 {
96     delete m_d;
97 }
98 
widget()99 QWidget *HighlighterSettingsPage::widget()
100 {
101     if (!m_d->m_widget) {
102         m_d->m_widget = new QWidget;
103         m_d->m_page = new Ui::HighlighterSettingsPage;
104         m_d->m_page->setupUi(m_d->m_widget);
105         m_d->m_page->definitionFilesPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
106         m_d->m_page->definitionFilesPath->setHistoryCompleter(QLatin1String("TextEditor.Highlighter.History"));
107         connect(m_d->m_page->downloadDefinitions,
108                 &QPushButton::pressed,
109                 [label = QPointer<QLabel>(m_d->m_page->updateStatus)]() {
110                     Highlighter::downloadDefinitions([label](){
111                         if (label)
112                             label->setText(HighlighterSettingsPagePrivate::tr("Download finished"));
113                     });
114                 });
115         connect(m_d->m_page->reloadDefinitions, &QPushButton::pressed, []() {
116             Highlighter::reload();
117         });
118         connect(m_d->m_page->resetCache, &QPushButton::clicked, []() {
119             Highlighter::clearDefinitionForDocumentCache();
120         });
121 
122         settingsToUI();
123     }
124     return m_d->m_widget;
125 }
126 
apply()127 void HighlighterSettingsPage::apply()
128 {
129     if (!m_d->m_page) // page was not shown
130         return;
131     if (settingsChanged())
132         settingsFromUI();
133 }
134 
finish()135 void HighlighterSettingsPage::finish()
136 {
137     delete m_d->m_widget;
138     if (!m_d->m_page) // page was not shown
139         return;
140     delete m_d->m_page;
141     m_d->m_page = nullptr;
142 }
143 
highlighterSettings() const144 const HighlighterSettings &HighlighterSettingsPage::highlighterSettings() const
145 {
146     m_d->ensureInitialized();
147     return m_d->m_settings;
148 }
149 
settingsFromUI()150 void HighlighterSettingsPage::settingsFromUI()
151 {
152     m_d->ensureInitialized();
153     m_d->m_settings.setDefinitionFilesPath(m_d->m_page->definitionFilesPath->filePath().toString());
154     m_d->m_settings.setIgnoredFilesPatterns(m_d->m_page->ignoreEdit->text());
155     m_d->m_settings.toSettings(m_d->m_settingsPrefix, Core::ICore::settings());
156 }
157 
settingsToUI()158 void HighlighterSettingsPage::settingsToUI()
159 {
160     m_d->ensureInitialized();
161     m_d->m_page->definitionFilesPath->setPath(m_d->m_settings.definitionFilesPath());
162     m_d->m_page->ignoreEdit->setText(m_d->m_settings.ignoredFilesPatterns());
163 }
164 
settingsChanged() const165 bool HighlighterSettingsPage::settingsChanged() const
166 {
167     m_d->ensureInitialized();
168     return (m_d->m_settings.definitionFilesPath() != m_d->m_page->definitionFilesPath->filePath().toString())
169             || (m_d->m_settings.ignoredFilesPatterns() != m_d->m_page->ignoreEdit->text());
170 }
171