1 /*
2     SPDX-FileCopyrightText: 2005-2014 Christoph Cullmann <cullmann@kde.org>
3     SPDX-FileCopyrightText: 2005-2014 Dominik Haumann <dhaumann@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef KTEXTEDITOR_EDITOR_H
9 #define KTEXTEDITOR_EDITOR_H
10 
11 #include <ktexteditor_export.h>
12 
13 #include <QObject>
14 #include <QVector>
15 
16 // theme support
17 #include <KSyntaxHighlighting/Theme>
18 
19 class KAboutData;
20 class KConfig;
21 
22 namespace KSyntaxHighlighting
23 {
24 class Repository;
25 }
26 
27 /**
28  * The KTextEditor namespace contains all the public API that is required
29  * to use the KTextEditor component. Using the KTextEditor interfaces is
30  * described in the article \ref index.
31  *
32  * @warning All classes that are \e not part of the KTextEditor namespace
33  *          are internal and subject to change. We mean it!
34  */
35 namespace KTextEditor
36 {
37 class Application;
38 class Command;
39 class Document;
40 class View;
41 class EditorPrivate;
42 class ConfigPage;
43 
44 /**
45  * \class Editor editor.h <KTextEditor/Editor>
46  *
47  * \brief Accessor interface for the KTextEditor framework.
48  *
49  * Topics:
50  *  - \ref editor_intro
51  *  - \ref editor_config
52  *  - \ref editor_commands
53  *
54  * \section editor_intro Introduction
55  *
56  * The Editor part can either be accessed through the static accessor Editor::instance()
57  * or through the KParts component model (see \ref kte_design_part).
58  * The Editor singleton provides general information and configuration methods
59  * for the Editor, for example KAboutData by using aboutData().
60  *
61  * The Editor has a list of all opened documents. Get this list with documents().
62  * To create a new Document call createDocument(). The signal documentCreated()
63  * is emitted whenever the Editor created a new document.
64  *
65  * \section editor_config Editor Configuration
66  *
67  * The config dialog can be shown with configDialog().
68  * Instead of using the config dialog, the config pages can also be embedded
69  * into the application's config dialog. To do this, configPages() returns the
70  * number of config pages that exist and configPage() returns the requested
71  * page. The configuration are saved automatically by the Editor.
72  *
73  * \note It is recommended to embed the config pages into the main application's
74  *       config dialog instead of using a separate config dialog, if the config
75  *       dialog does not look cluttered then. This way, all settings are grouped
76  *       together in one place.
77  *
78  * \section editor_commands Command Line Commands
79  *
80  * With Commands it is possible to add new commands to the command line.
81  * These Command%s then are added to all document View%s.
82  * Common use cases include commands like \e find or setting document variables.
83  * The list of all registered commands can be obtained either through commandList()
84  * or through commands(). Further, a specific command can be obtained through
85  * queryCommand(). For further information, read the Command API documentation.
86  *
87  * \see KTextEditor::Document, KTextEditor::ConfigPage, KTextEditor::Command
88  * \author Christoph Cullmann \<cullmann@kde.org\>
89  */
90 class KTEXTEDITOR_EXPORT Editor : public QObject
91 {
92     Q_OBJECT
93 
94 protected:
95     /**
96      * Constructor.
97      *
98      * Create the Editor object and pass it the internal
99      * implementation to store a d-pointer.
100      *
101      * @param impl d-pointer to use
102      */
103     Editor(EditorPrivate *impl);
104 
105     /**
106      * Virtual destructor.
107      */
108     ~Editor() override;
109 
110 public:
111     /**
112      * Accessor to get the Editor instance.
113      *
114      * @note This object will stay alive until QCoreApplication terminates.
115      *       You shall not delete it yourself.
116      *       There is only ONE Editor instance of this per process.
117      *
118      * \return Editor controller, after initial construction, will
119      *        live until QCoreApplication is terminating.
120      */
121     static Editor *instance();
122 
123 public:
124     /**
125      * Set the global application object.
126      * This will allow the editor component to access
127      * the hosting application.
128      * @param application application object
129      *        if the argument is a nullptr, this will reset the application back to a dummy interface
130      */
131     virtual void setApplication(KTextEditor::Application *application) = 0;
132 
133     /**
134      * Current hosting application, if any set.
135      * @return current application object or a dummy interface that allows you to call the functions
136      *         will never return a nullptr
137      */
138     virtual KTextEditor::Application *application() const = 0;
139 
140     /*
141      * Methods to create and manage the documents.
142      */
143 public:
144     /**
145      * Create a new document object with \p parent.
146      *
147      * For each created document, the signal documentCreated() is emitted.
148      *
149      * \param parent parent object
150      * \return new KTextEditor::Document object
151      * \see documents(), documentCreated()
152      */
153     virtual Document *createDocument(QObject *parent) = 0;
154 
155     /**
156      * Get a list of all documents of this editor.
157      * \return list of all existing documents
158      * \see createDocument()
159      */
160     virtual QList<Document *> documents() = 0;
161 
162 Q_SIGNALS:
163     /**
164      * The \p editor emits this signal whenever a \p document was successfully
165      * created.
166      * \param editor pointer to the Editor singleton which created the new document
167      * \param document the newly created document instance
168      * \see createDocument()
169      */
170     void documentCreated(KTextEditor::Editor *editor, KTextEditor::Document *document);
171 
172     /*
173      * General Information about this editor.
174      */
175 public:
176     /**
177      * Get the about data of this Editor part.
178      * \return about data
179      */
180     virtual const KAboutData &aboutData() const = 0;
181 
182     /**
183      * Get the current default encoding for this Editor part.
184      * \return default encoding
185      */
186     QString defaultEncoding() const;
187 
188     /*
189      * Configuration management.
190      */
191 public:
192     /**
193      * Show the editor's config dialog, changes will be applied to the
194      * editor and the configuration changes are saved.
195      *
196      * \note Instead of using the config dialog, the config pages can be
197      *       embedded into your own config dialog by using configPages() and
198      *       configPage().
199      * \param parent parent widget
200      */
201     virtual void configDialog(QWidget *parent) = 0;
202 
203     /**
204      * Get the number of available config pages.
205      * If a number < 1 is returned, it does not support config pages.
206      * \return number of config pages
207      * \see configPage()
208      */
209     virtual int configPages() const = 0;
210 
211     /**
212      * Get the config page with the \p number, config pages from 0 to
213      * configPages()-1 are available if configPages() > 0.
214      * Configuration changes done over this widget are automatically
215      * saved.
216      * \param number index of config page
217      * \param parent parent widget for config page
218      * \return created config page or NULL, if the number is out of bounds
219      * \see configPages()
220      */
221     virtual ConfigPage *configPage(int number, QWidget *parent) = 0;
222 
223 Q_SIGNALS:
224     /**
225      * This signal is emitted whenever the editor configuration is changed.
226      *
227      * \param editor the editor which's config has changed
228      *
229      * \since 5.79
230      */
231     void configChanged(KTextEditor::Editor *editor);
232 
233 public:
234     /**
235      * Get the current global editor font.
236      * Might change during runtime, configChanged() will be emitted in that cases.
237      * Individual views might have set different fonts, can be queried with the "font" key via \see KTextEditor::ConfigInterface::configValue().
238      *
239      * \return current global font for all views
240      *
241      * \since 5.80
242      */
243     QFont font() const;
244 
245     /**
246      * Get the current global theme.
247      * Might change during runtime, configChanged() will be emitted in that cases.
248      * Individual views might have set different themes, \see KTextEditor::View::theme().
249      *
250      * \return current global theme for all views
251      *
252      * \since 5.79
253      */
254     KSyntaxHighlighting::Theme theme() const;
255 
256 public:
257     /**
258      * Get read-only access to the syntax highlighting repository the editor uses.
259      * Might be reloaded during runtime, repositoryReloaded() will be emitted in that cases.
260      *
261      * \return syntax repository used by the editor
262      *
263      * \since 5.79
264      */
265     const KSyntaxHighlighting::Repository &repository() const;
266 
267 Q_SIGNALS:
268     /**
269      * This signal is emitted whenever the editor syntax repository is reloaded.
270      * Can be used to e.g. re-instantiate syntax definitions that got invalidated by
271      * the repository reload.
272      *
273      * \param editor the editor which's repository was reloaded
274      *
275      * \since 5.79
276      */
277     void repositoryReloaded(KTextEditor::Editor *editor);
278 
279 public:
280     /**
281      * Query for the command \p cmd.
282      * If the command \p cmd does not exist the return value is NULL.
283      *
284      * \param cmd name of command to query for
285      * \return the found command or NULL if no such command exists
286      */
287     virtual Command *queryCommand(const QString &cmd) const = 0;
288 
289     /**
290      * Get a list of all registered commands.
291      * \return list of all commands
292      * \see queryCommand(), commandList()
293      */
294     virtual QList<Command *> commands() const = 0;
295 
296     /**
297      * Get a list of available command line strings.
298      * \return command line strings
299      * \see commands()
300      */
301     virtual QStringList commandList() const = 0;
302 
303 public:
304     /**
305      * Function that is called to expand a variable in @p text.
306      */
307     // TODO KF6: Use std::function to allow captures (context via closure)
308     // using ExpandFunction = std::function<QString(const QStringView &text, KTextEditor::View *view)>;
309     using ExpandFunction = QString (*)(const QStringView &text, KTextEditor::View *view);
310 
311     /**
312      * Registers a variable called @p name for exact matches.
313      * For instance, a variable called "CurrentDocument:Path" could be
314      * registered which then expands to the path the current document.
315      *
316      * @return true on success, false if the variable could not be registered,
317      *         e.g. because it already was registered previously.
318      *
319      * @since 5.57
320      */
321     bool registerVariableMatch(const QString &name, const QString &description, ExpandFunction expansionFunc);
322 
323     /**
324      * Registers a variable for arbitrary text that matches the specified
325      * prefix. For instance, a variable called "ENV:" could be registered
326      * which then expands arbitrary environment variables, e.g. ENV:HOME
327      * would expand to the user's home directory.
328      *
329      * @note A colon ':' is used as separator for the prefix and the text
330      *       after the colon that should be evaluated.
331      *
332      * @return true on success, false if a prefix could not be registered,
333      *         e.g. because it already was registered previously.
334      *
335      * @since 5.57
336      */
337     bool registerVariablePrefix(const QString &prefix, const QString &description, ExpandFunction expansionFunc);
338 
339     /**
340      * Unregisters a variable that was previously registered with
341      * registerVariableMatch().
342      *
343      * @return true if the variable was successfully unregistered, and
344      *         false if the variable did not exist.
345      *
346      * @since 5.57
347      */
348     bool unregisterVariableMatch(const QString &variable);
349 
350     // TODO KF6: merge "unregisterVariableMatch()" and "unregisterVariablePrefix()" into
351     //           a single function "unregisterVariable(const QString& name)".
352     /**
353      * Unregisters a prefix of variable that was previously registered with
354      * registerVariableMatch().
355      *
356      * @return true if the variable was successfully unregistered, and
357      *         false if the variable did not exist.
358      *
359      * @since 5.57
360      */
361     bool unregisterVariablePrefix(const QString &variable);
362 
363     /**
364      * Expands a single @p variable, writing the expanded value to @p output.
365      *
366      * @return true on success, otherwise false.
367      *
368      * @since 5.57
369      */
370     bool expandVariable(const QString &variable, KTextEditor::View *view, QString &output) const;
371 
372     // TODO KF6: turn expandText into: QString expandText(text, view) to avoid output argument
373     /**
374      * Expands arbitrary @p text that may contain arbitrary many variables.
375      * On success, the expanded text is written to @p output.
376      *
377      * @since 5.57
378      */
379     void expandText(const QString &text, KTextEditor::View *view, QString &output) const;
380 
381     /**
382      * Adds a QAction to the widget in @p widgets that whenever focus is
383      * gained. When the action is invoked, a non-modal dialog is shown that
384      * lists all @p variables. If @p variables is non-empty, then only the
385      * variables in @p variables are listed.
386      *
387      * The supported QWidgets in the @p widgets argument currently are:
388      * - QLineEdit
389      * - QTextEdit
390      *
391      * @since 5.63
392      */
393     void addVariableExpansion(const QVector<QWidget *> &widgets, const QStringList &variables = QStringList()) const;
394 
395 private:
396     /**
397      * private d-pointer, pointing to the internal implementation
398      */
399     EditorPrivate *const d;
400 };
401 
402 }
403 
404 #endif
405