File indexing completed on 2024-04-14 05:45:54

0001 /*
0002     This file is part of the Okteta Gui library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2003, 2008-2009 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #ifndef OKTETA_BYTEARRAYTABLECURSOR_HPP
0010 #define OKTETA_BYTEARRAYTABLECURSOR_HPP
0011 
0012 // lib
0013 #include "coord.hpp"
0014 
0015 namespace Okteta {
0016 class ArrayChangeMetricsList;
0017 class ByteArrayTableLayout;
0018 
0019 /**@short navigates through the buffer in an abstract way, based on the layout
0020  *
0021  * The cursor is allowed to access every coord that has content as
0022  * described in the layout. It holds the coord of the actual position
0023  * and the according index in the data array.
0024  *
0025  * To enable the cursor to be placed behind the last position in a line
0026  * (e.g, to mark all data in the line without placing the cursor to the
0027  * beginning of the next line) there is a flag mBehind that should be read
0028  * as that the real index the cursor is at is the current one + 1
0029  * (as returned by realIndex())
0030  *
0031  * For appending new data to the buffer there is also the need to be able
0032  * to place the cursor at a position behind the last byte. This can be
0033  * enabled by calling setAppendPosEnabled(true). If the cursor is placed to
0034  * this position it gets the (real) index of the last byte + 1. As this
0035  * index does not point to an existing byte validIndex() returns -1.
0036  * Check for atAppendPos() to see whether cursor is at this position.
0037  *
0038  * If the buffer is empty there is no navigation possible, of course.
0039  * The cursor will be placed to coord 0/0 with index 1, mBehind=false.
0040  *
0041  * @author Friedrich W. H. Kossebau
0042  */
0043 class ByteArrayTableCursor
0044 {
0045 public:
0046     explicit ByteArrayTableCursor(const ByteArrayTableLayout* layout);
0047     ByteArrayTableCursor(const ByteArrayTableCursor&) = delete;
0048 
0049     ~ByteArrayTableCursor();
0050 
0051     ByteArrayTableCursor& operator=(const ByteArrayTableCursor&) = delete;
0052 
0053 public: // modificator
0054     void setAppendPosEnabled(bool appendPosEnabled = true);
0055 
0056 public: // state value access
0057     /** the index that is drawn at the actual coord */
0058     Address index() const;
0059     /** the pos of the actual coord */
0060     LinePosition pos() const;
0061     /** the line of the actual coord */
0062     Line line() const;
0063     /** the actual coord */
0064     Coord coord() const;
0065     /** true if the cursor is located to the right of the actual coord but still shown at the coord */
0066     bool isBehind() const;
0067     /** returns the real index. That is if the cursor is tagged as "behind" the current index
0068      * it's real index is the next one.
0069      * Attention: this could be outside the data's range if the cursor is behind the last byte!
0070      */
0071     Address realIndex() const;
0072     /** returns the true index if it is valid index that is it is inside the data's range.
0073      * Otherwise -1 is returned
0074      */
0075     Address validIndex() const;
0076 
0077     // bool isValid() const;
0078     /**
0079      *  Default is false.
0080      */
0081     bool appendPosEnabled() const;
0082 
0083 public: // index calculation service
0084     /** returns the index at the start of the cursor's line */
0085     Address indexAtLineStart() const;
0086     /** returns the index at the end of the cursor's line */
0087     Address indexAtLineEnd() const;
0088 
0089 public: // navigation commands
0090     void gotoIndex(Address index);
0091     void gotoCoord(Coord coord);
0092     void gotoCIndex(Address index);
0093     void gotoCCoord(Coord coord);
0094     /** sets the index to the real index, i.e. if "behind" one index, sets it to the next.
0095      * Undefined if the real index is invalid, or on the append pos if not allowed.
0096      */
0097     void gotoRealIndex();
0098 
0099     void gotoPreviousByte();
0100     void gotoNextByte();
0101     void gotoPreviousByte(Size indexSteps);
0102     void gotoNextByte(Size indexSteps);
0103     void gotoUp();
0104     void gotoDown();
0105     void gotoLineStart();
0106     void gotoLineEnd();
0107     void gotoStart();
0108     /** sets the index behind the last index.
0109      * If appendPosEnabled is true, this will be the last index + 1,
0110      * otherwise it will be the last index and the flag behind.
0111      */
0112     void gotoEnd();
0113     void gotoPageUp();
0114     void gotoPageDown();
0115 
0116     /** puts the cursor behind the actual position if it isn't already*/
0117     // TODO: make protected again
0118     void stepBehind();
0119     void updateCoord();
0120     void adaptToChanges(const ArrayChangeMetricsList& changeList, Size oldLength);
0121 
0122 public: // logical state access
0123     bool atStart() const;
0124     bool atEnd() const;
0125     /** could only be true in InsertMode: Cursor is behind the last byte */
0126     bool atAppendPos() const;
0127     bool atLineStart() const;
0128     bool atLineEnd() const;
0129 
0130 private:
0131     /** if newpos allowed steps at a coord behind the last existing
0132      * or, if that is at a line end, behind the line
0133      * does not check for empty content!
0134      */
0135     void stepToEnd();
0136 
0137 private:
0138     /** layout, tells how the column is organized  */
0139     const ByteArrayTableLayout* mLayout;
0140 
0141     /** Position in buffer */
0142     Address mIndex;
0143     /** Position and Line */
0144     Coord mCoord;
0145 
0146     /** tells whether the cursor is actually behind the actual position.
0147      * This is used for selection to the end of a line or of the whole buffer.
0148      */
0149     bool mBehind : 1;
0150 
0151     /** tells whether there could be a position behind the end of the layout */
0152     bool mAppendPosEnabled : 1;
0153 };
0154 
0155 inline Address ByteArrayTableCursor::index()      const { return mIndex; }
0156 inline LinePosition ByteArrayTableCursor::pos()   const { return mCoord.pos(); }
0157 inline Line ByteArrayTableCursor::line()          const { return mCoord.line(); }
0158 inline Coord ByteArrayTableCursor::coord()        const { return mCoord; }
0159 inline bool ByteArrayTableCursor::isBehind()      const { return mBehind; }
0160 inline Address ByteArrayTableCursor::realIndex()  const { return mBehind ? mIndex + 1 : mIndex; }
0161 inline bool ByteArrayTableCursor::appendPosEnabled() const { return mAppendPosEnabled; }
0162 
0163 inline void ByteArrayTableCursor::stepBehind() { mBehind = true; }
0164 
0165 // inline bool ByteArrayTableCursor::isValid()  const { return mIndex != -1; }
0166 
0167 }
0168 
0169 #endif