summaryrefslogtreecommitdiffstats
path: root/kate/part/katesupercursor.h
diff options
context:
space:
mode:
Diffstat (limited to 'kate/part/katesupercursor.h')
-rw-r--r--kate/part/katesupercursor.h463
1 files changed, 463 insertions, 0 deletions
diff --git a/kate/part/katesupercursor.h b/kate/part/katesupercursor.h
new file mode 100644
index 000000000..e6b16baa8
--- /dev/null
+++ b/kate/part/katesupercursor.h
@@ -0,0 +1,463 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2003 Hamish Rodda <rodda@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KATESUPERCURSOR_H
+#define KATESUPERCURSOR_H
+
+#include "katecursor.h"
+
+class KateDocument;
+class KateView;
+
+/**
+ * Possible additional features:
+ * - Notification when a cursor enters or exits a view
+ * - suggest something :)
+ *
+ * Unresolved issues:
+ * - testing, testing, testing
+ * - ie. everything which hasn't already been tested, you can see that which has inside the #ifdefs
+ * - api niceness
+ */
+
+/**
+ * A cursor which updates and gives off various interesting signals.
+ *
+ * This aims to be a working version of what KateCursor was originally intended to be.
+ *
+ * @author Hamish Rodda
+ **/
+class KateSuperCursor : public QObject, public KateDocCursor, public Kate::Cursor
+{
+ Q_OBJECT
+
+public:
+ /**
+ * bool privateC says: if private, than don't show to apps using the cursorinterface in the list,
+ * all internally only used SuperCursors should be private or people could modify them from the
+ * outside breaking kate's internals
+ */
+ KateSuperCursor(KateDocument* doc, bool privateC, const KateTextCursor& cursor, QObject* parent = 0L, const char* name = 0L);
+ KateSuperCursor(KateDocument* doc, bool privateC, int lineNum = 0, int col = 0, QObject* parent = 0L, const char* name = 0L);
+
+ ~KateSuperCursor ();
+
+ public:
+ // KTextEditor::Cursor interface
+ void position(uint *line, uint *col) const;
+ bool setPosition(uint line, uint col);
+ bool insertText(const QString& text);
+ bool removeText(uint numberOfCharacters);
+ QChar currentChar() const;
+
+ /**
+ * @returns true if the cursor is situated at the start of the line, false if it isn't.
+ */
+ bool atStartOfLine() const;
+
+ /**
+ * @returns true if the cursor is situated at the end of the line, false if it isn't.
+ */
+ bool atEndOfLine() const;
+
+ /**
+ * Returns how this cursor behaves when text is inserted at the cursor.
+ * Defaults to not moving on insert.
+ */
+ bool moveOnInsert() const;
+
+ /**
+ * Change the behavior of the cursor when text is inserted at the cursor.
+ *
+ * If @p moveOnInsert is true, the cursor will end up at the end of the insert.
+ */
+ void setMoveOnInsert(bool moveOnInsert);
+
+ /**
+ * Debug: output the position.
+ */
+ operator QString();
+
+ // Reimplementations;
+ virtual void setLine(int lineNum);
+ virtual void setCol(int colNum);
+ virtual void setPos(const KateTextCursor& pos);
+ virtual void setPos(int lineNum, int colNum);
+
+ signals:
+ /**
+ * The cursor's position was directly changed by the program.
+ */
+ void positionDirectlyChanged();
+
+ /**
+ * The cursor's position was changed.
+ */
+ void positionChanged();
+
+ /**
+ * Athough an edit took place, the cursor's position was unchanged.
+ */
+ void positionUnChanged();
+
+ /**
+ * The cursor's surrounding characters were both deleted simultaneously.
+ * The cursor is automatically placed at the start of the deleted region.
+ */
+ void positionDeleted();
+
+ /**
+ * A character was inserted immediately before the cursor.
+ *
+ * Whether the char was inserted before or after this cursor depends on
+ * moveOnInsert():
+ * @li true -> the char was inserted before
+ * @li false -> the char was inserted after
+ */
+ void charInsertedAt();
+
+ /**
+ * The character immediately before the cursor was deleted.
+ */
+ void charDeletedBefore();
+
+ /**
+ * The character immediately after the cursor was deleted.
+ */
+ void charDeletedAfter();
+
+ //BEGIN METHODES TO CALL FROM KATE DOCUMENT TO KEEP CURSOR UP TO DATE
+ public:
+ void editTextInserted ( uint line, uint col, uint len);
+ void editTextRemoved ( uint line, uint col, uint len);
+
+ void editLineWrapped ( uint line, uint col, bool newLine = true );
+ void editLineUnWrapped ( uint line, uint col, bool removeLine = true, uint length = 0 );
+
+ void editLineInserted ( uint line );
+ void editLineRemoved ( uint line );
+ //END
+
+ private:
+ KateDocument *m_doc;
+ bool m_moveOnInsert : 1;
+ bool m_lineRemoved : 1;
+ bool m_privateCursor : 1;
+};
+
+/**
+ * Represents a range of text, from the start() to the end().
+ *
+ * Also tracks its position and emits useful signals.
+ */
+class KateSuperRange : public QObject, public KateRange
+{
+ friend class KateSuperRangeList;
+
+ Q_OBJECT
+
+public:
+ /// Determine how the range reacts to characters inserted immediately outside the range.
+ enum InsertBehaviour {
+ /// Don't expand to encapsulate new characters in either direction. This is the default.
+ DoNotExpand = 0,
+ /// Expand to encapsulate new characters to the left of the range.
+ ExpandLeft = 0x1,
+ /// Expand to encapsulate new characters to the right of the range.
+ ExpandRight = 0x2
+ };
+
+ /**
+ * Constructor. Takes posession of @p start and @p end.
+ */
+ KateSuperRange(KateSuperCursor* start, KateSuperCursor* end, QObject* parent = 0L, const char* name = 0L);
+ KateSuperRange(KateDocument* doc, const KateRange& range, QObject* parent = 0L, const char* name = 0L);
+ KateSuperRange(KateDocument* doc, const KateTextCursor& start, const KateTextCursor& end, QObject* parent = 0L, const char* name = 0L);
+
+ virtual ~KateSuperRange();
+
+ // fulfill KateRange requirements
+ virtual KateTextCursor& start();
+ virtual KateTextCursor& end();
+ virtual const KateTextCursor& start() const;
+ virtual const KateTextCursor& end() const;
+
+ void allowZeroLength(bool yes=true){m_allowZeroLength=yes;}
+ /**
+ * Returns the super start cursor.
+ */
+ KateSuperCursor& superStart();
+ const KateSuperCursor& superStart() const;
+
+ /**
+ * Returns the super end cursor.
+ */
+ KateSuperCursor& superEnd();
+ const KateSuperCursor& superEnd() const;
+
+ /**
+ * Returns how this range reacts to characters inserted immediately outside the range.
+ */
+ int behaviour() const;
+
+ /**
+ * Determine how the range should react to characters inserted immediately outside the range.
+ *
+ * TODO does this need a custom function to enable determining of the behavior based on the
+ * text that is inserted / deleted?
+ *
+ * @sa InsertBehaviour
+ */
+ void setBehaviour(int behaviour);
+
+ /**
+ * Start and end must be valid and start <= end.
+ */
+ virtual bool isValid() const;
+
+ /**
+ * This is for use where the ranges are used in a heirachy,
+ * ie. their parents are KateSuperRanges which completely
+ * encapsulate them.
+ *
+ * @todo constrain children when their position changes deliberately;
+ * eliminate() children when they are equivalent to their parents
+ *
+ * @returns true if the range contains the cursor and no children
+ * also contain it; false otherwise.
+ */
+ bool owns(const KateTextCursor& cursor) const;
+
+ /**
+ * Returns true if the range includes @p cursor 's character.
+ * Returns false if @p cursor == end().
+ */
+ bool includes(const KateTextCursor& cursor) const;
+
+ /**
+ * Returns true if the range includes @p line
+ */
+ bool includes(uint lineNum) const;
+
+ /**
+ * Returns true if the range totally encompasses @p line
+ */
+ bool includesWholeLine(uint lineNum) const;
+
+ /**
+ * Returns whether @p cursor is the site of a boundary of this range.
+ */
+ bool boundaryAt(const KateTextCursor& cursor) const;
+
+ /**
+ * Returns whether there is a boundary of this range on @p line.
+ */
+ bool boundaryOn(uint lineNum) const;
+
+signals:
+ /**
+ * More interesting signals that aren't worth implementing here:
+ * firstCharDeleted: start()::charDeleted()
+ * lastCharDeleted: end()::previousCharDeleted()
+ */
+
+ /**
+ * The range's position changed.
+ */
+ void positionChanged();
+
+ /**
+ * The range's position was unchanged.
+ */
+ void positionUnChanged();
+
+ /**
+ * The contents of the range changed.
+ */
+ void contentsChanged();
+
+ /**
+ * Either cursor's surrounding characters were both deleted.
+ */
+ void boundaryDeleted();
+
+ /**
+ * The range now contains no characters (ie. the start and end cursors are the same).
+ *
+ * To eliminate this range under different conditions, connect the other signal directly
+ * to this signal.
+ */
+ void eliminated();
+
+ /**
+ * Indicates the region needs re-drawing.
+ */
+ void tagRange(KateSuperRange* range);
+
+public slots:
+ void slotTagRange();
+
+private slots:
+ void slotEvaluateChanged();
+ void slotEvaluateUnChanged();
+
+private:
+ void init();
+ void evaluateEliminated();
+ void evaluatePositionChanged();
+
+ KateSuperCursor* m_start;
+ KateSuperCursor* m_end;
+ bool m_evaluate;
+ bool m_startChanged;
+ bool m_endChanged;
+ bool m_deleteCursors;
+ bool m_allowZeroLength;
+};
+
+class KateSuperCursorList : public QPtrList<KateSuperCursor>
+{
+protected:
+ virtual int compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2);
+};
+
+class KateSuperRangeList : public QObject, public QPtrList<KateSuperRange>
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @sa autoManage()
+ */
+ KateSuperRangeList(bool autoManage = true, QObject* parent = 0L, const char* name = 0L);
+
+ /**
+ * Semi-copy constructor.
+ *
+ * Does not copy auto-manage value, as that would make it too easy to perform
+ * double-deletions.
+ *
+ * Also, does not connect signals and slots to save time, as this is mainly
+ * used by the document itself while drawing (call connectAll() to re-constitute)
+ */
+ KateSuperRangeList(const QPtrList<KateSuperRange>& rangeList, QObject* parent = 0L, const char* name = 0L);
+
+ virtual ~KateSuperRangeList() {}
+ /**
+ * Append another list.
+ * If this object was created by the semi-copy constructor, it may not connect items
+ * (unless connectAll() has already been called), call connectAll().
+ */
+ void appendList(const QPtrList<KateSuperRange>& rangeList);
+
+ /**
+ * Connect items that are not connected. This only needs to be called once,
+ * and only if this was created with the semi-copy constructor.
+ */
+ void connectAll();
+
+ /**
+ * Override to emit rangeEliminated() signals.
+ */
+ virtual void clear();
+
+ /**
+ * Automanage is a combination of autodeleting of the objects and
+ * removing of any eliminated() ranges.
+ */
+ bool autoManage() const;
+
+ /**
+ * @sa autoManage()
+ */
+ void setAutoManage(bool autoManage);
+
+ /**
+ * This is just a straight-forward list so that there is no confusion about whether
+ * this list should be auto-managed (ie. it shouldn't, to avoid double deletions).
+ */
+ QPtrList<KateSuperRange> rangesIncluding(const KateTextCursor& cursor);
+ QPtrList<KateSuperRange> rangesIncluding(uint line);
+
+ /**
+ * @retval true if one of the ranges in the list includes @p cursor
+ * @retval false otherwise
+ */
+ bool rangesInclude(const KateTextCursor& cursor);
+
+ /**
+ * Construct a list of boundaries, and return the first, or 0L if there are none.
+ * If @p start is defined, the first boundary returned will be at or after @p start.
+ *
+ * @returns the first boundary location
+ */
+ KateSuperCursor* firstBoundary(const KateTextCursor* start = 0L);
+
+ /**
+ * @returns the next boundary, or 0L if there are no more.
+ */
+ KateSuperCursor* nextBoundary();
+
+ /**
+ * @returns the current boundary
+ */
+ KateSuperCursor* currentBoundary();
+
+signals:
+ /**
+ * The range now contains no characters (ie. the start and end cursors are the same).
+ * If autoManage() is true, the range will be deleted after the signal has processed.
+ */
+ void rangeEliminated(KateSuperRange* range);
+
+ /**
+ * There are no ranges left.
+ */
+ void listEmpty();
+
+ /**
+ * Connected to all ranges if connect()ed.
+ */
+ void tagRange(KateSuperRange* range);
+
+protected:
+ /**
+ * internal reimplementation
+ */
+ virtual int compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2);
+
+ /**
+ * internal reimplementation
+ */
+ virtual QPtrCollection::Item newItem(QPtrCollection::Item d);
+
+private slots:
+ void slotEliminated();
+ void slotDeleted(QObject* range);
+
+private:
+ bool m_autoManage;
+ bool m_connect;
+
+ KateSuperCursorList m_columnBoundaries;
+ bool m_trackingBoundaries;
+};
+
+#endif
+
+// kate: space-indent on; indent-width 2; replace-tabs on;