1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 2001-2004 Christoph Cullmann <cullmann@kde.org> |
3 | Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> |
4 | Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> |
5 | Copyright (C) 2006 Hamish Rodda <rodda@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License version 2 as published by the Free Software Foundation. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #ifndef _KATE_DOCUMENT_H_ |
23 | #define _KATE_DOCUMENT_H_ |
24 | |
25 | #include <QtCore/QLinkedList> |
26 | #include <QtCore/QMap> |
27 | #include <QtCore/QDate> |
28 | #include <QtGui/QClipboard> |
29 | #include <QtCore/QStack> |
30 | |
31 | #include <kmimetype.h> |
32 | |
33 | #include <ktexteditor/document.h> |
34 | #include <ktexteditor/sessionconfiginterface.h> |
35 | #include <ktexteditor/searchinterface.h> |
36 | #include <ktexteditor/markinterface.h> |
37 | #include <ktexteditor/variableinterface.h> |
38 | #include <ktexteditor/modificationinterface.h> |
39 | #include <ktexteditor/configinterface.h> |
40 | #include <ktexteditor/annotationinterface.h> |
41 | #include <ktexteditor/highlightinterface.h> |
42 | #include <ktexteditor/movinginterface.h> |
43 | #include <ktexteditor/recoveryinterface.h> |
44 | #include <ktexteditor/messageinterface.h> |
45 | |
46 | #include "katepartprivate_export.h" |
47 | #include "katetextline.h" |
48 | #include "katetextcursor.h" |
49 | #include "katetextrange.h" |
50 | |
51 | namespace KTextEditor { |
52 | class Plugin; |
53 | class Attribute; |
54 | class TemplateScript; |
55 | } |
56 | |
57 | namespace KIO { class TransferJob; } |
58 | |
59 | namespace Kate { class SwapFile; } |
60 | |
61 | class KateBuffer; |
62 | class KateView; |
63 | class KateDocumentConfig; |
64 | class KateHighlighting; |
65 | class KateUndoManager; |
66 | class KateOnTheFlyChecker; |
67 | |
68 | class KateAutoIndent; |
69 | |
70 | |
71 | // |
72 | // Kate KTextEditor::Document class (and even KTextEditor::Editor ;) |
73 | // |
74 | class KATEPART_TESTS_EXPORT KateDocument : public KTextEditor::Document, |
75 | public KTextEditor::SessionConfigInterface, |
76 | public KTextEditor::ParameterizedSessionConfigInterface, |
77 | public KTextEditor::SearchInterface, |
78 | public KTextEditor::MarkInterface, |
79 | public KTextEditor::VariableInterface, |
80 | public KTextEditor::ModificationInterface, |
81 | public KTextEditor::ConfigInterface, |
82 | public KTextEditor::AnnotationInterface, |
83 | public KTextEditor::HighlightInterface, |
84 | public KTextEditor::MovingInterface, |
85 | public KTextEditor::RecoveryInterface, |
86 | public KTextEditor::MessageInterface, |
87 | private KTextEditor::MovingRangeFeedback |
88 | { |
89 | Q_OBJECT |
90 | Q_INTERFACES(KTextEditor::SessionConfigInterface) |
91 | Q_INTERFACES(KTextEditor::ParameterizedSessionConfigInterface) |
92 | Q_INTERFACES(KTextEditor::SearchInterface) |
93 | Q_INTERFACES(KTextEditor::MarkInterface) |
94 | Q_INTERFACES(KTextEditor::VariableInterface) |
95 | Q_INTERFACES(KTextEditor::ModificationInterface) |
96 | Q_INTERFACES(KTextEditor::AnnotationInterface) |
97 | Q_INTERFACES(KTextEditor::ConfigInterface) |
98 | Q_INTERFACES(KTextEditor::HighlightInterface) |
99 | Q_INTERFACES(KTextEditor::MovingInterface) |
100 | Q_INTERFACES(KTextEditor::RecoveryInterface) |
101 | Q_INTERFACES(KTextEditor::MessageInterface) |
102 | |
103 | friend class KateDocumentTest; |
104 | friend class KateBuffer; |
105 | |
106 | public: |
107 | explicit KateDocument (bool bSingleViewMode=false, bool bBrowserView=false, bool bReadOnly=false, |
108 | QWidget *parentWidget = 0, QObject * = 0); |
109 | ~KateDocument (); |
110 | |
111 | using ReadWritePart::closeUrl; |
112 | virtual bool closeUrl(); |
113 | |
114 | virtual bool openUrl( const KUrl &url ); |
115 | |
116 | virtual KTextEditor::Editor *editor (); |
117 | |
118 | KTextEditor::Range rangeOnLine(KTextEditor::Range range, int line) const; |
119 | |
120 | private: |
121 | void showAndSetOpeningErrorAccess(); |
122 | /* |
123 | * Overload this to have on-demand view creation |
124 | */ |
125 | public: |
126 | /** |
127 | * @return The widget defined by this part, set by setWidget(). |
128 | */ |
129 | virtual QWidget *widget(); |
130 | |
131 | Q_SIGNALS: |
132 | // TODO for KDE5: move to KTE::Document |
133 | void readWriteChanged (KTextEditor::Document *document); |
134 | |
135 | |
136 | |
137 | public: |
138 | bool readOnly () const { return m_bReadOnly; } |
139 | bool browserView () const { return m_bBrowserView; } |
140 | bool singleViewMode () const { return m_bSingleViewMode; } |
141 | static bool simpleMode (); |
142 | |
143 | private: |
144 | // only to make part work, don't change it ! |
145 | const bool m_bSingleViewMode; |
146 | const bool m_bBrowserView; |
147 | const bool m_bReadOnly; |
148 | |
149 | // |
150 | // KTextEditor::Document stuff |
151 | // |
152 | public: |
153 | virtual KTextEditor::View *createView( QWidget *parent ); |
154 | virtual const QList<KTextEditor::View*> &views () const; |
155 | |
156 | virtual KTextEditor::View* activeView() const { return m_activeView; } |
157 | // Invalid covariant returns my a$$... for some reason gcc won't let me return a KateView above! |
158 | KateView* activeKateView() const; |
159 | |
160 | private: |
161 | QLinkedList<KateView*> m_views; |
162 | QList<KTextEditor::View*> m_textEditViews; |
163 | KTextEditor::View *m_activeView; |
164 | |
165 | // |
166 | // KTextEditor::EditInterface stuff |
167 | // |
168 | public Q_SLOTS: |
169 | virtual bool setText(const QString &); |
170 | virtual bool setText(const QStringList& text); |
171 | virtual bool clear (); |
172 | |
173 | virtual bool insertText ( const KTextEditor::Cursor &position, const QString &s, bool block = false ); |
174 | virtual bool insertText ( const KTextEditor::Cursor &position, const QStringList &text, bool block = false ); |
175 | |
176 | virtual bool insertLine ( int line, const QString &s ); |
177 | virtual bool insertLines ( int line, const QStringList &s ); |
178 | |
179 | virtual bool removeText ( const KTextEditor::Range &range, bool block = false ); |
180 | virtual bool removeLine ( int line ); |
181 | |
182 | virtual bool replaceText ( const KTextEditor::Range &range, const QString &s, bool block = false ); |
183 | |
184 | // unhide method... |
185 | virtual bool replaceText (const KTextEditor::Range &r, const QStringList &l, bool b) |
186 | { return KTextEditor::Document::replaceText (r, l, b); } |
187 | |
188 | public: |
189 | virtual QString text ( const KTextEditor::Range &range, bool blockwise = false ) const; |
190 | virtual QStringList textLines ( const KTextEditor::Range& range, bool block = false ) const; |
191 | virtual QString text() const; |
192 | virtual QString line(int line) const; |
193 | virtual QChar character(const KTextEditor::Cursor& position) const; |
194 | virtual int lines() const; |
195 | virtual KTextEditor::Cursor documentEnd() const; |
196 | virtual int totalCharacters() const; |
197 | virtual int lineLength(int line) const; |
198 | |
199 | Q_SIGNALS: |
200 | void (const KTextEditor::Cursor& position, const QString& text); |
201 | |
202 | public: |
203 | //BEGIN editStart/editEnd (start, end, undo, cursor update, view update) |
204 | /** |
205 | * Enclose editor actions with @p editStart() and @p editEnd() to group |
206 | * them. |
207 | */ |
208 | void editStart (); |
209 | |
210 | /** |
211 | * Alias for @p editStart() |
212 | */ |
213 | void editBegin () { editStart(); } |
214 | |
215 | /** |
216 | * End a editor operation. |
217 | * @see editStart() |
218 | */ |
219 | void editEnd (); |
220 | |
221 | void pushEditState(); |
222 | void popEditState(); |
223 | |
224 | virtual bool startEditing () { editStart (); return true; } |
225 | virtual bool endEditing () { editEnd (); return true; } |
226 | |
227 | //END editStart/editEnd |
228 | |
229 | void inputMethodStart(); |
230 | void inputMethodEnd(); |
231 | |
232 | //BEGIN LINE BASED INSERT/REMOVE STUFF (editStart() and editEnd() included) |
233 | /** |
234 | * Add a string in the given line/column |
235 | * @param line line number |
236 | * @param col column |
237 | * @param s string to be inserted |
238 | * @return true on success |
239 | */ |
240 | bool editInsertText ( int line, int col, const QString &s ); |
241 | /** |
242 | * Remove a string in the given line/column |
243 | * @param line line number |
244 | * @param col column |
245 | * @param len length of text to be removed |
246 | * @return true on success |
247 | */ |
248 | bool editRemoveText ( int line, int col, int len ); |
249 | |
250 | /** |
251 | * Mark @p line as @p autowrapped. This is necessary if static word warp is |
252 | * enabled, because we have to know whether to insert a new line or add the |
253 | * wrapped words to the followin line. |
254 | * @param line line number |
255 | * @param autowrapped autowrapped? |
256 | * @return true on success |
257 | */ |
258 | bool editMarkLineAutoWrapped ( int line, bool autowrapped ); |
259 | |
260 | /** |
261 | * Wrap @p line. If @p newLine is true, ignore the textline's flag |
262 | * KateTextLine::flagAutoWrapped and force a new line. Whether a new line |
263 | * was needed/added you can grab with @p newLineAdded. |
264 | * @param line line number |
265 | * @param col column |
266 | * @param newLine if true, force a new line |
267 | * @param newLineAdded return value is true, if new line was added (may be 0) |
268 | * @return true on success |
269 | */ |
270 | bool editWrapLine ( int line, int col, bool newLine = true, bool *newLineAdded = 0 ); |
271 | /** |
272 | * Unwrap @p line. If @p removeLine is true, we force to join the lines. If |
273 | * @p removeLine is true, @p length is ignored (eg not needed). |
274 | * @param line line number |
275 | * @param removeLine if true, force to remove the next line |
276 | * @return true on success |
277 | */ |
278 | bool editUnWrapLine ( int line, bool removeLine = true, int length = 0 ); |
279 | |
280 | /** |
281 | * Insert a string at the given line. |
282 | * @param line line number |
283 | * @param s string to insert |
284 | * @return true on success |
285 | */ |
286 | bool editInsertLine ( int line, const QString &s ); |
287 | /** |
288 | * Remove a line |
289 | * @param line line number |
290 | * @return true on success |
291 | */ |
292 | bool editRemoveLine ( int line ); |
293 | |
294 | bool editRemoveLines ( int from, int to ); |
295 | |
296 | /** |
297 | * Remove a line |
298 | * @param startLine line to begin wrapping |
299 | * @param endLine line to stop wrapping |
300 | * @return true on success |
301 | */ |
302 | bool wrapText (int startLine, int endLine); |
303 | //END LINE BASED INSERT/REMOVE STUFF |
304 | |
305 | Q_SIGNALS: |
306 | /** |
307 | * Emmitted when text from @p line was wrapped at position pos onto line @p nextLine. |
308 | */ |
309 | void editLineWrapped ( int line, int col, int len ); |
310 | |
311 | /** |
312 | * Emitted each time text from @p nextLine was upwrapped onto @p line. |
313 | */ |
314 | void editLineUnWrapped ( int line, int col ); |
315 | |
316 | public: |
317 | bool isEditRunning() const; |
318 | |
319 | void setUndoMergeAllEdits(bool merge); |
320 | |
321 | private: |
322 | int editSessionNumber; |
323 | QStack<int> editStateStack; |
324 | bool editIsRunning; |
325 | bool m_undoMergeAllEdits; |
326 | |
327 | // |
328 | // KTextEditor::UndoInterface stuff |
329 | // |
330 | public Q_SLOTS: |
331 | void undo (); |
332 | void redo (); |
333 | |
334 | public: |
335 | uint undoCount () const; |
336 | uint redoCount () const; |
337 | |
338 | KateUndoManager* undoManager() |
339 | { |
340 | return m_undoManager; |
341 | } |
342 | |
343 | protected: |
344 | KateUndoManager* const m_undoManager; |
345 | |
346 | Q_SIGNALS: |
347 | void undoChanged (); |
348 | |
349 | // |
350 | // KTextEditor::SearchInterface stuff |
351 | // |
352 | public: |
353 | virtual QVector<KTextEditor::Range> searchText( |
354 | const KTextEditor::Range & range, |
355 | const QString & pattern, |
356 | const KTextEditor::Search::SearchOptions options); |
357 | |
358 | virtual KTextEditor::Search::SearchOptions supportedSearchOptions() const; |
359 | |
360 | private: |
361 | /** |
362 | * Return a widget suitable to be used as a dialog parent. |
363 | */ |
364 | QWidget * dialogParent(); |
365 | |
366 | /* |
367 | * Access to the mode/highlighting subsystem |
368 | */ |
369 | public: |
370 | /** |
371 | * Return the name of the currently used mode |
372 | * \return name of the used mode |
373 | * |
374 | */ |
375 | virtual QString mode() const; |
376 | |
377 | /** |
378 | * Return the name of the currently used mode |
379 | * \return name of the used mode |
380 | * |
381 | */ |
382 | virtual QString highlightingMode() const; |
383 | |
384 | /** |
385 | * Return a list of the names of all possible modes |
386 | * \return list of mode names |
387 | */ |
388 | virtual QStringList modes() const; |
389 | |
390 | /** |
391 | * Return a list of the names of all possible modes |
392 | * \return list of mode names |
393 | */ |
394 | virtual QStringList highlightingModes() const; |
395 | |
396 | /** |
397 | * Set the current mode of the document by giving its name |
398 | * \param name name of the mode to use for this document |
399 | * \return \e true on success, otherwise \e false |
400 | */ |
401 | virtual bool setMode(const QString &name); |
402 | |
403 | /** |
404 | * Set the current mode of the document by giving its name |
405 | * \param name name of the mode to use for this document |
406 | * \return \e true on success, otherwise \e false |
407 | */ |
408 | virtual bool setHighlightingMode(const QString &name); |
409 | /** |
410 | * Returns the name of the section for a highlight given its index in the highlight |
411 | * list (as returned by highlightModes()). |
412 | * You can use this function to build a tree of the highlight names, organized in sections. |
413 | * \param name the name of the highlight for which to find the section name. |
414 | */ |
415 | virtual QString highlightingModeSection( int index ) const; |
416 | |
417 | /** |
418 | * Returns the name of the section for a mode given its index in the highlight |
419 | * list (as returned by modes()). |
420 | * You can use this function to build a tree of the mode names, organized in sections. |
421 | * \param name the name of the highlight for which to find the section name. |
422 | */ |
423 | virtual QString modeSection( int index ) const; |
424 | |
425 | /* |
426 | * Helpers.... |
427 | */ |
428 | public: |
429 | void bufferHlChanged(); |
430 | |
431 | /** |
432 | * allow to mark, that we changed hl on user wish and should not reset it |
433 | * atm used for the user visible menu to select highlightings |
434 | */ |
435 | void setDontChangeHlOnSave(); |
436 | |
437 | /** |
438 | * Set that the BOM marker is forced via the tool menu |
439 | */ |
440 | void bomSetByUser(); |
441 | |
442 | // |
443 | // KTextEditor::SessionConfigInterface and KTextEditor::ParameterizedSessionConfigInterface stuff |
444 | // |
445 | public: |
446 | virtual void readSessionConfig (const KConfigGroup&); |
447 | virtual void writeSessionConfig (KConfigGroup&); |
448 | virtual void readParameterizedSessionConfig (const KConfigGroup&, unsigned long configParameters); |
449 | virtual void writeParameterizedSessionConfig (KConfigGroup&, unsigned long configParameters); |
450 | |
451 | Q_SIGNALS: |
452 | void configChanged(); |
453 | |
454 | // |
455 | // KTextEditor::MarkInterface |
456 | // |
457 | public Q_SLOTS: |
458 | virtual void setMark( int line, uint markType ); |
459 | virtual void clearMark( int line ); |
460 | |
461 | virtual void addMark( int line, uint markType ); |
462 | virtual void removeMark( int line, uint markType ); |
463 | |
464 | virtual void clearMarks(); |
465 | |
466 | void requestMarkTooltip( int line, QPoint position ); |
467 | |
468 | ///Returns true if the click on the mark should not be further processed |
469 | bool handleMarkClick( int line ); |
470 | |
471 | ///Returns true if the context-menu event should not further be processed |
472 | bool handleMarkContextMenu( int line, QPoint position ); |
473 | |
474 | virtual void setMarkPixmap( MarkInterface::MarkTypes, const QPixmap& ); |
475 | |
476 | virtual void setMarkDescription( MarkInterface::MarkTypes, const QString& ); |
477 | |
478 | virtual void setEditableMarks( uint markMask ); |
479 | |
480 | public: |
481 | virtual uint mark( int line ); |
482 | virtual const QHash<int, KTextEditor::Mark*> &marks (); |
483 | virtual QPixmap markPixmap( MarkInterface::MarkTypes ) const; |
484 | virtual QString markDescription( MarkInterface::MarkTypes ) const; |
485 | virtual QColor markColor( MarkInterface::MarkTypes ) const; |
486 | virtual uint editableMarks() const; |
487 | |
488 | Q_SIGNALS: |
489 | void markToolTipRequested( KTextEditor::Document* document, KTextEditor::Mark mark, QPoint position, bool& handled ); |
490 | |
491 | void ( KTextEditor::Document* document, KTextEditor::Mark mark, QPoint pos, bool& handled ); |
492 | |
493 | void markClicked( KTextEditor::Document* document, KTextEditor::Mark mark, bool& handled ); |
494 | |
495 | void marksChanged( KTextEditor::Document* ); |
496 | void markChanged( KTextEditor::Document*, KTextEditor::Mark, KTextEditor::MarkInterface::MarkChangeAction ); |
497 | |
498 | private: |
499 | QHash<int, KTextEditor::Mark*> m_marks; |
500 | QHash<int,QPixmap> m_markPixmaps; |
501 | QHash<int,QString> m_markDescriptions; |
502 | uint m_editableMarks; |
503 | |
504 | // |
505 | // KTextEditor::PrintInterface |
506 | // |
507 | public Q_SLOTS: |
508 | bool printDialog (); |
509 | Q_SCRIPTABLE bool print (); |
510 | |
511 | // |
512 | // KTextEditor::DocumentInfoInterface ( ### unfinished ) |
513 | // |
514 | public: |
515 | /** |
516 | * @return the name of the mimetype for the document. |
517 | * |
518 | * This method is using KMimeType::findByUrl, and if the pointer |
519 | * is then still the default MimeType for a nonlocal or unsaved file, |
520 | * uses mimeTypeForContent(). |
521 | */ |
522 | virtual QString mimeType(); |
523 | |
524 | /** |
525 | * @return a pointer to the KMimeType for this document, found by analyzing the |
526 | * actual content. |
527 | * |
528 | * Note that this method is *not* part of the DocumentInfoInterface. |
529 | */ |
530 | KMimeType::Ptr mimeTypeForContent(); |
531 | |
532 | // |
533 | // KTextEditor::VariableInterface |
534 | // |
535 | public: |
536 | virtual QString variable( const QString &name ) const; |
537 | // ### TODO KDE5: add to KTextEditor::VaribaleInterface |
538 | virtual QString setVariable( const QString &name, const QString &value); |
539 | |
540 | Q_SIGNALS: |
541 | void variableChanged( KTextEditor::Document*, const QString &, const QString & ); |
542 | |
543 | private: |
544 | QMap<QString, QString> m_storedVariables; |
545 | |
546 | // |
547 | // MovingInterface API |
548 | // |
549 | public: |
550 | /** |
551 | * Create a new moving cursor for this document. |
552 | * @param position position of the moving cursor to create |
553 | * @param insertBehavior insertion behavior |
554 | * @return new moving cursor for the document |
555 | */ |
556 | virtual KTextEditor::MovingCursor *newMovingCursor (const KTextEditor::Cursor &position, KTextEditor::MovingCursor::InsertBehavior insertBehavior = KTextEditor::MovingCursor::MoveOnInsert); |
557 | |
558 | /** |
559 | * Create a new moving range for this document. |
560 | * @param range range of the moving range to create |
561 | * @param insertBehaviors insertion behaviors |
562 | * @param emptyBehavior behavior on becoming empty |
563 | * @return new moving range for the document |
564 | */ |
565 | virtual KTextEditor::MovingRange *newMovingRange (const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors = KTextEditor::MovingRange::DoNotExpand |
566 | , KTextEditor::MovingRange::EmptyBehavior emptyBehavior = KTextEditor::MovingRange::AllowEmpty); |
567 | |
568 | /** |
569 | * Current revision |
570 | * @return current revision |
571 | */ |
572 | virtual qint64 revision () const; |
573 | |
574 | /** |
575 | * Last revision the buffer got successful saved |
576 | * @return last revision buffer got saved, -1 if none |
577 | */ |
578 | virtual qint64 lastSavedRevision () const; |
579 | |
580 | /** |
581 | * Lock a revision, this will keep it around until released again. |
582 | * But all revisions will always be cleared on buffer clear() (and therefor load()) |
583 | * @param revision revision to lock |
584 | */ |
585 | virtual void lockRevision (qint64 revision); |
586 | |
587 | /** |
588 | * Release a revision. |
589 | * @param revision revision to release |
590 | */ |
591 | virtual void unlockRevision (qint64 revision); |
592 | |
593 | /** |
594 | * Transform a cursor from one revision to an other. |
595 | * @param cursor cursor to transform |
596 | * @param insertBehavior behavior of this cursor on insert of text at its position |
597 | * @param fromRevision from this revision we want to transform |
598 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
599 | */ |
600 | virtual void transformCursor (KTextEditor::Cursor &cursor, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1); |
601 | |
602 | /** |
603 | * Transform a cursor from one revision to an other. |
604 | * @param line line number of the cursor to transform |
605 | * @param column column number of the cursor to transform |
606 | * @param insertBehavior behavior of this cursor on insert of text at its position |
607 | * @param fromRevision from this revision we want to transform |
608 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
609 | */ |
610 | virtual void transformCursor (int& line, int& column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1); |
611 | |
612 | /** |
613 | * Transform a range from one revision to an other. |
614 | * @param range range to transform |
615 | * @param insertBehaviors behavior of this range on insert of text at its position |
616 | * @param emptyBehavior behavior on becoming empty |
617 | * @param fromRevision from this revision we want to transform |
618 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
619 | */ |
620 | virtual void transformRange (KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision = -1); |
621 | |
622 | // |
623 | // MovingInterface Signals |
624 | // |
625 | Q_SIGNALS: |
626 | /** |
627 | * This signal is emitted before the cursors/ranges/revisions of a document are destroyed as the document is deleted. |
628 | * @param document the document which the interface belongs too which is in the process of being deleted |
629 | */ |
630 | void aboutToDeleteMovingInterfaceContent (KTextEditor::Document *document); |
631 | |
632 | /** |
633 | * This signal is emitted before the ranges of a document are invalidated and the revisions are deleted as the document is cleared (for example on load/reload). |
634 | * While this signal is emitted, still the old document content is around before the clear. |
635 | * @param document the document which the interface belongs too which will invalidate its data |
636 | */ |
637 | void aboutToInvalidateMovingInterfaceContent (KTextEditor::Document *document); |
638 | |
639 | // |
640 | // Annotation Interface |
641 | // |
642 | public: |
643 | |
644 | virtual void setAnnotationModel( KTextEditor::AnnotationModel* model ); |
645 | virtual KTextEditor::AnnotationModel* annotationModel() const; |
646 | |
647 | Q_SIGNALS: |
648 | void annotationModelChanged( KTextEditor::AnnotationModel*, KTextEditor::AnnotationModel* ); |
649 | |
650 | private: |
651 | KTextEditor::AnnotationModel* m_annotationModel; |
652 | |
653 | // |
654 | // KParts::ReadWrite stuff |
655 | // |
656 | public: |
657 | /** |
658 | * open the file obtained by the kparts framework |
659 | * the framework abstracts the loading of remote files |
660 | * @return success |
661 | */ |
662 | virtual bool openFile (); |
663 | |
664 | /** |
665 | * save the file obtained by the kparts framework |
666 | * the framework abstracts the uploading of remote files |
667 | * @return success |
668 | */ |
669 | virtual bool saveFile (); |
670 | |
671 | virtual void setReadWrite ( bool rw = true ); |
672 | |
673 | virtual void setModified( bool m ); |
674 | |
675 | private: |
676 | void activateDirWatch (const QString &useFileName = QString()); |
677 | void deactivateDirWatch (); |
678 | |
679 | QString m_dirWatchFile; |
680 | |
681 | public: |
682 | /** |
683 | * Type chars in a view. |
684 | * Will filter out non-printable chars from the realChars array before inserting. |
685 | */ |
686 | bool typeChars ( KateView *type, const QString &realChars ); |
687 | |
688 | /** |
689 | * gets the last line number (lines() - 1) |
690 | */ |
691 | inline int lastLine() const { return lines()-1; } |
692 | |
693 | // Repaint all of all of the views |
694 | void repaintViews(bool paintOnlyDirty = true); |
695 | |
696 | KateHighlighting *highlight () const; |
697 | |
698 | public Q_SLOTS: |
699 | void tagLines(int start, int end); |
700 | |
701 | private Q_SLOTS: |
702 | void internalHlChanged(); |
703 | |
704 | public: |
705 | void addView(KTextEditor::View *); |
706 | /** removes the view from the list of views. The view is *not* deleted. |
707 | * That's your job. Or, easier, just delete the view in the first place. |
708 | * It will remove itself. TODO: this could be converted to a private slot |
709 | * connected to the view's destroyed() signal. It is not currently called |
710 | * anywhere except from the KateView destructor. |
711 | */ |
712 | void removeView(KTextEditor::View *); |
713 | void setActiveView(KTextEditor::View*); |
714 | |
715 | bool ownedView(KateView *); |
716 | |
717 | int toVirtualColumn( int line, int column ) const; |
718 | int toVirtualColumn( const KTextEditor::Cursor& ) const; |
719 | int fromVirtualColumn( int line, int column ) const; |
720 | int fromVirtualColumn( const KTextEditor::Cursor& ) const; |
721 | |
722 | void newLine( KateView*view ); // Changes input |
723 | void backspace( KateView *view, const KTextEditor::Cursor& ); |
724 | void del( KateView *view, const KTextEditor::Cursor& ); |
725 | void transpose( const KTextEditor::Cursor& ); |
726 | void paste ( KateView* view, const QString &text ); |
727 | |
728 | public: |
729 | void indent ( KTextEditor::Range range, int change ); |
730 | void ( KateView *view, uint line, uint column, int change ); |
731 | void align ( KateView *view, const KTextEditor::Range &range ); |
732 | void insertTab( KateView *view, const KTextEditor::Cursor& ); |
733 | |
734 | enum TextTransform { Uppercase, Lowercase, Capitalize }; |
735 | |
736 | /** |
737 | Handling uppercase, lowercase and capitalize for the view. |
738 | |
739 | If there is a selection, that is transformed, otherwise for uppercase or |
740 | lowercase the character right of the cursor is transformed, for capitalize |
741 | the word under the cursor is transformed. |
742 | */ |
743 | void transform ( KateView *view, const KTextEditor::Cursor &, TextTransform ); |
744 | /** |
745 | Unwrap a range of lines. |
746 | */ |
747 | void joinLines( uint first, uint last ); |
748 | |
749 | private: |
750 | bool removeStringFromBeginning(int line, const QString &str); |
751 | bool removeStringFromEnd(int line, const QString &str); |
752 | |
753 | /** |
754 | Find the position (line and col) of the next char |
755 | that is not a space. If found line and col point to the found character. |
756 | Otherwise they have both the value -1. |
757 | @param line Line of the character which is examined first. |
758 | @param col Column of the character which is examined first. |
759 | @return True if the specified or a following character is not a space |
760 | Otherwise false. |
761 | */ |
762 | bool nextNonSpaceCharPos(int &line, int &col); |
763 | |
764 | /** |
765 | Find the position (line and col) of the previous char |
766 | that is not a space. If found line and col point to the found character. |
767 | Otherwise they have both the value -1. |
768 | @return True if the specified or a preceding character is not a space. |
769 | Otherwise false. |
770 | */ |
771 | bool previousNonSpaceCharPos(int &line, int &col); |
772 | |
773 | /** |
774 | * Sets a comment marker as defined by the language providing the attribute |
775 | * @p attrib on the line @p line |
776 | */ |
777 | void (int line, int attrib=0); |
778 | /** |
779 | * Removes a comment marker as defined by the language providing the attribute |
780 | * @p attrib on the line @p line |
781 | */ |
782 | bool (int line, int attrib=0); |
783 | |
784 | /** |
785 | * @see addStartLineCommentToSingleLine. |
786 | */ |
787 | void (int line, int attrib=0); |
788 | /** |
789 | *@see removeStartLineCommentFromSingleLine. |
790 | */ |
791 | bool (int line, int attrib=0); |
792 | /** |
793 | *@see removeStartLineCommentFromSingleLine. |
794 | */ |
795 | bool (const KTextEditor::Cursor &start, const KTextEditor::Cursor &end, int attrib=0); |
796 | |
797 | /** |
798 | * Add a comment marker as defined by the language providing the attribute |
799 | * @p attrib to each line in the selection. |
800 | */ |
801 | void ( KateView *view, int attrib=0 ); |
802 | /** |
803 | * @see addStartStopCommentToSelection. |
804 | */ |
805 | void ( KateView *view, int attrib=0 ); |
806 | |
807 | /** |
808 | * Removes comment markers relevant to the language providing |
809 | * the attribuge @p attrib from each line in the selection. |
810 | * |
811 | * @return whether the operation succeeded. |
812 | */ |
813 | bool ( KateView *view, int attrib=0 ); |
814 | /** |
815 | * @see removeStartStopCommentFromSelection. |
816 | */ |
817 | bool ( KateView *view, int attrib=0 ); |
818 | |
819 | public: |
820 | // KDE5: rename to wordAt(), add wordRangeAt(), see ktexteditor/document.h |
821 | QString getWord( const KTextEditor::Cursor& cursor ); |
822 | |
823 | public: |
824 | void newBracketMark( const KTextEditor::Cursor& start, KTextEditor::Range& bm, int maxLines = -1 ); |
825 | bool findMatchingBracket( KTextEditor::Range& range, int maxLines = -1 ); |
826 | |
827 | public: |
828 | virtual const QString &documentName () const { return m_docName; } |
829 | |
830 | private: |
831 | void updateDocName (); |
832 | |
833 | public: |
834 | /** |
835 | * @return whether the document is modified on disk since last saved |
836 | */ |
837 | bool isModifiedOnDisc() { return m_modOnHd; } |
838 | |
839 | virtual void setModifiedOnDisk( ModifiedOnDiskReason reason ); |
840 | |
841 | virtual void setModifiedOnDiskWarning ( bool on ); |
842 | |
843 | public Q_SLOTS: |
844 | /** |
845 | * Ask the user what to do, if the file has been modified on disk. |
846 | * Reimplemented from KTextEditor::Document. |
847 | */ |
848 | virtual void slotModifiedOnDisk( KTextEditor::View *v = 0 ); |
849 | |
850 | /** |
851 | * Reloads the current document from disk if possible |
852 | */ |
853 | virtual bool documentReload (); |
854 | |
855 | virtual bool documentSave (); |
856 | virtual bool documentSaveAs (); |
857 | |
858 | virtual bool save(); |
859 | public: |
860 | virtual bool saveAs( const KUrl &url ); |
861 | |
862 | Q_SIGNALS: |
863 | /** |
864 | * Indicate this file is modified on disk |
865 | * @param doc the KTextEditor::Document object that represents the file on disk |
866 | * @param isModified indicates the file was modified rather than created or deleted |
867 | * @param reason the reason we are emitting the signal. |
868 | */ |
869 | void modifiedOnDisk (KTextEditor::Document *doc, bool isModified, KTextEditor::ModificationInterface::ModifiedOnDiskReason reason); |
870 | |
871 | public: |
872 | void ignoreModifiedOnDiskOnce(); |
873 | |
874 | private: |
875 | int m_isasking; // don't reenter slotModifiedOnDisk when this is true |
876 | // -1: ignore once, 0: false, 1: true |
877 | |
878 | public: |
879 | virtual bool setEncoding (const QString &e); |
880 | virtual const QString &encoding() const; |
881 | |
882 | |
883 | public Q_SLOTS: |
884 | void setWordWrap (bool on); |
885 | void setWordWrapAt (uint col); |
886 | |
887 | public: |
888 | bool wordWrap() const; |
889 | uint wordWrapAt() const; |
890 | |
891 | public Q_SLOTS: |
892 | void setPageUpDownMovesCursor(bool on); |
893 | |
894 | public: |
895 | bool pageUpDownMovesCursor() const; |
896 | |
897 | // code folding |
898 | public: |
899 | Kate::TextLine kateTextLine(uint i); |
900 | Kate::TextLine plainKateTextLine(uint i); |
901 | |
902 | Q_SIGNALS: |
903 | void aboutToRemoveText(const KTextEditor::Range&); |
904 | |
905 | private Q_SLOTS: |
906 | void slotModOnHdDirty (const QString &path); |
907 | void slotModOnHdCreated (const QString &path); |
908 | void slotModOnHdDeleted (const QString &path); |
909 | |
910 | private: |
911 | /** |
912 | * create a MD5 digest of the file, if it is a local file. |
913 | * The result can be accessed through KateBuffer::digest(). |
914 | * This is using KMD5::hexDigest(). |
915 | * |
916 | * @return wheather the operation was attempted and succeeded. |
917 | */ |
918 | bool createDigest (); |
919 | |
920 | /** |
921 | * create a string for the modonhd warnings, giving the reason. |
922 | */ |
923 | QString reasonedMOHString() const; |
924 | |
925 | /** |
926 | * Removes all trailing whitespace in the document. |
927 | */ |
928 | void removeTrailingSpaces(); |
929 | |
930 | public: |
931 | /** |
932 | * md5 digest of this document |
933 | * @return md5 digest for this document |
934 | */ |
935 | const QByteArray &digest () const; |
936 | |
937 | void updateFileType (const QString &newType, bool user = false); |
938 | |
939 | QString fileType () const { return m_fileType; } |
940 | |
941 | /** |
942 | * Get access to buffer of this document. |
943 | * Is needed to create cursors and ranges for example. |
944 | * @return document buffer |
945 | */ |
946 | KateBuffer &buffer () { return *m_buffer; } |
947 | |
948 | /** |
949 | * set indentation mode by user |
950 | * this will remember that a user did set it and will avoid reset on save |
951 | */ |
952 | void rememberUserDidSetIndentationMode () |
953 | { |
954 | m_indenterSetByUser = true; |
955 | } |
956 | |
957 | /** |
958 | * User did set encoding for next reload => enforce it! |
959 | */ |
960 | void userSetEncodingForNextReload () |
961 | { |
962 | m_userSetEncodingForNextReload = true; |
963 | } |
964 | |
965 | // |
966 | // REALLY internal data ;) |
967 | // |
968 | private: |
969 | // text buffer |
970 | KateBuffer *const m_buffer; |
971 | |
972 | // indenter |
973 | KateAutoIndent *const m_indenter; |
974 | |
975 | bool m_hlSetByUser; |
976 | bool m_bomSetByUser; |
977 | bool m_indenterSetByUser; |
978 | bool m_userSetEncodingForNextReload; |
979 | |
980 | bool m_modOnHd; |
981 | ModifiedOnDiskReason m_modOnHdReason; |
982 | |
983 | QString m_docName; |
984 | int ; |
985 | |
986 | // file type !!! |
987 | QString m_fileType; |
988 | bool m_fileTypeSetByUser; |
989 | |
990 | /** |
991 | * document is still reloading a file |
992 | */ |
993 | bool m_reloading; |
994 | |
995 | public Q_SLOTS: |
996 | void slotQueryClose_save(bool *handled, bool* abortClosing); |
997 | |
998 | public: |
999 | virtual bool queryClose(); |
1000 | |
1001 | void makeAttribs (bool needInvalidate = true); |
1002 | |
1003 | static bool checkOverwrite( KUrl u, QWidget *parent ); |
1004 | |
1005 | /** |
1006 | * Configuration |
1007 | */ |
1008 | public: |
1009 | KateDocumentConfig *config() { return m_config; } |
1010 | KateDocumentConfig *config() const { return m_config; } |
1011 | |
1012 | void updateConfig (); |
1013 | |
1014 | private: |
1015 | KateDocumentConfig *const m_config; |
1016 | |
1017 | /** |
1018 | * Variable Reader |
1019 | * TODO add register functionality/ktexteditor interface |
1020 | */ |
1021 | private: |
1022 | /** |
1023 | * read dir config file |
1024 | */ |
1025 | void readDirConfig (); |
1026 | |
1027 | /** |
1028 | Reads all the variables in the document. |
1029 | Called when opening/saving a document |
1030 | */ |
1031 | void readVariables(bool onlyViewAndRenderer = false); |
1032 | |
1033 | /** |
1034 | Reads and applies the variables in a single line |
1035 | TODO registered variables gets saved in a [map] |
1036 | */ |
1037 | void readVariableLine( QString t, bool onlyViewAndRenderer = false ); |
1038 | /** |
1039 | Sets a view variable in all the views. |
1040 | */ |
1041 | void setViewVariable( QString var, QString val ); |
1042 | /** |
1043 | @return weather a string value could be converted |
1044 | to a bool value as supported. |
1045 | The value is put in *result. |
1046 | */ |
1047 | static bool checkBoolValue( QString value, bool *result ); |
1048 | /** |
1049 | @return weather a string value could be converted |
1050 | to a integer value. |
1051 | The value is put in *result. |
1052 | */ |
1053 | static bool checkIntValue( QString value, int *result ); |
1054 | /** |
1055 | Feeds value into @p col using QColor::setNamedColor() and returns |
1056 | wheather the color is valid |
1057 | */ |
1058 | static bool checkColorValue( QString value, QColor &col ); |
1059 | |
1060 | /** |
1061 | * helper regex to capture the document variables |
1062 | */ |
1063 | static QRegExp kvLine; |
1064 | static QRegExp kvLineWildcard; |
1065 | static QRegExp kvLineMime; |
1066 | static QRegExp kvVar; |
1067 | |
1068 | bool m_fileChangedDialogsActivated; |
1069 | |
1070 | // |
1071 | // KTextEditor::ConfigInterface |
1072 | // |
1073 | public: |
1074 | virtual QStringList configKeys() const; |
1075 | virtual QVariant configValue(const QString &key); |
1076 | virtual void setConfigValue(const QString &key, const QVariant &value); |
1077 | |
1078 | // |
1079 | // KTextEditor::RecoveryInterface |
1080 | // |
1081 | public: |
1082 | virtual bool isDataRecoveryAvailable() const; |
1083 | virtual void recoverData(); |
1084 | virtual void discardDataRecovery(); |
1085 | |
1086 | // |
1087 | // KTextEditor::HighlightInterface |
1088 | // |
1089 | public: |
1090 | virtual KTextEditor::Attribute::Ptr defaultStyle(const KTextEditor::HighlightInterface::DefaultStyle ds) const; |
1091 | virtual QList< KTextEditor::HighlightInterface::AttributeBlock > lineAttributes(const unsigned int line); |
1092 | virtual QStringList embeddedHighlightingModes() const; |
1093 | virtual QString highlightingModeAt(const KTextEditor::Cursor& position); |
1094 | // TODO KDE5: maybe make available in HighlightInterface for convenience |
1095 | virtual KTextEditor::Attribute::Ptr attributeAt(const KTextEditor::Cursor & position); |
1096 | |
1097 | // |
1098 | //BEGIN: KTextEditor::MessageInterface |
1099 | // |
1100 | public: |
1101 | virtual bool postMessage(KTextEditor::Message* message); |
1102 | |
1103 | public Q_SLOTS: |
1104 | void messageDestroyed(KTextEditor::Message* message); |
1105 | |
1106 | private: |
1107 | QHash<KTextEditor::Message *, QList<QSharedPointer<QAction> > > m_messageHash; |
1108 | //END KTextEditor::MessageInterface |
1109 | |
1110 | public: |
1111 | QString defaultDictionary() const; |
1112 | QList<QPair<KTextEditor::MovingRange*, QString> > dictionaryRanges() const; |
1113 | bool isOnTheFlySpellCheckingEnabled() const; |
1114 | |
1115 | QString dictionaryForMisspelledRange(const KTextEditor::Range& range) const; |
1116 | void clearMisspellingForWord(const QString& word); |
1117 | |
1118 | public Q_SLOTS: |
1119 | void clearDictionaryRanges(); |
1120 | void setDictionary(const QString& dict, const KTextEditor::Range &range); |
1121 | void revertToDefaultDictionary(const KTextEditor::Range &range); |
1122 | void setDefaultDictionary(const QString& dict); |
1123 | void onTheFlySpellCheckingEnabled(bool enable); |
1124 | void refreshOnTheFlyCheck(const KTextEditor::Range &range = KTextEditor::Range::invalid()); |
1125 | |
1126 | Q_SIGNALS: |
1127 | void dictionaryRangesPresent(bool yesNo); |
1128 | void defaultDictionaryChanged(KateDocument *document); |
1129 | |
1130 | public: |
1131 | bool containsCharacterEncoding(const KTextEditor::Range& range); |
1132 | |
1133 | typedef QList<QPair<int, int> > OffsetList; |
1134 | |
1135 | int computePositionWrtOffsets(const OffsetList& offsetList, int pos); |
1136 | |
1137 | /** |
1138 | * The first OffsetList is from decoded to encoded, and the second OffsetList from |
1139 | * encoded to decoded. |
1140 | **/ |
1141 | QString decodeCharacters(const KTextEditor::Range& range, |
1142 | KateDocument::OffsetList& decToEncOffsetList, |
1143 | KateDocument::OffsetList& encToDecOffsetList); |
1144 | void replaceCharactersByEncoding(const KTextEditor::Range& range); |
1145 | |
1146 | enum EncodedCharaterInsertionPolicy {EncodeAlways, EncodeWhenPresent, EncodeNever}; |
1147 | |
1148 | protected: |
1149 | KateOnTheFlyChecker *m_onTheFlyChecker; |
1150 | QString m_defaultDictionary; |
1151 | QList<QPair<KTextEditor::MovingRange*, QString> > m_dictionaryRanges; |
1152 | |
1153 | // from KTextEditor::MovingRangeFeedback |
1154 | void rangeInvalid(KTextEditor::MovingRange *movingRange); |
1155 | void rangeEmpty(KTextEditor::MovingRange *movingRange); |
1156 | |
1157 | void deleteDictionaryRange(KTextEditor::MovingRange *movingRange); |
1158 | |
1159 | private: |
1160 | Kate::SwapFile *m_swapfile; |
1161 | |
1162 | public: |
1163 | Kate::SwapFile* swapFile(); |
1164 | |
1165 | //helpers for scripting and codefolding |
1166 | int defStyleNum(int line, int column); |
1167 | bool (int line, int column); |
1168 | |
1169 | public: |
1170 | int findModifiedLine(int startLine, bool down); |
1171 | |
1172 | private Q_SLOTS: |
1173 | /** |
1174 | * watch for all started io jobs to remember if file is perhaps loading atm |
1175 | * @param job started job |
1176 | */ |
1177 | void slotStarted(KIO::Job *job); |
1178 | void slotCompleted(); |
1179 | void slotCanceled(); |
1180 | |
1181 | /** |
1182 | * trigger display of loading message, after 1000 ms |
1183 | */ |
1184 | void slotTriggerLoadingMessage (); |
1185 | |
1186 | /** |
1187 | * Abort loading |
1188 | */ |
1189 | void slotAbortLoading (); |
1190 | |
1191 | private: |
1192 | /** |
1193 | * different possible states |
1194 | */ |
1195 | enum DocumentStates { |
1196 | /** |
1197 | * Idle |
1198 | */ |
1199 | DocumentIdle, |
1200 | |
1201 | /** |
1202 | * Loading |
1203 | */ |
1204 | DocumentLoading, |
1205 | |
1206 | /** |
1207 | * Saving |
1208 | */ |
1209 | DocumentSaving, |
1210 | |
1211 | /** |
1212 | * Pre Saving As, this is between ::saveAs is called and ::save |
1213 | */ |
1214 | DocumentPreSavingAs, |
1215 | |
1216 | /** |
1217 | * Saving As |
1218 | */ |
1219 | DocumentSavingAs |
1220 | }; |
1221 | |
1222 | /** |
1223 | * current state |
1224 | */ |
1225 | DocumentStates m_documentState; |
1226 | |
1227 | /** |
1228 | * read-write state before loading started |
1229 | */ |
1230 | bool m_readWriteStateBeforeLoading; |
1231 | |
1232 | /** |
1233 | * if the document is untitled |
1234 | */ |
1235 | bool m_isUntitled; |
1236 | /** |
1237 | * loading job, we want to cancel with cancel in the loading message |
1238 | */ |
1239 | QPointer<KJob> m_loadingJob; |
1240 | |
1241 | /** |
1242 | * message to show during loading |
1243 | */ |
1244 | QPointer<KTextEditor::Message> m_loadingMessage; |
1245 | }; |
1246 | |
1247 | #endif |
1248 | |
1249 | // kate: space-indent on; indent-width 2; replace-tabs on; |
1250 | |
1251 | |