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>
27 #include <ktexteditor/range.h>
28 #include <ktexteditor/smartrange.h>
30 #include "documentcursor.h"
31 #include "simplerange.h"
35 namespace KTextEditor
{ class SmartRange
; class SmartCursor
; class SmartInterface
; }
40 class EditorIntegratorStatic
;
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
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.
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;
70 friend class EditorIntegrator
;
71 LockedSmartInterface(KTextEditor::SmartInterface
* iface
= 0, KTextEditor::Document
* doc
= 0);
73 class LockedSmartInterfacePrivate
* const d
;
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
;
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
);
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
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
);
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.
245 KTextEditor::SmartRange
* createRange(const LockedSmartInterface
& iface
, const KTextEditor::Cursor
& start
, const KTextEditor::Cursor
& end
);
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();
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