627 lines
18 KiB
C++
627 lines
18 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2010, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license GPL v3 (see license file)
|
|
*/
|
|
|
|
#ifndef __APPL_BUFFER_H__
|
|
#define __APPL_BUFFER_H__
|
|
|
|
#include <etk/types.h>
|
|
#include <etk/os/FSNode.h>
|
|
#include <ewol/ewol.h>
|
|
#include <etk/Buffer.h>
|
|
#include <ewol/object/Object.h>
|
|
#include <ewol/widget/Widget.h>
|
|
#include <ewol/compositing/Text.h>
|
|
#include <appl/Highlight.h>
|
|
|
|
namespace appl {
|
|
|
|
class DisplayHLData {
|
|
public:
|
|
std::vector<appl::HighlightInfo> HLData;
|
|
int64_t posHLPass1;
|
|
int64_t posHLPass2;
|
|
};
|
|
class Buffer : public ewol::Object {
|
|
public:
|
|
class Iterator {
|
|
// Private data :
|
|
private:
|
|
int64_t m_current; //!< curent Id in the Buffer
|
|
appl::Buffer* m_data; //!< Pointer on the curent Buffer
|
|
char32_t m_value; //!< store vlue to prevent multiple calcule of getting the data
|
|
public:
|
|
/**
|
|
* @brief Basic itarator constructor with no link.
|
|
*/
|
|
Iterator():
|
|
m_current(0),
|
|
m_data(nullptr),
|
|
m_value(u32char::Null) {
|
|
// nothing to do ...
|
|
};
|
|
/**
|
|
* @brief Recopy constructor.
|
|
* @param[in] _obj The Iterator that might be copy
|
|
*/
|
|
Iterator(const Iterator & _obj):
|
|
m_current(_obj.m_current),
|
|
m_data(_obj.m_data),
|
|
m_value(u32char::Null) {
|
|
// nothing to do ...
|
|
};
|
|
/**
|
|
* @brief Asignation operator.
|
|
* @param[in] _otherIterator The Iterator that might be copy
|
|
* @return reference on the curent Iterator
|
|
*/
|
|
Iterator& operator=(const Iterator & _obj) {
|
|
m_current = _obj.m_current;
|
|
m_data = _obj.m_data;
|
|
m_value = u32char::Null;
|
|
return *this;
|
|
};
|
|
/**
|
|
* @brief Basic destructor
|
|
*/
|
|
virtual ~Iterator() {
|
|
m_current = 0;
|
|
m_data = nullptr;
|
|
m_value = u32char::Null;
|
|
};
|
|
/**
|
|
* @brief basic boolean cast
|
|
* @return true if the element is present in buffer
|
|
*/
|
|
operator bool () const {
|
|
if (m_data == nullptr) {
|
|
return false;
|
|
}
|
|
if (m_current >= m_data->m_data.size()) {
|
|
return false;
|
|
}
|
|
if (m_current < 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
/**
|
|
* @brief basic boolean cast
|
|
* @return true if the element is present in buffer
|
|
*/
|
|
operator int64_t () const {
|
|
if (m_data == nullptr) {
|
|
return 0;
|
|
}
|
|
if (m_current < 0) {
|
|
return 0;
|
|
}
|
|
if (m_current > m_data->m_data.size()) {
|
|
return m_data->m_data.size();
|
|
}
|
|
return m_current;
|
|
};
|
|
/**
|
|
* @brief Incremental operator
|
|
* @return Reference on the current iterator incremented
|
|
*/
|
|
Iterator& operator++ ();
|
|
/**
|
|
* @brief Decremental operator
|
|
* @return Reference on the current iterator decremented
|
|
*/
|
|
Iterator& operator-- ();
|
|
/**
|
|
* @brief Incremental operator
|
|
* @return Reference on a new iterator and increment the other one
|
|
*/
|
|
Iterator operator++ (int32_t) {
|
|
Iterator it(*this);
|
|
++(*this);
|
|
return it;
|
|
};
|
|
/**
|
|
* @brief Decremental operator
|
|
* @return Reference on a new iterator and decrement the other one
|
|
*/
|
|
Iterator operator-- (int32_t) {
|
|
Iterator it(*this);
|
|
--(*this);
|
|
return it;
|
|
};
|
|
/**
|
|
* @brief egality iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator== (const Iterator& _obj) const {
|
|
if ( m_current == _obj.m_current
|
|
&& m_data == _obj.m_data) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief egality iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator!= (const Iterator& _obj) const {
|
|
if ( m_current != _obj.m_current
|
|
|| m_data != _obj.m_data) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief <= iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator<= (const Iterator& _obj) const {
|
|
if (m_data != _obj.m_data) {
|
|
return false;
|
|
}
|
|
if (m_current <= _obj.m_current) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief >= iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator>= (const Iterator& _obj) const {
|
|
if (m_data != _obj.m_data) {
|
|
return false;
|
|
}
|
|
if (m_current >= _obj.m_current) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief < iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator< (const Iterator& _obj) const {
|
|
if (m_data != _obj.m_data) {
|
|
return false;
|
|
}
|
|
if (m_current < _obj.m_current) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief > iterator
|
|
* @return true if the iterator is identical pos
|
|
*/
|
|
bool operator> (const Iterator& _obj) const {
|
|
if (m_data != _obj.m_data) {
|
|
return false;
|
|
}
|
|
if (m_current > _obj.m_current) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* @brief Get the value on the current element
|
|
* @return The request element value
|
|
*/
|
|
char32_t operator* ();
|
|
/**
|
|
* @brief Get the position in the buffer
|
|
* @return The requested position.
|
|
*/
|
|
int64_t getPos() const {
|
|
if (m_data == nullptr) {
|
|
return 0;
|
|
}
|
|
if (m_current < 0) {
|
|
return 0;
|
|
}
|
|
if (m_current >= m_data->m_data.size()) {
|
|
return m_data->m_data.size()-1;
|
|
}
|
|
return m_current;
|
|
};
|
|
/**
|
|
* @brief move the element position
|
|
* @return a new iterator.
|
|
*/
|
|
Iterator operator+ (const int64_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<_val; ++iii) {
|
|
++tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
Iterator operator+ (const int32_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<_val; ++iii) {
|
|
++tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
Iterator operator+ (const size_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<(int64_t)_val; ++iii) {
|
|
++tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
/**
|
|
* @brief move the element position
|
|
* @return a new iterator.
|
|
*/
|
|
Iterator operator- (const int64_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<_val; ++iii) {
|
|
--tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
Iterator operator- (const int32_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<_val; ++iii) {
|
|
--tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
Iterator operator- (const size_t _val) const {
|
|
Iterator tmpp(*this);
|
|
for (int64_t iii=0; iii<(int64_t)_val; ++iii) {
|
|
--tmpp;
|
|
}
|
|
return tmpp;
|
|
};
|
|
private:
|
|
Iterator(Buffer* _obj, int64_t _pos) :
|
|
m_current(_pos),
|
|
m_data(_obj),
|
|
m_value(u32char::Null) {
|
|
// nothing to do ...
|
|
};
|
|
friend class Buffer;
|
|
};
|
|
public:
|
|
static const char* const eventIsModify;
|
|
static const char* const eventIsSave;
|
|
static const char* const eventSelectChange;
|
|
static const char* const eventChangeName;
|
|
public:
|
|
Buffer();
|
|
virtual ~Buffer();
|
|
private:
|
|
bool m_hasFileName; //!< when new file, the buffer has no name ==> but it might be reference with a single name ...
|
|
std::string m_fileName; //!< name of the file (with his path)
|
|
public:
|
|
/**
|
|
* @brief get the curent filename of the Buffer
|
|
*/
|
|
const std::string& getFileName() {
|
|
return m_fileName;
|
|
}
|
|
/**
|
|
* @brief Check if the buffer has a real filename.
|
|
* @return the status of the existance of a name.
|
|
*/
|
|
bool hasFileName() {
|
|
return m_hasFileName;
|
|
}
|
|
/**
|
|
* @brief Load A specific file in this buffer.
|
|
* @param[in] _name name of the file.
|
|
* @return true if file corectly opened.
|
|
*/
|
|
bool loadFile(const std::string& _name);
|
|
/**
|
|
* @brief Set a file name at this buffer (no saving ...)
|
|
* @param[in] _name name of the file.
|
|
*/
|
|
void setFileName(const std::string& _name);
|
|
/**
|
|
* @brief save the file in the specify path.
|
|
* @return true is saving well done
|
|
*/
|
|
bool storeFile();
|
|
protected:
|
|
bool m_isModify; //!< true if the file is modify
|
|
public:
|
|
/**
|
|
* @breif get the status of file modification.
|
|
* @return true if file is modify.
|
|
*/
|
|
bool isModify() {
|
|
return m_isModify;
|
|
}
|
|
/**
|
|
* @brief Set the file modification status.
|
|
* @param[in] _status New modification status.
|
|
*/
|
|
void setModification(bool _status);
|
|
protected:
|
|
etk::Buffer m_data; //!< copy of the file buffer
|
|
public:
|
|
etk::Buffer& getData() {
|
|
return m_data;
|
|
};
|
|
protected:
|
|
int64_t m_cursorPos; //!< cursor position.
|
|
public:
|
|
void moveCursor(int64_t _pos);
|
|
protected:
|
|
int64_t m_cursorSelectPos; //!< cursor position.
|
|
public:
|
|
/**
|
|
* @brief Set the selection position in the buffer.
|
|
* @param[in] _pos Position of the selection.
|
|
*/
|
|
void setSelectionPos(const Iterator& _pos);
|
|
/**
|
|
* @brief Remove Selection of the buffer.
|
|
*/
|
|
void unSelect();
|
|
/**
|
|
* @brief Remove the selection of the buffer. (do nothing if no secection)
|
|
*/
|
|
void removeSelection();
|
|
/**
|
|
* @brief Get the status of selection.
|
|
* @return true if we have a curent selection, false otherwise.
|
|
*/
|
|
bool hasTextSelected() {
|
|
return m_cursorSelectPos >= 0;
|
|
}
|
|
/**
|
|
* @brief Get the Start position of the selection.
|
|
* @return position of the start selection.
|
|
*/
|
|
int64_t getStartSelectionPos() {
|
|
return std::min(m_cursorPos, m_cursorSelectPos);
|
|
}
|
|
/**
|
|
* @brief Get the Stop position of the selection.
|
|
* @return position of the stop selection.
|
|
*/
|
|
int64_t getStopSelectionPos() {
|
|
return std::max(m_cursorPos, m_cursorSelectPos);
|
|
}
|
|
protected:
|
|
float m_cursorPreferredCol; //!< position of the cursor when up and down is done.
|
|
public:
|
|
/**
|
|
* @brief Set the favorite up and down position (distance from the left of the screen.
|
|
* @param[in] _val New distance (in pixels).
|
|
*/
|
|
void setFavoriteUpDownPos(float _val) {
|
|
m_cursorPreferredCol = _val;
|
|
}
|
|
/**
|
|
* @brief Get the favorite distance from the left screen (For up and down moving).
|
|
* @return The distance in pixels.
|
|
*/
|
|
float getFavoriteUpDownPos() {
|
|
return m_cursorPreferredCol;
|
|
}
|
|
protected:
|
|
bool m_selectMode; //!< when true, the select mode keep the moving selecting
|
|
public:
|
|
/**
|
|
* @brief Set the selection mode (if true, the move event creata a selection)
|
|
* @param[in] _status New status of the section.
|
|
*/
|
|
void setSelectMode(bool _status) {
|
|
m_selectMode = _status;
|
|
}
|
|
/**
|
|
* @brief Get the selection mode (if true, the move event creata a selection)
|
|
* @return The selecting mode.
|
|
*/
|
|
bool getSelectMode() {
|
|
return m_selectMode;
|
|
}
|
|
public:
|
|
/**
|
|
* @brief Get the position of selection around (select word).
|
|
* @param[in] _startPos Position to start the selection.
|
|
* @param[out] _beginPos Position where the element start.
|
|
* @param[out] _endPos Position where the element stop.
|
|
* @return true if we find a selection around.
|
|
*/
|
|
bool getPosAround(const Iterator& _startPos, Iterator &_beginPos, Iterator &_endPos);
|
|
/**
|
|
* @brief Expand the specify char to have a user frendly display for special char and tabs
|
|
* @param[in] _indent Curent indentation in the line
|
|
* @param[in] _value Current value to transform
|
|
* @param[out] _out String that represent the curent value to display
|
|
*/
|
|
void expand(int32_t& _indent, const char32_t& _value, std::u32string& _out) const;
|
|
/**
|
|
* @brief get the start of a line with the position in the buffer.
|
|
* @param[in] _pos position in the buffer.
|
|
* @return The position in the buffer of the start of the line.
|
|
*/
|
|
Iterator getStartLine(const Iterator& _pos);
|
|
/**
|
|
* @brief get the end of a line with the position in the buffer.
|
|
* @param[in] _pos position in the buffer.
|
|
* @return The position in the buffer of the end of the line.
|
|
*/
|
|
Iterator getEndLine(const Iterator& _pos);
|
|
/**
|
|
* @brief Search a character in the buffer.
|
|
* @param[in] _pos Position to start the search of the element.
|
|
* @param[in] _search Character to search.
|
|
* @param[out] _result Research position.
|
|
* @return true if pos if fined.
|
|
*/
|
|
// TODO : rename find
|
|
bool search(const Iterator& _pos, const char32_t& _search, Iterator& _result);
|
|
/**
|
|
* @brief Search a character in the buffer in back mode.
|
|
* @param[in] _pos Position to start the search of the element.
|
|
* @param[in] _search Character to search.
|
|
* @param[out] _result Research position.
|
|
* @return true if pos if fined.
|
|
*/
|
|
// TODO : rename rfind
|
|
bool searchBack(const Iterator& _pos, const char32_t& _search, Iterator& _result);
|
|
/**
|
|
* @brief Search a string in the buffer.
|
|
* @param[in] _pos Position to start the search of the element.
|
|
* @param[in] _search String to search.
|
|
* @param[out] _result Research position.
|
|
* @param[in] _caseSensitive (optional) Search making attention of the case [default true]
|
|
* @return true if pos if fined.
|
|
*/
|
|
// TODO : rename find
|
|
bool search(const Iterator& _pos, const std::u32string& _search, Iterator& _result, bool _caseSensitive = true);
|
|
/**
|
|
* @brief Search a string in the buffer in back mode.
|
|
* @param[in] _pos Position to start the search of the element.
|
|
* @param[in] _search String to search.
|
|
* @param[out] _result Research position.
|
|
* @param[in] _caseSensitive (optional) Search making attention of the case [default true]
|
|
* @return true if pos if fined.
|
|
*/
|
|
// TODO : rename rfind
|
|
bool searchBack(const Iterator& _pos, const std::u32string& _search, Iterator& _result, bool _caseSensitive = true);
|
|
/**
|
|
* @brief find the first character of the line "nLines" forward
|
|
* @param[in] _startPos Start position.
|
|
* @param[in] _nLines Number of line to count.
|
|
* @return position of the starting the line.
|
|
*/
|
|
Iterator countForwardNLines(const Iterator& _startPos, int32_t _nLines);
|
|
/**
|
|
* @brief find the first character of the line "nLines" backwards
|
|
* @param[in] _startPos Start position to count (this caracter is not counted)
|
|
* @param[in] _nLines Number of line to count (if == 0 means find the beginning of the line)
|
|
* @return position of the starting the line
|
|
*/
|
|
Iterator countBackwardNLines(const Iterator& _startPos, int32_t _nLines);
|
|
public:
|
|
/**
|
|
* @brief copy data in the _data ref value.
|
|
* @param[out] _data Output stream to copy.
|
|
* @return true of no error occured.
|
|
*/
|
|
bool copy(std::string& _data);
|
|
/**
|
|
* @brief copy data in the _data ref value.
|
|
* @param[out] _data Output stream to copy.
|
|
* @param[in] _pos Position to add the data.
|
|
* @param[in] _posEnd End position to end replace the data.
|
|
*/
|
|
void copy(std::string& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
|
|
/**
|
|
* @brief Write data at a specific position
|
|
* @param[in] _data Data to insert in the buffer
|
|
* @param[in] _pos Position to add the data.
|
|
* @return true if the write is done corectly
|
|
*/
|
|
bool write(const std::string& _data, const appl::Buffer::Iterator& _pos);
|
|
/**
|
|
* @brief Write data at a specific position
|
|
* @param[in] _data Data to insert in the buffer
|
|
* @param[in] _pos Position to add the data.
|
|
* @param[in] _posEnd End position to end replace the data.
|
|
* @return true if the write is done corectly
|
|
*/
|
|
bool replace(const std::string& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
|
|
public: // iterator section :
|
|
/**
|
|
* @brief Get an iterator an an specific position
|
|
* @param[in] _pos Requested position of the iterator.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator position(int64_t _pos);
|
|
/**
|
|
* @brief Get an Iterator on the start position.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator begin();
|
|
/**
|
|
* @brief Get an Iterator on the end position.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator end();
|
|
/**
|
|
* @brief Get an Iterator on the cursor position.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator cursor();
|
|
/**
|
|
* @brief Get an Iterator on the start selection.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator selectStart();
|
|
/**
|
|
* @brief Get an Iterator on the stop selection.
|
|
* @return The Iterator
|
|
*/
|
|
Iterator selectStop();
|
|
protected:
|
|
int32_t m_nbLines; //!< number of line in the buffer
|
|
public:
|
|
/**
|
|
* @brief Get the number of line in the buffer.
|
|
* @return number of line in the Buffer.
|
|
*/
|
|
int32_t getNumberOfLines() {
|
|
return m_nbLines;
|
|
}
|
|
/**
|
|
* @brief Get the cursor line numberin the buffer.
|
|
* @return the line id in the Buffer.
|
|
*/
|
|
uint32_t getCursorLinesId();
|
|
protected:
|
|
/**
|
|
* @brief Count the number of line in the buffer
|
|
*/
|
|
void countNumberofLine();
|
|
protected:
|
|
std::string m_highlightType; //!< Name of the highlight type
|
|
|
|
ewol::object::Shared<appl::Highlight> m_highlight; //!< internal link with the Highlight system
|
|
std::vector<appl::HighlightInfo> m_HLDataPass1; //!< colorisation position in the current buffer pass 1
|
|
public:
|
|
/**
|
|
* @brief Find the Highligh capability
|
|
*/
|
|
void tryFindHighlightType();
|
|
/**
|
|
* @brief Set type of highlight
|
|
* @param[in] _type type of the highlight
|
|
*/
|
|
void setHighlightType(const std::string& _type);
|
|
/**
|
|
* @brief Get type of highlight
|
|
* @return Type of the highlight
|
|
*/
|
|
const std::string& setHighlightType() {
|
|
return m_highlightType;
|
|
};
|
|
|
|
void regenerateHighLightAt(int64_t _pos, int64_t _nbDeleted, int64_t _nbAdded);
|
|
void findMainHighLightPosition(int64_t _startPos,
|
|
int64_t _endPos,
|
|
int64_t& _startId,
|
|
int64_t& _stopId,
|
|
bool _backPreviousNotEnded);
|
|
void generateHighLightAt(int64_t _pos, int64_t _endPos, int64_t _addingPos=0);
|
|
void cleanHighLight();
|
|
appl::HighlightInfo* getElementColorAtPosition(int64_t _pos, int64_t &_starPos);
|
|
void hightlightGenerateLines(appl::DisplayHLData& _MData, const appl::Buffer::Iterator& _HLStart, int64_t _nbLines);
|
|
appl::HighlightInfo* getElementColorAtPosition(appl::DisplayHLData& _MData, int64_t _pos);
|
|
};
|
|
};
|
|
|
|
|
|
#endif
|