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
51namespace KTextEditor {
52 class Plugin;
53 class Attribute;
54 class TemplateScript;
55}
56
57namespace KIO { class TransferJob; }
58
59namespace Kate { class SwapFile; }
60
61class KateBuffer;
62class KateView;
63class KateDocumentConfig;
64class KateHighlighting;
65class KateUndoManager;
66class KateOnTheFlyChecker;
67
68class KateAutoIndent;
69
70
71//
72// Kate KTextEditor::Document class (and even KTextEditor::Editor ;)
73//
74class 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
131Q_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 charactersSemiInteractivelyInserted(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 markContextMenuRequested( 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 comment ( 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 addStartLineCommentToSingleLine(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 removeStartLineCommentFromSingleLine(int line, int attrib=0);
783
784 /**
785 * @see addStartLineCommentToSingleLine.
786 */
787 void addStartStopCommentToSingleLine(int line, int attrib=0);
788 /**
789 *@see removeStartLineCommentFromSingleLine.
790 */
791 bool removeStartStopCommentFromSingleLine(int line, int attrib=0);
792 /**
793 *@see removeStartLineCommentFromSingleLine.
794 */
795 bool removeStartStopCommentFromRegion(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 addStartStopCommentToSelection( KateView *view, int attrib=0 );
802 /**
803 * @see addStartStopCommentToSelection.
804 */
805 void addStartLineCommentToSelection( 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 removeStartStopCommentFromSelection( KateView *view, int attrib=0 );
814 /**
815 * @see removeStartStopCommentFromSelection.
816 */
817 bool removeStartLineCommentFromSelection( 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 m_docNameNumber;
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 isComment(int line, int column);
1168
1169public:
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