summaryrefslogtreecommitdiffstats
path: root/kate/part/katebuffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'kate/part/katebuffer.h')
-rw-r--r--kate/part/katebuffer.h709
1 files changed, 709 insertions, 0 deletions
diff --git a/kate/part/katebuffer.h b/kate/part/katebuffer.h
new file mode 100644
index 000000000..6b2d48ead
--- /dev/null
+++ b/kate/part/katebuffer.h
@@ -0,0 +1,709 @@
+/* This file is part of the KDE libraries
+ Copyright (c) 2000 Waldo Bastian <bastian@kde.org>
+ Copyright (C) 2002-2004 Christoph Cullmann <cullmann@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 __KATE_BUFFER_H__
+#define __KATE_BUFFER_H__
+
+#include "katetextline.h"
+#include "katecodefoldinghelpers.h"
+
+#include <kvmallocator.h>
+
+#include <qptrlist.h>
+#include <qobject.h>
+#include <qtimer.h>
+#include <qvaluevector.h>
+
+class KateLineInfo;
+class KateDocument;
+class KateHighlighting;
+class KateBufBlockList;
+class KateBuffer;
+class KateFileLoader;
+
+class QTextCodec;
+
+/**
+ * The KateBufBlock class contains an amount of data representing
+ * a certain number of lines.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ * @author Christoph Cullmann <cullmann@kde.org>
+ */
+class KateBufBlock
+{
+ friend class KateBufBlockList;
+
+ public:
+ /**
+ * Create an empty block. (empty == ONE line)
+ * @param parent buffer the block belongs to
+ * @param prev previous bufblock in the list
+ * @param next next bufblock in the list
+ * @param stream stream to load the content from, if any given
+ */
+ KateBufBlock ( KateBuffer *parent, KateBufBlock *prev = 0, KateBufBlock *next = 0,
+ KateFileLoader *stream = 0 );
+
+ /**
+ * destroy this block and take care of freeing all mem
+ */
+ ~KateBufBlock ();
+
+ private:
+ /**
+ * fill the block with the lines from the given stream
+ * @param stream stream to load data from
+ */
+ void fillBlock (KateFileLoader *stream);
+
+ public:
+ /**
+ * state flags
+ */
+ enum State
+ {
+ stateSwapped = 0,
+ stateClean = 1,
+ stateDirty = 2
+ };
+
+ /**
+ * returns the current state of this block
+ * @return state
+ */
+ State state () const { return m_state; }
+
+ public:
+ /**
+ * return line @p i
+ * The first line of this block is line 0.
+ * if you modifiy this line, please mark the block as dirty
+ * @param i line to return
+ * @return line pointer
+ */
+ KateTextLine::Ptr line(uint i);
+
+ /**
+ * insert @p line in front of line @p i
+ * marks the block dirty
+ * @param i where to insert
+ * @param line line pointer
+ */
+ void insertLine(uint i, KateTextLine::Ptr line);
+
+ /**
+ * remove line @p i
+ * marks the block dirty
+ * @param i line to remove
+ */
+ void removeLine(uint i);
+
+ /**
+ * mark this block as dirty, will invalidate the swap data
+ * insert/removeLine will mark the block dirty itself
+ */
+ void markDirty ();
+
+ public:
+ /**
+ * startLine
+ * @return first line in block
+ */
+ inline uint startLine () const { return m_startLine; };
+
+ /**
+ * update the first line, needed to keep it up to date
+ * @param line new startLine
+ */
+ inline void setStartLine (uint line) { m_startLine = line; }
+
+ /**
+ * first line behind this block
+ * @return line behind block
+ */
+ inline uint endLine () const { return m_startLine + m_lines; }
+
+ /**
+ * lines in this block
+ * @return lines
+ */
+ inline uint lines () const { return m_lines; }
+
+ /**
+ * prev block
+ * @return previous block
+ */
+ inline KateBufBlock *prev () { return m_prev; }
+
+ /**
+ * next block
+ * @return next block
+ */
+ inline KateBufBlock *next () { return m_next; }
+
+ /**
+ * methodes to swap in/out
+ */
+ private:
+ /**
+ * swap in the kvmallocater data, create string list
+ */
+ void swapIn ();
+
+ /**
+ * swap our string list out, delete it !
+ */
+ void swapOut ();
+
+ private:
+ /**
+ * VERY IMPORTANT, state of this block
+ * this uchar indicates if the block is swapped, loaded, clean or dirty
+ */
+ KateBufBlock::State m_state;
+
+ /**
+ * IMPORTANT, start line
+ */
+ uint m_startLine;
+
+ /**
+ * IMPORTANT, line count
+ */
+ uint m_lines;
+
+ /**
+ * here we swap our stuff
+ */
+ KVMAllocator::Block *m_vmblock;
+
+ /**
+ * swapped size
+ */
+ uint m_vmblockSize;
+
+ /**
+ * list of textlines
+ */
+ QValueVector<KateTextLine::Ptr> m_stringList;
+
+ /**
+ * parent buffer.
+ */
+ KateBuffer* m_parent;
+
+ /**
+ * prev block
+ */
+ KateBufBlock *m_prev;
+
+ /**
+ * next block
+ */
+ KateBufBlock *m_next;
+
+ private:
+ /**
+ * list pointer, to which list I belong
+ * list element pointers for the KateBufBlockList ONLY !!!
+ */
+ KateBufBlockList *list;
+
+ /**
+ * prev list item
+ */
+ KateBufBlock *listPrev;
+
+ /**
+ * next list item
+ */
+ KateBufBlock *listNext;
+};
+
+/**
+ * list which allows O(1) inserts/removes
+ * will not delete the elements on remove
+ * will use the next/prevNode pointers in the KateBufBlocks !
+ * internal use: loaded/clean/dirty block lists
+ *
+ * @author Christoph Cullmann <cullmann@kde.org>
+ */
+class KateBufBlockList
+{
+ public:
+ /**
+ * Default Constructor
+ */
+ KateBufBlockList ();
+
+ public:
+ /**
+ * count of blocks in this list
+ * @return count of blocks
+ */
+ inline uint count() const { return m_count; }
+
+ /**
+ * first block in this list or 0
+ * @return head of list
+ */
+ inline KateBufBlock *first () { return m_first; };
+
+ /**
+ * last block in this list or 0
+ * @return end of list
+ */
+ inline KateBufBlock *last () { return m_last; };
+
+ /**
+ * is buf the last block?
+ * @param buf block to test
+ * @return is this block the first one?
+ */
+ inline bool isFirst (KateBufBlock *buf) { return m_first == buf; };
+
+ /**
+ * is buf the last block?
+ * @param buf block to test
+ * @return is this block the last one?
+ */
+ inline bool isLast (KateBufBlock *buf) { return m_last == buf; };
+
+ /**
+ * append a block to this list !
+ * will remove it from the list it belonged before !
+ * @param buf block to append
+ */
+ void append (KateBufBlock *buf);
+
+ /**
+ * remove the block from the list it belongs to !
+ * @param buf block to remove
+ */
+ inline static void remove (KateBufBlock *buf)
+ {
+ if (buf->list)
+ buf->list->removeInternal (buf);
+ }
+
+ private:
+ /**
+ * internal helper for remove
+ * @param buf block to remove
+ */
+ void removeInternal (KateBufBlock *buf);
+
+ private:
+ /**
+ * count of blocks in list
+ */
+ uint m_count;
+
+ /**
+ * first block
+ */
+ KateBufBlock *m_first;
+
+ /**
+ * last block
+ */
+ KateBufBlock *m_last;
+};
+
+/**
+ * The KateBuffer class maintains a collections of lines.
+ * It allows to maintain state information in a lazy way.
+ * It handles swapping out of data using secondary storage.
+ *
+ * It is designed to handle large amounts of text-data efficiently
+ * with respect to CPU and memory usage.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ * @author Christoph Cullmann <cullmann@kde.org>
+ */
+class KateBuffer : public QObject
+{
+ Q_OBJECT
+
+ friend class KateBufBlock;
+
+ public:
+ /**
+ * maximal loaded block count
+ * @return max loaded blocks
+ */
+ inline static uint maxLoadedBlocks () { return m_maxLoadedBlocks; }
+
+ /**
+ * modifier for max loaded blocks limit
+ * @param count new limit
+ */
+ static void setMaxLoadedBlocks (uint count);
+
+ private:
+ /**
+ * global max loaded blocks limit
+ */
+ static uint m_maxLoadedBlocks;
+
+ public:
+ /**
+ * Create an empty buffer.
+ * @param doc parent document
+ */
+ KateBuffer (KateDocument *doc);
+
+ /**
+ * Goodbye buffer
+ */
+ ~KateBuffer ();
+
+ public:
+ /**
+ * start some editing action
+ */
+ void editStart ();
+
+ /**
+ * finish some editing action
+ */
+ void editEnd ();
+
+ /**
+ * were there changes in the current running
+ * editing session?
+ * @return changes done?
+ */
+ inline bool editChanged () const { return editChangesDone; }
+
+ /**
+ * dirty lines start
+ * @return start line
+ */
+ inline uint editTagStart () const { return editTagLineStart; }
+
+ /**
+ * dirty lines end
+ * @return end line
+ */
+ inline uint editTagEnd () const { return editTagLineEnd; }
+
+ /**
+ * line inserted/removed?
+ * @return line inserted/removed?
+ */
+ inline bool editTagFrom () const { return editTagLineFrom; }
+
+ private:
+ /**
+ * edit session recursion
+ */
+ uint editSessionNumber;
+
+ /**
+ * is a edit session running
+ */
+ bool editIsRunning;
+
+ /**
+ * dirty lines start at line
+ */
+ uint editTagLineStart;
+
+ /**
+ * dirty lines end at line
+ */
+ uint editTagLineEnd;
+
+ /**
+ * a line was inserted or removed
+ */
+ bool editTagLineFrom;
+
+ /**
+ * changes done?
+ */
+ bool editChangesDone;
+
+ public:
+ /**
+ * Clear the buffer.
+ */
+ void clear();
+
+ /**
+ * Open a file, use the given filename
+ * @param m_file filename to open
+ * @return success
+ */
+ bool openFile (const QString &m_file);
+
+ /**
+ * was the last loading broken because of not enough tmp disk space ?
+ * (will be reseted on successful save of the file, user gets warning if he really wants to do it)
+ * @return was loading borked?
+ */
+ bool loadingBorked () const { return m_loadingBorked; }
+
+ /**
+ * is this file a binary?
+ * @return binary file?
+ */
+ bool binary () const { return m_binary; }
+
+ /**
+ * Can the current codec handle all chars
+ * @return chars can be encoded
+ */
+ bool canEncode ();
+
+ /**
+ * Save the buffer to a file, use the given filename + codec + end of line chars (internal use of qtextstream)
+ * @param m_file filename to save to
+ * @return success
+ */
+ bool saveFile (const QString &m_file);
+
+ public:
+ /**
+ * Return line @p i
+ */
+ inline KateTextLine::Ptr line(uint i)
+ {
+ KateBufBlock *buf = findBlock(i);
+ if (!buf)
+ return 0;
+
+ if (i < m_lineHighlighted)
+ return buf->line (i - buf->startLine());
+
+ return line_internal (buf, i);
+ }
+
+ private:
+ /**
+ * line needs hl
+ */
+ KateTextLine::Ptr line_internal (KateBufBlock *buf, uint i);
+
+ inline void addIndentBasedFoldingInformation(QMemArray<uint> &foldingList,bool addindent,uint deindent);
+ inline void updatePreviousNotEmptyLine(KateBufBlock *blk,uint current_line,bool addindent,uint deindent);
+ public:
+ /**
+ * Return line @p i without triggering highlighting
+ */
+ inline KateTextLine::Ptr plainLine(uint i)
+ {
+ KateBufBlock *buf = findBlock(i);
+ if (!buf)
+ return 0;
+
+ return buf->line(i - buf->startLine());
+ }
+
+ /**
+ * Return the total number of lines in the buffer.
+ */
+ inline uint count() const { return m_lines; }
+
+ private:
+ /**
+ * Find the block containing line @p i
+ * index pointer gets filled with index of block in m_blocks
+ * index only valid if returned block != 0 !
+ */
+ KateBufBlock *findBlock (uint i, uint *index = 0)
+ {
+ // out of range !
+ if (i >= m_lines)
+ return 0;
+
+ if ((m_blocks[m_lastFoundBlock]->startLine() <= i) && (m_blocks[m_lastFoundBlock]->endLine() > i))
+ {
+ if (index)
+ (*index) = m_lastFoundBlock;
+
+ return m_blocks[m_lastFoundBlock];
+ }
+
+ return findBlock_internal (i, index);
+ }
+
+ KateBufBlock *findBlock_internal (uint i, uint *index = 0);
+
+ public:
+ /**
+ * Mark line @p i as changed !
+ */
+ void changeLine(uint i);
+
+ /**
+ * Insert @p line in front of line @p i
+ */
+ void insertLine(uint i, KateTextLine::Ptr line);
+
+ /**
+ * Remove line @p i
+ */
+ void removeLine(uint i);
+
+ public:
+ inline uint countVisible () { return m_lines - m_regionTree.getHiddenLinesCount(m_lines); }
+
+ inline uint lineNumber (uint visibleLine) { return m_regionTree.getRealLine (visibleLine); }
+
+ inline uint lineVisibleNumber (uint line) { return m_regionTree.getVirtualLine (line); }
+
+ inline void lineInfo (KateLineInfo *info, unsigned int line) { m_regionTree.getLineInfo(info,line); }
+
+ inline uint tabWidth () const { return m_tabWidth; }
+
+ public:
+ void setTabWidth (uint w);
+
+ /**
+ * Use @p highlight for highlighting
+ *
+ * @p highlight may be 0 in which case highlighting
+ * will be disabled.
+ */
+ void setHighlight (uint hlMode);
+
+ KateHighlighting *highlight () { return m_highlight; };
+
+ /**
+ * Invalidate highlighting of whole buffer.
+ */
+ void invalidateHighlighting();
+
+ KateCodeFoldingTree *foldingTree () { return &m_regionTree; };
+
+ public slots:
+ void codeFoldingColumnUpdate(unsigned int lineNr);
+
+ private:
+ /**
+ * Highlight information needs to be updated.
+ *
+ * @param buf The buffer being processed.
+ * @param startState highlighting state of last line before range
+ * @param from first line in range
+ * @param to last line in range
+ * @param invalidat should the rehighlighted lines be tagged ?
+ *
+ * @returns true when the highlighting in the next block needs to be updated,
+ * false otherwise.
+ */
+ bool doHighlight (KateBufBlock *buf, uint from, uint to, bool invalidate);
+
+ signals:
+ /**
+ * Emittend if codefolding returned with a changed list
+ */
+ void codeFoldingUpdated();
+
+ /**
+ * Emitted when the highlighting of a certain range has
+ * changed.
+ */
+ void tagLines(int start, int end);
+
+ private:
+ /**
+ * document we belong too
+ */
+ KateDocument *m_doc;
+
+ /**
+ * current line count
+ */
+ uint m_lines;
+
+ /**
+ * ALL blocks
+ * in order of linenumbers
+ */
+ QValueVector<KateBufBlock*> m_blocks;
+
+ /**
+ * last block where the start/end line is in sync with real life
+ */
+ uint m_lastInSyncBlock;
+
+ /**
+ * last block found by findBlock, there to make searching faster
+ */
+ uint m_lastFoundBlock;
+
+ /**
+ * status of the cache read/write errors
+ * write errors get handled, read errors not really atm
+ */
+ bool m_cacheReadError;
+ bool m_cacheWriteError;
+
+ /**
+ * had we cache error while loading ?
+ */
+ bool m_loadingBorked;
+
+ /**
+ * binary file loaded ?
+ */
+ bool m_binary;
+
+ /**
+ * highlighting & folding relevant stuff
+ */
+ private:
+ /**
+ * current highlighting mode or 0
+ */
+ KateHighlighting *m_highlight;
+
+ /**
+ * folding tree
+ */
+ KateCodeFoldingTree m_regionTree;
+
+ // for the scrapty indent sensitive langs
+ uint m_tabWidth;
+
+ uint m_lineHighlightedMax;
+ uint m_lineHighlighted;
+
+ /**
+ * number of dynamic contexts causing a full invalidation
+ */
+ uint m_maxDynamicContexts;
+
+ /**
+ * only used from the KateBufBlocks !
+ */
+ private:
+ /**
+ * all not swapped blocks !
+ */
+ KateBufBlockList m_loadedBlocks;
+};
+
+#endif
+
+// kate: space-indent on; indent-width 2; replace-tabs on;