Default to smart ranges, this is the right thing for most languages probably.
[kdevelopdvcssupport.git] / language / editor / editorintegrator.h
blob0b1f60757a5c494f0c6ef20b1d95dbbca898a10c
1 /* This file is part of KDevelop
2 Copyright 2006 Hamish Rodda <rodda@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #ifndef KDEVEDITORINTEGRATOR_H
20 #define KDEVEDITORINTEGRATOR_H
22 #include <QtCore/QDateTime>
23 #include <QtCore/QMutexLocker>
25 #include <KUrl>
27 #include <ktexteditor/range.h>
28 #include <ktexteditor/smartrange.h>
30 #include "documentcursor.h"
31 #include "simplerange.h"
33 class QMutex;
35 namespace KTextEditor { class SmartRange; class SmartCursor; class SmartInterface; }
37 namespace KDevelop
39 class DocumentRange;
40 class EditorIntegratorStatic;
41 class HashedString;
42 class IndexedString;
44 /**
45 * Class to hold a reference to a locked KTextEditor::SmartInterface.
46 * Implicitly shared. To get an instance of this class, see EditorIntegrator::smart()
48 * This class is re-entrant, but not thread safe.
50 class KDEVPLATFORMLANGUAGE_EXPORT LockedSmartInterface
52 public:
53 LockedSmartInterface(const LockedSmartInterface& lock);
54 ~LockedSmartInterface();
56 /// Unlock the smart interface when you've finished using it
57 /// This happens automatically on deletion, so you only need to call if
58 /// the object is not going to be deleted.
59 void unlock() const;
61 /**
62 * Return the current text editor document, based on the current URL.
64 KTextEditor::Document* currentDocument() const;
66 KTextEditor::SmartInterface* operator->() const;
67 operator bool() const;
69 private:
70 friend class EditorIntegrator;
71 LockedSmartInterface(KTextEditor::SmartInterface* iface = 0, KTextEditor::Document* doc = 0);
73 class LockedSmartInterfacePrivate* const d;
76 /**
77 * Provides facilities for easy integration of a text editor component with
78 * the information parsed from a source file.
80 * Uses a disguised singleton + stateful design.
82 * \todo introduce stacks for the state?
83 * \todo move private members to a private class
84 * \todo non-loaded documents don't trigger the removeDocument call...
86 class KDEVPLATFORMLANGUAGE_EXPORT EditorIntegrator
88 friend class EditorIntegratorStatic;
90 public:
91 EditorIntegrator();
92 virtual ~EditorIntegrator();
94 ///A hack working around problems while initialization, @see DUChain::documentLoadedPrepare. It used to happen that the document wasn't registered
95 ///to the editor-integrator there, and thus no smart-ranges/highlighting were created. We use this to inject the document.
96 void insertLoadedDocument(KTextEditor::Document* document);
98 /**
99 * Initialise the editor integrator.
100 * Only needs to be called once from the main thread.
102 static void initialise();
105 * Adds a text editor \a document to the integrator.
107 static void addDocument(KTextEditor::Document* document);
110 * Retrieve the mutex which allows background parsers to lock a document
111 * in place while they make their changes.
113 static QMutex* mutexForDocument(KTextEditor::Document* document);*/
116 * Removes the text editor \a document from the integrator.
118 static void removeDocument(KTextEditor::Document* document);
121 * Returns the text document for \a url, if one exists. The url should have been formatted using KUrl::pathOrUrl() at some point.
123 static KTextEditor::Document* documentForUrl(const HashedString& url);
126 * Returns the text document for \a url, if one exists. The url should have been formatted using KUrl::pathOrUrl() at some point.
127 * This shouuld be preferred over the method above
129 static KTextEditor::Document* documentForUrl(const IndexedString& url);
132 * Determine if a document has been loaded yet
134 static bool documentLoaded(KTextEditor::Document* document);
137 * Save the current revision of the given \a document. You should have the smart mutex locked so
138 * when you retrieve the text, it is at the same revision still ;)
140 * \Returns the revision retrieved, or -1 if there was an error.
142 static int saveCurrentRevision(KTextEditor::Document* document);
144 /// Returns the url of the currently associated editor
145 IndexedString currentUrl() const;
147 /// Associate this editor integrator with the editor which is currently editing the given \a url
148 /// @param useSmart Whether smart-ranges should be created for this url.
149 void setCurrentUrl(const IndexedString& url, bool useSmart = true);
151 /// Retrieve a locked version of the SmartInterface for the current document, or null if one does not exist / is being deleted etc.
152 LockedSmartInterface smart() const;
154 /// Retrieve a locked version of the SmartInterface for the current document, or null if one does not exist / is being deleted etc.
155 static LockedSmartInterface smart(const KUrl& url);
157 /// Top range type enumeration
158 enum TopRangeType {
159 Highlighting /**< top range type for highlighting */,
160 DefinitionUseChain /**< top range type for duchain */,
161 TopRangeCount /**< top range type for counting */
165 * Returns a toplevel range in a document for use as \a type.
167 * \param type The use for which the created range will be used
168 * \returns the range either found or created, if the document was valid and supports
169 * smart ranges. Zero if no smart interface is available for the document.
171 * Opens a range that needs to be closed using exitCurrentRange()
173 KTextEditor::SmartRange* topRange(const LockedSmartInterface& iface, TopRangeType type);
176 * Releases a toplevel \a range. The range should be deleted by the caller.
178 static void releaseTopRange(KTextEditor::SmartRange* range);
181 * Releases + safely deletes a text editor range.
183 * \warning you must already hold the smart lock for the corresponding document.
184 * \todo audit uses to check for smart lock holding
186 static void releaseRange(KTextEditor::SmartRange* range);
188 enum Edge {
189 FrontEdge /**< the front edge of a token */,
190 BackEdge /**< the back edge of a token */
194 * Create a new persistant cursor from the given \a position.
196 KTextEditor::SmartCursor* createCursor(const LockedSmartInterface& iface, const KTextEditor::Cursor& position);
199 * Create a new persistant cursor from the given \a token on the given \a edge.
201 KTextEditor::SmartCursor* createCursor(const LockedSmartInterface& iface, std::size_t token, Edge edge);
204 * Apply a possibly dated range to the current smart cursor. Performs translation on \a fromRange,
205 * then applies it to smartRange.
207 void adjustRangeTo(const LockedSmartInterface& iface, const SimpleRange& fromRange);
210 * Translate the given \a range to the current smart revision, and return the result.
211 * You need to have the smart mutex locked for the result to remain valid while you process it.
213 SimpleRange translate(const LockedSmartInterface& iface, const SimpleRange& fromRange) const;
216 * Create a text range over \a range as a child range of the current range.
217 * The returned range will become the new currentRange(), and will be put upon the range-stack.
219 * If the current document is loaded, and it supports creating smart ranges,
220 * this will be a smart range, otherwise it will be a DocumentRange.
222 * \param range Range of text to cover. If this is outside the parent's range, the
223 * parent will be adjusted (standard behaviour of SmartRange%s).
224 * \param insertBehavior: If a smart-range will be created, it will be created with the given insert-behavior
226 * \returns the newly created text range, or zero if no smart interface is available for the document.
228 KTextEditor::SmartRange* createRange(const LockedSmartInterface& iface, const KTextEditor::Range& range, KTextEditor::SmartRange::InsertBehaviors insertBehavior = KTextEditor::SmartRange::DoNotExpand);
231 * Create a text range from \a start to \a end as a child range of the current range.
232 * The returned range will become the new currentRange().
234 * If the current document is loaded, and it supports creating smart ranges,
235 * this will be a smart range, otherwise it will be a DocumentRange.
237 * \param start start of the range of text to cover. If this is outside the parent's range, the
238 * parent will be adjusted (standard behaviour of SmartRange%s).
239 * \param end end of the range of text to cover. If this is outside the parent's range, the
240 * parent will be adjusted (standard behaviour of SmartRange%s).
242 * \returns the newly created text range, or zero if no smart interface is available for the document.
243 * \overload
245 KTextEditor::SmartRange* createRange(const LockedSmartInterface& iface, const KTextEditor::Cursor& start, const KTextEditor::Cursor& end);
247 enum RangeEdge {
248 InnerEdge /**< the inner edge of a range */,
249 OuterEdge /**< the outer edge of a range */
253 * Returns the most current text range.
255 KTextEditor::SmartRange* currentRange(const LockedSmartInterface& iface) const;
258 * Sets the current range to \a range. It is put upon the range-stack.
259 * Does nothing if the range is zero.
261 void setCurrentRange(const LockedSmartInterface& iface, KTextEditor::SmartRange* range);
264 * Count of ranges currently on the stack.
266 int rangeStackSize(const LockedSmartInterface& iface) const;
269 * Sets the previous range on the stack to be the new current range.
270 * Does nothing if the range stack is empty.
272 void exitCurrentRange(const LockedSmartInterface& iface);
275 * Use this to connect to notifications provided by EditorIntegratorStatic.
277 static QObject* notifier();
279 private:
280 /// Remove a current associated document, eg. if the document gets closed
281 /// Only to be used by EditorIntegratorStatic
282 void clearCurrentDocument();
284 static EditorIntegratorStatic *data();
285 class EditorIntegratorPrivate* const d;
290 #endif // EDITORINTEGRATOR_H