diff --git a/lib/BlockArray.cpp b/lib/BlockArray.cpp index 45b4346c..c512aca8 100644 --- a/lib/BlockArray.cpp +++ b/lib/BlockArray.cpp @@ -32,25 +32,24 @@ #include #include - using namespace Konsole; static int blocksize = 0; BlockArray::BlockArray() - : size(0), - current(size_t(-1)), - index(size_t(-1)), - lastmap(nullptr), - lastmap_index(size_t(-1)), - lastblock(nullptr), ion(-1), - length(0) + : size(0), + current(size_t(-1)), + index(size_t(-1)), + lastmap(nullptr), + lastmap_index(size_t(-1)), + lastblock(nullptr), + ion(-1), + length(0) { // lastmap_index = index = current = size_t(-1); if (blocksize == 0) { blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize(); } - } BlockArray::~BlockArray() @@ -59,7 +58,7 @@ BlockArray::~BlockArray() Q_ASSERT(!lastblock); } -size_t BlockArray::append(Block * block) +size_t BlockArray::append(Block *block) { if (!size) { return size_t(-1); @@ -106,7 +105,7 @@ size_t BlockArray::newBlock() return index + 1; } -Block * BlockArray::lastBlock() const +Block *BlockArray::lastBlock() const { return lastblock; } @@ -126,7 +125,7 @@ bool BlockArray::has(size_t i) const return true; } -const Block * BlockArray::at(size_t i) +const Block *BlockArray::at(size_t i) { if (i == index + 1) { return lastblock; @@ -141,17 +140,17 @@ const Block * BlockArray::at(size_t i) return nullptr; } -// if (index - i >= length) { -// kDebug(1211) << "BlockArray::at() index - i >= length\n"; -// return 0; -// } + // if (index - i >= length) { + // kDebug(1211) << "BlockArray::at() index - i >= length\n"; + // return 0; + // } size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ; Q_ASSERT(j < size); unmap(); - Block * block = (Block *)mmap(nullptr, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize); + Block *block = (Block *)mmap(nullptr, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize); if (block == (Block *)-1) { perror("mmap"); @@ -183,7 +182,7 @@ bool BlockArray::setSize(size_t newsize) bool BlockArray::setHistorySize(size_t newsize) { -// kDebug(1211) << "setHistorySize " << size << " " << newsize; + // kDebug(1211) << "setHistorySize " << size << " " << newsize; if (size == newsize) { return false; @@ -203,12 +202,12 @@ bool BlockArray::setHistorySize(size_t newsize) } if (!size) { - FILE * tmp = tmpfile(); + FILE *tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); } else { ion = dup(fileno(tmp)); - if (ion<0) { + if (ion < 0) { perror("konsole: cannot dup temp file.\n"); fclose(tmp); } @@ -230,14 +229,14 @@ bool BlockArray::setHistorySize(size_t newsize) return false; } else { decreaseBuffer(newsize); - ftruncate(ion, length*blocksize); + ftruncate(ion, length * blocksize); size = newsize; return true; } } -void moveBlock(FILE * fion, int cursor, int newpos, char * buffer2) +void moveBlock(FILE *fion, int cursor, int newpos, char *buffer2) { int res = fseek(fion, cursor * blocksize, SEEK_SET); if (res) { @@ -272,11 +271,11 @@ void BlockArray::decreaseBuffer(size_t newsize) } // The Block constructor could do somthing in future... - char * buffer1 = new char[blocksize]; + char *buffer1 = new char[blocksize]; - FILE * fion = fdopen(dup(ion), "w+b"); + FILE *fion = fdopen(dup(ion), "w+b"); if (!fion) { - delete [] buffer1; + delete[] buffer1; perror("fdopen/dup"); return; } @@ -289,7 +288,7 @@ void BlockArray::decreaseBuffer(size_t newsize) } size_t oldpos; - for (size_t i = 0, cursor=firstblock; i < newsize; i++) { + for (size_t i = 0, cursor = firstblock; i < newsize; i++) { oldpos = (size + cursor + offset) % size; moveBlock(fion, oldpos, cursor, buffer1); if (oldpos < newsize) { @@ -302,10 +301,9 @@ void BlockArray::decreaseBuffer(size_t newsize) current = newsize - 1; length = newsize; - delete [] buffer1; + delete[] buffer1; fclose(fion); - } void BlockArray::increaseBuffer() @@ -320,8 +318,8 @@ void BlockArray::increaseBuffer() } // The Block constructor could do somthing in future... - char * buffer1 = new char[blocksize]; - char * buffer2 = new char[blocksize]; + char *buffer1 = new char[blocksize]; + char *buffer2 = new char[blocksize]; int runs = 1; int bpr = size; // blocks per run @@ -331,11 +329,11 @@ void BlockArray::increaseBuffer() runs = offset; } - FILE * fion = fdopen(dup(ion), "w+b"); + FILE *fion = fdopen(dup(ion), "w+b"); if (!fion) { perror("fdopen/dup"); - delete [] buffer1; - delete [] buffer2; + delete[] buffer1; + delete[] buffer2; return; } @@ -352,7 +350,7 @@ void BlockArray::increaseBuffer() perror("fread"); } int newpos = 0; - for (int j = 1, cursor=firstblock; j < bpr; j++) { + for (int j = 1, cursor = firstblock; j < bpr; j++) { cursor = (cursor + offset) % size; newpos = (cursor - offset + size) % size; moveBlock(fion, cursor, newpos, buffer2); @@ -369,10 +367,8 @@ void BlockArray::increaseBuffer() current = size - 1; length = size; - delete [] buffer1; - delete [] buffer2; + delete[] buffer1; + delete[] buffer2; fclose(fion); - } - diff --git a/lib/BlockArray.h b/lib/BlockArray.h index 52b531aa..8aa3c607 100644 --- a/lib/BlockArray.h +++ b/lib/BlockArray.h @@ -28,83 +28,79 @@ //#error Do not use in KDE 2.1 #define QTERMWIDGET_BLOCKSIZE (1 << 12) -#define ENTRIES ((QTERMWIDGET_BLOCKSIZE - sizeof(size_t) ) / sizeof(unsigned char)) +#define ENTRIES ((QTERMWIDGET_BLOCKSIZE - sizeof(size_t)) / sizeof(unsigned char)) namespace Konsole { -struct Block { - Block() { - size = 0; - } +struct Block +{ + Block() { size = 0; } unsigned char data[ENTRIES]; size_t size; }; // /////////////////////////////////////////////////////// -class BlockArray { +class BlockArray +{ public: /** - * Creates a history file for holding - * maximal size blocks. If more blocks - * are requested, then it drops earlier - * added ones. - */ + * Creates a history file for holding + * maximal size blocks. If more blocks + * are requested, then it drops earlier + * added ones. + */ BlockArray(); /// destructor ~BlockArray(); /** - * adds the Block at the end of history. - * This may drop other blocks. - * - * The ownership on the block is transfered. - * An unique index number is returned for accessing - * it later (if not yet dropped then) - * - * Note, that the block may be dropped completely - * if history is turned off. - */ - size_t append(Block * block); + * adds the Block at the end of history. + * This may drop other blocks. + * + * The ownership on the block is transfered. + * An unique index number is returned for accessing + * it later (if not yet dropped then) + * + * Note, that the block may be dropped completely + * if history is turned off. + */ + size_t append(Block *block); /** - * gets the block at the index. Function may return - * 0 if the block isn't available any more. - * - * The returned block is strictly readonly as only - * maped in memory - and will be invalid on the next - * operation on this class. - */ - const Block * at(size_t index); + * gets the block at the index. Function may return + * 0 if the block isn't available any more. + * + * The returned block is strictly readonly as only + * maped in memory - and will be invalid on the next + * operation on this class. + */ + const Block *at(size_t index); /** - * reorders blocks as needed. If newsize is null, - * the history is emptied completely. The indices - * returned on append won't change their semantic, - * but they may not be valid after this call. - */ + * reorders blocks as needed. If newsize is null, + * the history is emptied completely. The indices + * returned on append won't change their semantic, + * but they may not be valid after this call. + */ bool setHistorySize(size_t newsize); size_t newBlock(); - Block * lastBlock() const; + Block *lastBlock() const; /** - * Convenient function to set the size in KBytes - * instead of blocks - */ + * Convenient function to set the size in KBytes + * instead of blocks + */ bool setSize(size_t newsize); - size_t len() const { - return length; - } + size_t len() const { return length; } bool has(size_t index) const; - size_t getCurrent() const { - return current; - } + size_t getCurrent() const { return current; } private: void unmap(); @@ -116,13 +112,12 @@ class BlockArray { size_t current; size_t index; - Block * lastmap; + Block *lastmap; size_t lastmap_index; - Block * lastblock; + Block *lastblock; int ion; size_t length; - }; } diff --git a/lib/Character.h b/lib/Character.h index 9c9fae29..9262cc1d 100644 --- a/lib/Character.h +++ b/lib/Character.h @@ -29,29 +29,28 @@ // Local #include "CharacterColor.h" -namespace Konsole -{ +namespace Konsole { typedef unsigned char LineProperty; -static const int LINE_DEFAULT = 0; -static const int LINE_WRAPPED = (1 << 0); -static const int LINE_DOUBLEWIDTH = (1 << 1); -static const int LINE_DOUBLEHEIGHT = (1 << 2); - -#define DEFAULT_RENDITION 0 -#define RE_BOLD (1 << 0) -#define RE_BLINK (1 << 1) -#define RE_UNDERLINE (1 << 2) -#define RE_REVERSE (1 << 3) // Screen only -#define RE_INTENSIVE (1 << 3) // Widget only -#define RE_ITALIC (1 << 4) -#define RE_CURSOR (1 << 5) -#define RE_EXTENDED_CHAR (1 << 6) -#define RE_FAINT (1 << 7) -#define RE_STRIKEOUT (1 << 8) -#define RE_CONCEAL (1 << 9) -#define RE_OVERLINE (1 << 10) +static const int LINE_DEFAULT = 0; +static const int LINE_WRAPPED = (1 << 0); +static const int LINE_DOUBLEWIDTH = (1 << 1); +static const int LINE_DOUBLEHEIGHT = (1 << 2); + +#define DEFAULT_RENDITION 0 +#define RE_BOLD (1 << 0) +#define RE_BLINK (1 << 1) +#define RE_UNDERLINE (1 << 2) +#define RE_REVERSE (1 << 3) // Screen only +#define RE_INTENSIVE (1 << 3) // Widget only +#define RE_ITALIC (1 << 4) +#define RE_CURSOR (1 << 5) +#define RE_EXTENDED_CHAR (1 << 6) +#define RE_FAINT (1 << 7) +#define RE_STRIKEOUT (1 << 8) +#define RE_CONCEAL (1 << 9) +#define RE_OVERLINE (1 << 10) /** * A single character in the terminal which consists of a unicode character @@ -61,116 +60,111 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2); class Character { public: - /** - * Constructs a new character. - * - * @param _c The unicode character value of this character. - * @param _f The foreground color used to draw the character. - * @param _b The color used to draw the character's background. - * @param _r A set of rendition flags which specify how this character is to be drawn. - */ - inline Character(quint16 _c = ' ', - CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR), - CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR), - quint8 _r = DEFAULT_RENDITION) - : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {} - - union - { - /** The unicode character value for this character. */ - wchar_t character; /** - * Experimental addition which allows a single Character instance to contain more than - * one unicode character. + * Constructs a new character. * - * charSequence is a hash code which can be used to look up the unicode - * character sequence in the ExtendedCharTable used to create the sequence. + * @param _c The unicode character value of this character. + * @param _f The foreground color used to draw the character. + * @param _b The color used to draw the character's background. + * @param _r A set of rendition flags which specify how this character is to be drawn. + */ + inline Character(quint16 _c = ' ', + CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_FORE_COLOR), + CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_BACK_COLOR), + quint8 _r = DEFAULT_RENDITION) + : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) + { + } + + union { + /** The unicode character value for this character. */ + wchar_t character; + /** + * Experimental addition which allows a single Character instance to contain more than + * one unicode character. + * + * charSequence is a hash code which can be used to look up the unicode + * character sequence in the ExtendedCharTable used to create the sequence. + */ + quint16 charSequence; + }; + + /** A combination of RENDITION flags which specify options for drawing the character. */ + quint8 rendition; + + /** The foreground color used to draw this character. */ + CharacterColor foregroundColor; + /** The color used to draw this character's background. */ + CharacterColor backgroundColor; + + /** + * Returns true if this character has a transparent background when + * it is drawn with the specified @p palette. + */ + bool isTransparent(const ColorEntry *palette) const; + /** + * Returns true if this character should always be drawn in bold when + * it is drawn with the specified @p palette, independent of whether + * or not the character has the RE_BOLD rendition flag. + */ + ColorEntry::FontWeight fontWeight(const ColorEntry *base) const; + + /** + * returns true if the format (color, rendition flag) of the compared characters is equal */ - quint16 charSequence; - }; - - /** A combination of RENDITION flags which specify options for drawing the character. */ - quint8 rendition; - - /** The foreground color used to draw this character. */ - CharacterColor foregroundColor; - /** The color used to draw this character's background. */ - CharacterColor backgroundColor; - - /** - * Returns true if this character has a transparent background when - * it is drawn with the specified @p palette. - */ - bool isTransparent(const ColorEntry* palette) const; - /** - * Returns true if this character should always be drawn in bold when - * it is drawn with the specified @p palette, independent of whether - * or not the character has the RE_BOLD rendition flag. - */ - ColorEntry::FontWeight fontWeight(const ColorEntry* base) const; - - /** - * returns true if the format (color, rendition flag) of the compared characters is equal - */ - bool equalsFormat(const Character &other) const; - - /** - * Compares two characters and returns true if they have the same unicode character value, - * rendition and colors. - */ - friend bool operator == (const Character& a, const Character& b); - /** - * Compares two characters and returns true if they have different unicode character values, - * renditions or colors. - */ - friend bool operator != (const Character& a, const Character& b); + bool equalsFormat(const Character &other) const; + + /** + * Compares two characters and returns true if they have the same unicode character value, + * rendition and colors. + */ + friend bool operator==(const Character &a, const Character &b); + /** + * Compares two characters and returns true if they have different unicode character values, + * renditions or colors. + */ + friend bool operator!=(const Character &a, const Character &b); }; -inline bool operator == (const Character& a, const Character& b) +inline bool operator==(const Character &a, const Character &b) { - return a.character == b.character && - a.rendition == b.rendition && - a.foregroundColor == b.foregroundColor && - a.backgroundColor == b.backgroundColor; + return a.character == b.character && a.rendition == b.rendition + && a.foregroundColor == b.foregroundColor && a.backgroundColor == b.backgroundColor; } -inline bool operator != (const Character& a, const Character& b) +inline bool operator!=(const Character &a, const Character &b) { - return a.character != b.character || - a.rendition != b.rendition || - a.foregroundColor != b.foregroundColor || - a.backgroundColor != b.backgroundColor; + return a.character != b.character || a.rendition != b.rendition + || a.foregroundColor != b.foregroundColor || a.backgroundColor != b.backgroundColor; } -inline bool Character::isTransparent(const ColorEntry* base) const +inline bool Character::isTransparent(const ColorEntry *base) const { - return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && - base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent) - || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && - base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent); + return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) + && base[backgroundColor._u + 0 + (backgroundColor._v ? BASE_COLORS : 0)].transparent) + || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) + && base[backgroundColor._u + 2 + (backgroundColor._v ? BASE_COLORS : 0)] + .transparent); } -inline bool Character::equalsFormat(const Character& other) const +inline bool Character::equalsFormat(const Character &other) const { - return - backgroundColor==other.backgroundColor && - foregroundColor==other.foregroundColor && - rendition==other.rendition; + return backgroundColor == other.backgroundColor && foregroundColor == other.foregroundColor + && rendition == other.rendition; } -inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const +inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry *base) const { if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) - return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight; + return base[backgroundColor._u + 0 + (backgroundColor._v ? BASE_COLORS : 0)].fontWeight; else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) - return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight; + return base[backgroundColor._u + 2 + (backgroundColor._v ? BASE_COLORS : 0)].fontWeight; else return ColorEntry::UseCurrentFormat; } extern unsigned short vt100_graphics[32]; - /** * A table which stores sequences of unicode characters, referenced * by hash keys. The hash key itself is the same size as a unicode @@ -195,7 +189,7 @@ class ExtendedCharTable * @param unicodePoints An array of unicode character points * @param length Length of @p unicodePoints */ - ushort createExtendedChar(ushort* unicodePoints , ushort length); + ushort createExtendedChar(ushort *unicodePoints, ushort length); /** * Looks up and returns a pointer to a sequence of unicode characters * which was added to the table using createExtendedChar(). @@ -206,24 +200,24 @@ class ExtendedCharTable * * @return A unicode character sequence of size @p length. */ - ushort* lookupExtendedChar(ushort hash , ushort& length) const; + ushort *lookupExtendedChar(ushort hash, ushort &length) const; /** The global ExtendedCharTable instance. */ static ExtendedCharTable instance; + private: // calculates the hash key of a sequence of unicode points of size 'length' - ushort extendedCharHash(ushort* unicodePoints , ushort length) const; + ushort extendedCharHash(ushort *unicodePoints, ushort length) const; // tests whether the entry in the table specified by 'hash' matches the // character sequence 'unicodePoints' of size 'length' - bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const; + bool extendedCharMatch(ushort hash, ushort *unicodePoints, ushort length) const; // internal, maps hash keys to character sequence buffers. The first ushort // in each value is the length of the buffer, followed by the ushorts in the buffer // themselves. - QHash extendedCharTable; + QHash extendedCharTable; }; } Q_DECLARE_TYPEINFO(Konsole::Character, Q_MOVABLE_TYPE); #endif // CHARACTER_H - diff --git a/lib/CharacterColor.h b/lib/CharacterColor.h index 7ad8f5d5..4f58f75e 100644 --- a/lib/CharacterColor.h +++ b/lib/CharacterColor.h @@ -29,8 +29,7 @@ //#include #define KDE_NO_EXPORT -namespace Konsole -{ +namespace Konsole { /** * An entry in a terminal display's color palette. @@ -48,65 +47,65 @@ namespace Konsole class ColorEntry { public: - /** Specifies the weight to use when drawing text with this color. */ - enum FontWeight - { - /** Always draw text in this color with a bold weight. */ - Bold, - /** Always draw text in this color with a normal weight. */ - Normal, + /** Specifies the weight to use when drawing text with this color. */ + enum FontWeight { + /** Always draw text in this color with a bold weight. */ + Bold, + /** Always draw text in this color with a normal weight. */ + Normal, + /** + * Use the current font weight set by the terminal application. + * This is the default behavior. + */ + UseCurrentFormat + }; + /** - * Use the current font weight set by the terminal application. - * This is the default behavior. + * Constructs a new color palette entry. + * + * @param c The color value for this entry. + * @param tr Specifies that the color should be transparent when used as a background color. + * @param weight Specifies the font weight to use when drawing text with this color. */ - UseCurrentFormat - }; - - /** - * Constructs a new color palette entry. - * - * @param c The color value for this entry. - * @param tr Specifies that the color should be transparent when used as a background color. - * @param weight Specifies the font weight to use when drawing text with this color. - */ - ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat) - : color(c), transparent(tr), fontWeight(weight) {} - - /** - * Constructs a new color palette entry with an undefined color, and - * with the transparent and bold flags set to false. - */ - ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) {} - - /** The color value of this entry for display. */ - QColor color; - - /** - * If true character backgrounds using this color should be transparent. - * This is not applicable when the color is used to render text. - */ - bool transparent; - /** - * Specifies the font weight to use when drawing text with this color. - * This is not applicable when the color is used to draw a character's background. - */ - FontWeight fontWeight; -}; + ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat) + : color(c), transparent(tr), fontWeight(weight) + { + } + /** + * Constructs a new color palette entry with an undefined color, and + * with the transparent and bold flags set to false. + */ + ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) { } + + /** The color value of this entry for display. */ + QColor color; + + /** + * If true character backgrounds using this color should be transparent. + * This is not applicable when the color is used to render text. + */ + bool transparent; + /** + * Specifies the font weight to use when drawing text with this color. + * This is not applicable when the color is used to draw a character's background. + */ + FontWeight fontWeight; +}; // Attributed Character Representations /////////////////////////////// // Colors -#define BASE_COLORS (2+8) -#define INTENSITIES 2 -#define TABLE_COLORS (INTENSITIES*BASE_COLORS) +#define BASE_COLORS (2 + 8) +#define INTENSITIES 2 +#define TABLE_COLORS (INTENSITIES * BASE_COLORS) #define DEFAULT_FORE_COLOR 0 #define DEFAULT_BACK_COLOR 1 -//a standard set of colors using black text on a white background. -//defined in TerminalDisplay.cpp +// a standard set of colors using black text on a white background. +// defined in TerminalDisplay.cpp extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT; @@ -126,11 +125,11 @@ extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT; default foreground and default background colour. */ -#define COLOR_SPACE_UNDEFINED 0 -#define COLOR_SPACE_DEFAULT 1 -#define COLOR_SPACE_SYSTEM 2 -#define COLOR_SPACE_256 3 -#define COLOR_SPACE_RGB 4 +#define COLOR_SPACE_UNDEFINED 0 +#define COLOR_SPACE_DEFAULT 1 +#define COLOR_SPACE_SYSTEM 2 +#define COLOR_SPACE_256 3 +#define COLOR_SPACE_RGB 4 /** * Describes the color of a single character in the terminal. @@ -140,32 +139,22 @@ class CharacterColor friend class Character; public: - /** Constructs a new CharacterColor whoose color and color space are undefined. */ - CharacterColor() - : _colorSpace(COLOR_SPACE_UNDEFINED), - _u(0), - _v(0), - _w(0) - {} - - /** - * Constructs a new CharacterColor using the specified @p colorSpace and with - * color value @p co - * - * The meaning of @p co depends on the @p colorSpace used. - * - * TODO : Document how @p co relates to @p colorSpace - * - * TODO : Add documentation about available color spaces. - */ - CharacterColor(quint8 colorSpace, int co) - : _colorSpace(colorSpace), - _u(0), - _v(0), - _w(0) - { - switch (colorSpace) + /** Constructs a new CharacterColor whoose color and color space are undefined. */ + CharacterColor() : _colorSpace(COLOR_SPACE_UNDEFINED), _u(0), _v(0), _w(0) { } + + /** + * Constructs a new CharacterColor using the specified @p colorSpace and with + * color value @p co + * + * The meaning of @p co depends on the @p colorSpace used. + * + * TODO : Document how @p co relates to @p colorSpace + * + * TODO : Add documentation about available color spaces. + */ + CharacterColor(quint8 colorSpace, int co) : _colorSpace(colorSpace), _u(0), _v(0), _w(0) { + switch (colorSpace) { case COLOR_SPACE_DEFAULT: _u = co & 1; break; @@ -183,110 +172,109 @@ class CharacterColor break; default: _colorSpace = COLOR_SPACE_UNDEFINED; + } } - } - - /** - * Returns true if this character color entry is valid. - */ - bool isValid() const - { - return _colorSpace != COLOR_SPACE_UNDEFINED; - } - - /** - * Set the value of this color from a normal system color to the corresponding intensive - * system color if it's not already an intensive system color. - * - * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM - * color spaces. - */ - void setIntensive(); - - /** - * Returns the color within the specified color @p palette - * - * The @p palette is only used if this color is one of the 16 system colors, otherwise - * it is ignored. - */ - QColor color(const ColorEntry* palette) const; - - /** - * Compares two colors and returns true if they represent the same color value and - * use the same color space. - */ - friend bool operator == (const CharacterColor& a, const CharacterColor& b); - /** - * Compares two colors and returns true if they represent different color values - * or use different color spaces. - */ - friend bool operator != (const CharacterColor& a, const CharacterColor& b); + + /** + * Returns true if this character color entry is valid. + */ + bool isValid() const { return _colorSpace != COLOR_SPACE_UNDEFINED; } + + /** + * Set the value of this color from a normal system color to the corresponding intensive + * system color if it's not already an intensive system color. + * + * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM + * color spaces. + */ + void setIntensive(); + + /** + * Returns the color within the specified color @p palette + * + * The @p palette is only used if this color is one of the 16 system colors, otherwise + * it is ignored. + */ + QColor color(const ColorEntry *palette) const; + + /** + * Compares two colors and returns true if they represent the same color value and + * use the same color space. + */ + friend bool operator==(const CharacterColor &a, const CharacterColor &b); + /** + * Compares two colors and returns true if they represent different color values + * or use different color spaces. + */ + friend bool operator!=(const CharacterColor &a, const CharacterColor &b); private: - quint8 _colorSpace; + quint8 _colorSpace; - // bytes storing the character color - quint8 _u; - quint8 _v; - quint8 _w; + // bytes storing the character color + quint8 _u; + quint8 _v; + quint8 _w; }; -inline bool operator == (const CharacterColor& a, const CharacterColor& b) +inline bool operator==(const CharacterColor &a, const CharacterColor &b) { - return a._colorSpace == b._colorSpace && - a._u == b._u && - a._v == b._v && - a._w == b._w; + return a._colorSpace == b._colorSpace && a._u == b._u && a._v == b._v && a._w == b._w; } -inline bool operator != (const CharacterColor& a, const CharacterColor& b) +inline bool operator!=(const CharacterColor &a, const CharacterColor &b) { - return !operator==(a,b); + return !operator==(a, b); } -inline const QColor color256(quint8 u, const ColorEntry* base) +inline const QColor color256(quint8 u, const ColorEntry *base) { - // 0.. 16: system colors - if (u < 8) return base[u+2 ].color; - u -= 8; - if (u < 8) return base[u+2+BASE_COLORS].color; - u -= 8; - - // 16..231: 6x6x6 rgb color cube - if (u < 216) return QColor(((u/36)%6) ? (40*((u/36)%6)+55) : 0, - ((u/ 6)%6) ? (40*((u/ 6)%6)+55) : 0, - ((u/ 1)%6) ? (40*((u/ 1)%6)+55) : 0); - u -= 216; - - // 232..255: gray, leaving out black and white - int gray = u*10+8; return QColor(gray,gray,gray); + // 0.. 16: system colors + if (u < 8) + return base[u + 2].color; + u -= 8; + if (u < 8) + return base[u + 2 + BASE_COLORS].color; + u -= 8; + + // 16..231: 6x6x6 rgb color cube + if (u < 216) + return QColor(((u / 36) % 6) ? (40 * ((u / 36) % 6) + 55) : 0, + ((u / 6) % 6) ? (40 * ((u / 6) % 6) + 55) : 0, + ((u / 1) % 6) ? (40 * ((u / 1) % 6) + 55) : 0); + u -= 216; + + // 232..255: gray, leaving out black and white + int gray = u * 10 + 8; + return QColor(gray, gray, gray); } -inline QColor CharacterColor::color(const ColorEntry* base) const +inline QColor CharacterColor::color(const ColorEntry *base) const { - switch (_colorSpace) - { - case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color; - case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color; - case COLOR_SPACE_256: return color256(_u,base); - case COLOR_SPACE_RGB: return {_u,_v,_w}; - case COLOR_SPACE_UNDEFINED: return QColor(); - } - - Q_ASSERT(false); // invalid color space - - return QColor(); + switch (_colorSpace) { + case COLOR_SPACE_DEFAULT: + return base[_u + 0 + (_v ? BASE_COLORS : 0)].color; + case COLOR_SPACE_SYSTEM: + return base[_u + 2 + (_v ? BASE_COLORS : 0)].color; + case COLOR_SPACE_256: + return color256(_u, base); + case COLOR_SPACE_RGB: + return { _u, _v, _w }; + case COLOR_SPACE_UNDEFINED: + return QColor(); + } + + Q_ASSERT(false); // invalid color space + + return QColor(); } inline void CharacterColor::setIntensive() { - if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) - { - _v = 1; - } + if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) { + _v = 1; + } } - } #endif // CHARACTERCOLOR_H - diff --git a/lib/ColorScheme.cpp b/lib/ColorScheme.cpp index 12ce19fd..32cc9c61 100644 --- a/lib/ColorScheme.cpp +++ b/lib/ColorScheme.cpp @@ -33,7 +33,6 @@ #include #include - // KDE //#include //#include @@ -45,60 +44,50 @@ using namespace Konsole; const ColorEntry ColorScheme::defaultTable[TABLE_COLORS] = - // The following are almost IBM standard color codes, with some slight - // gamma correction for the dim colors to compensate for bright X screens. - // It contains the 8 ansiterm/xterm colors in 2 intensities. -{ - ColorEntry( QColor(0x00,0x00,0x00), false), ColorEntry( -QColor(0xFF,0xFF,0xFF), true), // Dfore, Dback - ColorEntry( QColor(0x00,0x00,0x00), false), ColorEntry( -QColor(0xB2,0x18,0x18), false), // Black, Red - ColorEntry( QColor(0x18,0xB2,0x18), false), ColorEntry( -QColor(0xB2,0x68,0x18), false), // Green, Yellow - ColorEntry( QColor(0x18,0x18,0xB2), false), ColorEntry( -QColor(0xB2,0x18,0xB2), false), // Blue, Magenta - ColorEntry( QColor(0x18,0xB2,0xB2), false), ColorEntry( -QColor(0xB2,0xB2,0xB2), false), // Cyan, White - // intensive - ColorEntry( QColor(0x00,0x00,0x00), false), ColorEntry( -QColor(0xFF,0xFF,0xFF), true), - ColorEntry( QColor(0x68,0x68,0x68), false), ColorEntry( -QColor(0xFF,0x54,0x54), false), - ColorEntry( QColor(0x54,0xFF,0x54), false), ColorEntry( -QColor(0xFF,0xFF,0x54), false), - ColorEntry( QColor(0x54,0x54,0xFF), false), ColorEntry( -QColor(0xFF,0x54,0xFF), false), - ColorEntry( QColor(0x54,0xFF,0xFF), false), ColorEntry( -QColor(0xFF,0xFF,0xFF), false) -}; - -const char* const ColorScheme::colorNames[TABLE_COLORS] = -{ - "Foreground", - "Background", - "Color0", - "Color1", - "Color2", - "Color3", - "Color4", - "Color5", - "Color6", - "Color7", - "ForegroundIntense", - "BackgroundIntense", - "Color0Intense", - "Color1Intense", - "Color2Intense", - "Color3Intense", - "Color4Intense", - "Color5Intense", - "Color6Intense", - "Color7Intense" -}; + // The following are almost IBM standard color codes, with some slight + // gamma correction for the dim colors to compensate for bright X screens. + // It contains the 8 ansiterm/xterm colors in 2 intensities. + { ColorEntry(QColor(0x00, 0x00, 0x00), false), + ColorEntry(QColor(0xFF, 0xFF, 0xFF), true), // Dfore, Dback + ColorEntry(QColor(0x00, 0x00, 0x00), false), + ColorEntry(QColor(0xB2, 0x18, 0x18), false), // Black, Red + ColorEntry(QColor(0x18, 0xB2, 0x18), false), + ColorEntry(QColor(0xB2, 0x68, 0x18), false), // Green, Yellow + ColorEntry(QColor(0x18, 0x18, 0xB2), false), + ColorEntry(QColor(0xB2, 0x18, 0xB2), false), // Blue, Magenta + ColorEntry(QColor(0x18, 0xB2, 0xB2), false), + ColorEntry(QColor(0xB2, 0xB2, 0xB2), false), // Cyan, White + // intensive + ColorEntry(QColor(0x00, 0x00, 0x00), false), ColorEntry(QColor(0xFF, 0xFF, 0xFF), true), + ColorEntry(QColor(0x68, 0x68, 0x68), false), ColorEntry(QColor(0xFF, 0x54, 0x54), false), + ColorEntry(QColor(0x54, 0xFF, 0x54), false), ColorEntry(QColor(0xFF, 0xFF, 0x54), false), + ColorEntry(QColor(0x54, 0x54, 0xFF), false), ColorEntry(QColor(0xFF, 0x54, 0xFF), false), + ColorEntry(QColor(0x54, 0xFF, 0xFF), false), + ColorEntry(QColor(0xFF, 0xFF, 0xFF), false) }; + +const char *const ColorScheme::colorNames[TABLE_COLORS] = { "Foreground", + "Background", + "Color0", + "Color1", + "Color2", + "Color3", + "Color4", + "Color5", + "Color6", + "Color7", + "ForegroundIntense", + "BackgroundIntense", + "Color0Intense", + "Color1Intense", + "Color2Intense", + "Color3Intense", + "Color4Intense", + "Color5Intense", + "Color6Intense", + "Color7Intense" }; // dummy silently comment out the tr_NOOP #define tr_NOOP -const char* const ColorScheme::translatedColorNames[TABLE_COLORS] = -{ +const char *const ColorScheme::translatedColorNames[TABLE_COLORS] = { tr_NOOP("Foreground"), tr_NOOP("Background"), tr_NOOP("Color 1"), @@ -127,26 +116,21 @@ ColorScheme::ColorScheme() _randomTable = nullptr; _opacity = 1.0; } -ColorScheme::ColorScheme(const ColorScheme& other) - : _opacity(other._opacity) - ,_table(nullptr) - ,_randomTable(nullptr) +ColorScheme::ColorScheme(const ColorScheme &other) + : _opacity(other._opacity), _table(nullptr), _randomTable(nullptr) { setName(other.name()); setDescription(other.description()); - if ( other._table != nullptr ) - { - for ( int i = 0 ; i < TABLE_COLORS ; i++ ) - setColorTableEntry(i,other._table[i]); + if (other._table != nullptr) { + for (int i = 0; i < TABLE_COLORS; i++) + setColorTableEntry(i, other._table[i]); } - if ( other._randomTable != nullptr ) - { - for ( int i = 0 ; i < TABLE_COLORS ; i++ ) - { - const RandomizationRange& range = other._randomTable[i]; - setRandomizationRange(i,range.hue,range.saturation,range.value); + if (other._randomTable != nullptr) { + for (int i = 0; i < TABLE_COLORS; i++) { + const RandomizationRange &range = other._randomTable[i]; + setRandomizationRange(i, range.hue, range.saturation, range.value); } } } @@ -156,21 +140,32 @@ ColorScheme::~ColorScheme() delete[] _randomTable; } -void ColorScheme::setDescription(const QString& description) { _description = description; } -QString ColorScheme::description() const { return _description; } +void ColorScheme::setDescription(const QString &description) +{ + _description = description; +} +QString ColorScheme::description() const +{ + return _description; +} -void ColorScheme::setName(const QString& name) { _name = name; } -QString ColorScheme::name() const { return _name; } +void ColorScheme::setName(const QString &name) +{ + _name = name; +} +QString ColorScheme::name() const +{ + return _name; +} -void ColorScheme::setColorTableEntry(int index , const ColorEntry& entry) +void ColorScheme::setColorTableEntry(int index, const ColorEntry &entry) { - Q_ASSERT( index >= 0 && index < TABLE_COLORS ); + Q_ASSERT(index >= 0 && index < TABLE_COLORS); - if ( !_table ) - { + if (!_table) { _table = new ColorEntry[TABLE_COLORS]; - for (int i=0;i= 0 && index < TABLE_COLORS ); + Q_ASSERT(index >= 0 && index < TABLE_COLORS); ColorEntry entry = colorTable()[index]; - if ( _randomTable != nullptr && - !_randomTable[index].isNull() ) - { - const RandomizationRange& range = _randomTable[index]; + if (_randomTable != nullptr && !_randomTable[index].isNull()) { + const RandomizationRange &range = _randomTable[index]; + int hueDifference = + range.hue ? QRandomGenerator::global()->bounded(range.hue) - range.hue / 2 : 0; + int saturationDifference = range.saturation + ? QRandomGenerator::global()->bounded(range.saturation) - range.saturation / 2 + : 0; + int valueDifference = range.value + ? QRandomGenerator::global()->bounded(range.value) - range.value / 2 + : 0; - int hueDifference = range.hue ? QRandomGenerator::global()->bounded(range.hue) - range.hue/2 : 0; - int saturationDifference = range.saturation ? QRandomGenerator::global()->bounded(range.saturation) - range.saturation/2 : 0; - int valueDifference = range.value ? QRandomGenerator::global()->bounded(range.value) - range.value/2 : 0; + QColor &color = entry.color; - QColor& color = entry.color; + int newHue = qAbs((color.hue() + hueDifference) % MAX_HUE); + int newValue = qMin(qAbs(color.value() + valueDifference), 255); + int newSaturation = qMin(qAbs(color.saturation() + saturationDifference), 255); - int newHue = qAbs( (color.hue() + hueDifference) % MAX_HUE ); - int newValue = qMin( qAbs(color.value() + valueDifference) , 255 ); - int newSaturation = qMin( qAbs(color.saturation() + saturationDifference) , 255 ); - - color.setHsv(newHue,newSaturation,newValue); + color.setHsv(newHue, newSaturation, newValue); } return entry; } -void ColorScheme::getColorTable(ColorEntry* table) const +void ColorScheme::getColorTable(ColorEntry *table) const { - for ( int i = 0 ; i < TABLE_COLORS ; i++ ) + for (int i = 0; i < TABLE_COLORS; i++) table[i] = colorEntry(i); } bool ColorScheme::randomizedBackgroundColor() const @@ -218,24 +215,20 @@ void ColorScheme::setRandomizedBackgroundColor(bool randomize) // adjusted as much as possible. // // the value and saturation are left alone to maintain read-ability - if ( randomize ) - { - setRandomizationRange( 1 /* background color index */ , MAX_HUE , 255 , 0 ); - } - else - { - if ( _randomTable ) - setRandomizationRange( 1 /* background color index */ , 0 , 0 , 0 ); + if (randomize) { + setRandomizationRange(1 /* background color index */, MAX_HUE, 255, 0); + } else { + if (_randomTable) + setRandomizationRange(1 /* background color index */, 0, 0, 0); } } -void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 saturation , - quint8 value ) +void ColorScheme::setRandomizationRange(int index, quint16 hue, quint8 saturation, quint8 value) { - Q_ASSERT( hue <= MAX_HUE ); - Q_ASSERT( index >= 0 && index < TABLE_COLORS ); + Q_ASSERT(hue <= MAX_HUE); + Q_ASSERT(index >= 0 && index < TABLE_COLORS); - if ( _randomTable == nullptr ) + if (_randomTable == nullptr) _randomTable = new RandomizationRange[TABLE_COLORS]; _randomTable[index].hue = hue; @@ -243,9 +236,9 @@ void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 satura _randomTable[index].saturation = saturation; } -const ColorEntry* ColorScheme::colorTable() const +const ColorEntry *ColorScheme::colorTable() const { - if ( _table ) + if (_table) return _table; else return defaultTable; @@ -264,20 +257,26 @@ bool ColorScheme::hasDarkBackground() const // so 127 is in the middle, anything less is deemed 'dark' return backgroundColor().value() < 127; } -void ColorScheme::setOpacity(qreal opacity) { _opacity = opacity; } -qreal ColorScheme::opacity() const { return _opacity; } +void ColorScheme::setOpacity(qreal opacity) +{ + _opacity = opacity; +} +qreal ColorScheme::opacity() const +{ + return _opacity; +} -void ColorScheme::read(const QString & fileName) +void ColorScheme::read(const QString &fileName) { QSettings s(fileName, QSettings::IniFormat); s.beginGroup(QLatin1String("General")); - _description = s.value(QLatin1String("Description"), QObject::tr("Un-named Color Scheme")).toString(); - _opacity = s.value(QLatin1String("Opacity"),qreal(1.0)).toDouble(); + _description = + s.value(QLatin1String("Description"), QObject::tr("Un-named Color Scheme")).toString(); + _opacity = s.value(QLatin1String("Opacity"), qreal(1.0)).toDouble(); s.endGroup(); - for (int i=0 ; i < TABLE_COLORS ; i++) - { + for (int i = 0; i < TABLE_COLORS; i++) { readColorEntry(&s, i); } } @@ -314,18 +313,18 @@ void ColorScheme::write(KConfig& config) const QString ColorScheme::colorNameForIndex(int index) { - Q_ASSERT( index >= 0 && index < TABLE_COLORS ); + Q_ASSERT(index >= 0 && index < TABLE_COLORS); return QString::fromLatin1(colorNames[index]); } QString ColorScheme::translatedColorNameForIndex(int index) { - Q_ASSERT( index >= 0 && index < TABLE_COLORS ); + Q_ASSERT(index >= 0 && index < TABLE_COLORS); return QString::fromLatin1(translatedColorNames[index]); } -void ColorScheme::readColorEntry(QSettings * s , int index) +void ColorScheme::readColorEntry(QSettings *s, int index) { QString colorName = colorNameForIndex(index); @@ -339,12 +338,10 @@ void ColorScheme::readColorEntry(QSettings * s , int index) bool ok = false; // XXX: Undocumented(?) QSettings behavior: values with commas are parsed // as QStringList and others QString - if (colorValue.type() == QVariant::StringList) - { + if (colorValue.type() == QVariant::StringList) { QStringList rgbList = colorValue.toStringList(); colorStr = rgbList.join(QLatin1Char(',')); - if (rgbList.count() == 3) - { + if (rgbList.count() == 3) { bool parse_ok; ok = true; @@ -355,14 +352,11 @@ void ColorScheme::readColorEntry(QSettings * s , int index) b = rgbList[2].toInt(&parse_ok); ok = ok && parse_ok && (b >= 0 && b <= 0xff); } - } - else - { + } else { colorStr = colorValue.toString(); QRegularExpression hexColorPattern(QLatin1String("^#[0-9a-f]{6}$"), QRegularExpression::CaseInsensitiveOption); - if (hexColorPattern.match(colorStr).hasMatch()) - { + if (hexColorPattern.match(colorStr).hasMatch()) { // Parsing is always ok as already matched by the regexp r = colorStr.midRef(1, 2).toInt(nullptr, 16); g = colorStr.midRef(3, 2).toInt(nullptr, 16); @@ -370,15 +364,14 @@ void ColorScheme::readColorEntry(QSettings * s , int index) ok = true; } } - if (!ok) - { - qWarning().nospace() << "Invalid color value " << colorStr - << " for " << colorName << ". Fallback to black."; + if (!ok) { + qWarning().nospace() << "Invalid color value " << colorStr << " for " << colorName + << ". Fallback to black."; r = g = b = 0; } entry.color = QColor(r, g, b); - entry.transparent = s->value(QLatin1String("Transparent"),false).toBool(); + entry.transparent = s->value(QLatin1String("Transparent"), false).toBool(); // Deprecated key from KDE 4.0 which set 'Bold' to true to force // a color to be bold or false to use the current format @@ -386,17 +379,18 @@ void ColorScheme::readColorEntry(QSettings * s , int index) // TODO - Add a new tri-state key which allows for bold, normal or // current format if (s->contains(QLatin1String("Bold"))) - entry.fontWeight = s->value(QLatin1String("Bold"),false).toBool() ? ColorEntry::Bold : - ColorEntry::UseCurrentFormat; + entry.fontWeight = s->value(QLatin1String("Bold"), false).toBool() + ? ColorEntry::Bold + : ColorEntry::UseCurrentFormat; - quint16 hue = s->value(QLatin1String("MaxRandomHue"),0).toInt(); - quint8 value = s->value(QLatin1String("MaxRandomValue"),0).toInt(); - quint8 saturation = s->value(QLatin1String("MaxRandomSaturation"),0).toInt(); + quint16 hue = s->value(QLatin1String("MaxRandomHue"), 0).toInt(); + quint8 value = s->value(QLatin1String("MaxRandomValue"), 0).toInt(); + quint8 saturation = s->value(QLatin1String("MaxRandomSaturation"), 0).toInt(); - setColorTableEntry( index , entry ); + setColorTableEntry(index, entry); - if ( hue != 0 || value != 0 || saturation != 0 ) - setRandomizationRange( index , hue , saturation , value ); + if (hue != 0 || value != 0 || saturation != 0) + setRandomizationRange(index, hue, saturation, value); s->endGroup(); } @@ -451,8 +445,7 @@ void ColorScheme::writeColorEntry(KConfig& config , const QString& colorName, co // // -- Robert Knight 21/07/2007 // -AccessibleColorScheme::AccessibleColorScheme() - : ColorScheme() +AccessibleColorScheme::AccessibleColorScheme() : ColorScheme() { #if 0 // It's not finished in konsole and it breaks Qt4 compilation as well @@ -488,29 +481,24 @@ AccessibleColorScheme::AccessibleColorScheme() #endif } -ColorSchemeManager::ColorSchemeManager() - : _haveLoadedAll(false) -{ -} +ColorSchemeManager::ColorSchemeManager() : _haveLoadedAll(false) { } ColorSchemeManager::~ColorSchemeManager() { - QHashIterator iter(_colorSchemes); - while (iter.hasNext()) - { + QHashIterator iter(_colorSchemes); + while (iter.hasNext()) { iter.next(); delete iter.value(); } } void ColorSchemeManager::loadAllColorSchemes() { - //qDebug() << "loadAllColorSchemes"; + // qDebug() << "loadAllColorSchemes"; int failed = 0; QList nativeColorSchemes = listColorSchemes(); QListIterator nativeIter(nativeColorSchemes); - while ( nativeIter.hasNext() ) - { - if ( !loadColorScheme( nativeIter.next() ) ) + while (nativeIter.hasNext()) { + if (!loadColorScheme(nativeIter.next())) failed++; } @@ -519,10 +507,9 @@ void ColorSchemeManager::loadAllColorSchemes() _haveLoadedAll = true; } -QList ColorSchemeManager::allColorSchemes() +QList ColorSchemeManager::allColorSchemes() { - if ( !_haveLoadedAll ) - { + if (!_haveLoadedAll) { loadAllColorSchemes(); } @@ -541,7 +528,7 @@ void ColorSchemeManager::addColorScheme(ColorScheme* scheme) } #endif -bool ColorSchemeManager::loadCustomColorScheme(const QString& path) +bool ColorSchemeManager::loadCustomColorScheme(const QString &path) { if (path.endsWith(QLatin1String(".colorscheme"))) return loadColorScheme(path); @@ -549,37 +536,34 @@ bool ColorSchemeManager::loadCustomColorScheme(const QString& path) return false; } -void ColorSchemeManager::addCustomColorSchemeDir(const QString& custom_dir) +void ColorSchemeManager::addCustomColorSchemeDir(const QString &custom_dir) { add_custom_color_scheme_dir(custom_dir); } -bool ColorSchemeManager::loadColorScheme(const QString& filePath) +bool ColorSchemeManager::loadColorScheme(const QString &filePath) { - if ( !filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath) ) + if (!filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath)) return false; QFileInfo info(filePath); - const QString& schemeName = info.baseName(); + const QString &schemeName = info.baseName(); - ColorScheme* scheme = new ColorScheme(); + ColorScheme *scheme = new ColorScheme(); scheme->setName(schemeName); scheme->read(filePath); - if (scheme->name().isEmpty()) - { - //qDebug() << "Color scheme in" << filePath << "does not have a valid name and was not loaded."; + if (scheme->name().isEmpty()) { + // qDebug() << "Color scheme in" << filePath << "does not have a valid name and was not + // loaded."; delete scheme; return false; } - if ( !_colorSchemes.contains(schemeName) ) - { - _colorSchemes.insert(schemeName,scheme); - } - else - { + if (!_colorSchemes.contains(schemeName)) { + _colorSchemes.insert(schemeName, scheme); + } else { /*qDebug() << "color scheme with name" << schemeName << "has already been" << "found, ignoring.";*/ @@ -591,8 +575,7 @@ bool ColorSchemeManager::loadColorScheme(const QString& filePath) QList ColorSchemeManager::listColorSchemes() { QList ret; - for (const QString &scheme_dir : get_color_schemes_dirs()) - { + for (const QString &scheme_dir : get_color_schemes_dirs()) { const QString dname(scheme_dir); QDir dir(dname); QStringList filters; @@ -603,72 +586,67 @@ QList ColorSchemeManager::listColorSchemes() ret << dname + QLatin1Char('/') + i; } return ret; -// return KGlobal::dirs()->findAllResources("data", -// "konsole/*.colorscheme", -// KStandardDirs::NoDuplicates); + // return KGlobal::dirs()->findAllResources("data", + // "konsole/*.colorscheme", + // KStandardDirs::NoDuplicates); } const ColorScheme ColorSchemeManager::_defaultColorScheme; -const ColorScheme* ColorSchemeManager::defaultColorScheme() const +const ColorScheme *ColorSchemeManager::defaultColorScheme() const { return &_defaultColorScheme; } -bool ColorSchemeManager::deleteColorScheme(const QString& name) +bool ColorSchemeManager::deleteColorScheme(const QString &name) { - Q_ASSERT( _colorSchemes.contains(name) ); + Q_ASSERT(_colorSchemes.contains(name)); // lookup the path and delete QString path = findColorSchemePath(name); - if ( QFile::remove(path) ) - { + if (QFile::remove(path)) { _colorSchemes.remove(name); return true; - } - else - { - //qDebug() << "Failed to remove color scheme -" << path; + } else { + // qDebug() << "Failed to remove color scheme -" << path; return false; } } -QString ColorSchemeManager::findColorSchemePath(const QString& name) const +QString ColorSchemeManager::findColorSchemePath(const QString &name) const { -// QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme"); + // QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme"); const QStringList dirs = get_color_schemes_dirs(); - if ( dirs.isEmpty() ) + if (dirs.isEmpty()) return QString(); const QString dir = dirs.first(); - QString path(dir + QLatin1Char('/')+ name + QLatin1String(".colorscheme")); - if ( !path.isEmpty() ) + QString path(dir + QLatin1Char('/') + name + QLatin1String(".colorscheme")); + if (!path.isEmpty()) return path; - //path = KStandardDirs::locate("data","konsole/"+name+".schema"); - path = dir + QLatin1Char('/')+ name + QLatin1String(".schema"); + // path = KStandardDirs::locate("data","konsole/"+name+".schema"); + path = dir + QLatin1Char('/') + name + QLatin1String(".schema"); return path; } -const ColorScheme* ColorSchemeManager::findColorScheme(const QString& name) +const ColorScheme *ColorSchemeManager::findColorScheme(const QString &name) { - if ( name.isEmpty() ) + if (name.isEmpty()) return defaultColorScheme(); - if ( _colorSchemes.contains(name) ) + if (_colorSchemes.contains(name)) return _colorSchemes[name]; - else - { + else { // look for this color scheme QString path = findColorSchemePath(name); - if ( !path.isEmpty() && loadColorScheme(path) ) - { + if (!path.isEmpty() && loadColorScheme(path)) { return findColorScheme(name); } - //qDebug() << "Could not find color scheme - " << name; + // qDebug() << "Could not find color scheme - " << name; return nullptr; } } Q_GLOBAL_STATIC(ColorSchemeManager, theColorSchemeManager) -ColorSchemeManager* ColorSchemeManager::instance() +ColorSchemeManager *ColorSchemeManager::instance() { return theColorSchemeManager; } diff --git a/lib/ColorScheme.h b/lib/ColorScheme.h index 15ceb4d6..86583e66 100644 --- a/lib/ColorScheme.h +++ b/lib/ColorScheme.h @@ -34,10 +34,9 @@ #include "CharacterColor.h" class QIODevice; -//class KConfig; +// class KConfig; -namespace Konsole -{ +namespace Konsole { /** * Represents a color scheme for a terminal display. @@ -53,16 +52,16 @@ class ColorScheme * for Konsole. */ ColorScheme(); - ColorScheme(const ColorScheme& other); + ColorScheme(const ColorScheme &other); ~ColorScheme(); /** Sets the descriptive name of the color scheme. */ - void setDescription(const QString& description); + void setDescription(const QString &description); /** Returns the descriptive name of the color scheme. */ QString description() const; /** Sets the name of the color scheme */ - void setName(const QString& name); + void setName(const QString &name); /** Returns the name of the color scheme */ QString name() const; @@ -73,10 +72,10 @@ class ColorScheme /** Writes the color scheme to the specified configuration source */ void write(KConfig& config) const; #endif - void read(const QString & filename); + void read(const QString &filename); /** Sets a single entry within the color palette. */ - void setColorTableEntry(int index , const ColorEntry& entry); + void setColorTableEntry(int index, const ColorEntry &entry); /** * Copies the color entries which form the palette for this color scheme @@ -87,7 +86,7 @@ class ColorScheme * @param randomSeed Color schemes may allow certain colors in their * palette to be randomized. The seed is used to pick the random color. */ - void getColorTable(ColorEntry* table) const; + void getColorTable(ColorEntry *table) const; /** * Retrieves a single color entry from the table. @@ -152,21 +151,18 @@ class ColorScheme class RandomizationRange { public: - RandomizationRange() : hue(0) , saturation(0) , value(0) {} + RandomizationRange() : hue(0), saturation(0), value(0) { } - bool isNull() const - { - return ( hue == 0 && saturation == 0 && value == 0 ); - } + bool isNull() const { return (hue == 0 && saturation == 0 && value == 0); } quint16 hue; - quint8 saturation; - quint8 value; + quint8 saturation; + quint8 value; }; // returns the active color table. if none has been set specifically, // this is the default color table. - const ColorEntry* colorTable() const; + const ColorEntry *colorTable() const; #if 0 // implemented upstream - user apps @@ -181,23 +177,22 @@ class ColorScheme // sets the amount of randomization allowed for a particular color // in the palette. creates the randomization table if // it does not already exist - void setRandomizationRange( int index , quint16 hue , quint8 saturation , quint8 value ); + void setRandomizationRange(int index, quint16 hue, quint8 saturation, quint8 value); QString _description; QString _name; qreal _opacity; - ColorEntry* _table; // pointer to custom color table or 0 if the default + ColorEntry *_table; // pointer to custom color table or 0 if the default // color scheme is being used - static const quint16 MAX_HUE = 340; - RandomizationRange* _randomTable; // pointer to randomization table or 0 - // if no colors in the color scheme support - // randomization + RandomizationRange *_randomTable; // pointer to randomization table or 0 + // if no colors in the color scheme support + // randomization - static const char* const colorNames[TABLE_COLORS]; - static const char* const translatedColorNames[TABLE_COLORS]; + static const char *const colorNames[TABLE_COLORS]; + static const char *const translatedColorNames[TABLE_COLORS]; static const ColorEntry defaultTable[]; // table of default color entries }; @@ -224,7 +219,6 @@ class AccessibleColorScheme : public ColorScheme class ColorSchemeManager { public: - /** * Constructs a new ColorSchemeManager and loads the list * of available color schemes. @@ -241,7 +235,7 @@ class ColorSchemeManager /** * Returns the default color scheme for Konsole */ - const ColorScheme* defaultColorScheme() const; + const ColorScheme *defaultColorScheme() const; /** * Returns the color scheme with the given name or 0 if no @@ -251,7 +245,7 @@ class ColorSchemeManager * The first time that a color scheme with a particular name is * requested, the configuration information is loaded from disk. */ - const ColorScheme* findColorScheme(const QString& name); + const ColorScheme *findColorScheme(const QString &name); #if 0 /** @@ -265,7 +259,7 @@ class ColorSchemeManager /** * Deletes a color scheme. Returns true on successful deletion or false otherwise. */ - bool deleteColorScheme(const QString& name); + bool deleteColorScheme(const QString &name); /** * Returns a list of the all the available color schemes. @@ -274,10 +268,10 @@ class ColorSchemeManager * * Subsequent calls will be inexpensive. */ - QList allColorSchemes(); + QList allColorSchemes(); /** Returns the global color scheme manager instance. */ - static ColorSchemeManager* instance(); + static ColorSchemeManager *instance(); /** @brief Loads a custom color scheme under given \em path. * @@ -291,27 +285,27 @@ class ColorSchemeManager * @param[in] path The path to KDE 4 .colorscheme or KDE 3 .schema. * @return Whether the color scheme is loaded successfully. */ - bool loadCustomColorScheme(const QString& path); + bool loadCustomColorScheme(const QString &path); /** * @brief Allows to add a custom location of color schemes. * * @param[in] custom_dir Custom location of color schemes (must end with /). */ - void addCustomColorSchemeDir(const QString& custom_dir); + void addCustomColorSchemeDir(const QString &custom_dir); private: // loads a color scheme from a KDE 4+ .colorscheme file - bool loadColorScheme(const QString& path); + bool loadColorScheme(const QString &path); // returns a list of paths of color schemes in the KDE 4+ .colorscheme file format QList listColorSchemes(); // loads all of the color schemes void loadAllColorSchemes(); // finds the path of a color scheme - QString findColorSchemePath(const QString& name) const; + QString findColorSchemePath(const QString &name) const; - QHash _colorSchemes; - QSet _modifiedSchemes; + QHash _colorSchemes; + QSet _modifiedSchemes; bool _haveLoadedAll; @@ -320,6 +314,6 @@ class ColorSchemeManager } -Q_DECLARE_METATYPE(const Konsole::ColorScheme*) +Q_DECLARE_METATYPE(const Konsole::ColorScheme *) -#endif //COLORSCHEME_H +#endif // COLORSCHEME_H diff --git a/lib/ColorTables.h b/lib/ColorTables.h index 57b0bd15..6b78cf16 100644 --- a/lib/ColorTables.h +++ b/lib/ColorTables.h @@ -3,7 +3,7 @@ #include "CharacterColor.h" -//using namespace Konsole; +// using namespace Konsole; #if 0 static const ColorEntry whiteonblack_color_table[TABLE_COLORS] = { // normal @@ -47,9 +47,6 @@ static const ColorEntry blackonlightyellow_color_table[TABLE_COLORS] = { ColorEntry(QColor( 84, 255, 255), false), ColorEntry(QColor( 255, 255, 255), false) }; - #endif - #endif - diff --git a/lib/DefaultTranslatorText.h b/lib/DefaultTranslatorText.h index e47417c5..a2337130 100644 --- a/lib/DefaultTranslatorText.h +++ b/lib/DefaultTranslatorText.h @@ -1,2 +1,2 @@ "keyboard \"Fallback Key Translator\"\n" -"key Tab : \"\\t\" \0" + "key Tab : \"\\t\" \0" diff --git a/lib/Emulation.cpp b/lib/Emulation.cpp index 001d15b0..996e8bbb 100644 --- a/lib/Emulation.cpp +++ b/lib/Emulation.cpp @@ -50,32 +50,34 @@ using namespace Konsole; -Emulation::Emulation() : - _currentScreen(nullptr), - _codec(nullptr), - _decoder(nullptr), - _keyTranslator(nullptr), - _usesMouse(false), - _bracketedPasteMode(false) -{ - // create screens with a default size - _screen[0] = new Screen(40,80); - _screen[1] = new Screen(40,80); - _currentScreen = _screen[0]; - - QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) ); - QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) ); - - // listen for mouse status changes - connect(this , SIGNAL(programUsesMouseChanged(bool)) , - SLOT(usesMouseChanged(bool))); - connect(this , SIGNAL(programBracketedPasteModeChanged(bool)) , - SLOT(bracketedPasteModeChanged(bool))); - - connect(this, &Emulation::cursorChanged, [this] (KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) { - emit titleChanged( 50, QString(QLatin1String("CursorShape=%1;BlinkingCursorEnabled=%2")) - .arg(static_cast(cursorShape)).arg(blinkingCursorEnabled) ); - }); +Emulation::Emulation() + : _currentScreen(nullptr), + _codec(nullptr), + _decoder(nullptr), + _keyTranslator(nullptr), + _usesMouse(false), + _bracketedPasteMode(false) +{ + // create screens with a default size + _screen[0] = new Screen(40, 80); + _screen[1] = new Screen(40, 80); + _currentScreen = _screen[0]; + + QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk())); + QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk())); + + // listen for mouse status changes + connect(this, SIGNAL(programUsesMouseChanged(bool)), SLOT(usesMouseChanged(bool))); + connect(this, SIGNAL(programBracketedPasteModeChanged(bool)), + SLOT(bracketedPasteModeChanged(bool))); + + connect(this, &Emulation::cursorChanged, + [this](KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) { + emit titleChanged(50, + QString(QLatin1String("CursorShape=%1;BlinkingCursorEnabled=%2")) + .arg(static_cast(cursorShape)) + .arg(blinkingCursorEnabled)); + }); } bool Emulation::programUsesMouse() const @@ -98,133 +100,136 @@ void Emulation::bracketedPasteModeChanged(bool bracketedPasteMode) _bracketedPasteMode = bracketedPasteMode; } -ScreenWindow* Emulation::createWindow() +ScreenWindow *Emulation::createWindow() { - ScreenWindow* window = new ScreenWindow(); + ScreenWindow *window = new ScreenWindow(); window->setScreen(_currentScreen); _windows << window; - connect(window , SIGNAL(selectionChanged()), - this , SLOT(bufferedUpdate())); + connect(window, SIGNAL(selectionChanged()), this, SLOT(bufferedUpdate())); - connect(this , SIGNAL(outputChanged()), - window , SLOT(notifyOutputChanged()) ); + connect(this, SIGNAL(outputChanged()), window, SLOT(notifyOutputChanged())); - connect(this, &Emulation::handleCommandFromKeyboard, - window, &ScreenWindow::handleCommandFromKeyboard); - connect(this, &Emulation::outputFromKeypressEvent, - window, &ScreenWindow::scrollToEnd); + connect(this, &Emulation::handleCommandFromKeyboard, window, + &ScreenWindow::handleCommandFromKeyboard); + connect(this, &Emulation::outputFromKeypressEvent, window, &ScreenWindow::scrollToEnd); return window; } Emulation::~Emulation() { - QListIterator windowIter(_windows); + QListIterator windowIter(_windows); - while (windowIter.hasNext()) - { - delete windowIter.next(); - } + while (windowIter.hasNext()) { + delete windowIter.next(); + } - delete _screen[0]; - delete _screen[1]; - delete _decoder; + delete _screen[0]; + delete _screen[1]; + delete _decoder; } void Emulation::setScreen(int n) { - Screen *old = _currentScreen; - _currentScreen = _screen[n & 1]; - if (_currentScreen != old) - { - // tell all windows onto this emulation to switch to the newly active screen - for(ScreenWindow* window : qAsConst(_windows)) - window->setScreen(_currentScreen); - } + Screen *old = _currentScreen; + _currentScreen = _screen[n & 1]; + if (_currentScreen != old) { + // tell all windows onto this emulation to switch to the newly active screen + for (ScreenWindow *window : qAsConst(_windows)) + window->setScreen(_currentScreen); + } } void Emulation::clearHistory() { - _screen[0]->setScroll( _screen[0]->getScroll() , false ); + _screen[0]->setScroll(_screen[0]->getScroll(), false); } -void Emulation::setHistory(const HistoryType& t) +void Emulation::setHistory(const HistoryType &t) { - _screen[0]->setScroll(t); + _screen[0]->setScroll(t); - showBulk(); + showBulk(); } -const HistoryType& Emulation::history() const +const HistoryType &Emulation::history() const { - return _screen[0]->getScroll(); + return _screen[0]->getScroll(); } -void Emulation::setCodec(const QTextCodec * qtc) +void Emulation::setCodec(const QTextCodec *qtc) { - if (qtc) - _codec = qtc; - else - setCodec(LocaleCodec); + if (qtc) + _codec = qtc; + else + setCodec(LocaleCodec); - delete _decoder; - _decoder = _codec->makeDecoder(); + delete _decoder; + _decoder = _codec->makeDecoder(); - emit useUtf8Request(utf8()); + emit useUtf8Request(utf8()); } void Emulation::setCodec(EmulationCodec codec) { - if ( codec == Utf8Codec ) - setCodec( QTextCodec::codecForName("utf8") ); - else if ( codec == LocaleCodec ) - setCodec( QTextCodec::codecForLocale() ); + if (codec == Utf8Codec) + setCodec(QTextCodec::codecForName("utf8")); + else if (codec == LocaleCodec) + setCodec(QTextCodec::codecForLocale()); } -void Emulation::setKeyBindings(const QString& name) +void Emulation::setKeyBindings(const QString &name) { - _keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name); - if (!_keyTranslator) - { - _keyTranslator = KeyboardTranslatorManager::instance()->defaultTranslator(); - } + _keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name); + if (!_keyTranslator) { + _keyTranslator = KeyboardTranslatorManager::instance()->defaultTranslator(); + } } QString Emulation::keyBindings() const { - return _keyTranslator->name(); + return _keyTranslator->name(); } void Emulation::receiveChar(wchar_t c) // process application unicode input to terminal // this is a trivial scanner { - c &= 0xff; - switch (c) - { - case '\b' : _currentScreen->backspace(); break; - case '\t' : _currentScreen->tab(); break; - case '\n' : _currentScreen->newLine(); break; - case '\r' : _currentScreen->toStartOfLine(); break; - case 0x07 : emit stateSet(NOTIFYBELL); - break; - default : _currentScreen->displayCharacter(c); break; - }; -} - -void Emulation::sendKeyEvent(QKeyEvent* ev, bool) -{ - emit stateSet(NOTIFYNORMAL); - - if (!ev->text().isEmpty()) - { // A block of text - // Note that the text is proper unicode. - // We should do a conversion here - emit sendData(ev->text().toUtf8().constData(),ev->text().length()); - } + c &= 0xff; + switch (c) { + case '\b': + _currentScreen->backspace(); + break; + case '\t': + _currentScreen->tab(); + break; + case '\n': + _currentScreen->newLine(); + break; + case '\r': + _currentScreen->toStartOfLine(); + break; + case 0x07: + emit stateSet(NOTIFYBELL); + break; + default: + _currentScreen->displayCharacter(c); + break; + }; +} + +void Emulation::sendKeyEvent(QKeyEvent *ev, bool) +{ + emit stateSet(NOTIFYNORMAL); + + if (!ev->text().isEmpty()) { // A block of text + // Note that the text is proper unicode. + // We should do a conversion here + emit sendData(ev->text().toUtf8().constData(), ev->text().length()); + } } -void Emulation::sendString(const char*,int) +void Emulation::sendString(const char *, int) { // default implementation does nothing } @@ -239,7 +244,7 @@ void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int TODO: Character composition from the old code. See #96536 */ -void Emulation::receiveData(const char* text, int length) +void Emulation::receiveData(const char *text, int length) { emit stateSet(NOTIFYACTIVITY); @@ -250,36 +255,34 @@ void Emulation::receiveData(const char* text, int length) * U+10FFFF * https://unicodebook.readthedocs.io/unicode_encodings.html#surrogates */ - QString utf16Text = _decoder->toUnicode(text,length); + QString utf16Text = _decoder->toUnicode(text, length); std::wstring unicodeText = utf16Text.toStdWString(); - //send characters to terminal emulator - for (size_t i=0;i 3) && (strncmp(text+i+1, "B00", 3) == 0)) + // this check into the above for loop? + for (int i = 0; i < length; i++) { + if (text[i] == '\030') { + if ((length - i - 1 > 3) && (strncmp(text + i + 1, "B00", 3) == 0)) emit zmodemDetected(); } } } -//OLDER VERSION -//This version of onRcvBlock was commented out because -// a) It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 tech preview) -// b) It messed up decoding of non-ASCII characters, with the result that (for example) chinese characters +// OLDER VERSION +// This version of onRcvBlock was commented out because +// a) It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 +// tech preview) b) It messed up decoding of non-ASCII characters, with the result that (for +// example) chinese characters // were not printed properly. // -//There is something about stopping the _decoder if "we get a control code halfway a multi-byte sequence" (see below) -//which hasn't been ported into the newer function (above). Hopefully someone who understands this better -//can find an alternative way of handling the check. - +// There is something about stopping the _decoder if "we get a control code halfway a multi-byte +// sequence" (see below) which hasn't been ported into the newer function (above). Hopefully someone +// who understands this better can find an alternative way of handling the check. /*void Emulation::onRcvBlock(const char *s, int len) { @@ -319,11 +322,9 @@ void Emulation::receiveData(const char* text, int length) } }*/ -void Emulation::writeToStream( TerminalCharacterDecoder* _decoder , - int startLine , - int endLine) +void Emulation::writeToStream(TerminalCharacterDecoder *_decoder, int startLine, int endLine) { - _currentScreen->writeLinesToStream(_decoder,startLine,endLine); + _currentScreen->writeLinesToStream(_decoder, startLine, endLine); } int Emulation::lineCount() const @@ -348,135 +349,119 @@ void Emulation::showBulk() void Emulation::bufferedUpdate() { - _bulkTimer1.setSingleShot(true); - _bulkTimer1.start(BULK_TIMEOUT1); - if (!_bulkTimer2.isActive()) - { - _bulkTimer2.setSingleShot(true); - _bulkTimer2.start(BULK_TIMEOUT2); - } + _bulkTimer1.setSingleShot(true); + _bulkTimer1.start(BULK_TIMEOUT1); + if (!_bulkTimer2.isActive()) { + _bulkTimer2.setSingleShot(true); + _bulkTimer2.start(BULK_TIMEOUT2); + } } char Emulation::eraseChar() const { - return '\b'; + return '\b'; } void Emulation::setImageSize(int lines, int columns) { - if ((lines < 1) || (columns < 1)) - return; + if ((lines < 1) || (columns < 1)) + return; - QSize screenSize[2] = { QSize(_screen[0]->getColumns(), - _screen[0]->getLines()), - QSize(_screen[1]->getColumns(), - _screen[1]->getLines()) }; - QSize newSize(columns,lines); + QSize screenSize[2] = { QSize(_screen[0]->getColumns(), _screen[0]->getLines()), + QSize(_screen[1]->getColumns(), _screen[1]->getLines()) }; + QSize newSize(columns, lines); - if (newSize == screenSize[0] && newSize == screenSize[1]) - return; + if (newSize == screenSize[0] && newSize == screenSize[1]) + return; - _screen[0]->resizeImage(lines,columns); - _screen[1]->resizeImage(lines,columns); + _screen[0]->resizeImage(lines, columns); + _screen[1]->resizeImage(lines, columns); - emit imageSizeChanged(lines,columns); + emit imageSizeChanged(lines, columns); - bufferedUpdate(); + bufferedUpdate(); } QSize Emulation::imageSize() const { - return {_currentScreen->getColumns(), _currentScreen->getLines()}; + return { _currentScreen->getColumns(), _currentScreen->getLines() }; } -ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const +ushort ExtendedCharTable::extendedCharHash(ushort *unicodePoints, ushort length) const { ushort hash = 0; - for ( ushort i = 0 ; i < length ; i++ ) - { - hash = 31*hash + unicodePoints[i]; + for (ushort i = 0; i < length; i++) { + hash = 31 * hash + unicodePoints[i]; } return hash; } -bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const +bool ExtendedCharTable::extendedCharMatch(ushort hash, ushort *unicodePoints, ushort length) const { - ushort* entry = extendedCharTable[hash]; + ushort *entry = extendedCharTable[hash]; // compare given length with stored sequence length ( given as the first ushort in the // stored buffer ) - if ( entry == nullptr || entry[0] != length ) - return false; + if (entry == nullptr || entry[0] != length) + return false; // if the lengths match, each character must be checked. the stored buffer starts at // entry[1] - for ( int i = 0 ; i < length ; i++ ) - { - if ( entry[i+1] != unicodePoints[i] ) - return false; + for (int i = 0; i < length; i++) { + if (entry[i + 1] != unicodePoints[i]) + return false; } return true; } -ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length) +ushort ExtendedCharTable::createExtendedChar(ushort *unicodePoints, ushort length) { // look for this sequence of points in the table - ushort hash = extendedCharHash(unicodePoints,length); + ushort hash = extendedCharHash(unicodePoints, length); // check existing entry for match - while ( extendedCharTable.contains(hash) ) - { - if ( extendedCharMatch(hash,unicodePoints,length) ) - { + while (extendedCharTable.contains(hash)) { + if (extendedCharMatch(hash, unicodePoints, length)) { // this sequence already has an entry in the table, // return its hash return hash; - } - else - { + } else { // if hash is already used by another, different sequence of unicode character // points then try next hash hash++; } } - - // add the new sequence to the table and - // return that index - ushort* buffer = new ushort[length+1]; + // add the new sequence to the table and + // return that index + ushort *buffer = new ushort[length + 1]; buffer[0] = length; - for ( int i = 0 ; i < length ; i++ ) - buffer[i+1] = unicodePoints[i]; + for (int i = 0; i < length; i++) + buffer[i + 1] = unicodePoints[i]; - extendedCharTable.insert(hash,buffer); + extendedCharTable.insert(hash, buffer); return hash; } -ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const +ushort *ExtendedCharTable::lookupExtendedChar(ushort hash, ushort &length) const { // lookup index in table and if found, set the length // argument and return a pointer to the character sequence - ushort* buffer = extendedCharTable[hash]; - if ( buffer ) - { + ushort *buffer = extendedCharTable[hash]; + if (buffer) { length = buffer[0]; - return buffer+1; - } - else - { + return buffer + 1; + } else { length = 0; return nullptr; } } -ExtendedCharTable::ExtendedCharTable() -{ -} +ExtendedCharTable::ExtendedCharTable() { } ExtendedCharTable::~ExtendedCharTable() { // free all allocated character buffers - QHashIterator iter(extendedCharTable); - while ( iter.hasNext() ) - { + QHashIterator iter(extendedCharTable); + while (iter.hasNext()) { iter.next(); delete[] iter.value(); } @@ -485,6 +470,4 @@ ExtendedCharTable::~ExtendedCharTable() // global instance ExtendedCharTable ExtendedCharTable::instance; - //#include "Emulation.moc" - diff --git a/lib/Emulation.h b/lib/Emulation.h index 7d2263b5..63cf801a 100644 --- a/lib/Emulation.h +++ b/lib/Emulation.h @@ -36,8 +36,7 @@ #include "qtermwidget_export.h" #include "KeyboardTranslator.h" -namespace Konsole -{ +namespace Konsole { class HistoryType; class Screen; @@ -50,23 +49,22 @@ class TerminalCharacterDecoder; * * These are the values used by Emulation::stateChanged() */ -enum -{ +enum { /** The emulation is currently receiving user input. */ - NOTIFYNORMAL=0, + NOTIFYNORMAL = 0, /** * The terminal program has triggered a bell event * to get the user's attention. */ - NOTIFYBELL=1, + NOTIFYBELL = 1, /** * The emulation is currently receiving data from its * terminal input. */ - NOTIFYACTIVITY=2, + NOTIFYACTIVITY = 2, // unused here? - NOTIFYSILENCE=3 + NOTIFYSILENCE = 3 }; /** @@ -120,399 +118,392 @@ enum */ class QTERMWIDGET_EXPORT Emulation : public QObject { -Q_OBJECT + Q_OBJECT public: + /** + * This enum describes the available shapes for the keyboard cursor. + * See setKeyboardCursorShape() + */ + enum class KeyboardCursorShape { + /** A rectangular block which covers the entire area of the cursor character. */ + BlockCursor = 0, + /** + * A single flat line which occupies the space at the bottom of the cursor + * character's area. + */ + UnderlineCursor = 1, + /** + * An cursor shaped like the capital letter 'I', similar to the IBeam + * cursor used in Qt/KDE text editors. + */ + IBeamCursor = 2 + }; + + /** Constructs a new terminal emulation */ + Emulation(); + ~Emulation() override; + + /** + * Creates a new window onto the output from this emulation. The contents + * of the window are then rendered by views which are set to use this window using the + * TerminalDisplay::setScreenWindow() method. + */ + ScreenWindow *createWindow(); + + /** Returns the size of the screen image which the emulation produces */ + QSize imageSize() const; + + /** + * Returns the total number of lines, including those stored in the history. + */ + int lineCount() const; + + /** + * Sets the history store used by this emulation. When new lines + * are added to the output, older lines at the top of the screen are transferred to a history + * store. + * + * The number of lines which are kept and the storage location depend on the + * type of store. + */ + void setHistory(const HistoryType &); + /** Returns the history store used by this emulation. See setHistory() */ + const HistoryType &history() const; + /** Clears the history scroll. */ + void clearHistory(); + + /** + * Copies the output history from @p startLine to @p endLine + * into @p stream, using @p decoder to convert the terminal + * characters into text. + * + * @param decoder A decoder which converts lines of terminal characters with + * appearance attributes into output text. PlainTextDecoder is the most commonly + * used decoder. + * @param startLine Index of first line to copy + * @param endLine Index of last line to copy + */ + virtual void writeToStream(TerminalCharacterDecoder *decoder, int startLine, int endLine); + + /** Returns the codec used to decode incoming characters. See setCodec() */ + const QTextCodec *codec() const { return _codec; } + /** Sets the codec used to decode incoming characters. */ + void setCodec(const QTextCodec *); + + /** + * Convenience method. + * Returns true if the current codec used to decode incoming + * characters is UTF-8 + */ + bool utf8() const + { + Q_ASSERT(_codec); + return _codec->mibEnum() == 106; + } + + /** TODO Document me */ + virtual char eraseChar() const; + + /** + * Sets the key bindings used to key events + * ( received through sendKeyEvent() ) into character + * streams to send to the terminal. + */ + void setKeyBindings(const QString &name); + /** + * Returns the name of the emulation's current key bindings. + * See setKeyBindings() + */ + QString keyBindings() const; - /** - * This enum describes the available shapes for the keyboard cursor. - * See setKeyboardCursorShape() - */ - enum class KeyboardCursorShape { - /** A rectangular block which covers the entire area of the cursor character. */ - BlockCursor = 0, - /** - * A single flat line which occupies the space at the bottom of the cursor - * character's area. - */ - UnderlineCursor = 1, - /** - * An cursor shaped like the capital letter 'I', similar to the IBeam - * cursor used in Qt/KDE text editors. - */ - IBeamCursor = 2 - }; - - - /** Constructs a new terminal emulation */ - Emulation(); - ~Emulation() override; - - /** - * Creates a new window onto the output from this emulation. The contents - * of the window are then rendered by views which are set to use this window using the - * TerminalDisplay::setScreenWindow() method. - */ - ScreenWindow* createWindow(); - - /** Returns the size of the screen image which the emulation produces */ - QSize imageSize() const; - - /** - * Returns the total number of lines, including those stored in the history. - */ - int lineCount() const; - - /** - * Sets the history store used by this emulation. When new lines - * are added to the output, older lines at the top of the screen are transferred to a history - * store. - * - * The number of lines which are kept and the storage location depend on the - * type of store. - */ - void setHistory(const HistoryType&); - /** Returns the history store used by this emulation. See setHistory() */ - const HistoryType& history() const; - /** Clears the history scroll. */ - void clearHistory(); - - /** - * Copies the output history from @p startLine to @p endLine - * into @p stream, using @p decoder to convert the terminal - * characters into text. - * - * @param decoder A decoder which converts lines of terminal characters with - * appearance attributes into output text. PlainTextDecoder is the most commonly - * used decoder. - * @param startLine Index of first line to copy - * @param endLine Index of last line to copy - */ - virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine); - - /** Returns the codec used to decode incoming characters. See setCodec() */ - const QTextCodec* codec() const { return _codec; } - /** Sets the codec used to decode incoming characters. */ - void setCodec(const QTextCodec*); - - /** - * Convenience method. - * Returns true if the current codec used to decode incoming - * characters is UTF-8 - */ - bool utf8() const - { Q_ASSERT(_codec); return _codec->mibEnum() == 106; } - - - /** TODO Document me */ - virtual char eraseChar() const; - - /** - * Sets the key bindings used to key events - * ( received through sendKeyEvent() ) into character - * streams to send to the terminal. - */ - void setKeyBindings(const QString& name); - /** - * Returns the name of the emulation's current key bindings. - * See setKeyBindings() - */ - QString keyBindings() const; - - /** - * Copies the current image into the history and clears the screen. - */ - virtual void clearEntireScreen() =0; - - /** Resets the state of the terminal. */ - virtual void reset() =0; - - /** - * Returns true if the active terminal program wants - * mouse input events. - * - * The programUsesMouseChanged() signal is emitted when this - * changes. - */ - bool programUsesMouse() const; - - bool programBracketedPasteMode() const; + /** + * Copies the current image into the history and clears the screen. + */ + virtual void clearEntireScreen() = 0; + + /** Resets the state of the terminal. */ + virtual void reset() = 0; + + /** + * Returns true if the active terminal program wants + * mouse input events. + * + * The programUsesMouseChanged() signal is emitted when this + * changes. + */ + bool programUsesMouse() const; + + bool programBracketedPasteMode() const; public slots: - /** Change the size of the emulation's image */ - virtual void setImageSize(int lines, int columns); - - /** - * Interprets a sequence of characters and sends the result to the terminal. - * This is equivalent to calling sendKeyEvent() for each character in @p text in succession. - */ - virtual void sendText(const QString& text) = 0; - - /** - * Interprets a key press event and emits the sendData() signal with - * the resulting character stream. - */ - virtual void sendKeyEvent(QKeyEvent*, bool fromPaste); - - /** - * Converts information about a mouse event into an xterm-compatible escape - * sequence and emits the character sequence via sendData() - */ - virtual void sendMouseEvent(int buttons, int column, int line, int eventType); - - /** - * Sends a string of characters to the foreground terminal process. - * - * @param string The characters to send. - * @param length Length of @p string or if set to a negative value, @p string will - * be treated as a null-terminated string and its length will be determined automatically. - */ - virtual void sendString(const char* string, int length = -1) = 0; - - /** - * Processes an incoming stream of characters. receiveData() decodes the incoming - * character buffer using the current codec(), and then calls receiveChar() for - * each unicode character in the resulting buffer. - * - * receiveData() also starts a timer which causes the outputChanged() signal - * to be emitted when it expires. The timer allows multiple updates in quick - * succession to be buffered into a single outputChanged() signal emission. - * - * @param buffer A string of characters received from the terminal program. - * @param len The length of @p buffer - */ - void receiveData(const char* buffer,int len); + /** Change the size of the emulation's image */ + virtual void setImageSize(int lines, int columns); + + /** + * Interprets a sequence of characters and sends the result to the terminal. + * This is equivalent to calling sendKeyEvent() for each character in @p text in succession. + */ + virtual void sendText(const QString &text) = 0; + + /** + * Interprets a key press event and emits the sendData() signal with + * the resulting character stream. + */ + virtual void sendKeyEvent(QKeyEvent *, bool fromPaste); + + /** + * Converts information about a mouse event into an xterm-compatible escape + * sequence and emits the character sequence via sendData() + */ + virtual void sendMouseEvent(int buttons, int column, int line, int eventType); + + /** + * Sends a string of characters to the foreground terminal process. + * + * @param string The characters to send. + * @param length Length of @p string or if set to a negative value, @p string will + * be treated as a null-terminated string and its length will be determined automatically. + */ + virtual void sendString(const char *string, int length = -1) = 0; + + /** + * Processes an incoming stream of characters. receiveData() decodes the incoming + * character buffer using the current codec(), and then calls receiveChar() for + * each unicode character in the resulting buffer. + * + * receiveData() also starts a timer which causes the outputChanged() signal + * to be emitted when it expires. The timer allows multiple updates in quick + * succession to be buffered into a single outputChanged() signal emission. + * + * @param buffer A string of characters received from the terminal program. + * @param len The length of @p buffer + */ + void receiveData(const char *buffer, int len); signals: - /** - * Emitted when a buffer of data is ready to send to the - * standard input of the terminal. - * - * @param data The buffer of data ready to be sent - * @param len The length of @p data in bytes - */ - void sendData(const char* data,int len); - - /** - * Requests that sending of input to the emulation - * from the terminal process be suspended or resumed. - * - * @param suspend If true, requests that sending of - * input from the terminal process' stdout be - * suspended. Otherwise requests that sending of - * input be resumed. - */ - void lockPtyRequest(bool suspend); - - /** - * Requests that the pty used by the terminal process - * be set to UTF 8 mode. - * - * TODO: More documentation - */ - void useUtf8Request(bool); - - /** - * Emitted when the activity state of the emulation is set. - * - * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY - * or NOTIFYBELL - */ - void stateSet(int state); - - /** TODO Document me */ - void zmodemDetected(); - - - /** - * Requests that the color of the text used - * to represent the tabs associated with this - * emulation be changed. This is a Konsole-specific - * extension from pre-KDE 4 times. - * - * TODO: Document how the parameter works. - */ - void changeTabTextColorRequest(int color); - - /** - * This is emitted when the program running in the shell indicates whether or - * not it is interested in mouse events. - * - * @param usesMouse This will be true if the program wants to be informed about - * mouse events or false otherwise. - */ - void programUsesMouseChanged(bool usesMouse); - - void programBracketedPasteModeChanged(bool bracketedPasteMode); - - /** - * Emitted when the contents of the screen image change. - * The emulation buffers the updates from successive image changes, - * and only emits outputChanged() at sensible intervals when - * there is a lot of terminal activity. - * - * Normally there is no need for objects other than the screen windows - * created with createWindow() to listen for this signal. - * - * ScreenWindow objects created using createWindow() will emit their - * own outputChanged() signal in response to this signal. - */ - void outputChanged(); - - /** - * Emitted when the program running in the terminal wishes to update the - * session's title. This also allows terminal programs to customize other - * aspects of the terminal emulation display. - * - * This signal is emitted when the escape sequence "\033]ARG;VALUE\007" - * is received in the input string, where ARG is a number specifying what - * should change and VALUE is a string specifying the new value. - * - * TODO: The name of this method is not very accurate since this method - * is used to perform a whole range of tasks besides just setting - * the user-title of the session. - * - * @param title Specifies what to change. - *
    - *
  • 0 - Set window icon text and session title to @p newTitle
  • - *
  • 1 - Set window icon text to @p newTitle
  • - *
  • 2 - Set session title to @p newTitle
  • - *
  • 11 - Set the session's default background color to @p newTitle, - * where @p newTitle can be an HTML-style string ("#RRGGBB") or a named - * color (eg 'red', 'blue'). - * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more - * details. - *
  • - *
  • 31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)
  • - *
  • 32 - Sets the icon associated with the session. @p newTitle is the name - * of the icon to use, which can be the name of any icon in the current KDE icon - * theme (eg: 'konsole', 'kate', 'folder_home')
  • - *
- * @param newTitle Specifies the new title - */ - - void titleChanged(int title,const QString& newTitle); - - /** - * Emitted when the program running in the terminal changes the - * screen size. - */ - void imageSizeChanged(int lineCount , int columnCount); - - /** - * Emitted when the setImageSize() is called on this emulation for - * the first time. - */ - void imageSizeInitialized(); - - /** - * Emitted after receiving the escape sequence which asks to change - * the terminal emulator's size - */ - void imageResizeRequest(const QSize& sizz); - - /** - * Emitted when the terminal program requests to change various properties - * of the terminal display. - * - * A profile change command occurs when a special escape sequence, followed - * by a string containing a series of name and value pairs is received. - * This string can be parsed using a ProfileCommandParser instance. - * - * @param text A string expected to contain a series of key and value pairs in - * the form: name=value;name2=value2 ... - */ - void profileChangeCommandReceived(const QString& text); - - /** - * Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed. - * @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to - * resume output. - */ - void flowControlKeyPressed(bool suspendKeyPressed); - - /** - * Emitted when the cursor shape or its blinking state is changed via - * DECSCUSR sequences. - * - * @param cursorShape One of 3 possible values in KeyboardCursorShape enum - * @param blinkingCursorEnabled Whether to enable blinking or not - */ - void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); - - void handleCommandFromKeyboard(KeyboardTranslator::Command command); - void outputFromKeypressEvent(void); + /** + * Emitted when a buffer of data is ready to send to the + * standard input of the terminal. + * + * @param data The buffer of data ready to be sent + * @param len The length of @p data in bytes + */ + void sendData(const char *data, int len); + + /** + * Requests that sending of input to the emulation + * from the terminal process be suspended or resumed. + * + * @param suspend If true, requests that sending of + * input from the terminal process' stdout be + * suspended. Otherwise requests that sending of + * input be resumed. + */ + void lockPtyRequest(bool suspend); + + /** + * Requests that the pty used by the terminal process + * be set to UTF 8 mode. + * + * TODO: More documentation + */ + void useUtf8Request(bool); + + /** + * Emitted when the activity state of the emulation is set. + * + * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY + * or NOTIFYBELL + */ + void stateSet(int state); + + /** TODO Document me */ + void zmodemDetected(); + + /** + * Requests that the color of the text used + * to represent the tabs associated with this + * emulation be changed. This is a Konsole-specific + * extension from pre-KDE 4 times. + * + * TODO: Document how the parameter works. + */ + void changeTabTextColorRequest(int color); + + /** + * This is emitted when the program running in the shell indicates whether or + * not it is interested in mouse events. + * + * @param usesMouse This will be true if the program wants to be informed about + * mouse events or false otherwise. + */ + void programUsesMouseChanged(bool usesMouse); + + void programBracketedPasteModeChanged(bool bracketedPasteMode); + + /** + * Emitted when the contents of the screen image change. + * The emulation buffers the updates from successive image changes, + * and only emits outputChanged() at sensible intervals when + * there is a lot of terminal activity. + * + * Normally there is no need for objects other than the screen windows + * created with createWindow() to listen for this signal. + * + * ScreenWindow objects created using createWindow() will emit their + * own outputChanged() signal in response to this signal. + */ + void outputChanged(); + + /** + * Emitted when the program running in the terminal wishes to update the + * session's title. This also allows terminal programs to customize other + * aspects of the terminal emulation display. + * + * This signal is emitted when the escape sequence "\033]ARG;VALUE\007" + * is received in the input string, where ARG is a number specifying what + * should change and VALUE is a string specifying the new value. + * + * TODO: The name of this method is not very accurate since this method + * is used to perform a whole range of tasks besides just setting + * the user-title of the session. + * + * @param title Specifies what to change. + *
    + *
  • 0 - Set window icon text and session title to @p newTitle
  • + *
  • 1 - Set window icon text to @p newTitle
  • + *
  • 2 - Set session title to @p newTitle
  • + *
  • 11 - Set the session's default background color to @p newTitle, + * where @p newTitle can be an HTML-style string ("#RRGGBB") or a named + * color (eg 'red', 'blue'). + * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more + * details. + *
  • + *
  • 31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)
  • + *
  • 32 - Sets the icon associated with the session. @p newTitle is the name + * of the icon to use, which can be the name of any icon in the current KDE icon + * theme (eg: 'konsole', 'kate', 'folder_home')
  • + *
+ * @param newTitle Specifies the new title + */ + + void titleChanged(int title, const QString &newTitle); + + /** + * Emitted when the program running in the terminal changes the + * screen size. + */ + void imageSizeChanged(int lineCount, int columnCount); + + /** + * Emitted when the setImageSize() is called on this emulation for + * the first time. + */ + void imageSizeInitialized(); + + /** + * Emitted after receiving the escape sequence which asks to change + * the terminal emulator's size + */ + void imageResizeRequest(const QSize &sizz); + + /** + * Emitted when the terminal program requests to change various properties + * of the terminal display. + * + * A profile change command occurs when a special escape sequence, followed + * by a string containing a series of name and value pairs is received. + * This string can be parsed using a ProfileCommandParser instance. + * + * @param text A string expected to contain a series of key and value pairs in + * the form: name=value;name2=value2 ... + */ + void profileChangeCommandReceived(const QString &text); + + /** + * Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed. + * @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to + * resume output. + */ + void flowControlKeyPressed(bool suspendKeyPressed); + + /** + * Emitted when the cursor shape or its blinking state is changed via + * DECSCUSR sequences. + * + * @param cursorShape One of 3 possible values in KeyboardCursorShape enum + * @param blinkingCursorEnabled Whether to enable blinking or not + */ + void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); + + void handleCommandFromKeyboard(KeyboardTranslator::Command command); + void outputFromKeypressEvent(void); protected: - virtual void setMode(int mode) = 0; - virtual void resetMode(int mode) = 0; - - /** - * Processes an incoming character. See receiveData() - * @p ch A unicode character code. - */ - virtual void receiveChar(wchar_t ch); - - /** - * Sets the active screen. The terminal has two screens, primary and alternate. - * The primary screen is used by default. When certain interactive programs such - * as Vim are run, they trigger a switch to the alternate screen. - * - * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen - */ - void setScreen(int index); - - enum EmulationCodec - { - LocaleCodec = 0, - Utf8Codec = 1 - }; - void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8 - - - QList _windows; - - Screen* _currentScreen; // pointer to the screen which is currently active, - // this is one of the elements in the screen[] array + virtual void setMode(int mode) = 0; + virtual void resetMode(int mode) = 0; - Screen* _screen[2]; // 0 = primary screen ( used by most programs, including the shell - // scrollbars are enabled in this mode ) - // 1 = alternate ( used by vi , emacs etc. - // scrollbars are not enabled in this mode ) + /** + * Processes an incoming character. See receiveData() + * @p ch A unicode character code. + */ + virtual void receiveChar(wchar_t ch); + /** + * Sets the active screen. The terminal has two screens, primary and alternate. + * The primary screen is used by default. When certain interactive programs such + * as Vim are run, they trigger a switch to the alternate screen. + * + * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen + */ + void setScreen(int index); + + enum EmulationCodec { LocaleCodec = 0, Utf8Codec = 1 }; + void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8 - //decodes an incoming C-style character stream into a unicode QString using - //the current text codec. (this allows for rendering of non-ASCII characters in text files etc.) - const QTextCodec* _codec; - QTextDecoder* _decoder; - const KeyboardTranslator* _keyTranslator; // the keyboard layout + QList _windows; + + Screen *_currentScreen; // pointer to the screen which is currently active, + // this is one of the elements in the screen[] array + + Screen *_screen[2]; // 0 = primary screen ( used by most programs, including the shell + // scrollbars are enabled in this mode ) + // 1 = alternate ( used by vi , emacs etc. + // scrollbars are not enabled in this mode ) + + // decodes an incoming C-style character stream into a unicode QString using + // the current text codec. (this allows for rendering of non-ASCII characters in text files + // etc.) + const QTextCodec *_codec; + QTextDecoder *_decoder; + const KeyboardTranslator *_keyTranslator; // the keyboard layout protected slots: - /** - * Schedules an update of attached views. - * Repeated calls to bufferedUpdate() in close succession will result in only a single update, - * much like the Qt buffered update of widgets. - */ - void bufferedUpdate(); + /** + * Schedules an update of attached views. + * Repeated calls to bufferedUpdate() in close succession will result in only a single update, + * much like the Qt buffered update of widgets. + */ + void bufferedUpdate(); private slots: - // triggered by timer, causes the emulation to send an updated screen image to each - // view - void showBulk(); + // triggered by timer, causes the emulation to send an updated screen image to each + // view + void showBulk(); - void usesMouseChanged(bool usesMouse); + void usesMouseChanged(bool usesMouse); - void bracketedPasteModeChanged(bool bracketedPasteMode); + void bracketedPasteModeChanged(bool bracketedPasteMode); private: - bool _usesMouse; - bool _bracketedPasteMode; - QTimer _bulkTimer1; - QTimer _bulkTimer2; - + bool _usesMouse; + bool _bracketedPasteMode; + QTimer _bulkTimer1; + QTimer _bulkTimer2; }; } diff --git a/lib/ExtendedDefaultTranslator.h b/lib/ExtendedDefaultTranslator.h index 6403c729..9394b9e5 100644 --- a/lib/ExtendedDefaultTranslator.h +++ b/lib/ExtendedDefaultTranslator.h @@ -1,74 +1,74 @@ "keyboard \"Default (XFree 4)\"" -"key Escape : \"\\E\"" -"key Tab -Shift : \"\\t\"\n" -"key Tab +Shift+Ansi : \"\\E[Z\"\n" -"key Tab +Shift-Ansi : \"\\t\"\n" -"key Backtab +Ansi : \"\\E[Z\"\n" -"key Backtab -Ansi : \"\\t\"\n" -"key Return-Shift-NewLine : \"\\r\"\n" -"key Return-Shift+NewLine : \"\\r\\n\"\n" -"key Return+Shift : \"\\EOM\"\n" -"key Backspace : \"\\x7f\"\n" -"key Up -Shift-Ansi : \"\\EA\"\n" -"key Down -Shift-Ansi : \"\\EB\"\n" -"key Right-Shift-Ansi : \"\\EC\"\n" -"key Left -Shift-Ansi : \"\\ED\"\n" -"key Up -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOA\"\n" -"key Down -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOB\"\n" -"key Right -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOC\"\n" -"key Left -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOD\"\n" -"key Up -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[A\"\n" -"key Down -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[B\"\n" -"key Right -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[C\"\n" -"key Left -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[D\"\n" -"key Up -Shift+AnyMod+Ansi : \"\\E[1;*A\"\n" -"key Down -Shift+AnyMod+Ansi : \"\\E[1;*B\"\n" -"key Right -Shift+AnyMod+Ansi : \"\\E[1;*C\"\n" -"key Left -Shift+AnyMod+Ansi : \"\\E[1;*D\"\n" -"key Enter+NewLine : \"\\r\\n\"\n" -"key Enter-NewLine : \"\\r\"\n" -"key Home -AnyMod -AppCuKeys : \"\\E[H\" \n" -"key End -AnyMod -AppCuKeys : \"\\E[F\" \n" -"key Home -AnyMod +AppCuKeys : \"\\EOH\" \n" -"key End -AnyMod +AppCuKeys : \"\\EOF\" \n" -"key Home +AnyMod : \"\\E[1;*H\"\n" -"key End +AnyMod : \"\\E[1;*F\"\n" -"key Insert -AnyMod : \"\\E[2~\"\n" -"key Delete -AnyMod : \"\\E[3~\"\n" -"key Insert +AnyMod : \"\\E[2;*~\"\n" -"key Delete +AnyMod : \"\\E[3;*~\"\n" -"key Prior -Shift-AnyMod : \"\\E[5~\"\n" -"key Next -Shift-AnyMod : \"\\E[6~\"\n" -"key Prior -Shift+AnyMod : \"\\E[5;*~\"\n" -"key Next -Shift+AnyMod : \"\\E[6;*~\"\n" -"key F1 -AnyMod : \"\\EOP\"\n" -"key F2 -AnyMod : \"\\EOQ\"\n" -"key F3 -AnyMod : \"\\EOR\"\n" -"key F4 -AnyMod : \"\\EOS\"\n" -"key F5 -AnyMod : \"\\E[15~\"\n" -"key F6 -AnyMod : \"\\E[17~\"\n" -"key F7 -AnyMod : \"\\E[18~\"\n" -"key F8 -AnyMod : \"\\E[19~\"\n" -"key F9 -AnyMod : \"\\E[20~\"\n" -"key F10 -AnyMod : \"\\E[21~\"\n" -"key F11 -AnyMod : \"\\E[23~\"\n" -"key F12 -AnyMod : \"\\E[24~\"\n" -"key F1 +AnyMod : \"\\EO*P\"\n" -"key F2 +AnyMod : \"\\EO*Q\"\n" -"key F3 +AnyMod : \"\\EO*R\"\n" -"key F4 +AnyMod : \"\\EO*S\"\n" -"key F5 +AnyMod : \"\\E[15;*~\"\n" -"key F6 +AnyMod : \"\\E[17;*~\"\n" -"key F7 +AnyMod : \"\\E[18;*~\"\n" -"key F8 +AnyMod : \"\\E[19;*~\"\n" -"key F9 +AnyMod : \"\\E[20;*~\"\n" -"key F10 +AnyMod : \"\\E[21;*~\"\n" -"key F11 +AnyMod : \"\\E[23;*~\"\n" -"key F12 +AnyMod : \"\\E[24;*~\"\n" -"key Space +Control : \"\\x00\"\n" -"key Up +Shift-AppScreen : scrollLineUp\n" -"key Prior +Shift-AppScreen : scrollPageUp\n" -"key Down +Shift-AppScreen : scrollLineDown\n" -"key Next +Shift-AppScreen : scrollPageDown\n" -"key ScrollLock : scrollLock\n" -"\0" + "key Escape : \"\\E\"" + "key Tab -Shift : \"\\t\"\n" + "key Tab +Shift+Ansi : \"\\E[Z\"\n" + "key Tab +Shift-Ansi : \"\\t\"\n" + "key Backtab +Ansi : \"\\E[Z\"\n" + "key Backtab -Ansi : \"\\t\"\n" + "key Return-Shift-NewLine : \"\\r\"\n" + "key Return-Shift+NewLine : \"\\r\\n\"\n" + "key Return+Shift : \"\\EOM\"\n" + "key Backspace : \"\\x7f\"\n" + "key Up -Shift-Ansi : \"\\EA\"\n" + "key Down -Shift-Ansi : \"\\EB\"\n" + "key Right-Shift-Ansi : \"\\EC\"\n" + "key Left -Shift-Ansi : \"\\ED\"\n" + "key Up -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOA\"\n" + "key Down -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOB\"\n" + "key Right -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOC\"\n" + "key Left -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOD\"\n" + "key Up -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[A\"\n" + "key Down -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[B\"\n" + "key Right -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[C\"\n" + "key Left -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[D\"\n" + "key Up -Shift+AnyMod+Ansi : \"\\E[1;*A\"\n" + "key Down -Shift+AnyMod+Ansi : \"\\E[1;*B\"\n" + "key Right -Shift+AnyMod+Ansi : \"\\E[1;*C\"\n" + "key Left -Shift+AnyMod+Ansi : \"\\E[1;*D\"\n" + "key Enter+NewLine : \"\\r\\n\"\n" + "key Enter-NewLine : \"\\r\"\n" + "key Home -AnyMod -AppCuKeys : \"\\E[H\" \n" + "key End -AnyMod -AppCuKeys : \"\\E[F\" \n" + "key Home -AnyMod +AppCuKeys : \"\\EOH\" \n" + "key End -AnyMod +AppCuKeys : \"\\EOF\" \n" + "key Home +AnyMod : \"\\E[1;*H\"\n" + "key End +AnyMod : \"\\E[1;*F\"\n" + "key Insert -AnyMod : \"\\E[2~\"\n" + "key Delete -AnyMod : \"\\E[3~\"\n" + "key Insert +AnyMod : \"\\E[2;*~\"\n" + "key Delete +AnyMod : \"\\E[3;*~\"\n" + "key Prior -Shift-AnyMod : \"\\E[5~\"\n" + "key Next -Shift-AnyMod : \"\\E[6~\"\n" + "key Prior -Shift+AnyMod : \"\\E[5;*~\"\n" + "key Next -Shift+AnyMod : \"\\E[6;*~\"\n" + "key F1 -AnyMod : \"\\EOP\"\n" + "key F2 -AnyMod : \"\\EOQ\"\n" + "key F3 -AnyMod : \"\\EOR\"\n" + "key F4 -AnyMod : \"\\EOS\"\n" + "key F5 -AnyMod : \"\\E[15~\"\n" + "key F6 -AnyMod : \"\\E[17~\"\n" + "key F7 -AnyMod : \"\\E[18~\"\n" + "key F8 -AnyMod : \"\\E[19~\"\n" + "key F9 -AnyMod : \"\\E[20~\"\n" + "key F10 -AnyMod : \"\\E[21~\"\n" + "key F11 -AnyMod : \"\\E[23~\"\n" + "key F12 -AnyMod : \"\\E[24~\"\n" + "key F1 +AnyMod : \"\\EO*P\"\n" + "key F2 +AnyMod : \"\\EO*Q\"\n" + "key F3 +AnyMod : \"\\EO*R\"\n" + "key F4 +AnyMod : \"\\EO*S\"\n" + "key F5 +AnyMod : \"\\E[15;*~\"\n" + "key F6 +AnyMod : \"\\E[17;*~\"\n" + "key F7 +AnyMod : \"\\E[18;*~\"\n" + "key F8 +AnyMod : \"\\E[19;*~\"\n" + "key F9 +AnyMod : \"\\E[20;*~\"\n" + "key F10 +AnyMod : \"\\E[21;*~\"\n" + "key F11 +AnyMod : \"\\E[23;*~\"\n" + "key F12 +AnyMod : \"\\E[24;*~\"\n" + "key Space +Control : \"\\x00\"\n" + "key Up +Shift-AppScreen : scrollLineUp\n" + "key Prior +Shift-AppScreen : scrollPageUp\n" + "key Down +Shift-AppScreen : scrollLineDown\n" + "key Next +Shift-AppScreen : scrollPageDown\n" + "key ScrollLock : scrollLock\n" + "\0" diff --git a/lib/Filter.cpp b/lib/Filter.cpp index f2192929..af82fa71 100644 --- a/lib/Filter.cpp +++ b/lib/Filter.cpp @@ -47,59 +47,56 @@ using namespace Konsole; FilterChain::~FilterChain() { - QMutableListIterator iter(*this); + QMutableListIterator iter(*this); - while ( iter.hasNext() ) - { - Filter* filter = iter.next(); + while (iter.hasNext()) { + Filter *filter = iter.next(); iter.remove(); delete filter; } } -void FilterChain::addFilter(Filter* filter) +void FilterChain::addFilter(Filter *filter) { append(filter); } -void FilterChain::removeFilter(Filter* filter) +void FilterChain::removeFilter(Filter *filter) { removeAll(filter); } -bool FilterChain::containsFilter(Filter* filter) +bool FilterChain::containsFilter(Filter *filter) { return contains(filter); } void FilterChain::reset() { - QListIterator iter(*this); + QListIterator iter(*this); while (iter.hasNext()) iter.next()->reset(); } -void FilterChain::setBuffer(const QString* buffer , const QList* linePositions) +void FilterChain::setBuffer(const QString *buffer, const QList *linePositions) { - QListIterator iter(*this); + QListIterator iter(*this); while (iter.hasNext()) - iter.next()->setBuffer(buffer,linePositions); + iter.next()->setBuffer(buffer, linePositions); } void FilterChain::process() { - QListIterator iter(*this); + QListIterator iter(*this); while (iter.hasNext()) iter.next()->process(); } void FilterChain::clear() { - QList::clear(); + QList::clear(); } -Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const +Filter::HotSpot *FilterChain::hotSpotAt(int line, int column) const { - QListIterator iter(*this); - while (iter.hasNext()) - { - Filter* filter = iter.next(); - Filter::HotSpot* spot = filter->hotSpotAt(line,column); - if ( spot != nullptr ) - { + QListIterator iter(*this); + while (iter.hasNext()) { + Filter *filter = iter.next(); + Filter::HotSpot *spot = filter->hotSpotAt(line, column); + if (spot != nullptr) { return spot; } } @@ -107,24 +104,19 @@ Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const return nullptr; } -QList FilterChain::hotSpots() const +QList FilterChain::hotSpots() const { - QList list; - QListIterator iter(*this); - while (iter.hasNext()) - { - Filter* filter = iter.next(); + QList list; + QListIterator iter(*this); + while (iter.hasNext()) { + Filter *filter = iter.next(); list << filter->hotSpots(); } return list; } -//QList FilterChain::hotSpotsAtLine(int line) const; +// QList FilterChain::hotSpotsAtLine(int line) const; -TerminalImageFilterChain::TerminalImageFilterChain() -: _buffer(nullptr) -, _linePositions(nullptr) -{ -} +TerminalImageFilterChain::TerminalImageFilterChain() : _buffer(nullptr), _linePositions(nullptr) { } TerminalImageFilterChain::~TerminalImageFilterChain() { @@ -132,7 +124,8 @@ TerminalImageFilterChain::~TerminalImageFilterChain() delete _linePositions; } -void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector& lineProperties) +void TerminalImageFilterChain::setImage(const Character *const image, int lines, int columns, + const QVector &lineProperties) { if (empty()) return; @@ -144,9 +137,9 @@ void TerminalImageFilterChain::setImage(const Character* const image , int lines decoder.setTrailingWhitespace(false); // setup new shared buffers for the filters to process on - QString* newBuffer = new QString(); - QList* newLinePositions = new QList(); - setBuffer( newBuffer , newLinePositions ); + QString *newBuffer = new QString(); + QList *newLinePositions = new QList(); + setBuffer(newBuffer, newLinePositions); // free the old buffers delete _buffer; @@ -158,10 +151,9 @@ void TerminalImageFilterChain::setImage(const Character* const image , int lines QTextStream lineStream(_buffer); decoder.begin(&lineStream); - for (int i=0 ; i < lines ; i++) - { + for (int i = 0; i < lines; i++) { _linePositions->append(_buffer->length()); - decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT); + decoder.decodeLine(image + i * columns, columns, LINE_DEFAULT); // pretend that each line ends with a newline character. // this prevents a link that occurs at the end of one line @@ -173,17 +165,13 @@ void TerminalImageFilterChain::setImage(const Character* const image , int lines // TODO - Use the "line wrapped" attribute associated with lines in a // terminal image to avoid adding this imaginary character for wrapped // lines - if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) ) + if (!(lineProperties.value(i, LINE_DEFAULT) & LINE_WRAPPED)) lineStream << QLatin1Char('\n'); } decoder.end(); } -Filter::Filter() : -_linePositions(nullptr), -_buffer(nullptr) -{ -} +Filter::Filter() : _linePositions(nullptr), _buffer(nullptr) { } Filter::~Filter() { @@ -197,79 +185,73 @@ void Filter::reset() _hotspotList.clear(); } -void Filter::setBuffer(const QString* buffer , const QList* linePositions) +void Filter::setBuffer(const QString *buffer, const QList *linePositions) { _buffer = buffer; _linePositions = linePositions; } -void Filter::getLineColumn(int position , int& startLine , int& startColumn) +void Filter::getLineColumn(int position, int &startLine, int &startColumn) { - Q_ASSERT( _linePositions ); - Q_ASSERT( _buffer ); + Q_ASSERT(_linePositions); + Q_ASSERT(_buffer); - - for (int i = 0 ; i < _linePositions->count() ; i++) - { + for (int i = 0; i < _linePositions->count(); i++) { int nextLine = 0; - if ( i == _linePositions->count()-1 ) + if (i == _linePositions->count() - 1) nextLine = _buffer->length() + 1; else - nextLine = _linePositions->value(i+1); + nextLine = _linePositions->value(i + 1); - if ( _linePositions->value(i) <= position && position < nextLine ) - { + if (_linePositions->value(i) <= position && position < nextLine) { startLine = i; - startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i)).toStdWString()); + startColumn = string_width( + buffer()->mid(_linePositions->value(i), position - _linePositions->value(i)) + .toStdWString()); return; } } } - /*void Filter::addLine(const QString& text) { _linePositions << _buffer.length(); _buffer.append(text); }*/ -const QString* Filter::buffer() +const QString *Filter::buffer() { return _buffer; } -Filter::HotSpot::~HotSpot() -{ -} -void Filter::addHotSpot(HotSpot* spot) +Filter::HotSpot::~HotSpot() { } +void Filter::addHotSpot(HotSpot *spot) { _hotspotList << spot; - for (int line = spot->startLine() ; line <= spot->endLine() ; line++) - { - _hotspots.insert(line,spot); + for (int line = spot->startLine(); line <= spot->endLine(); line++) { + _hotspots.insert(line, spot); } } -QList Filter::hotSpots() const +QList Filter::hotSpots() const { return _hotspotList; } -QList Filter::hotSpotsAtLine(int line) const +QList Filter::hotSpotsAtLine(int line) const { return _hotspots.values(line); } -Filter::HotSpot* Filter::hotSpotAt(int line , int column) const +Filter::HotSpot *Filter::hotSpotAt(int line, int column) const { - QListIterator spotIter(_hotspots.values(line)); + QListIterator spotIter(_hotspots.values(line)); - while (spotIter.hasNext()) - { - HotSpot* spot = spotIter.next(); + while (spotIter.hasNext()) { + HotSpot *spot = spotIter.next(); - if ( spot->startLine() == line && spot->startColumn() > column ) + if (spot->startLine() == line && spot->startColumn() > column) continue; - if ( spot->endLine() == line && spot->endColumn() < column ) + if (spot->endLine() == line && spot->endColumn() < column) continue; return spot; @@ -278,17 +260,17 @@ Filter::HotSpot* Filter::hotSpotAt(int line , int column) const return nullptr; } -Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn) - : _startLine(startLine) - , _startColumn(startColumn) - , _endLine(endLine) - , _endColumn(endColumn) - , _type(NotSpecified) +Filter::HotSpot::HotSpot(int startLine, int startColumn, int endLine, int endColumn) + : _startLine(startLine), + _startColumn(startColumn), + _endLine(endLine), + _endColumn(endColumn), + _type(NotSpecified) { } -QList Filter::HotSpot::actions() +QList Filter::HotSpot::actions() { - return QList(); + return QList(); } int Filter::HotSpot::startLine() const { @@ -315,21 +297,17 @@ void Filter::HotSpot::setType(Type type) _type = type; } -RegExpFilter::RegExpFilter() -{ -} +RegExpFilter::RegExpFilter() { } -RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn) - : Filter::HotSpot(startLine,startColumn,endLine,endColumn) +RegExpFilter::HotSpot::HotSpot(int startLine, int startColumn, int endLine, int endColumn) + : Filter::HotSpot(startLine, startColumn, endLine, endColumn) { setType(Marker); } -void RegExpFilter::HotSpot::activate(const QString&) -{ -} +void RegExpFilter::HotSpot::activate(const QString &) { } -void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts) +void RegExpFilter::HotSpot::setCapturedTexts(const QStringList &texts) { _capturedTexts = texts; } @@ -338,7 +316,7 @@ QStringList RegExpFilter::HotSpot::capturedTexts() const return _capturedTexts; } -void RegExpFilter::setRegExp(const QRegExp& regExp) +void RegExpFilter::setRegExp(const QRegExp ®Exp) { _searchText = regExp; } @@ -353,62 +331,57 @@ QRegExp RegExpFilter::regExp() const void RegExpFilter::process() { int pos = 0; - const QString* text = buffer(); + const QString *text = buffer(); - Q_ASSERT( text ); + Q_ASSERT(text); // ignore any regular expressions which match an empty string. // otherwise the while loop below will run indefinitely static const QString emptyString; - if ( _searchText.exactMatch(emptyString) ) + if (_searchText.exactMatch(emptyString)) return; - while(pos >= 0) - { - pos = _searchText.indexIn(*text,pos); + while (pos >= 0) { + pos = _searchText.indexIn(*text, pos); - if ( pos >= 0 ) - { + if (pos >= 0) { int startLine = 0; int endLine = 0; int startColumn = 0; int endColumn = 0; - getLineColumn(pos,startLine,startColumn); - getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn); + getLineColumn(pos, startLine, startColumn); + getLineColumn(pos + _searchText.matchedLength(), endLine, endColumn); - RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn, - endLine,endColumn); + RegExpFilter::HotSpot *spot = newHotSpot(startLine, startColumn, endLine, endColumn); spot->setCapturedTexts(_searchText.capturedTexts()); - addHotSpot( spot ); + addHotSpot(spot); pos += _searchText.matchedLength(); // if matchedLength == 0, the program will get stuck in an infinite loop - if ( _searchText.matchedLength() == 0 ) + if (_searchText.matchedLength() == 0) pos = -1; } } } -RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn, - int endLine,int endColumn) +RegExpFilter::HotSpot *RegExpFilter::newHotSpot(int startLine, int startColumn, int endLine, + int endColumn) { - return new RegExpFilter::HotSpot(startLine,startColumn, - endLine,endColumn); + return new RegExpFilter::HotSpot(startLine, startColumn, endLine, endColumn); } -RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine, - int endColumn) +RegExpFilter::HotSpot *UrlFilter::newHotSpot(int startLine, int startColumn, int endLine, + int endColumn) { - HotSpot *spot = new UrlFilter::HotSpot(startLine,startColumn, - endLine,endColumn); + HotSpot *spot = new UrlFilter::HotSpot(startLine, startColumn, endLine, endColumn); connect(spot->getUrlObject(), &FilterObject::activated, this, &UrlFilter::activated); return spot; } -UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn) -: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn) -, _urlObject(new FilterObject(this)) +UrlFilter::HotSpot::HotSpot(int startLine, int startColumn, int endLine, int endColumn) + : RegExpFilter::HotSpot(startLine, startColumn, endLine, endColumn), + _urlObject(new FilterObject(this)) { setType(Link); } @@ -417,66 +390,65 @@ UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const { QString url = capturedTexts().constFirst(); - if ( FullUrlRegExp.exactMatch(url) ) + if (FullUrlRegExp.exactMatch(url)) return StandardUrl; - else if ( EmailAddressRegExp.exactMatch(url) ) + else if (EmailAddressRegExp.exactMatch(url)) return Email; else return Unknown; } -void UrlFilter::HotSpot::activate(const QString& actionName) +void UrlFilter::HotSpot::activate(const QString &actionName) { QString url = capturedTexts().constFirst(); const UrlType kind = urlType(); - if ( actionName == QLatin1String("copy-action") ) - { + if (actionName == QLatin1String("copy-action")) { QApplication::clipboard()->setText(url); return; } - if ( actionName.isEmpty() || actionName == QLatin1String("open-action") || actionName == QLatin1String("click-action") ) - { - if ( kind == StandardUrl ) - { + if (actionName.isEmpty() || actionName == QLatin1String("open-action") + || actionName == QLatin1String("click-action")) { + if (kind == StandardUrl) { // if the URL path does not include the protocol ( eg. "www.kde.org" ) then // prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" ) - if (!url.contains(QLatin1String("://"))) - { + if (!url.contains(QLatin1String("://"))) { url.prepend(QLatin1String("http://")); } - } - else if ( kind == Email ) - { + } else if (kind == Email) { url.prepend(QLatin1String("mailto:")); } - _urlObject->emitActivated(QUrl(url, QUrl::StrictMode), actionName != QLatin1String("click-action")); + _urlObject->emitActivated(QUrl(url, QUrl::StrictMode), + actionName != QLatin1String("click-action")); } } -// Note: Altering these regular expressions can have a major effect on the performance of the filters -// used for finding URLs in the text, especially if they are very general and could match very long -// pieces of text. -// Please be careful when altering them. +// Note: Altering these regular expressions can have a major effect on the performance of the +// filters used for finding URLs in the text, especially if they are very general and could match +// very long pieces of text. Please be careful when altering them. -//regexp matches: +// regexp matches: // full url: -// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot -const QRegExp UrlFilter::FullUrlRegExp(QLatin1String("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]")); +// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends +// before whitespaces, <, >, ', ", ], !, comma and dot +const QRegExp UrlFilter::FullUrlRegExp( + QLatin1String("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]")); // email address: // [word chars, dots or dashes]@[word chars, dots or dashes].[word chars] -const QRegExp UrlFilter::EmailAddressRegExp(QLatin1String("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b")); +const QRegExp + UrlFilter::EmailAddressRegExp(QLatin1String("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b")); // matches full url or email address -const QRegExp UrlFilter::CompleteUrlRegExp(QLatin1Char('(')+FullUrlRegExp.pattern()+QLatin1Char('|')+ - EmailAddressRegExp.pattern()+QLatin1Char(')')); +const QRegExp UrlFilter::CompleteUrlRegExp(QLatin1Char('(') + FullUrlRegExp.pattern() + + QLatin1Char('|') + EmailAddressRegExp.pattern() + + QLatin1Char(')')); UrlFilter::UrlFilter() { - setRegExp( CompleteUrlRegExp ); + setRegExp(CompleteUrlRegExp); } UrlFilter::HotSpot::~HotSpot() @@ -484,7 +456,7 @@ UrlFilter::HotSpot::~HotSpot() delete _urlObject; } -void FilterObject::emitActivated(const QUrl& url, bool fromContextMenu) +void FilterObject::emitActivated(const QUrl &url, bool fromContextMenu) { emit activated(url, fromContextMenu); } @@ -494,29 +466,27 @@ void FilterObject::activate() _filter->activate(sender()->objectName()); } -FilterObject* UrlFilter::HotSpot::getUrlObject() const +FilterObject *UrlFilter::HotSpot::getUrlObject() const { return _urlObject; } -QList UrlFilter::HotSpot::actions() +QList UrlFilter::HotSpot::actions() { - QList list; + QList list; const UrlType kind = urlType(); - QAction* openAction = new QAction(_urlObject); - QAction* copyAction = new QAction(_urlObject);; + QAction *openAction = new QAction(_urlObject); + QAction *copyAction = new QAction(_urlObject); + ; - Q_ASSERT( kind == StandardUrl || kind == Email ); + Q_ASSERT(kind == StandardUrl || kind == Email); - if ( kind == StandardUrl ) - { + if (kind == StandardUrl) { openAction->setText(QObject::tr("Open Link")); copyAction->setText(QObject::tr("Copy Link Address")); - } - else if ( kind == Email ) - { + } else if (kind == Email) { openAction->setText(QObject::tr("Send Email To...")); copyAction->setText(QObject::tr("Copy Email Address")); } @@ -524,11 +494,11 @@ QList UrlFilter::HotSpot::actions() // object names are set here so that the hotspot performs the // correct action when activated() is called with the triggered // action passed as a parameter. - openAction->setObjectName( QLatin1String("open-action" )); - copyAction->setObjectName( QLatin1String("copy-action" )); + openAction->setObjectName(QLatin1String("open-action")); + copyAction->setObjectName(QLatin1String("copy-action")); - QObject::connect( openAction , &QAction::triggered , _urlObject , &FilterObject::activate ); - QObject::connect( copyAction , &QAction::triggered , _urlObject , &FilterObject::activate ); + QObject::connect(openAction, &QAction::triggered, _urlObject, &FilterObject::activate); + QObject::connect(copyAction, &QAction::triggered, _urlObject, &FilterObject::activate); list << openAction; list << copyAction; diff --git a/lib/Filter.h b/lib/Filter.h index 5da1242b..bcd93620 100644 --- a/lib/Filter.h +++ b/lib/Filter.h @@ -31,104 +31,106 @@ // Local #include "qtermwidget_export.h" -namespace Konsole -{ +namespace Konsole { typedef unsigned char LineProperty; class Character; /** - * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list) - * and marks the areas which match the filter's patterns as 'hotspots'. + * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a + * list) and marks the areas which match the filter's patterns as 'hotspots'. * - * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ), - * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact - * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's - * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response. + * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section + * ), and an action. When the user performs some activity such as a mouse-click in a hotspot area ( + * the exact action will depend on what is displaying the block of text which the filter is + * processing ), the hotspot's activate() method should be called. Depending on the type of hotspot + * this will trigger a suitable response. * - * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser. - * Hotspots may have more than one action, in which case the list of actions can be obtained using the - * actions() method. + * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a + * web browser. Hotspots may have more than one action, in which case the list of actions can be + * obtained using the actions() method. * * Different subclasses of filter will return different types of hotspot. - * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest. - * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest - * and add them to the filter's list of hotspots using addHotSpot() + * Subclasses must reimplement the process() method to examine a block of text and identify sections + * of interest. When processing the text they should create instances of Filter::HotSpot subclasses + * for sections of interest and add them to the filter's list of hotspots using addHotSpot() */ class QTERMWIDGET_EXPORT Filter : public QObject { public: /** - * Represents an area of text which matched the pattern a particular filter has been looking for. - * - * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ), - * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact - * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's - * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response. - * - * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser. - * Hotspots may have more than one action, in which case the list of actions can be obtained using the - * actions() method. These actions may then be displayed in a popup menu or toolbar for example. - */ + * Represents an area of text which matched the pattern a particular filter has been looking + * for. + * + * Each hotspot has a type identifier associated with it ( such as a link or a highlighted + * section ), and an action. When the user performs some activity such as a mouse-click in a + * hotspot area ( the exact action will depend on what is displaying the block of text which the + * filter is processing ), the hotspot's activate() method should be called. Depending on the + * type of hotspot this will trigger a suitable response. + * + * For example, if a hotspot represents a URL then a suitable action would be opening that URL + * in a web browser. Hotspots may have more than one action, in which case the list of actions + * can be obtained using the actions() method. These actions may then be displayed in a popup + * menu or toolbar for example. + */ class HotSpot { public: - /** - * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn) - * in a block of text. - */ - HotSpot(int startLine , int startColumn , int endLine , int endColumn); - virtual ~HotSpot(); - - enum Type - { + /** + * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p + * endLine,@p endColumn) in a block of text. + */ + HotSpot(int startLine, int startColumn, int endLine, int endColumn); + virtual ~HotSpot(); + + enum Type { // the type of the hotspot is not specified NotSpecified, // this hotspot represents a clickable link Link, // this hotspot represents a marker Marker - }; - - /** Returns the line when the hotspot area starts */ - int startLine() const; - /** Returns the line where the hotspot area ends */ - int endLine() const; - /** Returns the column on startLine() where the hotspot area starts */ - int startColumn() const; - /** Returns the column on endLine() where the hotspot area ends */ - int endColumn() const; - /** - * Returns the type of the hotspot. This is usually used as a hint for views on how to represent - * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them - */ - Type type() const; - /** - * Causes the an action associated with a hotspot to be triggered. - * - * @param action The action to trigger. This is - * typically empty ( in which case the default action should be performed ) or - * one of the object names from the actions() list. In which case the associated - * action should be performed. - */ - virtual void activate(const QString& action = QString()) = 0; - /** - * Returns a list of actions associated with the hotspot which can be used in a - * menu or toolbar - */ - virtual QList actions(); + }; + + /** Returns the line when the hotspot area starts */ + int startLine() const; + /** Returns the line where the hotspot area ends */ + int endLine() const; + /** Returns the column on startLine() where the hotspot area starts */ + int startColumn() const; + /** Returns the column on endLine() where the hotspot area ends */ + int endColumn() const; + /** + * Returns the type of the hotspot. This is usually used as a hint for views on how to + * represent the hotspot graphically. eg. Link hotspots are typically underlined when the + * user mouses over them + */ + Type type() const; + /** + * Causes the an action associated with a hotspot to be triggered. + * + * @param action The action to trigger. This is + * typically empty ( in which case the default action should be performed ) or + * one of the object names from the actions() list. In which case the associated + * action should be performed. + */ + virtual void activate(const QString &action = QString()) = 0; + /** + * Returns a list of actions associated with the hotspot which can be used in a + * menu or toolbar + */ + virtual QList actions(); protected: - /** Sets the type of a hotspot. This should only be set once */ - void setType(Type type); + /** Sets the type of a hotspot. This should only be set once */ + void setType(Type type); private: - int _startLine; - int _startColumn; - int _endLine; - int _endColumn; - Type _type; - + int _startLine; + int _startColumn; + int _endLine; + int _endColumn; + Type _type; }; /** Constructs a new filter. */ @@ -145,62 +147,64 @@ class QTERMWIDGET_EXPORT Filter : public QObject void reset(); /** Adds a new line of text to the filter and increments the line count */ - //void addLine(const QString& string); + // void addLine(const QString& string); - /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */ - HotSpot* hotSpotAt(int line , int column) const; + /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers + * that area */ + HotSpot *hotSpotAt(int line, int column) const; /** Returns the list of hotspots identified by the filter */ - QList hotSpots() const; + QList hotSpots() const; /** Returns the list of hotspots identified by the filter which occur on a given line */ - QList hotSpotsAtLine(int line) const; + QList hotSpotsAtLine(int line) const; /** * TODO: Document me */ - void setBuffer(const QString* buffer , const QList* linePositions); + void setBuffer(const QString *buffer, const QList *linePositions); protected: /** Adds a new hotspot to the list */ - void addHotSpot(HotSpot*); + void addHotSpot(HotSpot *); /** Returns the internal buffer */ - const QString* buffer(); + const QString *buffer(); /** Converts a character position within buffer() to a line and column */ - void getLineColumn(int position , int& startLine , int& startColumn); + void getLineColumn(int position, int &startLine, int &startColumn); private: - QMultiHash _hotspots; - QList _hotspotList; + QMultiHash _hotspots; + QList _hotspotList; - const QList* _linePositions; - const QString* _buffer; + const QList *_linePositions; + const QString *_buffer; }; /** - * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot - * instance for them. + * A filter which searches for sections of text matching a regular expression and creates a new + * RegExpFilter::HotSpot instance for them. * - * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression - * are found. + * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the + * regular expression are found. */ class QTERMWIDGET_EXPORT RegExpFilter : public Filter { public: /** - * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text - * matched by the filter's regular expression. + * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the + * text matched by the filter's regular expression. */ class HotSpot : public Filter::HotSpot { public: - HotSpot(int startLine, int startColumn, int endLine , int endColumn); - void activate(const QString& action = QString()) override; + HotSpot(int startLine, int startColumn, int endLine, int endColumn); + void activate(const QString &action = QString()) override; /** Sets the captured texts associated with this hotspot */ - void setCapturedTexts(const QStringList& texts); + void setCapturedTexts(const QStringList &texts); /** Returns the texts found by the filter when matching the filter's regular expression */ QStringList capturedTexts() const; + private: QStringList _capturedTexts; }; @@ -214,7 +218,7 @@ class QTERMWIDGET_EXPORT RegExpFilter : public Filter * Regular expressions which match the empty string are treated as not matching * anything. */ - void setRegExp(const QRegExp& text); + void setRegExp(const QRegExp &text); /** Returns the regular expression which the filter searches for in blocks of text */ QRegExp regExp() const; @@ -228,11 +232,11 @@ class QTERMWIDGET_EXPORT RegExpFilter : public Filter protected: /** - * Called when a match for the regular expression is encountered. Subclasses should reimplement this - * to return custom hotspot types + * Called when a match for the regular expression is encountered. Subclasses should reimplement + * this to return custom hotspot types */ - virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn, - int endLine,int endColumn); + virtual RegExpFilter::HotSpot *newHotSpot(int startLine, int startColumn, int endLine, + int endColumn); private: QRegExp _searchText; @@ -252,60 +256,55 @@ class QTERMWIDGET_EXPORT UrlFilter : public RegExpFilter class HotSpot : public RegExpFilter::HotSpot { public: - HotSpot(int startLine,int startColumn,int endLine,int endColumn); + HotSpot(int startLine, int startColumn, int endLine, int endColumn); ~HotSpot() override; - FilterObject* getUrlObject() const; + FilterObject *getUrlObject() const; - QList actions() override; + QList actions() override; /** * Open a web browser at the current URL. The url itself can be determined using * the capturedTexts() method. */ - void activate(const QString& action = QString()) override; + void activate(const QString &action = QString()) override; private: - enum UrlType - { - StandardUrl, - Email, - Unknown - }; + enum UrlType { StandardUrl, Email, Unknown }; UrlType urlType() const; - FilterObject* _urlObject; + FilterObject *_urlObject; }; UrlFilter(); protected: - RegExpFilter::HotSpot* newHotSpot(int,int,int,int) override; + RegExpFilter::HotSpot *newHotSpot(int, int, int, int) override; private: - static const QRegExp FullUrlRegExp; static const QRegExp EmailAddressRegExp; // combined OR of FullUrlRegExp and EmailAddressRegExp static const QRegExp CompleteUrlRegExp; signals: - void activated(const QUrl& url, bool fromContextMenu); + void activated(const QUrl &url, bool fromContextMenu); }; class QTERMWIDGET_NO_EXPORT FilterObject : public QObject { Q_OBJECT public: - FilterObject(Filter::HotSpot* filter) : _filter(filter) {} + FilterObject(Filter::HotSpot *filter) : _filter(filter) { } - void emitActivated(const QUrl& url, bool fromContextMenu); + void emitActivated(const QUrl &url, bool fromContextMenu); public slots: void activate(); + private: - Filter::HotSpot* _filter; + Filter::HotSpot *_filter; signals: - void activated(const QUrl& url, bool fromContextMenu); + void activated(const QUrl &url, bool fromContextMenu); }; /** @@ -325,17 +324,18 @@ public slots: * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on * a given line respectively. */ -class QTERMWIDGET_EXPORT FilterChain : protected QList +class QTERMWIDGET_EXPORT FilterChain : protected QList { public: virtual ~FilterChain(); /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */ - void addFilter(Filter* filter); - /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */ - void removeFilter(Filter* filter); + void addFilter(Filter *filter); + /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed + */ + void removeFilter(Filter *filter); /** Returns true if the chain contains @p filter */ - bool containsFilter(Filter* filter); + bool containsFilter(Filter *filter); /** Removes all filters from the chain */ void clear(); @@ -347,15 +347,14 @@ class QTERMWIDGET_EXPORT FilterChain : protected QList void process(); /** Sets the buffer for each filter in the chain to process. */ - void setBuffer(const QString* buffer , const QList* linePositions); + void setBuffer(const QString *buffer, const QList *linePositions); /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */ - Filter::HotSpot* hotSpotAt(int line , int column) const; + Filter::HotSpot *hotSpotAt(int line, int column) const; /** Returns a list of all the hotspots in all the chain's filters */ - QList hotSpots() const; + QList hotSpots() const; /** Returns a list of all hotspots at the given line in all the chain's filters */ QList hotSpotsAtLine(int line) const; - }; /** A filter chain which processes character images from terminal displays */ @@ -373,16 +372,16 @@ class QTERMWIDGET_NO_EXPORT TerminalImageFilterChain : public FilterChain * @param columns The number of columns in the terminal image * @param lineProperties The line properties to set for image */ - void setImage(const Character* const image , int lines , int columns, - const QVector& lineProperties); + void setImage(const Character *const image, int lines, int columns, + const QVector &lineProperties); private: - QString* _buffer; - QList* _linePositions; + QString *_buffer; + QList *_linePositions; }; } typedef Konsole::Filter Filter; -#endif //FILTER_H +#endif // FILTER_H diff --git a/lib/History.cpp b/lib/History.cpp index ec3536bd..abd51561 100644 --- a/lib/History.cpp +++ b/lib/History.cpp @@ -38,7 +38,7 @@ //#include // Reasonable line size -#define LINE_SIZE 1024 +#define LINE_SIZE 1024 #define KDE_lseek lseek using namespace Konsole; @@ -76,7 +76,7 @@ FIXME: There is noticeable decrease in speed, also. Perhaps, scheme with wrap around would be it's complexity. */ -//FIXME: tempory replacement for tmpfile +// FIXME: tempory replacement for tmpfile // this is here one for debugging purpose. //#define tmpfile xTmpFile @@ -87,17 +87,12 @@ FIXME: There is noticeable decrease in speed, also. Perhaps, A Row(X) data type which allows adding elements to the end. */ -HistoryFile::HistoryFile() - : ion(-1), - length(0), - fileMap(nullptr), - readWriteBalance(0) +HistoryFile::HistoryFile() : ion(-1), length(0), fileMap(nullptr), readWriteBalance(0) { - if (tmpFile.open()) - { - tmpFile.setAutoRemove(true); - ion = tmpFile.handle(); - } + if (tmpFile.open()) { + tmpFile.setAutoRemove(true); + ion = tmpFile.handle(); + } } HistoryFile::~HistoryFile() @@ -106,28 +101,28 @@ HistoryFile::~HistoryFile() unmap(); } -//TODO: Mapping the entire file in will cause problems if the history file becomes exceedingly large, -//(ie. larger than available memory). HistoryFile::map() should only map in sections of the file at a time, -//to avoid this. +// TODO: Mapping the entire file in will cause problems if the history file becomes exceedingly +// large, (ie. larger than available memory). HistoryFile::map() should only map in sections of the +//file at a time, to avoid this. void HistoryFile::map() { - Q_ASSERT( fileMap == nullptr ); + Q_ASSERT(fileMap == nullptr); - fileMap = (char*)mmap( nullptr , length , PROT_READ , MAP_PRIVATE , ion , 0 ); + fileMap = (char *)mmap(nullptr, length, PROT_READ, MAP_PRIVATE, ion, 0); - //if mmap'ing fails, fall back to the read-lseek combination - if ( fileMap == MAP_FAILED ) - { - readWriteBalance = 0; - fileMap = nullptr; - //qDebug() << __FILE__ << __LINE__ << ": mmap'ing history failed. errno = " << errno; + // if mmap'ing fails, fall back to the read-lseek combination + if (fileMap == MAP_FAILED) { + readWriteBalance = 0; + fileMap = nullptr; + // qDebug() << __FILE__ << __LINE__ << ": mmap'ing history failed. errno = " << errno; } } void HistoryFile::unmap() { - int result = munmap( fileMap , length ); - Q_ASSERT( result == 0 ); Q_UNUSED( result ); + int result = munmap(fileMap, length); + Q_ASSERT(result == 0); + Q_UNUSED(result); fileMap = nullptr; } @@ -137,68 +132,76 @@ bool HistoryFile::isMapped() const return (fileMap != nullptr); } -void HistoryFile::add(const unsigned char* bytes, int len) +void HistoryFile::add(const unsigned char *bytes, int len) { - if ( fileMap ) - unmap(); - - readWriteBalance++; - - int rc = 0; - - rc = KDE_lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryFile::add.seek"); return; } - rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryFile::add.write"); return; } - length += rc; -} + if (fileMap) + unmap(); -void HistoryFile::get(unsigned char* bytes, int len, int loc) -{ - //count number of get() calls vs. number of add() calls. - //If there are many more get() calls compared with add() - //calls (decided by using MAP_THRESHOLD) then mmap the log - //file to improve performance. - readWriteBalance--; - if ( !fileMap && readWriteBalance < MAP_THRESHOLD ) - map(); + readWriteBalance++; - if ( fileMap ) - { - for (int i=0;i length) - fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc); - rc = KDE_lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryFile::get.seek"); return; } - rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryFile::get.read"); return; } - } + rc = KDE_lseek(ion, length, SEEK_SET); + if (rc < 0) { + perror("HistoryFile::add.seek"); + return; + } + rc = write(ion, bytes, len); + if (rc < 0) { + perror("HistoryFile::add.write"); + return; + } + length += rc; +} + +void HistoryFile::get(unsigned char *bytes, int len, int loc) +{ + // count number of get() calls vs. number of add() calls. + // If there are many more get() calls compared with add() + // calls (decided by using MAP_THRESHOLD) then mmap the log + // file to improve performance. + readWriteBalance--; + if (!fileMap && readWriteBalance < MAP_THRESHOLD) + map(); + + if (fileMap) { + for (int i = 0; i < len; i++) + bytes[i] = fileMap[loc + i]; + } else { + int rc = 0; + + if (loc < 0 || len < 0 || loc + len > length) + fprintf(stderr, "getHist(...,%d,%d): invalid args.\n", len, loc); + rc = KDE_lseek(ion, loc, SEEK_SET); + if (rc < 0) { + perror("HistoryFile::get.seek"); + return; + } + rc = read(ion, bytes, len); + if (rc < 0) { + perror("HistoryFile::get.read"); + return; + } + } } int HistoryFile::len() { - return length; + return length; } - // History Scroll abstract base class ////////////////////////////////////// - -HistoryScroll::HistoryScroll(HistoryType* t) - : m_histType(t) -{ -} +HistoryScroll::HistoryScroll(HistoryType *t) : m_histType(t) { } HistoryScroll::~HistoryScroll() { - delete m_histType; + delete m_histType; } bool HistoryScroll::hasScroll() { - return true; + return true; } // History Scroll File ////////////////////////////////////// @@ -215,82 +218,80 @@ bool HistoryScroll::hasScroll() */ HistoryScrollFile::HistoryScrollFile(const QString &logFileName) - : HistoryScroll(new HistoryTypeFile(logFileName)), - m_logFileName(logFileName) + : HistoryScroll(new HistoryTypeFile(logFileName)), m_logFileName(logFileName) { } -HistoryScrollFile::~HistoryScrollFile() -{ -} +HistoryScrollFile::~HistoryScrollFile() { } int HistoryScrollFile::getLines() { - return index.len() / sizeof(int); + return index.len() / sizeof(int); } int HistoryScrollFile::getLineLen(int lineno) { - return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(Character); + return (startOfLine(lineno + 1) - startOfLine(lineno)) / sizeof(Character); } bool HistoryScrollFile::isWrappedLine(int lineno) { - if (lineno>=0 && lineno <= getLines()) { - unsigned char flag; - lineflags.get((unsigned char*)&flag,sizeof(unsigned char),(lineno)*sizeof(unsigned char)); - return flag; - } - return false; + if (lineno >= 0 && lineno <= getLines()) { + unsigned char flag; + lineflags.get((unsigned char *)&flag, sizeof(unsigned char), + (lineno) * sizeof(unsigned char)); + return flag; + } + return false; } int HistoryScrollFile::startOfLine(int lineno) { - if (lineno <= 0) return 0; - if (lineno <= getLines()) - { + if (lineno <= 0) + return 0; + if (lineno <= getLines()) { - if (!index.isMapped()) + if (!index.isMapped()) index.map(); - int res; - index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int)); - return res; + int res; + index.get((unsigned char *)&res, sizeof(int), (lineno - 1) * sizeof(int)); + return res; } - return cells.len(); + return cells.len(); } void HistoryScrollFile::getCells(int lineno, int colno, int count, Character res[]) { - cells.get((unsigned char*)res,count*sizeof(Character),startOfLine(lineno)+colno*sizeof(Character)); + cells.get((unsigned char *)res, count * sizeof(Character), + startOfLine(lineno) + colno * sizeof(Character)); } void HistoryScrollFile::addCells(const Character text[], int count) { - cells.add((unsigned char*)text,count*sizeof(Character)); + cells.add((unsigned char *)text, count * sizeof(Character)); } void HistoryScrollFile::addLine(bool previousWrapped) { - if (index.isMapped()) - index.unmap(); + if (index.isMapped()) + index.unmap(); - int locn = cells.len(); - index.add((unsigned char*)&locn,sizeof(int)); - unsigned char flags = previousWrapped ? 0x01 : 0x00; - lineflags.add((unsigned char*)&flags,sizeof(unsigned char)); + int locn = cells.len(); + index.add((unsigned char *)&locn, sizeof(int)); + unsigned char flags = previousWrapped ? 0x01 : 0x00; + lineflags.add((unsigned char *)&flags, sizeof(unsigned char)); } - // History Scroll Buffer ////////////////////////////////////// HistoryScrollBuffer::HistoryScrollBuffer(unsigned int maxLineCount) - : HistoryScroll(new HistoryTypeBuffer(maxLineCount)) - ,_historyBuffer() - ,_maxLineCount(0) - ,_usedLines(0) - ,_head(0) + : HistoryScroll(new HistoryTypeBuffer(maxLineCount)), + _historyBuffer(), + _maxLineCount(0), + _usedLines(0), + _head(0) { - setMaxNbLines(maxLineCount); + setMaxNbLines(maxLineCount); } HistoryScrollBuffer::~HistoryScrollBuffer() @@ -298,31 +299,30 @@ HistoryScrollBuffer::~HistoryScrollBuffer() delete[] _historyBuffer; } -void HistoryScrollBuffer::addCellsVector(const QVector& cells) +void HistoryScrollBuffer::addCellsVector(const QVector &cells) { _head++; - if ( _usedLines < _maxLineCount ) + if (_usedLines < _maxLineCount) _usedLines++; - if ( _head >= _maxLineCount ) - { + if (_head >= _maxLineCount) { _head = 0; } - _historyBuffer[bufferIndex(_usedLines-1)] = cells; - _wrappedLine[bufferIndex(_usedLines-1)] = false; + _historyBuffer[bufferIndex(_usedLines - 1)] = cells; + _wrappedLine[bufferIndex(_usedLines - 1)] = false; } void HistoryScrollBuffer::addCells(const Character a[], int count) { - HistoryLine newLine(count); - std::copy(a,a+count,newLine.begin()); + HistoryLine newLine(count); + std::copy(a, a + count, newLine.begin()); - addCellsVector(newLine); + addCellsVector(newLine); } void HistoryScrollBuffer::addLine(bool previousWrapped) { - _wrappedLine[bufferIndex(_usedLines-1)] = previousWrapped; + _wrappedLine[bufferIndex(_usedLines - 1)] = previousWrapped; } int HistoryScrollBuffer::getLines() @@ -332,155 +332,133 @@ int HistoryScrollBuffer::getLines() int HistoryScrollBuffer::getLineLen(int lineNumber) { - Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount ); + Q_ASSERT(lineNumber >= 0 && lineNumber < _maxLineCount); - if ( lineNumber < _usedLines ) - { - return _historyBuffer[bufferIndex(lineNumber)].size(); - } - else - { - return 0; - } + if (lineNumber < _usedLines) { + return _historyBuffer[bufferIndex(lineNumber)].size(); + } else { + return 0; + } } bool HistoryScrollBuffer::isWrappedLine(int lineNumber) { - Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount ); + Q_ASSERT(lineNumber >= 0 && lineNumber < _maxLineCount); - if (lineNumber < _usedLines) - { - //kDebug() << "Line" << lineNumber << "wrapped is" << _wrappedLine[bufferIndex(lineNumber)]; - return _wrappedLine[bufferIndex(lineNumber)]; - } - else - return false; + if (lineNumber < _usedLines) { + // kDebug() << "Line" << lineNumber << "wrapped is" << + // _wrappedLine[bufferIndex(lineNumber)]; + return _wrappedLine[bufferIndex(lineNumber)]; + } else + return false; } void HistoryScrollBuffer::getCells(int lineNumber, int startColumn, int count, Character buffer[]) { - if ( count == 0 ) return; + if (count == 0) + return; - Q_ASSERT( lineNumber < _maxLineCount ); + Q_ASSERT(lineNumber < _maxLineCount); - if (lineNumber >= _usedLines) - { - memset(static_cast(buffer), 0, count * sizeof(Character)); - return; - } + if (lineNumber >= _usedLines) { + memset(static_cast(buffer), 0, count * sizeof(Character)); + return; + } - const HistoryLine& line = _historyBuffer[bufferIndex(lineNumber)]; + const HistoryLine &line = _historyBuffer[bufferIndex(lineNumber)]; - //kDebug() << "startCol " << startColumn; - //kDebug() << "line.size() " << line.size(); - //kDebug() << "count " << count; + // kDebug() << "startCol " << startColumn; + // kDebug() << "line.size() " << line.size(); + // kDebug() << "count " << count; - Q_ASSERT( startColumn <= line.size() - count ); + Q_ASSERT(startColumn <= line.size() - count); - memcpy(buffer, line.constData() + startColumn , count * sizeof(Character)); + memcpy(buffer, line.constData() + startColumn, count * sizeof(Character)); } void HistoryScrollBuffer::setMaxNbLines(unsigned int lineCount) { - HistoryLine* oldBuffer = _historyBuffer; - HistoryLine* newBuffer = new HistoryLine[lineCount]; + HistoryLine *oldBuffer = _historyBuffer; + HistoryLine *newBuffer = new HistoryLine[lineCount]; - for ( int i = 0 ; i < qMin(_usedLines,(int)lineCount) ; i++ ) - { + for (int i = 0; i < qMin(_usedLines, (int)lineCount); i++) { newBuffer[i] = oldBuffer[bufferIndex(i)]; } - _usedLines = qMin(_usedLines,(int)lineCount); + _usedLines = qMin(_usedLines, (int)lineCount); _maxLineCount = lineCount; - _head = ( _usedLines == _maxLineCount ) ? 0 : _usedLines-1; + _head = (_usedLines == _maxLineCount) ? 0 : _usedLines - 1; _historyBuffer = newBuffer; delete[] oldBuffer; _wrappedLine.resize(lineCount); - dynamic_cast(m_histType)->m_nbLines = lineCount; + dynamic_cast(m_histType)->m_nbLines = lineCount; } int HistoryScrollBuffer::bufferIndex(int lineNumber) const { - Q_ASSERT( lineNumber >= 0 ); - Q_ASSERT( lineNumber < _maxLineCount ); - Q_ASSERT( (_usedLines == _maxLineCount) || lineNumber <= _head ); + Q_ASSERT(lineNumber >= 0); + Q_ASSERT(lineNumber < _maxLineCount); + Q_ASSERT((_usedLines == _maxLineCount) || lineNumber <= _head); - if ( _usedLines == _maxLineCount ) - { - return (_head+lineNumber+1) % _maxLineCount; - } - else - { + if (_usedLines == _maxLineCount) { + return (_head + lineNumber + 1) % _maxLineCount; + } else { return lineNumber; } } - // History Scroll None ////////////////////////////////////// -HistoryScrollNone::HistoryScrollNone() - : HistoryScroll(new HistoryTypeNone()) -{ -} +HistoryScrollNone::HistoryScrollNone() : HistoryScroll(new HistoryTypeNone()) { } -HistoryScrollNone::~HistoryScrollNone() -{ -} +HistoryScrollNone::~HistoryScrollNone() { } bool HistoryScrollNone::hasScroll() { - return false; + return false; } -int HistoryScrollNone::getLines() +int HistoryScrollNone::getLines() { - return 0; + return 0; } -int HistoryScrollNone::getLineLen(int) +int HistoryScrollNone::getLineLen(int) { - return 0; + return 0; } bool HistoryScrollNone::isWrappedLine(int /*lineno*/) { - return false; + return false; } -void HistoryScrollNone::getCells(int, int, int, Character []) -{ -} +void HistoryScrollNone::getCells(int, int, int, Character[]) { } -void HistoryScrollNone::addCells(const Character [], int) -{ -} +void HistoryScrollNone::addCells(const Character[], int) { } -void HistoryScrollNone::addLine(bool) -{ -} +void HistoryScrollNone::addLine(bool) { } // History Scroll BlockArray ////////////////////////////////////// HistoryScrollBlockArray::HistoryScrollBlockArray(size_t size) - : HistoryScroll(new HistoryTypeBlockArray(size)) + : HistoryScroll(new HistoryTypeBlockArray(size)) { - m_blockArray.setHistorySize(size); // nb. of lines. + m_blockArray.setHistorySize(size); // nb. of lines. } -HistoryScrollBlockArray::~HistoryScrollBlockArray() -{ -} +HistoryScrollBlockArray::~HistoryScrollBlockArray() { } -int HistoryScrollBlockArray::getLines() +int HistoryScrollBlockArray::getLines() { - return m_lineLengths.count(); + return m_lineLengths.count(); } -int HistoryScrollBlockArray::getLineLen(int lineno) +int HistoryScrollBlockArray::getLineLen(int lineno) { - if ( m_lineLengths.contains(lineno) ) + if (m_lineLengths.contains(lineno)) return m_lineLengths[lineno]; else return 0; @@ -488,500 +466,456 @@ int HistoryScrollBlockArray::getLineLen(int lineno) bool HistoryScrollBlockArray::isWrappedLine(int /*lineno*/) { - return false; + return false; } -void HistoryScrollBlockArray::getCells(int lineno, int colno, - int count, Character res[]) +void HistoryScrollBlockArray::getCells(int lineno, int colno, int count, Character res[]) { - if (!count) return; + if (!count) + return; - const Block *b = m_blockArray.at(lineno); + const Block *b = m_blockArray.at(lineno); - if (!b) { - memset(static_cast(res), 0, count * sizeof(Character)); // still better than random data - return; - } + if (!b) { + memset(static_cast(res), 0, + count * sizeof(Character)); // still better than random data + return; + } - Q_ASSERT(((colno + count) * sizeof(Character)) < ENTRIES); - memcpy(res, b->data + (colno * sizeof(Character)), count * sizeof(Character)); + Q_ASSERT(((colno + count) * sizeof(Character)) < ENTRIES); + memcpy(res, b->data + (colno * sizeof(Character)), count * sizeof(Character)); } void HistoryScrollBlockArray::addCells(const Character a[], int count) { - Block *b = m_blockArray.lastBlock(); + Block *b = m_blockArray.lastBlock(); - if (!b) return; + if (!b) + return; - // put cells in block's data - Q_ASSERT((count * sizeof(Character)) < ENTRIES); + // put cells in block's data + Q_ASSERT((count * sizeof(Character)) < ENTRIES); - memset(b->data, 0, sizeof(b->data)); + memset(b->data, 0, sizeof(b->data)); - memcpy(b->data, a, count * sizeof(Character)); - b->size = count * sizeof(Character); + memcpy(b->data, a, count * sizeof(Character)); + b->size = count * sizeof(Character); - size_t res = m_blockArray.newBlock(); - Q_ASSERT(res > 0); - Q_UNUSED( res ); + size_t res = m_blockArray.newBlock(); + Q_ASSERT(res > 0); + Q_UNUSED(res); - m_lineLengths.insert(m_blockArray.getCurrent(), count); + m_lineLengths.insert(m_blockArray.getCurrent(), count); } -void HistoryScrollBlockArray::addLine(bool) -{ -} +void HistoryScrollBlockArray::addLine(bool) { } //////////////////////////////////////////////////////////////// // Compact History Scroll ////////////////////////////////////// //////////////////////////////////////////////////////////////// -void* CompactHistoryBlock::allocate ( size_t length ) +void *CompactHistoryBlock::allocate(size_t length) { - Q_ASSERT ( length > 0 ); - if ( tail-blockStart+length > blockLength ) - return nullptr; + Q_ASSERT(length > 0); + if (tail - blockStart + length > blockLength) + return nullptr; - void* block = tail; - tail += length; - //kDebug() << "allocated " << length << " bytes at address " << block; - allocCount++; - return block; + void *block = tail; + tail += length; + // kDebug() << "allocated " << length << " bytes at address " << block; + allocCount++; + return block; } -void CompactHistoryBlock::deallocate ( ) +void CompactHistoryBlock::deallocate() { - allocCount--; - Q_ASSERT ( allocCount >= 0 ); + allocCount--; + Q_ASSERT(allocCount >= 0); } -void* CompactHistoryBlockList::allocate(size_t size) +void *CompactHistoryBlockList::allocate(size_t size) { - CompactHistoryBlock* block; - if ( list.isEmpty() || list.last()->remaining() < size) - { - block = new CompactHistoryBlock(); - list.append ( block ); - //kDebug() << "new block created, remaining " << block->remaining() << "number of blocks=" << list.size(); - } - else - { - block = list.last(); - //kDebug() << "old block used, remaining " << block->remaining(); - } - return block->allocate(size); + CompactHistoryBlock *block; + if (list.isEmpty() || list.last()->remaining() < size) { + block = new CompactHistoryBlock(); + list.append(block); + // kDebug() << "new block created, remaining " << block->remaining() << "number of blocks=" + // << list.size(); + } else { + block = list.last(); + // kDebug() << "old block used, remaining " << block->remaining(); + } + return block->allocate(size); } -void CompactHistoryBlockList::deallocate(void* ptr) +void CompactHistoryBlockList::deallocate(void *ptr) { - Q_ASSERT( !list.isEmpty()); + Q_ASSERT(!list.isEmpty()); - int i=0; - CompactHistoryBlock *block = list.at(i); - while ( icontains(ptr) ) - { - i++; - block=list.at(i); - } + int i = 0; + CompactHistoryBlock *block = list.at(i); + while (i < list.size() && !block->contains(ptr)) { + i++; + block = list.at(i); + } - Q_ASSERT( ideallocate(); + block->deallocate(); - if (!block->isInUse()) - { - list.removeAt(i); - delete block; - //kDebug() << "block deleted, new size = " << list.size(); - } + if (!block->isInUse()) { + list.removeAt(i); + delete block; + // kDebug() << "block deleted, new size = " << list.size(); + } } CompactHistoryBlockList::~CompactHistoryBlockList() { - qDeleteAll ( list.begin(), list.end() ); - list.clear(); -} - -void* CompactHistoryLine::operator new (size_t size, CompactHistoryBlockList& blockList) -{ - return blockList.allocate(size); -} - -CompactHistoryLine::CompactHistoryLine ( const TextLine& line, CompactHistoryBlockList& bList ) - : blockList(bList), - formatLength(0) -{ - length=line.size(); - - if (!line.empty()) { - formatLength=1; - int k=1; - - // count number of different formats in this text line - Character c = line[0]; - while ( k0) { - blockList.deallocate(text); - blockList.deallocate(formatArray); - } - blockList.deallocate(this); + // kDebug() << "~CHL"; + if (length > 0) { + blockList.deallocate(text); + blockList.deallocate(formatArray); + } + blockList.deallocate(this); } -void CompactHistoryLine::getCharacter ( int index, Character &r ) +void CompactHistoryLine::getCharacter(int index, Character &r) { - Q_ASSERT ( index < length ); - int formatPos=0; - while ( ( formatPos+1 ) < formatLength && index >= formatArray[formatPos+1].startPos ) - formatPos++; + Q_ASSERT(index < length); + int formatPos = 0; + while ((formatPos + 1) < formatLength && index >= formatArray[formatPos + 1].startPos) + formatPos++; - r.character=text[index]; - r.rendition = formatArray[formatPos].rendition; - r.foregroundColor = formatArray[formatPos].fgColor; - r.backgroundColor = formatArray[formatPos].bgColor; + r.character = text[index]; + r.rendition = formatArray[formatPos].rendition; + r.foregroundColor = formatArray[formatPos].fgColor; + r.backgroundColor = formatArray[formatPos].bgColor; } -void CompactHistoryLine::getCharacters ( Character* array, int length, int startColumn ) +void CompactHistoryLine::getCharacters(Character *array, int length, int startColumn) { - Q_ASSERT ( startColumn >= 0 && length >= 0 ); - Q_ASSERT ( startColumn+length <= ( int ) getLength() ); + Q_ASSERT(startColumn >= 0 && length >= 0); + Q_ASSERT(startColumn + length <= (int)getLength()); - for ( int i=startColumn; i ( int ) _maxLineCount ) - { - delete lines.takeAt ( 0 ); - } - lines.append ( line ); + if (lines.size() > (int)_maxLineCount) { + delete lines.takeAt(0); + } + lines.append(line); } -void CompactHistoryScroll::addCells ( const Character a[], int count ) +void CompactHistoryScroll::addCells(const Character a[], int count) { - TextLine newLine ( count ); - std::copy ( a,a+count,newLine.begin() ); - addCellsVector ( newLine ); + TextLine newLine(count); + std::copy(a, a + count, newLine.begin()); + addCellsVector(newLine); } -void CompactHistoryScroll::addLine ( bool previousWrapped ) +void CompactHistoryScroll::addLine(bool previousWrapped) { - CompactHistoryLine *line = lines.last(); - //kDebug() << "last line at address " << line; - line->setWrapped(previousWrapped); + CompactHistoryLine *line = lines.last(); + // kDebug() << "last line at address " << line; + line->setWrapped(previousWrapped); } int CompactHistoryScroll::getLines() { - return lines.size(); + return lines.size(); } -int CompactHistoryScroll::getLineLen ( int lineNumber ) +int CompactHistoryScroll::getLineLen(int lineNumber) { - Q_ASSERT ( lineNumber >= 0 && lineNumber < lines.size() ); - CompactHistoryLine* line = lines[lineNumber]; - //kDebug() << "request for line at address " << line; - return line->getLength(); + Q_ASSERT(lineNumber >= 0 && lineNumber < lines.size()); + CompactHistoryLine *line = lines[lineNumber]; + // kDebug() << "request for line at address " << line; + return line->getLength(); } - -void CompactHistoryScroll::getCells ( int lineNumber, int startColumn, int count, Character buffer[] ) +void CompactHistoryScroll::getCells(int lineNumber, int startColumn, int count, Character buffer[]) { - if ( count == 0 ) return; - Q_ASSERT ( lineNumber < lines.size() ); - CompactHistoryLine* line = lines[lineNumber]; - Q_ASSERT ( startColumn >= 0 ); - Q_ASSERT ( (unsigned int)startColumn <= line->getLength() - count ); - line->getCharacters ( buffer, count, startColumn ); + if (count == 0) + return; + Q_ASSERT(lineNumber < lines.size()); + CompactHistoryLine *line = lines[lineNumber]; + Q_ASSERT(startColumn >= 0); + Q_ASSERT((unsigned int)startColumn <= line->getLength() - count); + line->getCharacters(buffer, count, startColumn); } -void CompactHistoryScroll::setMaxNbLines ( unsigned int lineCount ) +void CompactHistoryScroll::setMaxNbLines(unsigned int lineCount) { - _maxLineCount = lineCount; + _maxLineCount = lineCount; - while (lines.size() > (int) lineCount) { - delete lines.takeAt(0); - } - //kDebug() << "set max lines to: " << _maxLineCount; + while (lines.size() > (int)lineCount) { + delete lines.takeAt(0); + } + // kDebug() << "set max lines to: " << _maxLineCount; } -bool CompactHistoryScroll::isWrappedLine ( int lineNumber ) +bool CompactHistoryScroll::isWrappedLine(int lineNumber) { - Q_ASSERT ( lineNumber < lines.size() ); - return lines[lineNumber]->isWrapped(); + Q_ASSERT(lineNumber < lines.size()); + return lines[lineNumber]->isWrapped(); } - ////////////////////////////////////////////////////////////////////// // History Types ////////////////////////////////////////////////////////////////////// -HistoryType::HistoryType() -{ -} +HistoryType::HistoryType() { } -HistoryType::~HistoryType() -{ -} +HistoryType::~HistoryType() { } ////////////////////////////// -HistoryTypeNone::HistoryTypeNone() -{ -} +HistoryTypeNone::HistoryTypeNone() { } bool HistoryTypeNone::isEnabled() const { - return false; + return false; } -HistoryScroll* HistoryTypeNone::scroll(HistoryScroll *old) const +HistoryScroll *HistoryTypeNone::scroll(HistoryScroll *old) const { - delete old; - return new HistoryScrollNone(); + delete old; + return new HistoryScrollNone(); } int HistoryTypeNone::maximumLineCount() const { - return 0; + return 0; } ////////////////////////////// -HistoryTypeBlockArray::HistoryTypeBlockArray(size_t size) - : m_size(size) -{ -} +HistoryTypeBlockArray::HistoryTypeBlockArray(size_t size) : m_size(size) { } bool HistoryTypeBlockArray::isEnabled() const { - return true; + return true; } int HistoryTypeBlockArray::maximumLineCount() const { - return m_size; + return m_size; } -HistoryScroll* HistoryTypeBlockArray::scroll(HistoryScroll *old) const +HistoryScroll *HistoryTypeBlockArray::scroll(HistoryScroll *old) const { - delete old; - return new HistoryScrollBlockArray(m_size); + delete old; + return new HistoryScrollBlockArray(m_size); } - ////////////////////////////// -HistoryTypeBuffer::HistoryTypeBuffer(unsigned int nbLines) - : m_nbLines(nbLines) -{ -} +HistoryTypeBuffer::HistoryTypeBuffer(unsigned int nbLines) : m_nbLines(nbLines) { } bool HistoryTypeBuffer::isEnabled() const { - return true; + return true; } int HistoryTypeBuffer::maximumLineCount() const { - return m_nbLines; -} - -HistoryScroll* HistoryTypeBuffer::scroll(HistoryScroll *old) const -{ - if (old) - { - HistoryScrollBuffer *oldBuffer = dynamic_cast(old); - if (oldBuffer) - { - oldBuffer->setMaxNbLines(m_nbLines); - return oldBuffer; - } - - HistoryScroll *newScroll = new HistoryScrollBuffer(m_nbLines); - int lines = old->getLines(); - int startLine = 0; - if (lines > (int) m_nbLines) - startLine = lines - m_nbLines; - - Character line[LINE_SIZE]; - for(int i = startLine; i < lines; i++) - { - int size = old->getLineLen(i); - if (size > LINE_SIZE) - { - Character *tmp_line = new Character[size]; - old->getCells(i, 0, size, tmp_line); - newScroll->addCells(tmp_line, size); - newScroll->addLine(old->isWrappedLine(i)); - delete [] tmp_line; - } - else - { - old->getCells(i, 0, size, line); - newScroll->addCells(line, size); - newScroll->addLine(old->isWrappedLine(i)); - } + return m_nbLines; +} + +HistoryScroll *HistoryTypeBuffer::scroll(HistoryScroll *old) const +{ + if (old) { + HistoryScrollBuffer *oldBuffer = dynamic_cast(old); + if (oldBuffer) { + oldBuffer->setMaxNbLines(m_nbLines); + return oldBuffer; + } + + HistoryScroll *newScroll = new HistoryScrollBuffer(m_nbLines); + int lines = old->getLines(); + int startLine = 0; + if (lines > (int)m_nbLines) + startLine = lines - m_nbLines; + + Character line[LINE_SIZE]; + for (int i = startLine; i < lines; i++) { + int size = old->getLineLen(i); + if (size > LINE_SIZE) { + Character *tmp_line = new Character[size]; + old->getCells(i, 0, size, tmp_line); + newScroll->addCells(tmp_line, size); + newScroll->addLine(old->isWrappedLine(i)); + delete[] tmp_line; + } else { + old->getCells(i, 0, size, line); + newScroll->addCells(line, size); + newScroll->addLine(old->isWrappedLine(i)); + } + } + delete old; + return newScroll; } - delete old; - return newScroll; - } - return new HistoryScrollBuffer(m_nbLines); + return new HistoryScrollBuffer(m_nbLines); } ////////////////////////////// -HistoryTypeFile::HistoryTypeFile(const QString& fileName) - : m_fileName(fileName) -{ -} +HistoryTypeFile::HistoryTypeFile(const QString &fileName) : m_fileName(fileName) { } bool HistoryTypeFile::isEnabled() const { - return true; + return true; } -const QString& HistoryTypeFile::getFileName() const +const QString &HistoryTypeFile::getFileName() const { - return m_fileName; + return m_fileName; } -HistoryScroll* HistoryTypeFile::scroll(HistoryScroll *old) const +HistoryScroll *HistoryTypeFile::scroll(HistoryScroll *old) const { - if (dynamic_cast(old)) - return old; // Unchanged. + if (dynamic_cast(old)) + return old; // Unchanged. - HistoryScroll *newScroll = new HistoryScrollFile(m_fileName); + HistoryScroll *newScroll = new HistoryScrollFile(m_fileName); - Character line[LINE_SIZE]; - int lines = (old != nullptr) ? old->getLines() : 0; - for(int i = 0; i < lines; i++) - { - int size = old->getLineLen(i); - if (size > LINE_SIZE) - { - Character *tmp_line = new Character[size]; - old->getCells(i, 0, size, tmp_line); - newScroll->addCells(tmp_line, size); - newScroll->addLine(old->isWrappedLine(i)); - delete [] tmp_line; - } - else - { - old->getCells(i, 0, size, line); - newScroll->addCells(line, size); - newScroll->addLine(old->isWrappedLine(i)); - } - } + Character line[LINE_SIZE]; + int lines = (old != nullptr) ? old->getLines() : 0; + for (int i = 0; i < lines; i++) { + int size = old->getLineLen(i); + if (size > LINE_SIZE) { + Character *tmp_line = new Character[size]; + old->getCells(i, 0, size, tmp_line); + newScroll->addCells(tmp_line, size); + newScroll->addLine(old->isWrappedLine(i)); + delete[] tmp_line; + } else { + old->getCells(i, 0, size, line); + newScroll->addCells(line, size); + newScroll->addLine(old->isWrappedLine(i)); + } + } - delete old; - return newScroll; + delete old; + return newScroll; } int HistoryTypeFile::maximumLineCount() const { - return 0; + return 0; } ////////////////////////////// -CompactHistoryType::CompactHistoryType ( unsigned int nbLines ) - : m_nbLines ( nbLines ) -{ -} +CompactHistoryType::CompactHistoryType(unsigned int nbLines) : m_nbLines(nbLines) { } bool CompactHistoryType::isEnabled() const { - return true; + return true; } int CompactHistoryType::maximumLineCount() const { - return m_nbLines; + return m_nbLines; } -HistoryScroll* CompactHistoryType::scroll ( HistoryScroll *old ) const +HistoryScroll *CompactHistoryType::scroll(HistoryScroll *old) const { - if ( old ) - { - CompactHistoryScroll *oldBuffer = dynamic_cast ( old ); - if ( oldBuffer ) - { - oldBuffer->setMaxNbLines ( m_nbLines ); - return oldBuffer; + if (old) { + CompactHistoryScroll *oldBuffer = dynamic_cast(old); + if (oldBuffer) { + oldBuffer->setMaxNbLines(m_nbLines); + return oldBuffer; + } + delete old; } - delete old; - } - return new CompactHistoryScroll ( m_nbLines ); + return new CompactHistoryScroll(m_nbLines); } diff --git a/lib/History.h b/lib/History.h index eb8c9e10..51c4361e 100644 --- a/lib/History.h +++ b/lib/History.h @@ -37,8 +37,7 @@ // map #include -namespace Konsole -{ +namespace Konsole { #if 1 /* @@ -48,37 +47,37 @@ namespace Konsole class HistoryFile { public: - HistoryFile(); - virtual ~HistoryFile(); - - virtual void add(const unsigned char* bytes, int len); - virtual void get(unsigned char* bytes, int len, int loc); - virtual int len(); + HistoryFile(); + virtual ~HistoryFile(); - //mmaps the file in read-only mode - void map(); - //un-mmaps the file - void unmap(); - //returns true if the file is mmap'ed - bool isMapped() const; + virtual void add(const unsigned char *bytes, int len); + virtual void get(unsigned char *bytes, int len, int loc); + virtual int len(); + // mmaps the file in read-only mode + void map(); + // un-mmaps the file + void unmap(); + // returns true if the file is mmap'ed + bool isMapped() const; private: - int ion; - int length; - QTemporaryFile tmpFile; - - //pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed - char* fileMap; - - //incremented whenver 'add' is called and decremented whenever - //'get' is called. - //this is used to detect when a large number of lines are being read and processed from the history - //and automatically mmap the file for better performance (saves the overhead of many lseek-read calls). - int readWriteBalance; - - //when readWriteBalance goes below this threshold, the file will be mmap'ed automatically - static const int MAP_THRESHOLD = -1000; + int ion; + int length; + QTemporaryFile tmpFile; + + // pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed + char *fileMap; + + // incremented whenver 'add' is called and decremented whenever + //'get' is called. + // this is used to detect when a large number of lines are being read and processed from the + // history and automatically mmap the file for better performance (saves the overhead of many + // lseek-read calls). + int readWriteBalance; + + // when readWriteBalance goes below this threshold, the file will be mmap'ed automatically + static const int MAP_THRESHOLD = -1000; }; #endif @@ -92,41 +91,45 @@ class HistoryType; class HistoryScroll { public: - HistoryScroll(HistoryType*); - virtual ~HistoryScroll(); - - virtual bool hasScroll(); - - // access to history - virtual int getLines() = 0; - virtual int getLineLen(int lineno) = 0; - virtual void getCells(int lineno, int colno, int count, Character res[]) = 0; - virtual bool isWrappedLine(int lineno) = 0; - - // backward compatibility (obsolete) - Character getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; } - - // adding lines. - virtual void addCells(const Character a[], int count) = 0; - // convenience method - this is virtual so that subclasses can take advantage - // of QVector's implicit copying - virtual void addCellsVector(const QVector& cells) - { - addCells(cells.data(),cells.size()); - } - - virtual void addLine(bool previousWrapped=false) = 0; - - // - // FIXME: Passing around constant references to HistoryType instances - // is very unsafe, because those references will no longer - // be valid if the history scroll is deleted. - // - const HistoryType& getType() { return *m_histType; } + HistoryScroll(HistoryType *); + virtual ~HistoryScroll(); + + virtual bool hasScroll(); + + // access to history + virtual int getLines() = 0; + virtual int getLineLen(int lineno) = 0; + virtual void getCells(int lineno, int colno, int count, Character res[]) = 0; + virtual bool isWrappedLine(int lineno) = 0; + + // backward compatibility (obsolete) + Character getCell(int lineno, int colno) + { + Character res; + getCells(lineno, colno, 1, &res); + return res; + } + + // adding lines. + virtual void addCells(const Character a[], int count) = 0; + // convenience method - this is virtual so that subclasses can take advantage + // of QVector's implicit copying + virtual void addCellsVector(const QVector &cells) + { + addCells(cells.data(), cells.size()); + } + + virtual void addLine(bool previousWrapped = false) = 0; + + // + // FIXME: Passing around constant references to HistoryType instances + // is very unsafe, because those references will no longer + // be valid if the history scroll is deleted. + // + const HistoryType &getType() { return *m_histType; } protected: - HistoryType* m_histType; - + HistoryType *m_histType; }; #if 1 @@ -138,66 +141,64 @@ class HistoryScroll class HistoryScrollFile : public HistoryScroll { public: - HistoryScrollFile(const QString &logFileName); - ~HistoryScrollFile() override; + HistoryScrollFile(const QString &logFileName); + ~HistoryScrollFile() override; - int getLines() override; - int getLineLen(int lineno) override; - void getCells(int lineno, int colno, int count, Character res[]) override; - bool isWrappedLine(int lineno) override; + int getLines() override; + int getLineLen(int lineno) override; + void getCells(int lineno, int colno, int count, Character res[]) override; + bool isWrappedLine(int lineno) override; - void addCells(const Character a[], int count) override; - void addLine(bool previousWrapped=false) override; + void addCells(const Character a[], int count) override; + void addLine(bool previousWrapped = false) override; private: - int startOfLine(int lineno); + int startOfLine(int lineno); - QString m_logFileName; - HistoryFile index; // lines Row(int) - HistoryFile cells; // text Row(Character) - HistoryFile lineflags; // flags Row(unsigned char) + QString m_logFileName; + HistoryFile index; // lines Row(int) + HistoryFile cells; // text Row(Character) + HistoryFile lineflags; // flags Row(unsigned char) }; - ////////////////////////////////////////////////////////////////////// // Buffer-based history (limited to a fixed nb of lines) ////////////////////////////////////////////////////////////////////// class HistoryScrollBuffer : public HistoryScroll { public: - typedef QVector HistoryLine; + typedef QVector HistoryLine; - HistoryScrollBuffer(unsigned int maxNbLines = 1000); - ~HistoryScrollBuffer() override; + HistoryScrollBuffer(unsigned int maxNbLines = 1000); + ~HistoryScrollBuffer() override; - int getLines() override; - int getLineLen(int lineno) override; - void getCells(int lineno, int colno, int count, Character res[]) override; - bool isWrappedLine(int lineno) override; + int getLines() override; + int getLineLen(int lineno) override; + void getCells(int lineno, int colno, int count, Character res[]) override; + bool isWrappedLine(int lineno) override; - void addCells(const Character a[], int count) override; - void addCellsVector(const QVector& cells) override; - void addLine(bool previousWrapped=false) override; - - void setMaxNbLines(unsigned int nbLines); - unsigned int maxNbLines() const { return _maxLineCount; } + void addCells(const Character a[], int count) override; + void addCellsVector(const QVector &cells) override; + void addLine(bool previousWrapped = false) override; + void setMaxNbLines(unsigned int nbLines); + unsigned int maxNbLines() const { return _maxLineCount; } private: - int bufferIndex(int lineNumber) const; - - HistoryLine* _historyBuffer; - QBitArray _wrappedLine; - int _maxLineCount; - int _usedLines; - int _head; - - //QVector m_histBuffer; - //QBitArray m_wrappedLine; - //unsigned int m_maxNbLines; - //unsigned int m_nbLines; - //unsigned int m_arrayIndex; - //bool m_buffFilled; + int bufferIndex(int lineNumber) const; + + HistoryLine *_historyBuffer; + QBitArray _wrappedLine; + int _maxLineCount; + int _usedLines; + int _head; + + // QVector m_histBuffer; + // QBitArray m_wrappedLine; + // unsigned int m_maxNbLines; + // unsigned int m_nbLines; + // unsigned int m_arrayIndex; + // bool m_buffFilled; }; /*class HistoryScrollBufferV2 : public HistoryScroll @@ -222,18 +223,18 @@ class HistoryScrollBuffer : public HistoryScroll class HistoryScrollNone : public HistoryScroll { public: - HistoryScrollNone(); - ~HistoryScrollNone() override; + HistoryScrollNone(); + ~HistoryScrollNone() override; - bool hasScroll() override; + bool hasScroll() override; - int getLines() override; - int getLineLen(int lineno) override; - void getCells(int lineno, int colno, int count, Character res[]) override; - bool isWrappedLine(int lineno) override; + int getLines() override; + int getLineLen(int lineno) override; + void getCells(int lineno, int colno, int count, Character res[]) override; + bool isWrappedLine(int lineno) override; - void addCells(const Character a[], int count) override; - void addLine(bool previousWrapped=false) override; + void addCells(const Character a[], int count) override; + void addLine(bool previousWrapped = false) override; }; ////////////////////////////////////////////////////////////////////// @@ -242,20 +243,20 @@ class HistoryScrollNone : public HistoryScroll class HistoryScrollBlockArray : public HistoryScroll { public: - HistoryScrollBlockArray(size_t size); - ~HistoryScrollBlockArray() override; + HistoryScrollBlockArray(size_t size); + ~HistoryScrollBlockArray() override; - int getLines() override; - int getLineLen(int lineno) override; - void getCells(int lineno, int colno, int count, Character res[]) override; - bool isWrappedLine(int lineno) override; + int getLines() override; + int getLineLen(int lineno) override; + void getCells(int lineno, int colno, int count, Character res[]) override; + bool isWrappedLine(int lineno) override; - void addCells(const Character a[], int count) override; - void addLine(bool previousWrapped=false) override; + void addCells(const Character a[], int count) override; + void addLine(bool previousWrapped = false) override; protected: - BlockArray m_blockArray; - QHash m_lineLengths; + BlockArray m_blockArray; + QHash m_lineLengths; }; ////////////////////////////////////////////////////////////////////// @@ -268,121 +269,133 @@ typedef QVector TextLine; class CharacterFormat { public: - bool equalsFormat(const CharacterFormat &other) const { - return other.rendition==rendition && other.fgColor==fgColor && other.bgColor==bgColor; - } - - bool equalsFormat(const Character &c) const { - return c.rendition==rendition && c.foregroundColor==fgColor && c.backgroundColor==bgColor; - } - - void setFormat(const Character& c) { - rendition=c.rendition; - fgColor=c.foregroundColor; - bgColor=c.backgroundColor; - } - - CharacterColor fgColor, bgColor; - quint16 startPos; - quint8 rendition; + bool equalsFormat(const CharacterFormat &other) const + { + return other.rendition == rendition && other.fgColor == fgColor && other.bgColor == bgColor; + } + + bool equalsFormat(const Character &c) const + { + return c.rendition == rendition && c.foregroundColor == fgColor + && c.backgroundColor == bgColor; + } + + void setFormat(const Character &c) + { + rendition = c.rendition; + fgColor = c.foregroundColor; + bgColor = c.backgroundColor; + } + + CharacterColor fgColor, bgColor; + quint16 startPos; + quint8 rendition; }; class CompactHistoryBlock { public: - - CompactHistoryBlock(){ - blockLength = 4096*64; // 256kb - head = (quint8*) mmap(nullptr, blockLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); - //head = (quint8*) malloc(blockLength); - Q_ASSERT(head != MAP_FAILED); - tail = blockStart = head; - allocCount=0; - } - - virtual ~CompactHistoryBlock(){ - //free(blockStart); - munmap(blockStart, blockLength); - } - - virtual unsigned int remaining(){ return blockStart+blockLength-tail;} - virtual unsigned length() { return blockLength; } - virtual void* allocate(size_t length); - virtual bool contains(void *addr) {return addr>=blockStart && addr<(blockStart+blockLength);} - virtual void deallocate(); - virtual bool isInUse(){ return allocCount!=0; } ; + CompactHistoryBlock() + { + blockLength = 4096 * 64; // 256kb + head = (quint8 *)mmap(nullptr, blockLength, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, + -1, 0); + // head = (quint8*) malloc(blockLength); + Q_ASSERT(head != MAP_FAILED); + tail = blockStart = head; + allocCount = 0; + } + + virtual ~CompactHistoryBlock() + { + // free(blockStart); + munmap(blockStart, blockLength); + } + + virtual unsigned int remaining() { return blockStart + blockLength - tail; } + virtual unsigned length() { return blockLength; } + virtual void *allocate(size_t length); + virtual bool contains(void *addr) + { + return addr >= blockStart && addr < (blockStart + blockLength); + } + virtual void deallocate(); + virtual bool isInUse() { return allocCount != 0; }; private: - size_t blockLength; - quint8* head; - quint8* tail; - quint8* blockStart; - int allocCount; + size_t blockLength; + quint8 *head; + quint8 *tail; + quint8 *blockStart; + int allocCount; }; -class CompactHistoryBlockList { +class CompactHistoryBlockList +{ public: - CompactHistoryBlockList() {}; - ~CompactHistoryBlockList(); + CompactHistoryBlockList(){}; + ~CompactHistoryBlockList(); + + void *allocate(size_t size); + void deallocate(void *); + int length() { return list.size(); } - void *allocate( size_t size ); - void deallocate(void *); - int length() {return list.size();} private: - QList list; + QList list; }; class CompactHistoryLine { public: - CompactHistoryLine(const TextLine&, CompactHistoryBlockList& blockList); - virtual ~CompactHistoryLine(); + CompactHistoryLine(const TextLine &, CompactHistoryBlockList &blockList); + virtual ~CompactHistoryLine(); - // custom new operator to allocate memory from custom pool instead of heap - static void *operator new( size_t size, CompactHistoryBlockList& blockList); - static void operator delete( void *) { /* do nothing, deallocation from pool is done in destructor*/ } ; + // custom new operator to allocate memory from custom pool instead of heap + static void *operator new(size_t size, CompactHistoryBlockList &blockList); + static void + operator delete(void *){ /* do nothing, deallocation from pool is done in destructor*/ }; - virtual void getCharacters(Character* array, int length, int startColumn) ; - virtual void getCharacter(int index, Character &r) ; - virtual bool isWrapped() const {return wrapped;}; - virtual void setWrapped(bool isWrapped) { wrapped=isWrapped;}; - virtual unsigned int getLength() const {return length;}; + virtual void getCharacters(Character *array, int length, int startColumn); + virtual void getCharacter(int index, Character &r); + virtual bool isWrapped() const { return wrapped; }; + virtual void setWrapped(bool isWrapped) { wrapped = isWrapped; }; + virtual unsigned int getLength() const { return length; }; protected: - CompactHistoryBlockList& blockList; - CharacterFormat* formatArray; - quint16 length; - quint16* text; - quint16 formatLength; - bool wrapped; + CompactHistoryBlockList &blockList; + CharacterFormat *formatArray; + quint16 length; + quint16 *text; + quint16 formatLength; + bool wrapped; }; class CompactHistoryScroll : public HistoryScroll { - typedef QList HistoryArray; + typedef QList HistoryArray; public: - CompactHistoryScroll(unsigned int maxNbLines = 1000); - ~CompactHistoryScroll() override; + CompactHistoryScroll(unsigned int maxNbLines = 1000); + ~CompactHistoryScroll() override; - int getLines() override; - int getLineLen(int lineno) override; - void getCells(int lineno, int colno, int count, Character res[]) override; - bool isWrappedLine(int lineno) override; + int getLines() override; + int getLineLen(int lineno) override; + void getCells(int lineno, int colno, int count, Character res[]) override; + bool isWrappedLine(int lineno) override; - void addCells(const Character a[], int count) override; - void addCellsVector(const TextLine& cells) override; - void addLine(bool previousWrapped=false) override; + void addCells(const Character a[], int count) override; + void addCellsVector(const TextLine &cells) override; + void addLine(bool previousWrapped = false) override; - void setMaxNbLines(unsigned int nbLines); - unsigned int maxNbLines() const { return _maxLineCount; } + void setMaxNbLines(unsigned int nbLines); + unsigned int maxNbLines() const { return _maxLineCount; } private: - bool hasDifferentColors(const TextLine& line) const; - HistoryArray lines; - CompactHistoryBlockList blockList; + bool hasDifferentColors(const TextLine &line) const; + HistoryArray lines; + CompactHistoryBlockList blockList; - unsigned int _maxLineCount; + unsigned int _maxLineCount; }; ////////////////////////////////////////////////////////////////////// @@ -392,100 +405,98 @@ class CompactHistoryScroll : public HistoryScroll class HistoryType { public: - HistoryType(); - virtual ~HistoryType(); - - /** - * Returns true if the history is enabled ( can store lines of output ) - * or false otherwise. - */ - virtual bool isEnabled() const = 0; - /** - * Returns true if the history size is unlimited. - */ - bool isUnlimited() const { return maximumLineCount() == 0; } - /** - * Returns the maximum number of lines which this history type - * can store or 0 if the history can store an unlimited number of lines. - */ - virtual int maximumLineCount() const = 0; - - virtual HistoryScroll* scroll(HistoryScroll *) const = 0; + HistoryType(); + virtual ~HistoryType(); + + /** + * Returns true if the history is enabled ( can store lines of output ) + * or false otherwise. + */ + virtual bool isEnabled() const = 0; + /** + * Returns true if the history size is unlimited. + */ + bool isUnlimited() const { return maximumLineCount() == 0; } + /** + * Returns the maximum number of lines which this history type + * can store or 0 if the history can store an unlimited number of lines. + */ + virtual int maximumLineCount() const = 0; + + virtual HistoryScroll *scroll(HistoryScroll *) const = 0; }; class HistoryTypeNone : public HistoryType { public: - HistoryTypeNone(); + HistoryTypeNone(); - bool isEnabled() const override; - int maximumLineCount() const override; + bool isEnabled() const override; + int maximumLineCount() const override; - HistoryScroll* scroll(HistoryScroll *) const override; + HistoryScroll *scroll(HistoryScroll *) const override; }; class HistoryTypeBlockArray : public HistoryType { public: - HistoryTypeBlockArray(size_t size); + HistoryTypeBlockArray(size_t size); - bool isEnabled() const override; - int maximumLineCount() const override; + bool isEnabled() const override; + int maximumLineCount() const override; - HistoryScroll* scroll(HistoryScroll *) const override; + HistoryScroll *scroll(HistoryScroll *) const override; protected: - size_t m_size; + size_t m_size; }; #if 1 class HistoryTypeFile : public HistoryType { public: - HistoryTypeFile(const QString& fileName=QString()); + HistoryTypeFile(const QString &fileName = QString()); - bool isEnabled() const override; - virtual const QString& getFileName() const; - int maximumLineCount() const override; + bool isEnabled() const override; + virtual const QString &getFileName() const; + int maximumLineCount() const override; - HistoryScroll* scroll(HistoryScroll *) const override; + HistoryScroll *scroll(HistoryScroll *) const override; protected: - QString m_fileName; + QString m_fileName; }; - class HistoryTypeBuffer : public HistoryType { friend class HistoryScrollBuffer; public: - HistoryTypeBuffer(unsigned int nbLines); + HistoryTypeBuffer(unsigned int nbLines); - bool isEnabled() const override; - int maximumLineCount() const override; + bool isEnabled() const override; + int maximumLineCount() const override; - HistoryScroll* scroll(HistoryScroll *) const override; + HistoryScroll *scroll(HistoryScroll *) const override; protected: - unsigned int m_nbLines; + unsigned int m_nbLines; }; class CompactHistoryType : public HistoryType { public: - CompactHistoryType(unsigned int size); + CompactHistoryType(unsigned int size); - bool isEnabled() const override; - int maximumLineCount() const override; + bool isEnabled() const override; + int maximumLineCount() const override; - HistoryScroll* scroll(HistoryScroll *) const override; + HistoryScroll *scroll(HistoryScroll *) const override; protected: - unsigned int m_nbLines; + unsigned int m_nbLines; }; - #endif } diff --git a/lib/HistorySearch.cpp b/lib/HistorySearch.cpp index 33c6f4ef..b111a011 100644 --- a/lib/HistorySearch.cpp +++ b/lib/HistorySearch.cpp @@ -24,35 +24,35 @@ #include "Emulation.h" #include "HistorySearch.h" -HistorySearch::HistorySearch(EmulationPtr emulation, const QRegExp& regExp, - bool forwards, int startColumn, int startLine, - QObject* parent) : -QObject(parent), -m_emulation(emulation), -m_regExp(regExp), -m_forwards(forwards), -m_startColumn(startColumn), -m_startLine(startLine) { +HistorySearch::HistorySearch(EmulationPtr emulation, const QRegExp ®Exp, bool forwards, + int startColumn, int startLine, QObject *parent) + : QObject(parent), + m_emulation(emulation), + m_regExp(regExp), + m_forwards(forwards), + m_startColumn(startColumn), + m_startLine(startLine) +{ } -HistorySearch::~HistorySearch() { -} +HistorySearch::~HistorySearch() { } -void HistorySearch::search() { +void HistorySearch::search() +{ bool found = false; - if (! m_regExp.isEmpty()) - { + if (!m_regExp.isEmpty()) { if (m_forwards) { - found = search(m_startColumn, m_startLine, -1, m_emulation->lineCount()) || search(0, 0, m_startColumn, m_startLine); + found = search(m_startColumn, m_startLine, -1, m_emulation->lineCount()) + || search(0, 0, m_startColumn, m_startLine); } else { - found = search(0, 0, m_startColumn, m_startLine) || search(m_startColumn, m_startLine, -1, m_emulation->lineCount()); + found = search(0, 0, m_startColumn, m_startLine) + || search(m_startColumn, m_startLine, -1, m_emulation->lineCount()); } if (found) { emit matchFound(m_foundStartColumn, m_foundStartLine, m_foundEndColumn, m_foundEndLine); - } - else { + } else { emit noMatchFound(); } } @@ -60,9 +60,10 @@ void HistorySearch::search() { deleteLater(); } -bool HistorySearch::search(int startColumn, int startLine, int endColumn, int endLine) { - qDebug() << "search from" << startColumn << "," << startLine - << "to" << endColumn << "," << endLine; +bool HistorySearch::search(int startColumn, int startLine, int endColumn, int endLine) +{ + qDebug() << "search from" << startColumn << "," << startLine << "to" << endColumn << "," + << endLine; int linesRead = 0; int linesToRead = endLine - startLine + 1; @@ -81,7 +82,8 @@ bool HistorySearch::search(int startColumn, int startLine, int endColumn, int en decoder.setRecordLinePositions(true); // Calculate lines to read and read them - int blockStartLine = m_forwards ? startLine + linesRead : endLine - linesRead - blockSize + 1; + int blockStartLine = + m_forwards ? startLine + linesRead : endLine - linesRead - blockSize + 1; int chunkEndLine = blockStartLine + blockSize - 1; m_emulation->writeToStream(&decoder, blockStartLine, chunkEndLine); @@ -90,40 +92,35 @@ bool HistorySearch::search(int startColumn, int startLine, int endColumn, int en // last line of the string int endPosition; - // The String that Emulator.writeToStream produces has a newline at the end, and so ends with an - // empty line - we ignore that. + // The String that Emulator.writeToStream produces has a newline at the end, and so ends + // with an empty line - we ignore that. int numberOfLinesInString = decoder.linePositions().size() - 1; - if (numberOfLinesInString > 0 && endColumn > -1 ) - { + if (numberOfLinesInString > 0 && endColumn > -1) { endPosition = decoder.linePositions().at(numberOfLinesInString - 1) + endColumn; - } - else - { + } else { endPosition = string.size(); } // So now we can log for m_regExp in the string between startColumn and endPosition int matchStart; - if (m_forwards) - { + if (m_forwards) { matchStart = string.indexOf(m_regExp, startColumn); if (matchStart >= endPosition) matchStart = -1; - } - else - { + } else { matchStart = string.lastIndexOf(m_regExp, endPosition - 1); if (matchStart < startColumn) matchStart = -1; } - if (matchStart > -1) - { + if (matchStart > -1) { int matchEnd = matchStart + m_regExp.matchedLength() - 1; qDebug() << "Found in string from" << matchStart << "to" << matchEnd; - // Translate startPos and endPos to startColum, startLine, endColumn and endLine in history. - int startLineNumberInString = findLineNumberInString(decoder.linePositions(), matchStart); + // Translate startPos and endPos to startColum, startLine, endColumn and endLine in + // history. + int startLineNumberInString = + findLineNumberInString(decoder.linePositions(), matchStart); m_foundStartColumn = matchStart - decoder.linePositions().at(startLineNumberInString); m_foundStartLine = startLineNumberInString + startLine + linesRead; @@ -131,15 +128,13 @@ bool HistorySearch::search(int startColumn, int startLine, int endColumn, int en m_foundEndColumn = matchEnd - decoder.linePositions().at(endLineNumberInString); m_foundEndLine = endLineNumberInString + startLine + linesRead; - qDebug() << "m_foundStartColumn" << m_foundStartColumn - << "m_foundStartLine" << m_foundEndLine - << "m_foundEndColumn" << m_foundEndColumn - << "m_foundEndLine" << m_foundEndLine; + qDebug() << "m_foundStartColumn" << m_foundStartColumn << "m_foundStartLine" + << m_foundEndLine << "m_foundEndColumn" << m_foundEndColumn << "m_foundEndLine" + << m_foundEndLine; return true; } - linesRead += blockSize; } @@ -147,8 +142,8 @@ bool HistorySearch::search(int startColumn, int startLine, int endColumn, int en return false; } - -int HistorySearch::findLineNumberInString(QList linePositions, int position) { +int HistorySearch::findLineNumberInString(QList linePositions, int position) +{ int lineNum = 0; while (lineNum + 1 < linePositions.size() && linePositions[lineNum + 1] <= position) lineNum++; diff --git a/lib/HistorySearch.h b/lib/HistorySearch.h index ad5ac878..37b903ea 100644 --- a/lib/HistorySearch.h +++ b/lib/HistorySearch.h @@ -17,7 +17,7 @@ 02110-1301 USA. */ #ifndef TASK_H -#define TASK_H +#define TASK_H #include #include @@ -38,8 +38,8 @@ class HistorySearch : public QObject Q_OBJECT public: - explicit HistorySearch(EmulationPtr emulation, const QRegExp& regExp, bool forwards, - int startColumn, int startLine, QObject* parent); + explicit HistorySearch(EmulationPtr emulation, const QRegExp ®Exp, bool forwards, + int startColumn, int startLine, QObject *parent); ~HistorySearch() override; @@ -53,7 +53,6 @@ class HistorySearch : public QObject bool search(int startColumn, int startLine, int endColumn, int endLine); int findLineNumberInString(QList linePositions, int position); - EmulationPtr m_emulation; QRegExp m_regExp; bool m_forwards; @@ -66,5 +65,4 @@ class HistorySearch : public QObject int m_foundEndLine; }; -#endif /* TASK_H */ - +#endif /* TASK_H */ diff --git a/lib/KeyboardTranslator.cpp b/lib/KeyboardTranslator.cpp index c37ec483..db08de52 100644 --- a/lib/KeyboardTranslator.cpp +++ b/lib/KeyboardTranslator.cpp @@ -44,11 +44,9 @@ using namespace Konsole; - -const QByteArray KeyboardTranslatorManager::defaultTranslatorText( -"keyboard \"Fallback Key Translator\"\n" -"key Tab : \"\\t\"" -); +const QByteArray + KeyboardTranslatorManager::defaultTranslatorText("keyboard \"Fallback Key Translator\"\n" + "key Tab : \"\\t\""); #ifdef Q_OS_MAC // On Mac, Qt::ControlModifier means Cmd, and MetaModifier means Ctrl @@ -57,18 +55,15 @@ const Qt::KeyboardModifier KeyboardTranslator::CTRL_MOD = Qt::MetaModifier; const Qt::KeyboardModifier KeyboardTranslator::CTRL_MOD = Qt::ControlModifier; #endif -KeyboardTranslatorManager::KeyboardTranslatorManager() - : _haveLoadedAll(false) -{ -} +KeyboardTranslatorManager::KeyboardTranslatorManager() : _haveLoadedAll(false) { } KeyboardTranslatorManager::~KeyboardTranslatorManager() { qDeleteAll(_translators); } -QString KeyboardTranslatorManager::findTranslatorPath(const QString& name) +QString KeyboardTranslatorManager::findTranslatorPath(const QString &name) { return QString(get_kb_layout_dir() + name + QLatin1String(".keytab")); - //return KGlobal::dirs()->findResource("data","konsole/"+name+".keytab"); + // return KGlobal::dirs()->findResource("data","konsole/"+name+".keytab"); } void KeyboardTranslatorManager::findTranslators() @@ -78,49 +73,49 @@ void KeyboardTranslatorManager::findTranslators() filters << QLatin1String("*.keytab"); dir.setNameFilters(filters); QStringList list = dir.entryList(filters); -// QStringList list = KGlobal::dirs()->findAllResources("data", -// "konsole/*.keytab", -// KStandardDirs::NoDuplicates); + // QStringList list = KGlobal::dirs()->findAllResources("data", + // "konsole/*.keytab", + // KStandardDirs::NoDuplicates); // add the name of each translator to the list and associated // the name with a null pointer to indicate that the translator // has not yet been loaded from disk QStringListIterator listIter(list); - while (listIter.hasNext()) - { + while (listIter.hasNext()) { QString translatorPath = listIter.next(); QString name = QFileInfo(translatorPath).baseName(); - if ( !_translators.contains(name) ) - _translators.insert(name,0); + if (!_translators.contains(name)) + _translators.insert(name, 0); } _haveLoadedAll = true; } -const KeyboardTranslator* KeyboardTranslatorManager::findTranslator(const QString& name) +const KeyboardTranslator *KeyboardTranslatorManager::findTranslator(const QString &name) { - if ( name.isEmpty() ) + if (name.isEmpty()) return defaultTranslator(); - if ( _translators.contains(name) && _translators[name] != 0 ) + if (_translators.contains(name) && _translators[name] != 0) return _translators[name]; - KeyboardTranslator* translator = loadTranslator(name); + KeyboardTranslator *translator = loadTranslator(name); - if ( translator != nullptr ) + if (translator != nullptr) _translators[name] = translator; - else if ( !name.isEmpty() ) + else if (!name.isEmpty()) qDebug() << "Unable to load translator" << name; return translator; } -bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator* translator) +bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator *translator) { -qDebug() << "KeyboardTranslatorManager::saveTranslator" << "unimplemented"; -Q_UNUSED(translator); + qDebug() << "KeyboardTranslatorManager::saveTranslator" + << "unimplemented"; + Q_UNUSED(translator); #if 0 const QString path = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name() +".keytab"; @@ -149,57 +144,54 @@ Q_UNUSED(translator); return true; } -KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(const QString& name) +KeyboardTranslator *KeyboardTranslatorManager::loadTranslator(const QString &name) { - const QString& path = findTranslatorPath(name); + const QString &path = findTranslatorPath(name); QFile source(path); if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text)) return nullptr; - return loadTranslator(&source,name); + return loadTranslator(&source, name); } -const KeyboardTranslator* KeyboardTranslatorManager::defaultTranslator() +const KeyboardTranslator *KeyboardTranslatorManager::defaultTranslator() { // Try to find the default.keytab file if it exists, otherwise // fall back to the hard-coded one - const KeyboardTranslator* translator = findTranslator(QLatin1String("default")); - if (!translator) - { + const KeyboardTranslator *translator = findTranslator(QLatin1String("default")); + if (!translator) { QBuffer textBuffer; textBuffer.setData(defaultTranslatorText); textBuffer.open(QIODevice::ReadOnly); - translator = loadTranslator(&textBuffer,QLatin1String("fallback")); + translator = loadTranslator(&textBuffer, QLatin1String("fallback")); } return translator; } -KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(QIODevice* source,const QString& name) +KeyboardTranslator *KeyboardTranslatorManager::loadTranslator(QIODevice *source, + const QString &name) { - KeyboardTranslator* translator = new KeyboardTranslator(name); + KeyboardTranslator *translator = new KeyboardTranslator(name); KeyboardTranslatorReader reader(source); - translator->setDescription( reader.description() ); - while ( reader.hasNextEntry() ) + translator->setDescription(reader.description()); + while (reader.hasNextEntry()) translator->addEntry(reader.nextEntry()); source->close(); - if ( !reader.parseError() ) - { + if (!reader.parseError()) { return translator; - } - else - { + } else { delete translator; return nullptr; } } -KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice* destination) -: _destination(destination) +KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice *destination) + : _destination(destination) { - Q_ASSERT( destination && destination->isWritable() ); + Q_ASSERT(destination && destination->isWritable()); _writer = new QTextStream(_destination); } @@ -207,22 +199,22 @@ KeyboardTranslatorWriter::~KeyboardTranslatorWriter() { delete _writer; } -void KeyboardTranslatorWriter::writeHeader( const QString& description ) +void KeyboardTranslatorWriter::writeHeader(const QString &description) { *_writer << "keyboard \"" << description << '\"' << '\n'; } -void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entry ) +void KeyboardTranslatorWriter::writeEntry(const KeyboardTranslator::Entry &entry) { QString result; - if ( entry.command() != KeyboardTranslator::NoCommand ) + if (entry.command() != KeyboardTranslator::NoCommand) result = entry.resultToString(); else result = QLatin1Char('\"') + entry.resultToString() + QLatin1Char('\"'); - *_writer << QLatin1String("key ") << entry.conditionToString() << QLatin1String(" : ") << result << QLatin1Char('\n'); + *_writer << QLatin1String("key ") << entry.conditionToString() << QLatin1String(" : ") << result + << QLatin1Char('\n'); } - // each line of the keyboard translation file is one of: // // - keyboard "name" @@ -242,28 +234,24 @@ void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entr // already been removed) // -KeyboardTranslatorReader::KeyboardTranslatorReader( QIODevice* source ) - : _source(source) - , _hasNext(false) +KeyboardTranslatorReader::KeyboardTranslatorReader(QIODevice *source) + : _source(source), _hasNext(false) { - // read input until we find the description - while ( _description.isEmpty() && !source->atEnd() ) - { - QList tokens = tokenize( QString::fromUtf8(source->readLine()) ); - if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword ) + // read input until we find the description + while (_description.isEmpty() && !source->atEnd()) { + QList tokens = tokenize(QString::fromUtf8(source->readLine())); + if (!tokens.isEmpty() && tokens.first().type == Token::TitleKeyword) _description = tokens[1].text; - } - // read first entry (if any) - readNext(); + } + // read first entry (if any) + readNext(); } void KeyboardTranslatorReader::readNext() { // find next entry - while ( !_source->atEnd() ) - { - const QList& tokens = tokenize( QString::fromUtf8(_source->readLine()) ); - if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword ) - { + while (!_source->atEnd()) { + const QList &tokens = tokenize(QString::fromUtf8(_source->readLine())); + if (!tokens.isEmpty() && tokens.first().type == Token::KeyKeyword) { KeyboardTranslator::States flags = KeyboardTranslator::NoState; KeyboardTranslator::States flagMask = KeyboardTranslator::NoState; Qt::KeyboardModifiers modifiers = Qt::NoModifier; @@ -271,36 +259,29 @@ void KeyboardTranslatorReader::readNext() int keyCode = Qt::Key_unknown; - decodeSequence(tokens[1].text.toLower(), - keyCode, - modifiers, - modifierMask, - flags, + decodeSequence(tokens[1].text.toLower(), keyCode, modifiers, modifierMask, flags, flagMask); KeyboardTranslator::Command command = KeyboardTranslator::NoCommand; QByteArray text; // get text or command - if ( tokens[2].type == Token::OutputText ) - { + if (tokens[2].type == Token::OutputText) { text = tokens[2].text.toLocal8Bit(); - } - else if ( tokens[2].type == Token::Command ) - { + } else if (tokens[2].type == Token::Command) { // identify command - if (!parseAsCommand(tokens[2].text,command)) + if (!parseAsCommand(tokens[2].text, command)) qDebug() << "Command" << tokens[2].text << "not understood."; } KeyboardTranslator::Entry newEntry; - newEntry.setKeyCode( keyCode ); - newEntry.setState( flags ); - newEntry.setStateMask( flagMask ); - newEntry.setModifiers( modifiers ); - newEntry.setModifierMask( modifierMask ); - newEntry.setText( text ); - newEntry.setCommand( command ); + newEntry.setKeyCode(keyCode); + newEntry.setState(flags); + newEntry.setStateMask(flagMask); + newEntry.setModifiers(modifiers); + newEntry.setModifierMask(modifierMask); + newEntry.setText(text); + newEntry.setCommand(command); _nextEntry = newEntry; @@ -313,23 +294,24 @@ void KeyboardTranslatorReader::readNext() _hasNext = false; } -bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTranslator::Command& command) +bool KeyboardTranslatorReader::parseAsCommand(const QString &text, + KeyboardTranslator::Command &command) { - if ( text.compare(QLatin1String("erase"),Qt::CaseInsensitive) == 0 ) + if (text.compare(QLatin1String("erase"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::EraseCommand; - else if ( text.compare(QLatin1String("scrollpageup"),Qt::CaseInsensitive) == 0 ) + else if (text.compare(QLatin1String("scrollpageup"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollPageUpCommand; - else if ( text.compare(QLatin1String("scrollpagedown"),Qt::CaseInsensitive) == 0 ) + else if (text.compare(QLatin1String("scrollpagedown"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollPageDownCommand; - else if ( text.compare(QLatin1String("scrolllineup"),Qt::CaseInsensitive) == 0 ) + else if (text.compare(QLatin1String("scrolllineup"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollLineUpCommand; - else if ( text.compare(QLatin1String("scrolllinedown"),Qt::CaseInsensitive) == 0 ) + else if (text.compare(QLatin1String("scrolllinedown"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollLineDownCommand; - else if ( text.compare(QLatin1String("scrolllock"),Qt::CaseInsensitive) == 0 ) + else if (text.compare(QLatin1String("scrolllock"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollLockCommand; - else if ( text.compare(QLatin1String("scrolluptotop"),Qt::CaseInsensitive) == 0) + else if (text.compare(QLatin1String("scrolluptotop"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollUpToTopCommand; - else if ( text.compare(QLatin1String("scrolldowntobottom"),Qt::CaseInsensitive) == 0) + else if (text.compare(QLatin1String("scrolldowntobottom"), Qt::CaseInsensitive) == 0) command = KeyboardTranslator::ScrollDownToBottomCommand; else return false; @@ -337,12 +319,11 @@ bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTransl return true; } -bool KeyboardTranslatorReader::decodeSequence(const QString& text, - int& keyCode, - Qt::KeyboardModifiers& modifiers, - Qt::KeyboardModifiers& modifierMask, - KeyboardTranslator::States& flags, - KeyboardTranslator::States& flagMask) +bool KeyboardTranslatorReader::decodeSequence(const QString &text, int &keyCode, + Qt::KeyboardModifiers &modifiers, + Qt::KeyboardModifiers &modifierMask, + KeyboardTranslator::States &flags, + KeyboardTranslator::States &flagMask) { bool isWanted = true; bool endOfItem = false; @@ -353,42 +334,34 @@ bool KeyboardTranslatorReader::decodeSequence(const QString& text, KeyboardTranslator::States tempFlags = flags; KeyboardTranslator::States tempFlagMask = flagMask; - for ( int i = 0 ; i < text.count() ; i++ ) - { - const QChar& ch = text[i]; + for (int i = 0; i < text.count(); i++) { + const QChar &ch = text[i]; bool isFirstLetter = i == 0; - bool isLastLetter = ( i == text.count()-1 ); + bool isLastLetter = (i == text.count() - 1); endOfItem = true; - if ( ch.isLetterOrNumber() ) - { + if (ch.isLetterOrNumber()) { endOfItem = false; buffer.append(ch); - } else if ( isFirstLetter ) - { + } else if (isFirstLetter) { buffer.append(ch); } - if ( (endOfItem || isLastLetter) && !buffer.isEmpty() ) - { + if ((endOfItem || isLastLetter) && !buffer.isEmpty()) { Qt::KeyboardModifier itemModifier = Qt::NoModifier; int itemKeyCode = 0; KeyboardTranslator::State itemFlag = KeyboardTranslator::NoState; - if ( parseAsModifier(buffer,itemModifier) ) - { + if (parseAsModifier(buffer, itemModifier)) { tempModifierMask |= itemModifier; - if ( isWanted ) + if (isWanted) tempModifiers |= itemModifier; - } - else if ( parseAsStateFlag(buffer,itemFlag) ) - { + } else if (parseAsStateFlag(buffer, itemFlag)) { tempFlagMask |= itemFlag; - if ( isWanted ) + if (isWanted) tempFlags |= itemFlag; - } - else if ( parseAsKeyCode(buffer,itemKeyCode) ) + } else if (parseAsKeyCode(buffer, itemKeyCode)) keyCode = itemKeyCode; else qDebug() << "Unable to parse key binding item:" << buffer; @@ -398,10 +371,10 @@ bool KeyboardTranslatorReader::decodeSequence(const QString& text, // check if this is a wanted / not-wanted flag and update the // state ready for the next item - if ( ch == QLatin1Char('+') ) - isWanted = true; - else if ( ch == QLatin1Char('-') ) - isWanted = false; + if (ch == QLatin1Char('+')) + isWanted = true; + else if (ch == QLatin1Char('-')) + isWanted = false; } modifiers = tempModifiers; @@ -412,58 +385,57 @@ bool KeyboardTranslatorReader::decodeSequence(const QString& text, return true; } -bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier) +bool KeyboardTranslatorReader::parseAsModifier(const QString &item, Qt::KeyboardModifier &modifier) { - if ( item == QLatin1String("shift") ) + if (item == QLatin1String("shift")) modifier = Qt::ShiftModifier; - else if ( item == QLatin1String("ctrl") || item == QLatin1String("control") ) + else if (item == QLatin1String("ctrl") || item == QLatin1String("control")) modifier = Qt::ControlModifier; - else if ( item == QLatin1String("alt") ) + else if (item == QLatin1String("alt")) modifier = Qt::AltModifier; - else if ( item == QLatin1String("meta") ) + else if (item == QLatin1String("meta")) modifier = Qt::MetaModifier; - else if ( item == QLatin1String("keypad") ) + else if (item == QLatin1String("keypad")) modifier = Qt::KeypadModifier; else return false; return true; } -bool KeyboardTranslatorReader::parseAsStateFlag(const QString& item , KeyboardTranslator::State& flag) +bool KeyboardTranslatorReader::parseAsStateFlag(const QString &item, + KeyboardTranslator::State &flag) { - if ( item == QLatin1String("appcukeys") || item == QLatin1String("appcursorkeys") ) + if (item == QLatin1String("appcukeys") || item == QLatin1String("appcursorkeys")) flag = KeyboardTranslator::CursorKeysState; - else if ( item == QLatin1String("ansi") ) + else if (item == QLatin1String("ansi")) flag = KeyboardTranslator::AnsiState; - else if ( item == QLatin1String("newline") ) + else if (item == QLatin1String("newline")) flag = KeyboardTranslator::NewLineState; - else if ( item == QLatin1String("appscreen") ) + else if (item == QLatin1String("appscreen")) flag = KeyboardTranslator::AlternateScreenState; - else if ( item == QLatin1String("anymod") || item == QLatin1String("anymodifier") ) + else if (item == QLatin1String("anymod") || item == QLatin1String("anymodifier")) flag = KeyboardTranslator::AnyModifierState; - else if ( item == QLatin1String("appkeypad") ) + else if (item == QLatin1String("appkeypad")) flag = KeyboardTranslator::ApplicationKeypadState; else return false; return true; } -bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode) +bool KeyboardTranslatorReader::parseAsKeyCode(const QString &item, int &keyCode) { QKeySequence sequence = QKeySequence::fromString(item); - if ( !sequence.isEmpty() ) - { + if (!sequence.isEmpty()) { keyCode = sequence[0]; - if ( sequence.count() > 1 ) - { + if (sequence.count() > 1) { qDebug() << "Unhandled key codes in sequence: " << item; } } // additional cases implemented for backwards compatibility with KDE 3 - else if ( item == QLatin1String("prior") ) + else if (item == QLatin1String("prior")) keyCode = Qt::Key_PageUp; - else if ( item == QLatin1String("next") ) + else if (item == QLatin1String("next")) keyCode = Qt::Key_PageDown; else return false; @@ -479,8 +451,8 @@ bool KeyboardTranslatorReader::hasNextEntry() const { return _hasNext; } -KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& condition , - const QString& result ) +KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry(const QString &condition, + const QString &result) { QString entryString = QString::fromLatin1("keyboard \"temporary\"\nkey "); entryString.append(condition); @@ -490,7 +462,7 @@ KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& // otherwise the result will be treated as a string to echo when the key sequence // specified by 'condition' is pressed KeyboardTranslator::Command command; - if (parseAsCommand(result,command)) + if (parseAsCommand(result, command)) entryString.append(result); else entryString.append(QLatin1Char('\"') + result + QLatin1Char('\"')); @@ -501,7 +473,7 @@ KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& KeyboardTranslatorReader reader(&buffer); KeyboardTranslator::Entry entry; - if ( reader.hasNextEntry() ) + if (reader.hasNextEntry()) entry = reader.nextEntry(); return entry; @@ -509,7 +481,7 @@ KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& KeyboardTranslator::Entry KeyboardTranslatorReader::nextEntry() { - Q_ASSERT( _hasNext ); + Q_ASSERT(_hasNext); KeyboardTranslator::Entry entry = _nextEntry; readNext(); return entry; @@ -518,15 +490,14 @@ bool KeyboardTranslatorReader::parseError() { return false; } -QList KeyboardTranslatorReader::tokenize(const QString& line) +QList KeyboardTranslatorReader::tokenize(const QString &line) { QString text = line; // remove comments bool inQuotes = false; int commentPos = -1; - for (int i=text.length()-1;i>=0;i--) - { + for (int i = text.length() - 1; i >= 0; i--) { QChar ch = text[i]; if (ch == QLatin1Char('\"')) inQuotes = !inQuotes; @@ -534,7 +505,7 @@ QList KeyboardTranslatorReader::tokenize(const commentPos = i; } if (commentPos != -1) - text.remove(commentPos,text.length()); + text.remove(commentPos, text.length()); text = text.simplified(); @@ -545,40 +516,32 @@ QList KeyboardTranslatorReader::tokenize(const static QRegExp key(QLatin1String("key\\s+([\\w\\+\\s\\-\\*\\.]+)\\s*:\\s*(\"(.*)\"|\\w+)")); QList list; - if ( text.isEmpty() ) - { + if (text.isEmpty()) { return list; } - if ( title.exactMatch(text) ) - { - Token titleToken = { Token::TitleKeyword , QString() }; - Token textToken = { Token::TitleText , title.capturedTexts().at(1) }; + if (title.exactMatch(text)) { + Token titleToken = { Token::TitleKeyword, QString() }; + Token textToken = { Token::TitleText, title.capturedTexts().at(1) }; list << titleToken << textToken; - } - else if ( key.exactMatch(text) ) - { - Token keyToken = { Token::KeyKeyword , QString() }; - Token sequenceToken = { Token::KeySequence , key.capturedTexts().value(1).remove(QLatin1Char(' ')) }; + } else if (key.exactMatch(text)) { + Token keyToken = { Token::KeyKeyword, QString() }; + Token sequenceToken = { Token::KeySequence, + key.capturedTexts().value(1).remove(QLatin1Char(' ')) }; list << keyToken << sequenceToken; - if ( key.capturedTexts().at(3).isEmpty() ) - { + if (key.capturedTexts().at(3).isEmpty()) { // capturedTexts()[2] is a command - Token commandToken = { Token::Command , key.capturedTexts().at(2) }; + Token commandToken = { Token::Command, key.capturedTexts().at(2) }; list << commandToken; - } - else - { + } else { // capturedTexts()[3] is the output string - Token outputToken = { Token::OutputText , key.capturedTexts().at(3) }; - list << outputToken; + Token outputToken = { Token::OutputText, key.capturedTexts().at(3) }; + list << outputToken; } - } - else - { + } else { qDebug() << "Line in keyboard translator file could not be understood:" << text; } @@ -587,8 +550,7 @@ QList KeyboardTranslatorReader::tokenize(const QList KeyboardTranslatorManager::allTranslators() { - if ( !_haveLoadedAll ) - { + if (!_haveLoadedAll) { findTranslators(); } @@ -596,28 +558,23 @@ QList KeyboardTranslatorManager::allTranslators() } KeyboardTranslator::Entry::Entry() -: _keyCode(0) -, _modifiers(Qt::NoModifier) -, _modifierMask(Qt::NoModifier) -, _state(NoState) -, _stateMask(NoState) -, _command(NoCommand) + : _keyCode(0), + _modifiers(Qt::NoModifier), + _modifierMask(Qt::NoModifier), + _state(NoState), + _stateMask(NoState), + _command(NoCommand) { } -bool KeyboardTranslator::Entry::operator==(const Entry& rhs) const +bool KeyboardTranslator::Entry::operator==(const Entry &rhs) const { - return _keyCode == rhs._keyCode && - _modifiers == rhs._modifiers && - _modifierMask == rhs._modifierMask && - _state == rhs._state && - _stateMask == rhs._stateMask && - _command == rhs._command && - _text == rhs._text; + return _keyCode == rhs._keyCode && _modifiers == rhs._modifiers + && _modifierMask == rhs._modifierMask && _state == rhs._state + && _stateMask == rhs._stateMask && _command == rhs._command && _text == rhs._text; } -bool KeyboardTranslator::Entry::matches(int keyCode , - Qt::KeyboardModifiers modifiers, +bool KeyboardTranslator::Entry::matches(int keyCode, Qt::KeyboardModifiers modifiers, States testState) const { #ifdef Q_OS_MAC @@ -625,180 +582,196 @@ bool KeyboardTranslator::Entry::matches(int keyCode , modifiers &= ~Qt::KeypadModifier; #endif - if ( _keyCode != keyCode ) + if (_keyCode != keyCode) return false; - if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) ) + if ((modifiers & _modifierMask) != (_modifiers & _modifierMask)) return false; // if modifiers is non-zero, the 'any modifier' state is implicit - if ( (modifiers & ~Qt::KeypadModifier) != 0 ) + if ((modifiers & ~Qt::KeypadModifier) != 0) testState |= AnyModifierState; - if ( (testState & _stateMask) != (_state & _stateMask) ) + if ((testState & _stateMask) != (_state & _stateMask)) return false; // special handling for the 'Any Modifier' state, which checks for the presence of // any or no modifiers. In this context, the 'keypad' modifier does not count. bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier; bool wantAnyModifier = _state & KeyboardTranslator::AnyModifierState; - if ( _stateMask & KeyboardTranslator::AnyModifierState ) - { - if ( wantAnyModifier != anyModifiersSet ) - return false; + if (_stateMask & KeyboardTranslator::AnyModifierState) { + if (wantAnyModifier != anyModifiersSet) + return false; } return true; } -QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const +QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards, + Qt::KeyboardModifiers modifiers) const { - QByteArray result(text(expandWildCards,modifiers)); + QByteArray result(text(expandWildCards, modifiers)); - for ( int i = 0 ; i < result.count() ; i++ ) - { + for (int i = 0; i < result.count(); i++) { char ch = result[i]; char replacement = 0; - switch ( ch ) - { - case 27 : replacement = 'E'; break; - case 8 : replacement = 'b'; break; - case 12 : replacement = 'f'; break; - case 9 : replacement = 't'; break; - case 13 : replacement = 'r'; break; - case 10 : replacement = 'n'; break; - default: - // any character which is not printable is replaced by an equivalent - // \xhh escape sequence (where 'hh' are the corresponding hex digits) - if ( !QChar(QLatin1Char(ch)).isPrint() ) - replacement = 'x'; + switch (ch) { + case 27: + replacement = 'E'; + break; + case 8: + replacement = 'b'; + break; + case 12: + replacement = 'f'; + break; + case 9: + replacement = 't'; + break; + case 13: + replacement = 'r'; + break; + case 10: + replacement = 'n'; + break; + default: + // any character which is not printable is replaced by an equivalent + // \xhh escape sequence (where 'hh' are the corresponding hex digits) + if (!QChar(QLatin1Char(ch)).isPrint()) + replacement = 'x'; } - if ( replacement == 'x' ) - { - result.replace(i,1,"\\x"+QByteArray(1,ch).toHex()); - } else if ( replacement != 0 ) - { - result.remove(i,1); - result.insert(i,'\\'); - result.insert(i+1,replacement); + if (replacement == 'x') { + result.replace(i, 1, "\\x" + QByteArray(1, ch).toHex()); + } else if (replacement != 0) { + result.remove(i, 1); + result.insert(i, '\\'); + result.insert(i + 1, replacement); } } return result; } -QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const +QByteArray KeyboardTranslator::Entry::unescape(const QByteArray &input) const { QByteArray result(input); - for ( int i = 0 ; i < result.count()-1 ; i++ ) - { + for (int i = 0; i < result.count() - 1; i++) { QByteRef ch = result[i]; - if ( ch == '\\' ) - { - char replacement[2] = {0,0}; - int charsToRemove = 2; - bool escapedChar = true; - - switch ( result[i+1] ) - { - case 'E' : replacement[0] = 27; break; - case 'b' : replacement[0] = 8 ; break; - case 'f' : replacement[0] = 12; break; - case 't' : replacement[0] = 9 ; break; - case 'r' : replacement[0] = 13; break; - case 'n' : replacement[0] = 10; break; - case 'x' : - { - // format is \xh or \xhh where 'h' is a hexadecimal - // digit from 0-9 or A-F which should be replaced - // with the corresponding character value - char hexDigits[3] = {0}; - - if ( (i < result.count()-2) && isxdigit(result[i+2]) ) - hexDigits[0] = result[i+2]; - if ( (i < result.count()-3) && isxdigit(result[i+3]) ) - hexDigits[1] = result[i+3]; - - unsigned charValue = 0; - sscanf(hexDigits,"%x",&charValue); - - replacement[0] = (char)charValue; - charsToRemove = 2 + strlen(hexDigits); - } - break; - default: - escapedChar = false; - } - - if ( escapedChar ) - result.replace(i,charsToRemove,replacement); + if (ch == '\\') { + char replacement[2] = { 0, 0 }; + int charsToRemove = 2; + bool escapedChar = true; + + switch (result[i + 1]) { + case 'E': + replacement[0] = 27; + break; + case 'b': + replacement[0] = 8; + break; + case 'f': + replacement[0] = 12; + break; + case 't': + replacement[0] = 9; + break; + case 'r': + replacement[0] = 13; + break; + case 'n': + replacement[0] = 10; + break; + case 'x': { + // format is \xh or \xhh where 'h' is a hexadecimal + // digit from 0-9 or A-F which should be replaced + // with the corresponding character value + char hexDigits[3] = { 0 }; + + if ((i < result.count() - 2) && isxdigit(result[i + 2])) + hexDigits[0] = result[i + 2]; + if ((i < result.count() - 3) && isxdigit(result[i + 3])) + hexDigits[1] = result[i + 3]; + + unsigned charValue = 0; + sscanf(hexDigits, "%x", &charValue); + + replacement[0] = (char)charValue; + charsToRemove = 2 + strlen(hexDigits); + } break; + default: + escapedChar = false; + } + + if (escapedChar) + result.replace(i, charsToRemove, replacement); } } return result; } -void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const +void KeyboardTranslator::Entry::insertModifier(QString &item, int modifier) const { - if ( !(modifier & _modifierMask) ) + if (!(modifier & _modifierMask)) return; - if ( modifier & _modifiers ) + if (modifier & _modifiers) item += QLatin1Char('+'); else item += QLatin1Char('-'); - if ( modifier == Qt::ShiftModifier ) + if (modifier == Qt::ShiftModifier) item += QLatin1String("Shift"); - else if ( modifier == Qt::ControlModifier ) + else if (modifier == Qt::ControlModifier) item += QLatin1String("Ctrl"); - else if ( modifier == Qt::AltModifier ) + else if (modifier == Qt::AltModifier) item += QLatin1String("Alt"); - else if ( modifier == Qt::MetaModifier ) + else if (modifier == Qt::MetaModifier) item += QLatin1String("Meta"); - else if ( modifier == Qt::KeypadModifier ) + else if (modifier == Qt::KeypadModifier) item += QLatin1String("KeyPad"); } -void KeyboardTranslator::Entry::insertState( QString& item , int state ) const +void KeyboardTranslator::Entry::insertState(QString &item, int state) const { - if ( !(state & _stateMask) ) + if (!(state & _stateMask)) return; - if ( state & _state ) - item += QLatin1Char('+') ; + if (state & _state) + item += QLatin1Char('+'); else - item += QLatin1Char('-') ; + item += QLatin1Char('-'); - if ( state == KeyboardTranslator::AlternateScreenState ) + if (state == KeyboardTranslator::AlternateScreenState) item += QLatin1String("AppScreen"); - else if ( state == KeyboardTranslator::NewLineState ) + else if (state == KeyboardTranslator::NewLineState) item += QLatin1String("NewLine"); - else if ( state == KeyboardTranslator::AnsiState ) + else if (state == KeyboardTranslator::AnsiState) item += QLatin1String("Ansi"); - else if ( state == KeyboardTranslator::CursorKeysState ) + else if (state == KeyboardTranslator::CursorKeysState) item += QLatin1String("AppCursorKeys"); - else if ( state == KeyboardTranslator::AnyModifierState ) + else if (state == KeyboardTranslator::AnyModifierState) item += QLatin1String("AnyModifier"); - else if ( state == KeyboardTranslator::ApplicationKeypadState ) + else if (state == KeyboardTranslator::ApplicationKeypadState) item += QLatin1String("AppKeypad"); } -QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const +QString KeyboardTranslator::Entry::resultToString(bool expandWildCards, + Qt::KeyboardModifiers modifiers) const { - if ( !_text.isEmpty() ) - return QString::fromLatin1(escapedText(expandWildCards,modifiers)); - else if ( _command == EraseCommand ) + if (!_text.isEmpty()) + return QString::fromLatin1(escapedText(expandWildCards, modifiers)); + else if (_command == EraseCommand) return QLatin1String("Erase"); - else if ( _command == ScrollPageUpCommand ) + else if (_command == ScrollPageUpCommand) return QLatin1String("ScrollPageUp"); - else if ( _command == ScrollPageDownCommand ) + else if (_command == ScrollPageDownCommand) return QLatin1String("ScrollPageDown"); - else if ( _command == ScrollLineUpCommand ) + else if (_command == ScrollLineUpCommand) return QLatin1String("ScrollLineUp"); - else if ( _command == ScrollLineDownCommand ) + else if (_command == ScrollLineDownCommand) return QLatin1String("ScrollLineDown"); - else if ( _command == ScrollLockCommand ) + else if (_command == ScrollLockCommand) return QLatin1String("ScrollLock"); else if (_command == ScrollUpToTopCommand) return QLatin1String("ScrollUpToTop"); @@ -811,28 +784,25 @@ QString KeyboardTranslator::Entry::conditionToString() const { QString result = QKeySequence(_keyCode).toString(); - insertModifier( result , Qt::ShiftModifier ); - insertModifier( result , Qt::ControlModifier ); - insertModifier( result , Qt::AltModifier ); - insertModifier( result , Qt::MetaModifier ); - insertModifier( result , Qt::KeypadModifier ); + insertModifier(result, Qt::ShiftModifier); + insertModifier(result, Qt::ControlModifier); + insertModifier(result, Qt::AltModifier); + insertModifier(result, Qt::MetaModifier); + insertModifier(result, Qt::KeypadModifier); - insertState( result , KeyboardTranslator::AlternateScreenState ); - insertState( result , KeyboardTranslator::NewLineState ); - insertState( result , KeyboardTranslator::AnsiState ); - insertState( result , KeyboardTranslator::CursorKeysState ); - insertState( result , KeyboardTranslator::AnyModifierState ); - insertState( result , KeyboardTranslator::ApplicationKeypadState ); + insertState(result, KeyboardTranslator::AlternateScreenState); + insertState(result, KeyboardTranslator::NewLineState); + insertState(result, KeyboardTranslator::AnsiState); + insertState(result, KeyboardTranslator::CursorKeysState); + insertState(result, KeyboardTranslator::AnyModifierState); + insertState(result, KeyboardTranslator::ApplicationKeypadState); return result; } -KeyboardTranslator::KeyboardTranslator(const QString& name) -: _name(name) -{ -} +KeyboardTranslator::KeyboardTranslator(const QString &name) : _name(name) { } -void KeyboardTranslator::setDescription(const QString& description) +void KeyboardTranslator::setDescription(const QString &description) { _description = description; } @@ -840,7 +810,7 @@ QString KeyboardTranslator::description() const { return _description; } -void KeyboardTranslator::setName(const QString& name) +void KeyboardTranslator::setName(const QString &name) { _name = name; } @@ -854,58 +824,54 @@ QList KeyboardTranslator::entries() const return _entries.values(); } -void KeyboardTranslator::addEntry(const Entry& entry) +void KeyboardTranslator::addEntry(const Entry &entry) { const int keyCode = entry.keyCode(); - _entries.insert(keyCode,entry); + _entries.insert(keyCode, entry); } -void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement) +void KeyboardTranslator::replaceEntry(const Entry &existing, const Entry &replacement) { - if ( !existing.isNull() ) - _entries.remove(existing.keyCode(),existing); - _entries.insert(replacement.keyCode(),replacement); + if (!existing.isNull()) + _entries.remove(existing.keyCode(), existing); + _entries.insert(replacement.keyCode(), replacement); } -void KeyboardTranslator::removeEntry(const Entry& entry) +void KeyboardTranslator::removeEntry(const Entry &entry) { - _entries.remove(entry.keyCode(),entry); + _entries.remove(entry.keyCode(), entry); } -KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const +KeyboardTranslator::Entry +KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const { - for (auto it = _entries.cbegin(), end = _entries.cend(); it != end; ++it) - { + for (auto it = _entries.cbegin(), end = _entries.cend(); it != end; ++it) { if (it.key() == keyCode) - if ( it.value().matches(keyCode,modifiers,state) ) + if (it.value().matches(keyCode, modifiers, state)) return *it; } return Entry(); // entry not found } -void KeyboardTranslatorManager::addTranslator(KeyboardTranslator* translator) +void KeyboardTranslatorManager::addTranslator(KeyboardTranslator *translator) { - _translators.insert(translator->name(),translator); + _translators.insert(translator->name(), translator); - if ( !saveTranslator(translator) ) - qDebug() << "Unable to save translator" << translator->name() - << "to disk."; + if (!saveTranslator(translator)) + qDebug() << "Unable to save translator" << translator->name() << "to disk."; } -bool KeyboardTranslatorManager::deleteTranslator(const QString& name) +bool KeyboardTranslatorManager::deleteTranslator(const QString &name) { - Q_ASSERT( _translators.contains(name) ); + Q_ASSERT(_translators.contains(name)); // locate and delete QString path = findTranslatorPath(name); - if ( QFile::remove(path) ) - { + if (QFile::remove(path)) { _translators.remove(name); return true; - } - else - { + } else { qDebug() << "Failed to remove translator - " << path; return false; } } -Q_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager ) -KeyboardTranslatorManager* KeyboardTranslatorManager::instance() +Q_GLOBAL_STATIC(KeyboardTranslatorManager, theKeyboardTranslatorManager) +KeyboardTranslatorManager *KeyboardTranslatorManager::instance() { return theKeyboardTranslatorManager; } diff --git a/lib/KeyboardTranslator.h b/lib/KeyboardTranslator.h index 4ca6b866..de115cfb 100644 --- a/lib/KeyboardTranslator.h +++ b/lib/KeyboardTranslator.h @@ -36,8 +36,7 @@ class QIODevice; class QTextStream; -namespace Konsole -{ +namespace Konsole { /** * A convertor which maps between key sequences pressed by the user and the @@ -63,8 +62,7 @@ class KeyboardTranslator * This enum describes the states which may be associated with with a particular * entry in the keyboard translation entry. */ - enum State - { + enum State { /** Indicates that no special state is active */ NoState = 0, /** @@ -90,13 +88,12 @@ class KeyboardTranslator /** Indicates that the numpad is in application mode. */ ApplicationKeypadState = 32 }; - Q_DECLARE_FLAGS(States,State) + Q_DECLARE_FLAGS(States, State) /** * This enum describes commands which are associated with particular key sequences. */ - enum Command - { + enum Command { /** Indicates that no command is associated with this command sequence */ NoCommand = 0, /** TODO Document me */ @@ -118,7 +115,7 @@ class KeyboardTranslator /** Echos the operating system specific erase character. */ EraseCommand = 256 }; - Q_DECLARE_FLAGS(Commands,Command) + Q_DECLARE_FLAGS(Commands, Command) /** * Represents an association between a key sequence pressed by the user @@ -160,7 +157,7 @@ class KeyboardTranslator Qt::KeyboardModifiers modifiers = Qt::NoModifier) const; /** Sets the character sequence associated with this entry */ - void setText(const QByteArray& text); + void setText(const QByteArray &text); /** * Returns the character sequence associated with this entry, @@ -193,9 +190,9 @@ class KeyboardTranslator Qt::KeyboardModifiers modifierMask() const; /** See modifiers() */ - void setModifiers( Qt::KeyboardModifiers modifiers ); + void setModifiers(Qt::KeyboardModifiers modifiers); /** See modifierMask() and modifiers() */ - void setModifierMask( Qt::KeyboardModifiers modifiers ); + void setModifierMask(Qt::KeyboardModifiers modifiers); /** * Returns a bitwise-OR of the enabled state flags associated with this entry. @@ -211,15 +208,15 @@ class KeyboardTranslator States stateMask() const; /** See state() */ - void setState( States state ); + void setState(States state); /** See stateMask() */ - void setStateMask( States mask ); + void setStateMask(States mask); /** * Returns the key code and modifiers associated with this entry * as a QKeySequence */ - //QKeySequence keySequence() const; + // QKeySequence keySequence() const; /** * Returns this entry's conditions ( ie. its key code, modifier and state criteria ) @@ -241,16 +238,14 @@ class KeyboardTranslator * Returns true if this entry matches the given key sequence, specified * as a combination of @p keyCode , @p modifiers and @p state. */ - bool matches( int keyCode , - Qt::KeyboardModifiers modifiers , - States flags ) const; + bool matches(int keyCode, Qt::KeyboardModifiers modifiers, States flags) const; - bool operator==(const Entry& rhs) const; + bool operator==(const Entry &rhs) const; private: - void insertModifier( QString& item , int modifier ) const; - void insertState( QString& item , int state ) const; - QByteArray unescape(const QByteArray& text) const; + void insertModifier(QString &item, int modifier) const; + void insertState(QString &item, int state) const; + QByteArray unescape(const QByteArray &text) const; int _keyCode; Qt::KeyboardModifiers _modifiers; @@ -263,21 +258,21 @@ class KeyboardTranslator }; /** Constructs a new keyboard translator with the given @p name */ - KeyboardTranslator(const QString& name); + KeyboardTranslator(const QString &name); - //KeyboardTranslator(const KeyboardTranslator& other); + // KeyboardTranslator(const KeyboardTranslator& other); /** Returns the name of this keyboard translator */ QString name() const; /** Sets the name of this keyboard translator */ - void setName(const QString& name); + void setName(const QString &name); /** Returns the descriptive name of this keyboard translator */ QString description() const; /** Sets the descriptive name of this keyboard translator */ - void setDescription(const QString& description); + void setDescription(const QString &description); /** * Looks for an entry in this keyboard translator which matches the given @@ -290,26 +285,24 @@ class KeyboardTranslator * @param modifiers A combination of modifiers * @param state Optional flags which specify the current state of the terminal */ - Entry findEntry(int keyCode , - Qt::KeyboardModifiers modifiers , - States state = NoState) const; + Entry findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state = NoState) const; /** * Adds an entry to this keyboard translator's table. Entries can be looked up according * to their key sequence using findEntry() */ - void addEntry(const Entry& entry); + void addEntry(const Entry &entry); /** * Replaces an entry in the translator. If the @p existing entry is null, * then this is equivalent to calling addEntry(@p replacement) */ - void replaceEntry(const Entry& existing , const Entry& replacement); + void replaceEntry(const Entry &existing, const Entry &replacement); /** * Removes an entry from the table. */ - void removeEntry(const Entry& entry); + void removeEntry(const Entry &entry); /** Returns a list of all entries in the translator. */ QList entries() const; @@ -318,10 +311,9 @@ class KeyboardTranslator static const Qt::KeyboardModifier CTRL_MOD; private: - - QMultiHash _entries; // entries in this keyboard translation, - // entries are indexed according to - // their keycode + QMultiHash _entries; // entries in this keyboard translation, + // entries are indexed according to + // their keycode QString _name; QString _description; }; @@ -360,7 +352,7 @@ class KeyboardTranslatorReader { public: /** Constructs a new reader which parses the given @p source */ - KeyboardTranslatorReader( QIODevice* source ); + KeyboardTranslatorReader(QIODevice *source); /** * Returns the description text. @@ -385,38 +377,27 @@ class KeyboardTranslatorReader * * The condition and result strings are in the same format as in */ - static KeyboardTranslator::Entry createEntry( const QString& condition , - const QString& result ); + static KeyboardTranslator::Entry createEntry(const QString &condition, const QString &result); + private: struct Token { - enum Type - { - TitleKeyword, - TitleText, - KeyKeyword, - KeySequence, - Command, - OutputText - }; + enum Type { TitleKeyword, TitleText, KeyKeyword, KeySequence, Command, OutputText }; Type type; QString text; }; - QList tokenize(const QString&); + QList tokenize(const QString &); void readNext(); - bool decodeSequence(const QString& , - int& keyCode, - Qt::KeyboardModifiers& modifiers, - Qt::KeyboardModifiers& modifierMask, - KeyboardTranslator::States& state, - KeyboardTranslator::States& stateFlags); - - static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier); - static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state); - static bool parseAsKeyCode(const QString& item , int& keyCode); - static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command); - - QIODevice* _source; + bool decodeSequence(const QString &, int &keyCode, Qt::KeyboardModifiers &modifiers, + Qt::KeyboardModifiers &modifierMask, KeyboardTranslator::States &state, + KeyboardTranslator::States &stateFlags); + + static bool parseAsModifier(const QString &item, Qt::KeyboardModifier &modifier); + static bool parseAsStateFlag(const QString &item, KeyboardTranslator::State &state); + static bool parseAsKeyCode(const QString &item, int &keyCode); + static bool parseAsCommand(const QString &text, KeyboardTranslator::Command &command); + + QIODevice *_source; QString _description; KeyboardTranslator::Entry _nextEntry; bool _hasNext; @@ -430,20 +411,20 @@ class KeyboardTranslatorWriter * Constructs a new writer which saves data into @p destination. * The caller is responsible for closing the device when writing is complete. */ - KeyboardTranslatorWriter(QIODevice* destination); + KeyboardTranslatorWriter(QIODevice *destination); ~KeyboardTranslatorWriter(); /** * Writes the header for the keyboard translator. * @param description Description of the keyboard translator. */ - void writeHeader( const QString& description ); + void writeHeader(const QString &description); /** Writes a translator entry. */ - void writeEntry( const KeyboardTranslator::Entry& entry ); + void writeEntry(const KeyboardTranslator::Entry &entry); private: - QIODevice* _destination; - QTextStream* _writer; + QIODevice *_destination; + QTextStream *_writer; }; /** @@ -463,8 +444,8 @@ class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager KeyboardTranslatorManager(); ~KeyboardTranslatorManager(); - KeyboardTranslatorManager(const KeyboardTranslatorManager&) = delete; - KeyboardTranslatorManager& operator=(const KeyboardTranslatorManager&) = delete; + KeyboardTranslatorManager(const KeyboardTranslatorManager &) = delete; + KeyboardTranslatorManager &operator=(const KeyboardTranslatorManager &) = delete; /** * Adds a new translator. If a translator with the same name @@ -472,17 +453,17 @@ class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager * * TODO: More documentation. */ - void addTranslator(KeyboardTranslator* translator); + void addTranslator(KeyboardTranslator *translator); /** * Deletes a translator. Returns true on successful deletion or false otherwise. * * TODO: More documentation */ - bool deleteTranslator(const QString& name); + bool deleteTranslator(const QString &name); /** Returns the default translator for Konsole. */ - const KeyboardTranslator* defaultTranslator(); + const KeyboardTranslator *defaultTranslator(); /** * Returns the keyboard translator with the given name or 0 if no translator @@ -491,7 +472,7 @@ class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager * The first time that a translator with a particular name is requested, * the on-disk .keyboard file is loaded and parsed. */ - const KeyboardTranslator* findTranslator(const QString& name); + const KeyboardTranslator *findTranslator(const QString &name); /** * Returns a list of the names of available keyboard translators. * @@ -501,51 +482,66 @@ class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager QList allTranslators(); /** Returns the global KeyboardTranslatorManager instance. */ - static KeyboardTranslatorManager* instance(); + static KeyboardTranslatorManager *instance(); private: static const QByteArray defaultTranslatorText; void findTranslators(); // locate the available translators - KeyboardTranslator* loadTranslator(const QString& name); // loads the translator + KeyboardTranslator *loadTranslator(const QString &name); // loads the translator // with the given name - KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name); + KeyboardTranslator *loadTranslator(QIODevice *device, const QString &name); - bool saveTranslator(const KeyboardTranslator* translator); - QString findTranslatorPath(const QString& name); + bool saveTranslator(const KeyboardTranslator *translator); + QString findTranslatorPath(const QString &name); - QHash _translators; // maps translator-name -> KeyboardTranslator - // instance + QHash _translators; // maps translator-name -> KeyboardTranslator + // instance bool _haveLoadedAll; }; -inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; } -inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; } +inline int KeyboardTranslator::Entry::keyCode() const +{ + return _keyCode; +} +inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) +{ + _keyCode = keyCode; +} -inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier ) +inline void KeyboardTranslator::Entry::setModifiers(Qt::KeyboardModifiers modifier) { _modifiers = modifier; } -inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; } +inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const +{ + return _modifiers; +} -inline void KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask ) +inline void KeyboardTranslator::Entry::setModifierMask(Qt::KeyboardModifiers mask) +{ + _modifierMask = mask; +} +inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { - _modifierMask = mask; + return _modifierMask; } -inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; } inline bool KeyboardTranslator::Entry::isNull() const { - return ( *this == Entry() ); + return (*this == Entry()); } -inline void KeyboardTranslator::Entry::setCommand( Command command ) +inline void KeyboardTranslator::Entry::setCommand(Command command) { _command = command; } -inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const { return _command; } +inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const +{ + return _command; +} -inline void KeyboardTranslator::Entry::setText( const QByteArray& text ) +inline void KeyboardTranslator::Entry::setText(const QByteArray &text) { _text = unescape(text); } @@ -553,19 +549,18 @@ inline int oneOrZero(int value) { return value ? 1 : 0; } -inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const +inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards, + Qt::KeyboardModifiers modifiers) const { QByteArray expandedText = _text; - if (expandWildCards) - { + if (expandWildCards) { int modifierValue = 1; modifierValue += oneOrZero(modifiers & Qt::ShiftModifier); modifierValue += oneOrZero(modifiers & Qt::AltModifier) << 1; modifierValue += oneOrZero(modifiers & KeyboardTranslator::CTRL_MOD) << 2; - for (int i=0;i<_text.length();i++) - { + for (int i = 0; i < _text.length(); i++) { if (expandedText[i] == '*') expandedText[i] = '0' + modifierValue; } @@ -574,22 +569,27 @@ inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::Keybo return expandedText; } -inline void KeyboardTranslator::Entry::setState( States state ) +inline void KeyboardTranslator::Entry::setState(States state) { _state = state; } -inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; } +inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const +{ + return _state; +} -inline void KeyboardTranslator::Entry::setStateMask( States stateMask ) +inline void KeyboardTranslator::Entry::setStateMask(States stateMask) { _stateMask = stateMask; } -inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; } +inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const +{ + return _stateMask; +} } Q_DECLARE_METATYPE(Konsole::KeyboardTranslator::Entry) -Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator*) +Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator *) #endif // KEYBOARDTRANSLATOR_H - diff --git a/lib/Pty.cpp b/lib/Pty.cpp index 821517a3..44eb2bfe 100644 --- a/lib/Pty.cpp +++ b/lib/Pty.cpp @@ -48,41 +48,38 @@ using namespace Konsole; void Pty::setWindowSize(int lines, int cols) { - _windowColumns = cols; - _windowLines = lines; + _windowColumns = cols; + _windowLines = lines; - if (pty()->masterFd() >= 0) - pty()->setWinSize(lines, cols); + if (pty()->masterFd() >= 0) + pty()->setWinSize(lines, cols); } QSize Pty::windowSize() const { - return {_windowColumns,_windowLines}; + return { _windowColumns, _windowLines }; } void Pty::setFlowControlEnabled(bool enable) { - _xonXoff = enable; + _xonXoff = enable; - if (pty()->masterFd() >= 0) - { - struct ::termios ttmode; - pty()->tcGetAttr(&ttmode); - if (!enable) - ttmode.c_iflag &= ~(IXOFF | IXON); - else - ttmode.c_iflag |= (IXOFF | IXON); - if (!pty()->tcSetAttr(&ttmode)) - qWarning() << "Unable to set terminal attributes."; - } + if (pty()->masterFd() >= 0) { + struct ::termios ttmode; + pty()->tcGetAttr(&ttmode); + if (!enable) + ttmode.c_iflag &= ~(IXOFF | IXON); + else + ttmode.c_iflag |= (IXOFF | IXON); + if (!pty()->tcSetAttr(&ttmode)) + qWarning() << "Unable to set terminal attributes."; + } } bool Pty::flowControlEnabled() const { - if (pty()->masterFd() >= 0) - { + if (pty()->masterFd() >= 0) { struct ::termios ttmode; pty()->tcGetAttr(&ttmode); - return ttmode.c_iflag & IXOFF && - ttmode.c_iflag & IXON; + return ttmode.c_iflag & IXOFF && ttmode.c_iflag & IXON; } qWarning() << "Unable to get flow control status, terminal not connected."; return false; @@ -91,40 +88,37 @@ bool Pty::flowControlEnabled() const void Pty::setUtf8Mode(bool enable) { #ifdef IUTF8 // XXX not a reasonable place to check it. - _utf8 = enable; + _utf8 = enable; - if (pty()->masterFd() >= 0) - { - struct ::termios ttmode; - pty()->tcGetAttr(&ttmode); - if (!enable) - ttmode.c_iflag &= ~IUTF8; - else - ttmode.c_iflag |= IUTF8; - if (!pty()->tcSetAttr(&ttmode)) - qWarning() << "Unable to set terminal attributes."; - } + if (pty()->masterFd() >= 0) { + struct ::termios ttmode; + pty()->tcGetAttr(&ttmode); + if (!enable) + ttmode.c_iflag &= ~IUTF8; + else + ttmode.c_iflag |= IUTF8; + if (!pty()->tcSetAttr(&ttmode)) + qWarning() << "Unable to set terminal attributes."; + } #endif } void Pty::setErase(char erase) { - _eraseChar = erase; + _eraseChar = erase; - if (pty()->masterFd() >= 0) - { - struct ::termios ttmode; - pty()->tcGetAttr(&ttmode); - ttmode.c_cc[VERASE] = erase; - if (!pty()->tcSetAttr(&ttmode)) - qWarning() << "Unable to set terminal attributes."; - } + if (pty()->masterFd() >= 0) { + struct ::termios ttmode; + pty()->tcGetAttr(&ttmode); + ttmode.c_cc[VERASE] = erase; + if (!pty()->tcSetAttr(&ttmode)) + qWarning() << "Unable to set terminal attributes."; + } } char Pty::erase() const { - if (pty()->masterFd() >= 0) - { + if (pty()->masterFd() >= 0) { struct ::termios ttyAttributes; pty()->tcGetAttr(&ttyAttributes); return ttyAttributes.c_cc[VERASE]; @@ -133,90 +127,86 @@ char Pty::erase() const return _eraseChar; } -void Pty::addEnvironmentVariables(const QStringList& environment) +void Pty::addEnvironmentVariables(const QStringList &environment) { QListIterator iter(environment); - while (iter.hasNext()) - { + while (iter.hasNext()) { QString pair = iter.next(); // split on the first '=' character int pos = pair.indexOf(QLatin1Char('=')); - if ( pos >= 0 ) - { + if (pos >= 0) { QString variable = pair.left(pos); - QString value = pair.mid(pos+1); + QString value = pair.mid(pos + 1); - setEnv(variable,value); + setEnv(variable, value); } } } -int Pty::start(const QString& program, - const QStringList& programArguments, - const QStringList& environment, - ulong winid, - bool addToUtmp - //const QString& dbusService, - //const QString& dbusSession - ) +int Pty::start(const QString &program, const QStringList &programArguments, + const QStringList &environment, ulong winid, bool addToUtmp + // const QString& dbusService, + // const QString& dbusSession +) { - clearProgram(); - - // For historical reasons, the first argument in programArguments is the - // name of the program to execute, so create a list consisting of all - // but the first argument to pass to setProgram() - Q_ASSERT(programArguments.count() >= 1); - setProgram(program, programArguments.mid(1)); - - addEnvironmentVariables(environment); - - setEnv(QLatin1String("WINDOWID"), QString::number(winid)); - setEnv(QLatin1String("COLORTERM"), QLatin1String("truecolor")); - - // unless the LANGUAGE environment variable has been set explicitly - // set it to a null string - // this fixes the problem where KCatalog sets the LANGUAGE environment - // variable during the application's startup to something which - // differs from LANG,LC_* etc. and causes programs run from - // the terminal to display messages in the wrong language - // - // this can happen if LANG contains a language which KDE - // does not have a translation for - // - // BR:149300 - setEnv(QLatin1String("LANGUAGE"),QString(),false /* do not overwrite existing value if any */); - - setUseUtmp(addToUtmp); - - struct ::termios ttmode; - pty()->tcGetAttr(&ttmode); - if (!_xonXoff) - ttmode.c_iflag &= ~(IXOFF | IXON); - else - ttmode.c_iflag |= (IXOFF | IXON); + clearProgram(); + + // For historical reasons, the first argument in programArguments is the + // name of the program to execute, so create a list consisting of all + // but the first argument to pass to setProgram() + Q_ASSERT(programArguments.count() >= 1); + setProgram(program, programArguments.mid(1)); + + addEnvironmentVariables(environment); + + setEnv(QLatin1String("WINDOWID"), QString::number(winid)); + setEnv(QLatin1String("COLORTERM"), QLatin1String("truecolor")); + + // unless the LANGUAGE environment variable has been set explicitly + // set it to a null string + // this fixes the problem where KCatalog sets the LANGUAGE environment + // variable during the application's startup to something which + // differs from LANG,LC_* etc. and causes programs run from + // the terminal to display messages in the wrong language + // + // this can happen if LANG contains a language which KDE + // does not have a translation for + // + // BR:149300 + setEnv(QLatin1String("LANGUAGE"), QString(), + false /* do not overwrite existing value if any */); + + setUseUtmp(addToUtmp); + + struct ::termios ttmode; + pty()->tcGetAttr(&ttmode); + if (!_xonXoff) + ttmode.c_iflag &= ~(IXOFF | IXON); + else + ttmode.c_iflag |= (IXOFF | IXON); #ifdef IUTF8 // XXX not a reasonable place to check it. - if (!_utf8) - ttmode.c_iflag &= ~IUTF8; - else - ttmode.c_iflag |= IUTF8; + if (!_utf8) + ttmode.c_iflag &= ~IUTF8; + else + ttmode.c_iflag |= IUTF8; #endif - if (_eraseChar != 0) - ttmode.c_cc[VERASE] = _eraseChar; + if (_eraseChar != 0) + ttmode.c_cc[VERASE] = _eraseChar; - if (!pty()->tcSetAttr(&ttmode)) - qWarning() << "Unable to set terminal attributes."; + if (!pty()->tcSetAttr(&ttmode)) + qWarning() << "Unable to set terminal attributes."; - pty()->setWinSize(_windowLines, _windowColumns); + pty()->setWinSize(_windowLines, _windowColumns); - KProcess::start(); + KProcess::start(); - if (!waitForStarted()) - return -1; + if (!waitForStarted()) + return -1; - return 0; + return 0; } void Pty::setEmptyPTYProperties() @@ -224,94 +214,88 @@ void Pty::setEmptyPTYProperties() struct ::termios ttmode; pty()->tcGetAttr(&ttmode); if (!_xonXoff) - ttmode.c_iflag &= ~(IXOFF | IXON); + ttmode.c_iflag &= ~(IXOFF | IXON); else - ttmode.c_iflag |= (IXOFF | IXON); - #ifdef IUTF8 // XXX not a reasonable place to check it. + ttmode.c_iflag |= (IXOFF | IXON); +#ifdef IUTF8 // XXX not a reasonable place to check it. if (!_utf8) - ttmode.c_iflag &= ~IUTF8; + ttmode.c_iflag &= ~IUTF8; else - ttmode.c_iflag |= IUTF8; - #endif + ttmode.c_iflag |= IUTF8; +#endif if (_eraseChar != 0) ttmode.c_cc[VERASE] = _eraseChar; if (!pty()->tcSetAttr(&ttmode)) - qWarning() << "Unable to set terminal attributes."; + qWarning() << "Unable to set terminal attributes."; } void Pty::setWriteable(bool writeable) { - struct stat sbuf; - stat(pty()->ttyName(), &sbuf); - if (writeable) - chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP); - else - chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH)); + struct stat sbuf; + stat(pty()->ttyName(), &sbuf); + if (writeable) + chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP); + else + chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP | S_IWOTH)); } -Pty::Pty(int masterFd, QObject* parent) - : KPtyProcess(masterFd,parent) +Pty::Pty(int masterFd, QObject *parent) : KPtyProcess(masterFd, parent) { init(); } -Pty::Pty(QObject* parent) - : KPtyProcess(parent) +Pty::Pty(QObject *parent) : KPtyProcess(parent) { init(); } void Pty::init() { - _windowColumns = 0; - _windowLines = 0; - _eraseChar = 0; - _xonXoff = true; - _utf8 =true; - - connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived())); - setPtyChannels(KPtyProcess::AllChannels); + _windowColumns = 0; + _windowLines = 0; + _eraseChar = 0; + _xonXoff = true; + _utf8 = true; + + connect(pty(), SIGNAL(readyRead()), this, SLOT(dataReceived())); + setPtyChannels(KPtyProcess::AllChannels); } -Pty::~Pty() -{ -} +Pty::~Pty() { } -void Pty::sendData(const char* data, int length) +void Pty::sendData(const char *data, int length) { - if (!length) - return; - - if (!pty()->write(data,length)) - { - qWarning() << "Pty::doSendJobs - Could not send input data to terminal process."; - return; - } + if (!length) + return; + + if (!pty()->write(data, length)) { + qWarning() << "Pty::doSendJobs - Could not send input data to terminal process."; + return; + } } void Pty::dataReceived() { - QByteArray data = pty()->readAll(); - emit receivedData(data.constData(),data.count()); + QByteArray data = pty()->readAll(); + emit receivedData(data.constData(), data.count()); } void Pty::lockPty(bool lock) { Q_UNUSED(lock); -// TODO: Support for locking the Pty - //if (lock) - //suspend(); - //else - //resume(); + // TODO: Support for locking the Pty + // if (lock) + // suspend(); + // else + // resume(); } int Pty::foregroundProcessGroup() const { int pid = tcgetpgrp(pty()->masterFd()); - if ( pid != -1 ) - { + if (pid != -1) { return pid; } @@ -332,8 +316,8 @@ void Pty::setupChildProcess() sigemptyset(&sigset); action.sa_handler = SIG_DFL; action.sa_flags = 0; - for (int signal=1;signal < NSIG; signal++) { - sigaction(signal,&action,nullptr); + for (int signal = 1; signal < NSIG; signal++) { + sigaction(signal, &action, nullptr); sigaddset(&sigset, signal); } sigprocmask(SIG_UNBLOCK, &sigset, nullptr); diff --git a/lib/Pty.h b/lib/Pty.h index f427a53a..148ebeee 100644 --- a/lib/Pty.h +++ b/lib/Pty.h @@ -55,12 +55,11 @@ namespace Konsole { * To start the terminal process, call the start() method * with the program name and appropriate arguments. */ -class Pty: public KPtyProcess +class Pty : public KPtyProcess { -Q_OBJECT - - public: + Q_OBJECT +public: /** * Constructs a new Pty. * @@ -70,13 +69,13 @@ Q_OBJECT * To start the terminal process, call the run() method with the * name of the program to start and appropriate arguments. */ - explicit Pty(QObject* parent = nullptr); + explicit Pty(QObject *parent = nullptr); /** * Construct a process using an open pty master. * See KPtyProcess::KPtyProcess() */ - explicit Pty(int ptyMasterFd, QObject* parent = nullptr); + explicit Pty(int ptyMasterFd, QObject *parent = nullptr); ~Pty() override; @@ -100,12 +99,8 @@ Q_OBJECT * @param dbusSession Specifies the value of the KONSOLE_DBUS_SESSION * environment variable in the process's environment. */ - int start( const QString& program, - const QStringList& arguments, - const QStringList& environment, - ulong winid, - bool addToUtmp - ); + int start(const QString &program, const QStringList &arguments, const QStringList &environment, + ulong winid, bool addToUtmp); /** * set properties for "EmptyPTY" @@ -150,7 +145,7 @@ Q_OBJECT */ int foregroundProcessGroup() const; - public slots: +public slots: /** * Put the pty into UTF-8 mode on systems which support it. @@ -175,9 +170,9 @@ Q_OBJECT * @param buffer Pointer to the data to send. * @param length Length of @p buffer. */ - void sendData(const char* buffer, int length); + void sendData(const char *buffer, int length); - signals: +signals: /** * Emitted when a new block of data is received from @@ -186,24 +181,24 @@ Q_OBJECT * @param buffer Pointer to the data received. * @param length Length of @p buffer */ - void receivedData(const char* buffer, int length); + void receivedData(const char *buffer, int length); - protected: - void setupChildProcess() override; +protected: + void setupChildProcess() override; - private slots: +private slots: // called when data is received from the terminal process void dataReceived(); - private: - void init(); +private: + void init(); // takes a list of key=value pairs and adds them // to the environment for the process - void addEnvironmentVariables(const QStringList& environment); + void addEnvironmentVariables(const QStringList &environment); - int _windowColumns; - int _windowLines; + int _windowColumns; + int _windowLines; char _eraseChar; bool _xonXoff; bool _utf8; diff --git a/lib/Screen.cpp b/lib/Screen.cpp index bd6a375d..25a1f4c2 100644 --- a/lib/Screen.cpp +++ b/lib/Screen.cpp @@ -43,49 +43,53 @@ using namespace Konsole; -//FIXME: this is emulation specific. Use false for xterm, true for ANSI. -//FIXME: see if we can get this from terminfo. +// FIXME: this is emulation specific. Use false for xterm, true for ANSI. +// FIXME: see if we can get this from terminfo. #define BS_CLEARS false -//Macro to convert x,y position on screen to position within an image. +// Macro to convert x,y position on screen to position within an image. // -//Originally the image was stored as one large contiguous block of -//memory, so a position within the image could be represented as an -//offset from the beginning of the block. For efficiency reasons this -//is no longer the case. -//Many internal parts of this class still use this representation for parameters and so on, -//notably moveImage() and clearImage(). -//This macro converts from an X,Y position into an image offset. +// Originally the image was stored as one large contiguous block of +// memory, so a position within the image could be represented as an +// offset from the beginning of the block. For efficiency reasons this +// is no longer the case. +// Many internal parts of this class still use this representation for parameters and so on, +// notably moveImage() and clearImage(). +// This macro converts from an X,Y position into an image offset. #ifndef loc -#define loc(X,Y) ((Y)*columns+(X)) +# define loc(X, Y) ((Y)*columns + (X)) #endif - -Character Screen::defaultChar = Character(' ', - CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR), - CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR), - DEFAULT_RENDITION); +Character Screen::defaultChar = + Character(' ', CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_FORE_COLOR), + CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_BACK_COLOR), DEFAULT_RENDITION); //#define REVERSE_WRAPPED_LINES // for wrapped line debug - Screen::Screen(int l, int c) -: lines(l), - columns(c), - screenLines(new ImageLine[lines+1] ), - _scrolledLines(0), - _droppedLines(0), - history(new HistoryScrollNone()), - cuX(0), cuY(0), - currentRendition(0), - _topMargin(0), _bottomMargin(0), - selBegin(0), selTopLeft(0), selBottomRight(0), - blockSelectionMode(false), - effectiveForeground(CharacterColor()), effectiveBackground(CharacterColor()), effectiveRendition(0), - lastPos(-1) -{ - lineProperties.resize(lines+1); - for (int i=0;i _bottomMargin ? lines-1 : _bottomMargin; - cuX = qMin(columns-1,cuX); // nowrap! - cuY = qMin(stop,cuY+n); + if (n == 0) + n = 1; // Default + int stop = cuY > _bottomMargin ? lines - 1 : _bottomMargin; + cuX = qMin(columns - 1, cuX); // nowrap! + cuY = qMin(stop, cuY + n); } void Screen::cursorLeft(int n) - //=CUB +//=CUB { - if (n == 0) n = 1; // Default - cuX = qMin(columns-1,cuX); // nowrap! - cuX = qMax(0,cuX-n); + if (n == 0) + n = 1; // Default + cuX = qMin(columns - 1, cuX); // nowrap! + cuX = qMax(0, cuX - n); } void Screen::cursorNextLine(int n) - //=CNL +//=CNL { if (n == 0) { n = 1; // Default @@ -140,18 +147,17 @@ void Screen::cursorNextLine(int n) } n--; } - } void Screen::cursorPreviousLine(int n) - //=CPL +//=CPL { if (n == 0) { n = 1; // Default } cuX = 0; while (n > 0) { - if (cuY > 0) { + if (cuY > 0) { cuY -= 1; } n--; @@ -159,28 +165,30 @@ void Screen::cursorPreviousLine(int n) } void Screen::cursorRight(int n) - //=CUF +//=CUF { - if (n == 0) n = 1; // Default - cuX = qMin(columns-1,cuX+n); + if (n == 0) + n = 1; // Default + cuX = qMin(columns - 1, cuX + n); } void Screen::setMargins(int top, int bot) - //=STBM -{ - if (top == 0) top = 1; // Default - if (bot == 0) bot = lines; // Default - top = top - 1; // Adjust to internal lineno - bot = bot - 1; // Adjust to internal lineno - if ( !( 0 <= top && top < bot && bot < lines ) ) - { //Debug()<<" setRegion("< 0) cuY -= 1; } void Screen::nextLine() - //=NEL +//=NEL { - toStartOfLine(); index(); + toStartOfLine(); + index(); } void Screen::eraseChars(int n) { - if (n == 0) n = 1; // Default - int p = qMax(0,qMin(cuX+n-1,columns-1)); - clearImage(loc(cuX,cuY),loc(p,cuY),' '); + if (n == 0) + n = 1; // Default + int p = qMax(0, qMin(cuX + n - 1, columns - 1)); + clearImage(loc(cuX, cuY), loc(p, cuY), ' '); } void Screen::deleteChars(int n) { - Q_ASSERT( n >= 0 ); + Q_ASSERT(n >= 0); // always delete at least one char if (n == 0) n = 1; // if cursor is beyond the end of the line there is nothing to do - if ( cuX >= screenLines[cuY].count() ) + if (cuX >= screenLines[cuY].count()) return; - if ( cuX+n > screenLines[cuY].count() ) + if (cuX + n > screenLines[cuY].count()) n = screenLines[cuY].count() - cuX; - Q_ASSERT( n >= 0 ); - Q_ASSERT( cuX+n <= screenLines[cuY].count() ); + Q_ASSERT(n >= 0); + Q_ASSERT(cuX + n <= screenLines[cuY].count()); - screenLines[cuY].remove(cuX,n); + screenLines[cuY].remove(cuX, n); } void Screen::insertChars(int n) { - if (n == 0) n = 1; // Default + if (n == 0) + n = 1; // Default - if ( screenLines[cuY].size() < cuX ) + if (screenLines[cuY].size() < cuX) screenLines[cuY].resize(cuX); - screenLines[cuY].insert(cuX,n,' '); + screenLines[cuY].insert(cuX, n, ' '); - if ( screenLines[cuY].count() > columns ) + if (screenLines[cuY].count() > columns) screenLines[cuY].resize(columns); } void Screen::repeatChars(int count) - //=REP +//=REP { - if (count == 0) - { + if (count == 0) { count = 1; } /** @@ -273,39 +283,44 @@ void Screen::repeatChars(int count) * character (those other than escape sequences). So, lastDrawnChar can be * safely used. */ - for (int i = 0; i < count; i++) - { + for (int i = 0; i < count; i++) { displayCharacter(lastDrawnChar); } } void Screen::deleteLines(int n) { - if (n == 0) n = 1; // Default - scrollUp(cuY,n); + if (n == 0) + n = 1; // Default + scrollUp(cuY, n); } void Screen::insertLines(int n) { - if (n == 0) n = 1; // Default - scrollDown(cuY,n); + if (n == 0) + n = 1; // Default + scrollDown(cuY, n); } void Screen::setMode(int m) { currentModes[m] = true; - switch(m) - { - case MODE_Origin : cuX = 0; cuY = _topMargin; break; //FIXME: home + switch (m) { + case MODE_Origin: + cuX = 0; + cuY = _topMargin; + break; // FIXME: home } } void Screen::resetMode(int m) { currentModes[m] = false; - switch(m) - { - case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home + switch (m) { + case MODE_Origin: + cuX = 0; + cuY = 0; + break; // FIXME: home } } @@ -327,7 +342,7 @@ bool Screen::getMode(int m) const void Screen::saveCursor() { savedState.cursorColumn = cuX; - savedState.cursorLine = cuY; + savedState.cursorLine = cuY; savedState.rendition = currentRendition; savedState.foreground = currentForeground; savedState.background = currentBackground; @@ -335,37 +350,37 @@ void Screen::saveCursor() void Screen::restoreCursor() { - cuX = qMin(savedState.cursorColumn,columns-1); - cuY = qMin(savedState.cursorLine,lines-1); - currentRendition = savedState.rendition; - currentForeground = savedState.foreground; - currentBackground = savedState.background; + cuX = qMin(savedState.cursorColumn, columns - 1); + cuY = qMin(savedState.cursorLine, lines - 1); + currentRendition = savedState.rendition; + currentForeground = savedState.foreground; + currentBackground = savedState.background; updateEffectiveRendition(); } void Screen::resizeImage(int new_lines, int new_columns) { - if ((new_lines==lines) && (new_columns==columns)) return; + if ((new_lines == lines) && (new_columns == columns)) + return; - if (cuY > new_lines-1) - { // attempt to preserve focus and lines - _bottomMargin = lines-1; //FIXME: margin lost - for (int i = 0; i < cuY-(new_lines-1); i++) - { - addHistLine(); scrollUp(0,1); + if (cuY > new_lines - 1) { // attempt to preserve focus and lines + _bottomMargin = lines - 1; // FIXME: margin lost + for (int i = 0; i < cuY - (new_lines - 1); i++) { + addHistLine(); + scrollUp(0, 1); } } // create new screen lines and copy from old to new - ImageLine* newScreenLines = new ImageLine[new_lines+1]; - for (int i=0; i < qMin(lines,new_lines+1) ;i++) - newScreenLines[i]=screenLines[i]; - for (int i=lines;(i > 0) && (i 0) && (i < new_lines + 1); i++) + newScreenLines[i].resize(new_columns); - lineProperties.resize(new_lines+1); - for (int i=lines;(i > 0) && (i 0) && (i < new_lines + 1); i++) lineProperties[i] = LINE_DEFAULT; clearSelection(); @@ -375,12 +390,12 @@ void Screen::resizeImage(int new_lines, int new_columns) lines = new_lines; columns = new_columns; - cuX = qMin(cuX,columns-1); - cuY = qMin(cuY,lines-1); + cuX = qMin(cuX, columns - 1); + cuY = qMin(cuY, lines - 1); // FIXME: try to keep values, evtl. - _topMargin=0; - _bottomMargin=lines-1; + _topMargin = 0; + _bottomMargin = lines - 1; initTabStops(); clearSelection(); } @@ -388,10 +403,9 @@ void Screen::resizeImage(int new_lines, int new_columns) void Screen::setDefaultMargins() { _topMargin = 0; - _bottomMargin = lines-1; + _bottomMargin = lines - 1; } - /* Clarifying rendition here and in the display. @@ -426,25 +440,22 @@ void Screen::setDefaultMargins() into RE_BOLD and RE_INTENSIVE. */ -void Screen::reverseRendition(Character& p) const +void Screen::reverseRendition(Character &p) const { CharacterColor f = p.foregroundColor; CharacterColor b = p.backgroundColor; p.foregroundColor = b; - p.backgroundColor = f; //p->r &= ~RE_TRANSPARENT; + p.backgroundColor = f; // p->r &= ~RE_TRANSPARENT; } void Screen::updateEffectiveRendition() { effectiveRendition = currentRendition; - if (currentRendition & RE_REVERSE) - { + if (currentRendition & RE_REVERSE) { effectiveForeground = currentBackground; effectiveBackground = currentForeground; - } - else - { + } else { effectiveForeground = currentForeground; effectiveBackground = currentBackground; } @@ -453,27 +464,23 @@ void Screen::updateEffectiveRendition() effectiveForeground.setIntensive(); } -void Screen::copyFromHistory(Character* dest, int startLine, int count) const +void Screen::copyFromHistory(Character *dest, int startLine, int count) const { - Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= history->getLines() ); + Q_ASSERT(startLine >= 0 && count > 0 && startLine + count <= history->getLines()); - for (int line = startLine; line < startLine + count; line++) - { - const int length = qMin(columns,history->getLineLen(line)); - const int destLineOffset = (line-startLine)*columns; + for (int line = startLine; line < startLine + count; line++) { + const int length = qMin(columns, history->getLineLen(line)); + const int destLineOffset = (line - startLine) * columns; - history->getCells(line,0,length,dest + destLineOffset); + history->getCells(line, 0, length, dest + destLineOffset); for (int column = length; column < columns; column++) - dest[destLineOffset+column] = defaultChar; + dest[destLineOffset + column] = defaultChar; // invert selected text - if (selBegin !=-1) - { - for (int column = 0; column < columns; column++) - { - if (isSelected(column,line)) - { + if (selBegin != -1) { + for (int column = 0; column < columns; column++) { + if (isSelected(column, line)) { reverseRendition(dest[destLineOffset + column]); } } @@ -481,84 +488,78 @@ void Screen::copyFromHistory(Character* dest, int startLine, int count) const } } -void Screen::copyFromScreen(Character* dest , int startLine , int count) const +void Screen::copyFromScreen(Character *dest, int startLine, int count) const { - Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= lines ); + Q_ASSERT(startLine >= 0 && count > 0 && startLine + count <= lines); - for (int line = startLine; line < (startLine+count) ; line++) - { - int srcLineStartIndex = line*columns; - int destLineStartIndex = (line-startLine)*columns; + for (int line = startLine; line < (startLine + count); line++) { + int srcLineStartIndex = line * columns; + int destLineStartIndex = (line - startLine) * columns; - for (int column = 0; column < columns; column++) - { + for (int column = 0; column < columns; column++) { int srcIndex = srcLineStartIndex + column; int destIndex = destLineStartIndex + column; - dest[destIndex] = screenLines[srcIndex/columns].value(srcIndex%columns,defaultChar); + dest[destIndex] = + screenLines[srcIndex / columns].value(srcIndex % columns, defaultChar); // invert selected text - if (selBegin != -1 && isSelected(column,line + history->getLines())) + if (selBegin != -1 && isSelected(column, line + history->getLines())) reverseRendition(dest[destIndex]); } - } } -void Screen::getImage( Character* dest, int size, int startLine, int endLine ) const +void Screen::getImage(Character *dest, int size, int startLine, int endLine) const { - Q_ASSERT( startLine >= 0 ); - Q_ASSERT( endLine >= startLine && endLine < history->getLines() + lines ); + Q_ASSERT(startLine >= 0); + Q_ASSERT(endLine >= startLine && endLine < history->getLines() + lines); const int mergedLines = endLine - startLine + 1; - Q_ASSERT( size >= mergedLines * columns ); - Q_UNUSED( size ); + Q_ASSERT(size >= mergedLines * columns); + Q_UNUSED(size); - const int linesInHistoryBuffer = qBound(0,history->getLines()-startLine,mergedLines); + const int linesInHistoryBuffer = qBound(0, history->getLines() - startLine, mergedLines); const int linesInScreenBuffer = mergedLines - linesInHistoryBuffer; // copy lines from history buffer if (linesInHistoryBuffer > 0) - copyFromHistory(dest,startLine,linesInHistoryBuffer); + copyFromHistory(dest, startLine, linesInHistoryBuffer); // copy lines from screen buffer if (linesInScreenBuffer > 0) - copyFromScreen(dest + linesInHistoryBuffer*columns, - startLine + linesInHistoryBuffer - history->getLines(), - linesInScreenBuffer); + copyFromScreen(dest + linesInHistoryBuffer * columns, + startLine + linesInHistoryBuffer - history->getLines(), linesInScreenBuffer); // invert display when in screen mode - if (getMode(MODE_Screen)) - { - for (int i = 0; i < mergedLines*columns; i++) + if (getMode(MODE_Screen)) { + for (int i = 0; i < mergedLines * columns; i++) reverseRendition(dest[i]); // for reverse display } // mark the character at the current cursor position int cursorIndex = loc(cuX, cuY + linesInHistoryBuffer); - if(getMode(MODE_Cursor) && cursorIndex < columns*mergedLines) + if (getMode(MODE_Cursor) && cursorIndex < columns * mergedLines) dest[cursorIndex].rendition |= RE_CURSOR; } -QVector Screen::getLineProperties( int startLine , int endLine ) const +QVector Screen::getLineProperties(int startLine, int endLine) const { - Q_ASSERT( startLine >= 0 ); - Q_ASSERT( endLine >= startLine && endLine < history->getLines() + lines ); + Q_ASSERT(startLine >= 0); + Q_ASSERT(endLine >= startLine && endLine < history->getLines() + lines); - const int mergedLines = endLine-startLine+1; - const int linesInHistory = qBound(0,history->getLines()-startLine,mergedLines); + const int mergedLines = endLine - startLine + 1; + const int linesInHistory = qBound(0, history->getLines() - startLine, mergedLines); const int linesInScreen = mergedLines - linesInHistory; QVector result(mergedLines); int index = 0; // copy properties for lines in history - for (int line = startLine; line < startLine + linesInHistory; line++) - { - //TODO Support for line properties other than wrapped lines - if (history->isWrappedLine(line)) - { + for (int line = startLine; line < startLine + linesInHistory; line++) { + // TODO Support for line properties other than wrapped lines + if (history->isWrappedLine(line)) { result[index] = (LineProperty)(result[index] | LINE_WRAPPED); } index++; @@ -566,9 +567,8 @@ QVector Screen::getLineProperties( int startLine , int endLine ) c // copy properties for lines in screen buffer const int firstScreenLine = startLine + linesInHistory - history->getLines(); - for (int line = firstScreenLine; line < firstScreenLine+linesInScreen; line++) - { - result[index]=lineProperties[line]; + for (int line = firstScreenLine; line < firstScreenLine + linesInScreen; line++) { + result[index] = lineProperties[line]; index++; } @@ -577,20 +577,23 @@ QVector Screen::getLineProperties( int startLine , int endLine ) c void Screen::reset(bool clearScreen) { - setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin - resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1] - resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke - setMode(MODE_Cursor); // cursor visible - resetMode(MODE_Screen); // screen not inverse + setMode(MODE_Wrap); + saveMode(MODE_Wrap); // wrap at end of margin + resetMode(MODE_Origin); + saveMode(MODE_Origin); // position refere to [1,1] + resetMode(MODE_Insert); + saveMode(MODE_Insert); // overstroke + setMode(MODE_Cursor); // cursor visible + resetMode(MODE_Screen); // screen not inverse resetMode(MODE_NewLine); - _topMargin=0; - _bottomMargin=lines-1; + _topMargin = 0; + _bottomMargin = lines - 1; setDefaultRendition(); saveCursor(); - if ( clearScreen ) + if (clearScreen) clear(); } @@ -602,11 +605,11 @@ void Screen::clear() void Screen::backspace() { - cuX = qMin(columns-1,cuX); // nowrap! - cuX = qMax(0,cuX-1); + cuX = qMin(columns - 1, cuX); // nowrap! + cuX = qMax(0, cuX - 1); - if (screenLines[cuY].size() < cuX+1) - screenLines[cuY].resize(cuX+1); + if (screenLines[cuY].size() < cuX + 1) + screenLines[cuY].resize(cuX + 1); if (BS_CLEARS) screenLines[cuY][cuX].character = ' '; @@ -615,11 +618,11 @@ void Screen::backspace() void Screen::tab(int n) { // note that TAB is a format effector (does not write ' '); - if (n == 0) n = 1; - while((n > 0) && (cuX < columns-1)) - { + if (n == 0) + n = 1; + while ((n > 0) && (cuX < columns - 1)) { cursorRight(1); - while((cuX < columns-1) && !tabStops[cuX]) + while ((cuX < columns - 1) && !tabStops[cuX]) cursorRight(1); n--; } @@ -628,22 +631,26 @@ void Screen::tab(int n) void Screen::backtab(int n) { // note that TAB is a format effector (does not write ' '); - if (n == 0) n = 1; - while((n > 0) && (cuX > 0)) - { - cursorLeft(1); while((cuX > 0) && !tabStops[cuX]) cursorLeft(1); + if (n == 0) + n = 1; + while ((n > 0) && (cuX > 0)) { + cursorLeft(1); + while ((cuX > 0) && !tabStops[cuX]) + cursorLeft(1); n--; } } void Screen::clearTabStops() { - for (int i = 0; i < columns; i++) tabStops[i] = false; + for (int i = 0; i < columns; i++) + tabStops[i] = false; } void Screen::changeTabStop(bool set) { - if (cuX >= columns) return; + if (cuX >= columns) + return; tabStops[cuX] = set; } @@ -655,7 +662,7 @@ void Screen::initTabStops() // i.e. the kids start counting from 0 instead of 1. // Other programs might behave correctly. Be aware. for (int i = 0; i < columns; i++) - tabStops[i] = (i%8 == 0 && i != 0); + tabStops[i] = (i % 8 == 0 && i != 0); } void Screen::newLine() @@ -670,8 +677,8 @@ void Screen::checkSelection(int from, int to) if (selBegin == -1) return; int scr_TL = loc(0, history->getLines()); - //Clear entire selection if it overlaps region [from, to] - if ( (selBottomRight >= (from+scr_TL)) && (selTopLeft <= (to+scr_TL)) ) + // Clear entire selection if it overlaps region [from, to] + if ((selBottomRight >= (from + scr_TL)) && (selTopLeft <= (to + scr_TL))) clearSelection(); } @@ -686,30 +693,29 @@ void Screen::displayCharacter(wchar_t c) if (w <= 0) return; - if (cuX+w > columns) { + if (cuX + w > columns) { if (getMode(MODE_Wrap)) { lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | LINE_WRAPPED); nextLine(); - } - else - cuX = columns-w; + } else + cuX = columns - w; } // ensure current line vector has enough elements int size = screenLines[cuY].size(); - if (size < cuX+w) - { - screenLines[cuY].resize(cuX+w); + if (size < cuX + w) { + screenLines[cuY].resize(cuX + w); } - if (getMode(MODE_Insert)) insertChars(w); + if (getMode(MODE_Insert)) + insertChars(w); - lastPos = loc(cuX,cuY); + lastPos = loc(cuX, cuY); // check if selection is still valid. checkSelection(lastPos, lastPos); - Character& currentChar = screenLines[cuY][cuX]; + Character ¤tChar = screenLines[cuY][cuX]; currentChar.character = c; currentChar.foregroundColor = effectiveForeground; @@ -720,14 +726,13 @@ void Screen::displayCharacter(wchar_t c) int i = 0; int newCursorX = cuX + w--; - while(w) - { + while (w) { i++; - if ( screenLines[cuY].size() < cuX + i + 1 ) - screenLines[cuY].resize(cuX+i+1); + if (screenLines[cuY].size() < cuX + i + 1) + screenLines[cuY].resize(cuX + i + 1); - Character& ch = screenLines[cuY][cuX + i]; + Character &ch = screenLines[cuY][cuX + i]; ch.character = 0; ch.foregroundColor = effectiveForeground; ch.backgroundColor = effectiveBackground; @@ -738,9 +743,9 @@ void Screen::displayCharacter(wchar_t c) cuX = newCursorX; } -void Screen::compose(const QString& /*compose*/) +void Screen::compose(const QString & /*compose*/) { - Q_ASSERT( 0 /*Not implemented yet*/ ); + Q_ASSERT(0 /*Not implemented yet*/); /* if (lastPos == -1) return; @@ -770,8 +775,10 @@ void Screen::resetScrolledLines() void Screen::scrollUp(int n) { - if (n == 0) n = 1; // Default - if (_topMargin == 0) addHistLine(); // history.history + if (n == 0) + n = 1; // Default + if (_topMargin == 0) + addHistLine(); // history.history scrollUp(_topMargin, n); } @@ -790,16 +797,17 @@ void Screen::scrollUp(int from, int n) n = _bottomMargin + 1 - from; _scrolledLines -= n; - _lastScrolledRegion = QRect(0,_topMargin,columns-1,(_bottomMargin-_topMargin)); + _lastScrolledRegion = QRect(0, _topMargin, columns - 1, (_bottomMargin - _topMargin)); - //FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds. - moveImage(loc(0,from),loc(0,from+n),loc(columns,_bottomMargin)); - clearImage(loc(0,_bottomMargin-n+1),loc(columns-1,_bottomMargin),' '); + // FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds. + moveImage(loc(0, from), loc(0, from + n), loc(columns, _bottomMargin)); + clearImage(loc(0, _bottomMargin - n + 1), loc(columns - 1, _bottomMargin), ' '); } void Screen::scrollDown(int n) { - if (n == 0) n = 1; // Default + if (n == 0) + n = 1; // Default scrollDown(_topMargin, n); } @@ -807,34 +815,37 @@ void Screen::scrollDown(int from, int n) { _scrolledLines += n; - //FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds. + // FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds. if (n <= 0) return; if (from > _bottomMargin) return; if (from + n > _bottomMargin) n = _bottomMargin - from; - moveImage(loc(0,from+n),loc(0,from),loc(columns-1,_bottomMargin-n)); - clearImage(loc(0,from),loc(columns-1,from+n-1),' '); + moveImage(loc(0, from + n), loc(0, from), loc(columns - 1, _bottomMargin - n)); + clearImage(loc(0, from), loc(columns - 1, from + n - 1), ' '); } void Screen::setCursorYX(int y, int x) { - setCursorY(y); setCursorX(x); + setCursorY(y); + setCursorX(x); } void Screen::setCursorX(int x) { - if (x == 0) x = 1; // Default + if (x == 0) + x = 1; // Default x -= 1; // Adjust - cuX = qMax(0,qMin(columns-1, x)); + cuX = qMax(0, qMin(columns - 1, x)); } void Screen::setCursorY(int y) { - if (y == 0) y = 1; // Default + if (y == 0) + y = 1; // Default y -= 1; // Adjust - cuY = qMax(0,qMin(lines -1, y + (getMode(MODE_Origin) ? _topMargin : 0) )); + cuY = qMax(0, qMin(lines - 1, y + (getMode(MODE_Origin) ? _topMargin : 0))); } void Screen::home() @@ -860,95 +871,83 @@ int Screen::getCursorY() const void Screen::clearImage(int loca, int loce, char c) { - int scr_TL=loc(0,history->getLines()); - //FIXME: check positions + int scr_TL = loc(0, history->getLines()); + // FIXME: check positions - //Clear entire selection if it overlaps region to be moved... - if ( (selBottomRight > (loca+scr_TL) )&&(selTopLeft < (loce+scr_TL)) ) - { + // Clear entire selection if it overlaps region to be moved... + if ((selBottomRight > (loca + scr_TL)) && (selTopLeft < (loce + scr_TL))) { clearSelection(); } - int topLine = loca/columns; - int bottomLine = loce/columns; + int topLine = loca / columns; + int bottomLine = loce / columns; - Character clearCh(c,currentForeground,currentBackground,DEFAULT_RENDITION); + Character clearCh(c, currentForeground, currentBackground, DEFAULT_RENDITION); - //if the character being used to clear the area is the same as the - //default character, the affected lines can simply be shrunk. + // if the character being used to clear the area is the same as the + // default character, the affected lines can simply be shrunk. bool isDefaultCh = (clearCh == Character()); - for (int y=topLine;y<=bottomLine;y++) - { + for (int y = topLine; y <= bottomLine; y++) { lineProperties[y] = 0; - int endCol = ( y == bottomLine) ? loce%columns : columns-1; - int startCol = ( y == topLine ) ? loca%columns : 0; + int endCol = (y == bottomLine) ? loce % columns : columns - 1; + int startCol = (y == topLine) ? loca % columns : 0; - QVector& line = screenLines[y]; + QVector &line = screenLines[y]; - if ( isDefaultCh && endCol == columns-1 ) - { + if (isDefaultCh && endCol == columns - 1) { line.resize(startCol); - } - else - { + } else { if (line.size() < endCol + 1) - line.resize(endCol+1); + line.resize(endCol + 1); - Character* data = line.data(); - for (int i=startCol;i<=endCol;i++) - data[i]=clearCh; + Character *data = line.data(); + for (int i = startCol; i <= endCol; i++) + data[i] = clearCh; } } } void Screen::moveImage(int dest, int sourceBegin, int sourceEnd) { - Q_ASSERT( sourceBegin <= sourceEnd ); + Q_ASSERT(sourceBegin <= sourceEnd); - int lines=(sourceEnd-sourceBegin)/columns; + int lines = (sourceEnd - sourceBegin) / columns; - //move screen image and line properties: - //the source and destination areas of the image may overlap, - //so it matters that we do the copy in the right order - - //forwards if dest < sourceBegin or backwards otherwise. + // move screen image and line properties: + // the source and destination areas of the image may overlap, + // so it matters that we do the copy in the right order - + // forwards if dest < sourceBegin or backwards otherwise. //(search the web for 'memmove implementation' for details) - if (dest < sourceBegin) - { - for (int i=0;i<=lines;i++) - { - screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ]; - lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i]; + if (dest < sourceBegin) { + for (int i = 0; i <= lines; i++) { + screenLines[(dest / columns) + i] = screenLines[(sourceBegin / columns) + i]; + lineProperties[(dest / columns) + i] = lineProperties[(sourceBegin / columns) + i]; } - } - else - { - for (int i=lines;i>=0;i--) - { - screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ]; - lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i]; + } else { + for (int i = lines; i >= 0; i--) { + screenLines[(dest / columns) + i] = screenLines[(sourceBegin / columns) + i]; + lineProperties[(dest / columns) + i] = lineProperties[(sourceBegin / columns) + i]; } } - if (lastPos != -1) - { + if (lastPos != -1) { int diff = dest - sourceBegin; // Scroll by this amount lastPos += diff; - if ((lastPos < 0) || (lastPos >= (lines*columns))) + if ((lastPos < 0) || (lastPos >= (lines * columns))) lastPos = -1; } // Adjust selection to follow scroll. - if (selBegin != -1) - { + if (selBegin != -1) { bool beginIsTL = (selBegin == selTopLeft); int diff = dest - sourceBegin; // Scroll by this amount - int scr_TL=loc(0,history->getLines()); - int srca = sourceBegin+scr_TL; // Translate index from screen to global - int srce = sourceEnd+scr_TL; // Translate index from screen to global - int desta = srca+diff; - int deste = srce+diff; + int scr_TL = loc(0, history->getLines()); + int srca = sourceBegin + scr_TL; // Translate index from screen to global + int srce = sourceEnd + scr_TL; // Translate index from screen to global + int desta = srca + diff; + int deste = srce + diff; if ((selTopLeft >= srca) && (selTopLeft <= srce)) selTopLeft += diff; @@ -960,12 +959,9 @@ void Screen::moveImage(int dest, int sourceBegin, int sourceEnd) else if ((selBottomRight >= desta) && (selBottomRight <= deste)) selBottomRight = -1; // Clear selection (see below) - if (selBottomRight < 0) - { + if (selBottomRight < 0) { clearSelection(); - } - else - { + } else { if (selTopLeft < 0) selTopLeft = 0; } @@ -979,23 +975,23 @@ void Screen::moveImage(int dest, int sourceBegin, int sourceEnd) void Screen::clearToEndOfScreen() { - clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' '); + clearImage(loc(cuX, cuY), loc(columns - 1, lines - 1), ' '); } void Screen::clearToBeginOfScreen() { - clearImage(loc(0,0),loc(cuX,cuY),' '); + clearImage(loc(0, 0), loc(cuX, cuY), ' '); } void Screen::clearEntireScreen() { // Add entire screen to history - for (int i = 0; i < (lines-1); i++) - { - addHistLine(); scrollUp(0,1); + for (int i = 0; i < (lines - 1); i++) { + addHistLine(); + scrollUp(0, 1); } - clearImage(loc(0,0),loc(columns-1,lines-1),' '); + clearImage(loc(0, 0), loc(columns - 1, lines - 1), ' '); } /*! fill screen with 'E' @@ -1004,22 +1000,22 @@ void Screen::clearEntireScreen() void Screen::helpAlign() { - clearImage(loc(0,0),loc(columns-1,lines-1),'E'); + clearImage(loc(0, 0), loc(columns - 1, lines - 1), 'E'); } void Screen::clearToEndOfLine() { - clearImage(loc(cuX,cuY),loc(columns-1,cuY),' '); + clearImage(loc(cuX, cuY), loc(columns - 1, cuY), ' '); } void Screen::clearToBeginOfLine() { - clearImage(loc(0,cuY),loc(cuX,cuY),' '); + clearImage(loc(0, cuY), loc(cuX, cuY), ' '); } void Screen::clearEntireLine() { - clearImage(loc(0,cuY),loc(columns-1,cuY),' '); + clearImage(loc(0, cuY), loc(columns - 1, cuY), ' '); } void Screen::setRendition(int re) @@ -1036,9 +1032,9 @@ void Screen::resetRendition(int re) void Screen::setDefaultRendition() { - setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR); - setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR); - currentRendition = DEFAULT_RENDITION; + setForeColor(COLOR_SPACE_DEFAULT, DEFAULT_FORE_COLOR); + setBackColor(COLOR_SPACE_DEFAULT, DEFAULT_BACK_COLOR); + currentRendition = DEFAULT_RENDITION; updateEffectiveRendition(); } @@ -1046,20 +1042,20 @@ void Screen::setForeColor(int space, int color) { currentForeground = CharacterColor(space, color); - if ( currentForeground.isValid() ) + if (currentForeground.isValid()) updateEffectiveRendition(); else - setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR); + setForeColor(COLOR_SPACE_DEFAULT, DEFAULT_FORE_COLOR); } void Screen::setBackColor(int space, int color) { currentBackground = CharacterColor(space, color); - if ( currentBackground.isValid() ) + if (currentBackground.isValid()) updateEffectiveRendition(); else - setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR); + setBackColor(COLOR_SPACE_DEFAULT, DEFAULT_BACK_COLOR); } void Screen::clearSelection() @@ -1069,57 +1065,49 @@ void Screen::clearSelection() selBegin = -1; } -void Screen::getSelectionStart(int& column , int& line) const +void Screen::getSelectionStart(int &column, int &line) const { - if ( selTopLeft != -1 ) - { + if (selTopLeft != -1) { column = selTopLeft % columns; line = selTopLeft / columns; - } - else - { + } else { column = cuX + getHistLines(); line = cuY + getHistLines(); } } -void Screen::getSelectionEnd(int& column , int& line) const +void Screen::getSelectionEnd(int &column, int &line) const { - if ( selBottomRight != -1 ) - { + if (selBottomRight != -1) { column = selBottomRight % columns; line = selBottomRight / columns; - } - else - { + } else { column = cuX + getHistLines(); line = cuY + getHistLines(); } } void Screen::setSelectionStart(const int x, const int y, const bool mode) { - selBegin = loc(x,y); + selBegin = loc(x, y); /* FIXME, HACK to correct for x too far to the right... */ - if (x == columns) selBegin--; + if (x == columns) + selBegin--; selBottomRight = selBegin; selTopLeft = selBegin; blockSelectionMode = mode; } -void Screen::setSelectionEnd( const int x, const int y) +void Screen::setSelectionEnd(const int x, const int y) { if (selBegin == -1) return; - int endPos = loc(x,y); + int endPos = loc(x, y); - if (endPos < selBegin) - { + if (endPos < selBegin) { selTopLeft = endPos; selBottomRight = selBegin; - } - else - { + } else { /* FIXME, HACK to correct for x too far to the right... */ if (x == columns) endPos--; @@ -1129,28 +1117,25 @@ void Screen::setSelectionEnd( const int x, const int y) } // Normalize the selection in column mode - if (blockSelectionMode) - { + if (blockSelectionMode) { int topRow = selTopLeft / columns; int topColumn = selTopLeft % columns; int bottomRow = selBottomRight / columns; int bottomColumn = selBottomRight % columns; - selTopLeft = loc(qMin(topColumn,bottomColumn),topRow); - selBottomRight = loc(qMax(topColumn,bottomColumn),bottomRow); + selTopLeft = loc(qMin(topColumn, bottomColumn), topRow); + selBottomRight = loc(qMax(topColumn, bottomColumn), bottomRow); } } -bool Screen::isSelected( const int x,const int y) const +bool Screen::isSelected(const int x, const int y) const { bool columnInSelection = true; - if (blockSelectionMode) - { - columnInSelection = x >= (selTopLeft % columns) && - x <= (selBottomRight % columns); + if (blockSelectionMode) { + columnInSelection = x >= (selTopLeft % columns) && x <= (selBottomRight % columns); } - int pos = loc(x,y); + int pos = loc(x, y); return pos >= selTopLeft && pos <= selBottomRight && columnInSelection; } @@ -1161,7 +1146,7 @@ QString Screen::selectedText(bool preserveLineBreaks) const PlainTextDecoder decoder; decoder.begin(&stream); - writeSelectionToStream(&decoder , preserveLineBreaks); + writeSelectionToStream(&decoder, preserveLineBreaks); decoder.end(); return result; @@ -1172,17 +1157,16 @@ bool Screen::isSelectionValid() const return selTopLeft >= 0 && selBottomRight >= 0; } -void Screen::writeSelectionToStream(TerminalCharacterDecoder* decoder , - bool preserveLineBreaks) const +void Screen::writeSelectionToStream(TerminalCharacterDecoder *decoder, + bool preserveLineBreaks) const { if (!isSelectionValid()) return; - writeToStream(decoder,selTopLeft,selBottomRight,preserveLineBreaks); + writeToStream(decoder, selTopLeft, selBottomRight, preserveLineBreaks); } -void Screen::writeToStream(TerminalCharacterDecoder* decoder, - int startIndex, int endIndex, - bool preserveLineBreaks) const +void Screen::writeToStream(TerminalCharacterDecoder *decoder, int startIndex, int endIndex, + bool preserveLineBreaks) const { int top = startIndex / columns; int left = startIndex % columns; @@ -1190,131 +1174,111 @@ void Screen::writeToStream(TerminalCharacterDecoder* decoder, int bottom = endIndex / columns; int right = endIndex % columns; - Q_ASSERT( top >= 0 && left >= 0 && bottom >= 0 && right >= 0 ); + Q_ASSERT(top >= 0 && left >= 0 && bottom >= 0 && right >= 0); - for (int y=top;y<=bottom;y++) - { + for (int y = top; y <= bottom; y++) { int start = 0; - if ( y == top || blockSelectionMode ) start = left; + if (y == top || blockSelectionMode) + start = left; int count = -1; - if ( y == bottom || blockSelectionMode ) count = right - start + 1; + if (y == bottom || blockSelectionMode) + count = right - start + 1; - const bool appendNewLine = ( y != bottom ); - int copied = copyLineToStream( y, - start, - count, - decoder, - appendNewLine, - preserveLineBreaks ); + const bool appendNewLine = (y != bottom); + int copied = copyLineToStream(y, start, count, decoder, appendNewLine, preserveLineBreaks); // if the selection goes beyond the end of the last line then // append a new line character. // // this makes it possible to 'select' a trailing new line character after // the text on a line. - if ( y == bottom && - copied < count ) - { + if (y == bottom && copied < count) { Character newLineChar('\n'); - decoder->decodeLine(&newLineChar,1,0); + decoder->decodeLine(&newLineChar, 1, 0); } } } -int Screen::copyLineToStream(int line , - int start, - int count, - TerminalCharacterDecoder* decoder, - bool appendNewLine, - bool preserveLineBreaks) const +int Screen::copyLineToStream(int line, int start, int count, TerminalCharacterDecoder *decoder, + bool appendNewLine, bool preserveLineBreaks) const { - //buffer to hold characters for decoding - //the buffer is static to avoid initialising every - //element on each call to copyLineToStream + // buffer to hold characters for decoding + // the buffer is static to avoid initialising every + // element on each call to copyLineToStream //(which is unnecessary since all elements will be overwritten anyway) static const int MAX_CHARS = 1024; static Character characterBuffer[MAX_CHARS]; - Q_ASSERT( count < MAX_CHARS ); + Q_ASSERT(count < MAX_CHARS); LineProperty currentLineProperties = 0; - //determine if the line is in the history buffer or the screen image - if (line < history->getLines()) - { + // determine if the line is in the history buffer or the screen image + if (line < history->getLines()) { const int lineLength = history->getLineLen(line); // ensure that start position is before end of line - start = qMin(start,qMax(0,lineLength-1)); + start = qMin(start, qMax(0, lineLength - 1)); // retrieve line from history buffer. It is assumed // that the history buffer does not store trailing white space // at the end of the line, so it does not need to be trimmed here - if (count == -1) - { - count = lineLength-start; - } - else - { - count = qMin(start+count,lineLength)-start; + if (count == -1) { + count = lineLength - start; + } else { + count = qMin(start + count, lineLength) - start; } // safety checks - Q_ASSERT( start >= 0 ); - Q_ASSERT( count >= 0 ); - Q_ASSERT( (start+count) <= history->getLineLen(line) ); + Q_ASSERT(start >= 0); + Q_ASSERT(count >= 0); + Q_ASSERT((start + count) <= history->getLineLen(line)); - history->getCells(line,start,count,characterBuffer); + history->getCells(line, start, count, characterBuffer); - if ( history->isWrappedLine(line) ) + if (history->isWrappedLine(line)) currentLineProperties |= LINE_WRAPPED; - } - else - { - if ( count == -1 ) + } else { + if (count == -1) count = columns - start; - Q_ASSERT( count >= 0 ); + Q_ASSERT(count >= 0); - const int screenLine = line-history->getLines(); + const int screenLine = line - history->getLines(); - Character* data = screenLines[screenLine].data(); + Character *data = screenLines[screenLine].data(); int length = screenLines[screenLine].count(); - //retrieve line from screen image - for (int i=start;i < qMin(start+count,length);i++) - { - characterBuffer[i-start] = data[i]; + // retrieve line from screen image + for (int i = start; i < qMin(start + count, length); i++) { + characterBuffer[i - start] = data[i]; } // count cannot be any greater than length - count = qBound(0,count,length-start); + count = qBound(0, count, length - start); - Q_ASSERT( screenLine < lineProperties.count() ); + Q_ASSERT(screenLine < lineProperties.count()); currentLineProperties |= lineProperties[screenLine]; } // add new line character at end - const bool omitLineBreak = (currentLineProperties & LINE_WRAPPED) || - !preserveLineBreaks; + const bool omitLineBreak = (currentLineProperties & LINE_WRAPPED) || !preserveLineBreaks; - if ( !omitLineBreak && appendNewLine && (count+1 < MAX_CHARS) ) - { + if (!omitLineBreak && appendNewLine && (count + 1 < MAX_CHARS)) { characterBuffer[count] = '\n'; count++; } - //decode line and write to text stream - decoder->decodeLine( (Character*) characterBuffer , - count, currentLineProperties ); + // decode line and write to text stream + decoder->decodeLine((Character *)characterBuffer, count, currentLineProperties); return count; } -void Screen::writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const +void Screen::writeLinesToStream(TerminalCharacterDecoder *decoder, int fromLine, int toLine) const { - writeToStream(decoder,loc(0,fromLine),loc(columns-1,toLine)); + writeToStream(decoder, loc(0, fromLine), loc(columns - 1, toLine)); } void Screen::addHistLine() @@ -1322,12 +1286,11 @@ void Screen::addHistLine() // add line to history buffer // we have to take care about scrolling, too... - if (hasScroll()) - { + if (hasScroll()) { int oldHistLines = history->getLines(); history->addCellsVector(screenLines[0]); - history->addLine( lineProperties[0] & LINE_WRAPPED ); + history->addLine(lineProperties[0] & LINE_WRAPPED); int newHistLines = history->getLines(); @@ -1335,23 +1298,20 @@ void Screen::addHistLine() // If the history is full, increment the count // of dropped lines - if ( newHistLines == oldHistLines ) + if (newHistLines == oldHistLines) _droppedLines++; // Adjust selection for the new point of reference - if (newHistLines > oldHistLines) - { - if (selBegin != -1) - { + if (newHistLines > oldHistLines) { + if (selBegin != -1) { selTopLeft += columns; selBottomRight += columns; } } - if (selBegin != -1) - { + if (selBegin != -1) { // Scroll selection in history up - int top_BR = loc(0, 1+newHistLines); + int top_BR = loc(0, 1 + newHistLines); if (selTopLeft < top_BR) selTopLeft -= columns; @@ -1361,8 +1321,7 @@ void Screen::addHistLine() if (selBottomRight < 0) clearSelection(); - else - { + else { if (selTopLeft < 0) selTopLeft = 0; } @@ -1373,7 +1332,6 @@ void Screen::addHistLine() selBegin = selBottomRight; } } - } int Screen::getHistLines() const @@ -1381,15 +1339,14 @@ int Screen::getHistLines() const return history->getLines(); } -void Screen::setScroll(const HistoryType& t , bool copyPreviousScroll) +void Screen::setScroll(const HistoryType &t, bool copyPreviousScroll) { clearSelection(); - if ( copyPreviousScroll ) + if (copyPreviousScroll) history = t.scroll(history); - else - { - HistoryScroll* oldScroll = history; + else { + HistoryScroll *oldScroll = history; history = t.scroll(nullptr); delete oldScroll; } @@ -1400,20 +1357,20 @@ bool Screen::hasScroll() const return history->hasScroll(); } -const HistoryType& Screen::getScroll() const +const HistoryType &Screen::getScroll() const { return history->getType(); } -void Screen::setLineProperty(LineProperty property , bool enable) +void Screen::setLineProperty(LineProperty property, bool enable) { - if ( enable ) + if (enable) lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | property); else lineProperties[cuY] = (LineProperty)(lineProperties[cuY] & ~property); } -void Screen::fillWithDefaultChar(Character* dest, int count) +void Screen::fillWithDefaultChar(Character *dest, int count) { - for (int i=0;i getLineProperties( int startLine , int endLine ) const; - + QVector getLineProperties(int startLine, int endLine) const; /** Return the number of lines. */ - int getLines() const - { return lines; } + int getLines() const { return lines; } /** Return the number of columns. */ - int getColumns() const - { return columns; } + int getColumns() const { return columns; } /** Return the number of lines in the history buffer. */ int getHistLines() const; /** @@ -407,9 +403,9 @@ class Screen * If @p copyPreviousScroll is true then the contents of the previous * history buffer are copied into the new scroll. */ - void setScroll(const HistoryType& , bool copyPreviousScroll = true); + void setScroll(const HistoryType &, bool copyPreviousScroll = true); /** Returns the type of storage used to keep lines in the history. */ - const HistoryType& getScroll() const; + const HistoryType &getScroll() const; /** * Returns true if this screen keeps lines that are scrolled off the screen * in a history buffer. @@ -437,22 +433,22 @@ class Screen * Retrieves the start of the selection or the cursor position if there * is no selection. */ - void getSelectionStart(int& column , int& line) const; + void getSelectionStart(int &column, int &line) const; /** * Retrieves the end of the selection or the cursor position if there * is no selection. */ - void getSelectionEnd(int& column , int& line) const; + void getSelectionEnd(int &column, int &line) const; /** Clears the current selection */ void clearSelection(); /** - * Returns true if the character at (@p column, @p line) is part of the - * current selection. - */ - bool isSelected(const int column,const int line) const; + * Returns true if the character at (@p column, @p line) is part of the + * current selection. + */ + bool isSelected(const int column, const int line) const; /** * Convenience method. Returns the currently selected text. @@ -468,7 +464,7 @@ class Screen * @param fromLine The first line in the history to retrieve * @param toLine The last line in the history to retrieve */ - void writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const; + void writeLinesToStream(TerminalCharacterDecoder *decoder, int fromLine, int toLine) const; /** * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY @@ -480,8 +476,8 @@ class Screen * @param preserveLineBreaks Specifies whether new line characters should * be inserted into the returned text at the end of each terminal line. */ - void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool - preserveLineBreaks = true) const; + void writeSelectionToStream(TerminalCharacterDecoder *decoder, + bool preserveLineBreaks = true) const; /** * Checks if the text between from and to is inside the current @@ -512,7 +508,7 @@ class Screen * * @param enable true to apply the attribute to the current line or false to remove it */ - void setLineProperty(LineProperty property , bool enable); + void setLineProperty(LineProperty property, bool enable); /** * Returns the number of lines that the image has been scrolled up or down by, @@ -555,43 +551,39 @@ class Screen void resetDroppedLines(); /** - * Fills the buffer @p dest with @p count instances of the default (ie. blank) - * Character style. - */ - static void fillWithDefaultChar(Character* dest, int count); + * Fills the buffer @p dest with @p count instances of the default (ie. blank) + * Character style. + */ + static void fillWithDefaultChar(Character *dest, int count); private: Screen(const Screen &) = delete; Screen &operator=(const Screen &) = delete; - //copies a line of text from the screen or history into a stream using a - //specified character decoder. Returns the number of lines actually copied, - //which may be less than 'count' if (start+count) is more than the number of characters on - //the line + // copies a line of text from the screen or history into a stream using a + // specified character decoder. Returns the number of lines actually copied, + // which may be less than 'count' if (start+count) is more than the number of characters on + // the line // - //line - the line number to copy, from 0 (the earliest line in the history) up to + // line - the line number to copy, from 0 (the earliest line in the history) up to // history->getLines() + lines - 1 - //start - the first column on the line to copy - //count - the number of characters on the line to copy - //decoder - a decoder which converts terminal characters (an Character array) into text - //appendNewLine - if true a new line character (\n) is appended to the end of the line - int copyLineToStream(int line, - int start, - int count, - TerminalCharacterDecoder* decoder, - bool appendNewLine, - bool preserveLineBreaks) const; - - //fills a section of the screen image with the character 'c' - //the parameters are specified as offsets from the start of the screen image. - //the loc(x,y) macro can be used to generate these values from a column,line pair. + // start - the first column on the line to copy + // count - the number of characters on the line to copy + // decoder - a decoder which converts terminal characters (an Character array) into text + // appendNewLine - if true a new line character (\n) is appended to the end of the line + int copyLineToStream(int line, int start, int count, TerminalCharacterDecoder *decoder, + bool appendNewLine, bool preserveLineBreaks) const; + + // fills a section of the screen image with the character 'c' + // the parameters are specified as offsets from the start of the screen image. + // the loc(x,y) macro can be used to generate these values from a column,line pair. void clearImage(int loca, int loce, char c); - //move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'. - //the parameters are specified as offsets from the start of the screen image. - //the loc(x,y) macro can be used to generate these values from a column,line pair. + // move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'. + // the parameters are specified as offsets from the start of the screen image. + // the loc(x,y) macro can be used to generate these values from a column,line pair. // - //NOTE: moveImage() can only move whole lines + // NOTE: moveImage() can only move whole lines void moveImage(int dest, int sourceBegin, int sourceEnd); // scroll up 'i' lines in current region, clearing the bottom 'i' lines void scrollUp(int from, int i); @@ -603,37 +595,36 @@ class Screen void initTabStops(); void updateEffectiveRendition(); - void reverseRendition(Character& p) const; + void reverseRendition(Character &p) const; bool isSelectionValid() const; // copies text from 'startIndex' to 'endIndex' to a stream // startIndex and endIndex are positions generated using the loc(x,y) macro - void writeToStream(TerminalCharacterDecoder* decoder, int startIndex, - int endIndex, bool preserveLineBreaks = true) const; + void writeToStream(TerminalCharacterDecoder *decoder, int startIndex, int endIndex, + bool preserveLineBreaks = true) const; // copies 'count' lines from the screen buffer into 'dest', // starting from 'startLine', where 0 is the first line in the screen buffer - void copyFromScreen(Character* dest, int startLine, int count) const; + void copyFromScreen(Character *dest, int startLine, int count) const; // copies 'count' lines from the history buffer into 'dest', // starting from 'startLine', where 0 is the first line in the history - void copyFromHistory(Character* dest, int startLine, int count) const; - + void copyFromHistory(Character *dest, int startLine, int count) const; // screen image ---------------- int lines; int columns; - typedef QVector ImageLine; // [0..columns] - ImageLine* screenLines; // [lines] + typedef QVector ImageLine; // [0..columns] + ImageLine *screenLines; // [lines] int _scrolledLines; QRect _lastScrolledRegion; int _droppedLines; - QVarLengthArray lineProperties; + QVarLengthArray lineProperties; // history buffer --------------- - HistoryScroll* history; + HistoryScroll *history; // cursor location int cuX; @@ -658,20 +649,19 @@ class Screen // selection ------------------- int selBegin; // The first location selected. - int selTopLeft; // TopLeft Location. - int selBottomRight; // Bottom Right Location. - bool blockSelectionMode; // Column selection mode + int selTopLeft; // TopLeft Location. + int selBottomRight; // Bottom Right Location. + bool blockSelectionMode; // Column selection mode // effective colors and rendition ------------ CharacterColor effectiveForeground; // These are derived from CharacterColor effectiveBackground; // the cu_* variables above - quint8 effectiveRendition; // to speed up operation + quint8 effectiveRendition; // to speed up operation class SavedState { public: - SavedState() - : cursorColumn(0),cursorLine(0),rendition(0) {} + SavedState() : cursorColumn(0), cursorLine(0), rendition(0) { } int cursorColumn; int cursorLine; diff --git a/lib/ScreenWindow.cpp b/lib/ScreenWindow.cpp index a6ce7c27..6b982627 100644 --- a/lib/ScreenWindow.cpp +++ b/lib/ScreenWindow.cpp @@ -28,51 +28,49 @@ using namespace Konsole; -ScreenWindow::ScreenWindow(QObject* parent) - : QObject(parent) - , _screen(nullptr) - , _windowBuffer(nullptr) - , _windowBufferSize(0) - , _bufferNeedsUpdate(true) - , _windowLines(1) - , _currentLine(0) - , _trackOutput(true) - , _scrollCount(0) +ScreenWindow::ScreenWindow(QObject *parent) + : QObject(parent), + _screen(nullptr), + _windowBuffer(nullptr), + _windowBufferSize(0), + _bufferNeedsUpdate(true), + _windowLines(1), + _currentLine(0), + _trackOutput(true), + _scrollCount(0) { } ScreenWindow::~ScreenWindow() { delete[] _windowBuffer; } -void ScreenWindow::setScreen(Screen* screen) +void ScreenWindow::setScreen(Screen *screen) { - Q_ASSERT( screen ); + Q_ASSERT(screen); _screen = screen; } -Screen* ScreenWindow::screen() const +Screen *ScreenWindow::screen() const { return _screen; } -Character* ScreenWindow::getImage() +Character *ScreenWindow::getImage() { // reallocate internal buffer if the window size has changed int size = windowLines() * windowColumns(); - if (_windowBuffer == nullptr || _windowBufferSize != size) - { + if (_windowBuffer == nullptr || _windowBufferSize != size) { delete[] _windowBuffer; _windowBufferSize = size; _windowBuffer = new Character[size]; _bufferNeedsUpdate = true; } - if (!_bufferNeedsUpdate) + if (!_bufferNeedsUpdate) return _windowBuffer; - _screen->getImage(_windowBuffer,size, - currentLine(),endWindowLine()); + _screen->getImage(_windowBuffer, size, currentLine(), endWindowLine()); // this window may look beyond the end of the screen, in which // case there will be an unused area which needs to be filled @@ -91,7 +89,7 @@ void ScreenWindow::fillUnusedArea() int unusedLines = windowEndLine - screenEndLine; int charsToFill = unusedLines * windowColumns(); - Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill,charsToFill); + Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill, charsToFill); } // return the index of the line at the end of this window, or if this window @@ -103,12 +101,11 @@ void ScreenWindow::fillUnusedArea() // int ScreenWindow::endWindowLine() const { - return qMin(currentLine() + windowLines() - 1, - lineCount() - 1); + return qMin(currentLine() + windowLines() - 1, lineCount() - 1); } QVector ScreenWindow::getLineProperties() { - QVector result = _screen->getLineProperties(currentLine(),endWindowLine()); + QVector result = _screen->getLineProperties(currentLine(), endWindowLine()); if (result.count() != windowLines()) result.resize(windowLines()); @@ -116,40 +113,40 @@ QVector ScreenWindow::getLineProperties() return result; } -QString ScreenWindow::selectedText( bool preserveLineBreaks ) const +QString ScreenWindow::selectedText(bool preserveLineBreaks) const { - return _screen->selectedText( preserveLineBreaks ); + return _screen->selectedText(preserveLineBreaks); } -void ScreenWindow::getSelectionStart( int& column , int& line ) +void ScreenWindow::getSelectionStart(int &column, int &line) { - _screen->getSelectionStart(column,line); + _screen->getSelectionStart(column, line); line -= currentLine(); } -void ScreenWindow::getSelectionEnd( int& column , int& line ) +void ScreenWindow::getSelectionEnd(int &column, int &line) { - _screen->getSelectionEnd(column,line); + _screen->getSelectionEnd(column, line); line -= currentLine(); } -void ScreenWindow::setSelectionStart( int column , int line , bool columnMode ) +void ScreenWindow::setSelectionStart(int column, int line, bool columnMode) { - _screen->setSelectionStart( column , qMin(line + currentLine(),endWindowLine()) , columnMode); + _screen->setSelectionStart(column, qMin(line + currentLine(), endWindowLine()), columnMode); _bufferNeedsUpdate = true; emit selectionChanged(); } -void ScreenWindow::setSelectionEnd( int column , int line ) +void ScreenWindow::setSelectionEnd(int column, int line) { - _screen->setSelectionEnd( column , qMin(line + currentLine(),endWindowLine()) ); + _screen->setSelectionEnd(column, qMin(line + currentLine(), endWindowLine())); _bufferNeedsUpdate = true; emit selectionChanged(); } -bool ScreenWindow::isSelected( int column , int line ) +bool ScreenWindow::isSelected(int column, int line) { - return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) ); + return _screen->isSelected(column, qMin(line + currentLine(), endWindowLine())); } void ScreenWindow::clearSelection() @@ -188,38 +185,35 @@ QPoint ScreenWindow::cursorPosition() const { QPoint position; - position.setX( _screen->getCursorX() ); - position.setY( _screen->getCursorY() ); + position.setX(_screen->getCursorX()); + position.setY(_screen->getCursorY()); return position; } int ScreenWindow::currentLine() const { - return qBound(0,_currentLine,lineCount()-windowLines()); + return qBound(0, _currentLine, lineCount() - windowLines()); } -void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount ) +void ScreenWindow::scrollBy(RelativeScrollMode mode, int amount) { - if ( mode == ScrollLines ) - { - scrollTo( currentLine() + amount ); - } - else if ( mode == ScrollPages ) - { - scrollTo( currentLine() + amount * ( windowLines() / 2 ) ); + if (mode == ScrollLines) { + scrollTo(currentLine() + amount); + } else if (mode == ScrollPages) { + scrollTo(currentLine() + amount * (windowLines() / 2)); } } bool ScreenWindow::atEndOfOutput() const { - return currentLine() == (lineCount()-windowLines()); + return currentLine() == (lineCount() - windowLines()); } -void ScreenWindow::scrollTo( int line ) +void ScreenWindow::scrollTo(int line) { int maxCurrentLineNumber = lineCount() - windowLines(); - line = qBound(0,line,maxCurrentLineNumber); + line = qBound(0, line, maxCurrentLineNumber); const int delta = line - _currentLine; _currentLine = line; @@ -257,34 +251,30 @@ QRect ScreenWindow::scrollRegion() const { bool equalToScreenSize = windowLines() == _screen->getLines(); - if ( atEndOfOutput() && equalToScreenSize ) + if (atEndOfOutput() && equalToScreenSize) return _screen->lastScrolledRegion(); else - return {0,0,windowColumns(),windowLines()}; + return { 0, 0, windowColumns(), windowLines() }; } void ScreenWindow::notifyOutputChanged() { // move window to the bottom of the screen and update scroll count // if this window is currently tracking the bottom of the screen - if ( _trackOutput ) - { + if (_trackOutput) { _scrollCount -= _screen->scrolledLines(); - _currentLine = qMax(0,_screen->getHistLines() - (windowLines()-_screen->getLines())); - } - else - { + _currentLine = qMax(0, _screen->getHistLines() - (windowLines() - _screen->getLines())); + } else { // if the history is not unlimited then it may // have run out of space and dropped the oldest // lines of output - in this case the screen // window's current line number will need to // be adjusted - otherwise the output will scroll - _currentLine = qMax(0,_currentLine - - _screen->droppedLines()); + _currentLine = qMax(0, _currentLine - _screen->droppedLines()); // ensure that the screen window's current position does // not go beyond the bottom of the screen - _currentLine = qMin( _currentLine , _screen->getHistLines() ); + _currentLine = qMin(_currentLine, _screen->getHistLines()); } _bufferNeedsUpdate = true; @@ -298,42 +288,35 @@ void ScreenWindow::handleCommandFromKeyboard(KeyboardTranslator::Command command bool update = false; // EraseCommand is handled in Vt102Emulation - if ( command & KeyboardTranslator::ScrollPageUpCommand ) - { - scrollBy( ScreenWindow::ScrollPages , -1 ); + if (command & KeyboardTranslator::ScrollPageUpCommand) { + scrollBy(ScreenWindow::ScrollPages, -1); update = true; } - if ( command & KeyboardTranslator::ScrollPageDownCommand ) - { - scrollBy( ScreenWindow::ScrollPages , 1 ); + if (command & KeyboardTranslator::ScrollPageDownCommand) { + scrollBy(ScreenWindow::ScrollPages, 1); update = true; } - if ( command & KeyboardTranslator::ScrollLineUpCommand ) - { - scrollBy( ScreenWindow::ScrollLines , -1 ); + if (command & KeyboardTranslator::ScrollLineUpCommand) { + scrollBy(ScreenWindow::ScrollLines, -1); update = true; } - if ( command & KeyboardTranslator::ScrollLineDownCommand ) - { - scrollBy( ScreenWindow::ScrollLines , 1 ); + if (command & KeyboardTranslator::ScrollLineDownCommand) { + scrollBy(ScreenWindow::ScrollLines, 1); update = true; } - if ( command & KeyboardTranslator::ScrollDownToBottomCommand ) - { + if (command & KeyboardTranslator::ScrollDownToBottomCommand) { Q_EMIT scrollToEnd(); update = true; } - if ( command & KeyboardTranslator::ScrollUpToTopCommand) - { + if (command & KeyboardTranslator::ScrollUpToTopCommand) { scrollTo(0); update = true; } // TODO: KeyboardTranslator::ScrollLockCommand // TODO: KeyboardTranslator::SendCommand - if ( update ) - { - setTrackOutput( atEndOfOutput() ); + if (update) { + setTrackOutput(atEndOfOutput()); Q_EMIT outputChanged(); } diff --git a/lib/ScreenWindow.h b/lib/ScreenWindow.h index 3a75c085..d6d90372 100644 --- a/lib/ScreenWindow.h +++ b/lib/ScreenWindow.h @@ -29,8 +29,7 @@ #include "Character.h" #include "KeyboardTranslator.h" -namespace Konsole -{ +namespace Konsole { class Screen; @@ -42,10 +41,11 @@ class Screen; * A new ScreenWindow for a terminal session can be created by calling Emulation::createWindow() * * Use the scrollTo() method to scroll the window up and down on the screen. - * Use the getImage() method to retrieve the character image which is currently visible in the window. + * Use the getImage() method to retrieve the character image which is currently visible in the + * window. * - * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new - * lines are added to it. + * setTrackOutput() controls whether the window moves to the bottom of the associated screen when + * new lines are added to it. * * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should * be called. This in turn will update the window's position and emit the outputChanged() signal @@ -53,25 +53,26 @@ class Screen; */ class ScreenWindow : public QObject { -Q_OBJECT + Q_OBJECT public: /** * Constructs a new screen window with the given parent. - * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties(). + * A screen must be specified by calling setScreen() before calling getImage() or + * getLineProperties(). * - * You should not call this constructor directly, instead use the Emulation::createWindow() method - * to create a window on the emulation which you wish to view. This allows the emulation + * You should not call this constructor directly, instead use the Emulation::createWindow() + * method to create a window on the emulation which you wish to view. This allows the emulation * to notify the window when the associated screen has changed and synchronize selection updates * between all views on a session. */ - ScreenWindow(QObject* parent = nullptr); + ScreenWindow(QObject *parent = nullptr); ~ScreenWindow() override; /** Sets the screen which this window looks onto */ - void setScreen(Screen* screen); + void setScreen(Screen *screen); /** Returns the screen which this window looks onto */ - Screen* screen() const; + Screen *screen() const; /** * Returns the image of characters which are currently visible through this window @@ -80,7 +81,7 @@ Q_OBJECT * The returned buffer is managed by the ScreenWindow instance and does not need to be * deleted by the caller. */ - Character* getImage(); + Character *getImage(); /** * Returns the line attributes associated with the lines of characters which @@ -119,24 +120,24 @@ Q_OBJECT * Sets the start of the selection to the given @p line and @p column within * the window. */ - void setSelectionStart( int column , int line , bool columnMode ); + void setSelectionStart(int column, int line, bool columnMode); /** * Sets the end of the selection to the given @p line and @p column within * the window. */ - void setSelectionEnd( int column , int line ); + void setSelectionEnd(int column, int line); /** * Retrieves the start of the selection within the window. */ - void getSelectionStart( int& column , int& line ); + void getSelectionStart(int &column, int &line); /** * Retrieves the end of the selection within the window. */ - void getSelectionEnd( int& column , int& line ); + void getSelectionEnd(int &column, int &line); /** * Returns true if the character at @p line , @p column is part of the selection. */ - bool isSelected( int column , int line ); + bool isSelected(int column, int line); /** * Clears the current selection */ @@ -170,11 +171,10 @@ Q_OBJECT bool atEndOfOutput() const; /** Scrolls the window so that @p line is at the top of the window */ - void scrollTo( int line ); + void scrollTo(int line); /** Describes the units which scrollBy() moves the window by. */ - enum RelativeScrollMode - { + enum RelativeScrollMode { /** Scroll the window down by a given number of lines. */ ScrollLines, /** @@ -193,7 +193,7 @@ Q_OBJECT * this number is positive, the view is scrolled down. If this number is negative, the view * is scrolled up. */ - void scrollBy( RelativeScrollMode mode , int amount ); + void scrollBy(RelativeScrollMode mode, int amount); /** * Specifies whether the window should automatically move to the bottom @@ -214,7 +214,7 @@ Q_OBJECT * * @param preserveLineBreaks See Screen::selectedText() */ - QString selectedText( bool preserveLineBreaks ) const; + QString selectedText(bool preserveLineBreaks) const; public slots: /** @@ -248,16 +248,16 @@ public slots: int endWindowLine() const; void fillUnusedArea(); - Screen* _screen; // see setScreen() , screen() - Character* _windowBuffer; + Screen *_screen; // see setScreen() , screen() + Character *_windowBuffer; int _windowBufferSize; bool _bufferNeedsUpdate; - int _windowLines; - int _currentLine; // see scrollTo() , currentLine() + int _windowLines; + int _currentLine; // see scrollTo() , currentLine() bool _trackOutput; // see setTrackOutput() , trackOutput() - int _scrollCount; // count of lines which the window has been scrolled by since - // the last call to resetScrollCount() + int _scrollCount; // count of lines which the window has been scrolled by since + // the last call to resetScrollCount() }; } diff --git a/lib/SearchBar.cpp b/lib/SearchBar.cpp index 1de92f45..d4e026fd 100644 --- a/lib/SearchBar.cpp +++ b/lib/SearchBar.cpp @@ -28,7 +28,8 @@ SearchBar::SearchBar(QWidget *parent) : QWidget(parent) widget.setupUi(this); setAutoFillBackground(true); // make it always opaque, especially inside translucent windows connect(widget.closeButton, &QAbstractButton::clicked, this, &SearchBar::hide); - connect(widget.searchTextEdit, SIGNAL(textChanged(QString)), this, SIGNAL(searchCriteriaChanged())); + connect(widget.searchTextEdit, SIGNAL(textChanged(QString)), this, + SIGNAL(searchCriteriaChanged())); connect(widget.findPreviousButton, SIGNAL(clicked()), this, SIGNAL(findPrevious())); connect(widget.findNextButton, SIGNAL(clicked()), this, SIGNAL(findNext())); @@ -42,26 +43,25 @@ SearchBar::SearchBar(QWidget *parent) : QWidget(parent) m_matchCaseMenuEntry->setChecked(true); connect(m_matchCaseMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(searchCriteriaChanged())); - m_useRegularExpressionMenuEntry = optionsMenu->addAction(tr("Regular expression")); m_useRegularExpressionMenuEntry->setCheckable(true); - connect(m_useRegularExpressionMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(searchCriteriaChanged())); + connect(m_useRegularExpressionMenuEntry, SIGNAL(toggled(bool)), this, + SIGNAL(searchCriteriaChanged())); m_highlightMatchesMenuEntry = optionsMenu->addAction(tr("Highlight all matches")); m_highlightMatchesMenuEntry->setCheckable(true); m_highlightMatchesMenuEntry->setChecked(true); - connect(m_highlightMatchesMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(highlightMatchesChanged(bool))); + connect(m_highlightMatchesMenuEntry, SIGNAL(toggled(bool)), this, + SIGNAL(highlightMatchesChanged(bool))); } -SearchBar::~SearchBar() { -} +SearchBar::~SearchBar() { } QString SearchBar::searchText() { return widget.searchTextEdit->text(); } - bool SearchBar::useRegularExpression() { return m_useRegularExpressionMenuEntry->isChecked(); @@ -87,8 +87,7 @@ void SearchBar::show() void SearchBar::hide() { QWidget::hide(); - if (QWidget *p = parentWidget()) - { + if (QWidget *p = parentWidget()) { p->setFocus(Qt::OtherFocusReason); // give the focus to the parent widget on hiding } } @@ -100,22 +99,15 @@ void SearchBar::noMatchFound() widget.searchTextEdit->setPalette(palette); } - -void SearchBar::keyReleaseEvent(QKeyEvent* keyEvent) +void SearchBar::keyReleaseEvent(QKeyEvent *keyEvent) { - if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) - { - if (keyEvent->modifiers() == Qt::ShiftModifier) - { + if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { + if (keyEvent->modifiers() == Qt::ShiftModifier) { Q_EMIT findPrevious(); - } - else - { + } else { Q_EMIT findNext(); } - } - else if (keyEvent->key() == Qt::Key_Escape) - { + } else if (keyEvent->key() == Qt::Key_Escape) { hide(); } } @@ -123,5 +115,4 @@ void SearchBar::keyReleaseEvent(QKeyEvent* keyEvent) void SearchBar::clearBackgroundColor() { widget.searchTextEdit->setPalette(QWidget::window()->palette()); - } diff --git a/lib/SearchBar.h b/lib/SearchBar.h index 1200884f..1ccaeb84 100644 --- a/lib/SearchBar.h +++ b/lib/SearchBar.h @@ -17,17 +17,18 @@ 02110-1301 USA. */ #ifndef _SEARCHBAR_H -#define _SEARCHBAR_H +#define _SEARCHBAR_H #include #include "ui_SearchBar.h" #include "HistorySearch.h" -class SearchBar : public QWidget { +class SearchBar : public QWidget +{ Q_OBJECT public: - SearchBar(QWidget* parent = nullptr); + SearchBar(QWidget *parent = nullptr); ~SearchBar() override; virtual void show(); QString searchText(); @@ -46,7 +47,7 @@ public slots: void findPrevious(); protected: - void keyReleaseEvent(QKeyEvent* keyEvent) override; + void keyReleaseEvent(QKeyEvent *keyEvent) override; private slots: void clearBackgroundColor(); @@ -58,4 +59,4 @@ private slots: QAction *m_highlightMatchesMenuEntry; }; -#endif /* _SEARCHBAR_H */ +#endif /* _SEARCHBAR_H */ diff --git a/lib/Session.cpp b/lib/Session.cpp index 4891e4ee..0aa953e7 100644 --- a/lib/Session.cpp +++ b/lib/Session.cpp @@ -48,74 +48,74 @@ using namespace Konsole; int Session::lastSessionId = 0; -Session::Session(QObject* parent) : - QObject(parent), - _shellProcess(nullptr) - , _emulation(nullptr) - , _monitorActivity(false) - , _monitorSilence(false) - , _notifiedActivity(false) - , _autoClose(true) - , _wantedClose(false) - , _silenceSeconds(10) - , _isTitleChanged(false) - , _addToUtmp(false) // disabled by default because of a bug encountered on certain systems - // which caused Konsole to hang when closing a tab and then opening a new - // one. A 'QProcess destroyed while still running' warning was being - // printed to the terminal. Likely a problem in KPty::logout() - // or KPty::login() which uses a QProcess to start /usr/bin/utempter - , _flowControl(true) - , _fullScripting(false) - , _sessionId(0) -// , _zmodemBusy(false) -// , _zmodemProc(0) -// , _zmodemProgress(0) - , _hasDarkBackground(false) -{ - //prepare DBus communication -// new SessionAdaptor(this); +Session::Session(QObject *parent) + : QObject(parent), + _shellProcess(nullptr), + _emulation(nullptr), + _monitorActivity(false), + _monitorSilence(false), + _notifiedActivity(false), + _autoClose(true), + _wantedClose(false), + _silenceSeconds(10), + _isTitleChanged(false), + _addToUtmp(false) // disabled by default because of a bug encountered on certain systems + // which caused Konsole to hang when closing a tab and then opening a new + // one. A 'QProcess destroyed while still running' warning was being + // printed to the terminal. Likely a problem in KPty::logout() + // or KPty::login() which uses a QProcess to start /usr/bin/utempter + , + _flowControl(true), + _fullScripting(false), + _sessionId(0) + // , _zmodemBusy(false) + // , _zmodemProc(0) + // , _zmodemProgress(0) + , + _hasDarkBackground(false) +{ + // prepare DBus communication + // new SessionAdaptor(this); _sessionId = ++lastSessionId; -// QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this); + // QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), + // this); - //create teletype for I/O with shell process + // create teletype for I/O with shell process _shellProcess = new Pty(); ptySlaveFd = _shellProcess->pty()->slaveFd(); - //create emulation backend + // create emulation backend _emulation = new Vt102Emulation(); - connect( _emulation, SIGNAL( titleChanged( int, const QString & ) ), - this, SLOT( setUserTitle( int, const QString & ) ) ); - connect( _emulation, SIGNAL( stateSet(int) ), - this, SLOT( activityStateSet(int) ) ); -// connect( _emulation, SIGNAL( zmodemDetected() ), this , -// SLOT( fireZModemDetected() ) ); - connect( _emulation, SIGNAL( changeTabTextColorRequest( int ) ), - this, SIGNAL( changeTabTextColorRequest( int ) ) ); - connect( _emulation, SIGNAL(profileChangeCommandReceived(const QString &)), - this, SIGNAL( profileChangeCommandReceived(const QString &)) ); - - connect(_emulation, SIGNAL(imageResizeRequest(QSize)), - this, SLOT(onEmulationSizeChange(QSize))); - connect(_emulation, SIGNAL(imageSizeChanged(int, int)), - this, SLOT(onViewSizeChange(int, int))); - connect(_emulation, &Vt102Emulation::cursorChanged, - this, &Session::cursorChanged); - - //connect teletype to emulation backend + connect(_emulation, SIGNAL(titleChanged(int, const QString &)), this, + SLOT(setUserTitle(int, const QString &))); + connect(_emulation, SIGNAL(stateSet(int)), this, SLOT(activityStateSet(int))); + // connect( _emulation, SIGNAL( zmodemDetected() ), this , + // SLOT( fireZModemDetected() ) ); + connect(_emulation, SIGNAL(changeTabTextColorRequest(int)), this, + SIGNAL(changeTabTextColorRequest(int))); + connect(_emulation, SIGNAL(profileChangeCommandReceived(const QString &)), this, + SIGNAL(profileChangeCommandReceived(const QString &))); + + connect(_emulation, SIGNAL(imageResizeRequest(QSize)), this, + SLOT(onEmulationSizeChange(QSize))); + connect(_emulation, SIGNAL(imageSizeChanged(int, int)), this, SLOT(onViewSizeChange(int, int))); + connect(_emulation, &Vt102Emulation::cursorChanged, this, &Session::cursorChanged); + + // connect teletype to emulation backend _shellProcess->setUtf8Mode(_emulation->utf8()); - connect( _shellProcess,SIGNAL(receivedData(const char *,int)),this, - SLOT(onReceiveBlock(const char *,int)) ); - connect( _emulation,SIGNAL(sendData(const char *,int)),_shellProcess, - SLOT(sendData(const char *,int)) ); - connect( _emulation,SIGNAL(lockPtyRequest(bool)),_shellProcess,SLOT(lockPty(bool)) ); - connect( _emulation,SIGNAL(useUtf8Request(bool)),_shellProcess,SLOT(setUtf8Mode(bool)) ); + connect(_shellProcess, SIGNAL(receivedData(const char *, int)), this, + SLOT(onReceiveBlock(const char *, int))); + connect(_emulation, SIGNAL(sendData(const char *, int)), _shellProcess, + SLOT(sendData(const char *, int))); + connect(_emulation, SIGNAL(lockPtyRequest(bool)), _shellProcess, SLOT(lockPty(bool))); + connect(_emulation, SIGNAL(useUtf8Request(bool)), _shellProcess, SLOT(setUtf8Mode(bool))); - connect( _shellProcess,SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(done(int)) ); + connect(_shellProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(done(int))); // not in kprocess anymore connect( _shellProcess,SIGNAL(done(int)), this, SLOT(done(int)) ); - //setup timer for monitoring session activity + // setup timer for monitoring session activity _monitorTimer = new QTimer(this); _monitorTimer->setSingleShot(true); connect(_monitorTimer, SIGNAL(timeout()), this, SLOT(monitorTimerDone())); @@ -143,20 +143,20 @@ bool Session::isRunning() const return _shellProcess->state() == QProcess::Running; } -void Session::setCodec(QTextCodec * codec) const +void Session::setCodec(QTextCodec *codec) const { emulation()->setCodec(codec); } -void Session::setProgram(const QString & program) +void Session::setProgram(const QString &program) { _program = ShellCommand::expand(program); } -void Session::setInitialWorkingDirectory(const QString & dir) +void Session::setInitialWorkingDirectory(const QString &dir) { _initialWorkingDir = ShellCommand::expand(dir); } -void Session::setArguments(const QStringList & arguments) +void Session::setArguments(const QStringList &arguments) { _arguments = ShellCommand::expand(arguments); } @@ -166,77 +166,74 @@ QList Session::views() const return _views; } -void Session::addView(TerminalDisplay * widget) +void Session::addView(TerminalDisplay *widget) { - Q_ASSERT( !_views.contains(widget) ); + Q_ASSERT(!_views.contains(widget)); _views.append(widget); - if ( _emulation != nullptr ) { + if (_emulation != nullptr) { // connect emulation - view signals and slots - connect( widget , &TerminalDisplay::keyPressedSignal, _emulation , - &Emulation::sendKeyEvent); - connect( widget , SIGNAL(mouseSignal(int,int,int,int)) , _emulation , - SLOT(sendMouseEvent(int,int,int,int)) ); - connect( widget , SIGNAL(sendStringToEmu(const char *)) , _emulation , - SLOT(sendString(const char *)) ); + connect(widget, &TerminalDisplay::keyPressedSignal, _emulation, &Emulation::sendKeyEvent); + connect(widget, SIGNAL(mouseSignal(int, int, int, int)), _emulation, + SLOT(sendMouseEvent(int, int, int, int))); + connect(widget, SIGNAL(sendStringToEmu(const char *)), _emulation, + SLOT(sendString(const char *))); // allow emulation to notify view when the foreground process // indicates whether or not it is interested in mouse signals - connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , - SLOT(setUsesMouse(bool)) ); + connect(_emulation, SIGNAL(programUsesMouseChanged(bool)), widget, + SLOT(setUsesMouse(bool))); - widget->setUsesMouse( _emulation->programUsesMouse() ); + widget->setUsesMouse(_emulation->programUsesMouse()); - connect( _emulation , SIGNAL(programBracketedPasteModeChanged(bool)) , - widget , SLOT(setBracketedPasteMode(bool)) ); + connect(_emulation, SIGNAL(programBracketedPasteModeChanged(bool)), widget, + SLOT(setBracketedPasteMode(bool))); widget->setBracketedPasteMode(_emulation->programBracketedPasteMode()); widget->setScreenWindow(_emulation->createWindow()); } - //connect view signals and slots - QObject::connect( widget ,SIGNAL(changedContentSizeSignal(int,int)),this, - SLOT(onViewSizeChange(int,int))); + // connect view signals and slots + QObject::connect(widget, SIGNAL(changedContentSizeSignal(int, int)), this, + SLOT(onViewSizeChange(int, int))); - QObject::connect( widget ,SIGNAL(destroyed(QObject *)) , this , - SLOT(viewDestroyed(QObject *)) ); -//slot for close + QObject::connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(viewDestroyed(QObject *))); + // slot for close QObject::connect(this, SIGNAL(finished()), widget, SLOT(close())); - } -void Session::viewDestroyed(QObject * view) +void Session::viewDestroyed(QObject *view) { - TerminalDisplay * display = (TerminalDisplay *)view; + TerminalDisplay *display = (TerminalDisplay *)view; - Q_ASSERT( _views.contains(display) ); + Q_ASSERT(_views.contains(display)); removeView(display); } -void Session::removeView(TerminalDisplay * widget) +void Session::removeView(TerminalDisplay *widget) { _views.removeAll(widget); - disconnect(widget,nullptr,this,nullptr); + disconnect(widget, nullptr, this, nullptr); - if ( _emulation != nullptr ) { + if (_emulation != nullptr) { // disconnect // - key presses signals from widget // - mouse activity signals from widget // - string sending signals from widget // // ... and any other signals connected in addView() - disconnect( widget, nullptr, _emulation, nullptr); + disconnect(widget, nullptr, _emulation, nullptr); // disconnect state change signals emitted by emulation - disconnect( _emulation , nullptr , widget , nullptr); + disconnect(_emulation, nullptr, widget, nullptr); } // close the session automatically when the last view is removed - if ( _views.count() == 0 ) { + if (_views.count() == 0) { close(); } } @@ -246,11 +243,13 @@ void Session::run() // Upon a KPty error, there is no description on what that error was... // Check to see if the given program is executable. - /* ok iam not exactly sure where _program comes from - however it was set to /bin/bash on my system - * Thats bad for BSD as its /usr/local/bin/bash there - its also bad for arch as its /usr/bin/bash there too! - * So i added a check to see if /bin/bash exists - if no then we use $SHELL - if that does not exist either, we fall back to /bin/sh - * As far as i know /bin/sh exists on every unix system.. You could also just put some ifdef __FREEBSD__ here but i think these 2 filechecks are worth - * their computing time on any system - especially with the problem on arch linux beeing there too. + /* ok iam not exactly sure where _program comes from - however it was set to /bin/bash on my + * system Thats bad for BSD as its /usr/local/bin/bash there - its also bad for arch as its + * /usr/bin/bash there too! So i added a check to see if /bin/bash exists - if no then we use + * $SHELL - if that does not exist either, we fall back to /bin/sh As far as i know /bin/sh + * exists on every unix system.. You could also just put some ifdef __FREEBSD__ here but i think + * these 2 filechecks are worth their computing time on any system - especially with the problem + * on arch linux beeing there too. */ QString exec = QString::fromLocal8Bit(QFile::encodeName(_program)); // if 'exec' is not specified, fall back to default shell. if that @@ -258,18 +257,18 @@ void Session::run() // here we expect full path. If there is no fullpath let's expect it's // a custom shell (eg. python, etc.) available in the PATH. - if (exec.startsWith(QLatin1Char('/')) || exec.isEmpty()) - { - const QString defaultShell{QLatin1String("/bin/sh")}; + if (exec.startsWith(QLatin1Char('/')) || exec.isEmpty()) { + const QString defaultShell{ QLatin1String("/bin/sh") }; QFile excheck(exec); - if ( exec.isEmpty() || !excheck.exists() ) { + if (exec.isEmpty() || !excheck.exists()) { exec = QString::fromLocal8Bit(qgetenv("SHELL")); } excheck.setFileName(exec); - if ( exec.isEmpty() || !excheck.exists() ) { - qWarning() << "Neither default shell nor $SHELL is set to a correct path. Fallback to" << defaultShell; + if (exec.isEmpty() || !excheck.exists()) { + qWarning() << "Neither default shell nor $SHELL is set to a correct path. Fallback to" + << defaultShell; exec = defaultShell; } } @@ -296,24 +295,22 @@ void Session::run() // tell the terminal exactly which colors are being used, but instead approximates // the color scheme as "black on white" or "white on black" depending on whether // the background color is deemed dark or not - QString backgroundColorHint = _hasDarkBackground ? QLatin1String("COLORFGBG=15;0") : QLatin1String("COLORFGBG=0;15"); + QString backgroundColorHint = + _hasDarkBackground ? QLatin1String("COLORFGBG=15;0") : QLatin1String("COLORFGBG=0;15"); /* if we do all the checking if this shell exists then we use it ;) * Dont know about the arguments though.. maybe youll need some more checking im not sure * However this works on Arch and FreeBSD now. */ - int result = _shellProcess->start(exec, - arguments, - _environment << backgroundColorHint, - windowId(), - _addToUtmp); + int result = _shellProcess->start(exec, arguments, _environment << backgroundColorHint, + windowId(), _addToUtmp); if (result < 0) { qDebug() << "CRASHED! result: " << result; return; } - _shellProcess->setWriteable(false); // We are reachable via kwrited. + _shellProcess->setWriteable(false); // We are reachable via kwrited. emit started(); } @@ -324,22 +321,22 @@ void Session::runEmptyPTY() _shellProcess->setWriteable(false); // disconnet send data from emulator to internal terminal process - disconnect( _emulation,SIGNAL(sendData(const char *,int)), - _shellProcess, SLOT(sendData(const char *,int)) ); + disconnect(_emulation, SIGNAL(sendData(const char *, int)), _shellProcess, + SLOT(sendData(const char *, int))); _shellProcess->setEmptyPTYProperties(); emit started(); } -void Session::setUserTitle( int what, const QString & caption ) +void Session::setUserTitle(int what, const QString &caption) { - //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) + // set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) bool modified = false; // (btw: what=0 changes _userTitle and icon, what=1 only icon, what=2 only _nameTitle if ((what == 0) || (what == 2)) { _isTitleChanged = true; - if ( _userTitle != caption ) { + if (_userTitle != caption) { _userTitle = caption; modified = true; } @@ -347,15 +344,15 @@ void Session::setUserTitle( int what, const QString & caption ) if ((what == 0) || (what == 1)) { _isTitleChanged = true; - if ( _iconText != caption ) { + if (_iconText != caption) { _iconText = caption; modified = true; } } if (what == 11) { - QString colorString = caption.section(QLatin1Char(';'),0,0); - //qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString; + QString colorString = caption.section(QLatin1Char(';'), 0, 0); + // qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString; QColor backColor = QColor(colorString); if (backColor.isValid()) { // change color via \033]11;Color\007 if (backColor != _modifiedBackground) { @@ -364,7 +361,7 @@ void Session::setUserTitle( int what, const QString & caption ) // bail out here until the code to connect the terminal display // to the changeBackgroundColor() signal has been written // and tested - just so we don't forget to do this. - Q_ASSERT( 0 ); + Q_ASSERT(0); emit changeBackgroundColorRequest(backColor); } @@ -373,22 +370,22 @@ void Session::setUserTitle( int what, const QString & caption ) if (what == 30) { _isTitleChanged = true; - if ( _nameTitle != caption ) { - setTitle(Session::NameRole,caption); + if (_nameTitle != caption) { + setTitle(Session::NameRole, caption); return; } } if (what == 31) { - QString cwd=caption; - cwd=cwd.replace( QRegExp(QLatin1String("^~")), QDir::homePath() ); + QString cwd = caption; + cwd = cwd.replace(QRegExp(QLatin1String("^~")), QDir::homePath()); emit openUrlRequest(cwd); } // change icon via \033]32;Icon\007 if (what == 32) { _isTitleChanged = true; - if ( _iconName != caption ) { + if (_iconName != caption) { _iconName = caption; modified = true; @@ -400,7 +397,7 @@ void Session::setUserTitle( int what, const QString & caption ) return; } - if ( modified ) { + if (modified) { emit titleChanged(); } } @@ -409,19 +406,19 @@ QString Session::userTitle() const { return _userTitle; } -void Session::setTabTitleFormat(TabTitleContext context , const QString & format) +void Session::setTabTitleFormat(TabTitleContext context, const QString &format) { - if ( context == LocalTabTitle ) { + if (context == LocalTabTitle) { _localTabTitleFormat = format; - } else if ( context == RemoteTabTitle ) { + } else if (context == RemoteTabTitle) { _remoteTabTitleFormat = format; } } QString Session::tabTitleFormat(TabTitleContext context) const { - if ( context == LocalTabTitle ) { + if (context == LocalTabTitle) { return _localTabTitleFormat; - } else if ( context == RemoteTabTitle ) { + } else if (context == RemoteTabTitle) { return _remoteTabTitleFormat; } @@ -430,14 +427,15 @@ QString Session::tabTitleFormat(TabTitleContext context) const void Session::monitorTimerDone() { - //FIXME: The idea here is that the notification popup will appear to tell the user than output from - //the terminal has stopped and the popup will disappear when the user activates the session. + // FIXME: The idea here is that the notification popup will appear to tell the user than output + // from the terminal has stopped and the popup will disappear when the user activates the + // session. // - //This breaks with the addition of multiple views of a session. The popup should disappear - //when any of the views of the session becomes active - + // This breaks with the addition of multiple views of a session. The popup should disappear + // when any of the views of the session becomes active - //FIXME: Make message text for this notification and the activity notification more descriptive. + // FIXME: Make message text for this notification and the activity notification more + // descriptive. if (_monitorSilence) { emit silence(); emit stateChanged(NOTIFYSILENCE); @@ -445,31 +443,31 @@ void Session::monitorTimerDone() emit stateChanged(NOTIFYNORMAL); } - _notifiedActivity=false; + _notifiedActivity = false; } void Session::activityStateSet(int state) { - if (state==NOTIFYBELL) { + if (state == NOTIFYBELL) { emit bellRequest(tr("Bell in session '%1'").arg(_nameTitle)); - } else if (state==NOTIFYACTIVITY) { + } else if (state == NOTIFYACTIVITY) { if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); + _monitorTimer->start(_silenceSeconds * 1000); } - if ( _monitorActivity ) { - //FIXME: See comments in Session::monitorTimerDone() + if (_monitorActivity) { + // FIXME: See comments in Session::monitorTimerDone() if (!_notifiedActivity) { - _notifiedActivity=true; + _notifiedActivity = true; emit activity(); } } } - if ( state==NOTIFYACTIVITY && !_monitorActivity ) { + if (state == NOTIFYACTIVITY && !_monitorActivity) { state = NOTIFYNORMAL; } - if ( state==NOTIFYSILENCE && !_monitorSilence ) { + if (state == NOTIFYSILENCE && !_monitorSilence) { state = NOTIFYNORMAL; } @@ -498,21 +496,20 @@ void Session::updateTerminalSize() const int VIEW_LINES_THRESHOLD = 2; const int VIEW_COLUMNS_THRESHOLD = 2; - //select largest number of lines and columns that will fit in all visible views - while ( viewIter.hasNext() ) { - TerminalDisplay * view = viewIter.next(); - if ( view->isHidden() == false && - view->lines() >= VIEW_LINES_THRESHOLD && - view->columns() >= VIEW_COLUMNS_THRESHOLD ) { - minLines = (minLines == -1) ? view->lines() : qMin( minLines , view->lines() ); - minColumns = (minColumns == -1) ? view->columns() : qMin( minColumns , view->columns() ); + // select largest number of lines and columns that will fit in all visible views + while (viewIter.hasNext()) { + TerminalDisplay *view = viewIter.next(); + if (view->isHidden() == false && view->lines() >= VIEW_LINES_THRESHOLD + && view->columns() >= VIEW_COLUMNS_THRESHOLD) { + minLines = (minLines == -1) ? view->lines() : qMin(minLines, view->lines()); + minColumns = (minColumns == -1) ? view->columns() : qMin(minColumns, view->columns()); } } // backend emulation must have a _terminal of at least 1 column x 1 line in size - if ( minLines > 0 && minColumns > 0 ) { - _emulation->setImageSize( minLines , minColumns ); - _shellProcess->setWindowSize( minLines , minColumns ); + if (minLines > 0 && minColumns > 0) { + _emulation->setImageSize(minLines, minColumns); + _shellProcess->setWindowSize(minLines, minColumns); } } @@ -533,21 +530,19 @@ void Session::refresh() // send an email with method or patches to konsole-devel@kde.org const QSize existingSize = _shellProcess->windowSize(); - _shellProcess->setWindowSize(existingSize.height(),existingSize.width()+1); - _shellProcess->setWindowSize(existingSize.height(),existingSize.width()); + _shellProcess->setWindowSize(existingSize.height(), existingSize.width() + 1); + _shellProcess->setWindowSize(existingSize.height(), existingSize.width()); } bool Session::sendSignal(int signal) { - int result = ::kill(static_cast(_shellProcess->processId()),signal); + int result = ::kill(static_cast(_shellProcess->processId()), signal); - if ( result == 0 ) - { - _shellProcess->waitForFinished(); - return true; - } - else - return false; + if (result == 0) { + _shellProcess->waitForFinished(); + return true; + } else + return false; } void Session::close() @@ -560,12 +555,12 @@ void Session::close() } } -void Session::sendText(const QString & text) const +void Session::sendText(const QString &text) const { _emulation->sendText(text); } -void Session::sendKeyEvent(QKeyEvent* e) const +void Session::sendKeyEvent(QKeyEvent *e) const { _emulation->sendKeyEvent(e, false); } @@ -574,10 +569,10 @@ Session::~Session() { delete _emulation; delete _shellProcess; -// delete _zmodemProc; + // delete _zmodemProc; } -void Session::setProfileKey(const QString & key) +void Session::setProfileKey(const QString &key) { _profileKey = key; emit profileChanged(key); @@ -609,14 +604,13 @@ void Session::done(int exitStatus) } } - if ( !_wantedClose && _shellProcess->exitStatus() != QProcess::NormalExit ) + if (!_wantedClose && _shellProcess->exitStatus() != QProcess::NormalExit) message = tr("Session '%1' exited unexpectedly.").arg(_nameTitle); else emit finished(); - } -Emulation * Session::emulation() const +Emulation *Session::emulation() const { return _emulation; } @@ -631,7 +625,7 @@ QStringList Session::environment() const return _environment; } -void Session::setEnvironment(const QStringList & environment) +void Session::setEnvironment(const QStringList &environment) { _environment = environment; } @@ -641,17 +635,17 @@ int Session::sessionId() const return _sessionId; } -void Session::setKeyBindings(const QString & id) +void Session::setKeyBindings(const QString &id) { _emulation->setKeyBindings(id); } -void Session::setTitle(TitleRole role , const QString & newTitle) +void Session::setTitle(TitleRole role, const QString &newTitle) { - if ( title(role) != newTitle ) { - if ( role == NameRole ) { + if (title(role) != newTitle) { + if (role == NameRole) { _nameTitle = newTitle; - } else if ( role == DisplayedTitleRole ) { + } else if (role == DisplayedTitleRole) { _displayTitle = newTitle; } @@ -661,27 +655,27 @@ void Session::setTitle(TitleRole role , const QString & newTitle) QString Session::title(TitleRole role) const { - if ( role == NameRole ) { + if (role == NameRole) { return _nameTitle; - } else if ( role == DisplayedTitleRole ) { + } else if (role == DisplayedTitleRole) { return _displayTitle; } else { return QString(); } } -void Session::setIconName(const QString & iconName) +void Session::setIconName(const QString &iconName) { - if ( iconName != _iconName ) { + if (iconName != _iconName) { _iconName = iconName; emit titleChanged(); } } -void Session::setIconText(const QString & iconText) +void Session::setIconText(const QString &iconText) { _iconText = iconText; - //kDebug(1211)<<"Session setIconText " << _iconText; + // kDebug(1211)<<"Session setIconText " << _iconText; } QString Session::iconName() const @@ -699,12 +693,12 @@ bool Session::isTitleChanged() const return _isTitleChanged; } -void Session::setHistoryType(const HistoryType & hType) +void Session::setHistoryType(const HistoryType &hType) { _emulation->setHistory(hType); } -const HistoryType & Session::historyType() const +const HistoryType &Session::historyType() const { return _emulation->history(); } @@ -730,28 +724,28 @@ bool Session::isMonitorActivity() const return _monitorActivity; } // unused currently -bool Session::isMonitorSilence() const +bool Session::isMonitorSilence() const { return _monitorSilence; } void Session::setMonitorActivity(bool _monitor) { - _monitorActivity=_monitor; - _notifiedActivity=false; + _monitorActivity = _monitor; + _notifiedActivity = false; activityStateSet(NOTIFYNORMAL); } void Session::setMonitorSilence(bool _monitor) { - if (_monitorSilence==_monitor) { + if (_monitorSilence == _monitor) { return; } - _monitorSilence=_monitor; + _monitorSilence = _monitor; if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); + _monitorTimer->start(_silenceSeconds * 1000); } else { _monitorTimer->stop(); } @@ -761,9 +755,9 @@ void Session::setMonitorSilence(bool _monitor) void Session::setMonitorSilenceSeconds(int seconds) { - _silenceSeconds=seconds; + _silenceSeconds = seconds; if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); + _monitorTimer->start(_silenceSeconds * 1000); } } @@ -790,7 +784,7 @@ bool Session::flowControlEnabled() const { return _flowControl; } -//void Session::fireZModemDetected() +// void Session::fireZModemDetected() //{ // if (!_zmodemBusy) // { @@ -799,13 +793,13 @@ bool Session::flowControlEnabled() const // } //} -//void Session::cancelZModem() +// void Session::cancelZModem() //{ // _shellProcess->sendData("\030\030\030\030", 4); // Abort // _zmodemBusy = false; //} -//void Session::startZModem(const QString &zmodem, const QString &dir, const QStringList &list) +// void Session::startZModem(const QString &zmodem, const QString &dir, const QStringList &list) //{ // _zmodemBusy = true; // _zmodemProc = new KProcess(); @@ -825,8 +819,9 @@ bool Session::flowControlEnabled() const // connect(_zmodemProc,SIGNAL (finished(int,QProcess::ExitStatus)), // this, SLOT(zmodemFinished())); // -// disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) ); -// connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(zmodemRcvBlock(const char*,int)) ); +// disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const +// char*,int)) ); connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, +// SLOT(zmodemRcvBlock(const char*,int)) ); // // _zmodemProgress = new ZModemDialog(QApplication::activeWindow(), false, // i18n("ZModem Progress")); @@ -894,8 +889,9 @@ void Session::zmodemFinished() _zmodemProc = 0; _zmodemBusy = false; - disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this ,SLOT(zmodemRcvBlock(const char*,int)) ); - connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) ); + disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this ,SLOT(zmodemRcvBlock(const +char*,int)) ); connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, +SLOT(onReceiveBlock(const char*,int)) ); _shellProcess->sendData("\030\030\030\030", 4); // Abort _shellProcess->sendData("\001\013\n", 3); // Try to get prompt back @@ -903,10 +899,10 @@ void Session::zmodemFinished() } } */ -void Session::onReceiveBlock( const char * buf, int len ) +void Session::onReceiveBlock(const char *buf, int len) { - _emulation->receiveData( buf, len ); - emit receivedData( QString::fromLatin1( buf, len ) ); + _emulation->receiveData(buf, len); + emit receivedData(QString::fromLatin1(buf, len)); } QSize Session::size() @@ -914,7 +910,7 @@ QSize Session::size() return _emulation->imageSize(); } -void Session::setSize(const QSize & size) +void Session::setSize(const QSize &size) { if ((size.width() <= 1) || (size.height() <= 1)) { return; @@ -935,10 +931,7 @@ int Session::getPtySlaveFd() const return ptySlaveFd; } -SessionGroup::SessionGroup() - : _masterMode(0) -{ -} +SessionGroup::SessionGroup() : _masterMode(0) { } SessionGroup::~SessionGroup() { // disconnect all @@ -952,29 +945,29 @@ QList SessionGroup::sessions() const { return _sessions.keys(); } -bool SessionGroup::masterStatus(Session * session) const +bool SessionGroup::masterStatus(Session *session) const { return _sessions[session]; } -void SessionGroup::addSession(Session * session) +void SessionGroup::addSession(Session *session) { - _sessions.insert(session,false); + _sessions.insert(session, false); QListIterator masterIter(masters()); - while ( masterIter.hasNext() ) { - connectPair(masterIter.next(),session); + while (masterIter.hasNext()) { + connectPair(masterIter.next(), session); } } -void SessionGroup::removeSession(Session * session) +void SessionGroup::removeSession(Session *session) { - setMasterStatus(session,false); + setMasterStatus(session, false); QListIterator masterIter(masters()); - while ( masterIter.hasNext() ) { - disconnectPair(masterIter.next(),session); + while (masterIter.hasNext()) { + disconnectPair(masterIter.next(), session); } _sessions.remove(session); @@ -994,24 +987,24 @@ void SessionGroup::connectAll(bool connect) { QListIterator masterIter(masters()); - while ( masterIter.hasNext() ) { - Session * master = masterIter.next(); + while (masterIter.hasNext()) { + Session *master = masterIter.next(); QListIterator otherIter(_sessions.keys()); - while ( otherIter.hasNext() ) { - Session * other = otherIter.next(); + while (otherIter.hasNext()) { + Session *other = otherIter.next(); - if ( other != master ) { - if ( connect ) { - connectPair(master,other); + if (other != master) { + if (connect) { + connectPair(master, other); } else { - disconnectPair(master,other); + disconnectPair(master, other); } } } } } -void SessionGroup::setMasterStatus(Session * session, bool master) +void SessionGroup::setMasterStatus(Session *session, bool master) { bool wasMaster = _sessions[session]; _sessions[session] = master; @@ -1022,7 +1015,7 @@ void SessionGroup::setMasterStatus(Session * session, bool master) QListIterator iter(_sessions.keys()); while (iter.hasNext()) { - Session * other = iter.next(); + Session *other = iter.next(); if (other != session) { if (master) { @@ -1034,26 +1027,26 @@ void SessionGroup::setMasterStatus(Session * session, bool master) } } -void SessionGroup::connectPair(Session * master , Session * other) const +void SessionGroup::connectPair(Session *master, Session *other) const { -// qDebug() << k_funcinfo; + // qDebug() << k_funcinfo; - if ( _masterMode & CopyInputToAll ) { + if (_masterMode & CopyInputToAll) { qDebug() << "Connection session " << master->nameTitle() << "to" << other->nameTitle(); - connect( master->emulation() , SIGNAL(sendData(const char *,int)) , other->emulation() , - SLOT(sendString(const char *,int)) ); + connect(master->emulation(), SIGNAL(sendData(const char *, int)), other->emulation(), + SLOT(sendString(const char *, int))); } } -void SessionGroup::disconnectPair(Session * master , Session * other) const +void SessionGroup::disconnectPair(Session *master, Session *other) const { -// qDebug() << k_funcinfo; + // qDebug() << k_funcinfo; - if ( _masterMode & CopyInputToAll ) { + if (_masterMode & CopyInputToAll) { qDebug() << "Disconnecting session " << master->nameTitle() << "from" << other->nameTitle(); - disconnect( master->emulation() , SIGNAL(sendData(const char *,int)) , other->emulation() , - SLOT(sendString(const char *,int)) ); + disconnect(master->emulation(), SIGNAL(sendData(const char *, int)), other->emulation(), + SLOT(sendString(const char *, int))); } } diff --git a/lib/Session.h b/lib/Session.h index b2a4d6ad..77582053 100644 --- a/lib/Session.h +++ b/lib/Session.h @@ -38,7 +38,7 @@ namespace Konsole { class Emulation; class Pty; class TerminalDisplay; -//class ZModemDialog; +// class ZModemDialog; /** * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. @@ -51,7 +51,8 @@ class TerminalDisplay; * or send input to the program in the terminal in the form of keypresses and mouse * activity. */ -class Session : public QObject { +class Session : public QObject +{ Q_OBJECT public: @@ -71,7 +72,7 @@ class Session : public QObject { * falls back to using the program specified in the SHELL environment * variable. */ - Session(QObject* parent = nullptr); + Session(QObject *parent = nullptr); ~Session() override; /** @@ -86,7 +87,7 @@ class Session : public QObject { * @param profileKey A key which can be used to obtain the current * profile settings from the SessionManager */ - void setProfileKey(const QString & profileKey); + void setProfileKey(const QString &profileKey); /** * Returns the profile key associated with this session. * This can be passed to the SessionManager to obtain the current @@ -104,7 +105,7 @@ class Session : public QObject { * Views can be removed using removeView(). The session is automatically * closed when the last view is removed. */ - void addView(TerminalDisplay * widget); + void addView(TerminalDisplay *widget); /** * Removes a view from this session. When the last view is removed, * the session will be closed automatically. @@ -112,7 +113,7 @@ class Session : public QObject { * @p widget will no longer display output from or send input * to the terminal */ - void removeView(TerminalDisplay * widget); + void removeView(TerminalDisplay *widget); /** * Returns the views connected to this session @@ -123,7 +124,7 @@ class Session : public QObject { * Returns the terminal emulation instance being used to encode / decode * characters to / from the process. */ - Emulation * emulation() const; + Emulation *emulation() const; /** * Returns the environment of this session as a list of strings like @@ -135,7 +136,7 @@ class Session : public QObject { * @p environment should be a list of strings like * VARIABLE=VALUE */ - void setEnvironment(const QStringList & environment); + void setEnvironment(const QStringList &environment); /** Returns the unique ID for this session. */ int sessionId() const; @@ -168,11 +169,10 @@ class Session : public QObject { * followed by a letter. (eg. %d for directory). The dynamic * elements available depend on the @p context */ - void setTabTitleFormat(TabTitleContext context , const QString & format); + void setTabTitleFormat(TabTitleContext context, const QString &format); /** Returns the format used by this session for tab titles. */ QString tabTitleFormat(TabTitleContext context) const; - /** Returns the arguments passed to the shell process when run() is called. */ QStringList arguments() const; /** Returns the program name of the shell process started when run() is called. */ @@ -182,20 +182,18 @@ class Session : public QObject { * Sets the command line arguments which the session's program will be passed when * run() is called. */ - void setArguments(const QStringList & arguments); + void setArguments(const QStringList &arguments); /** Sets the program to be executed when run() is called. */ - void setProgram(const QString & program); + void setProgram(const QString &program); /** Returns the session's current working directory. */ - QString initialWorkingDirectory() { - return _initialWorkingDir; - } + QString initialWorkingDirectory() { return _initialWorkingDir; } /** * Sets the initial working directory for the session when it is run * This has no effect once the session has been started. */ - void setInitialWorkingDirectory( const QString & dir ); + void setInitialWorkingDirectory(const QString &dir); /** * Sets the type of history store used by this session. @@ -205,11 +203,11 @@ class Session : public QObject { * remembered before they are lost and the storage * (in memory, on-disk etc.) used. */ - void setHistoryType(const HistoryType & type); + void setHistoryType(const HistoryType &type); /** * Returns the type of history store used by this session. */ - const HistoryType & historyType() const; + const HistoryType &historyType() const; /** * Clears the history store used by this session. */ @@ -237,7 +235,7 @@ class Session : public QObject { * Returns true if monitoring for inactivity (silence) * in the session is enabled. */ - bool isMonitorSilence() const; + bool isMonitorSilence() const; /** See setMonitorSilence() */ void setMonitorSilenceSeconds(int seconds); @@ -250,7 +248,7 @@ class Session : public QObject { * names of available key bindings can be determined using the * KeyboardTranslatorManager class. */ - void setKeyBindings(const QString & id); + void setKeyBindings(const QString &id); /** Returns the name of the key bindings used by this session. */ QString keyBindings() const; @@ -265,21 +263,19 @@ class Session : public QObject { }; /** Sets the session's title for the specified @p role to @p title. */ - void setTitle(TitleRole role , const QString & title); + void setTitle(TitleRole role, const QString &title); /** Returns the session's title for the specified @p role. */ QString title(TitleRole role) const; /** Convenience method used to read the name property. Returns title(Session::NameRole). */ - QString nameTitle() const { - return title(Session::NameRole); - } + QString nameTitle() const { return title(Session::NameRole); } /** Sets the name of the icon associated with this session. */ - void setIconName(const QString & iconName); + void setIconName(const QString &iconName); /** Returns the name of the icon associated with this session. */ QString iconName() const; /** Sets the text of the icon associated with this session. */ - void setIconText(const QString & iconText); + void setIconText(const QString &iconText); /** Returns the text of the icon associated with this session. */ QString iconText() const; @@ -296,9 +292,7 @@ class Session : public QObject { * Specifies whether to close the session automatically when the terminal * process terminates. */ - void setAutoClose(bool b) { - _autoClose = b; - } + void setAutoClose(bool b) { _autoClose = b; } /** * Sets whether flow control is enabled for this terminal @@ -312,9 +306,9 @@ class Session : public QObject { /** * Sends @p text to the current foreground terminal program. */ - void sendText(const QString & text) const; + void sendText(const QString &text) const; - void sendKeyEvent(QKeyEvent* e) const; + void sendKeyEvent(QKeyEvent *e) const; /** * Returns the process id of the terminal process. @@ -337,10 +331,10 @@ class Session : public QObject { * * @param size The size in lines and columns to request. */ - void setSize(const QSize & size); + void setSize(const QSize &size); /** Sets the text codec used by this session's terminal emulation. */ - void setCodec(QTextCodec * codec) const; + void setCodec(QTextCodec *codec) const; /** * Sets whether the session has a dark background or not. The session @@ -364,9 +358,9 @@ class Session : public QObject { */ void refresh(); -// void startZModem(const QString &rz, const QString &dir, const QStringList &list); -// void cancelZModem(); -// bool isZModemBusy() { return _zmodemBusy; } + // void startZModem(const QString &rz, const QString &dir, const QStringList &list); + // void cancelZModem(); + // bool isZModemBusy() { return _zmodemBusy; } /** * Returns a pty slave file descriptor. @@ -403,7 +397,7 @@ public slots: * emulation display. For a list of what may be changed see the * Emulation::titleChanged() signal. */ - void setUserTitle( int, const QString & caption ); + void setUserTitle(int, const QString &caption); signals: @@ -418,13 +412,13 @@ public slots: /** * Emitted when output is received from the terminal process. */ - void receivedData( const QString & text ); + void receivedData(const QString &text); /** Emitted when the session's title has changed. */ void titleChanged(); /** Emitted when the session's profile has changed. */ - void profileChanged(const QString & profile); + void profileChanged(const QString &profile); /** * Emitted when the activity state of this session changes. @@ -435,7 +429,7 @@ public slots: void stateChanged(int state); /** Emitted when a bell event occurs in the session. */ - void bellRequest( const QString & message ); + void bellRequest(const QString &message); /** * Requests that the color the text for any tabs associated with @@ -452,10 +446,10 @@ public slots: void changeBackgroundColorRequest(const QColor &); /** TODO: Document me. */ - void openUrlRequest(const QString & url); + void openUrlRequest(const QString &url); /** TODO: Document me. */ -// void zmodemDetected(); + // void zmodemDetected(); /** * Emitted when the terminal process requests a change @@ -463,7 +457,7 @@ public slots: * * @param size The requested window size in terms of lines and columns. */ - void resizeRequest(const QSize & size); + void resizeRequest(const QSize &size); /** * Emitted when a profile change command is received from the terminal. @@ -471,7 +465,7 @@ public slots: * @param text The text of the command. This is a string of the form * "PropertyName=Value;PropertyName=Value ..." */ - void profileChangeCommandReceived(const QString & text); + void profileChangeCommandReceived(const QString &text); /** * Emitted when the flow control state changes. @@ -491,9 +485,9 @@ public slots: private slots: void done(int); -// void fireZModemDetected(); + // void fireZModemDetected(); - void onReceiveBlock( const char * buffer, int len ); + void onReceiveBlock(const char *buffer, int len); void monitorTimerDone(); void onViewSizeChange(int height, int width); @@ -501,75 +495,73 @@ private slots: void activityStateSet(int); - //automatically detach views from sessions when view is destroyed - void viewDestroyed(QObject * view); + // automatically detach views from sessions when view is destroyed + void viewDestroyed(QObject *view); -// void zmodemReadStatus(); -// void zmodemReadAndSendBlock(); -// void zmodemRcvBlock(const char *data, int len); -// void zmodemFinished(); + // void zmodemReadStatus(); + // void zmodemReadAndSendBlock(); + // void zmodemRcvBlock(const char *data, int len); + // void zmodemFinished(); private: - void updateTerminalSize(); WId windowId() const; - int _uniqueIdentifier; + int _uniqueIdentifier; - Pty *_shellProcess; - Emulation * _emulation; + Pty *_shellProcess; + Emulation *_emulation; QList _views; - bool _monitorActivity; - bool _monitorSilence; - bool _notifiedActivity; - bool _masterMode; - bool _autoClose; - bool _wantedClose; - QTimer * _monitorTimer; + bool _monitorActivity; + bool _monitorSilence; + bool _notifiedActivity; + bool _masterMode; + bool _autoClose; + bool _wantedClose; + QTimer *_monitorTimer; - int _silenceSeconds; + int _silenceSeconds; - QString _nameTitle; - QString _displayTitle; - QString _userTitle; + QString _nameTitle; + QString _displayTitle; + QString _userTitle; - QString _localTabTitleFormat; - QString _remoteTabTitleFormat; + QString _localTabTitleFormat; + QString _remoteTabTitleFormat; - QString _iconName; - QString _iconText; // as set by: echo -en '\033]1;IconText\007 - bool _isTitleChanged; ///< flag if the title/icon was changed by user - bool _addToUtmp; - bool _flowControl; - bool _fullScripting; + QString _iconName; + QString _iconText; // as set by: echo -en '\033]1;IconText\007 + bool _isTitleChanged; ///< flag if the title/icon was changed by user + bool _addToUtmp; + bool _flowControl; + bool _fullScripting; - QString _program; - QStringList _arguments; + QString _program; + QStringList _arguments; - QStringList _environment; - int _sessionId; + QStringList _environment; + int _sessionId; - QString _initialWorkingDir; + QString _initialWorkingDir; // ZModem -// bool _zmodemBusy; -// KProcess* _zmodemProc; -// ZModemDialog* _zmodemProgress; + // bool _zmodemBusy; + // KProcess* _zmodemProc; + // ZModemDialog* _zmodemProgress; // Color/Font Changes by ESC Sequences - QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 + QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 - QString _profileKey; + QString _profileKey; bool _hasDarkBackground; static int lastSessionId; int ptySlaveFd; - }; /** @@ -578,7 +570,8 @@ private slots: * The type of activity which is propagated and method of propagation is controlled * by the masterMode() flags. */ -class SessionGroup : public QObject { +class SessionGroup : public QObject +{ Q_OBJECT public: @@ -588,9 +581,9 @@ class SessionGroup : public QObject { ~SessionGroup() override; /** Adds a session to the group. */ - void addSession( Session * session ); + void addSession(Session *session); /** Removes a session from the group. */ - void removeSession( Session * session ); + void removeSession(Session *session); /** Returns the list of sessions currently in the group. */ QList sessions() const; @@ -603,9 +596,9 @@ class SessionGroup : public QObject { * @param session The session whoose master status should be changed. * @param master True to make this session a master or false otherwise */ - void setMasterStatus( Session * session , bool master ); + void setMasterStatus(Session *session, bool master); /** Returns the master status of a session. See setMasterStatus() */ - bool masterStatus( Session * session ) const; + bool masterStatus(Session *session) const; /** * This enum describes the options for propagating certain activity or @@ -625,7 +618,7 @@ class SessionGroup : public QObject { * * @param mode A bitwise OR of MasterMode flags. */ - void setMasterMode( int mode ); + void setMasterMode(int mode); /** * Returns a bitwise OR of the active MasterMode flags for this group. * See setMasterMode() @@ -633,13 +626,13 @@ class SessionGroup : public QObject { int masterMode() const; private: - void connectPair(Session * master , Session * other) const; - void disconnectPair(Session * master , Session * other) const; + void connectPair(Session *master, Session *other) const; + void disconnectPair(Session *master, Session *other) const; void connectAll(bool connect); QList masters() const; // maps sessions to their master status - QHash _sessions; + QHash _sessions; int _masterMode; }; diff --git a/lib/ShellCommand.cpp b/lib/ShellCommand.cpp index 03afa452..3693d6a7 100644 --- a/lib/ShellCommand.cpp +++ b/lib/ShellCommand.cpp @@ -22,46 +22,45 @@ // Own #include "ShellCommand.h" -//some versions of gcc(4.3) require explicit include +// some versions of gcc(4.3) require explicit include #include - using namespace Konsole; // expands environment variables in 'text' // function copied from kdelibs/kio/kio/kurlcompletion.cpp -static bool expandEnv(QString & text); +static bool expandEnv(QString &text); -ShellCommand::ShellCommand(const QString & fullCommand) +ShellCommand::ShellCommand(const QString &fullCommand) { bool inQuotes = false; QString builder; - for ( int i = 0 ; i < fullCommand.count() ; i++ ) { + for (int i = 0; i < fullCommand.count(); i++) { QChar ch = fullCommand[i]; - const bool isLastChar = ( i == fullCommand.count() - 1 ); - const bool isQuote = ( ch == QLatin1Char('\'') || ch == QLatin1Char('\"') ); + const bool isLastChar = (i == fullCommand.count() - 1); + const bool isQuote = (ch == QLatin1Char('\'') || ch == QLatin1Char('\"')); - if ( !isLastChar && isQuote ) { + if (!isLastChar && isQuote) { inQuotes = !inQuotes; } else { - if ( (!ch.isSpace() || inQuotes) && !isQuote ) { + if ((!ch.isSpace() || inQuotes) && !isQuote) { builder.append(ch); } - if ( (ch.isSpace() && !inQuotes) || ( i == fullCommand.count()-1 ) ) { + if ((ch.isSpace() && !inQuotes) || (i == fullCommand.count() - 1)) { _arguments << builder; builder.clear(); } } } } -ShellCommand::ShellCommand(const QString & command , const QStringList & arguments) +ShellCommand::ShellCommand(const QString &command, const QStringList &arguments) : _arguments(arguments) { - if ( !_arguments.isEmpty() ) { + if (!_arguments.isEmpty()) { _arguments[0] = command; } } @@ -71,7 +70,7 @@ QString ShellCommand::fullCommand() const } QString ShellCommand::command() const { - if ( !_arguments.isEmpty() ) { + if (!_arguments.isEmpty()) { return _arguments[0]; } else { return QString(); @@ -91,17 +90,17 @@ bool ShellCommand::isAvailable() const Q_ASSERT(0); // not implemented yet return false; } -QStringList ShellCommand::expand(const QStringList & items) +QStringList ShellCommand::expand(const QStringList &items) { QStringList result; - for(const QString &item : items) { + for (const QString &item : items) { result << expand(item); } return result; } -QString ShellCommand::expand(const QString & text) +QString ShellCommand::expand(const QString &text) { QString result = text; expandEnv(result); @@ -114,7 +113,7 @@ QString ShellCommand::expand(const QString & text) * Expand environment variables in text. Escaped '$' characters are ignored. * Return true if any variables were expanded */ -static bool expandEnv( QString & text ) +static bool expandEnv(QString &text) { // Find all environment variables beginning with '$' // @@ -122,11 +121,11 @@ static bool expandEnv( QString & text ) bool expanded = false; - while ( (pos = text.indexOf(QLatin1Char('$'), pos)) != -1 ) { + while ((pos = text.indexOf(QLatin1Char('$'), pos)) != -1) { // Skip escaped '$' // - if ( pos > 0 && text.at(pos-1) == QLatin1Char('\\') ) { + if (pos > 0 && text.at(pos - 1) == QLatin1Char('\\')) { pos++; } // Variable found => expand @@ -134,29 +133,28 @@ static bool expandEnv( QString & text ) else { // Find the end of the variable = next '/' or ' ' // - int pos2 = text.indexOf( QLatin1Char(' '), pos+1 ); - int pos_tmp = text.indexOf( QLatin1Char('/'), pos+1 ); + int pos2 = text.indexOf(QLatin1Char(' '), pos + 1); + int pos_tmp = text.indexOf(QLatin1Char('/'), pos + 1); - if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) ) { + if (pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2)) { pos2 = pos_tmp; } - if ( pos2 == -1 ) { + if (pos2 == -1) { pos2 = text.length(); } // Replace if the variable is terminated by '/' or ' ' // and defined // - if ( pos2 >= 0 ) { + if (pos2 >= 0) { int len = pos2 - pos; - QString key = text.mid( pos+1, len-1); - QString value = - QString::fromLocal8Bit( qgetenv(key.toLocal8Bit().constData()) ); + QString key = text.mid(pos + 1, len - 1); + QString value = QString::fromLocal8Bit(qgetenv(key.toLocal8Bit().constData())); - if ( !value.isEmpty() ) { + if (!value.isEmpty()) { expanded = true; - text.replace( pos, len, value ); + text.replace(pos, len, value); pos = pos + value.length(); } else { pos = pos2; diff --git a/lib/ShellCommand.h b/lib/ShellCommand.h index 3a5804ac..91872c3a 100644 --- a/lib/ShellCommand.h +++ b/lib/ShellCommand.h @@ -48,18 +48,19 @@ namespace Konsole { * * */ -class ShellCommand { +class ShellCommand +{ public: /** * Constructs a ShellCommand from a command line. * * @param fullCommand The command line to parse. */ - ShellCommand(const QString & fullCommand); + ShellCommand(const QString &fullCommand); /** * Constructs a ShellCommand with the specified @p command and @p arguments. */ - ShellCommand(const QString & command , const QStringList & arguments); + ShellCommand(const QString &command, const QStringList &arguments); /** Returns the command. */ QString command() const; @@ -77,10 +78,10 @@ class ShellCommand { bool isAvailable() const; /** Expands environment variables in @p text .*/ - static QString expand(const QString & text); + static QString expand(const QString &text); /** Expands environment variables in each string in @p list. */ - static QStringList expand(const QStringList & items); + static QStringList expand(const QStringList &items); private: QStringList _arguments; @@ -89,4 +90,3 @@ class ShellCommand { } #endif // SHELLCOMMAND_H - diff --git a/lib/TerminalCharacterDecoder.cpp b/lib/TerminalCharacterDecoder.cpp index aa13b410..61be56db 100644 --- a/lib/TerminalCharacterDecoder.cpp +++ b/lib/TerminalCharacterDecoder.cpp @@ -35,11 +35,8 @@ using namespace Konsole; PlainTextDecoder::PlainTextDecoder() - : _output(nullptr) - , _includeTrailingWhitespace(true) - , _recordLinePositions(false) + : _output(nullptr), _includeTrailingWhitespace(true), _recordLinePositions(false) { - } void PlainTextDecoder::setTrailingWhitespace(bool enable) { @@ -49,11 +46,11 @@ bool PlainTextDecoder::trailingWhitespace() const { return _includeTrailingWhitespace; } -void PlainTextDecoder::begin(QTextStream* output) +void PlainTextDecoder::begin(QTextStream *output) { - _output = output; - if (!_linePositions.isEmpty()) - _linePositions.clear(); + _output = output; + if (!_linePositions.isEmpty()) + _linePositions.clear(); } void PlainTextDecoder::end() { @@ -68,31 +65,29 @@ QList PlainTextDecoder::linePositions() const { return _linePositions; } -void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/ - ) +void PlainTextDecoder::decodeLine(const Character *const characters, int count, + LineProperty /*properties*/ +) { - Q_ASSERT( _output ); + Q_ASSERT(_output); - if (_recordLinePositions && _output->string()) - { + if (_recordLinePositions && _output->string()) { int pos = _output->string()->count(); _linePositions << pos; } // check the real length - for (int i = 0 ; i < count ; i++) - { - if (characters + i == nullptr) - { + for (int i = 0; i < count; i++) { + if (characters + i == nullptr) { count = i; break; } } - //TODO should we ignore or respect the LINE_WRAPPED line property? + // TODO should we ignore or respect the LINE_WRAPPED line property? - //note: we build up a QString and send it to the text stream rather writing into the text - //stream a character at a time because it is more efficient. + // note: we build up a QString and send it to the text stream rather writing into the text + // stream a character at a time because it is more efficient. //(since QTextStream always deals with QStrings internally anyway) std::wstring plainText; plainText.reserve(count); @@ -101,49 +96,45 @@ void PlainTextDecoder::decodeLine(const Character* const characters, int count, // if inclusion of trailing whitespace is disabled then find the end of the // line - if ( !_includeTrailingWhitespace ) - { - for (int i = count-1 ; i >= 0 ; i--) - { - if ( characters[i].character != L' ' ) + if (!_includeTrailingWhitespace) { + for (int i = count - 1; i >= 0; i--) { + if (characters[i].character != L' ') break; else outputCount--; } } - for (int i=0;i') - text.append(L">"); + text.append(L">"); else - text.push_back(ch); - } - else - { - text.append(L" "); //HTML truncates multiple spaces, so use a space marker instead + text.push_back(ch); + } else { + text.append(L" "); // HTML truncates multiple spaces, so use a space marker instead } - } - //close any remaining open inner spans - if ( _innerSpanOpen ) + // close any remaining open inner spans + if (_innerSpanOpen) closeSpan(text); - //start new line + // start new line text.append(L"
"); *_output << QString::fromStdWString(text); } -void HTMLDecoder::openSpan(std::wstring& text , const QString& style) +void HTMLDecoder::openSpan(std::wstring &text, const QString &style) { - text.append( QString(QLatin1String("")).arg(style).toStdWString() ); + text.append(QString(QLatin1String("")).arg(style).toStdWString()); } -void HTMLDecoder::closeSpan(std::wstring& text) +void HTMLDecoder::closeSpan(std::wstring &text) { text.append(L""); } -void HTMLDecoder::setColorTable(const ColorEntry* table) +void HTMLDecoder::setColorTable(const ColorEntry *table) { _colorTable = table; } diff --git a/lib/TerminalCharacterDecoder.h b/lib/TerminalCharacterDecoder.h index c49b3d42..6ce6b11a 100644 --- a/lib/TerminalCharacterDecoder.h +++ b/lib/TerminalCharacterDecoder.h @@ -28,14 +28,13 @@ class QTextStream; -namespace Konsole -{ +namespace Konsole { /** * Base class for terminal character decoders * - * The decoder converts lines of terminal characters which consist of a unicode character, foreground - * and background colours and other appearance-related properties into text strings. + * The decoder converts lines of terminal characters which consist of a unicode character, + * foreground and background colours and other appearance-related properties into text strings. * * Derived classes may produce either plain text with no other colour or appearance information, or * they may produce text which incorporates these additional properties. @@ -43,10 +42,10 @@ namespace Konsole class TerminalCharacterDecoder { public: - virtual ~TerminalCharacterDecoder() {} + virtual ~TerminalCharacterDecoder() { } /** Begin decoding characters. The resulting text is appended to @p output. */ - virtual void begin(QTextStream* output) = 0; + virtual void begin(QTextStream *output) = 0; /** End decoding. */ virtual void end() = 0; @@ -58,14 +57,13 @@ class TerminalCharacterDecoder * @param count The number of characters * @param properties Additional properties which affect all characters in the line */ - virtual void decodeLine(const Character* const characters, - int count, + virtual void decodeLine(const Character *const characters, int count, LineProperty properties) = 0; }; /** - * A terminal character decoder which produces plain text, ignoring colours and other appearance-related - * properties of the original characters. + * A terminal character decoder which produces plain text, ignoring colours and other + * appearance-related properties of the original characters. */ class PlainTextDecoder : public TerminalCharacterDecoder { @@ -89,19 +87,17 @@ class PlainTextDecoder : public TerminalCharacterDecoder * the output device is not a string. */ QList linePositions() const; - /** Enables recording of character positions at which new lines are added. See linePositions() */ + /** Enables recording of character positions at which new lines are added. See linePositions() + */ void setRecordLinePositions(bool record); - void begin(QTextStream* output) override; + void begin(QTextStream *output) override; void end() override; - void decodeLine(const Character* const characters, - int count, - LineProperty properties) override; - + void decodeLine(const Character *const characters, int count, LineProperty properties) override; private: - QTextStream* _output; + QTextStream *_output; bool _includeTrailingWhitespace; bool _recordLinePositions; @@ -123,26 +119,23 @@ class HTMLDecoder : public TerminalCharacterDecoder * Sets the colour table which the decoder uses to produce the HTML colour codes in its * output */ - void setColorTable( const ColorEntry* table ); + void setColorTable(const ColorEntry *table); - void decodeLine(const Character* const characters, - int count, - LineProperty properties) override; + void decodeLine(const Character *const characters, int count, LineProperty properties) override; - void begin(QTextStream* output) override; + void begin(QTextStream *output) override; void end() override; private: - void openSpan(std::wstring& text , const QString& style); - void closeSpan(std::wstring& text); + void openSpan(std::wstring &text, const QString &style); + void closeSpan(std::wstring &text); - QTextStream* _output; - const ColorEntry* _colorTable; + QTextStream *_output; + const ColorEntry *_colorTable; bool _innerSpanOpen; quint8 _lastRendition; CharacterColor _lastForeColor; CharacterColor _lastBackColor; - }; } diff --git a/lib/TerminalDisplay.cpp b/lib/TerminalDisplay.cpp index a36d3914..6af3114f 100644 --- a/lib/TerminalDisplay.cpp +++ b/lib/TerminalDisplay.cpp @@ -69,34 +69,43 @@ using namespace Konsole; #ifndef loc -#define loc(X,Y) ((Y)*_columns+(X)) +# define loc(X, Y) ((Y)*_columns + (X)) #endif #define yMouseScroll 1 -#define REPCHAR "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - "abcdefgjijklmnopqrstuvwxyz" \ - "0123456789./+@" +#define REPCHAR \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefgjijklmnopqrstuvwxyz" \ + "0123456789./+@" const ColorEntry Konsole::base_color_table[TABLE_COLORS] = -// The following are almost IBM standard color codes, with some slight -// gamma correction for the dim colors to compensate for bright X screens. -// It contains the 8 ansiterm/xterm colors in 2 intensities. -{ - // Fixme: could add faint colors here, also. - // normal - ColorEntry(QColor(0x00,0x00,0x00), false), ColorEntry( QColor(0xB2,0xB2,0xB2), true), // Dfore, Dback - ColorEntry(QColor(0x00,0x00,0x00), false), ColorEntry( QColor(0xB2,0x18,0x18), false), // Black, Red - ColorEntry(QColor(0x18,0xB2,0x18), false), ColorEntry( QColor(0xB2,0x68,0x18), false), // Green, Yellow - ColorEntry(QColor(0x18,0x18,0xB2), false), ColorEntry( QColor(0xB2,0x18,0xB2), false), // Blue, Magenta - ColorEntry(QColor(0x18,0xB2,0xB2), false), ColorEntry( QColor(0xB2,0xB2,0xB2), false), // Cyan, White - // intensiv - ColorEntry(QColor(0x00,0x00,0x00), false), ColorEntry( QColor(0xFF,0xFF,0xFF), true), - ColorEntry(QColor(0x68,0x68,0x68), false), ColorEntry( QColor(0xFF,0x54,0x54), false), - ColorEntry(QColor(0x54,0xFF,0x54), false), ColorEntry( QColor(0xFF,0xFF,0x54), false), - ColorEntry(QColor(0x54,0x54,0xFF), false), ColorEntry( QColor(0xFF,0x54,0xFF), false), - ColorEntry(QColor(0x54,0xFF,0xFF), false), ColorEntry( QColor(0xFF,0xFF,0xFF), false) -}; + // The following are almost IBM standard color codes, with some slight + // gamma correction for the dim colors to compensate for bright X screens. + // It contains the 8 ansiterm/xterm colors in 2 intensities. + { + // Fixme: could add faint colors here, also. + // normal + ColorEntry(QColor(0x00, 0x00, 0x00), false), + ColorEntry(QColor(0xB2, 0xB2, 0xB2), true), // Dfore, Dback + ColorEntry(QColor(0x00, 0x00, 0x00), false), + ColorEntry(QColor(0xB2, 0x18, 0x18), false), // Black, Red + ColorEntry(QColor(0x18, 0xB2, 0x18), false), + ColorEntry(QColor(0xB2, 0x68, 0x18), false), // Green, Yellow + ColorEntry(QColor(0x18, 0x18, 0xB2), false), + ColorEntry(QColor(0xB2, 0x18, 0xB2), false), // Blue, Magenta + ColorEntry(QColor(0x18, 0xB2, 0xB2), false), + ColorEntry(QColor(0xB2, 0xB2, 0xB2), false), // Cyan, White + // intensiv + ColorEntry(QColor(0x00, 0x00, 0x00), false), ColorEntry(QColor(0xFF, 0xFF, 0xFF), true), + ColorEntry(QColor(0x68, 0x68, 0x68), false), + ColorEntry(QColor(0xFF, 0x54, 0x54), false), + ColorEntry(QColor(0x54, 0xFF, 0x54), false), + ColorEntry(QColor(0xFF, 0xFF, 0x54), false), + ColorEntry(QColor(0x54, 0x54, 0xFF), false), + ColorEntry(QColor(0xFF, 0x54, 0xFF), false), + ColorEntry(QColor(0x54, 0xFF, 0xFF), false), ColorEntry(QColor(0xFF, 0xFF, 0xFF), false) + }; // scroll increment used when dragging selection at top/bottom of window. @@ -106,7 +115,7 @@ bool TerminalDisplay::HAVE_TRANSPARENCY = true; // we use this to force QPainter to display text in LTR mode // more information can be found in: http://unicode.org/reports/tr9/ -const QChar LTR_OVERRIDE_CHAR( 0x202D ); +const QChar LTR_OVERRIDE_CHAR(0x202D); /* ------------------------------------------------------------------------- */ /* */ @@ -122,51 +131,50 @@ const QChar LTR_OVERRIDE_CHAR( 0x202D ); IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White */ -ScreenWindow* TerminalDisplay::screenWindow() const +ScreenWindow *TerminalDisplay::screenWindow() const { return _screenWindow; } -void TerminalDisplay::setScreenWindow(ScreenWindow* window) +void TerminalDisplay::setScreenWindow(ScreenWindow *window) { // disconnect existing screen window if any - if ( _screenWindow ) - { - disconnect( _screenWindow , nullptr , this , nullptr ); + if (_screenWindow) { + disconnect(_screenWindow, nullptr, this, nullptr); } _screenWindow = window; - if ( window ) - { + if (window) { -// TODO: Determine if this is an issue. -//#warning "The order here is not specified - does it matter whether updateImage or updateLineProperties comes first?" - connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateLineProperties()) ); - connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage()) ); - connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateFilters()) ); - connect( _screenWindow , SIGNAL(scrolled(int)) , this , SLOT(updateFilters()) ); - connect( _screenWindow , &ScreenWindow::scrollToEnd , this , &TerminalDisplay::scrollToEnd ); + // TODO: Determine if this is an issue. + //#warning "The order here is not specified - does it matter whether updateImage or + //updateLineProperties comes first?" + connect(_screenWindow, SIGNAL(outputChanged()), this, SLOT(updateLineProperties())); + connect(_screenWindow, SIGNAL(outputChanged()), this, SLOT(updateImage())); + connect(_screenWindow, SIGNAL(outputChanged()), this, SLOT(updateFilters())); + connect(_screenWindow, SIGNAL(scrolled(int)), this, SLOT(updateFilters())); + connect(_screenWindow, &ScreenWindow::scrollToEnd, this, &TerminalDisplay::scrollToEnd); window->setWindowLines(_lines); } } -const ColorEntry* TerminalDisplay::colorTable() const +const ColorEntry *TerminalDisplay::colorTable() const { - return _colorTable; + return _colorTable; } -void TerminalDisplay::setBackgroundColor(const QColor& color) +void TerminalDisplay::setBackgroundColor(const QColor &color) { _colorTable[DEFAULT_BACK_COLOR].color = color; QPalette p = palette(); - p.setColor( backgroundRole(), color ); - setPalette( p ); + p.setColor(backgroundRole(), color); + setPalette(p); - // Avoid propagating the palette change to the scroll bar - _scrollBar->setPalette( QApplication::palette() ); + // Avoid propagating the palette change to the scroll bar + _scrollBar->setPalette(QApplication::palette()); update(); } -void TerminalDisplay::setForegroundColor(const QColor& color) +void TerminalDisplay::setForegroundColor(const QColor &color) { _colorTable[DEFAULT_FORE_COLOR].color = color; @@ -174,10 +182,10 @@ void TerminalDisplay::setForegroundColor(const QColor& color) } void TerminalDisplay::setColorTable(const ColorEntry table[]) { - for (int i = 0; i < TABLE_COLORS; i++) - _colorTable[i] = table[i]; + for (int i = 0; i < TABLE_COLORS; i++) + _colorTable[i] = table[i]; - setBackgroundColor(_colorTable[DEFAULT_BACK_COLOR].color); + setBackgroundColor(_colorTable[DEFAULT_BACK_COLOR].color); } /* ------------------------------------------------------------------------- */ @@ -198,112 +206,112 @@ void TerminalDisplay::setColorTable(const ColorEntry table[]) QCodec. */ -bool TerminalDisplay::isLineChar(wchar_t c) const { +bool TerminalDisplay::isLineChar(wchar_t c) const +{ return _drawLineChars && ((c & 0xFF80) == 0x2500); } -bool TerminalDisplay::isLineCharString(const std::wstring& string) const { +bool TerminalDisplay::isLineCharString(const std::wstring &string) const +{ return (string.length() > 0) && (isLineChar(string[0])); } - // assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. -unsigned short Konsole::vt100_graphics[32] = -{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 - 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, - 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, - 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, - 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 -}; +unsigned short + Konsole::vt100_graphics[32] = { // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 + 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, 0x2424, 0x240b, + 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, + 0x2524, 0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 + }; -void TerminalDisplay::fontChange(const QFont&) +void TerminalDisplay::fontChange(const QFont &) { - QFontMetrics fm(font()); - _fontHeight = fm.height() + _lineSpacing; + QFontMetrics fm(font()); + _fontHeight = fm.height() + _lineSpacing; - // waba TerminalDisplay 1.123: - // "Base character width on widest ASCII character. This prevents too wide - // characters in the presence of double wide (e.g. Japanese) characters." - // Get the width from representative normal width characters - _fontWidth = qRound((double)fm.horizontalAdvance(QLatin1String(REPCHAR))/(double)qstrlen(REPCHAR)); + // waba TerminalDisplay 1.123: + // "Base character width on widest ASCII character. This prevents too wide + // characters in the presence of double wide (e.g. Japanese) characters." + // Get the width from representative normal width characters + _fontWidth = + qRound((double)fm.horizontalAdvance(QLatin1String(REPCHAR)) / (double)qstrlen(REPCHAR)); - _fixedFont = true; + _fixedFont = true; - int fw = fm.horizontalAdvance(QLatin1Char(REPCHAR[0])); - for(unsigned int i=1; i< qstrlen(REPCHAR); i++) - { - if (fw != fm.horizontalAdvance(QLatin1Char(REPCHAR[i]))) - { - _fixedFont = false; - break; + int fw = fm.horizontalAdvance(QLatin1Char(REPCHAR[0])); + for (unsigned int i = 1; i < qstrlen(REPCHAR); i++) { + if (fw != fm.horizontalAdvance(QLatin1Char(REPCHAR[i]))) { + _fixedFont = false; + break; + } } - } - if (_fontWidth < 1) - _fontWidth=1; + if (_fontWidth < 1) + _fontWidth = 1; - _fontAscent = fm.ascent(); + _fontAscent = fm.ascent(); - emit changedFontMetricSignal( _fontHeight, _fontWidth ); - propagateSize(); + emit changedFontMetricSignal(_fontHeight, _fontWidth); + propagateSize(); - // We will run paint event testing procedure. - // Although this operation will destory the orignal content, - // the content will be drawn again after the test. - _drawTextTestFlag = true; - update(); + // We will run paint event testing procedure. + // Although this operation will destory the orignal content, + // the content will be drawn again after the test. + _drawTextTestFlag = true; + update(); } -void TerminalDisplay::calDrawTextAdditionHeight(QPainter& painter) +void TerminalDisplay::calDrawTextAdditionHeight(QPainter &painter) { QRect test_rect, feedback_rect; - test_rect.setRect(1, 1, _fontWidth * 4, _fontHeight); - painter.drawText(test_rect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + QLatin1String("Mq"), &feedback_rect); + test_rect.setRect(1, 1, _fontWidth * 4, _fontHeight); + painter.drawText(test_rect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + QLatin1String("Mq"), + &feedback_rect); - //qDebug() << "test_rect:" << test_rect << "feeback_rect:" << feedback_rect; + // qDebug() << "test_rect:" << test_rect << "feeback_rect:" << feedback_rect; - _drawTextAdditionHeight = (feedback_rect.height() - _fontHeight) / 2; - if(_drawTextAdditionHeight < 0) { - _drawTextAdditionHeight = 0; - } + _drawTextAdditionHeight = (feedback_rect.height() - _fontHeight) / 2; + if (_drawTextAdditionHeight < 0) { + _drawTextAdditionHeight = 0; + } - _drawTextTestFlag = false; + _drawTextTestFlag = false; } -void TerminalDisplay::setVTFont(const QFont& f) +void TerminalDisplay::setVTFont(const QFont &f) { - QFont font = f; + QFont font = f; - // This was originally set for OS X only: - // mac uses floats for font width specification. - // this ensures the same handling for all platforms - // but then there was revealed that various Linux distros - // have this problem too... - font.setStyleStrategy(QFont::ForceIntegerMetrics); + // This was originally set for OS X only: + // mac uses floats for font width specification. + // this ensures the same handling for all platforms + // but then there was revealed that various Linux distros + // have this problem too... + font.setStyleStrategy(QFont::ForceIntegerMetrics); - if ( !QFontInfo(font).fixedPitch() ) - { - qDebug() << "Using a variable-width font in the terminal. This may cause performance degradation and display/alignment errors."; - } + if (!QFontInfo(font).fixedPitch()) { + qDebug() << "Using a variable-width font in the terminal. This may cause performance " + "degradation and display/alignment errors."; + } - // hint that text should be drawn without anti-aliasing. - // depending on the user's font configuration, this may not be respected - if (!_antialiasText) - font.setStyleStrategy( QFont::NoAntialias ); + // hint that text should be drawn without anti-aliasing. + // depending on the user's font configuration, this may not be respected + if (!_antialiasText) + font.setStyleStrategy(QFont::NoAntialias); - // experimental optimization. Konsole assumes that the terminal is using a - // mono-spaced font, in which case kerning information should have an effect. - // Disabling kerning saves some computation when rendering text. - font.setKerning(false); + // experimental optimization. Konsole assumes that the terminal is using a + // mono-spaced font, in which case kerning information should have an effect. + // Disabling kerning saves some computation when rendering text. + font.setKerning(false); - QWidget::setFont(font); - fontChange(font); + QWidget::setFont(font); + fontChange(font); } void TerminalDisplay::setFont(const QFont &) { - // ignore font change request if not coming from konsole itself + // ignore font change request if not coming from konsole itself } /* ------------------------------------------------------------------------- */ @@ -313,134 +321,133 @@ void TerminalDisplay::setFont(const QFont &) /* ------------------------------------------------------------------------- */ TerminalDisplay::TerminalDisplay(QWidget *parent) -:QWidget(parent) -,_screenWindow(nullptr) -,_allowBell(true) -,_gridLayout(nullptr) -,_fontHeight(1) -,_fontWidth(1) -,_fontAscent(1) -,_boldIntense(true) -,_lines(1) -,_columns(1) -,_usedLines(1) -,_usedColumns(1) -,_contentHeight(1) -,_contentWidth(1) -,_image(nullptr) -,_randomSeed(0) -,_resizing(false) -,_terminalSizeHint(false) -,_terminalSizeStartup(true) -,_bidiEnabled(false) -,_mouseMarks(false) -,_disabledBracketedPasteMode(false) -,_actSel(0) -,_wordSelectionMode(false) -,_lineSelectionMode(false) -,_preserveLineBreaks(false) -,_columnSelectionMode(false) -,_scrollbarLocation(QTermWidget::NoScrollBar) -,_wordCharacters(QLatin1String(":@-./_~")) -,_bellMode(SystemBeepBell) -,_blinking(false) -,_hasBlinker(false) -,_cursorBlinking(false) -,_hasBlinkingCursor(false) -,_allowBlinkingText(true) -,_ctrlDrag(false) -,_tripleClickMode(SelectWholeLine) -,_isFixedSize(false) -,_possibleTripleClick(false) -,_resizeWidget(nullptr) -,_resizeTimer(nullptr) -,_flowControlWarningEnabled(false) -,_outputSuspendedLabel(nullptr) -,_lineSpacing(0) -,_colorsInverted(false) -,_opacity(static_cast(1)) -,_backgroundMode(None) -,_filterChain(new TerminalImageFilterChain()) -,_cursorShape(Emulation::KeyboardCursorShape::BlockCursor) -,mMotionAfterPasting(NoMoveScreenWindow) -,_leftBaseMargin(1) -,_topBaseMargin(1) -,_drawLineChars(true) -{ - // variables for draw text - _drawTextAdditionHeight = 0; - _drawTextTestFlag = false; - - // terminal applications are not designed with Right-To-Left in mind, - // so the layout is forced to Left-To-Right - setLayoutDirection(Qt::LeftToRight); - - // The offsets are not yet calculated. - // Do not calculate these too often to be more smoothly when resizing - // konsole in opaque mode. - _topMargin = _topBaseMargin; - _leftMargin = _leftBaseMargin; - - // create scroll bar for scrolling output up and down - // set the scroll bar's slider to occupy the whole area of the scroll bar initially - _scrollBar = new QScrollBar(this); - // since the contrast with the terminal background may not be enough, - // the scrollbar should be auto-filled if not transient - if (!_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) - _scrollBar->setAutoFillBackground(true); - setScroll(0,0); - _scrollBar->setCursor( Qt::ArrowCursor ); - connect(_scrollBar, SIGNAL(valueChanged(int)), this, - SLOT(scrollBarPositionChanged(int))); - // qtermwidget: we have to hide it here due the _scrollbarLocation==NoScrollBar - // check in TerminalDisplay::setScrollBarPosition(ScrollBarPosition position) - _scrollBar->hide(); - - // setup timers for blinking cursor and text - _blinkTimer = new QTimer(this); - connect(_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkEvent())); - _blinkCursorTimer = new QTimer(this); - connect(_blinkCursorTimer, SIGNAL(timeout()), this, SLOT(blinkCursorEvent())); - -// KCursor::setAutoHideCursor( this, true ); - - setUsesMouse(true); - setBracketedPasteMode(false); - setColorTable(base_color_table); - setMouseTracking(true); - - // Enable drag and drop - setAcceptDrops(true); // attempt - dragInfo.state = diNone; - - setFocusPolicy( Qt::WheelFocus ); - - // enable input method support - setAttribute(Qt::WA_InputMethodEnabled, true); - - // this is an important optimization, it tells Qt - // that TerminalDisplay will handle repainting its entire area. - setAttribute(Qt::WA_OpaquePaintEvent); - - _gridLayout = new QGridLayout(this); - _gridLayout->setContentsMargins(0, 0, 0, 0); - - setLayout( _gridLayout ); - - new AutoScrollHandler(this); + : QWidget(parent), + _screenWindow(nullptr), + _allowBell(true), + _gridLayout(nullptr), + _fontHeight(1), + _fontWidth(1), + _fontAscent(1), + _boldIntense(true), + _lines(1), + _columns(1), + _usedLines(1), + _usedColumns(1), + _contentHeight(1), + _contentWidth(1), + _image(nullptr), + _randomSeed(0), + _resizing(false), + _terminalSizeHint(false), + _terminalSizeStartup(true), + _bidiEnabled(false), + _mouseMarks(false), + _disabledBracketedPasteMode(false), + _actSel(0), + _wordSelectionMode(false), + _lineSelectionMode(false), + _preserveLineBreaks(false), + _columnSelectionMode(false), + _scrollbarLocation(QTermWidget::NoScrollBar), + _wordCharacters(QLatin1String(":@-./_~")), + _bellMode(SystemBeepBell), + _blinking(false), + _hasBlinker(false), + _cursorBlinking(false), + _hasBlinkingCursor(false), + _allowBlinkingText(true), + _ctrlDrag(false), + _tripleClickMode(SelectWholeLine), + _isFixedSize(false), + _possibleTripleClick(false), + _resizeWidget(nullptr), + _resizeTimer(nullptr), + _flowControlWarningEnabled(false), + _outputSuspendedLabel(nullptr), + _lineSpacing(0), + _colorsInverted(false), + _opacity(static_cast(1)), + _backgroundMode(None), + _filterChain(new TerminalImageFilterChain()), + _cursorShape(Emulation::KeyboardCursorShape::BlockCursor), + mMotionAfterPasting(NoMoveScreenWindow), + _leftBaseMargin(1), + _topBaseMargin(1), + _drawLineChars(true) +{ + // variables for draw text + _drawTextAdditionHeight = 0; + _drawTextTestFlag = false; + + // terminal applications are not designed with Right-To-Left in mind, + // so the layout is forced to Left-To-Right + setLayoutDirection(Qt::LeftToRight); + + // The offsets are not yet calculated. + // Do not calculate these too often to be more smoothly when resizing + // konsole in opaque mode. + _topMargin = _topBaseMargin; + _leftMargin = _leftBaseMargin; + + // create scroll bar for scrolling output up and down + // set the scroll bar's slider to occupy the whole area of the scroll bar initially + _scrollBar = new QScrollBar(this); + // since the contrast with the terminal background may not be enough, + // the scrollbar should be auto-filled if not transient + if (!_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) + _scrollBar->setAutoFillBackground(true); + setScroll(0, 0); + _scrollBar->setCursor(Qt::ArrowCursor); + connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + // qtermwidget: we have to hide it here due the _scrollbarLocation==NoScrollBar + // check in TerminalDisplay::setScrollBarPosition(ScrollBarPosition position) + _scrollBar->hide(); + + // setup timers for blinking cursor and text + _blinkTimer = new QTimer(this); + connect(_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkEvent())); + _blinkCursorTimer = new QTimer(this); + connect(_blinkCursorTimer, SIGNAL(timeout()), this, SLOT(blinkCursorEvent())); + + // KCursor::setAutoHideCursor( this, true ); + + setUsesMouse(true); + setBracketedPasteMode(false); + setColorTable(base_color_table); + setMouseTracking(true); + + // Enable drag and drop + setAcceptDrops(true); // attempt + dragInfo.state = diNone; + + setFocusPolicy(Qt::WheelFocus); + + // enable input method support + setAttribute(Qt::WA_InputMethodEnabled, true); + + // this is an important optimization, it tells Qt + // that TerminalDisplay will handle repainting its entire area. + setAttribute(Qt::WA_OpaquePaintEvent); + + _gridLayout = new QGridLayout(this); + _gridLayout->setContentsMargins(0, 0, 0, 0); + + setLayout(_gridLayout); + + new AutoScrollHandler(this); } TerminalDisplay::~TerminalDisplay() { - disconnect(_blinkTimer); - disconnect(_blinkCursorTimer); - qApp->removeEventFilter( this ); + disconnect(_blinkTimer); + disconnect(_blinkCursorTimer); + qApp->removeEventFilter(this); - delete[] _image; + delete[] _image; - delete _gridLayout; - delete _outputSuspendedLabel; - delete _filterChain; + delete _gridLayout; + delete _outputSuspendedLabel; + delete _filterChain; } /* ------------------------------------------------------------------------- */ @@ -467,107 +474,104 @@ where _ = none - = horizontal line. */ - -enum LineEncode -{ - TopL = (1<<1), - TopC = (1<<2), - TopR = (1<<3), - - LeftT = (1<<5), - Int11 = (1<<6), - Int12 = (1<<7), - Int13 = (1<<8), - RightT = (1<<9), - - LeftC = (1<<10), - Int21 = (1<<11), - Int22 = (1<<12), - Int23 = (1<<13), - RightC = (1<<14), - - LeftB = (1<<15), - Int31 = (1<<16), - Int32 = (1<<17), - Int33 = (1<<18), - RightB = (1<<19), - - BotL = (1<<21), - BotC = (1<<22), - BotR = (1<<23) +enum LineEncode { + TopL = (1 << 1), + TopC = (1 << 2), + TopR = (1 << 3), + + LeftT = (1 << 5), + Int11 = (1 << 6), + Int12 = (1 << 7), + Int13 = (1 << 8), + RightT = (1 << 9), + + LeftC = (1 << 10), + Int21 = (1 << 11), + Int22 = (1 << 12), + Int23 = (1 << 13), + RightC = (1 << 14), + + LeftB = (1 << 15), + Int31 = (1 << 16), + Int32 = (1 << 17), + Int33 = (1 << 18), + RightB = (1 << 19), + + BotL = (1 << 21), + BotC = (1 << 22), + BotR = (1 << 23) }; #include "LineFont.h" -static void drawLineChar(QPainter& paint, int x, int y, int w, int h, uint8_t code) +static void drawLineChar(QPainter &paint, int x, int y, int w, int h, uint8_t code) { - //Calculate cell midpoints, end points. - int cx = x + w/2; - int cy = y + h/2; + // Calculate cell midpoints, end points. + int cx = x + w / 2; + int cy = y + h / 2; int ex = x + w - 1; int ey = y + h - 1; quint32 toDraw = LineChars[code]; - //Top _lines: + // Top _lines: if (toDraw & TopL) - paint.drawLine(cx-1, y, cx-1, cy-2); + paint.drawLine(cx - 1, y, cx - 1, cy - 2); if (toDraw & TopC) - paint.drawLine(cx, y, cx, cy-2); + paint.drawLine(cx, y, cx, cy - 2); if (toDraw & TopR) - paint.drawLine(cx+1, y, cx+1, cy-2); + paint.drawLine(cx + 1, y, cx + 1, cy - 2); - //Bot _lines: + // Bot _lines: if (toDraw & BotL) - paint.drawLine(cx-1, cy+2, cx-1, ey); + paint.drawLine(cx - 1, cy + 2, cx - 1, ey); if (toDraw & BotC) - paint.drawLine(cx, cy+2, cx, ey); + paint.drawLine(cx, cy + 2, cx, ey); if (toDraw & BotR) - paint.drawLine(cx+1, cy+2, cx+1, ey); + paint.drawLine(cx + 1, cy + 2, cx + 1, ey); - //Left _lines: + // Left _lines: if (toDraw & LeftT) - paint.drawLine(x, cy-1, cx-2, cy-1); + paint.drawLine(x, cy - 1, cx - 2, cy - 1); if (toDraw & LeftC) - paint.drawLine(x, cy, cx-2, cy); + paint.drawLine(x, cy, cx - 2, cy); if (toDraw & LeftB) - paint.drawLine(x, cy+1, cx-2, cy+1); + paint.drawLine(x, cy + 1, cx - 2, cy + 1); - //Right _lines: + // Right _lines: if (toDraw & RightT) - paint.drawLine(cx+2, cy-1, ex, cy-1); + paint.drawLine(cx + 2, cy - 1, ex, cy - 1); if (toDraw & RightC) - paint.drawLine(cx+2, cy, ex, cy); + paint.drawLine(cx + 2, cy, ex, cy); if (toDraw & RightB) - paint.drawLine(cx+2, cy+1, ex, cy+1); + paint.drawLine(cx + 2, cy + 1, ex, cy + 1); - //Intersection points. + // Intersection points. if (toDraw & Int11) - paint.drawPoint(cx-1, cy-1); + paint.drawPoint(cx - 1, cy - 1); if (toDraw & Int12) - paint.drawPoint(cx, cy-1); + paint.drawPoint(cx, cy - 1); if (toDraw & Int13) - paint.drawPoint(cx+1, cy-1); + paint.drawPoint(cx + 1, cy - 1); if (toDraw & Int21) - paint.drawPoint(cx-1, cy); + paint.drawPoint(cx - 1, cy); if (toDraw & Int22) paint.drawPoint(cx, cy); if (toDraw & Int23) - paint.drawPoint(cx+1, cy); + paint.drawPoint(cx + 1, cy); if (toDraw & Int31) - paint.drawPoint(cx-1, cy+1); + paint.drawPoint(cx - 1, cy + 1); if (toDraw & Int32) - paint.drawPoint(cx, cy+1); + paint.drawPoint(cx, cy + 1); if (toDraw & Int33) - paint.drawPoint(cx+1, cy+1); - + paint.drawPoint(cx + 1, cy + 1); } -static void drawOtherChar(QPainter& paint, int x, int y, int w, int h, uchar code) +static void drawOtherChar(QPainter &paint, int x, int y, int w, int h, uchar code) { - //Calculate cell midpoints, end points. + // Calculate cell midpoints, end points. const int cx = x + w / 2; const int cy = y + h / 2; const int ex = x + w - 1; @@ -646,28 +650,26 @@ static void drawOtherChar(QPainter& paint, int x, int y, int w, int h, uchar cod } } -void TerminalDisplay::drawLineCharString( QPainter& painter, int x, int y, const std::wstring& str, - const Character* attributes) const +void TerminalDisplay::drawLineCharString(QPainter &painter, int x, int y, const std::wstring &str, + const Character *attributes) const { - const QPen& currentPen = painter.pen(); + const QPen ¤tPen = painter.pen(); - if ( (attributes->rendition & RE_BOLD) && _boldIntense ) - { - QPen boldPen(currentPen); - boldPen.setWidth(3); - painter.setPen( boldPen ); - } + if ((attributes->rendition & RE_BOLD) && _boldIntense) { + QPen boldPen(currentPen); + boldPen.setWidth(3); + painter.setPen(boldPen); + } - for (size_t i=0 ; i < str.length(); i++) - { - uint8_t code = static_cast(str[i] & 0xffU); - if (LineChars[code]) - drawLineChar(painter, x + (_fontWidth*i), y, _fontWidth, _fontHeight, code); - else - drawOtherChar(painter, x + (_fontWidth * i), y, _fontWidth, _fontHeight, code); - } + for (size_t i = 0; i < str.length(); i++) { + uint8_t code = static_cast(str[i] & 0xffU); + if (LineChars[code]) + drawLineChar(painter, x + (_fontWidth * i), y, _fontWidth, _fontHeight, code); + else + drawOtherChar(painter, x + (_fontWidth * i), y, _fontWidth, _fontHeight, code); + } - painter.setPen( currentPen ); + painter.setPen(currentPen); } void TerminalDisplay::setKeyboardCursorShape(QTermWidget::KeyboardCursorShape shape) @@ -680,7 +682,7 @@ QTermWidget::KeyboardCursorShape TerminalDisplay::keyboardCursorShape() const { return _cursorShape; } -void TerminalDisplay::setKeyboardCursorColor(bool useForegroundColor, const QColor& color) +void TerminalDisplay::setKeyboardCursorColor(bool useForegroundColor, const QColor &color) { if (useForegroundColor) _cursorColor = QColor(); // an invalid color means that @@ -701,15 +703,12 @@ void TerminalDisplay::setOpacity(qreal opacity) _opacity = qBound(static_cast(0), opacity, static_cast(1)); } -void TerminalDisplay::setBackgroundImage(const QString& backgroundImage) +void TerminalDisplay::setBackgroundImage(const QString &backgroundImage) { - if (!backgroundImage.isEmpty()) - { + if (!backgroundImage.isEmpty()) { _backgroundImage.load(backgroundImage); setAttribute(Qt::WA_OpaquePaintEvent, false); - } - else - { + } else { _backgroundImage = QPixmap(); setAttribute(Qt::WA_OpaquePaintEvent, true); } @@ -720,92 +719,75 @@ void TerminalDisplay::setBackgroundMode(BackgroundMode mode) _backgroundMode = mode; } -void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const QColor& backgroundColor, bool useOpacitySetting ) +void TerminalDisplay::drawBackground(QPainter &painter, const QRect &rect, + const QColor &backgroundColor, bool useOpacitySetting) { - // The whole widget rectangle is filled by the background color from - // the color scheme set in setColorTable(), while the scrollbar is - // left to the widget style for a consistent look. - if ( useOpacitySetting ) - { - if (_backgroundImage.isNull()) { - QColor color(backgroundColor); - color.setAlphaF(_opacity); - - painter.save(); - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(rect, color); - painter.restore(); - } + // The whole widget rectangle is filled by the background color from + // the color scheme set in setColorTable(), while the scrollbar is + // left to the widget style for a consistent look. + if (useOpacitySetting) { + if (_backgroundImage.isNull()) { + QColor color(backgroundColor); + color.setAlphaF(_opacity); + + painter.save(); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(rect, color); + painter.restore(); } - else - painter.fillRect(rect, backgroundColor); + } else + painter.fillRect(rect, backgroundColor); } -void TerminalDisplay::drawCursor(QPainter& painter, - const QRect& rect, - const QColor& foregroundColor, - const QColor& /*backgroundColor*/, - bool& invertCharacterColor) +void TerminalDisplay::drawCursor(QPainter &painter, const QRect &rect, + const QColor &foregroundColor, const QColor & /*backgroundColor*/, + bool &invertCharacterColor) { QRectF cursorRect = rect; cursorRect.setHeight(_fontHeight - _lineSpacing - 1); - if (!_cursorBlinking) - { - if ( _cursorColor.isValid() ) - painter.setPen(_cursorColor); - else - painter.setPen(foregroundColor); + if (!_cursorBlinking) { + if (_cursorColor.isValid()) + painter.setPen(_cursorColor); + else + painter.setPen(foregroundColor); - if ( _cursorShape == Emulation::KeyboardCursorShape::BlockCursor ) - { + if (_cursorShape == Emulation::KeyboardCursorShape::BlockCursor) { // draw the cursor outline, adjusting the area so that // it is draw entirely inside 'rect' - float penWidth = qMax(1,painter.pen().width()); + float penWidth = qMax(1, painter.pen().width()); - painter.drawRect(cursorRect.adjusted(penWidth/2, - penWidth/2, - - penWidth/2, - - penWidth/2)); - if ( hasFocus() ) - { - painter.fillRect(cursorRect, _cursorColor.isValid() ? _cursorColor : foregroundColor); + painter.drawRect( + cursorRect.adjusted(penWidth / 2, penWidth / 2, -penWidth / 2, -penWidth / 2)); + if (hasFocus()) { + painter.fillRect(cursorRect, + _cursorColor.isValid() ? _cursorColor : foregroundColor); - if ( !_cursorColor.isValid() ) - { + if (!_cursorColor.isValid()) { // invert the colour used to draw the text to ensure that the character at // the cursor position is readable invertCharacterColor = true; } } - } - else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor ) - painter.drawLine(cursorRect.left(), - cursorRect.bottom(), - cursorRect.right(), + } else if (_cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor) + painter.drawLine(cursorRect.left(), cursorRect.bottom(), cursorRect.right(), cursorRect.bottom()); - else if ( _cursorShape == Emulation::KeyboardCursorShape::IBeamCursor ) - painter.drawLine(cursorRect.left(), - cursorRect.top(), - cursorRect.left(), + else if (_cursorShape == Emulation::KeyboardCursorShape::IBeamCursor) + painter.drawLine(cursorRect.left(), cursorRect.top(), cursorRect.left(), cursorRect.bottom()); - } } -void TerminalDisplay::drawCharacters(QPainter& painter, - const QRect& rect, - const std::wstring& text, - const Character* style, - bool invertCharacterColor) +void TerminalDisplay::drawCharacters(QPainter &painter, const QRect &rect, const std::wstring &text, + const Character *style, bool invertCharacterColor) { // don't draw text which is currently blinking - if ( _blinking && (style->rendition & RE_BLINK) ) + if (_blinking && (style->rendition & RE_BLINK)) return; // don't draw concealed characters if (style->rendition & RE_CONCEAL) - return; + return; // setup bold and underline bool useBold = ((style->rendition & RE_BOLD) && _boldIntense) || font().bold(); @@ -815,34 +797,30 @@ void TerminalDisplay::drawCharacters(QPainter& painter, const bool useOverline = style->rendition & RE_OVERLINE || font().overline(); QFont font = painter.font(); - if ( font.bold() != useBold - || font.underline() != useUnderline - || font.italic() != useItalic - || font.strikeOut() != useStrikeOut - || font.overline() != useOverline) { - font.setBold(useBold); - font.setUnderline(useUnderline); - font.setItalic(useItalic); - font.setStrikeOut(useStrikeOut); - font.setOverline(useOverline); - painter.setFont(font); + if (font.bold() != useBold || font.underline() != useUnderline || font.italic() != useItalic + || font.strikeOut() != useStrikeOut || font.overline() != useOverline) { + font.setBold(useBold); + font.setUnderline(useUnderline); + font.setItalic(useItalic); + font.setStrikeOut(useStrikeOut); + font.setOverline(useOverline); + painter.setFont(font); } // setup pen - const CharacterColor& textColor = ( invertCharacterColor ? style->backgroundColor : style->foregroundColor ); + const CharacterColor &textColor = + (invertCharacterColor ? style->backgroundColor : style->foregroundColor); const QColor color = textColor.color(_colorTable); QPen pen = painter.pen(); - if ( pen.color() != color ) - { + if (pen.color() != color) { pen.setColor(color); painter.setPen(color); } // draw text - if ( isLineCharString(text) ) - drawLineCharString(painter,rect.x(),rect.y(),text,style); - else - { + if (isLineCharString(text)) + drawLineCharString(painter, rect.x(), rect.y(), text, style); + else { // Force using LTR as the document layout for the terminal area, because // there is no use cases for RTL emulator and RTL terminal application. // @@ -850,21 +828,21 @@ void TerminalDisplay::drawCharacters(QPainter& painter, painter.setLayoutDirection(Qt::LeftToRight); if (_bidiEnabled) { - painter.drawText(rect.x(), rect.y() + _fontAscent + _lineSpacing, QString::fromStdWString(text)); + painter.drawText(rect.x(), rect.y() + _fontAscent + _lineSpacing, + QString::fromStdWString(text)); } else { - { - QRect drawRect(rect.topLeft(), rect.size()); - drawRect.setHeight(rect.height() + _drawTextAdditionHeight); - painter.drawText(drawRect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + QString::fromStdWString(text)); - } + { + QRect drawRect(rect.topLeft(), rect.size()); + drawRect.setHeight(rect.height() + _drawTextAdditionHeight); + painter.drawText(drawRect, Qt::AlignBottom, + LTR_OVERRIDE_CHAR + QString::fromStdWString(text)); + } } } } -void TerminalDisplay::drawTextFragment(QPainter& painter , - const QRect& rect, - const std::wstring& text, - const Character* style) +void TerminalDisplay::drawTextFragment(QPainter &painter, const QRect &rect, + const std::wstring &text, const Character *style) { painter.save(); @@ -873,24 +851,29 @@ void TerminalDisplay::drawTextFragment(QPainter& painter , const QColor backgroundColor = style->backgroundColor.color(_colorTable); // draw background if different from the display's background color - if ( backgroundColor != palette().window().color() ) - drawBackground(painter,rect,backgroundColor, - false /* do not use transparency */); + if (backgroundColor != palette().window().color()) + drawBackground(painter, rect, backgroundColor, false /* do not use transparency */); // draw cursor shape if the current character is the cursor // this may alter the foreground and background colors bool invertCharacterColor = false; - if ( style->rendition & RE_CURSOR ) - drawCursor(painter,rect,foregroundColor,backgroundColor,invertCharacterColor); + if (style->rendition & RE_CURSOR) + drawCursor(painter, rect, foregroundColor, backgroundColor, invertCharacterColor); // draw text - drawCharacters(painter,rect,text,style,invertCharacterColor); + drawCharacters(painter, rect, text, style, invertCharacterColor); painter.restore(); } -void TerminalDisplay::setRandomSeed(uint randomSeed) { _randomSeed = randomSeed; } -uint TerminalDisplay::randomSeed() const { return _randomSeed; } +void TerminalDisplay::setRandomSeed(uint randomSeed) +{ + _randomSeed = randomSeed; +} +uint TerminalDisplay::randomSeed() const +{ + return _randomSeed; +} #if 0 /*! @@ -920,12 +903,12 @@ void TerminalDisplay::setCursorPos(const int curx, const int cury) // display is much cheaper than re-rendering all the text for the // part of the image which has moved up or down. // Instead only new lines have to be drawn -void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion) +void TerminalDisplay::scrollImage(int lines, const QRect &screenWindowRegion) { // if the flow control warning is enabled this will interfere with the // scrolling optimizations and cause artifacts. the simple solution here // is to just disable the optimization whilst it is visible - if ( _outputSuspendedLabel && _outputSuspendedLabel->isVisible() ) + if (_outputSuspendedLabel && _outputSuspendedLabel->isVisible()) return; // constrain the region to the display @@ -933,14 +916,12 @@ void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion) // internal image - 2, so that the height of 'region' is strictly less // than the height of the internal image. QRect region = screenWindowRegion; - region.setBottom( qMin(region.bottom(),this->_lines-2) ); + region.setBottom(qMin(region.bottom(), this->_lines - 2)); // return if there is nothing to do - if ( lines == 0 - || _image == nullptr - || !region.isValid() - || (region.top() + abs(lines)) >= region.bottom() - || this->_lines <= region.height() ) return; + if (lines == 0 || _image == nullptr || !region.isValid() + || (region.top() + abs(lines)) >= region.bottom() || this->_lines <= region.height()) + return; // hide terminal size label to prevent it being scrolled if (_resizeWidget && _resizeWidget->isVisible()) @@ -956,99 +937,96 @@ void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion) // Set the QT_FLUSH_PAINT environment variable to '1' before starting the // application to monitor repainting. // - int scrollBarWidth = _scrollBar->isHidden() ? 0 : - _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar) ? - 0 : _scrollBar->width(); + int scrollBarWidth = _scrollBar->isHidden() + ? 0 + : _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar) + ? 0 + : _scrollBar->width(); const int SCROLLBAR_CONTENT_GAP = scrollBarWidth == 0 ? 0 : 1; QRect scrollRect; - if ( _scrollbarLocation == QTermWidget::ScrollBarLeft ) - { - scrollRect.setLeft(scrollBarWidth+SCROLLBAR_CONTENT_GAP); + if (_scrollbarLocation == QTermWidget::ScrollBarLeft) { + scrollRect.setLeft(scrollBarWidth + SCROLLBAR_CONTENT_GAP); scrollRect.setRight(width()); - } - else - { + } else { scrollRect.setLeft(0); scrollRect.setRight(width() - scrollBarWidth - SCROLLBAR_CONTENT_GAP); } - void* firstCharPos = &_image[ region.top() * this->_columns ]; - void* lastCharPos = &_image[ (region.top() + abs(lines)) * this->_columns ]; + void *firstCharPos = &_image[region.top() * this->_columns]; + void *lastCharPos = &_image[(region.top() + abs(lines)) * this->_columns]; int top = _topMargin + (region.top() * _fontHeight); int linesToMove = region.height() - abs(lines); - int bytesToMove = linesToMove * - this->_columns * - sizeof(Character); + int bytesToMove = linesToMove * this->_columns * sizeof(Character); - Q_ASSERT( linesToMove > 0 ); - Q_ASSERT( bytesToMove > 0 ); + Q_ASSERT(linesToMove > 0); + Q_ASSERT(bytesToMove > 0); - //scroll internal image - if ( lines > 0 ) - { + // scroll internal image + if (lines > 0) { // check that the memory areas that we are going to move are valid - Q_ASSERT( (char*)lastCharPos + bytesToMove < - (char*)(_image + (this->_lines * this->_columns)) ); + Q_ASSERT((char *)lastCharPos + bytesToMove + < (char *)(_image + (this->_lines * this->_columns))); - Q_ASSERT( (lines*this->_columns) < _imageSize ); + Q_ASSERT((lines * this->_columns) < _imageSize); - //scroll internal image down - memmove( firstCharPos , lastCharPos , bytesToMove ); + // scroll internal image down + memmove(firstCharPos, lastCharPos, bytesToMove); - //set region of display to scroll + // set region of display to scroll scrollRect.setTop(top); - } - else - { + } else { // check that the memory areas that we are going to move are valid - Q_ASSERT( (char*)firstCharPos + bytesToMove < - (char*)(_image + (this->_lines * this->_columns)) ); + Q_ASSERT((char *)firstCharPos + bytesToMove + < (char *)(_image + (this->_lines * this->_columns))); - //scroll internal image up - memmove( lastCharPos , firstCharPos , bytesToMove ); + // scroll internal image up + memmove(lastCharPos, firstCharPos, bytesToMove); - //set region of the display to scroll + // set region of the display to scroll scrollRect.setTop(top + abs(lines) * _fontHeight); } - scrollRect.setHeight(linesToMove * _fontHeight ); + scrollRect.setHeight(linesToMove * _fontHeight); Q_ASSERT(scrollRect.isValid() && !scrollRect.isEmpty()); - //scroll the display vertically to match internal _image - scroll( 0 , _fontHeight * (-lines) , scrollRect ); + // scroll the display vertically to match internal _image + scroll(0, _fontHeight * (-lines), scrollRect); } QRegion TerminalDisplay::hotSpotRegion() const { QRegion region; const auto hotSpots = _filterChain->hotSpots(); - for( Filter::HotSpot* const hotSpot : hotSpots ) - { + for (Filter::HotSpot *const hotSpot : hotSpots) { QRect r; - if (hotSpot->startLine()==hotSpot->endLine()) { + if (hotSpot->startLine() == hotSpot->endLine()) { r.setLeft(hotSpot->startColumn()); r.setTop(hotSpot->startLine()); r.setRight(hotSpot->endColumn()); r.setBottom(hotSpot->endLine()); - region |= imageToWidget(r);; + region |= imageToWidget(r); + ; } else { r.setLeft(hotSpot->startColumn()); r.setTop(hotSpot->startLine()); r.setRight(_columns); r.setBottom(hotSpot->startLine()); - region |= imageToWidget(r);; - for ( int line = hotSpot->startLine()+1 ; line < hotSpot->endLine() ; line++ ) { + region |= imageToWidget(r); + ; + for (int line = hotSpot->startLine() + 1; line < hotSpot->endLine(); line++) { r.setLeft(0); r.setTop(line); r.setRight(_columns); r.setBottom(line); - region |= imageToWidget(r);; + region |= imageToWidget(r); + ; } r.setLeft(0); r.setTop(hotSpot->endLine()); r.setRight(hotSpot->endColumn()); r.setBottom(hotSpot->endLine()); - region |= imageToWidget(r);; + region |= imageToWidget(r); + ; } } return region; @@ -1066,249 +1044,236 @@ void TerminalDisplay::processFilters() // ScreenWindow emits a scrolled() signal - which will happen before // updateImage() is called on the display and therefore _image is // out of date at this point - _filterChain->setImage( _screenWindow->getImage(), - _screenWindow->windowLines(), - _screenWindow->windowColumns(), - _screenWindow->getLineProperties() ); + _filterChain->setImage(_screenWindow->getImage(), _screenWindow->windowLines(), + _screenWindow->windowColumns(), _screenWindow->getLineProperties()); _filterChain->process(); QRegion postUpdateHotSpots = hotSpotRegion(); - update( preUpdateHotSpots | postUpdateHotSpots ); + update(preUpdateHotSpots | postUpdateHotSpots); } void TerminalDisplay::updateImage() { - if ( !_screenWindow ) - return; + if (!_screenWindow) + return; - // optimization - scroll the existing image where possible and - // avoid expensive text drawing for parts of the image that - // can simply be moved up or down - scrollImage( _screenWindow->scrollCount() , - _screenWindow->scrollRegion() ); - _screenWindow->resetScrollCount(); + // optimization - scroll the existing image where possible and + // avoid expensive text drawing for parts of the image that + // can simply be moved up or down + scrollImage(_screenWindow->scrollCount(), _screenWindow->scrollRegion()); + _screenWindow->resetScrollCount(); - if (!_image) { - // Create _image. - // The emitted changedContentSizeSignal also leads to getImage being recreated, so do this first. - updateImageSize(); - } + if (!_image) { + // Create _image. + // The emitted changedContentSizeSignal also leads to getImage being recreated, so do this + // first. + updateImageSize(); + } - Character* const newimg = _screenWindow->getImage(); - int lines = _screenWindow->windowLines(); - int columns = _screenWindow->windowColumns(); + Character *const newimg = _screenWindow->getImage(); + int lines = _screenWindow->windowLines(); + int columns = _screenWindow->windowColumns(); - setScroll( _screenWindow->currentLine() , _screenWindow->lineCount() ); + setScroll(_screenWindow->currentLine(), _screenWindow->lineCount()); - Q_ASSERT( this->_usedLines <= this->_lines ); - Q_ASSERT( this->_usedColumns <= this->_columns ); + Q_ASSERT(this->_usedLines <= this->_lines); + Q_ASSERT(this->_usedColumns <= this->_columns); - int y,x,len; + int y, x, len; - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - _hasBlinker = false; + QPoint tL = contentsRect().topLeft(); + int tLx = tL.x(); + int tLy = tL.y(); + _hasBlinker = false; - CharacterColor cf; // undefined - CharacterColor _clipboard; // undefined - int cr = -1; // undefined + CharacterColor cf; // undefined + CharacterColor _clipboard; // undefined + int cr = -1; // undefined - const int linesToUpdate = qMin(this->_lines, qMax(0,lines )); - const int columnsToUpdate = qMin(this->_columns,qMax(0,columns)); + const int linesToUpdate = qMin(this->_lines, qMax(0, lines)); + const int columnsToUpdate = qMin(this->_columns, qMax(0, columns)); - wchar_t *disstrU = new wchar_t[columnsToUpdate]; - char *dirtyMask = new char[columnsToUpdate+2]; - QRegion dirtyRegion; + wchar_t *disstrU = new wchar_t[columnsToUpdate]; + char *dirtyMask = new char[columnsToUpdate + 2]; + QRegion dirtyRegion; - // debugging variable, this records the number of lines that are found to - // be 'dirty' ( ie. have changed from the old _image to the new _image ) and - // which therefore need to be repainted - int dirtyLineCount = 0; + // debugging variable, this records the number of lines that are found to + // be 'dirty' ( ie. have changed from the old _image to the new _image ) and + // which therefore need to be repainted + int dirtyLineCount = 0; - for (y = 0; y < linesToUpdate; ++y) - { - const Character* currentLine = &_image[y*this->_columns]; - const Character* const newLine = &newimg[y*columns]; + for (y = 0; y < linesToUpdate; ++y) { + const Character *currentLine = &_image[y * this->_columns]; + const Character *const newLine = &newimg[y * columns]; - bool updateLine = false; + bool updateLine = false; - // The dirty mask indicates which characters need repainting. We also - // mark surrounding neighbours dirty, in case the character exceeds - // its cell boundaries - memset(dirtyMask, 0, columnsToUpdate+2); + // The dirty mask indicates which characters need repainting. We also + // mark surrounding neighbours dirty, in case the character exceeds + // its cell boundaries + memset(dirtyMask, 0, columnsToUpdate + 2); - for( x = 0 ; x < columnsToUpdate ; ++x) - { - if ( newLine[x] != currentLine[x] ) - { - dirtyMask[x] = true; + for (x = 0; x < columnsToUpdate; ++x) { + if (newLine[x] != currentLine[x]) { + dirtyMask[x] = true; + } } - } - if (!_resizing) // not while _resizing, we're expecting a paintEvent - for (x = 0; x < columnsToUpdate; ++x) - { - _hasBlinker |= (newLine[x].rendition & RE_BLINK); - - // Start drawing if this character or the next one differs. - // We also take the next one into account to handle the situation - // where characters exceed their cell width. - if (dirtyMask[x]) - { - wchar_t c = newLine[x+0].character; - if ( !c ) - continue; - int p = 0; - disstrU[p++] = c; //fontMap(c); - bool lineDraw = isLineChar(c); - bool doubleWidth = (x+1 == columnsToUpdate) ? false : (newLine[x+1].character == 0); - cr = newLine[x].rendition; - _clipboard = newLine[x].backgroundColor; - if (newLine[x].foregroundColor != cf) cf = newLine[x].foregroundColor; - int lln = columnsToUpdate - x; - for (len = 1; len < lln; ++len) - { - const Character& ch = newLine[x+len]; + if (!_resizing) // not while _resizing, we're expecting a paintEvent + for (x = 0; x < columnsToUpdate; ++x) { + _hasBlinker |= (newLine[x].rendition & RE_BLINK); + + // Start drawing if this character or the next one differs. + // We also take the next one into account to handle the situation + // where characters exceed their cell width. + if (dirtyMask[x]) { + wchar_t c = newLine[x + 0].character; + if (!c) + continue; + int p = 0; + disstrU[p++] = c; // fontMap(c); + bool lineDraw = isLineChar(c); + bool doubleWidth = + (x + 1 == columnsToUpdate) ? false : (newLine[x + 1].character == 0); + cr = newLine[x].rendition; + _clipboard = newLine[x].backgroundColor; + if (newLine[x].foregroundColor != cf) + cf = newLine[x].foregroundColor; + int lln = columnsToUpdate - x; + for (len = 1; len < lln; ++len) { + const Character &ch = newLine[x + len]; + + if (!ch.character) + continue; // Skip trailing part of multi-col chars. + + bool nextIsDoubleWidth = (x + len + 1 == columnsToUpdate) + ? false + : (newLine[x + len + 1].character == 0); + + if (ch.foregroundColor != cf || ch.backgroundColor != _clipboard + || ch.rendition != cr || !dirtyMask[x + len] + || isLineChar(c) != lineDraw || nextIsDoubleWidth != doubleWidth) + break; + + disstrU[p++] = c; // fontMap(c); + } + + std::wstring unistr(disstrU, p); + + bool saveFixedFont = _fixedFont; + if (lineDraw) + _fixedFont = false; + if (doubleWidth) + _fixedFont = false; + + updateLine = true; + + _fixedFont = saveFixedFont; + x += len - 1; + } + } - if (!ch.character) - continue; // Skip trailing part of multi-col chars. + // both the top and bottom halves of double height _lines must always be redrawn + // although both top and bottom halves contain the same characters, only + // the top one is actually + // drawn. + if (_lineProperties.count() > y) + updateLine |= (_lineProperties[y] & LINE_DOUBLEHEIGHT); - bool nextIsDoubleWidth = (x+len+1 == columnsToUpdate) ? false : (newLine[x+len+1].character == 0); + // if the characters on the line are different in the old and the new _image + // then this line must be repainted. + if (updateLine) { + dirtyLineCount++; - if ( ch.foregroundColor != cf || - ch.backgroundColor != _clipboard || - ch.rendition != cr || - !dirtyMask[x+len] || - isLineChar(c) != lineDraw || - nextIsDoubleWidth != doubleWidth ) - break; + // add the area occupied by this line to the region which needs to be + // repainted + QRect dirtyRect = QRect(_leftMargin + tLx, _topMargin + tLy + _fontHeight * y, + _fontWidth * columnsToUpdate, _fontHeight); - disstrU[p++] = c; //fontMap(c); + dirtyRegion |= dirtyRect; } - std::wstring unistr(disstrU, p); - - bool saveFixedFont = _fixedFont; - if (lineDraw) - _fixedFont = false; - if (doubleWidth) - _fixedFont = false; - - updateLine = true; - - _fixedFont = saveFixedFont; - x += len - 1; - } - + // replace the line of characters in the old _image with the + // current line of the new _image + memcpy((void *)currentLine, (const void *)newLine, columnsToUpdate * sizeof(Character)); } - //both the top and bottom halves of double height _lines must always be redrawn - //although both top and bottom halves contain the same characters, only - //the top one is actually - //drawn. - if (_lineProperties.count() > y) - updateLine |= (_lineProperties[y] & LINE_DOUBLEHEIGHT); - - // if the characters on the line are different in the old and the new _image - // then this line must be repainted. - if (updateLine) - { - dirtyLineCount++; - - // add the area occupied by this line to the region which needs to be - // repainted - QRect dirtyRect = QRect( _leftMargin+tLx , - _topMargin+tLy+_fontHeight*y , - _fontWidth * columnsToUpdate , - _fontHeight ); - - dirtyRegion |= dirtyRect; + // if the new _image is smaller than the previous _image, then ensure that the area + // outside the new _image is cleared + if (linesToUpdate < _usedLines) { + dirtyRegion |= + QRect(_leftMargin + tLx, _topMargin + tLy + _fontHeight * linesToUpdate, + _fontWidth * this->_columns, _fontHeight * (_usedLines - linesToUpdate)); } + _usedLines = linesToUpdate; - // replace the line of characters in the old _image with the - // current line of the new _image - memcpy((void*)currentLine,(const void*)newLine,columnsToUpdate*sizeof(Character)); - } - - // if the new _image is smaller than the previous _image, then ensure that the area - // outside the new _image is cleared - if ( linesToUpdate < _usedLines ) - { - dirtyRegion |= QRect( _leftMargin+tLx , - _topMargin+tLy+_fontHeight*linesToUpdate , - _fontWidth * this->_columns , - _fontHeight * (_usedLines-linesToUpdate) ); - } - _usedLines = linesToUpdate; - - if ( columnsToUpdate < _usedColumns ) - { - dirtyRegion |= QRect( _leftMargin+tLx+columnsToUpdate*_fontWidth , - _topMargin+tLy , - _fontWidth * (_usedColumns-columnsToUpdate) , - _fontHeight * this->_lines ); - } - _usedColumns = columnsToUpdate; - - dirtyRegion |= _inputMethodData.previousPreeditRect; + if (columnsToUpdate < _usedColumns) { + dirtyRegion |= + QRect(_leftMargin + tLx + columnsToUpdate * _fontWidth, _topMargin + tLy, + _fontWidth * (_usedColumns - columnsToUpdate), _fontHeight * this->_lines); + } + _usedColumns = columnsToUpdate; - // update the parts of the display which have changed - update(dirtyRegion); + dirtyRegion |= _inputMethodData.previousPreeditRect; - if ( _hasBlinker && !_blinkTimer->isActive()) _blinkTimer->start( TEXT_BLINK_DELAY ); - if (!_hasBlinker && _blinkTimer->isActive()) { _blinkTimer->stop(); _blinking = false; } - delete[] dirtyMask; - delete[] disstrU; + // update the parts of the display which have changed + update(dirtyRegion); + if (_hasBlinker && !_blinkTimer->isActive()) + _blinkTimer->start(TEXT_BLINK_DELAY); + if (!_hasBlinker && _blinkTimer->isActive()) { + _blinkTimer->stop(); + _blinking = false; + } + delete[] dirtyMask; + delete[] disstrU; } void TerminalDisplay::showResizeNotification() { - if (_terminalSizeHint && isVisible()) - { - if (_terminalSizeStartup) { - _terminalSizeStartup=false; - return; - } - if (!_resizeWidget) - { - const QString label = tr("Size: XXX x XXX"); - _resizeWidget = new QLabel(label, this); - _resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().horizontalAdvance(label)); - _resizeWidget->setMinimumHeight(_resizeWidget->sizeHint().height()); - _resizeWidget->setAlignment(Qt::AlignCenter); - - _resizeWidget->setStyleSheet(QLatin1String("background-color:palette(window);border-style:solid;border-width:1px;border-color:palette(dark)")); - - _resizeTimer = new QTimer(this); - _resizeTimer->setSingleShot(true); - connect(_resizeTimer, SIGNAL(timeout()), _resizeWidget, SLOT(hide())); - } - _resizeWidget->setText(tr("Size: %1 x %2").arg(_columns).arg(_lines)); - _resizeWidget->move((width()-_resizeWidget->width())/2, - (height()-_resizeWidget->height())/2+20); - _resizeWidget->show(); - _resizeTimer->start(1000); - } + if (_terminalSizeHint && isVisible()) { + if (_terminalSizeStartup) { + _terminalSizeStartup = false; + return; + } + if (!_resizeWidget) { + const QString label = tr("Size: XXX x XXX"); + _resizeWidget = new QLabel(label, this); + _resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().horizontalAdvance(label)); + _resizeWidget->setMinimumHeight(_resizeWidget->sizeHint().height()); + _resizeWidget->setAlignment(Qt::AlignCenter); + + _resizeWidget->setStyleSheet( + QLatin1String("background-color:palette(window);border-style:solid;border-" + "width:1px;border-color:palette(dark)")); + + _resizeTimer = new QTimer(this); + _resizeTimer->setSingleShot(true); + connect(_resizeTimer, SIGNAL(timeout()), _resizeWidget, SLOT(hide())); + } + _resizeWidget->setText(tr("Size: %1 x %2").arg(_columns).arg(_lines)); + _resizeWidget->move((width() - _resizeWidget->width()) / 2, + (height() - _resizeWidget->height()) / 2 + 20); + _resizeWidget->show(); + _resizeTimer->start(1000); + } } void TerminalDisplay::setBlinkingCursor(bool blink) { - _hasBlinkingCursor=blink; + _hasBlinkingCursor = blink; - if (blink && !_blinkCursorTimer->isActive()) - _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2); + if (blink && !_blinkCursorTimer->isActive()) + _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2); - if (!blink && _blinkCursorTimer->isActive()) - { - _blinkCursorTimer->stop(); - if (_cursorBlinking) - blinkCursorEvent(); - else - _cursorBlinking = false; - } + if (!blink && _blinkCursorTimer->isActive()) { + _blinkCursorTimer->stop(); + if (_cursorBlinking) + blinkCursorEvent(); + else + _cursorBlinking = false; + } } void TerminalDisplay::setBlinkingTextEnabled(bool blink) @@ -1318,14 +1283,13 @@ void TerminalDisplay::setBlinkingTextEnabled(bool blink) if (blink && !_blinkTimer->isActive()) _blinkTimer->start(TEXT_BLINK_DELAY); - if (!blink && _blinkTimer->isActive()) - { + if (!blink && _blinkTimer->isActive()) { _blinkTimer->stop(); _blinking = false; } } -void TerminalDisplay::focusOutEvent(QFocusEvent*) +void TerminalDisplay::focusOutEvent(QFocusEvent *) { emit termLostFocus(); // trigger a repaint of the cursor so that it is both visible (in case @@ -1340,11 +1304,10 @@ void TerminalDisplay::focusOutEvent(QFocusEvent*) _blinkTimer->stop(); } -void TerminalDisplay::focusInEvent(QFocusEvent*) +void TerminalDisplay::focusInEvent(QFocusEvent *) { emit termGetFocus(); - if (_hasBlinkingCursor) - { + if (_hasBlinkingCursor) { _blinkCursorTimer->start(); } updateCursor(); @@ -1353,106 +1316,84 @@ void TerminalDisplay::focusInEvent(QFocusEvent*) _blinkTimer->start(); } -void TerminalDisplay::paintEvent( QPaintEvent* pe ) +void TerminalDisplay::paintEvent(QPaintEvent *pe) { - QPainter paint(this); - QRect cr = contentsRect(); + QPainter paint(this); + QRect cr = contentsRect(); - if ( !_backgroundImage.isNull() ) - { - QColor background = _colorTable[DEFAULT_BACK_COLOR].color; - if (_opacity < static_cast(1)) - { - background.setAlphaF(_opacity); - paint.save(); - paint.setCompositionMode(QPainter::CompositionMode_Source); - paint.fillRect(cr, background); - paint.restore(); - } - else - { - paint.fillRect(cr, background); - } - - paint.save(); - paint.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - - if (_backgroundMode == Stretch) - { // scale the image without keeping its proportions to fill the screen - paint.drawPixmap(cr, _backgroundImage, _backgroundImage.rect()); - } - else if (_backgroundMode == Zoom) - { // zoom in/out the image to fit it - QRect r = _backgroundImage.rect(); - qreal wRatio = static_cast(cr.width()) / r.width(); - qreal hRatio = static_cast(cr.height()) / r.height(); - if (wRatio > hRatio) - { - r.setWidth(qRound(r.width() * hRatio)); - r.setHeight(cr.height()); - } - else - { - r.setHeight(qRound(r.height() * wRatio)); - r.setWidth(cr.width()); + if (!_backgroundImage.isNull()) { + QColor background = _colorTable[DEFAULT_BACK_COLOR].color; + if (_opacity < static_cast(1)) { + background.setAlphaF(_opacity); + paint.save(); + paint.setCompositionMode(QPainter::CompositionMode_Source); + paint.fillRect(cr, background); + paint.restore(); + } else { + paint.fillRect(cr, background); } - r.moveCenter(cr.center()); - paint.drawPixmap(r, _backgroundImage, _backgroundImage.rect()); - } - else if (_backgroundMode == Fit) - { // if the image is bigger than the terminal, zoom it out to fit it - QRect r = _backgroundImage.rect(); - qreal wRatio = static_cast(cr.width()) / r.width(); - qreal hRatio = static_cast(cr.height()) / r.height(); - if (r.width() > cr.width()) - { - if (wRatio <= hRatio) - { + + paint.save(); + paint.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + + if (_backgroundMode + == Stretch) { // scale the image without keeping its proportions to fill the screen + paint.drawPixmap(cr, _backgroundImage, _backgroundImage.rect()); + } else if (_backgroundMode == Zoom) { // zoom in/out the image to fit it + QRect r = _backgroundImage.rect(); + qreal wRatio = static_cast(cr.width()) / r.width(); + qreal hRatio = static_cast(cr.height()) / r.height(); + if (wRatio > hRatio) { + r.setWidth(qRound(r.width() * hRatio)); + r.setHeight(cr.height()); + } else { r.setHeight(qRound(r.height() * wRatio)); r.setWidth(cr.width()); } - else - { + r.moveCenter(cr.center()); + paint.drawPixmap(r, _backgroundImage, _backgroundImage.rect()); + } else if (_backgroundMode + == Fit) { // if the image is bigger than the terminal, zoom it out to fit it + QRect r = _backgroundImage.rect(); + qreal wRatio = static_cast(cr.width()) / r.width(); + qreal hRatio = static_cast(cr.height()) / r.height(); + if (r.width() > cr.width()) { + if (wRatio <= hRatio) { + r.setHeight(qRound(r.height() * wRatio)); + r.setWidth(cr.width()); + } else { + r.setWidth(qRound(r.width() * hRatio)); + r.setHeight(cr.height()); + } + } else if (r.height() > cr.height()) { r.setWidth(qRound(r.width() * hRatio)); r.setHeight(cr.height()); } - } - else if (r.height() > cr.height()) + r.moveCenter(cr.center()); + paint.drawPixmap(r, _backgroundImage, _backgroundImage.rect()); + } else if (_backgroundMode == Center) { // center the image without scaling/zooming + QRect r = _backgroundImage.rect(); + r.moveCenter(cr.center()); + paint.drawPixmap(r.topLeft(), _backgroundImage); + } else // if (_backgroundMode == None) { - r.setWidth(qRound(r.width() * hRatio)); - r.setHeight(cr.height()); + paint.drawPixmap(0, 0, _backgroundImage); } - r.moveCenter(cr.center()); - paint.drawPixmap(r, _backgroundImage, _backgroundImage.rect()); - } - else if (_backgroundMode == Center) - { // center the image without scaling/zooming - QRect r = _backgroundImage.rect(); - r.moveCenter(cr.center()); - paint.drawPixmap(r.topLeft(), _backgroundImage); - } - else //if (_backgroundMode == None) - { - paint.drawPixmap(0, 0, _backgroundImage); - } - paint.restore(); - } + paint.restore(); + } - if(_drawTextTestFlag) - { - calDrawTextAdditionHeight(paint); - } + if (_drawTextTestFlag) { + calDrawTextAdditionHeight(paint); + } - const QRegion regToDraw = pe->region() & cr; - for (auto rect = regToDraw.begin(); rect != regToDraw.end(); rect++) - { - drawBackground(paint,*rect,palette().window().color(), - true /* use opacity setting */); - drawContents(paint, *rect); - } - drawInputMethodPreeditString(paint,preeditRect()); - paintFilters(paint); + const QRegion regToDraw = pe->region() & cr; + for (auto rect = regToDraw.begin(); rect != regToDraw.end(); rect++) { + drawBackground(paint, *rect, palette().window().color(), true /* use opacity setting */); + drawContents(paint, *rect); + } + drawInputMethodPreeditString(paint, preeditRect()); + paintFilters(paint); } QPoint TerminalDisplay::cursorPosition() const @@ -1460,25 +1401,24 @@ QPoint TerminalDisplay::cursorPosition() const if (_screenWindow) return _screenWindow->cursorPosition(); else - return {0,0}; + return { 0, 0 }; } QRect TerminalDisplay::preeditRect() const { const int preeditLength = string_width(_inputMethodData.preeditString); - if ( preeditLength == 0 ) + if (preeditLength == 0) return {}; - return QRect(_leftMargin + _fontWidth*cursorPosition().x(), - _topMargin + _fontHeight*cursorPosition().y(), - _fontWidth*preeditLength, + return QRect(_leftMargin + _fontWidth * cursorPosition().x(), + _topMargin + _fontHeight * cursorPosition().y(), _fontWidth * preeditLength, _fontHeight); } -void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRect& rect) +void TerminalDisplay::drawInputMethodPreeditString(QPainter &painter, const QRect &rect) { - if ( _inputMethodData.preeditString.empty() ) + if (_inputMethodData.preeditString.empty()) return; const QPoint cursorPos = cursorPosition(); @@ -1486,21 +1426,21 @@ void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRe bool invertColors = false; const QColor background = _colorTable[DEFAULT_BACK_COLOR].color; const QColor foreground = _colorTable[DEFAULT_FORE_COLOR].color; - const Character* style = &_image[loc(cursorPos.x(),cursorPos.y())]; + const Character *style = &_image[loc(cursorPos.x(), cursorPos.y())]; - drawBackground(painter,rect,background,true); - drawCursor(painter,rect,foreground,background,invertColors); - drawCharacters(painter,rect,_inputMethodData.preeditString,style,invertColors); + drawBackground(painter, rect, background, true); + drawCursor(painter, rect, foreground, background, invertColors); + drawCharacters(painter, rect, _inputMethodData.preeditString, style, invertColors); _inputMethodData.previousPreeditRect = rect; } -FilterChain* TerminalDisplay::filterChain() const +FilterChain *TerminalDisplay::filterChain() const { return _filterChain; } -void TerminalDisplay::paintFilters(QPainter& painter) +void TerminalDisplay::paintFilters(QPainter &painter) { // get color of character under mouse and use it to draw // lines for filters @@ -1508,72 +1448,72 @@ void TerminalDisplay::paintFilters(QPainter& painter) int cursorLine; int cursorColumn; int leftMargin = _leftBaseMargin - + ((_scrollbarLocation == QTermWidget::ScrollBarLeft - && !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) - ? _scrollBar->width() : 0); + + ((_scrollbarLocation == QTermWidget::ScrollBarLeft + && !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, + _scrollBar)) + ? _scrollBar->width() + : 0); - getCharacterPosition( cursorPos , cursorLine , cursorColumn ); - Character cursorCharacter = _image[loc(cursorColumn,cursorLine)]; + getCharacterPosition(cursorPos, cursorLine, cursorColumn); + Character cursorCharacter = _image[loc(cursorColumn, cursorLine)]; - painter.setPen( QPen(cursorCharacter.foregroundColor.color(colorTable())) ); + painter.setPen(QPen(cursorCharacter.foregroundColor.color(colorTable()))); // iterate over hotspots identified by the display's currently active filters // and draw appropriate visuals to indicate the presence of the hotspot - QList spots = _filterChain->hotSpots(); - QListIterator iter(spots); - while (iter.hasNext()) - { - Filter::HotSpot* spot = iter.next(); + QList spots = _filterChain->hotSpots(); + QListIterator iter(spots); + while (iter.hasNext()) { + Filter::HotSpot *spot = iter.next(); QRegion region; - if ( spot->type() == Filter::HotSpot::Link ) { + if (spot->type() == Filter::HotSpot::Link) { QRect r; - if (spot->startLine()==spot->endLine()) { - r.setCoords( spot->startColumn()*_fontWidth + 1 + leftMargin, - spot->startLine()*_fontHeight + 1 + _topBaseMargin, - spot->endColumn()*_fontWidth - 1 + leftMargin, - (spot->endLine()+1)*_fontHeight - 1 + _topBaseMargin ); + if (spot->startLine() == spot->endLine()) { + r.setCoords(spot->startColumn() * _fontWidth + 1 + leftMargin, + spot->startLine() * _fontHeight + 1 + _topBaseMargin, + spot->endColumn() * _fontWidth - 1 + leftMargin, + (spot->endLine() + 1) * _fontHeight - 1 + _topBaseMargin); region |= r; } else { - r.setCoords( spot->startColumn()*_fontWidth + 1 + leftMargin, - spot->startLine()*_fontHeight + 1 + _topBaseMargin, - _columns*_fontWidth - 1 + leftMargin, - (spot->startLine()+1)*_fontHeight - 1 + _topBaseMargin ); + r.setCoords(spot->startColumn() * _fontWidth + 1 + leftMargin, + spot->startLine() * _fontHeight + 1 + _topBaseMargin, + _columns * _fontWidth - 1 + leftMargin, + (spot->startLine() + 1) * _fontHeight - 1 + _topBaseMargin); region |= r; - for ( int line = spot->startLine()+1 ; line < spot->endLine() ; line++ ) { - r.setCoords( 0*_fontWidth + 1 + leftMargin, - line*_fontHeight + 1 + _topBaseMargin, - _columns*_fontWidth - 1 + leftMargin, - (line+1)*_fontHeight - 1 + _topBaseMargin ); + for (int line = spot->startLine() + 1; line < spot->endLine(); line++) { + r.setCoords(0 * _fontWidth + 1 + leftMargin, + line * _fontHeight + 1 + _topBaseMargin, + _columns * _fontWidth - 1 + leftMargin, + (line + 1) * _fontHeight - 1 + _topBaseMargin); region |= r; } - r.setCoords( 0*_fontWidth + 1 + leftMargin, - spot->endLine()*_fontHeight + 1 + _topBaseMargin, - spot->endColumn()*_fontWidth - 1 + leftMargin, - (spot->endLine()+1)*_fontHeight - 1 + _topBaseMargin ); + r.setCoords(0 * _fontWidth + 1 + leftMargin, + spot->endLine() * _fontHeight + 1 + _topBaseMargin, + spot->endColumn() * _fontWidth - 1 + leftMargin, + (spot->endLine() + 1) * _fontHeight - 1 + _topBaseMargin); region |= r; } } - for ( int line = spot->startLine() ; line <= spot->endLine() ; line++ ) - { + for (int line = spot->startLine(); line <= spot->endLine(); line++) { int startColumn = 0; - int endColumn = _columns-1; // TODO use number of _columns which are actually - // occupied on this line rather than the width of the - // display in _columns + int endColumn = _columns - 1; // TODO use number of _columns which are actually + // occupied on this line rather than the width of the + // display in _columns // ignore whitespace at the end of the lines - while ( QChar(_image[loc(endColumn,line)].character).isSpace() && endColumn > 0 ) + while (QChar(_image[loc(endColumn, line)].character).isSpace() && endColumn > 0) endColumn--; // increment here because the column which we want to set 'endColumn' to // is the first whitespace character at the end of the line endColumn++; - if ( line == spot->startLine() ) + if (line == spot->startLine()) startColumn = spot->startColumn(); - if ( line == spot->endLine() ) + if (line == spot->endLine()) endColumn = spot->endColumn(); // subtract one pixel from @@ -1586,31 +1526,28 @@ void TerminalDisplay::paintFilters(QPainter& painter) // because the check below for the position of the cursor // finds it on the border of the target area QRect r; - r.setCoords( startColumn*_fontWidth + 1 + leftMargin, - line*_fontHeight + 1 + _topBaseMargin, - endColumn*_fontWidth - 1 + leftMargin, - (line+1)*_fontHeight - 1 + _topBaseMargin ); + r.setCoords(startColumn * _fontWidth + 1 + leftMargin, + line * _fontHeight + 1 + _topBaseMargin, + endColumn * _fontWidth - 1 + leftMargin, + (line + 1) * _fontHeight - 1 + _topBaseMargin); // Underline link hotspots - if ( spot->type() == Filter::HotSpot::Link ) - { + if (spot->type() == Filter::HotSpot::Link) { QFontMetrics metrics(font()); - // find the baseline (which is the invisible line that the characters in the font sit on, - // with some having tails dangling below) + // find the baseline (which is the invisible line that the characters in the font + // sit on, with some having tails dangling below) int baseline = r.bottom() - metrics.descent(); // find the position of the underline below that int underlinePos = baseline + metrics.underlinePos(); - if ( region.contains( mapFromGlobal(QCursor::pos()) ) ){ - painter.drawLine( r.left() , underlinePos , - r.right() , underlinePos ); + if (region.contains(mapFromGlobal(QCursor::pos()))) { + painter.drawLine(r.left(), underlinePos, r.right(), underlinePos); } } // Marker hotspots simply have a transparent rectanglular shape // drawn on top of them - else if ( spot->type() == Filter::HotSpot::Marker ) - { - //TODO - Do not use a hardcoded colour for this - painter.fillRect(r,QBrush(QColor(255,0,0,120))); + else if (spot->type() == Filter::HotSpot::Marker) { + // TODO - Do not use a hardcoded colour for this + painter.fillRect(r, QBrush(QColor(255, 0, 0, 120))); } } } @@ -1618,191 +1555,179 @@ void TerminalDisplay::paintFilters(QPainter& painter) int TerminalDisplay::textWidth(const int startColumn, const int length, const int line) const { - QFontMetrics fm(font()); - int result = 0; - for (int column = 0; column < length; column++) { - result += fm.horizontalAdvance(_image[loc(startColumn + column, line)].character); - } - return result; + QFontMetrics fm(font()); + int result = 0; + for (int column = 0; column < length; column++) { + result += fm.horizontalAdvance(_image[loc(startColumn + column, line)].character); + } + return result; } -QRect TerminalDisplay::calculateTextArea(int topLeftX, int topLeftY, int startColumn, int line, int length) { - int left = _fixedFont ? _fontWidth * startColumn : textWidth(0, startColumn, line); - int top = _fontHeight * line; - int width = _fixedFont ? _fontWidth * length : textWidth(startColumn, length, line); - return {_leftMargin + topLeftX + left, - _topMargin + topLeftY + top, - width, - _fontHeight}; +QRect TerminalDisplay::calculateTextArea(int topLeftX, int topLeftY, int startColumn, int line, + int length) +{ + int left = _fixedFont ? _fontWidth * startColumn : textWidth(0, startColumn, line); + int top = _fontHeight * line; + int width = _fixedFont ? _fontWidth * length : textWidth(startColumn, length, line); + return { _leftMargin + topLeftX + left, _topMargin + topLeftY + top, width, _fontHeight }; } void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect) { - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - - int lux = qMin(_usedColumns-1, qMax(0,(rect.left() - tLx - _leftMargin ) / _fontWidth)); - int luy = qMin(_usedLines-1, qMax(0,(rect.top() - tLy - _topMargin ) / _fontHeight)); - int rlx = qMin(_usedColumns-1, qMax(0,(rect.right() - tLx - _leftMargin ) / _fontWidth)); - int rly = qMin(_usedLines-1, qMax(0,(rect.bottom() - tLy - _topMargin ) / _fontHeight)); - - const int bufferSize = _usedColumns; - std::wstring unistr; - unistr.reserve(bufferSize); - for (int y = luy; y <= rly; y++) - { - quint32 c = _image[loc(lux,y)].character; - int x = lux; - if(!c && x) - x--; // Search for start of multi-column character - for (; x <= rlx; x++) - { - int len = 1; - int p = 0; - - // reset our buffer to the maximal size - unistr.resize(bufferSize); - - // is this a single character or a sequence of characters ? - if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR ) - { - // sequence of characters - ushort extendedCharLength = 0; - ushort* chars = ExtendedCharTable::instance - .lookupExtendedChar(_image[loc(x,y)].charSequence,extendedCharLength); - for ( int index = 0 ; index < extendedCharLength ; index++ ) - { - Q_ASSERT( p < bufferSize ); - unistr[p++] = chars[index]; - } - } - else - { - // single character - c = _image[loc(x,y)].character; - if (c) - { - Q_ASSERT( p < bufferSize ); - unistr[p++] = c; //fontMap(c); - } - } - - bool lineDraw = isLineChar(c); - bool doubleWidth = (_image[ qMin(loc(x,y)+1,_imageSize) ].character == 0); - CharacterColor currentForeground = _image[loc(x,y)].foregroundColor; - CharacterColor currentBackground = _image[loc(x,y)].backgroundColor; - quint8 currentRendition = _image[loc(x,y)].rendition; - - while (x+len <= rlx && - _image[loc(x+len,y)].foregroundColor == currentForeground && - _image[loc(x+len,y)].backgroundColor == currentBackground && - _image[loc(x+len,y)].rendition == currentRendition && - (_image[ qMin(loc(x+len,y)+1,_imageSize) ].character == 0) == doubleWidth && - isLineChar( c = _image[loc(x+len,y)].character) == lineDraw) // Assignment! - { - if (c) - unistr[p++] = c; //fontMap(c); - if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if condition - len++; // Skip trailing part of multi-column character - len++; - } - if ((x+len < _usedColumns) && (!_image[loc(x+len,y)].character)) - len++; // Adjust for trailing part of multi-column character - - bool save__fixedFont = _fixedFont; - if (lineDraw) - _fixedFont = false; - unistr.resize(p); - - // Create a text scaling matrix for double width and double height lines. - QTransform textScale; - - if (y < _lineProperties.size()) - { - if (_lineProperties[y] & LINE_DOUBLEWIDTH) - textScale.scale(2,1); - - if (_lineProperties[y] & LINE_DOUBLEHEIGHT) - textScale.scale(1,2); - } - - //Apply text scaling matrix. - paint.setWorldTransform(textScale, true); + QPoint tL = contentsRect().topLeft(); + int tLx = tL.x(); + int tLy = tL.y(); + + int lux = qMin(_usedColumns - 1, qMax(0, (rect.left() - tLx - _leftMargin) / _fontWidth)); + int luy = qMin(_usedLines - 1, qMax(0, (rect.top() - tLy - _topMargin) / _fontHeight)); + int rlx = qMin(_usedColumns - 1, qMax(0, (rect.right() - tLx - _leftMargin) / _fontWidth)); + int rly = qMin(_usedLines - 1, qMax(0, (rect.bottom() - tLy - _topMargin) / _fontHeight)); + + const int bufferSize = _usedColumns; + std::wstring unistr; + unistr.reserve(bufferSize); + for (int y = luy; y <= rly; y++) { + quint32 c = _image[loc(lux, y)].character; + int x = lux; + if (!c && x) + x--; // Search for start of multi-column character + for (; x <= rlx; x++) { + int len = 1; + int p = 0; + + // reset our buffer to the maximal size + unistr.resize(bufferSize); + + // is this a single character or a sequence of characters ? + if (_image[loc(x, y)].rendition & RE_EXTENDED_CHAR) { + // sequence of characters + ushort extendedCharLength = 0; + ushort *chars = ExtendedCharTable::instance.lookupExtendedChar( + _image[loc(x, y)].charSequence, extendedCharLength); + for (int index = 0; index < extendedCharLength; index++) { + Q_ASSERT(p < bufferSize); + unistr[p++] = chars[index]; + } + } else { + // single character + c = _image[loc(x, y)].character; + if (c) { + Q_ASSERT(p < bufferSize); + unistr[p++] = c; // fontMap(c); + } + } - //calculate the area in which the text will be drawn - QRect textArea = calculateTextArea(tLx, tLy, x, y, len); + bool lineDraw = isLineChar(c); + bool doubleWidth = (_image[qMin(loc(x, y) + 1, _imageSize)].character == 0); + CharacterColor currentForeground = _image[loc(x, y)].foregroundColor; + CharacterColor currentBackground = _image[loc(x, y)].backgroundColor; + quint8 currentRendition = _image[loc(x, y)].rendition; + + while (x + len <= rlx && _image[loc(x + len, y)].foregroundColor == currentForeground + && _image[loc(x + len, y)].backgroundColor == currentBackground + && _image[loc(x + len, y)].rendition == currentRendition + && (_image[qMin(loc(x + len, y) + 1, _imageSize)].character == 0) == doubleWidth + && isLineChar(c = _image[loc(x + len, y)].character) == lineDraw) // Assignment! + { + if (c) + unistr[p++] = c; // fontMap(c); + if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if + // condition + len++; // Skip trailing part of multi-column character + len++; + } + if ((x + len < _usedColumns) && (!_image[loc(x + len, y)].character)) + len++; // Adjust for trailing part of multi-column character - //move the calculated area to take account of scaling applied to the painter. - //the position of the area from the origin (0,0) is scaled - //by the opposite of whatever - //transformation has been applied to the painter. this ensures that - //painting does actually start from textArea.topLeft() - //(instead of textArea.topLeft() * painter-scale) - textArea.moveTopLeft( textScale.inverted().map(textArea.topLeft()) ); + bool save__fixedFont = _fixedFont; + if (lineDraw) + _fixedFont = false; + unistr.resize(p); - //paint text fragment - drawTextFragment( paint, - textArea, - unistr, - &_image[loc(x,y)] ); //, - //0, - //!_isPrinting ); + // Create a text scaling matrix for double width and double height lines. + QTransform textScale; - _fixedFont = save__fixedFont; + if (y < _lineProperties.size()) { + if (_lineProperties[y] & LINE_DOUBLEWIDTH) + textScale.scale(2, 1); - //reset back to single-width, single-height _lines - paint.setWorldTransform(textScale.inverted(), true); + if (_lineProperties[y] & LINE_DOUBLEHEIGHT) + textScale.scale(1, 2); + } - if (y < _lineProperties.size()-1) - { - //double-height _lines are represented by two adjacent _lines - //containing the same characters - //both _lines will have the LINE_DOUBLEHEIGHT attribute. - //If the current line has the LINE_DOUBLEHEIGHT attribute, - //we can therefore skip the next line - if (_lineProperties[y] & LINE_DOUBLEHEIGHT) - y++; - } + // Apply text scaling matrix. + paint.setWorldTransform(textScale, true); + + // calculate the area in which the text will be drawn + QRect textArea = calculateTextArea(tLx, tLy, x, y, len); + + // move the calculated area to take account of scaling applied to the painter. + // the position of the area from the origin (0,0) is scaled + // by the opposite of whatever + // transformation has been applied to the painter. this ensures that + // painting does actually start from textArea.topLeft() + //(instead of textArea.topLeft() * painter-scale) + textArea.moveTopLeft(textScale.inverted().map(textArea.topLeft())); + + // paint text fragment + drawTextFragment(paint, textArea, unistr, &_image[loc(x, y)]); //, + // 0, + //!_isPrinting ); + + _fixedFont = save__fixedFont; + + // reset back to single-width, single-height _lines + paint.setWorldTransform(textScale.inverted(), true); + + if (y < _lineProperties.size() - 1) { + // double-height _lines are represented by two adjacent _lines + // containing the same characters + // both _lines will have the LINE_DOUBLEHEIGHT attribute. + // If the current line has the LINE_DOUBLEHEIGHT attribute, + // we can therefore skip the next line + if (_lineProperties[y] & LINE_DOUBLEHEIGHT) + y++; + } - x += len - 1; + x += len - 1; + } } - } } void TerminalDisplay::blinkEvent() { - if (!_allowBlinkingText) return; + if (!_allowBlinkingText) + return; - _blinking = !_blinking; + _blinking = !_blinking; - //TODO: Optimize to only repaint the areas of the widget - // where there is blinking text - // rather than repainting the whole widget. - update(); + // TODO: Optimize to only repaint the areas of the widget + // where there is blinking text + // rather than repainting the whole widget. + update(); } -QRect TerminalDisplay::imageToWidget(const QRect& imageArea) const +QRect TerminalDisplay::imageToWidget(const QRect &imageArea) const { QRect result; - result.setLeft( _leftMargin + _fontWidth * imageArea.left() ); - result.setTop( _topMargin + _fontHeight * imageArea.top() ); - result.setWidth( _fontWidth * imageArea.width() ); - result.setHeight( _fontHeight * imageArea.height() ); + result.setLeft(_leftMargin + _fontWidth * imageArea.left()); + result.setTop(_topMargin + _fontHeight * imageArea.top()); + result.setWidth(_fontWidth * imageArea.width()); + result.setHeight(_fontHeight * imageArea.height()); return result; } void TerminalDisplay::updateCursor() { - QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) ); - update(cursorRect); + QRect cursorRect = imageToWidget(QRect(cursorPosition(), QSize(1, 1))); + update(cursorRect); } void TerminalDisplay::blinkCursorEvent() { - _cursorBlinking = !_cursorBlinking; - updateCursor(); + _cursorBlinking = !_cursorBlinking; + updateCursor(); } /* ------------------------------------------------------------------------- */ @@ -1811,74 +1736,70 @@ void TerminalDisplay::blinkCursorEvent() /* */ /* ------------------------------------------------------------------------- */ -void TerminalDisplay::resizeEvent(QResizeEvent*) +void TerminalDisplay::resizeEvent(QResizeEvent *) { - updateImageSize(); - processFilters(); + updateImageSize(); + processFilters(); } void TerminalDisplay::propagateSize() { - if (_isFixedSize) - { - setSize(_columns, _lines); - QWidget::setFixedSize(sizeHint()); - parentWidget()->adjustSize(); - parentWidget()->setFixedSize(parentWidget()->sizeHint()); - return; - } - if (_image) - updateImageSize(); + if (_isFixedSize) { + setSize(_columns, _lines); + QWidget::setFixedSize(sizeHint()); + parentWidget()->adjustSize(); + parentWidget()->setFixedSize(parentWidget()->sizeHint()); + return; + } + if (_image) + updateImageSize(); } void TerminalDisplay::updateImageSize() { - Character* oldimg = _image; - int oldlin = _lines; - int oldcol = _columns; + Character *oldimg = _image; + int oldlin = _lines; + int oldcol = _columns; - makeImage(); + makeImage(); - // copy the old image to reduce flicker - int lines = qMin(oldlin,_lines); - int columns = qMin(oldcol,_columns); + // copy the old image to reduce flicker + int lines = qMin(oldlin, _lines); + int columns = qMin(oldcol, _columns); - if (oldimg) - { - for (int line = 0; line < lines; line++) - { - memcpy((void*)&_image[_columns*line], - (void*)&oldimg[oldcol*line],columns*sizeof(Character)); + if (oldimg) { + for (int line = 0; line < lines; line++) { + memcpy((void *)&_image[_columns * line], (void *)&oldimg[oldcol * line], + columns * sizeof(Character)); + } + delete[] oldimg; } - delete[] oldimg; - } - if (_screenWindow) - _screenWindow->setWindowLines(_lines); + if (_screenWindow) + _screenWindow->setWindowLines(_lines); - _resizing = (oldlin!=_lines) || (oldcol!=_columns); + _resizing = (oldlin != _lines) || (oldcol != _columns); - if ( _resizing ) - { - showResizeNotification(); - emit changedContentSizeSignal(_contentHeight, _contentWidth); // expose resizeEvent - } + if (_resizing) { + showResizeNotification(); + emit changedContentSizeSignal(_contentHeight, _contentWidth); // expose resizeEvent + } - _resizing = false; + _resizing = false; } -//showEvent and hideEvent are reimplemented here so that it appears to other classes that the -//display has been resized when the display is hidden or shown. +// showEvent and hideEvent are reimplemented here so that it appears to other classes that the +// display has been resized when the display is hidden or shown. // -//TODO: Perhaps it would be better to have separate signals for show and hide instead of using -//the same signal as the one for a content size change -void TerminalDisplay::showEvent(QShowEvent*) +// TODO: Perhaps it would be better to have separate signals for show and hide instead of using +// the same signal as the one for a content size change +void TerminalDisplay::showEvent(QShowEvent *) { - emit changedContentSizeSignal(_contentHeight,_contentWidth); + emit changedContentSizeSignal(_contentHeight, _contentWidth); } -void TerminalDisplay::hideEvent(QHideEvent*) +void TerminalDisplay::hideEvent(QHideEvent *) { - emit changedContentSizeSignal(_contentHeight,_contentWidth); + emit changedContentSizeSignal(_contentHeight, _contentWidth); } /* ------------------------------------------------------------------------- */ @@ -1889,549 +1810,531 @@ void TerminalDisplay::hideEvent(QHideEvent*) void TerminalDisplay::scrollBarPositionChanged(int) { - if ( !_screenWindow ) - return; + if (!_screenWindow) + return; - _screenWindow->scrollTo( _scrollBar->value() ); + _screenWindow->scrollTo(_scrollBar->value()); - // if the thumb has been moved to the bottom of the _scrollBar then set - // the display to automatically track new output, - // that is, scroll down automatically - // to how new _lines as they are added - const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum()); - _screenWindow->setTrackOutput( atEndOfOutput ); + // if the thumb has been moved to the bottom of the _scrollBar then set + // the display to automatically track new output, + // that is, scroll down automatically + // to how new _lines as they are added + const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum()); + _screenWindow->setTrackOutput(atEndOfOutput); - updateImage(); + updateImage(); } void TerminalDisplay::setScroll(int cursor, int slines) { - // update _scrollBar if the range or value has changed, - // otherwise return - // - // setting the range or value of a _scrollBar will always trigger - // a repaint, so it should be avoided if it is not necessary - if ( _scrollBar->minimum() == 0 && - _scrollBar->maximum() == (slines - _lines) && - _scrollBar->value() == cursor ) - { + // update _scrollBar if the range or value has changed, + // otherwise return + // + // setting the range or value of a _scrollBar will always trigger + // a repaint, so it should be avoided if it is not necessary + if (_scrollBar->minimum() == 0 && _scrollBar->maximum() == (slines - _lines) + && _scrollBar->value() == cursor) { return; - } + } - disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); - _scrollBar->setRange(0,slines - _lines); - _scrollBar->setSingleStep(1); - _scrollBar->setPageStep(_lines); - _scrollBar->setValue(cursor); - connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + _scrollBar->setRange(0, slines - _lines); + _scrollBar->setSingleStep(1); + _scrollBar->setPageStep(_lines); + _scrollBar->setValue(cursor); + connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); } void TerminalDisplay::scrollToEnd() { - disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); - _scrollBar->setValue( _scrollBar->maximum() ); - connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + _scrollBar->setValue(_scrollBar->maximum()); + connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); - _screenWindow->scrollTo( _scrollBar->value() + 1 ); - _screenWindow->setTrackOutput( _screenWindow->atEndOfOutput() ); + _screenWindow->scrollTo(_scrollBar->value() + 1); + _screenWindow->setTrackOutput(_screenWindow->atEndOfOutput()); } void TerminalDisplay::setScrollBarPosition(QTermWidget::ScrollBarPosition position) { - if (_scrollbarLocation == position) - return; + if (_scrollbarLocation == position) + return; - if ( position == QTermWidget::NoScrollBar ) - _scrollBar->hide(); - else - _scrollBar->show(); + if (position == QTermWidget::NoScrollBar) + _scrollBar->hide(); + else + _scrollBar->show(); - _topMargin = _leftMargin = 1; - _scrollbarLocation = position; + _topMargin = _leftMargin = 1; + _scrollbarLocation = position; - propagateSize(); - update(); + propagateSize(); + update(); } -void TerminalDisplay::mousePressEvent(QMouseEvent* ev) +void TerminalDisplay::mousePressEvent(QMouseEvent *ev) { - if ( _possibleTripleClick && (ev->button()==Qt::LeftButton) ) { - mouseTripleClickEvent(ev); - return; - } + if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) { + mouseTripleClickEvent(ev); + return; + } + + if (!contentsRect().contains(ev->pos())) + return; + + if (!_screenWindow) + return; - if ( !contentsRect().contains(ev->pos()) ) return; + int charLine; + int charColumn; + getCharacterPosition(ev->pos(), charLine, charColumn); + QPoint pos = QPoint(charColumn, charLine); - if ( !_screenWindow ) return; + if (ev->button() == Qt::LeftButton) { + _lineSelectionMode = false; + _wordSelectionMode = false; - int charLine; - int charColumn; - getCharacterPosition(ev->pos(),charLine,charColumn); - QPoint pos = QPoint(charColumn,charLine); + emit isBusySelecting(true); // Keep it steady... + // Drag only when the Control key is hold + bool selected = false; - if ( ev->button() == Qt::LeftButton) - { - _lineSelectionMode = false; - _wordSelectionMode = false; + // The receiver of the testIsSelected() signal will adjust + // 'selected' accordingly. + // emit testIsSelected(pos.x(), pos.y(), selected); - emit isBusySelecting(true); // Keep it steady... - // Drag only when the Control key is hold - bool selected = false; + selected = _screenWindow->isSelected(pos.x(), pos.y()); + + if ((!_ctrlDrag || ev->modifiers() & Qt::ControlModifier) && selected) { + // The user clicked inside selected text + dragInfo.state = diPending; + dragInfo.start = ev->pos(); + } else { + // No reason to ever start a drag event + dragInfo.state = diNone; + + _preserveLineBreaks = !((ev->modifiers() & Qt::ControlModifier) + && !(ev->modifiers() & Qt::AltModifier)); + _columnSelectionMode = + (ev->modifiers() & Qt::AltModifier) && (ev->modifiers() & Qt::ControlModifier); - // The receiver of the testIsSelected() signal will adjust - // 'selected' accordingly. - //emit testIsSelected(pos.x(), pos.y(), selected); + if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) { + _screenWindow->clearSelection(); - selected = _screenWindow->isSelected(pos.x(),pos.y()); + // emit clearSelectionSignal(); + pos.ry() += _scrollBar->value(); + _iPntSel = _pntSel = pos; + _actSel = 1; // left mouse button pressed but nothing selected yet. - if ((!_ctrlDrag || ev->modifiers() & Qt::ControlModifier) && selected ) { - // The user clicked inside selected text - dragInfo.state = diPending; - dragInfo.start = ev->pos(); + } else { + emit mouseSignal(0, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 0); + } + + Filter::HotSpot *spot = _filterChain->hotSpotAt(charLine, charColumn); + if (spot && spot->type() == Filter::HotSpot::Link) + spot->activate(QLatin1String("click-action")); + } + } else if (ev->button() == Qt::MidButton) { + if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) + emitSelection(true, ev->modifiers() & Qt::ControlModifier); + else + emit mouseSignal(1, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 0); + } else if (ev->button() == Qt::RightButton) { + if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) + emit configureRequest(ev->pos()); + else + emit mouseSignal(2, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 0); } - else { - // No reason to ever start a drag event - dragInfo.state = diNone; - - _preserveLineBreaks = !( ( ev->modifiers() & Qt::ControlModifier ) && !(ev->modifiers() & Qt::AltModifier) ); - _columnSelectionMode = (ev->modifiers() & Qt::AltModifier) && (ev->modifiers() & Qt::ControlModifier); - - if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) - { - _screenWindow->clearSelection(); - - //emit clearSelectionSignal(); - pos.ry() += _scrollBar->value(); - _iPntSel = _pntSel = pos; - _actSel = 1; // left mouse button pressed but nothing selected yet. - - } - else - { - emit mouseSignal( 0, charColumn + 1, charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0); - } - - Filter::HotSpot *spot = _filterChain->hotSpotAt(charLine, charColumn); - if (spot && spot->type() == Filter::HotSpot::Link) - spot->activate(QLatin1String("click-action")); - } - } - else if ( ev->button() == Qt::MidButton ) - { - if ( _mouseMarks || (ev->modifiers() & Qt::ShiftModifier) ) - emitSelection(true,ev->modifiers() & Qt::ControlModifier); - else - emit mouseSignal( 1, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0); - } - else if ( ev->button() == Qt::RightButton ) - { - if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) - emit configureRequest(ev->pos()); - else - emit mouseSignal( 2, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0); - } } -QList TerminalDisplay::filterActions(const QPoint& position) +QList TerminalDisplay::filterActions(const QPoint &position) { - int charLine, charColumn; - getCharacterPosition(position,charLine,charColumn); + int charLine, charColumn; + getCharacterPosition(position, charLine, charColumn); - Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn); + Filter::HotSpot *spot = _filterChain->hotSpotAt(charLine, charColumn); - return spot ? spot->actions() : QList(); + return spot ? spot->actions() : QList(); } -void TerminalDisplay::mouseMoveEvent(QMouseEvent* ev) +void TerminalDisplay::mouseMoveEvent(QMouseEvent *ev) { - int charLine = 0; - int charColumn = 0; - int leftMargin = _leftBaseMargin - + ((_scrollbarLocation == QTermWidget::ScrollBarLeft - && !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) - ? _scrollBar->width() : 0); - - getCharacterPosition(ev->pos(),charLine,charColumn); - - // handle filters - // change link hot-spot appearance on mouse-over - Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn); - if ( spot && spot->type() == Filter::HotSpot::Link) - { - QRegion previousHotspotArea = _mouseOverHotspotArea; - _mouseOverHotspotArea = QRegion(); - QRect r; - if (spot->startLine()==spot->endLine()) { - r.setCoords( spot->startColumn()*_fontWidth + leftMargin, - spot->startLine()*_fontHeight + _topBaseMargin, - spot->endColumn()*_fontWidth + leftMargin, - (spot->endLine()+1)*_fontHeight - 1 + _topBaseMargin ); - _mouseOverHotspotArea |= r; - } else { - r.setCoords( spot->startColumn()*_fontWidth + leftMargin, - spot->startLine()*_fontHeight + _topBaseMargin, - _columns*_fontWidth - 1 + leftMargin, - (spot->startLine()+1)*_fontHeight + _topBaseMargin ); - _mouseOverHotspotArea |= r; - for ( int line = spot->startLine()+1 ; line < spot->endLine() ; line++ ) { - r.setCoords( 0*_fontWidth + leftMargin, - line*_fontHeight + _topBaseMargin, - _columns*_fontWidth + leftMargin, - (line+1)*_fontHeight + _topBaseMargin ); + int charLine = 0; + int charColumn = 0; + int leftMargin = _leftBaseMargin + + ((_scrollbarLocation == QTermWidget::ScrollBarLeft + && !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, + _scrollBar)) + ? _scrollBar->width() + : 0); + + getCharacterPosition(ev->pos(), charLine, charColumn); + + // handle filters + // change link hot-spot appearance on mouse-over + Filter::HotSpot *spot = _filterChain->hotSpotAt(charLine, charColumn); + if (spot && spot->type() == Filter::HotSpot::Link) { + QRegion previousHotspotArea = _mouseOverHotspotArea; + _mouseOverHotspotArea = QRegion(); + QRect r; + if (spot->startLine() == spot->endLine()) { + r.setCoords(spot->startColumn() * _fontWidth + leftMargin, + spot->startLine() * _fontHeight + _topBaseMargin, + spot->endColumn() * _fontWidth + leftMargin, + (spot->endLine() + 1) * _fontHeight - 1 + _topBaseMargin); + _mouseOverHotspotArea |= r; + } else { + r.setCoords(spot->startColumn() * _fontWidth + leftMargin, + spot->startLine() * _fontHeight + _topBaseMargin, + _columns * _fontWidth - 1 + leftMargin, + (spot->startLine() + 1) * _fontHeight + _topBaseMargin); + _mouseOverHotspotArea |= r; + for (int line = spot->startLine() + 1; line < spot->endLine(); line++) { + r.setCoords(0 * _fontWidth + leftMargin, line * _fontHeight + _topBaseMargin, + _columns * _fontWidth + leftMargin, + (line + 1) * _fontHeight + _topBaseMargin); + _mouseOverHotspotArea |= r; + } + r.setCoords(0 * _fontWidth + leftMargin, spot->endLine() * _fontHeight + _topBaseMargin, + spot->endColumn() * _fontWidth + leftMargin, + (spot->endLine() + 1) * _fontHeight + _topBaseMargin); _mouseOverHotspotArea |= r; } - r.setCoords( 0*_fontWidth + leftMargin, - spot->endLine()*_fontHeight + _topBaseMargin, - spot->endColumn()*_fontWidth + leftMargin, - (spot->endLine()+1)*_fontHeight + _topBaseMargin ); - _mouseOverHotspotArea |= r; - } - - update( _mouseOverHotspotArea | previousHotspotArea ); - } - else if ( !_mouseOverHotspotArea.isEmpty() ) - { - update( _mouseOverHotspotArea ); + + update(_mouseOverHotspotArea | previousHotspotArea); + } else if (!_mouseOverHotspotArea.isEmpty()) { + update(_mouseOverHotspotArea); // set hotspot area to an invalid rectangle _mouseOverHotspotArea = QRegion(); - } - - // for auto-hiding the cursor, we need mouseTracking - if (ev->buttons() == Qt::NoButton ) return; - - // if the terminal is interested in mouse movements - // then emit a mouse movement signal, unless the shift - // key is being held down, which overrides this. - if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) - { - int button = 3; - if (ev->buttons() & Qt::LeftButton) - button = 0; - if (ev->buttons() & Qt::MidButton) - button = 1; - if (ev->buttons() & Qt::RightButton) - button = 2; - - - emit mouseSignal( button, - charColumn + 1, - charLine + 1 +_scrollBar->value() -_scrollBar->maximum(), - 1 ); - - return; - } - - if (dragInfo.state == diPending) - { - // we had a mouse down, but haven't confirmed a drag yet - // if the mouse has moved sufficiently, we will confirm - -// int distance = KGlobalSettings::dndEventDelay(); - int distance = QApplication::startDragDistance(); - if ( ev->x() > dragInfo.start.x() + distance || ev->x() < dragInfo.start.x() - distance || - ev->y() > dragInfo.start.y() + distance || ev->y() < dragInfo.start.y() - distance) - { - // we've left the drag square, we can start a real drag operation now - emit isBusySelecting(false); // Ok.. we can breath again. - - _screenWindow->clearSelection(); - doDrag(); - } - return; - } - else if (dragInfo.state == diDragging) - { - // this isn't technically needed because mouseMoveEvent is suppressed during - // Qt drag operations, replaced by dragMoveEvent - return; - } - - if (_actSel == 0) return; - - // don't extend selection while pasting - if (ev->buttons() & Qt::MidButton) return; - - extendSelection( ev->pos() ); -} - -void TerminalDisplay::extendSelection( const QPoint& position ) -{ - QPoint pos = position; - - if ( !_screenWindow ) - return; - - //if ( !contentsRect().contains(ev->pos()) ) return; - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - int scroll = _scrollBar->value(); - - // we're in the process of moving the mouse with the left button pressed - // the mouse cursor will kept caught within the bounds of the text in - // this widget. - - int linesBeyondWidget = 0; - - QRect textBounds(tLx + _leftMargin, - tLy + _topMargin, - _usedColumns*_fontWidth-1, - _usedLines*_fontHeight-1); - - // Adjust position within text area bounds. - QPoint oldpos = pos; - - pos.setX( qBound(textBounds.left(),pos.x(),textBounds.right()) ); - pos.setY( qBound(textBounds.top(),pos.y(),textBounds.bottom()) ); - - if ( oldpos.y() > textBounds.bottom() ) - { - linesBeyondWidget = (oldpos.y()-textBounds.bottom()) / _fontHeight; - _scrollBar->setValue(_scrollBar->value()+linesBeyondWidget+1); // scrollforward - } - if ( oldpos.y() < textBounds.top() ) - { - linesBeyondWidget = (textBounds.top()-oldpos.y()) / _fontHeight; - _scrollBar->setValue(_scrollBar->value()-linesBeyondWidget-1); // history - } - - int charColumn = 0; - int charLine = 0; - getCharacterPosition(pos,charLine,charColumn); - - QPoint here = QPoint(charColumn,charLine); //QPoint((pos.x()-tLx-_leftMargin+(_fontWidth/2))/_fontWidth,(pos.y()-tLy-_topMargin)/_fontHeight); - QPoint ohere; - QPoint _iPntSelCorr = _iPntSel; - _iPntSelCorr.ry() -= _scrollBar->value(); - QPoint _pntSelCorr = _pntSel; - _pntSelCorr.ry() -= _scrollBar->value(); - bool swapping = false; - - if ( _wordSelectionMode ) - { - // Extend to word boundaries - int i; - QChar selClass; - - bool left_not_right = ( here.y() < _iPntSelCorr.y() || - ( here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() ) ); - bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() || - ( _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() ) ); - swapping = left_not_right != old_left_not_right; - - // Find left (left_not_right ? from here : from start) - QPoint left = left_not_right ? here : _iPntSelCorr; - i = loc(left.x(),left.y()); - if (i>=0 && i<=_imageSize) { - selClass = charClass(_image[i].character); - while ( ((left.x()>0) || (left.y()>0 && (_lineProperties[left.y()-1] & LINE_WRAPPED) )) - && charClass(_image[i-1].character) == selClass ) - { i--; if (left.x()>0) left.rx()--; else {left.rx()=_usedColumns-1; left.ry()--;} } - } - - // Find left (left_not_right ? from start : from here) - QPoint right = left_not_right ? _iPntSelCorr : here; - i = loc(right.x(),right.y()); - if (i>=0 && i<=_imageSize) { - selClass = charClass(_image[i].character); - while( ((right.x()<_usedColumns-1) || (right.y()<_usedLines-1 && (_lineProperties[right.y()] & LINE_WRAPPED) )) - && charClass(_image[i+1].character) == selClass ) - { i++; if (right.x()<_usedColumns-1) right.rx()++; else {right.rx()=0; right.ry()++; } } - } - - // Pick which is start (ohere) and which is extension (here) - if ( left_not_right ) - { - here = left; ohere = right; - } - else - { - here = right; ohere = left; } - ohere.rx()++; - } - if ( _lineSelectionMode ) - { - // Extend to complete line - bool above_not_below = ( here.y() < _iPntSelCorr.y() ); + // for auto-hiding the cursor, we need mouseTracking + if (ev->buttons() == Qt::NoButton) + return; - QPoint above = above_not_below ? here : _iPntSelCorr; - QPoint below = above_not_below ? _iPntSelCorr : here; + // if the terminal is interested in mouse movements + // then emit a mouse movement signal, unless the shift + // key is being held down, which overrides this. + if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) { + int button = 3; + if (ev->buttons() & Qt::LeftButton) + button = 0; + if (ev->buttons() & Qt::MidButton) + button = 1; + if (ev->buttons() & Qt::RightButton) + button = 2; + + emit mouseSignal(button, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 1); - while (above.y()>0 && (_lineProperties[above.y()-1] & LINE_WRAPPED) ) - above.ry()--; - while (below.y()<_usedLines-1 && (_lineProperties[below.y()] & LINE_WRAPPED) ) - below.ry()++; + return; + } - above.setX(0); - below.setX(_usedColumns-1); + if (dragInfo.state == diPending) { + // we had a mouse down, but haven't confirmed a drag yet + // if the mouse has moved sufficiently, we will confirm - // Pick which is start (ohere) and which is extension (here) - if ( above_not_below ) - { - here = above; ohere = below; - } - else - { - here = below; ohere = above; + // int distance = KGlobalSettings::dndEventDelay(); + int distance = QApplication::startDragDistance(); + if (ev->x() > dragInfo.start.x() + distance || ev->x() < dragInfo.start.x() - distance + || ev->y() > dragInfo.start.y() + distance || ev->y() < dragInfo.start.y() - distance) { + // we've left the drag square, we can start a real drag operation now + emit isBusySelecting(false); // Ok.. we can breath again. + + _screenWindow->clearSelection(); + doDrag(); + } + return; + } else if (dragInfo.state == diDragging) { + // this isn't technically needed because mouseMoveEvent is suppressed during + // Qt drag operations, replaced by dragMoveEvent + return; } - QPoint newSelBegin = QPoint( ohere.x(), ohere.y() ); - swapping = !(_tripleSelBegin==newSelBegin); - _tripleSelBegin = newSelBegin; + if (_actSel == 0) + return; - ohere.rx()++; - } + // don't extend selection while pasting + if (ev->buttons() & Qt::MidButton) + return; - int offset = 0; - if ( !_wordSelectionMode && !_lineSelectionMode ) - { - int i; - QChar selClass; + extendSelection(ev->pos()); +} - bool left_not_right = ( here.y() < _iPntSelCorr.y() || - ( here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() ) ); - bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() || - ( _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() ) ); - swapping = left_not_right != old_left_not_right; +void TerminalDisplay::extendSelection(const QPoint &position) +{ + QPoint pos = position; - // Find left (left_not_right ? from here : from start) - QPoint left = left_not_right ? here : _iPntSelCorr; + if (!_screenWindow) + return; - // Find left (left_not_right ? from start : from here) - QPoint right = left_not_right ? _iPntSelCorr : here; - if ( right.x() > 0 && !_columnSelectionMode ) - { - i = loc(right.x(),right.y()); - if (i>=0 && i<=_imageSize) { - selClass = charClass(_image[i-1].character); - /* if (selClass == ' ') - { - while ( right.x() < _usedColumns-1 && charClass(_image[i+1].character) == selClass && (right.y()<_usedLines-1) && - !(_lineProperties[right.y()] & LINE_WRAPPED)) - { i++; right.rx()++; } - if (right.x() < _usedColumns-1) - right = left_not_right ? _iPntSelCorr : here; - else - right.rx()++; // will be balanced later because of offset=-1; - }*/ - } - } - - // Pick which is start (ohere) and which is extension (here) - if ( left_not_right ) - { - here = left; ohere = right; offset = 0; - } - else - { - here = right; ohere = left; offset = -1; + // if ( !contentsRect().contains(ev->pos()) ) return; + QPoint tL = contentsRect().topLeft(); + int tLx = tL.x(); + int tLy = tL.y(); + int scroll = _scrollBar->value(); + + // we're in the process of moving the mouse with the left button pressed + // the mouse cursor will kept caught within the bounds of the text in + // this widget. + + int linesBeyondWidget = 0; + + QRect textBounds(tLx + _leftMargin, tLy + _topMargin, _usedColumns * _fontWidth - 1, + _usedLines * _fontHeight - 1); + + // Adjust position within text area bounds. + QPoint oldpos = pos; + + pos.setX(qBound(textBounds.left(), pos.x(), textBounds.right())); + pos.setY(qBound(textBounds.top(), pos.y(), textBounds.bottom())); + + if (oldpos.y() > textBounds.bottom()) { + linesBeyondWidget = (oldpos.y() - textBounds.bottom()) / _fontHeight; + _scrollBar->setValue(_scrollBar->value() + linesBeyondWidget + 1); // scrollforward + } + if (oldpos.y() < textBounds.top()) { + linesBeyondWidget = (textBounds.top() - oldpos.y()) / _fontHeight; + _scrollBar->setValue(_scrollBar->value() - linesBeyondWidget - 1); // history + } + + int charColumn = 0; + int charLine = 0; + getCharacterPosition(pos, charLine, charColumn); + + QPoint here = QPoint( + charColumn, + charLine); // QPoint((pos.x()-tLx-_leftMargin+(_fontWidth/2))/_fontWidth,(pos.y()-tLy-_topMargin)/_fontHeight); + QPoint ohere; + QPoint _iPntSelCorr = _iPntSel; + _iPntSelCorr.ry() -= _scrollBar->value(); + QPoint _pntSelCorr = _pntSel; + _pntSelCorr.ry() -= _scrollBar->value(); + bool swapping = false; + + if (_wordSelectionMode) { + // Extend to word boundaries + int i; + QChar selClass; + + bool left_not_right = (here.y() < _iPntSelCorr.y() + || (here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x())); + bool old_left_not_right = + (_pntSelCorr.y() < _iPntSelCorr.y() + || (_pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x())); + swapping = left_not_right != old_left_not_right; + + // Find left (left_not_right ? from here : from start) + QPoint left = left_not_right ? here : _iPntSelCorr; + i = loc(left.x(), left.y()); + if (i >= 0 && i <= _imageSize) { + selClass = charClass(_image[i].character); + while (((left.x() > 0) + || (left.y() > 0 && (_lineProperties[left.y() - 1] & LINE_WRAPPED))) + && charClass(_image[i - 1].character) == selClass) { + i--; + if (left.x() > 0) + left.rx()--; + else { + left.rx() = _usedColumns - 1; + left.ry()--; + } + } + } + + // Find left (left_not_right ? from start : from here) + QPoint right = left_not_right ? _iPntSelCorr : here; + i = loc(right.x(), right.y()); + if (i >= 0 && i <= _imageSize) { + selClass = charClass(_image[i].character); + while (((right.x() < _usedColumns - 1) + || (right.y() < _usedLines - 1 && (_lineProperties[right.y()] & LINE_WRAPPED))) + && charClass(_image[i + 1].character) == selClass) { + i++; + if (right.x() < _usedColumns - 1) + right.rx()++; + else { + right.rx() = 0; + right.ry()++; + } + } + } + + // Pick which is start (ohere) and which is extension (here) + if (left_not_right) { + here = left; + ohere = right; + } else { + here = right; + ohere = left; + } + ohere.rx()++; } - } - if ((here == _pntSelCorr) && (scroll == _scrollBar->value())) return; // not moved + if (_lineSelectionMode) { + // Extend to complete line + bool above_not_below = (here.y() < _iPntSelCorr.y()); - if (here == ohere) return; // It's not left, it's not right. + QPoint above = above_not_below ? here : _iPntSelCorr; + QPoint below = above_not_below ? _iPntSelCorr : here; - if ( _actSel < 2 || swapping ) - { - if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode ) - { - _screenWindow->setSelectionStart( ohere.x() , ohere.y() , true ); - } - else - { - _screenWindow->setSelectionStart( ohere.x()-1-offset , ohere.y() , false ); + while (above.y() > 0 && (_lineProperties[above.y() - 1] & LINE_WRAPPED)) + above.ry()--; + while (below.y() < _usedLines - 1 && (_lineProperties[below.y()] & LINE_WRAPPED)) + below.ry()++; + + above.setX(0); + below.setX(_usedColumns - 1); + + // Pick which is start (ohere) and which is extension (here) + if (above_not_below) { + here = above; + ohere = below; + } else { + here = below; + ohere = above; + } + + QPoint newSelBegin = QPoint(ohere.x(), ohere.y()); + swapping = !(_tripleSelBegin == newSelBegin); + _tripleSelBegin = newSelBegin; + + ohere.rx()++; + } + + int offset = 0; + if (!_wordSelectionMode && !_lineSelectionMode) { + int i; + QChar selClass; + + bool left_not_right = (here.y() < _iPntSelCorr.y() + || (here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x())); + bool old_left_not_right = + (_pntSelCorr.y() < _iPntSelCorr.y() + || (_pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x())); + swapping = left_not_right != old_left_not_right; + + // Find left (left_not_right ? from here : from start) + QPoint left = left_not_right ? here : _iPntSelCorr; + + // Find left (left_not_right ? from start : from here) + QPoint right = left_not_right ? _iPntSelCorr : here; + if (right.x() > 0 && !_columnSelectionMode) { + i = loc(right.x(), right.y()); + if (i >= 0 && i <= _imageSize) { + selClass = charClass(_image[i - 1].character); + /* if (selClass == ' ') + { + while ( right.x() < _usedColumns-1 && charClass(_image[i+1].character) == + selClass && (right.y()<_usedLines-1) && + !(_lineProperties[right.y()] & LINE_WRAPPED)) + { i++; right.rx()++; } + if (right.x() < _usedColumns-1) + right = left_not_right ? _iPntSelCorr : here; + else + right.rx()++; // will be balanced later because of offset=-1; + }*/ + } + } + + // Pick which is start (ohere) and which is extension (here) + if (left_not_right) { + here = left; + ohere = right; + offset = 0; + } else { + here = right; + ohere = left; + offset = -1; + } } - } + if ((here == _pntSelCorr) && (scroll == _scrollBar->value())) + return; // not moved - _actSel = 2; // within selection - _pntSel = here; - _pntSel.ry() += _scrollBar->value(); + if (here == ohere) + return; // It's not left, it's not right. - if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode ) - { - _screenWindow->setSelectionEnd( here.x() , here.y() ); - } - else - { - _screenWindow->setSelectionEnd( here.x()+offset , here.y() ); - } + if (_actSel < 2 || swapping) { + if (_columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode) { + _screenWindow->setSelectionStart(ohere.x(), ohere.y(), true); + } else { + _screenWindow->setSelectionStart(ohere.x() - 1 - offset, ohere.y(), false); + } + } + + _actSel = 2; // within selection + _pntSel = here; + _pntSel.ry() += _scrollBar->value(); + if (_columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode) { + _screenWindow->setSelectionEnd(here.x(), here.y()); + } else { + _screenWindow->setSelectionEnd(here.x() + offset, here.y()); + } } -void TerminalDisplay::mouseReleaseEvent(QMouseEvent* ev) +void TerminalDisplay::mouseReleaseEvent(QMouseEvent *ev) { - if ( !_screenWindow ) + if (!_screenWindow) return; int charLine; int charColumn; - getCharacterPosition(ev->pos(),charLine,charColumn); - - if ( ev->button() == Qt::LeftButton) - { - emit isBusySelecting(false); - if(dragInfo.state == diPending) - { - // We had a drag event pending but never confirmed. Kill selection - _screenWindow->clearSelection(); - //emit clearSelectionSignal(); - } - else - { - if ( _actSel > 1 ) - { - setSelection( _screenWindow->selectedText(_preserveLineBreaks) ); - } + getCharacterPosition(ev->pos(), charLine, charColumn); + + if (ev->button() == Qt::LeftButton) { + emit isBusySelecting(false); + if (dragInfo.state == diPending) { + // We had a drag event pending but never confirmed. Kill selection + _screenWindow->clearSelection(); + // emit clearSelectionSignal(); + } else { + if (_actSel > 1) { + setSelection(_screenWindow->selectedText(_preserveLineBreaks)); + } - _actSel = 0; + _actSel = 0; - //FIXME: emits a release event even if the mouse is - // outside the range. The procedure used in `mouseMoveEvent' - // applies here, too. + // FIXME: emits a release event even if the mouse is + // outside the range. The procedure used in `mouseMoveEvent' + // applies here, too. - if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) - emit mouseSignal( 0, - charColumn + 1, - charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 2); + if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) + emit mouseSignal(0, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 2); + } + dragInfo.state = diNone; } - dragInfo.state = diNone; - } - - if ( !_mouseMarks && - ((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier)) - || ev->button() == Qt::MidButton) ) - { - emit mouseSignal( ev->button() == Qt::MidButton ? 1 : 2, - charColumn + 1, - charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , - 2); - } + if (!_mouseMarks + && ((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier)) + || ev->button() == Qt::MidButton)) { + emit mouseSignal(ev->button() == Qt::MidButton ? 1 : 2, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 2); + } } -void TerminalDisplay::getCharacterPosition(const QPointF& widgetPoint,int& line,int& column) const +void TerminalDisplay::getCharacterPosition(const QPointF &widgetPoint, int &line, int &column) const { - line = (widgetPoint.y()-contentsRect().top()-_topMargin) / _fontHeight; + line = (widgetPoint.y() - contentsRect().top() - _topMargin) / _fontHeight; if (line < 0) line = 0; if (line >= _usedLines) line = _usedLines - 1; int x = widgetPoint.x() + _fontWidth / 2 - contentsRect().left() - _leftMargin; - if ( _fixedFont ) + if (_fixedFont) column = x / _fontWidth; - else - { + else { column = 0; - while(column + 1 < _usedColumns && x > textWidth(0, column + 1, line)) + while (column + 1 < _usedColumns && x > textWidth(0, column + 1, line)) column++; } - if ( column < 0 ) + if (column < 0) column = 0; // the column value returned can be equal to _usedColumns, which @@ -2439,13 +2342,13 @@ void TerminalDisplay::getCharacterPosition(const QPointF& widgetPoint,int& line, // // this is required so that the user can select characters in the right-most // column (or left-most for right-to-left input) - if ( column > _usedColumns ) + if (column > _usedColumns) column = _usedColumns; } void TerminalDisplay::updateFilters() { - if ( !_screenWindow ) + if (!_screenWindow) return; processFilters(); @@ -2453,236 +2356,219 @@ void TerminalDisplay::updateFilters() void TerminalDisplay::updateLineProperties() { - if ( !_screenWindow ) + if (!_screenWindow) return; _lineProperties = _screenWindow->getLineProperties(); } -void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent* ev) -{ - if ( ev->button() != Qt::LeftButton) return; - if ( !_screenWindow ) return; - - int charLine = 0; - int charColumn = 0; - - getCharacterPosition(ev->pos(),charLine,charColumn); - - QPoint pos(charColumn,charLine); - - // pass on double click as two clicks. - if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) - { - // Send just _ONE_ click event, since the first click of the double click - // was already sent by the click handler - emit mouseSignal( 0, - pos.x()+1, - pos.y()+1 +_scrollBar->value() -_scrollBar->maximum(), - 0 ); // left button - return; - } - - _screenWindow->clearSelection(); - QPoint bgnSel = pos; - QPoint endSel = pos; - int i = loc(bgnSel.x(),bgnSel.y()); - _iPntSel = bgnSel; - _iPntSel.ry() += _scrollBar->value(); - - _wordSelectionMode = true; - - // find word boundaries... - QChar selClass = charClass(_image[i].character); - { - // find the start of the word - int x = bgnSel.x(); - while ( ((x>0) || (bgnSel.y()>0 && (_lineProperties[bgnSel.y()-1] & LINE_WRAPPED) )) - && charClass(_image[i-1].character) == selClass ) - { - i--; - if (x>0) - x--; - else - { - x=_usedColumns-1; - bgnSel.ry()--; - } - } - - bgnSel.setX(x); - _screenWindow->setSelectionStart( bgnSel.x() , bgnSel.y() , false ); - - // find the end of the word - i = loc( endSel.x(), endSel.y() ); - x = endSel.x(); - while( ((x<_usedColumns-1) || (endSel.y()<_usedLines-1 && (_lineProperties[endSel.y()] & LINE_WRAPPED) )) - && charClass(_image[i+1].character) == selClass ) - { - i++; - if (x<_usedColumns-1) - x++; - else - { - x=0; - endSel.ry()++; - } - } - - endSel.setX(x); - - // In word selection mode don't select @ (64) if at end of word. - if ( ( QChar( _image[i].character ) == QLatin1Char('@') ) && ( ( endSel.x() - bgnSel.x() ) > 0 ) ) - endSel.setX( x - 1 ); - - - _actSel = 2; // within selection - - _screenWindow->setSelectionEnd( endSel.x() , endSel.y() ); - - setSelection( _screenWindow->selectedText(_preserveLineBreaks) ); - } - - _possibleTripleClick=true; - - QTimer::singleShot(QApplication::doubleClickInterval(),this, - SLOT(tripleClickTimeout())); -} - -void TerminalDisplay::wheelEvent( QWheelEvent* ev ) -{ - if (ev->angleDelta().y() == 0) - return; - - // if the terminal program is not interested mouse events - // then send the event to the scrollbar if the slider has room to move - // or otherwise send simulated up / down key presses to the terminal program - // for the benefit of programs such as 'less' - if ( _mouseMarks ) - { - bool canScroll = _scrollBar->maximum() > 0; - if (canScroll) - _scrollBar->event(ev); - else +void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent *ev) +{ + if (ev->button() != Qt::LeftButton) + return; + if (!_screenWindow) + return; + + int charLine = 0; + int charColumn = 0; + + getCharacterPosition(ev->pos(), charLine, charColumn); + + QPoint pos(charColumn, charLine); + + // pass on double click as two clicks. + if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) { + // Send just _ONE_ click event, since the first click of the double click + // was already sent by the click handler + emit mouseSignal(0, pos.x() + 1, pos.y() + 1 + _scrollBar->value() - _scrollBar->maximum(), + 0); // left button + return; + } + + _screenWindow->clearSelection(); + QPoint bgnSel = pos; + QPoint endSel = pos; + int i = loc(bgnSel.x(), bgnSel.y()); + _iPntSel = bgnSel; + _iPntSel.ry() += _scrollBar->value(); + + _wordSelectionMode = true; + + // find word boundaries... + QChar selClass = charClass(_image[i].character); { - // assume that each Up / Down key event will cause the terminal application - // to scroll by one line. - // - // to get a reasonable scrolling speed, scroll by one line for every 5 degrees - // of mouse wheel rotation. Mouse wheels typically move in steps of 15 degrees, - // giving a scroll of 3 lines - int key = ev->angleDelta().y() > 0 ? Qt::Key_Up : Qt::Key_Down; + // find the start of the word + int x = bgnSel.x(); + while (((x > 0) || (bgnSel.y() > 0 && (_lineProperties[bgnSel.y() - 1] & LINE_WRAPPED))) + && charClass(_image[i - 1].character) == selClass) { + i--; + if (x > 0) + x--; + else { + x = _usedColumns - 1; + bgnSel.ry()--; + } + } + + bgnSel.setX(x); + _screenWindow->setSelectionStart(bgnSel.x(), bgnSel.y(), false); + + // find the end of the word + i = loc(endSel.x(), endSel.y()); + x = endSel.x(); + while (((x < _usedColumns - 1) + || (endSel.y() < _usedLines - 1 && (_lineProperties[endSel.y()] & LINE_WRAPPED))) + && charClass(_image[i + 1].character) == selClass) { + i++; + if (x < _usedColumns - 1) + x++; + else { + x = 0; + endSel.ry()++; + } + } - // QWheelEvent::angleDelta().y() gives rotation in eighths of a degree - int wheelDegrees = ev->angleDelta().y() / 8; - int linesToScroll = abs(wheelDegrees) / 5; + endSel.setX(x); - QKeyEvent keyScrollEvent(QEvent::KeyPress,key,Qt::NoModifier); + // In word selection mode don't select @ (64) if at end of word. + if ((QChar(_image[i].character) == QLatin1Char('@')) && ((endSel.x() - bgnSel.x()) > 0)) + endSel.setX(x - 1); - for (int i=0;isetSelectionEnd(endSel.x(), endSel.y()); + + setSelection(_screenWindow->selectedText(_preserveLineBreaks)); } - } - else - { - // terminal program wants notification of mouse activity - int charLine; - int charColumn; - getCharacterPosition( ev->position() , charLine , charColumn ); + _possibleTripleClick = true; - emit mouseSignal( ev->angleDelta().y() > 0 ? 4 : 5, - charColumn + 1, - charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , - 0); - } + QTimer::singleShot(QApplication::doubleClickInterval(), this, SLOT(tripleClickTimeout())); } -void TerminalDisplay::tripleClickTimeout() +void TerminalDisplay::wheelEvent(QWheelEvent *ev) { - _possibleTripleClick=false; + if (ev->angleDelta().y() == 0) + return; + + // if the terminal program is not interested mouse events + // then send the event to the scrollbar if the slider has room to move + // or otherwise send simulated up / down key presses to the terminal program + // for the benefit of programs such as 'less' + if (_mouseMarks) { + bool canScroll = _scrollBar->maximum() > 0; + if (canScroll) + _scrollBar->event(ev); + else { + // assume that each Up / Down key event will cause the terminal application + // to scroll by one line. + // + // to get a reasonable scrolling speed, scroll by one line for every 5 degrees + // of mouse wheel rotation. Mouse wheels typically move in steps of 15 degrees, + // giving a scroll of 3 lines + int key = ev->angleDelta().y() > 0 ? Qt::Key_Up : Qt::Key_Down; + + // QWheelEvent::angleDelta().y() gives rotation in eighths of a degree + int wheelDegrees = ev->angleDelta().y() / 8; + int linesToScroll = abs(wheelDegrees) / 5; + + QKeyEvent keyScrollEvent(QEvent::KeyPress, key, Qt::NoModifier); + + for (int i = 0; i < linesToScroll; i++) + emit keyPressedSignal(&keyScrollEvent, false); + } + } else { + // terminal program wants notification of mouse activity + + int charLine; + int charColumn; + getCharacterPosition(ev->position(), charLine, charColumn); + + emit mouseSignal(ev->angleDelta().y() > 0 ? 4 : 5, charColumn + 1, + charLine + 1 + _scrollBar->value() - _scrollBar->maximum(), 0); + } } -void TerminalDisplay::mouseTripleClickEvent(QMouseEvent* ev) +void TerminalDisplay::tripleClickTimeout() { - if ( !_screenWindow ) return; - - int charLine; - int charColumn; - getCharacterPosition(ev->pos(),charLine,charColumn); - _iPntSel = QPoint(charColumn,charLine); + _possibleTripleClick = false; +} - _screenWindow->clearSelection(); +void TerminalDisplay::mouseTripleClickEvent(QMouseEvent *ev) +{ + if (!_screenWindow) + return; - _lineSelectionMode = true; - _wordSelectionMode = false; + int charLine; + int charColumn; + getCharacterPosition(ev->pos(), charLine, charColumn); + _iPntSel = QPoint(charColumn, charLine); - _actSel = 2; // within selection - emit isBusySelecting(true); // Keep it steady... + _screenWindow->clearSelection(); - while (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) ) - _iPntSel.ry()--; + _lineSelectionMode = true; + _wordSelectionMode = false; - if (_tripleClickMode == SelectForwardsFromCursor) { - // find word boundary start - int i = loc(_iPntSel.x(),_iPntSel.y()); - QChar selClass = charClass(_image[i].character); - int x = _iPntSel.x(); + _actSel = 2; // within selection + emit isBusySelecting(true); // Keep it steady... - while ( ((x>0) || - (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) ) - ) - && charClass(_image[i-1].character) == selClass ) - { - i--; - if (x>0) - x--; - else - { - x=_columns-1; - _iPntSel.ry()--; + while (_iPntSel.y() > 0 && (_lineProperties[_iPntSel.y() - 1] & LINE_WRAPPED)) + _iPntSel.ry()--; + + if (_tripleClickMode == SelectForwardsFromCursor) { + // find word boundary start + int i = loc(_iPntSel.x(), _iPntSel.y()); + QChar selClass = charClass(_image[i].character); + int x = _iPntSel.x(); + + while (((x > 0) || (_iPntSel.y() > 0 && (_lineProperties[_iPntSel.y() - 1] & LINE_WRAPPED))) + && charClass(_image[i - 1].character) == selClass) { + i--; + if (x > 0) + x--; + else { + x = _columns - 1; + _iPntSel.ry()--; + } } - } - _screenWindow->setSelectionStart( x , _iPntSel.y() , false ); - _tripleSelBegin = QPoint( x, _iPntSel.y() ); - } - else if (_tripleClickMode == SelectWholeLine) { - _screenWindow->setSelectionStart( 0 , _iPntSel.y() , false ); - _tripleSelBegin = QPoint( 0, _iPntSel.y() ); - } + _screenWindow->setSelectionStart(x, _iPntSel.y(), false); + _tripleSelBegin = QPoint(x, _iPntSel.y()); + } else if (_tripleClickMode == SelectWholeLine) { + _screenWindow->setSelectionStart(0, _iPntSel.y(), false); + _tripleSelBegin = QPoint(0, _iPntSel.y()); + } - while (_iPntSel.y()<_lines-1 && (_lineProperties[_iPntSel.y()] & LINE_WRAPPED) ) - _iPntSel.ry()++; + while (_iPntSel.y() < _lines - 1 && (_lineProperties[_iPntSel.y()] & LINE_WRAPPED)) + _iPntSel.ry()++; - _screenWindow->setSelectionEnd( _columns - 1 , _iPntSel.y() ); + _screenWindow->setSelectionEnd(_columns - 1, _iPntSel.y()); - setSelection(_screenWindow->selectedText(_preserveLineBreaks)); + setSelection(_screenWindow->selectedText(_preserveLineBreaks)); - _iPntSel.ry() += _scrollBar->value(); + _iPntSel.ry() += _scrollBar->value(); } - -bool TerminalDisplay::focusNextPrevChild( bool next ) +bool TerminalDisplay::focusNextPrevChild(bool next) { - if (next) - return false; // This disables changing the active part in konqueror - // when pressing Tab - return QWidget::focusNextPrevChild( next ); + if (next) + return false; // This disables changing the active part in konqueror + // when pressing Tab + return QWidget::focusNextPrevChild(next); } - QChar TerminalDisplay::charClass(QChar qch) const { - if ( qch.isSpace() ) return QLatin1Char(' '); + if (qch.isSpace()) + return QLatin1Char(' '); - if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) ) - return QLatin1Char('a'); + if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive)) + return QLatin1Char('a'); return qch; } -void TerminalDisplay::setWordCharacters(const QString& wc) +void TerminalDisplay::setWordCharacters(const QString &wc) { _wordCharacters = wc; } @@ -2691,7 +2577,7 @@ void TerminalDisplay::setUsesMouse(bool on) { if (_mouseMarks != on) { _mouseMarks = on; - setCursor( _mouseMarks ? Qt::IBeamCursor : Qt::ArrowCursor ); + setCursor(_mouseMarks ? Qt::IBeamCursor : Qt::ArrowCursor); emit usesMouseChanged(); } } @@ -2717,121 +2603,119 @@ bool TerminalDisplay::bracketedPasteMode() const #undef KeyPress -void TerminalDisplay::emitSelection(bool useXselection,bool appendReturn) -{ - if ( !_screenWindow ) - return; - - // Paste Clipboard by simulating keypress events - QString text = QApplication::clipboard()->text(useXselection ? QClipboard::Selection : - QClipboard::Clipboard); - if ( ! text.isEmpty() ) - { - text.replace(QLatin1String("\r\n"), QLatin1String("\n")); - text.replace(QLatin1Char('\n'), QLatin1Char('\r')); - - if (_trimPastedTrailingNewlines) { - text.replace(QRegularExpression(QStringLiteral("\\r+$")), QString()); - } - - if (_confirmMultilinePaste && text.contains(QLatin1Char('\r'))) { - QMessageBox confirmation(this); - confirmation.setWindowTitle(tr("Paste multiline text")); - confirmation.setText(tr("Are you sure you want to paste this text?")); - confirmation.setDetailedText(text); - confirmation.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - // Click "Show details..." to show those by default - const auto buttons = confirmation.buttons(); - for( QAbstractButton * btn : buttons ) { - if (confirmation.buttonRole(btn) == QMessageBox::ActionRole && btn->text() == QMessageBox::tr("Show Details...")) { - Q_EMIT btn->clicked(); - break; - } +void TerminalDisplay::emitSelection(bool useXselection, bool appendReturn) +{ + if (!_screenWindow) + return; + + // Paste Clipboard by simulating keypress events + QString text = QApplication::clipboard()->text(useXselection ? QClipboard::Selection + : QClipboard::Clipboard); + if (!text.isEmpty()) { + text.replace(QLatin1String("\r\n"), QLatin1String("\n")); + text.replace(QLatin1Char('\n'), QLatin1Char('\r')); + + if (_trimPastedTrailingNewlines) { + text.replace(QRegularExpression(QStringLiteral("\\r+$")), QString()); } - confirmation.setDefaultButton(QMessageBox::Yes); - confirmation.exec(); - if (confirmation.standardButton(confirmation.clickedButton()) != QMessageBox::Yes) { - return; + + if (_confirmMultilinePaste && text.contains(QLatin1Char('\r'))) { + QMessageBox confirmation(this); + confirmation.setWindowTitle(tr("Paste multiline text")); + confirmation.setText(tr("Are you sure you want to paste this text?")); + confirmation.setDetailedText(text); + confirmation.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + // Click "Show details..." to show those by default + const auto buttons = confirmation.buttons(); + for (QAbstractButton *btn : buttons) { + if (confirmation.buttonRole(btn) == QMessageBox::ActionRole + && btn->text() == QMessageBox::tr("Show Details...")) { + Q_EMIT btn->clicked(); + break; + } + } + confirmation.setDefaultButton(QMessageBox::Yes); + confirmation.exec(); + if (confirmation.standardButton(confirmation.clickedButton()) != QMessageBox::Yes) { + return; + } } - } - bracketText(text); + bracketText(text); - // appendReturn is intentionally handled _after_ enclosing texts with brackets as - // that feature is used to allow execution of commands immediately after paste. - // Ref: https://bugs.kde.org/show_bug.cgi?id=16179 - // Ref: https://github.com/KDE/konsole/commit/83d365f2ebfe2e659c1e857a2f5f247c556ab571 - if(appendReturn) { - text.append(QLatin1Char('\r')); - } + // appendReturn is intentionally handled _after_ enclosing texts with brackets as + // that feature is used to allow execution of commands immediately after paste. + // Ref: https://bugs.kde.org/show_bug.cgi?id=16179 + // Ref: https://github.com/KDE/konsole/commit/83d365f2ebfe2e659c1e857a2f5f247c556ab571 + if (appendReturn) { + text.append(QLatin1Char('\r')); + } - QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text); - emit keyPressedSignal(&e, true); // expose as a big fat keypress event + QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text); + emit keyPressedSignal(&e, true); // expose as a big fat keypress event - _screenWindow->clearSelection(); + _screenWindow->clearSelection(); - switch(mMotionAfterPasting) - { - case MoveStartScreenWindow: - // Temporarily stop tracking output, or pasting contents triggers - // ScreenWindow::notifyOutputChanged() and the latter scrolls the - // terminal to the last line. It will be re-enabled when needed - // (e.g., scrolling to the last line). - _screenWindow->setTrackOutput(false); - _screenWindow->scrollTo(0); - break; - case MoveEndScreenWindow: - scrollToEnd(); - break; - case NoMoveScreenWindow: - break; + switch (mMotionAfterPasting) { + case MoveStartScreenWindow: + // Temporarily stop tracking output, or pasting contents triggers + // ScreenWindow::notifyOutputChanged() and the latter scrolls the + // terminal to the last line. It will be re-enabled when needed + // (e.g., scrolling to the last line). + _screenWindow->setTrackOutput(false); + _screenWindow->scrollTo(0); + break; + case MoveEndScreenWindow: + scrollToEnd(); + break; + case NoMoveScreenWindow: + break; + } } - } } -void TerminalDisplay::bracketText(QString& text) const +void TerminalDisplay::bracketText(QString &text) const { - if (bracketedPasteMode() && !_disabledBracketedPasteMode) - { + if (bracketedPasteMode() && !_disabledBracketedPasteMode) { text.prepend(QLatin1String("\033[200~")); text.append(QLatin1String("\033[201~")); } } -void TerminalDisplay::setSelection(const QString& t) +void TerminalDisplay::setSelection(const QString &t) { - if (QApplication::clipboard()->supportsSelection()) - { + if (QApplication::clipboard()->supportsSelection()) { QApplication::clipboard()->setText(t, QClipboard::Selection); } } void TerminalDisplay::copyClipboard() { - if ( !_screenWindow ) - return; + if (!_screenWindow) + return; - QString text = _screenWindow->selectedText(_preserveLineBreaks); - if (!text.isEmpty()) - QApplication::clipboard()->setText(text); + QString text = _screenWindow->selectedText(_preserveLineBreaks); + if (!text.isEmpty()) + QApplication::clipboard()->setText(text); } void TerminalDisplay::pasteClipboard() { - emitSelection(false,false); + emitSelection(false, false); } void TerminalDisplay::pasteSelection() { - emitSelection(true,false); + emitSelection(true, false); } - -void TerminalDisplay::setConfirmMultilinePaste(bool confirmMultilinePaste) { +void TerminalDisplay::setConfirmMultilinePaste(bool confirmMultilinePaste) +{ _confirmMultilinePaste = confirmMultilinePaste; } -void TerminalDisplay::setTrimPastedTrailingNewlines(bool trimPastedTrailingNewlines) { +void TerminalDisplay::setTrimPastedTrailingNewlines(bool trimPastedTrailingNewlines) +{ _trimPastedTrailingNewlines = trimPastedTrailingNewlines; } @@ -2841,7 +2725,7 @@ void TerminalDisplay::setTrimPastedTrailingNewlines(bool trimPastedTrailingNewli /* */ /* ------------------------------------------------------------------------- */ -void TerminalDisplay::setFlowControlWarningEnabled( bool enable ) +void TerminalDisplay::setFlowControlWarningEnabled(bool enable) { _flowControlWarningEnabled = enable; @@ -2861,18 +2745,17 @@ int TerminalDisplay::motionAfterPasting() return mMotionAfterPasting; } -void TerminalDisplay::keyPressEvent( QKeyEvent* event ) +void TerminalDisplay::keyPressEvent(QKeyEvent *event) { - _actSel=0; // Key stroke implies a screen update, so TerminalDisplay won't - // know where the current selection is. + _actSel = 0; // Key stroke implies a screen update, so TerminalDisplay won't + // know where the current selection is. - if (_hasBlinkingCursor) - { - _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2); - if (_cursorBlinking) - blinkCursorEvent(); - else - _cursorBlinking = false; + if (_hasBlinkingCursor) { + _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2); + if (_cursorBlinking) + blinkCursorEvent(); + else + _cursorBlinking = false; } emit keyPressedSignal(event, false); @@ -2880,9 +2763,9 @@ void TerminalDisplay::keyPressEvent( QKeyEvent* event ) event->accept(); } -void TerminalDisplay::inputMethodEvent( QInputMethodEvent* event ) +void TerminalDisplay::inputMethodEvent(QInputMethodEvent *event) { - QKeyEvent keyEvent(QEvent::KeyPress,0,Qt::NoModifier,event->commitString()); + QKeyEvent keyEvent(QEvent::KeyPress, 0, Qt::NoModifier, event->commitString()); emit keyPressedSignal(&keyEvent, false); _inputMethodData.preeditString = event->preeditString().toStdWString(); @@ -2890,67 +2773,61 @@ void TerminalDisplay::inputMethodEvent( QInputMethodEvent* event ) event->accept(); } -QVariant TerminalDisplay::inputMethodQuery( Qt::InputMethodQuery query ) const +QVariant TerminalDisplay::inputMethodQuery(Qt::InputMethodQuery query) const { - const QPoint cursorPos = _screenWindow ? _screenWindow->cursorPosition() : QPoint(0,0); - switch ( query ) - { - case Qt::ImMicroFocus: - return imageToWidget(QRect(cursorPos.x(),cursorPos.y(),1,1)); - break; - case Qt::ImFont: - return font(); - break; - case Qt::ImCursorPosition: - // return the cursor position within the current line - return cursorPos.x(); - break; - case Qt::ImSurroundingText: - { - // return the text from the current line - QString lineText; - QTextStream stream(&lineText); - PlainTextDecoder decoder; - decoder.begin(&stream); - decoder.decodeLine(&_image[loc(0,cursorPos.y())],_usedColumns,_lineProperties[cursorPos.y()]); - decoder.end(); - return lineText; - } - break; - case Qt::ImCurrentSelection: - return QString(); - break; - default: - break; + const QPoint cursorPos = _screenWindow ? _screenWindow->cursorPosition() : QPoint(0, 0); + switch (query) { + case Qt::ImMicroFocus: + return imageToWidget(QRect(cursorPos.x(), cursorPos.y(), 1, 1)); + break; + case Qt::ImFont: + return font(); + break; + case Qt::ImCursorPosition: + // return the cursor position within the current line + return cursorPos.x(); + break; + case Qt::ImSurroundingText: { + // return the text from the current line + QString lineText; + QTextStream stream(&lineText); + PlainTextDecoder decoder; + decoder.begin(&stream); + decoder.decodeLine(&_image[loc(0, cursorPos.y())], _usedColumns, + _lineProperties[cursorPos.y()]); + decoder.end(); + return lineText; + } break; + case Qt::ImCurrentSelection: + return QString(); + break; + default: + break; } return QVariant(); } -bool TerminalDisplay::handleShortcutOverrideEvent(QKeyEvent* keyEvent) +bool TerminalDisplay::handleShortcutOverrideEvent(QKeyEvent *keyEvent) { int modifiers = keyEvent->modifiers(); // When a possible shortcut combination is pressed, // emit the overrideShortcutCheck() signal to allow the host // to decide whether the terminal should override it or not. - if (modifiers != Qt::NoModifier) - { + if (modifiers != Qt::NoModifier) { int modifierCount = 0; unsigned int currentModifier = Qt::ShiftModifier; - while (currentModifier <= Qt::KeypadModifier) - { + while (currentModifier <= Qt::KeypadModifier) { if (modifiers & currentModifier) modifierCount++; currentModifier <<= 1; } - if (modifierCount < 2) - { + if (modifierCount < 2) { bool override = false; - emit overrideShortcutCheck(keyEvent,override); - if (override) - { + emit overrideShortcutCheck(keyEvent, override); + if (override) { keyEvent->accept(); return true; } @@ -2960,44 +2837,42 @@ bool TerminalDisplay::handleShortcutOverrideEvent(QKeyEvent* keyEvent) // Override any of the following shortcuts because // they are needed by the terminal int keyCode = keyEvent->key() | modifiers; - switch ( keyCode ) - { - // list is taken from the QLineEdit::event() code - case Qt::Key_Tab: - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Escape: + switch (keyCode) { + // list is taken from the QLineEdit::event() code + case Qt::Key_Tab: + case Qt::Key_Delete: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Escape: keyEvent->accept(); return true; } return false; } -bool TerminalDisplay::event(QEvent* event) +bool TerminalDisplay::event(QEvent *event) { - bool eventHandled = false; - switch (event->type()) - { + bool eventHandled = false; + switch (event->type()) { case QEvent::ShortcutOverride: - eventHandled = handleShortcutOverrideEvent((QKeyEvent*)event); + eventHandled = handleShortcutOverrideEvent((QKeyEvent *)event); break; case QEvent::PaletteChange: case QEvent::ApplicationPaletteChange: - _scrollBar->setPalette( QApplication::palette() ); + _scrollBar->setPalette(QApplication::palette()); break; default: break; - } - return eventHandled ? true : QWidget::event(event); + } + return eventHandled ? true : QWidget::event(event); } void TerminalDisplay::setBellMode(int mode) { - _bellMode=mode; + _bellMode = mode; } void TerminalDisplay::enableBell() @@ -3005,32 +2880,27 @@ void TerminalDisplay::enableBell() _allowBell = true; } -void TerminalDisplay::bell(const QString& message) +void TerminalDisplay::bell(const QString &message) { - if (_bellMode==NoBell) return; - - //limit the rate at which bells can occur - //...mainly for sound effects where rapid bells in sequence - //produce a horrible noise - if ( _allowBell ) - { - _allowBell = false; - QTimer::singleShot(500,this,SLOT(enableBell())); + if (_bellMode == NoBell) + return; - if (_bellMode==SystemBeepBell) - { - QApplication::beep(); - } - else if (_bellMode==NotifyBell) - { - emit notifyBell(message); - } - else if (_bellMode==VisualBell) - { - swapColorTable(); - QTimer::singleShot(200,this,SLOT(swapColorTable())); + // limit the rate at which bells can occur + //...mainly for sound effects where rapid bells in sequence + // produce a horrible noise + if (_allowBell) { + _allowBell = false; + QTimer::singleShot(500, this, SLOT(enableBell())); + + if (_bellMode == SystemBeepBell) { + QApplication::beep(); + } else if (_bellMode == NotifyBell) { + emit notifyBell(message); + } else if (_bellMode == VisualBell) { + swapColorTable(); + QTimer::singleShot(200, this, SLOT(swapColorTable())); + } } - } } void TerminalDisplay::selectionChanged() @@ -3040,226 +2910,216 @@ void TerminalDisplay::selectionChanged() void TerminalDisplay::swapColorTable() { - ColorEntry color = _colorTable[1]; - _colorTable[1]=_colorTable[0]; - _colorTable[0]= color; - _colorsInverted = !_colorsInverted; - update(); + ColorEntry color = _colorTable[1]; + _colorTable[1] = _colorTable[0]; + _colorTable[0] = color; + _colorsInverted = !_colorsInverted; + update(); } void TerminalDisplay::clearImage() { - // We initialize _image[_imageSize] too. See makeImage() - for (int i = 0; i <= _imageSize; i++) - { - _image[i].character = ' '; - _image[i].foregroundColor = CharacterColor(COLOR_SPACE_DEFAULT, - DEFAULT_FORE_COLOR); - _image[i].backgroundColor = CharacterColor(COLOR_SPACE_DEFAULT, - DEFAULT_BACK_COLOR); - _image[i].rendition = DEFAULT_RENDITION; - } + // We initialize _image[_imageSize] too. See makeImage() + for (int i = 0; i <= _imageSize; i++) { + _image[i].character = ' '; + _image[i].foregroundColor = CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_FORE_COLOR); + _image[i].backgroundColor = CharacterColor(COLOR_SPACE_DEFAULT, DEFAULT_BACK_COLOR); + _image[i].rendition = DEFAULT_RENDITION; + } } void TerminalDisplay::calcGeometry() { - _scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height()); - int scrollBarWidth = _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar) - ? 0 : _scrollBar->width(); - switch(_scrollbarLocation) - { - case QTermWidget::NoScrollBar : - _leftMargin = _leftBaseMargin; - _contentWidth = contentsRect().width() - 2 * _leftBaseMargin; - break; - case QTermWidget::ScrollBarLeft : - _leftMargin = _leftBaseMargin + scrollBarWidth; - _contentWidth = contentsRect().width() - 2 * _leftBaseMargin - scrollBarWidth; - _scrollBar->move(contentsRect().topLeft()); - break; + _scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height()); + int scrollBarWidth = + _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar) + ? 0 + : _scrollBar->width(); + switch (_scrollbarLocation) { + case QTermWidget::NoScrollBar: + _leftMargin = _leftBaseMargin; + _contentWidth = contentsRect().width() - 2 * _leftBaseMargin; + break; + case QTermWidget::ScrollBarLeft: + _leftMargin = _leftBaseMargin + scrollBarWidth; + _contentWidth = contentsRect().width() - 2 * _leftBaseMargin - scrollBarWidth; + _scrollBar->move(contentsRect().topLeft()); + break; case QTermWidget::ScrollBarRight: - _leftMargin = _leftBaseMargin; - _contentWidth = contentsRect().width() - 2 * _leftBaseMargin - scrollBarWidth; - _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width()-1, 0)); - break; - } + _leftMargin = _leftBaseMargin; + _contentWidth = contentsRect().width() - 2 * _leftBaseMargin - scrollBarWidth; + _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width() - 1, 0)); + break; + } - _topMargin = _topBaseMargin; - _contentHeight = contentsRect().height() - 2 * _topBaseMargin + /* mysterious */ 1; + _topMargin = _topBaseMargin; + _contentHeight = contentsRect().height() - 2 * _topBaseMargin + /* mysterious */ 1; - if (!_isFixedSize) - { - // ensure that display is always at least one column wide - _columns = qMax(1,_contentWidth / _fontWidth); - _usedColumns = qMin(_usedColumns,_columns); + if (!_isFixedSize) { + // ensure that display is always at least one column wide + _columns = qMax(1, _contentWidth / _fontWidth); + _usedColumns = qMin(_usedColumns, _columns); - // ensure that display is always at least one line high - _lines = qMax(1,_contentHeight / _fontHeight); - _usedLines = qMin(_usedLines,_lines); - } + // ensure that display is always at least one line high + _lines = qMax(1, _contentHeight / _fontHeight); + _usedLines = qMin(_usedLines, _lines); + } } void TerminalDisplay::makeImage() { - calcGeometry(); + calcGeometry(); - // confirm that array will be of non-zero size, since the painting code - // assumes a non-zero array length - Q_ASSERT( _lines > 0 && _columns > 0 ); - Q_ASSERT( _usedLines <= _lines && _usedColumns <= _columns ); + // confirm that array will be of non-zero size, since the painting code + // assumes a non-zero array length + Q_ASSERT(_lines > 0 && _columns > 0); + Q_ASSERT(_usedLines <= _lines && _usedColumns <= _columns); - _imageSize=_lines*_columns; + _imageSize = _lines * _columns; - // We over-commit one character so that we can be more relaxed in dealing with - // certain boundary conditions: _image[_imageSize] is a valid but unused position - _image = new Character[_imageSize+1]; + // We over-commit one character so that we can be more relaxed in dealing with + // certain boundary conditions: _image[_imageSize] is a valid but unused position + _image = new Character[_imageSize + 1]; - clearImage(); + clearImage(); } // calculate the needed size, this must be synced with calcGeometry() void TerminalDisplay::setSize(int columns, int lines) { - int scrollBarWidth = (_scrollBar->isHidden() - || _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) - ? 0 : _scrollBar->sizeHint().width(); - int horizontalMargin = 2 * _leftBaseMargin; - int verticalMargin = 2 * _topBaseMargin; + int scrollBarWidth = + (_scrollBar->isHidden() + || _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)) + ? 0 + : _scrollBar->sizeHint().width(); + int horizontalMargin = 2 * _leftBaseMargin; + int verticalMargin = 2 * _topBaseMargin; - QSize newSize = QSize( horizontalMargin + scrollBarWidth + (columns * _fontWidth) , - verticalMargin + (lines * _fontHeight) ); + QSize newSize = QSize(horizontalMargin + scrollBarWidth + (columns * _fontWidth), + verticalMargin + (lines * _fontHeight)); - if ( newSize != size() ) - { - _size = newSize; - updateGeometry(); - } + if (newSize != size()) { + _size = newSize; + updateGeometry(); + } } void TerminalDisplay::setFixedSize(int cols, int lins) { - _isFixedSize = true; + _isFixedSize = true; - //ensure that display is at least one line by one column in size - _columns = qMax(1,cols); - _lines = qMax(1,lins); - _usedColumns = qMin(_usedColumns,_columns); - _usedLines = qMin(_usedLines,_lines); + // ensure that display is at least one line by one column in size + _columns = qMax(1, cols); + _lines = qMax(1, lins); + _usedColumns = qMin(_usedColumns, _columns); + _usedLines = qMin(_usedLines, _lines); - if (_image) - { - delete[] _image; - makeImage(); - } - setSize(cols, lins); - QWidget::setFixedSize(_size); + if (_image) { + delete[] _image; + makeImage(); + } + setSize(cols, lins); + QWidget::setFixedSize(_size); } QSize TerminalDisplay::sizeHint() const { - return _size; + return _size; } - /* --------------------------------------------------------------------- */ /* */ /* Drag & Drop */ /* */ /* --------------------------------------------------------------------- */ -void TerminalDisplay::dragEnterEvent(QDragEnterEvent* event) +void TerminalDisplay::dragEnterEvent(QDragEnterEvent *event) { - if (event->mimeData()->hasFormat(QLatin1String("text/plain"))) - event->acceptProposedAction(); - if (event->mimeData()->urls().count()) - event->acceptProposedAction(); + if (event->mimeData()->hasFormat(QLatin1String("text/plain"))) + event->acceptProposedAction(); + if (event->mimeData()->urls().count()) + event->acceptProposedAction(); } -void TerminalDisplay::dropEvent(QDropEvent* event) +void TerminalDisplay::dropEvent(QDropEvent *event) { - //KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); - QList urls = event->mimeData()->urls(); + // KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); + QList urls = event->mimeData()->urls(); - QString dropText; - if (!urls.isEmpty()) - { - // TODO/FIXME: escape or quote pasted things if neccessary... - qDebug() << "TerminalDisplay: handling urls. It can be broken. Report any errors, please"; - for ( int i = 0 ; i < urls.count() ; i++ ) - { - //KUrl url = KIO::NetAccess::mostLocalUrl( urls[i] , 0 ); - QUrl url = urls[i]; + QString dropText; + if (!urls.isEmpty()) { + // TODO/FIXME: escape or quote pasted things if neccessary... + qDebug() << "TerminalDisplay: handling urls. It can be broken. Report any errors, please"; + for (int i = 0; i < urls.count(); i++) { + // KUrl url = KIO::NetAccess::mostLocalUrl( urls[i] , 0 ); + QUrl url = urls[i]; - QString urlText; + QString urlText; - if (url.isLocalFile()) - urlText = url.path(); - else - urlText = url.toString(); + if (url.isLocalFile()) + urlText = url.path(); + else + urlText = url.toString(); - // in future it may be useful to be able to insert file names with drag-and-drop - // without quoting them (this only affects paths with spaces in) - //urlText = KShell::quoteArg(urlText); + // in future it may be useful to be able to insert file names with drag-and-drop + // without quoting them (this only affects paths with spaces in) + // urlText = KShell::quoteArg(urlText); - QChar q(QLatin1Char('\'')); - dropText += q + QString(urlText).replace(q, QLatin1String("'\\''")) + q; - dropText += QLatin1Char(' '); + QChar q(QLatin1Char('\'')); + dropText += q + QString(urlText).replace(q, QLatin1String("'\\''")) + q; + dropText += QLatin1Char(' '); + } + } else { + dropText = event->mimeData()->text(); } - } - else - { - dropText = event->mimeData()->text(); - } emit sendStringToEmu(dropText.toLocal8Bit().constData()); } void TerminalDisplay::doDrag() { - dragInfo.state = diDragging; - dragInfo.dragObject = new QDrag(this); - QMimeData *mimeData = new QMimeData; - mimeData->setText(QApplication::clipboard()->text(QClipboard::Selection)); - dragInfo.dragObject->setMimeData(mimeData); - dragInfo.dragObject->exec(Qt::CopyAction); - // Don't delete the QTextDrag object. Qt will delete it when it's done with it. + dragInfo.state = diDragging; + dragInfo.dragObject = new QDrag(this); + QMimeData *mimeData = new QMimeData; + mimeData->setText(QApplication::clipboard()->text(QClipboard::Selection)); + dragInfo.dragObject->setMimeData(mimeData); + dragInfo.dragObject->exec(Qt::CopyAction); + // Don't delete the QTextDrag object. Qt will delete it when it's done with it. } void TerminalDisplay::outputSuspended(bool suspended) { - //create the label when this function is first called - if (!_outputSuspendedLabel) - { - //This label includes a link to an English language website - //describing the 'flow control' (Xon/Xoff) feature found in almost - //all terminal emulators. - //If there isn't a suitable article available in the target language the link - //can simply be removed. - _outputSuspendedLabel = new QLabel( tr("Output has been " - "suspended" - " by pressing Ctrl+S." - " Press Ctrl+Q to resume."), - this ); - - QPalette palette(_outputSuspendedLabel->palette()); - //KColorScheme::adjustBackground(palette,KColorScheme::NeutralBackground); - _outputSuspendedLabel->setPalette(palette); - _outputSuspendedLabel->setAutoFillBackground(true); - _outputSuspendedLabel->setBackgroundRole(QPalette::Base); - _outputSuspendedLabel->setFont(QApplication::font()); - _outputSuspendedLabel->setContentsMargins(5, 5, 5, 5); - - //enable activation of "Xon/Xoff" link in label - _outputSuspendedLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | - Qt::LinksAccessibleByKeyboard); - _outputSuspendedLabel->setOpenExternalLinks(true); - _outputSuspendedLabel->setVisible(false); - - _gridLayout->addWidget(_outputSuspendedLabel); - _gridLayout->addItem( new QSpacerItem(0,0,QSizePolicy::Expanding, - QSizePolicy::Expanding), - 1,0); - + // create the label when this function is first called + if (!_outputSuspendedLabel) { + // This label includes a link to an English language website + // describing the 'flow control' (Xon/Xoff) feature found in almost + // all terminal emulators. + // If there isn't a suitable article available in the target language the link + // can simply be removed. + _outputSuspendedLabel = + new QLabel(tr("Output has been " + "suspended" + " by pressing Ctrl+S." + " Press Ctrl+Q to resume."), + this); + + QPalette palette(_outputSuspendedLabel->palette()); + // KColorScheme::adjustBackground(palette,KColorScheme::NeutralBackground); + _outputSuspendedLabel->setPalette(palette); + _outputSuspendedLabel->setAutoFillBackground(true); + _outputSuspendedLabel->setBackgroundRole(QPalette::Base); + _outputSuspendedLabel->setFont(QApplication::font()); + _outputSuspendedLabel->setContentsMargins(5, 5, 5, 5); + + // enable activation of "Xon/Xoff" link in label + _outputSuspendedLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse + | Qt::LinksAccessibleByKeyboard); + _outputSuspendedLabel->setOpenExternalLinks(true); + _outputSuspendedLabel->setVisible(false); + + _gridLayout->addWidget(_outputSuspendedLabel); + _gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), + 1, 0); } _outputSuspendedLabel->setVisible(suspended); @@ -3267,13 +3127,13 @@ void TerminalDisplay::outputSuspended(bool suspended) uint TerminalDisplay::lineSpacing() const { - return _lineSpacing; + return _lineSpacing; } void TerminalDisplay::setLineSpacing(uint i) { - _lineSpacing = i; - setVTFont(font()); // Trigger an update. + _lineSpacing = i; + setVTFont(font()); // Trigger an update. } int TerminalDisplay::margin() const @@ -3287,58 +3147,47 @@ void TerminalDisplay::setMargin(int i) _leftBaseMargin = i; } -AutoScrollHandler::AutoScrollHandler(QWidget* parent) -: QObject(parent) -, _timerId(0) +AutoScrollHandler::AutoScrollHandler(QWidget *parent) : QObject(parent), _timerId(0) { parent->installEventFilter(this); } -void AutoScrollHandler::timerEvent(QTimerEvent* event) +void AutoScrollHandler::timerEvent(QTimerEvent *event) { if (event->timerId() != _timerId) return; - QMouseEvent mouseEvent( QEvent::MouseMove, - widget()->mapFromGlobal(QCursor::pos()), - Qt::NoButton, - Qt::LeftButton, - Qt::NoModifier); + QMouseEvent mouseEvent(QEvent::MouseMove, widget()->mapFromGlobal(QCursor::pos()), Qt::NoButton, + Qt::LeftButton, Qt::NoModifier); - QApplication::sendEvent(widget(),&mouseEvent); + QApplication::sendEvent(widget(), &mouseEvent); } -bool AutoScrollHandler::eventFilter(QObject* watched,QEvent* event) +bool AutoScrollHandler::eventFilter(QObject *watched, QEvent *event) { - Q_ASSERT( watched == parent() ); - Q_UNUSED( watched ); + Q_ASSERT(watched == parent()); + Q_UNUSED(watched); - QMouseEvent* mouseEvent = (QMouseEvent*)event; - switch (event->type()) - { - case QEvent::MouseMove: - { - bool mouseInWidget = widget()->rect().contains(mouseEvent->pos()); + QMouseEvent *mouseEvent = (QMouseEvent *)event; + switch (event->type()) { + case QEvent::MouseMove: { + bool mouseInWidget = widget()->rect().contains(mouseEvent->pos()); - if (mouseInWidget) - { - if (_timerId) - killTimer(_timerId); - _timerId = 0; - } - else - { - if (!_timerId && (mouseEvent->buttons() & Qt::LeftButton)) - _timerId = startTimer(100); - } - break; - } - case QEvent::MouseButtonRelease: - if (_timerId && (mouseEvent->buttons() & ~Qt::LeftButton)) - { + if (mouseInWidget) { + if (_timerId) killTimer(_timerId); - _timerId = 0; - } + _timerId = 0; + } else { + if (!_timerId && (mouseEvent->buttons() & Qt::LeftButton)) + _timerId = startTimer(100); + } break; - default: + } + case QEvent::MouseButtonRelease: + if (_timerId && (mouseEvent->buttons() & ~Qt::LeftButton)) { + killTimer(_timerId); + _timerId = 0; + } + break; + default: break; }; diff --git a/lib/TerminalDisplay.h b/lib/TerminalDisplay.h index af9cd176..f1d498d7 100644 --- a/lib/TerminalDisplay.h +++ b/lib/TerminalDisplay.h @@ -47,36 +47,28 @@ class QHideEvent; class QTimerEvent; class QWidget; -//class KMenu; +// class KMenu; -namespace Konsole -{ +namespace Konsole { - enum MotionAfterPasting - { - // No move screenwindow after pasting - NoMoveScreenWindow = 0, - // Move start of screenwindow after pasting - MoveStartScreenWindow = 1, - // Move end of screenwindow after pasting - MoveEndScreenWindow = 2 - }; +enum MotionAfterPasting { + // No move screenwindow after pasting + NoMoveScreenWindow = 0, + // Move start of screenwindow after pasting + MoveStartScreenWindow = 1, + // Move end of screenwindow after pasting + MoveEndScreenWindow = 2 +}; - enum BackgroundMode { - None, - Stretch, - Zoom, - Fit, - Center - }; +enum BackgroundMode { None, Stretch, Zoom, Fit, Center }; extern unsigned short vt100_graphics[32]; class ScreenWindow; /** - * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity - * to the terminal. + * A widget which displays output from a terminal emulation and sends input keypresses and mouse + * activity to the terminal. * * When the terminal emulation receives new output from the program running in the terminal, * it will update the display by calling updateImage(). @@ -85,15 +77,15 @@ class ScreenWindow; */ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget { - Q_OBJECT + Q_OBJECT public: /** Constructs a new terminal display widget with the specified parent. */ - TerminalDisplay(QWidget *parent=nullptr); + TerminalDisplay(QWidget *parent = nullptr); ~TerminalDisplay() override; /** Returns the terminal color palette used by the display. */ - const ColorEntry* colorTable() const; + const ColorEntry *colorTable() const; /** Sets the terminal color palette used by the display. */ void setColorTable(const ColorEntry table[]); /** @@ -111,7 +103,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget void setOpacity(qreal opacity); /** Sets the background image of the terminal display. */ - void setBackgroundImage(const QString& backgroundImage); + void setBackgroundImage(const QString &backgroundImage); /** Sets the background image mode of the terminal display. */ void setBackgroundMode(BackgroundMode mode); @@ -139,14 +131,14 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * Returns the display's filter chain. When the image for the display is updated, * the text is passed through each filter in the chain. Each filter can define * hotspots which correspond to certain strings (such as URLs or particular words). - * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() ) - * the view will draw visual cues such as underlines on mouse-over for links or translucent - * rectangles for markers. + * Depending on the type of the hotspots created by the filter ( returned by + * Filter::Hotspot::type() ) the view will draw visual cues such as underlines on mouse-over for + * links or translucent rectangles for markers. * * To add a new filter to the view, call: * viewWidget->filterChain()->addFilter( filterObject ); */ - FilterChain* filterChain() const; + FilterChain *filterChain() const; /** * Updates the filters in the display's filter chain. This will cause @@ -168,7 +160,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * Returns a list of menu actions created by the filters for the content * at the given @p position. */ - QList filterActions(const QPoint& position); + QList filterActions(const QPoint &position); /** Returns true if the cursor is set to blink or false otherwise. */ bool blinkingCursor() { return _hasBlinkingCursor; } @@ -178,15 +170,14 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget /** Specifies whether or not text can blink. */ void setBlinkingTextEnabled(bool blink); - void setCtrlDrag(bool enable) { _ctrlDrag=enable; } + void setCtrlDrag(bool enable) { _ctrlDrag = enable; } bool ctrlDrag() { return _ctrlDrag; } /** * This enum describes the methods for selecting text when - * the user triple-clicks within the display. - */ - enum TripleClickMode - { + * the user triple-clicks within the display. + */ + enum TripleClickMode { /** Select the whole line underneath the cursor. */ SelectWholeLine, /** Select from the current cursor position to the end of the line. */ @@ -203,10 +194,10 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget int margin() const; uint lineSpacing() const; - void emitSelection(bool useXselection,bool appendReturn); + void emitSelection(bool useXselection, bool appendReturn); /** change and wrap text corresponding to paste mode **/ - void bracketText(QString& text) const; + void bracketText(QString &text) const; /** * Sets the shape of the keyboard cursor. This is the cursor drawn @@ -237,7 +228,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * @param color The color to use to draw the cursor. This is only taken into * account if @p useForegroundColor is false. */ - void setKeyboardCursorColor(bool useForegroundColor , const QColor& color); + void setKeyboardCursorColor(bool useForegroundColor, const QColor &color); /** * Returns the color of the keyboard cursor, or an invalid color if the keyboard @@ -252,7 +243,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * This will depend upon the height of the widget and the current font. * See fontHeight() */ - int lines() { return _lines; } + int lines() { return _lines; } /** * Returns the number of characters of text which can be displayed on * each line in the widget. @@ -260,17 +251,17 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * This will depend upon the width of the widget and the current font. * See fontWidth() */ - int columns() { return _columns; } + int columns() { return _columns; } /** * Returns the height of the characters in the font used to draw the text in the display. */ - int fontHeight() { return _fontHeight; } + int fontHeight() { return _fontHeight; } /** * Returns the width of the characters in the display. * This assumes the use of a fixed-width font. */ - int fontWidth() { return _fontWidth; } + int fontWidth() { return _fontWidth; } void setSize(int cols, int lins); void setFixedSize(int cols, int lins); @@ -289,7 +280,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * @param wc An array of characters which are to be considered parts * of a word ( in addition to letters and numbers ). */ - void setWordCharacters(const QString& wc); + void setWordCharacters(const QString &wc); /** * Returns the characters which are considered part of a word for the * purpose of selecting words in the display with the mouse. @@ -319,19 +310,18 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * can be used to alert the user when a 'bell' occurs in the terminal * session. */ - enum BellMode - { + enum BellMode { /** A system beep. */ - SystemBeepBell=0, + SystemBeepBell = 0, /** * KDE notification. This may play a sound, show a passive popup * or perform some other action depending on the user's settings. */ - NotifyBell=1, + NotifyBell = 1, /** A silent, visual bell (eg. inverting the display's colors briefly) */ - VisualBell=2, + VisualBell = 2, /** No bell effects */ - NoBell=3 + NoBell = 3 }; void setSelection(const QString &t); @@ -349,17 +339,17 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * Sets the font used to draw the display. Has no effect if @p font * is larger than the size of the display itself. */ - void setVTFont(const QFont& font); + void setVTFont(const QFont &font); /** * Specified whether anti-aliasing of text in the terminal display * is enabled or not. Defaults to enabled. */ - static void setAntialias( bool antialias ) { _antialiasText = antialias; } + static void setAntialias(bool antialias) { _antialiasText = antialias; } /** * Returns true if anti-aliasing of text in the terminal is enabled. */ - static bool antialias() { return _antialiasText; } + static bool antialias() { return _antialiasText; } /** * Specify whether line chars should be drawn by ourselves or left to @@ -382,7 +372,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * terminal in lines and columns is displayed whilst the widget * is being resized. */ - void setTerminalSizeHint(bool on) { _terminalSizeHint=on; } + void setTerminalSizeHint(bool on) { _terminalSizeHint = on; } /** * Returns whether or not the current height and width of * the terminal in lines and columns is displayed whilst the widget @@ -395,13 +385,13 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * * See setTerminalSizeHint() , isTerminalSizeHint() */ - void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; } + void setTerminalSizeStartup(bool on) { _terminalSizeStartup = on; } /** * Sets the status of the BiDi rendering inside the terminal display. * Defaults to disabled. */ - void setBidiEnabled(bool set) { _bidiEnabled=set; } + void setBidiEnabled(bool set) { _bidiEnabled = set; } /** * Returns the status of the BiDi rendering in this widget. */ @@ -415,9 +405,10 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered * by the TerminalDisplay. */ - void setScreenWindow( ScreenWindow* window ); - /** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */ - ScreenWindow* screenWindow() const; + void setScreenWindow(ScreenWindow *window); + /** Returns the terminal screen section which is displayed in this widget. See + * setScreenWindow() */ + ScreenWindow *screenWindow() const; static bool HAVE_TRANSPARENCY; @@ -428,7 +419,7 @@ class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget // maps a point on the widget to the position ( ie. line and column ) // of the character at that point. - void getCharacterPosition(const QPointF& widgetPoint,int& line,int& column) const; + void getCharacterPosition(const QPointF &widgetPoint, int &line, int &column) const; void disableBracketedPasteMode(bool disable) { _disabledBracketedPasteMode = disable; } bool bracketedPasteModeIsDisabled() const { return _disabledBracketedPasteMode; } @@ -465,24 +456,23 @@ public slots: void pasteSelection(); /** - * Changes whether the flow control warning box should be shown when the flow control - * stop key (Ctrl+S) are pressed. - */ + * Changes whether the flow control warning box should be shown when the flow control + * stop key (Ctrl+S) are pressed. + */ void setFlowControlWarningEnabled(bool enabled); /** * Returns true if the flow control warning box is enabled. * See outputSuspended() and setFlowControlWarningEnabled() */ - bool flowControlWarningEnabled() const - { return _flowControlWarningEnabled; } + bool flowControlWarningEnabled() const { return _flowControlWarningEnabled; } /** * Causes the widget to display or hide a message informing the user that terminal * output has been suspended (by using the flow control key combination Ctrl+S) * * @param suspended True if terminal output has been suspended and the warning message should - * be shown or false to indicate that terminal output has been resumed and that - * the warning message should disappear. + * be shown or false to indicate that terminal output has been resumed and + * that the warning message should disappear. */ void outputSuspended(bool suspended); @@ -492,13 +482,13 @@ public slots: * * If this is set to true, mouse signals will be emitted by the view when the user clicks, drags * or otherwise moves the mouse inside the view. - * The user interaction needed to create selections will also change, and the user will be required - * to hold down the shift key to create a selection or perform other mouse activities inside the - * view area - since the program running in the terminal is being allowed to handle normal mouse - * events itself. + * The user interaction needed to create selections will also change, and the user will be + * required to hold down the shift key to create a selection or perform other mouse activities + * inside the view area - since the program running in the terminal is being allowed to handle + * normal mouse events itself. * - * @param usesMouse Set to true if the program running in the terminal is interested in mouse events - * or false otherwise. + * @param usesMouse Set to true if the program running in the terminal is interested in mouse + * events or false otherwise. */ void setUsesMouse(bool usesMouse); @@ -512,19 +502,19 @@ public slots: * Shows a notification that a bell event has occurred in the terminal. * TODO: More documentation here */ - void bell(const QString& message); + void bell(const QString &message); /** * Sets the background of the display to the specified color. * @see setColorTable(), setForegroundColor() */ - void setBackgroundColor(const QColor& color); + void setBackgroundColor(const QColor &color); /** * Sets the text of the display to the specified color. * @see setColorTable(), setBackgroundColor() */ - void setForegroundColor(const QColor& color); + void setForegroundColor(const QColor &color); void selectionChanged(); @@ -537,7 +527,8 @@ public slots: /** * A mouse event occurred. - * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release) + * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 + * for release) * @param column The character column where the event occurred * @param line The character row where the event occurred * @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion @@ -552,62 +543,63 @@ public slots: * * This can be used to display a context menu. */ - void configureRequest(const QPoint& position); + void configureRequest(const QPoint &position); /** * When a shortcut which is also a valid terminal key sequence is pressed while * the terminal widget has focus, this signal is emitted to allow the host to decide * whether the shortcut should be overridden. - * When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead - * and the action associated with the shortcut will not be triggered. + * When the shortcut is overridden, the key sequence will be sent to the terminal emulation + * instead and the action associated with the shortcut will not be triggered. * * @p override is set to false by default and the shortcut will be triggered as normal. */ - void overrideShortcutCheck(QKeyEvent* keyEvent,bool& override); + void overrideShortcutCheck(QKeyEvent *keyEvent, bool &override); - void isBusySelecting(bool); - void sendStringToEmu(const char*); + void isBusySelecting(bool); + void sendStringToEmu(const char *); - // qtermwidget signals - void copyAvailable(bool); - void termGetFocus(); - void termLostFocus(); + // qtermwidget signals + void copyAvailable(bool); + void termGetFocus(); + void termLostFocus(); - void notifyBell(const QString&); + void notifyBell(const QString &); void usesMouseChanged(); protected: - bool event( QEvent * ) override; + bool event(QEvent *) override; - void paintEvent( QPaintEvent * ) override; + void paintEvent(QPaintEvent *) override; - void showEvent(QShowEvent*) override; - void hideEvent(QHideEvent*) override; - void resizeEvent(QResizeEvent*) override; + void showEvent(QShowEvent *) override; + void hideEvent(QHideEvent *) override; + void resizeEvent(QResizeEvent *) override; virtual void fontChange(const QFont &font); - void focusInEvent(QFocusEvent* event) override; - void focusOutEvent(QFocusEvent* event) override; - void keyPressEvent(QKeyEvent* event) override; - void mouseDoubleClickEvent(QMouseEvent* ev) override; - void mousePressEvent( QMouseEvent* ) override; - void mouseReleaseEvent( QMouseEvent* ) override; - void mouseMoveEvent( QMouseEvent* ) override; - virtual void extendSelection( const QPoint& pos ); - void wheelEvent( QWheelEvent* ) override; - - bool focusNextPrevChild( bool next ) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *ev) override; + void mousePressEvent(QMouseEvent *) override; + void mouseReleaseEvent(QMouseEvent *) override; + void mouseMoveEvent(QMouseEvent *) override; + virtual void extendSelection(const QPoint &pos); + void wheelEvent(QWheelEvent *) override; + + bool focusNextPrevChild(bool next) override; // drag and drop - void dragEnterEvent(QDragEnterEvent* event) override; - void dropEvent(QDropEvent* event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dropEvent(QDropEvent *event) override; void doDrag(); enum DragState { diNone, diPending, diDragging }; - struct _dragInfo { - DragState state; - QPoint start; - QDrag *dragObject; + struct _dragInfo + { + DragState state; + QPoint start; + QDrag *dragObject; } dragInfo; // classifies the 'ch' into one of three categories @@ -620,11 +612,11 @@ public slots: void clearImage(); - void mouseTripleClickEvent(QMouseEvent* ev); + void mouseTripleClickEvent(QMouseEvent *ev); // reimplemented - void inputMethodEvent ( QInputMethodEvent* event ) override; - QVariant inputMethodQuery( Qt::InputMethodQuery query ) const override; + void inputMethodEvent(QInputMethodEvent *event) override; + QVariant inputMethodQuery(Qt::InputMethodQuery query) const override; protected slots: @@ -632,17 +624,16 @@ protected slots: void blinkEvent(); void blinkCursorEvent(); - //Renables bell noises and visuals. Used to disable further bells for a short period of time - //after emitting the first in a sequence of bell events. + // Renables bell noises and visuals. Used to disable further bells for a short period of time + // after emitting the first in a sequence of bell events. void enableBell(); private slots: void swapColorTable(); - void tripleClickTimeout(); // resets possibleTripleClick + void tripleClickTimeout(); // resets possibleTripleClick private: - // -- Drawing helpers -- // determine the width of this text @@ -656,31 +647,31 @@ private slots: void drawContents(QPainter &paint, const QRect &rect); // draws a section of text, all the text in this section // has a common color and style - void drawTextFragment(QPainter& painter, const QRect& rect, - const std::wstring& text, const Character* style); + void drawTextFragment(QPainter &painter, const QRect &rect, const std::wstring &text, + const Character *style); // draws the background for a text fragment // if useOpacitySetting is true then the color's alpha value will be set to // the display's transparency (set with setOpacity()), otherwise the background // will be drawn fully opaque - void drawBackground(QPainter& painter, const QRect& rect, const QColor& color, + void drawBackground(QPainter &painter, const QRect &rect, const QColor &color, bool useOpacitySetting); // draws the cursor character - void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor, - const QColor& backgroundColor , bool& invertColors); + void drawCursor(QPainter &painter, const QRect &rect, const QColor &foregroundColor, + const QColor &backgroundColor, bool &invertColors); // draws the characters or line graphics in a text fragment - void drawCharacters(QPainter& painter, const QRect& rect, const std::wstring& text, - const Character* style, bool invertCharacterColor); + void drawCharacters(QPainter &painter, const QRect &rect, const std::wstring &text, + const Character *style, bool invertCharacterColor); // draws a string of line graphics - void drawLineCharString(QPainter& painter, int x, int y, - const std::wstring& str, const Character* attributes) const; + void drawLineCharString(QPainter &painter, int x, int y, const std::wstring &str, + const Character *attributes) const; // draws the preedit string for input methods - void drawInputMethodPreeditString(QPainter& painter , const QRect& rect); + void drawInputMethodPreeditString(QPainter &painter, const QRect &rect); // -- // maps an area in the character image to an area on the widget - QRect imageToWidget(const QRect& imageArea) const; + QRect imageToWidget(const QRect &imageArea) const; // the area where the preedit string for input methods will be draw QRect preeditRect() const; @@ -695,16 +686,16 @@ private slots: // 'region' is the part of the image to scroll - currently only // the top, bottom and height of 'region' are taken into account, // the left and right are ignored. - void scrollImage(int lines , const QRect& region); + void scrollImage(int lines, const QRect ®ion); void calcGeometry(); void propagateSize(); void updateImageSize(); void makeImage(); - void paintFilters(QPainter& painter); + void paintFilters(QPainter &painter); - void calDrawTextAdditionHeight(QPainter& painter); + void calDrawTextAdditionHeight(QPainter &painter); // returns a region covering all of the areas of the widget which contain // a hotspot @@ -716,10 +707,10 @@ private slots: // redraws the cursor void updateCursor(); - bool handleShortcutOverrideEvent(QKeyEvent* event); + bool handleShortcutOverrideEvent(QKeyEvent *event); bool isLineChar(wchar_t c) const; - bool isLineCharString(const std::wstring& string) const; + bool isLineCharString(const std::wstring &string) const; // the window onto the terminal screen which this display // is currently showing. @@ -727,34 +718,34 @@ private slots: bool _allowBell; - QGridLayout* _gridLayout; + QGridLayout *_gridLayout; bool _fixedFont; // has fixed pitch - int _fontHeight; // height - int _fontWidth; // width - int _fontAscent; // ascend - bool _boldIntense; // Whether intense colors should be rendered with bold font - int _drawTextAdditionHeight; // additional height to prevent font trancation - bool _drawTextTestFlag; // indicate it is a testing or not + int _fontHeight; // height + int _fontWidth; // width + int _fontAscent; // ascend + bool _boldIntense; // Whether intense colors should be rendered with bold font + int _drawTextAdditionHeight; // additional height to prevent font trancation + bool _drawTextTestFlag; // indicate it is a testing or not - int _leftMargin; // offset - int _topMargin; // offset + int _leftMargin; // offset + int _topMargin; // offset - int _lines; // the number of lines that can be displayed in the widget - int _columns; // the number of columns that can be displayed in the widget + int _lines; // the number of lines that can be displayed in the widget + int _columns; // the number of columns that can be displayed in the widget - int _usedLines; // the number of lines that are actually being used, this will be less + int _usedLines; // the number of lines that are actually being used, this will be less // than 'lines' if the character image provided with setImage() is smaller // than the maximum image size which can be displayed int _usedColumns; // the number of columns that are actually being used, this will be less - // than 'columns' if the character image provided with setImage() is smaller - // than the maximum image size which can be displayed + // than 'columns' if the character image provided with setImage() is smaller + // than the maximum image size which can be displayed int _contentHeight; int _contentWidth; - Character* _image; // [lines][columns] - // only the area [usedLines][usedColumns] in the image contains valid data + Character *_image; // [lines][columns] + // only the area [usedLines][usedColumns] in the image contains valid data int _imageSize; QVector _lineProperties; @@ -770,48 +761,47 @@ private slots: bool _bracketedPasteMode; bool _disabledBracketedPasteMode; - QPoint _iPntSel; // initial selection point - QPoint _pntSel; // current selection point - QPoint _tripleSelBegin; // help avoid flicker - int _actSel; // selection state - bool _wordSelectionMode; - bool _lineSelectionMode; - bool _preserveLineBreaks; - bool _columnSelectionMode; - - QClipboard* _clipboard; - QScrollBar* _scrollBar; + QPoint _iPntSel; // initial selection point + QPoint _pntSel; // current selection point + QPoint _tripleSelBegin; // help avoid flicker + int _actSel; // selection state + bool _wordSelectionMode; + bool _lineSelectionMode; + bool _preserveLineBreaks; + bool _columnSelectionMode; + + QClipboard *_clipboard; + QScrollBar *_scrollBar; QTermWidget::ScrollBarPosition _scrollbarLocation; - QString _wordCharacters; - int _bellMode; + QString _wordCharacters; + int _bellMode; - bool _blinking; // hide text in paintEvent + bool _blinking; // hide text in paintEvent bool _hasBlinker; // has characters to blink - bool _cursorBlinking; // hide cursor in paintEvent - bool _hasBlinkingCursor; // has blinking cursor enabled - bool _allowBlinkingText; // allow text to blink - bool _ctrlDrag; // require Ctrl key for drag + bool _cursorBlinking; // hide cursor in paintEvent + bool _hasBlinkingCursor; // has blinking cursor enabled + bool _allowBlinkingText; // allow text to blink + bool _ctrlDrag; // require Ctrl key for drag TripleClickMode _tripleClickMode; - bool _isFixedSize; //Columns / lines are locked. - QTimer* _blinkTimer; // active when hasBlinker - QTimer* _blinkCursorTimer; // active when hasBlinkingCursor + bool _isFixedSize; // Columns / lines are locked. + QTimer *_blinkTimer; // active when hasBlinker + QTimer *_blinkCursorTimer; // active when hasBlinkingCursor - //QMenu* _drop; + // QMenu* _drop; QString _dropText; int _dndFileCount; - bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted + bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted // after QApplication::doubleClickInterval() delay - - QLabel* _resizeWidget; - QTimer* _resizeTimer; + QLabel *_resizeWidget; + QTimer *_resizeTimer; bool _flowControlWarningEnabled; - //widgets related to the warning message that appears when the user presses Ctrl+S to suspend - //terminal output - informing them what has happened and how to resume output - QLabel* _outputSuspendedLabel; + // widgets related to the warning message that appears when the user presses Ctrl+S to suspend + // terminal output - informing them what has happened and how to resume output + QLabel *_outputSuspendedLabel; uint _lineSpacing; @@ -826,7 +816,7 @@ private slots: // list of filters currently applied to the display. used for links and // search highlight - TerminalImageFilterChain* _filterChain; + TerminalImageFilterChain *_filterChain; QRegion _mouseOverHotspotArea; QTermWidget::KeyboardCursorShape _cursorShape; @@ -835,7 +825,6 @@ private slots: // color of the character under the cursor is used QColor _cursorColor; - MotionAfterPasting mMotionAfterPasting; bool _confirmMultilinePaste; bool _trimPastedTrailingNewlines; @@ -847,9 +836,9 @@ private slots: }; InputMethodData _inputMethodData; - static bool _antialiasText; // do we antialias or not + static bool _antialiasText; // do we antialias or not - //the delay in milliseconds between redrawing blinking text + // the delay in milliseconds between redrawing blinking text static const int TEXT_BLINK_DELAY = 500; int _leftBaseMargin; @@ -858,23 +847,22 @@ private slots: bool _drawLineChars; public: - static void setTransparencyEnabled(bool enable) - { - HAVE_TRANSPARENCY = enable; - } + static void setTransparencyEnabled(bool enable) { HAVE_TRANSPARENCY = enable; } }; class AutoScrollHandler : public QObject { -Q_OBJECT + Q_OBJECT public: - AutoScrollHandler(QWidget* parent); + AutoScrollHandler(QWidget *parent); + protected: - void timerEvent(QTimerEvent* event) override; - bool eventFilter(QObject* watched,QEvent* event) override; + void timerEvent(QTimerEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + private: - QWidget* widget() const { return static_cast(parent()); } + QWidget *widget() const { return static_cast(parent()); } int _timerId; }; diff --git a/lib/Vt102Emulation.cpp b/lib/Vt102Emulation.cpp index 3105cca4..48391c87 100644 --- a/lib/Vt102Emulation.cpp +++ b/lib/Vt102Emulation.cpp @@ -30,12 +30,12 @@ // this allows konsole to be compiled without XKB and XTEST extensions // even though it might be available on a particular system. #if defined(AVOID_XKB) - #undef HAVE_XKB +# undef HAVE_XKB #endif #if defined(HAVE_XKB) - void scrolllock_set_off(); - void scrolllock_set_on(); +void scrolllock_set_off(); +void scrolllock_set_on(); #endif // Standard @@ -56,42 +56,37 @@ #include "KeyboardTranslator.h" #include "Screen.h" - using namespace Konsole; Vt102Emulation::Vt102Emulation() - : Emulation(), - prevCC(0), - _titleUpdateTimer(new QTimer(this)), - _reportFocusEvents(false) + : Emulation(), prevCC(0), _titleUpdateTimer(new QTimer(this)), _reportFocusEvents(false) { - _titleUpdateTimer->setSingleShot(true); - QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle())); + _titleUpdateTimer->setSingleShot(true); + QObject::connect(_titleUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTitle())); - initTokenizer(); - reset(); + initTokenizer(); + reset(); } -Vt102Emulation::~Vt102Emulation() -{} +Vt102Emulation::~Vt102Emulation() { } void Vt102Emulation::clearEntireScreen() { - _currentScreen->clearEntireScreen(); - bufferedUpdate(); + _currentScreen->clearEntireScreen(); + bufferedUpdate(); } void Vt102Emulation::reset() { - resetTokenizer(); - resetModes(); - resetCharset(0); - _screen[0]->reset(); - resetCharset(1); - _screen[1]->reset(); - setCodec(LocaleCodec); - - bufferedUpdate(); + resetTokenizer(); + resetModes(); + resetCharset(0); + _screen[0]->reset(); + resetCharset(1); + _screen[1]->reset(); + setCodec(LocaleCodec); + + bufferedUpdate(); } /* ------------------------------------------------------------------------- */ @@ -154,21 +149,22 @@ void Vt102Emulation::reset() */ -#define TY_CONSTRUCT(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) ) +#define TY_CONSTRUCT(T, A, N) \ + (((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff)) -#define TY_CHR( ) TY_CONSTRUCT(0,0,0) -#define TY_CTL(A ) TY_CONSTRUCT(1,A,0) -#define TY_ESC(A ) TY_CONSTRUCT(2,A,0) -#define TY_ESC_CS(A,B) TY_CONSTRUCT(3,A,B) -#define TY_ESC_DE(A ) TY_CONSTRUCT(4,A,0) -#define TY_CSI_PS(A,N) TY_CONSTRUCT(5,A,N) -#define TY_CSI_PN(A ) TY_CONSTRUCT(6,A,0) -#define TY_CSI_PR(A,N) TY_CONSTRUCT(7,A,N) -#define TY_CSI_PS_SP(A,N) TY_CONSTRUCT(11,A,N) +#define TY_CHR() TY_CONSTRUCT(0, 0, 0) +#define TY_CTL(A) TY_CONSTRUCT(1, A, 0) +#define TY_ESC(A) TY_CONSTRUCT(2, A, 0) +#define TY_ESC_CS(A, B) TY_CONSTRUCT(3, A, B) +#define TY_ESC_DE(A) TY_CONSTRUCT(4, A, 0) +#define TY_CSI_PS(A, N) TY_CONSTRUCT(5, A, N) +#define TY_CSI_PN(A) TY_CONSTRUCT(6, A, 0) +#define TY_CSI_PR(A, N) TY_CONSTRUCT(7, A, N) +#define TY_CSI_PS_SP(A, N) TY_CONSTRUCT(11, A, N) -#define TY_VT52(A) TY_CONSTRUCT(8,A,0) -#define TY_CSI_PG(A) TY_CONSTRUCT(9,A,0) -#define TY_CSI_PE(A) TY_CONSTRUCT(10,A,0) +#define TY_VT52(A) TY_CONSTRUCT(8, A, 0) +#define TY_CSI_PG(A) TY_CONSTRUCT(9, A, 0) +#define TY_CSI_PE(A) TY_CONSTRUCT(10, A, 0) #define MAX_ARGUMENT 4096 @@ -183,64 +179,65 @@ void Vt102Emulation::reset() void Vt102Emulation::resetTokenizer() { - tokenBufferPos = 0; - argc = 0; - argv[0] = 0; - argv[1] = 0; - prevCC = 0; + tokenBufferPos = 0; + argc = 0; + argv[0] = 0; + argv[1] = 0; + prevCC = 0; } void Vt102Emulation::addDigit(int digit) { - if (argv[argc] < MAX_ARGUMENT) - argv[argc] = 10*argv[argc] + digit; + if (argv[argc] < MAX_ARGUMENT) + argv[argc] = 10 * argv[argc] + digit; } void Vt102Emulation::addArgument() { - argc = qMin(argc+1,MAXARGS-1); - argv[argc] = 0; + argc = qMin(argc + 1, MAXARGS - 1); + argv[argc] = 0; } void Vt102Emulation::addToCurrentToken(wchar_t cc) { - tokenBuffer[tokenBufferPos] = cc; - tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1); + tokenBuffer[tokenBufferPos] = cc; + tokenBufferPos = qMin(tokenBufferPos + 1, MAX_TOKEN_LENGTH - 1); } // Character Class flags used while decoding -#define CTL 1 // Control character -#define CHR 2 // Printable character -#define CPN 4 // TODO: Document me -#define DIG 8 // Digit -#define SCS 16 // TODO: Document me -#define GRP 32 // TODO: Document me -#define CPS 64 // Character which indicates end of window resize - // escape sequence '\e[8;;t' +#define CTL 1 // Control character +#define CHR 2 // Printable character +#define CPN 4 // TODO: Document me +#define DIG 8 // Digit +#define SCS 16 // TODO: Document me +#define GRP 32 // TODO: Document me +#define CPS \ + 64 // Character which indicates end of window resize + // escape sequence '\e[8;;t' void Vt102Emulation::initTokenizer() { - int i; - quint8* s; - for(i = 0;i < 256; ++i) - charClass[i] = 0; - for(i = 0;i < 32; ++i) - charClass[i] |= CTL; - for(i = 32;i < 256; ++i) - charClass[i] |= CHR; - for(s = (quint8*)"@ABCDEFGHILMPSTXZbcdfry"; *s; ++s) - charClass[*s] |= CPN; - // resize = \e[8;;t - for(s = (quint8*)"t"; *s; ++s) - charClass[*s] |= CPS; - for(s = (quint8*)"0123456789"; *s; ++s) - charClass[*s] |= DIG; - for(s = (quint8*)"()+*%"; *s; ++s) - charClass[*s] |= SCS; - for(s = (quint8*)"()+*#[]%"; *s; ++s) - charClass[*s] |= GRP; - - resetTokenizer(); + int i; + quint8 *s; + for (i = 0; i < 256; ++i) + charClass[i] = 0; + for (i = 0; i < 32; ++i) + charClass[i] |= CTL; + for (i = 32; i < 256; ++i) + charClass[i] |= CHR; + for (s = (quint8 *)"@ABCDEFGHILMPSTXZbcdfry"; *s; ++s) + charClass[*s] |= CPN; + // resize = \e[8;;t + for (s = (quint8 *)"t"; *s; ++s) + charClass[*s] |= CPS; + for (s = (quint8 *)"0123456789"; *s; ++s) + charClass[*s] |= DIG; + for (s = (quint8 *)"()+*%"; *s; ++s) + charClass[*s] |= SCS; + for (s = (quint8 *)"()+*#[]%"; *s; ++s) + charClass[*s] |= GRP; + + resetTokenizer(); } /* Ok, here comes the nasty part of the decoder. @@ -262,174 +259,217 @@ void Vt102Emulation::initTokenizer() Note that they need to applied in proper order. */ -#define lec(P,L,C) (p == (P) && s[(L)] == (C)) -#define lun( ) (p == 1 && cc >= 32 ) -#define les(P,L,C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C)) -#define eec(C) (p >= 3 && cc == (C)) -#define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C)) -#define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C)) -#define epp( ) (p >= 3 && s[2] == '?') -#define epe( ) (p >= 3 && s[2] == '!') -#define egt( ) (p >= 3 && s[2] == '>') -#define esp( ) (p == 4 && s[3] == ' ') -#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']') -#define Xte (Xpe && (cc == 7 || (prevCC == 27 && cc == 92) )) // 27, 92 => "\e\\" (ST, String Terminator) -#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) - -#define CNTL(c) ((c)-'@') +#define lec(P, L, C) (p == (P) && s[(L)] == (C)) +#define lun() (p == 1 && cc >= 32) +#define les(P, L, C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C)) +#define eec(C) (p >= 3 && cc == (C)) +#define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C)) +#define eps(C) \ + (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 \ + && (charClass[cc] & (C)) == (C)) +#define epp() (p >= 3 && s[2] == '?') +#define epe() (p >= 3 && s[2] == '!') +#define egt() (p >= 3 && s[2] == '>') +#define esp() (p == 4 && s[3] == ' ') +#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']') +#define Xte \ + (Xpe && (cc == 7 || (prevCC == 27 && cc == 92))) // 27, 92 => "\e\\" (ST, String Terminator) +#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) + +#define CNTL(c) ((c) - '@') #define ESC 27 #define DEL 127 // process an incoming unicode character void Vt102Emulation::receiveChar(wchar_t cc) { - if (cc == DEL) - return; //VT100: ignore. - - if (ces(CTL)) - { - // ignore control characters in the text part of Xpe (aka OSC) "ESC]" - // escape sequences; this matches what XTERM docs say - if (Xpe) { - prevCC = cc; - return; - } + if (cc == DEL) + return; // VT100: ignore. + + if (ces(CTL)) { + // ignore control characters in the text part of Xpe (aka OSC) "ESC]" + // escape sequences; this matches what XTERM docs say + if (Xpe) { + prevCC = cc; + return; + } - // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 - // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do - // of course. Guess this originates from a weakly layered handling of the X-on - // X-off protocol, which comes really below this level. - if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) - resetTokenizer(); //VT100: CAN or SUB - if (cc != ESC) - { - processToken(TY_CTL(cc+'@' ),0,0); - return; - } - } - // advance the state - addToCurrentToken(cc); - - wchar_t* s = tokenBuffer; - int p = tokenBufferPos; - - if (getMode(MODE_Ansi)) - { - if (lec(1,0,ESC)) { return; } - if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; } - if (les(2,1,GRP)) { return; } - if (Xte ) { processWindowAttributeChange(); resetTokenizer(); return; } - if (Xpe ) { prevCC = cc; return; } - if (lec(3,2,'?')) { return; } - if (lec(3,2,'>')) { return; } - if (lec(3,2,'!')) { return; } - if (lun( )) { processToken( TY_CHR(), applyCharset(cc), 0); resetTokenizer(); return; } - if (lec(2,0,ESC)) { processToken( TY_ESC(s[1]), 0, 0); resetTokenizer(); return; } - if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0); resetTokenizer(); return; } - if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0); resetTokenizer(); return; } - if (eps( CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]); resetTokenizer(); return; } - if (esp( )) { return; } - if (lec(5, 4, 'q') && s[3] == ' ') { - processToken( TY_CSI_PS_SP(cc, argv[0]), argv[0], 0); - resetTokenizer(); - return; + // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 + // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do + // of course. Guess this originates from a weakly layered handling of the X-on + // X-off protocol, which comes really below this level. + if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) + resetTokenizer(); // VT100: CAN or SUB + if (cc != ESC) { + processToken(TY_CTL(cc + '@'), 0, 0); + return; + } } + // advance the state + addToCurrentToken(cc); - // resize = \e[8;;t - if (eps(CPS)) - { - processToken( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]); - resetTokenizer(); - return; - } + wchar_t *s = tokenBuffer; + int p = tokenBufferPos; - if (epe( )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; } - if (ees(DIG)) { addDigit(cc-'0'); return; } - if (eec(';') || eec(':')) { addArgument(); return; } - for (int i=0;i<=argc;i++) - { - if (epp()) - processToken( TY_CSI_PR(cc,argv[i]), 0, 0); - else if (egt()) - processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c - else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2) - { - // ESC[ ... 48;2;;; ... m -or- ESC[ ... 38;2;;; ... m - i += 2; - processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]); - i += 2; + if (getMode(MODE_Ansi)) { + if (lec(1, 0, ESC)) { + return; } - else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5) - { - // ESC[ ... 48;5; ... m -or- ESC[ ... 38;5; ... m - i += 2; - processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]); + if (lec(1, 0, ESC + 128)) { + s[0] = ESC; + receiveChar('['); + return; + } + if (les(2, 1, GRP)) { + return; + } + if (Xte) { + processWindowAttributeChange(); + resetTokenizer(); + return; + } + if (Xpe) { + prevCC = cc; + return; + } + if (lec(3, 2, '?')) { + return; + } + if (lec(3, 2, '>')) { + return; + } + if (lec(3, 2, '!')) { + return; + } + if (lun()) { + processToken(TY_CHR(), applyCharset(cc), 0); + resetTokenizer(); + return; + } + if (lec(2, 0, ESC)) { + processToken(TY_ESC(s[1]), 0, 0); + resetTokenizer(); + return; + } + if (les(3, 1, SCS)) { + processToken(TY_ESC_CS(s[1], s[2]), 0, 0); + resetTokenizer(); + return; + } + if (lec(3, 1, '#')) { + processToken(TY_ESC_DE(s[2]), 0, 0); + resetTokenizer(); + return; + } + if (eps(CPN)) { + processToken(TY_CSI_PN(cc), argv[0], argv[1]); + resetTokenizer(); + return; + } + if (esp()) { + return; + } + if (lec(5, 4, 'q') && s[3] == ' ') { + processToken(TY_CSI_PS_SP(cc, argv[0]), argv[0], 0); + resetTokenizer(); + return; + } + + // resize = \e[8;;t + if (eps(CPS)) { + processToken(TY_CSI_PS(cc, argv[0]), argv[1], argv[2]); + resetTokenizer(); + return; + } + + if (epe()) { + processToken(TY_CSI_PE(cc), 0, 0); + resetTokenizer(); + return; + } + if (ees(DIG)) { + addDigit(cc - '0'); + return; + } + if (eec(';') || eec(':')) { + addArgument(); + return; + } + for (int i = 0; i <= argc; i++) { + if (epp()) + processToken(TY_CSI_PR(cc, argv[i]), 0, 0); + else if (egt()) + processToken(TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c + else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) + && argv[i + 1] == 2) { + // ESC[ ... 48;2;;; ... m -or- ESC[ ... 38;2;;; + // ... m + i += 2; + processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_RGB, + (argv[i] << 16) | (argv[i + 1] << 8) | argv[i + 2]); + i += 2; + } else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) + && argv[i + 1] == 5) { + // ESC[ ... 48;5; ... m -or- ESC[ ... 38;5; ... m + i += 2; + processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_256, argv[i]); + } else + processToken(TY_CSI_PS(cc, argv[i]), 0, 0); } - else - processToken( TY_CSI_PS(cc,argv[i]), 0, 0); - } - resetTokenizer(); - } - else - { - // VT52 Mode - if (lec(1,0,ESC)) - return; - if (les(1,0,CHR)) - { - processToken( TY_CHR(), s[0], 0); resetTokenizer(); - return; - } - if (lec(2,1,'Y')) - return; - if (lec(3,1,'Y')) - return; - if (p < 4) - { - processToken( TY_VT52(s[1] ), 0, 0); + } else { + // VT52 Mode + if (lec(1, 0, ESC)) + return; + if (les(1, 0, CHR)) { + processToken(TY_CHR(), s[0], 0); + resetTokenizer(); + return; + } + if (lec(2, 1, 'Y')) + return; + if (lec(3, 1, 'Y')) + return; + if (p < 4) { + processToken(TY_VT52(s[1]), 0, 0); + resetTokenizer(); + return; + } + processToken(TY_VT52(s[1]), s[2], s[3]); resetTokenizer(); return; } - processToken( TY_VT52(s[1]), s[2], s[3]); - resetTokenizer(); - return; - } } void Vt102Emulation::processWindowAttributeChange() { - // Describes the window or terminal session attribute to change - // See Session::UserTitleChange for possible values - int attributeToChange = 0; - int i; - for (i = 2; i < tokenBufferPos && - tokenBuffer[i] >= '0' && - tokenBuffer[i] <= '9'; i++) - { - attributeToChange = 10 * attributeToChange + (tokenBuffer[i]-'0'); - } - - if (tokenBuffer[i] != ';') - { - reportDecodingError(); - return; - } - - // copy from the first char after ';', and skipping the ending delimiter - // 0x07 or 0x92. Note that as control characters in OSC text parts are - // ignored, only the second char in ST ("\e\\") is appended to tokenBuffer. - QString newValue = QString::fromWCharArray(tokenBuffer + i + 1, tokenBufferPos-i-2); - - _pendingTitleUpdates[attributeToChange] = newValue; - _titleUpdateTimer->start(20); + // Describes the window or terminal session attribute to change + // See Session::UserTitleChange for possible values + int attributeToChange = 0; + int i; + for (i = 2; i < tokenBufferPos && tokenBuffer[i] >= '0' && tokenBuffer[i] <= '9'; i++) { + attributeToChange = 10 * attributeToChange + (tokenBuffer[i] - '0'); + } + + if (tokenBuffer[i] != ';') { + reportDecodingError(); + return; + } + + // copy from the first char after ';', and skipping the ending delimiter + // 0x07 or 0x92. Note that as control characters in OSC text parts are + // ignored, only the second char in ST ("\e\\") is appended to tokenBuffer. + QString newValue = QString::fromWCharArray(tokenBuffer + i + 1, tokenBufferPos - i - 2); + + _pendingTitleUpdates[attributeToChange] = newValue; + _titleUpdateTimer->start(20); } void Vt102Emulation::updateTitle() { - QListIterator iter( _pendingTitleUpdates.keys() ); + QListIterator iter(_pendingTitleUpdates.keys()); while (iter.hasNext()) { int arg = iter.next(); - emit titleChanged( arg , _pendingTitleUpdates[arg] ); + emit titleChanged(arg, _pendingTitleUpdates[arg]); } _pendingTitleUpdates.clear(); } @@ -454,479 +494,997 @@ void Vt102Emulation::updateTitle() void Vt102Emulation::processToken(int token, wchar_t p, int q) { - switch (token) - { - - case TY_CHR( ) : _currentScreen->displayCharacter (p ); break; //UTF16 - - // 127 DEL : ignored on input - - case TY_CTL('@' ) : /* NUL: ignored */ break; - case TY_CTL('A' ) : /* SOH: ignored */ break; - case TY_CTL('B' ) : /* STX: ignored */ break; - case TY_CTL('C' ) : /* ETX: ignored */ break; - case TY_CTL('D' ) : /* EOT: ignored */ break; - case TY_CTL('E' ) : reportAnswerBack ( ); break; //VT100 - case TY_CTL('F' ) : /* ACK: ignored */ break; - case TY_CTL('G' ) : emit stateSet(NOTIFYBELL); - break; //VT100 - case TY_CTL('H' ) : _currentScreen->backspace ( ); break; //VT100 - case TY_CTL('I' ) : _currentScreen->tab ( ); break; //VT100 - case TY_CTL('J' ) : _currentScreen->newLine ( ); break; //VT100 - case TY_CTL('K' ) : _currentScreen->newLine ( ); break; //VT100 - case TY_CTL('L' ) : _currentScreen->newLine ( ); break; //VT100 - case TY_CTL('M' ) : _currentScreen->toStartOfLine ( ); break; //VT100 - - case TY_CTL('N' ) : useCharset ( 1); break; //VT100 - case TY_CTL('O' ) : useCharset ( 0); break; //VT100 - - case TY_CTL('P' ) : /* DLE: ignored */ break; - case TY_CTL('Q' ) : /* DC1: XON continue */ break; //VT100 - case TY_CTL('R' ) : /* DC2: ignored */ break; - case TY_CTL('S' ) : /* DC3: XOFF halt */ break; //VT100 - case TY_CTL('T' ) : /* DC4: ignored */ break; - case TY_CTL('U' ) : /* NAK: ignored */ break; - case TY_CTL('V' ) : /* SYN: ignored */ break; - case TY_CTL('W' ) : /* ETB: ignored */ break; - case TY_CTL('X' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100 - case TY_CTL('Y' ) : /* EM : ignored */ break; - case TY_CTL('Z' ) : _currentScreen->displayCharacter ( 0x2592); break; //VT100 - case TY_CTL('[' ) : /* ESC: cannot be seen here. */ break; - case TY_CTL('\\' ) : /* FS : ignored */ break; - case TY_CTL(']' ) : /* GS : ignored */ break; - case TY_CTL('^' ) : /* RS : ignored */ break; - case TY_CTL('_' ) : /* US : ignored */ break; - - case TY_ESC('D' ) : _currentScreen->index ( ); break; //VT100 - case TY_ESC('E' ) : _currentScreen->nextLine ( ); break; //VT100 - case TY_ESC('H' ) : _currentScreen->changeTabStop (true ); break; //VT100 - case TY_ESC('M' ) : _currentScreen->reverseIndex ( ); break; //VT100 - case TY_ESC('Z' ) : reportTerminalType ( ); break; - case TY_ESC('c' ) : reset ( ); break; - - case TY_ESC('n' ) : useCharset ( 2); break; - case TY_ESC('o' ) : useCharset ( 3); break; - case TY_ESC('7' ) : saveCursor ( ); break; - case TY_ESC('8' ) : restoreCursor ( ); break; - - case TY_ESC('=' ) : setMode (MODE_AppKeyPad); break; - case TY_ESC('>' ) : resetMode (MODE_AppKeyPad); break; - case TY_ESC('<' ) : setMode (MODE_Ansi ); break; //VT100 - - case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100 - case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100 - case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100 - - case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100 - case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100 - case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100 - - case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100 - case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100 - case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100 - - case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100 - case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100 - case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100 - - case TY_ESC_CS('%', 'G') : setCodec (Utf8Codec ); break; //LINUX - case TY_ESC_CS('%', '@') : setCodec (LocaleCodec ); break; //LINUX - - case TY_ESC_DE('3' ) : /* Double height line, top half */ - _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true ); - _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true ); - break; - case TY_ESC_DE('4' ) : /* Double height line, bottom half */ - _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true ); - _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true ); - break; - case TY_ESC_DE('5' ) : /* Single width, single height line*/ - _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false); - _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false); - break; - case TY_ESC_DE('6' ) : /* Double width, single height line*/ - _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true); - _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false); - break; - case TY_ESC_DE('8' ) : _currentScreen->helpAlign ( ); break; - -// resize = \e[8;;t - case TY_CSI_PS('t', 8) : setImageSize( p /*lines */, q /* columns */ ); - emit imageResizeRequest(QSize(q, p)); - break; - -// change tab text color : \e[28;t color: 0-16,777,215 - case TY_CSI_PS('t', 28) : emit changeTabTextColorRequest ( p ); break; - - case TY_CSI_PS('K', 0) : _currentScreen->clearToEndOfLine ( ); break; - case TY_CSI_PS('K', 1) : _currentScreen->clearToBeginOfLine ( ); break; - case TY_CSI_PS('K', 2) : _currentScreen->clearEntireLine ( ); break; - case TY_CSI_PS('J', 0) : _currentScreen->clearToEndOfScreen ( ); break; - case TY_CSI_PS('J', 1) : _currentScreen->clearToBeginOfScreen ( ); break; - case TY_CSI_PS('J', 2) : _currentScreen->clearEntireScreen ( ); break; - case TY_CSI_PS('J', 3) : clearHistory(); break; - case TY_CSI_PS('g', 0) : _currentScreen->changeTabStop (false ); break; //VT100 - case TY_CSI_PS('g', 3) : _currentScreen->clearTabStops ( ); break; //VT100 - case TY_CSI_PS('h', 4) : _currentScreen-> setMode (MODE_Insert ); break; - case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break; - case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100 - case TY_CSI_PS('l', 4) : _currentScreen-> resetMode (MODE_Insert ); break; - case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break; - case TY_CSI_PS('s', 0) : saveCursor ( ); break; - case TY_CSI_PS('u', 0) : restoreCursor ( ); break; - - case TY_CSI_PS('m', 0) : _currentScreen->setDefaultRendition ( ); break; - case TY_CSI_PS('m', 1) : _currentScreen-> setRendition (RE_BOLD ); break; //VT100 - case TY_CSI_PS('m', 2) : _currentScreen-> setRendition (RE_FAINT ); break; - case TY_CSI_PS('m', 3) : _currentScreen-> setRendition (RE_ITALIC ); break; //VT100 - case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break; //VT100 - case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break; //VT100 - case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break; - case TY_CSI_PS('m', 8) : _currentScreen-> setRendition (RE_CONCEAL ); break; - case TY_CSI_PS('m', 9) : _currentScreen-> setRendition (RE_STRIKEOUT); break; - case TY_CSI_PS('m', 53) : _currentScreen-> setRendition (RE_OVERLINE ); break; - case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX - case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX - case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX - case TY_CSI_PS('m', 21) : _currentScreen->resetRendition (RE_BOLD ); break; - case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD ); - _currentScreen->resetRendition (RE_FAINT ); break; - case TY_CSI_PS('m', 23) : _currentScreen->resetRendition (RE_ITALIC ); break; //VT100 - case TY_CSI_PS('m', 24) : _currentScreen->resetRendition (RE_UNDERLINE); break; - case TY_CSI_PS('m', 25) : _currentScreen->resetRendition (RE_BLINK ); break; - case TY_CSI_PS('m', 27) : _currentScreen->resetRendition (RE_REVERSE ); break; - case TY_CSI_PS('m', 28) : _currentScreen->resetRendition (RE_CONCEAL ); break; - case TY_CSI_PS('m', 29) : _currentScreen->resetRendition (RE_STRIKEOUT); break; - case TY_CSI_PS('m', 55) : _currentScreen->resetRendition (RE_OVERLINE ); break; - - case TY_CSI_PS('m', 30) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 0); break; - case TY_CSI_PS('m', 31) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 1); break; - case TY_CSI_PS('m', 32) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 2); break; - case TY_CSI_PS('m', 33) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 3); break; - case TY_CSI_PS('m', 34) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 4); break; - case TY_CSI_PS('m', 35) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 5); break; - case TY_CSI_PS('m', 36) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 6); break; - case TY_CSI_PS('m', 37) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 7); break; - - case TY_CSI_PS('m', 38) : _currentScreen->setForeColor (p, q); break; - - case TY_CSI_PS('m', 39) : _currentScreen->setForeColor (COLOR_SPACE_DEFAULT, 0); break; - - case TY_CSI_PS('m', 40) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 0); break; - case TY_CSI_PS('m', 41) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 1); break; - case TY_CSI_PS('m', 42) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 2); break; - case TY_CSI_PS('m', 43) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 3); break; - case TY_CSI_PS('m', 44) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 4); break; - case TY_CSI_PS('m', 45) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 5); break; - case TY_CSI_PS('m', 46) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 6); break; - case TY_CSI_PS('m', 47) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 7); break; - - case TY_CSI_PS('m', 48) : _currentScreen->setBackColor (p, q); break; - - case TY_CSI_PS('m', 49) : _currentScreen->setBackColor (COLOR_SPACE_DEFAULT, 1); break; - - case TY_CSI_PS('m', 90) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 8); break; - case TY_CSI_PS('m', 91) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 9); break; - case TY_CSI_PS('m', 92) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 10); break; - case TY_CSI_PS('m', 93) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 11); break; - case TY_CSI_PS('m', 94) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 12); break; - case TY_CSI_PS('m', 95) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 13); break; - case TY_CSI_PS('m', 96) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 14); break; - case TY_CSI_PS('m', 97) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 15); break; - - case TY_CSI_PS('m', 100) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 8); break; - case TY_CSI_PS('m', 101) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 9); break; - case TY_CSI_PS('m', 102) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 10); break; - case TY_CSI_PS('m', 103) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 11); break; - case TY_CSI_PS('m', 104) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 12); break; - case TY_CSI_PS('m', 105) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 13); break; - case TY_CSI_PS('m', 106) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 14); break; - case TY_CSI_PS('m', 107) : _currentScreen->setBackColor (COLOR_SPACE_SYSTEM, 15); break; - - case TY_CSI_PS('n', 5) : reportStatus ( ); break; - case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break; - case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100 - case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100 - case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100 - case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100 - case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100 - case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100 - case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100 - - case TY_CSI_PS_SP('q', 0) : /* fall through */ - case TY_CSI_PS_SP('q', 1) : emit cursorChanged(KeyboardCursorShape::BlockCursor, true ); break; - case TY_CSI_PS_SP('q', 2) : emit cursorChanged(KeyboardCursorShape::BlockCursor, false); break; - case TY_CSI_PS_SP('q', 3) : emit cursorChanged(KeyboardCursorShape::UnderlineCursor, true ); break; - case TY_CSI_PS_SP('q', 4) : emit cursorChanged(KeyboardCursorShape::UnderlineCursor, false); break; - case TY_CSI_PS_SP('q', 5) : emit cursorChanged(KeyboardCursorShape::IBeamCursor, true ); break; - case TY_CSI_PS_SP('q', 6) : emit cursorChanged(KeyboardCursorShape::IBeamCursor, false); break; - - case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break; - case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break; //VT100 - case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break; //VT100 - case TY_CSI_PN('C' ) : _currentScreen->cursorRight (p ); break; //VT100 - case TY_CSI_PN('D' ) : _currentScreen->cursorLeft (p ); break; //VT100 - case TY_CSI_PN('E' ) : _currentScreen->cursorNextLine (p ); break; //VT100 - case TY_CSI_PN('F' ) : _currentScreen->cursorPreviousLine (p ); break; //VT100 - case TY_CSI_PN('G' ) : _currentScreen->setCursorX (p ); break; //LINUX - case TY_CSI_PN('H' ) : _currentScreen->setCursorYX (p, q); break; //VT100 - case TY_CSI_PN('I' ) : _currentScreen->tab (p ); break; - case TY_CSI_PN('L' ) : _currentScreen->insertLines (p ); break; - case TY_CSI_PN('M' ) : _currentScreen->deleteLines (p ); break; - case TY_CSI_PN('P' ) : _currentScreen->deleteChars (p ); break; - case TY_CSI_PN('S' ) : _currentScreen->scrollUp (p ); break; - case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break; - case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break; - case TY_CSI_PN('Z' ) : _currentScreen->backtab (p ); break; - case TY_CSI_PN('b' ) : _currentScreen->repeatChars (p ); break; - case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100 - case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX - case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100 - case TY_CSI_PN('r' ) : setMargins (p, q); break; //VT100 - case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100 - - case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100 - case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100 - case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME - case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME - - case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100 - - case TY_CSI_PR('h', 3) : setMode (MODE_132Columns);break; //VT100 - case TY_CSI_PR('l', 3) : resetMode (MODE_132Columns);break; //VT100 - - case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100 - case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100 - - case TY_CSI_PR('h', 5) : _currentScreen-> setMode (MODE_Screen ); break; //VT100 - case TY_CSI_PR('l', 5) : _currentScreen-> resetMode (MODE_Screen ); break; //VT100 - - case TY_CSI_PR('h', 6) : _currentScreen-> setMode (MODE_Origin ); break; //VT100 - case TY_CSI_PR('l', 6) : _currentScreen-> resetMode (MODE_Origin ); break; //VT100 - case TY_CSI_PR('s', 6) : _currentScreen-> saveMode (MODE_Origin ); break; //FIXME - case TY_CSI_PR('r', 6) : _currentScreen->restoreMode (MODE_Origin ); break; //FIXME - - case TY_CSI_PR('h', 7) : _currentScreen-> setMode (MODE_Wrap ); break; //VT100 - case TY_CSI_PR('l', 7) : _currentScreen-> resetMode (MODE_Wrap ); break; //VT100 - case TY_CSI_PR('s', 7) : _currentScreen-> saveMode (MODE_Wrap ); break; //FIXME - case TY_CSI_PR('r', 7) : _currentScreen->restoreMode (MODE_Wrap ); break; //FIXME - - case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100 - case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100 - case TY_CSI_PR('s', 8) : /* IGNORED: autorepeat on */ break; //VT100 - case TY_CSI_PR('r', 8) : /* IGNORED: autorepeat off */ break; //VT100 - - case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100 - case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100 - case TY_CSI_PR('s', 9) : /* IGNORED: interlace */ break; //VT100 - case TY_CSI_PR('r', 9) : /* IGNORED: interlace */ break; //VT100 - - case TY_CSI_PR('h', 12) : /* IGNORED: Cursor blink */ break; //att610 - case TY_CSI_PR('l', 12) : /* IGNORED: Cursor blink */ break; //att610 - case TY_CSI_PR('s', 12) : /* IGNORED: Cursor blink */ break; //att610 - case TY_CSI_PR('r', 12) : /* IGNORED: Cursor blink */ break; //att610 - - case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100 - case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100 - case TY_CSI_PR('s', 25) : saveMode (MODE_Cursor ); break; //VT100 - case TY_CSI_PR('r', 25) : restoreMode (MODE_Cursor ); break; //VT100 - - case TY_CSI_PR('h', 40) : setMode(MODE_Allow132Columns ); break; // XTERM - case TY_CSI_PR('l', 40) : resetMode(MODE_Allow132Columns ); break; // XTERM - - case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM - case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM - case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM - case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM - - case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100 - case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100 - case TY_CSI_PR('s', 47) : saveMode (MODE_AppScreen); break; //XTERM - case TY_CSI_PR('r', 47) : restoreMode (MODE_AppScreen); break; //XTERM - - case TY_CSI_PR('h', 67) : /* IGNORED: DECBKM */ break; //XTERM - case TY_CSI_PR('l', 67) : /* IGNORED: DECBKM */ break; //XTERM - case TY_CSI_PR('s', 67) : /* IGNORED: DECBKM */ break; //XTERM - case TY_CSI_PR('r', 67) : /* IGNORED: DECBKM */ break; //XTERM - - // XTerm defines the following modes: - // SET_VT200_MOUSE 1000 - // SET_VT200_HIGHLIGHT_MOUSE 1001 - // SET_BTN_EVENT_MOUSE 1002 - // SET_ANY_EVENT_MOUSE 1003 - // - - //Note about mouse modes: - //There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003 - //Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse). - //TODO: Implementation of mouse modes 1001 (something called hilight tracking) and - //1003 (a slight variation on dragging the mouse) - // - - case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM - case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM - case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM - case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM - - case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM - case TY_CSI_PR('l', 1001) : resetMode (MODE_Mouse1001); break; //XTERM - case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM - case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM - - case TY_CSI_PR('h', 1002) : setMode (MODE_Mouse1002); break; //XTERM - case TY_CSI_PR('l', 1002) : resetMode (MODE_Mouse1002); break; //XTERM - case TY_CSI_PR('s', 1002) : saveMode (MODE_Mouse1002); break; //XTERM - case TY_CSI_PR('r', 1002) : restoreMode (MODE_Mouse1002); break; //XTERM - - case TY_CSI_PR('h', 1003) : setMode (MODE_Mouse1003); break; //XTERM - case TY_CSI_PR('l', 1003) : resetMode (MODE_Mouse1003); break; //XTERM - case TY_CSI_PR('s', 1003) : saveMode (MODE_Mouse1003); break; //XTERM - case TY_CSI_PR('r', 1003) : restoreMode (MODE_Mouse1003); break; //XTERM - - case TY_CSI_PR('h', 1004) : _reportFocusEvents = true; break; - case TY_CSI_PR('l', 1004) : _reportFocusEvents = false; break; - - case TY_CSI_PR('h', 1005) : setMode (MODE_Mouse1005); break; //XTERM - case TY_CSI_PR('l', 1005) : resetMode (MODE_Mouse1005); break; //XTERM - case TY_CSI_PR('s', 1005) : saveMode (MODE_Mouse1005); break; //XTERM - case TY_CSI_PR('r', 1005) : restoreMode (MODE_Mouse1005); break; //XTERM - - case TY_CSI_PR('h', 1006) : setMode (MODE_Mouse1006); break; //XTERM - case TY_CSI_PR('l', 1006) : resetMode (MODE_Mouse1006); break; //XTERM - case TY_CSI_PR('s', 1006) : saveMode (MODE_Mouse1006); break; //XTERM - case TY_CSI_PR('r', 1006) : restoreMode (MODE_Mouse1006); break; //XTERM - - case TY_CSI_PR('h', 1015) : setMode (MODE_Mouse1015); break; //URXVT - case TY_CSI_PR('l', 1015) : resetMode (MODE_Mouse1015); break; //URXVT - case TY_CSI_PR('s', 1015) : saveMode (MODE_Mouse1015); break; //URXVT - case TY_CSI_PR('r', 1015) : restoreMode (MODE_Mouse1015); break; //URXVT - - case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation */ break; //XTERM - - case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM - case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM - case TY_CSI_PR('s', 1047) : saveMode (MODE_AppScreen); break; //XTERM - case TY_CSI_PR('r', 1047) : restoreMode (MODE_AppScreen); break; //XTERM - - //FIXME: Unitoken: save translations - case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM - case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM - case TY_CSI_PR('s', 1048) : saveCursor ( ); break; //XTERM - case TY_CSI_PR('r', 1048) : restoreCursor ( ); break; //XTERM - - //FIXME: every once new sequences like this pop up in xterm. + switch (token) { + + case TY_CHR(): + _currentScreen->displayCharacter(p); + break; // UTF16 + + // 127 DEL : ignored on input + + case TY_CTL('@'): /* NUL: ignored */ + break; + case TY_CTL('A'): /* SOH: ignored */ + break; + case TY_CTL('B'): /* STX: ignored */ + break; + case TY_CTL('C'): /* ETX: ignored */ + break; + case TY_CTL('D'): /* EOT: ignored */ + break; + case TY_CTL('E'): + reportAnswerBack(); + break; // VT100 + case TY_CTL('F'): /* ACK: ignored */ + break; + case TY_CTL('G'): + emit stateSet(NOTIFYBELL); + break; // VT100 + case TY_CTL('H'): + _currentScreen->backspace(); + break; // VT100 + case TY_CTL('I'): + _currentScreen->tab(); + break; // VT100 + case TY_CTL('J'): + _currentScreen->newLine(); + break; // VT100 + case TY_CTL('K'): + _currentScreen->newLine(); + break; // VT100 + case TY_CTL('L'): + _currentScreen->newLine(); + break; // VT100 + case TY_CTL('M'): + _currentScreen->toStartOfLine(); + break; // VT100 + + case TY_CTL('N'): + useCharset(1); + break; // VT100 + case TY_CTL('O'): + useCharset(0); + break; // VT100 + + case TY_CTL('P'): /* DLE: ignored */ + break; + case TY_CTL('Q'): /* DC1: XON continue */ + break; // VT100 + case TY_CTL('R'): /* DC2: ignored */ + break; + case TY_CTL('S'): /* DC3: XOFF halt */ + break; // VT100 + case TY_CTL('T'): /* DC4: ignored */ + break; + case TY_CTL('U'): /* NAK: ignored */ + break; + case TY_CTL('V'): /* SYN: ignored */ + break; + case TY_CTL('W'): /* ETB: ignored */ + break; + case TY_CTL('X'): + _currentScreen->displayCharacter(0x2592); + break; // VT100 + case TY_CTL('Y'): /* EM : ignored */ + break; + case TY_CTL('Z'): + _currentScreen->displayCharacter(0x2592); + break; // VT100 + case TY_CTL('['): /* ESC: cannot be seen here. */ + break; + case TY_CTL('\\'): /* FS : ignored */ + break; + case TY_CTL(']'): /* GS : ignored */ + break; + case TY_CTL('^'): /* RS : ignored */ + break; + case TY_CTL('_'): /* US : ignored */ + break; + + case TY_ESC('D'): + _currentScreen->index(); + break; // VT100 + case TY_ESC('E'): + _currentScreen->nextLine(); + break; // VT100 + case TY_ESC('H'): + _currentScreen->changeTabStop(true); + break; // VT100 + case TY_ESC('M'): + _currentScreen->reverseIndex(); + break; // VT100 + case TY_ESC('Z'): + reportTerminalType(); + break; + case TY_ESC('c'): + reset(); + break; + + case TY_ESC('n'): + useCharset(2); + break; + case TY_ESC('o'): + useCharset(3); + break; + case TY_ESC('7'): + saveCursor(); + break; + case TY_ESC('8'): + restoreCursor(); + break; + + case TY_ESC('='): + setMode(MODE_AppKeyPad); + break; + case TY_ESC('>'): + resetMode(MODE_AppKeyPad); + break; + case TY_ESC('<'): + setMode(MODE_Ansi); + break; // VT100 + + case TY_ESC_CS('(', '0'): + setCharset(0, '0'); + break; // VT100 + case TY_ESC_CS('(', 'A'): + setCharset(0, 'A'); + break; // VT100 + case TY_ESC_CS('(', 'B'): + setCharset(0, 'B'); + break; // VT100 + + case TY_ESC_CS(')', '0'): + setCharset(1, '0'); + break; // VT100 + case TY_ESC_CS(')', 'A'): + setCharset(1, 'A'); + break; // VT100 + case TY_ESC_CS(')', 'B'): + setCharset(1, 'B'); + break; // VT100 + + case TY_ESC_CS('*', '0'): + setCharset(2, '0'); + break; // VT100 + case TY_ESC_CS('*', 'A'): + setCharset(2, 'A'); + break; // VT100 + case TY_ESC_CS('*', 'B'): + setCharset(2, 'B'); + break; // VT100 + + case TY_ESC_CS('+', '0'): + setCharset(3, '0'); + break; // VT100 + case TY_ESC_CS('+', 'A'): + setCharset(3, 'A'); + break; // VT100 + case TY_ESC_CS('+', 'B'): + setCharset(3, 'B'); + break; // VT100 + + case TY_ESC_CS('%', 'G'): + setCodec(Utf8Codec); + break; // LINUX + case TY_ESC_CS('%', '@'): + setCodec(LocaleCodec); + break; // LINUX + + case TY_ESC_DE('3'): /* Double height line, top half */ + _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); + _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, true); + break; + case TY_ESC_DE('4'): /* Double height line, bottom half */ + _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); + _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, true); + break; + case TY_ESC_DE('5'): /* Single width, single height line*/ + _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, false); + _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, false); + break; + case TY_ESC_DE('6'): /* Double width, single height line*/ + _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true); + _currentScreen->setLineProperty(LINE_DOUBLEHEIGHT, false); + break; + case TY_ESC_DE('8'): + _currentScreen->helpAlign(); + break; + + // resize = \e[8;;t + case TY_CSI_PS('t', 8): + setImageSize(p /*lines */, q /* columns */); + emit imageResizeRequest(QSize(q, p)); + break; + + // change tab text color : \e[28;t color: 0-16,777,215 + case TY_CSI_PS('t', 28): + emit changeTabTextColorRequest(p); + break; + + case TY_CSI_PS('K', 0): + _currentScreen->clearToEndOfLine(); + break; + case TY_CSI_PS('K', 1): + _currentScreen->clearToBeginOfLine(); + break; + case TY_CSI_PS('K', 2): + _currentScreen->clearEntireLine(); + break; + case TY_CSI_PS('J', 0): + _currentScreen->clearToEndOfScreen(); + break; + case TY_CSI_PS('J', 1): + _currentScreen->clearToBeginOfScreen(); + break; + case TY_CSI_PS('J', 2): + _currentScreen->clearEntireScreen(); + break; + case TY_CSI_PS('J', 3): + clearHistory(); + break; + case TY_CSI_PS('g', 0): + _currentScreen->changeTabStop(false); + break; // VT100 + case TY_CSI_PS('g', 3): + _currentScreen->clearTabStops(); + break; // VT100 + case TY_CSI_PS('h', 4): + _currentScreen->setMode(MODE_Insert); + break; + case TY_CSI_PS('h', 20): + setMode(MODE_NewLine); + break; + case TY_CSI_PS('i', 0): /* IGNORE: attached printer */ + break; // VT100 + case TY_CSI_PS('l', 4): + _currentScreen->resetMode(MODE_Insert); + break; + case TY_CSI_PS('l', 20): + resetMode(MODE_NewLine); + break; + case TY_CSI_PS('s', 0): + saveCursor(); + break; + case TY_CSI_PS('u', 0): + restoreCursor(); + break; + + case TY_CSI_PS('m', 0): + _currentScreen->setDefaultRendition(); + break; + case TY_CSI_PS('m', 1): + _currentScreen->setRendition(RE_BOLD); + break; // VT100 + case TY_CSI_PS('m', 2): + _currentScreen->setRendition(RE_FAINT); + break; + case TY_CSI_PS('m', 3): + _currentScreen->setRendition(RE_ITALIC); + break; // VT100 + case TY_CSI_PS('m', 4): + _currentScreen->setRendition(RE_UNDERLINE); + break; // VT100 + case TY_CSI_PS('m', 5): + _currentScreen->setRendition(RE_BLINK); + break; // VT100 + case TY_CSI_PS('m', 7): + _currentScreen->setRendition(RE_REVERSE); + break; + case TY_CSI_PS('m', 8): + _currentScreen->setRendition(RE_CONCEAL); + break; + case TY_CSI_PS('m', 9): + _currentScreen->setRendition(RE_STRIKEOUT); + break; + case TY_CSI_PS('m', 53): + _currentScreen->setRendition(RE_OVERLINE); + break; + case TY_CSI_PS('m', 10): /* IGNORED: mapping related */ + break; // LINUX + case TY_CSI_PS('m', 11): /* IGNORED: mapping related */ + break; // LINUX + case TY_CSI_PS('m', 12): /* IGNORED: mapping related */ + break; // LINUX + case TY_CSI_PS('m', 21): + _currentScreen->resetRendition(RE_BOLD); + break; + case TY_CSI_PS('m', 22): + _currentScreen->resetRendition(RE_BOLD); + _currentScreen->resetRendition(RE_FAINT); + break; + case TY_CSI_PS('m', 23): + _currentScreen->resetRendition(RE_ITALIC); + break; // VT100 + case TY_CSI_PS('m', 24): + _currentScreen->resetRendition(RE_UNDERLINE); + break; + case TY_CSI_PS('m', 25): + _currentScreen->resetRendition(RE_BLINK); + break; + case TY_CSI_PS('m', 27): + _currentScreen->resetRendition(RE_REVERSE); + break; + case TY_CSI_PS('m', 28): + _currentScreen->resetRendition(RE_CONCEAL); + break; + case TY_CSI_PS('m', 29): + _currentScreen->resetRendition(RE_STRIKEOUT); + break; + case TY_CSI_PS('m', 55): + _currentScreen->resetRendition(RE_OVERLINE); + break; + + case TY_CSI_PS('m', 30): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 0); + break; + case TY_CSI_PS('m', 31): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 1); + break; + case TY_CSI_PS('m', 32): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 2); + break; + case TY_CSI_PS('m', 33): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 3); + break; + case TY_CSI_PS('m', 34): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 4); + break; + case TY_CSI_PS('m', 35): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 5); + break; + case TY_CSI_PS('m', 36): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 6); + break; + case TY_CSI_PS('m', 37): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 7); + break; + + case TY_CSI_PS('m', 38): + _currentScreen->setForeColor(p, q); + break; + + case TY_CSI_PS('m', 39): + _currentScreen->setForeColor(COLOR_SPACE_DEFAULT, 0); + break; + + case TY_CSI_PS('m', 40): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 0); + break; + case TY_CSI_PS('m', 41): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 1); + break; + case TY_CSI_PS('m', 42): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 2); + break; + case TY_CSI_PS('m', 43): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 3); + break; + case TY_CSI_PS('m', 44): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 4); + break; + case TY_CSI_PS('m', 45): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 5); + break; + case TY_CSI_PS('m', 46): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 6); + break; + case TY_CSI_PS('m', 47): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 7); + break; + + case TY_CSI_PS('m', 48): + _currentScreen->setBackColor(p, q); + break; + + case TY_CSI_PS('m', 49): + _currentScreen->setBackColor(COLOR_SPACE_DEFAULT, 1); + break; + + case TY_CSI_PS('m', 90): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 8); + break; + case TY_CSI_PS('m', 91): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 9); + break; + case TY_CSI_PS('m', 92): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 10); + break; + case TY_CSI_PS('m', 93): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 11); + break; + case TY_CSI_PS('m', 94): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 12); + break; + case TY_CSI_PS('m', 95): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 13); + break; + case TY_CSI_PS('m', 96): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 14); + break; + case TY_CSI_PS('m', 97): + _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 15); + break; + + case TY_CSI_PS('m', 100): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 8); + break; + case TY_CSI_PS('m', 101): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 9); + break; + case TY_CSI_PS('m', 102): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 10); + break; + case TY_CSI_PS('m', 103): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 11); + break; + case TY_CSI_PS('m', 104): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 12); + break; + case TY_CSI_PS('m', 105): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 13); + break; + case TY_CSI_PS('m', 106): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 14); + break; + case TY_CSI_PS('m', 107): + _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 15); + break; + + case TY_CSI_PS('n', 5): + reportStatus(); + break; + case TY_CSI_PS('n', 6): + reportCursorPosition(); + break; + case TY_CSI_PS('q', 0): /* IGNORED: LEDs off */ + break; // VT100 + case TY_CSI_PS('q', 1): /* IGNORED: LED1 on */ + break; // VT100 + case TY_CSI_PS('q', 2): /* IGNORED: LED2 on */ + break; // VT100 + case TY_CSI_PS('q', 3): /* IGNORED: LED3 on */ + break; // VT100 + case TY_CSI_PS('q', 4): /* IGNORED: LED4 on */ + break; // VT100 + case TY_CSI_PS('x', 0): + reportTerminalParms(2); + break; // VT100 + case TY_CSI_PS('x', 1): + reportTerminalParms(3); + break; // VT100 + + case TY_CSI_PS_SP('q', 0): /* fall through */ + case TY_CSI_PS_SP('q', 1): + emit cursorChanged(KeyboardCursorShape::BlockCursor, true); + break; + case TY_CSI_PS_SP('q', 2): + emit cursorChanged(KeyboardCursorShape::BlockCursor, false); + break; + case TY_CSI_PS_SP('q', 3): + emit cursorChanged(KeyboardCursorShape::UnderlineCursor, true); + break; + case TY_CSI_PS_SP('q', 4): + emit cursorChanged(KeyboardCursorShape::UnderlineCursor, false); + break; + case TY_CSI_PS_SP('q', 5): + emit cursorChanged(KeyboardCursorShape::IBeamCursor, true); + break; + case TY_CSI_PS_SP('q', 6): + emit cursorChanged(KeyboardCursorShape::IBeamCursor, false); + break; + + case TY_CSI_PN('@'): + _currentScreen->insertChars(p); + break; + case TY_CSI_PN('A'): + _currentScreen->cursorUp(p); + break; // VT100 + case TY_CSI_PN('B'): + _currentScreen->cursorDown(p); + break; // VT100 + case TY_CSI_PN('C'): + _currentScreen->cursorRight(p); + break; // VT100 + case TY_CSI_PN('D'): + _currentScreen->cursorLeft(p); + break; // VT100 + case TY_CSI_PN('E'): + _currentScreen->cursorNextLine(p); + break; // VT100 + case TY_CSI_PN('F'): + _currentScreen->cursorPreviousLine(p); + break; // VT100 + case TY_CSI_PN('G'): + _currentScreen->setCursorX(p); + break; // LINUX + case TY_CSI_PN('H'): + _currentScreen->setCursorYX(p, q); + break; // VT100 + case TY_CSI_PN('I'): + _currentScreen->tab(p); + break; + case TY_CSI_PN('L'): + _currentScreen->insertLines(p); + break; + case TY_CSI_PN('M'): + _currentScreen->deleteLines(p); + break; + case TY_CSI_PN('P'): + _currentScreen->deleteChars(p); + break; + case TY_CSI_PN('S'): + _currentScreen->scrollUp(p); + break; + case TY_CSI_PN('T'): + _currentScreen->scrollDown(p); + break; + case TY_CSI_PN('X'): + _currentScreen->eraseChars(p); + break; + case TY_CSI_PN('Z'): + _currentScreen->backtab(p); + break; + case TY_CSI_PN('b'): + _currentScreen->repeatChars(p); + break; + case TY_CSI_PN('c'): + reportTerminalType(); + break; // VT100 + case TY_CSI_PN('d'): + _currentScreen->setCursorY(p); + break; // LINUX + case TY_CSI_PN('f'): + _currentScreen->setCursorYX(p, q); + break; // VT100 + case TY_CSI_PN('r'): + setMargins(p, q); + break; // VT100 + case TY_CSI_PN('y'): /* IGNORED: Confidence test */ + break; // VT100 + + case TY_CSI_PR('h', 1): + setMode(MODE_AppCuKeys); + break; // VT100 + case TY_CSI_PR('l', 1): + resetMode(MODE_AppCuKeys); + break; // VT100 + case TY_CSI_PR('s', 1): + saveMode(MODE_AppCuKeys); + break; // FIXME + case TY_CSI_PR('r', 1): + restoreMode(MODE_AppCuKeys); + break; // FIXME + + case TY_CSI_PR('l', 2): + resetMode(MODE_Ansi); + break; // VT100 + + case TY_CSI_PR('h', 3): + setMode(MODE_132Columns); + break; // VT100 + case TY_CSI_PR('l', 3): + resetMode(MODE_132Columns); + break; // VT100 + + case TY_CSI_PR('h', 4): /* IGNORED: soft scrolling */ + break; // VT100 + case TY_CSI_PR('l', 4): /* IGNORED: soft scrolling */ + break; // VT100 + + case TY_CSI_PR('h', 5): + _currentScreen->setMode(MODE_Screen); + break; // VT100 + case TY_CSI_PR('l', 5): + _currentScreen->resetMode(MODE_Screen); + break; // VT100 + + case TY_CSI_PR('h', 6): + _currentScreen->setMode(MODE_Origin); + break; // VT100 + case TY_CSI_PR('l', 6): + _currentScreen->resetMode(MODE_Origin); + break; // VT100 + case TY_CSI_PR('s', 6): + _currentScreen->saveMode(MODE_Origin); + break; // FIXME + case TY_CSI_PR('r', 6): + _currentScreen->restoreMode(MODE_Origin); + break; // FIXME + + case TY_CSI_PR('h', 7): + _currentScreen->setMode(MODE_Wrap); + break; // VT100 + case TY_CSI_PR('l', 7): + _currentScreen->resetMode(MODE_Wrap); + break; // VT100 + case TY_CSI_PR('s', 7): + _currentScreen->saveMode(MODE_Wrap); + break; // FIXME + case TY_CSI_PR('r', 7): + _currentScreen->restoreMode(MODE_Wrap); + break; // FIXME + + case TY_CSI_PR('h', 8): /* IGNORED: autorepeat on */ + break; // VT100 + case TY_CSI_PR('l', 8): /* IGNORED: autorepeat off */ + break; // VT100 + case TY_CSI_PR('s', 8): /* IGNORED: autorepeat on */ + break; // VT100 + case TY_CSI_PR('r', 8): /* IGNORED: autorepeat off */ + break; // VT100 + + case TY_CSI_PR('h', 9): /* IGNORED: interlace */ + break; // VT100 + case TY_CSI_PR('l', 9): /* IGNORED: interlace */ + break; // VT100 + case TY_CSI_PR('s', 9): /* IGNORED: interlace */ + break; // VT100 + case TY_CSI_PR('r', 9): /* IGNORED: interlace */ + break; // VT100 + + case TY_CSI_PR('h', 12): /* IGNORED: Cursor blink */ + break; // att610 + case TY_CSI_PR('l', 12): /* IGNORED: Cursor blink */ + break; // att610 + case TY_CSI_PR('s', 12): /* IGNORED: Cursor blink */ + break; // att610 + case TY_CSI_PR('r', 12): /* IGNORED: Cursor blink */ + break; // att610 + + case TY_CSI_PR('h', 25): + setMode(MODE_Cursor); + break; // VT100 + case TY_CSI_PR('l', 25): + resetMode(MODE_Cursor); + break; // VT100 + case TY_CSI_PR('s', 25): + saveMode(MODE_Cursor); + break; // VT100 + case TY_CSI_PR('r', 25): + restoreMode(MODE_Cursor); + break; // VT100 + + case TY_CSI_PR('h', 40): + setMode(MODE_Allow132Columns); + break; // XTERM + case TY_CSI_PR('l', 40): + resetMode(MODE_Allow132Columns); + break; // XTERM + + case TY_CSI_PR('h', 41): /* IGNORED: obsolete more(1) fix */ + break; // XTERM + case TY_CSI_PR('l', 41): /* IGNORED: obsolete more(1) fix */ + break; // XTERM + case TY_CSI_PR('s', 41): /* IGNORED: obsolete more(1) fix */ + break; // XTERM + case TY_CSI_PR('r', 41): /* IGNORED: obsolete more(1) fix */ + break; // XTERM + + case TY_CSI_PR('h', 47): + setMode(MODE_AppScreen); + break; // VT100 + case TY_CSI_PR('l', 47): + resetMode(MODE_AppScreen); + break; // VT100 + case TY_CSI_PR('s', 47): + saveMode(MODE_AppScreen); + break; // XTERM + case TY_CSI_PR('r', 47): + restoreMode(MODE_AppScreen); + break; // XTERM + + case TY_CSI_PR('h', 67): /* IGNORED: DECBKM */ + break; // XTERM + case TY_CSI_PR('l', 67): /* IGNORED: DECBKM */ + break; // XTERM + case TY_CSI_PR('s', 67): /* IGNORED: DECBKM */ + break; // XTERM + case TY_CSI_PR('r', 67): /* IGNORED: DECBKM */ + break; // XTERM + + // XTerm defines the following modes: + // SET_VT200_MOUSE 1000 + // SET_VT200_HIGHLIGHT_MOUSE 1001 + // SET_BTN_EVENT_MOUSE 1002 + // SET_ANY_EVENT_MOUSE 1003 + // + + // Note about mouse modes: + // There are four mouse modes which xterm-compatible terminals can support - + // 1000,1001,1002,1003 Konsole currently supports mode 1000 (basic mouse press and release) + // and mode 1002 (dragging the mouse). + // TODO: Implementation of mouse modes 1001 (something called hilight tracking) and + // 1003 (a slight variation on dragging the mouse) + // + + case TY_CSI_PR('h', 1000): + setMode(MODE_Mouse1000); + break; // XTERM + case TY_CSI_PR('l', 1000): + resetMode(MODE_Mouse1000); + break; // XTERM + case TY_CSI_PR('s', 1000): + saveMode(MODE_Mouse1000); + break; // XTERM + case TY_CSI_PR('r', 1000): + restoreMode(MODE_Mouse1000); + break; // XTERM + + case TY_CSI_PR('h', 1001): /* IGNORED: hilite mouse tracking */ + break; // XTERM + case TY_CSI_PR('l', 1001): + resetMode(MODE_Mouse1001); + break; // XTERM + case TY_CSI_PR('s', 1001): /* IGNORED: hilite mouse tracking */ + break; // XTERM + case TY_CSI_PR('r', 1001): /* IGNORED: hilite mouse tracking */ + break; // XTERM + + case TY_CSI_PR('h', 1002): + setMode(MODE_Mouse1002); + break; // XTERM + case TY_CSI_PR('l', 1002): + resetMode(MODE_Mouse1002); + break; // XTERM + case TY_CSI_PR('s', 1002): + saveMode(MODE_Mouse1002); + break; // XTERM + case TY_CSI_PR('r', 1002): + restoreMode(MODE_Mouse1002); + break; // XTERM + + case TY_CSI_PR('h', 1003): + setMode(MODE_Mouse1003); + break; // XTERM + case TY_CSI_PR('l', 1003): + resetMode(MODE_Mouse1003); + break; // XTERM + case TY_CSI_PR('s', 1003): + saveMode(MODE_Mouse1003); + break; // XTERM + case TY_CSI_PR('r', 1003): + restoreMode(MODE_Mouse1003); + break; // XTERM + + case TY_CSI_PR('h', 1004): + _reportFocusEvents = true; + break; + case TY_CSI_PR('l', 1004): + _reportFocusEvents = false; + break; + + case TY_CSI_PR('h', 1005): + setMode(MODE_Mouse1005); + break; // XTERM + case TY_CSI_PR('l', 1005): + resetMode(MODE_Mouse1005); + break; // XTERM + case TY_CSI_PR('s', 1005): + saveMode(MODE_Mouse1005); + break; // XTERM + case TY_CSI_PR('r', 1005): + restoreMode(MODE_Mouse1005); + break; // XTERM + + case TY_CSI_PR('h', 1006): + setMode(MODE_Mouse1006); + break; // XTERM + case TY_CSI_PR('l', 1006): + resetMode(MODE_Mouse1006); + break; // XTERM + case TY_CSI_PR('s', 1006): + saveMode(MODE_Mouse1006); + break; // XTERM + case TY_CSI_PR('r', 1006): + restoreMode(MODE_Mouse1006); + break; // XTERM + + case TY_CSI_PR('h', 1015): + setMode(MODE_Mouse1015); + break; // URXVT + case TY_CSI_PR('l', 1015): + resetMode(MODE_Mouse1015); + break; // URXVT + case TY_CSI_PR('s', 1015): + saveMode(MODE_Mouse1015); + break; // URXVT + case TY_CSI_PR('r', 1015): + restoreMode(MODE_Mouse1015); + break; // URXVT + + case TY_CSI_PR('h', 1034): /* IGNORED: 8bitinput activation */ + break; // XTERM + + case TY_CSI_PR('h', 1047): + setMode(MODE_AppScreen); + break; // XTERM + case TY_CSI_PR('l', 1047): + _screen[1]->clearEntireScreen(); + resetMode(MODE_AppScreen); + break; // XTERM + case TY_CSI_PR('s', 1047): + saveMode(MODE_AppScreen); + break; // XTERM + case TY_CSI_PR('r', 1047): + restoreMode(MODE_AppScreen); + break; // XTERM + + // FIXME: Unitoken: save translations + case TY_CSI_PR('h', 1048): + saveCursor(); + break; // XTERM + case TY_CSI_PR('l', 1048): + restoreCursor(); + break; // XTERM + case TY_CSI_PR('s', 1048): + saveCursor(); + break; // XTERM + case TY_CSI_PR('r', 1048): + restoreCursor(); + break; // XTERM + + // FIXME: every once new sequences like this pop up in xterm. // Here's a guess of what they could mean. - case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM - case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM - - case TY_CSI_PR('h', 2004) : setMode (MODE_BracketedPaste); break; //XTERM - case TY_CSI_PR('l', 2004) : resetMode (MODE_BracketedPaste); break; //XTERM - case TY_CSI_PR('s', 2004) : saveMode (MODE_BracketedPaste); break; //XTERM - case TY_CSI_PR('r', 2004) : restoreMode (MODE_BracketedPaste); break; //XTERM - - //FIXME: weird DEC reset sequence - case TY_CSI_PE('p' ) : /* IGNORED: reset ( ) */ break; - - //FIXME: when changing between vt52 and ansi mode evtl do some resetting. - case TY_VT52('A' ) : _currentScreen->cursorUp ( 1); break; //VT52 - case TY_VT52('B' ) : _currentScreen->cursorDown ( 1); break; //VT52 - case TY_VT52('C' ) : _currentScreen->cursorRight ( 1); break; //VT52 - case TY_VT52('D' ) : _currentScreen->cursorLeft ( 1); break; //VT52 - - case TY_VT52('F' ) : setAndUseCharset (0, '0'); break; //VT52 - case TY_VT52('G' ) : setAndUseCharset (0, 'B'); break; //VT52 - - case TY_VT52('H' ) : _currentScreen->setCursorYX (1,1 ); break; //VT52 - case TY_VT52('I' ) : _currentScreen->reverseIndex ( ); break; //VT52 - case TY_VT52('J' ) : _currentScreen->clearToEndOfScreen ( ); break; //VT52 - case TY_VT52('K' ) : _currentScreen->clearToEndOfLine ( ); break; //VT52 - case TY_VT52('Y' ) : _currentScreen->setCursorYX (p-31,q-31 ); break; //VT52 - case TY_VT52('Z' ) : reportTerminalType ( ); break; //VT52 - case TY_VT52('<' ) : setMode (MODE_Ansi ); break; //VT52 - case TY_VT52('=' ) : setMode (MODE_AppKeyPad); break; //VT52 - case TY_VT52('>' ) : resetMode (MODE_AppKeyPad); break; //VT52 - - case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break; //VT100 + case TY_CSI_PR('h', 1049): + saveCursor(); + _screen[1]->clearEntireScreen(); + setMode(MODE_AppScreen); + break; // XTERM + case TY_CSI_PR('l', 1049): + resetMode(MODE_AppScreen); + restoreCursor(); + break; // XTERM + + case TY_CSI_PR('h', 2004): + setMode(MODE_BracketedPaste); + break; // XTERM + case TY_CSI_PR('l', 2004): + resetMode(MODE_BracketedPaste); + break; // XTERM + case TY_CSI_PR('s', 2004): + saveMode(MODE_BracketedPaste); + break; // XTERM + case TY_CSI_PR('r', 2004): + restoreMode(MODE_BracketedPaste); + break; // XTERM + + // FIXME: weird DEC reset sequence + case TY_CSI_PE('p'): /* IGNORED: reset ( ) */ + break; + + // FIXME: when changing between vt52 and ansi mode evtl do some resetting. + case TY_VT52('A'): + _currentScreen->cursorUp(1); + break; // VT52 + case TY_VT52('B'): + _currentScreen->cursorDown(1); + break; // VT52 + case TY_VT52('C'): + _currentScreen->cursorRight(1); + break; // VT52 + case TY_VT52('D'): + _currentScreen->cursorLeft(1); + break; // VT52 + + case TY_VT52('F'): + setAndUseCharset(0, '0'); + break; // VT52 + case TY_VT52('G'): + setAndUseCharset(0, 'B'); + break; // VT52 + + case TY_VT52('H'): + _currentScreen->setCursorYX(1, 1); + break; // VT52 + case TY_VT52('I'): + _currentScreen->reverseIndex(); + break; // VT52 + case TY_VT52('J'): + _currentScreen->clearToEndOfScreen(); + break; // VT52 + case TY_VT52('K'): + _currentScreen->clearToEndOfLine(); + break; // VT52 + case TY_VT52('Y'): + _currentScreen->setCursorYX(p - 31, q - 31); + break; // VT52 + case TY_VT52('Z'): + reportTerminalType(); + break; // VT52 + case TY_VT52('<'): + setMode(MODE_Ansi); + break; // VT52 + case TY_VT52('='): + setMode(MODE_AppKeyPad); + break; // VT52 + case TY_VT52('>'): + resetMode(MODE_AppKeyPad); + break; // VT52 + + case TY_CSI_PG('c'): + reportSecondaryAttributes(); + break; // VT100 default: reportDecodingError(); break; - }; + }; } void Vt102Emulation::clearScreenAndSetColumns(int columnCount) { - setImageSize(_currentScreen->getLines(),columnCount); + setImageSize(_currentScreen->getLines(), columnCount); clearEntireScreen(); setDefaultMargins(); - _currentScreen->setCursorYX(0,0); + _currentScreen->setCursorYX(0, 0); } -void Vt102Emulation::sendString(const char* s , int length) +void Vt102Emulation::sendString(const char *s, int length) { - if ( length >= 0 ) - emit sendData(s,length); - else - emit sendData(s,strlen(s)); + if (length >= 0) + emit sendData(s, length); + else + emit sendData(s, strlen(s)); } void Vt102Emulation::reportCursorPosition() { - const size_t sz = 20; - char tmp[sz]; - const size_t r = snprintf(tmp, sz, "\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1); - if (sz <= r) { - qWarning("Vt102Emulation::reportCursorPosition: Buffer too small\n"); - } - sendString(tmp); + const size_t sz = 20; + char tmp[sz]; + const size_t r = snprintf(tmp, sz, "\033[%d;%dR", _currentScreen->getCursorY() + 1, + _currentScreen->getCursorX() + 1); + if (sz <= r) { + qWarning("Vt102Emulation::reportCursorPosition: Buffer too small\n"); + } + sendString(tmp); } void Vt102Emulation::reportTerminalType() { - // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide)) - // VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities) - // VT100: ^[[?1;2c - // VT101: ^[[?1;0c - // VT102: ^[[?6v - if (getMode(MODE_Ansi)) - sendString("\033[?1;2c"); // I'm a VT100 - else - sendString("\033/Z"); // I'm a VT52 + // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide)) + // VT220: ^[[?63;1;2;3;6;7;8c (list deps on emul. capabilities) + // VT100: ^[[?1;2c + // VT101: ^[[?1;0c + // VT102: ^[[?6v + if (getMode(MODE_Ansi)) + sendString("\033[?1;2c"); // I'm a VT100 + else + sendString("\033/Z"); // I'm a VT52 } void Vt102Emulation::reportSecondaryAttributes() { - // Seconday device attribute response (Request was: ^[[>0c or ^[[>c) - if (getMode(MODE_Ansi)) - sendString("\033[>0;115;0c"); // Why 115? ;) - else - sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for - // konsoles backward compatibility. + // Seconday device attribute response (Request was: ^[[>0c or ^[[>c) + if (getMode(MODE_Ansi)) + sendString("\033[>0;115;0c"); // Why 115? ;) + else + sendString("\033/Z"); // FIXME I don't think VT52 knows about it but kept for + // konsoles backward compatibility. } void Vt102Emulation::reportTerminalParms(int p) // DECREPTPARM { - const size_t sz = 100; - char tmp[sz]; - const size_t r = snprintf(tmp, sz, "\033[%d;1;1;112;112;1;0x",p); // not really true. - if (sz <= r) { - qWarning("Vt102Emulation::reportTerminalParms: Buffer too small\n"); - } - sendString(tmp); + const size_t sz = 100; + char tmp[sz]; + const size_t r = snprintf(tmp, sz, "\033[%d;1;1;112;112;1;0x", p); // not really true. + if (sz <= r) { + qWarning("Vt102Emulation::reportTerminalParms: Buffer too small\n"); + } + sendString(tmp); } void Vt102Emulation::reportStatus() { - sendString("\033[0n"); //VT100. Device status report. 0 = Ready. + sendString("\033[0n"); // VT100. Device status report. 0 = Ready. } void Vt102Emulation::reportAnswerBack() { - // FIXME - Test this with VTTEST - // This is really obsolete VT100 stuff. - const char* ANSWER_BACK = ""; - sendString(ANSWER_BACK); + // FIXME - Test this with VTTEST + // This is really obsolete VT100 stuff. + const char *ANSWER_BACK = ""; + sendString(ANSWER_BACK); } /*! @@ -939,30 +1497,33 @@ void Vt102Emulation::reportAnswerBack() 2 = Mouse button release */ -void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType ) +void Vt102Emulation::sendMouseEvent(int cb, int cx, int cy, int eventType) { if (cx < 1 || cy < 1) - return; + return; // With the exception of the 1006 mode, button release is encoded in cb. - // Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only that. + // Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for + // only that. if (eventType == 2 && !getMode(MODE_Mouse1006)) cb = 3; // normal buttons are passed as 0x20 + button, // mouse wheel (buttons 4,5) as 0x5c + button if (cb >= 4) - cb += 0x3c; + cb += 0x3c; - //Mouse motion handling + // Mouse motion handling if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) - cb += 0x20; //add 32 to signify motion event + cb += 0x20; // add 32 to signify motion event char command[32]; command[0] = '\0'; - // Check the extensions in decreasing order of preference. Encoding the release event above assumes that 1006 comes first. + // Check the extensions in decreasing order of preference. Encoding the release event above + // assumes that 1006 comes first. if (getMode(MODE_Mouse1006)) { - snprintf(command, sizeof(command), "\033[<%d;%d;%d%c", cb, cx, cy, eventType == 2 ? 'm' : 'M'); + snprintf(command, sizeof(command), "\033[<%d;%d;%d%c", cb, cx, cy, + eventType == 2 ? 'm' : 'M'); } else if (getMode(MODE_Mouse1015)) { snprintf(command, sizeof(command), "\033[%d;%d;%dM", cb + 0x20, cx, cy); } else if (getMode(MODE_Mouse1005)) { @@ -981,7 +1542,7 @@ void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType ) snprintf(command, sizeof(command), "\033[M%c%c%c", cb + 0x20, cx + 0x20, cy + 0x20); } - sendString(command); + sendString(command); } /** @@ -1010,33 +1571,32 @@ void Vt102Emulation::focusGained(void) sendString("\033[I"); } -void Vt102Emulation::sendText( const QString& text ) +void Vt102Emulation::sendText(const QString &text) { - if (!text.isEmpty()) - { - QKeyEvent event(QEvent::KeyPress, - 0, - Qt::NoModifier, - text); - sendKeyEvent(&event, false); // expose as a big fat keypress event - } + if (!text.isEmpty()) { + QKeyEvent event(QEvent::KeyPress, 0, Qt::NoModifier, text); + sendKeyEvent(&event, false); // expose as a big fat keypress event + } } -void Vt102Emulation::sendKeyEvent(QKeyEvent* event, bool fromPaste) +void Vt102Emulation::sendKeyEvent(QKeyEvent *event, bool fromPaste) { Qt::KeyboardModifiers modifiers = event->modifiers(); KeyboardTranslator::States states = KeyboardTranslator::NoState; // get current states - if (getMode(MODE_NewLine) ) states |= KeyboardTranslator::NewLineState; - if (getMode(MODE_Ansi) ) states |= KeyboardTranslator::AnsiState; - if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState; - if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState; + if (getMode(MODE_NewLine)) + states |= KeyboardTranslator::NewLineState; + if (getMode(MODE_Ansi)) + states |= KeyboardTranslator::AnsiState; + if (getMode(MODE_AppCuKeys)) + states |= KeyboardTranslator::CursorKeysState; + if (getMode(MODE_AppScreen)) + states |= KeyboardTranslator::AlternateScreenState; if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) states |= KeyboardTranslator::ApplicationKeypadState; // check flow control state - if (modifiers & KeyboardTranslator::CTRL_MOD) - { + if (modifiers & KeyboardTranslator::CTRL_MOD) { switch (event->key()) { case Qt::Key_S: emit flowControlKeyPressed(true); @@ -1049,12 +1609,9 @@ void Vt102Emulation::sendKeyEvent(QKeyEvent* event, bool fromPaste) } // lookup key binding - if ( _keyTranslator ) - { - KeyboardTranslator::Entry entry = _keyTranslator->findEntry( - event->key() , - modifiers, - states ); + if (_keyTranslator) { + KeyboardTranslator::Entry entry = + _keyTranslator->findEntry(event->key(), modifiers, states); // send result to terminal QByteArray textToSend; @@ -1065,22 +1622,19 @@ void Vt102Emulation::sendKeyEvent(QKeyEvent* event, bool fromPaste) // in the keyboard modifier) bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; bool wantsMetaModifier = entry.modifiers() & entry.modifierMask() & Qt::MetaModifier; - bool wantsAnyModifier = entry.state() & - entry.stateMask() & KeyboardTranslator::AnyModifierState; + bool wantsAnyModifier = + entry.state() & entry.stateMask() & KeyboardTranslator::AnyModifierState; - if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) - && !event->text().isEmpty() ) - { + if (modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) + && !event->text().isEmpty()) { textToSend.prepend("\033"); } - if ( modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) - && !event->text().isEmpty() ) - { + if (modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) + && !event->text().isEmpty()) { textToSend.prepend("\030@s"); } - if ( entry.command() != KeyboardTranslator::NoCommand ) - { + if (entry.command() != KeyboardTranslator::NoCommand) { if (entry.command() & KeyboardTranslator::EraseCommand) { textToSend += eraseChar(); } else { @@ -1088,42 +1642,34 @@ void Vt102Emulation::sendKeyEvent(QKeyEvent* event, bool fromPaste) } // TODO command handling - } - else if ( !entry.text().isEmpty() ) - { - textToSend += _codec->fromUnicode(QString::fromUtf8(entry.text(true,modifiers))); - } - else if((modifiers & KeyboardTranslator::CTRL_MOD) && event->key() >= 0x40 && event->key() < 0x5f) { + } else if (!entry.text().isEmpty()) { + textToSend += _codec->fromUnicode(QString::fromUtf8(entry.text(true, modifiers))); + } else if ((modifiers & KeyboardTranslator::CTRL_MOD) && event->key() >= 0x40 + && event->key() < 0x5f) { textToSend += (event->key() & 0x1f); - } - else if(event->key() == Qt::Key_Tab) { + } else if (event->key() == Qt::Key_Tab) { textToSend += 0x09; - } - else if (event->key() == Qt::Key_PageUp) { + } else if (event->key() == Qt::Key_PageUp) { textToSend += "\033[5~"; - } - else if (event->key() == Qt::Key_PageDown) { + } else if (event->key() == Qt::Key_PageDown) { textToSend += "\033[6~"; - } - else { + } else { textToSend += _codec->fromUnicode(event->text()); } if (!fromPaste && textToSend.length()) { Q_EMIT outputFromKeypressEvent(); } - Q_EMIT sendData( textToSend.constData() , textToSend.length() ); - } - else - { + Q_EMIT sendData(textToSend.constData(), textToSend.length()); + } else { // print an error message to the terminal if no key translator has been // set - QString translatorError = tr("No keyboard translator available. " - "The information needed to convert key presses " - "into characters to send to the terminal " - "is missing."); + QString translatorError = tr("No keyboard translator available. " + "The information needed to convert key presses " + "into characters to send to the terminal " + "is missing."); reset(); - receiveData( translatorError.toUtf8().constData() , translatorError.count() ); + receiveData(translatorError.toUtf8().constData(), translatorError.count()); } } @@ -1151,15 +1697,17 @@ void Vt102Emulation::sendKeyEvent(QKeyEvent* event, bool fromPaste) particular glyphs allocated in (0x00-0x1f) in their code page. */ -#define CHARSET _charset[_currentScreen==_screen[1]] +#define CHARSET _charset[_currentScreen == _screen[1]] // Apply current character map. wchar_t Vt102Emulation::applyCharset(wchar_t c) { - if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f]; - if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete - return c; + if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) + return vt100_graphics[c - 0x5f]; + if (CHARSET.pound && c == '#') + return 0xa3; // This mode is obsolete + return c; } /* @@ -1172,31 +1720,33 @@ wchar_t Vt102Emulation::applyCharset(wchar_t c) void Vt102Emulation::resetCharset(int scrno) { - _charset[scrno].cu_cs = 0; - qstrncpy(_charset[scrno].charset,"BBBB",4); - _charset[scrno].sa_graphic = false; - _charset[scrno].sa_pound = false; - _charset[scrno].graphic = false; - _charset[scrno].pound = false; + _charset[scrno].cu_cs = 0; + qstrncpy(_charset[scrno].charset, "BBBB", 4); + _charset[scrno].sa_graphic = false; + _charset[scrno].sa_pound = false; + _charset[scrno].graphic = false; + _charset[scrno].pound = false; } void Vt102Emulation::setCharset(int n, int cs) // on both screens. { - _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs); - _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs); + _charset[0].charset[n & 3] = cs; + useCharset(_charset[0].cu_cs); + _charset[1].charset[n & 3] = cs; + useCharset(_charset[1].cu_cs); } void Vt102Emulation::setAndUseCharset(int n, int cs) { - CHARSET.charset[n&3] = cs; - useCharset(n&3); + CHARSET.charset[n & 3] = cs; + useCharset(n & 3); } void Vt102Emulation::useCharset(int n) { - CHARSET.cu_cs = n&3; - CHARSET.graphic = (CHARSET.charset[n&3] == '0'); - CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete + CHARSET.cu_cs = n & 3; + CHARSET.graphic = (CHARSET.charset[n & 3] == '0'); + CHARSET.pound = (CHARSET.charset[n & 3] == 'A'); // This mode is obsolete } void Vt102Emulation::setDefaultMargins() @@ -1207,25 +1757,25 @@ void Vt102Emulation::setDefaultMargins() void Vt102Emulation::setMargins(int t, int b) { - _screen[0]->setMargins(t, b); - _screen[1]->setMargins(t, b); + _screen[0]->setMargins(t, b); + _screen[1]->setMargins(t, b); } void Vt102Emulation::saveCursor() { - CHARSET.sa_graphic = CHARSET.graphic; - CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete - // we are not clear about these - //sa_charset = charsets[cScreen->_charset]; - //sa_charset_num = cScreen->_charset; - _currentScreen->saveCursor(); + CHARSET.sa_graphic = CHARSET.graphic; + CHARSET.sa_pound = CHARSET.pound; // This mode is obsolete + // we are not clear about these + // sa_charset = charsets[cScreen->_charset]; + // sa_charset_num = cScreen->_charset; + _currentScreen->saveCursor(); } void Vt102Emulation::restoreCursor() { - CHARSET.graphic = CHARSET.sa_graphic; - CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete - _currentScreen->restoreCursor(); + CHARSET.graphic = CHARSET.sa_graphic; + CHARSET.pound = CHARSET.sa_pound; // This mode is obsolete + _currentScreen->restoreCursor(); } /* ------------------------------------------------------------------------- */ @@ -1250,31 +1800,42 @@ void Vt102Emulation::restoreCursor() void Vt102Emulation::resetModes() { - // MODE_Allow132Columns is not reset here - // to match Xterm's behaviour (see Xterm's VTReset() function) - - resetMode(MODE_132Columns); saveMode(MODE_132Columns); - resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000); - resetMode(MODE_Mouse1001); saveMode(MODE_Mouse1001); - resetMode(MODE_Mouse1002); saveMode(MODE_Mouse1002); - resetMode(MODE_Mouse1003); saveMode(MODE_Mouse1003); - resetMode(MODE_Mouse1005); saveMode(MODE_Mouse1005); - resetMode(MODE_Mouse1006); saveMode(MODE_Mouse1006); - resetMode(MODE_Mouse1015); saveMode(MODE_Mouse1015); - resetMode(MODE_BracketedPaste); saveMode(MODE_BracketedPaste); - - resetMode(MODE_AppScreen); saveMode(MODE_AppScreen); - resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys); - resetMode(MODE_AppKeyPad); saveMode(MODE_AppKeyPad); - resetMode(MODE_NewLine); - setMode(MODE_Ansi); + // MODE_Allow132Columns is not reset here + // to match Xterm's behaviour (see Xterm's VTReset() function) + + resetMode(MODE_132Columns); + saveMode(MODE_132Columns); + resetMode(MODE_Mouse1000); + saveMode(MODE_Mouse1000); + resetMode(MODE_Mouse1001); + saveMode(MODE_Mouse1001); + resetMode(MODE_Mouse1002); + saveMode(MODE_Mouse1002); + resetMode(MODE_Mouse1003); + saveMode(MODE_Mouse1003); + resetMode(MODE_Mouse1005); + saveMode(MODE_Mouse1005); + resetMode(MODE_Mouse1006); + saveMode(MODE_Mouse1006); + resetMode(MODE_Mouse1015); + saveMode(MODE_Mouse1015); + resetMode(MODE_BracketedPaste); + saveMode(MODE_BracketedPaste); + + resetMode(MODE_AppScreen); + saveMode(MODE_AppScreen); + resetMode(MODE_AppCuKeys); + saveMode(MODE_AppCuKeys); + resetMode(MODE_AppKeyPad); + saveMode(MODE_AppKeyPad); + resetMode(MODE_NewLine); + setMode(MODE_Ansi); } void Vt102Emulation::setMode(int m) { - _currentModes.mode[m] = true; - switch (m) - { + _currentModes.mode[m] = true; + switch (m) { case MODE_132Columns: if (getMode(MODE_Allow132Columns)) clearScreenAndSetColumns(132); @@ -1286,91 +1847,87 @@ void Vt102Emulation::setMode(int m) case MODE_Mouse1002: case MODE_Mouse1003: emit programUsesMouseChanged(false); - break; + break; case MODE_BracketedPaste: emit programBracketedPasteModeChanged(true); - break; - - case MODE_AppScreen : _screen[1]->clearSelection(); - setScreen(1); - break; - } - if (m < MODES_SCREEN || m == MODE_NewLine) - { - _screen[0]->setMode(m); - _screen[1]->setMode(m); - } + break; + + case MODE_AppScreen: + _screen[1]->clearSelection(); + setScreen(1); + break; + } + if (m < MODES_SCREEN || m == MODE_NewLine) { + _screen[0]->setMode(m); + _screen[1]->setMode(m); + } } void Vt102Emulation::resetMode(int m) { - _currentModes.mode[m] = false; - switch (m) - { + _currentModes.mode[m] = false; + switch (m) { case MODE_132Columns: if (getMode(MODE_Allow132Columns)) clearScreenAndSetColumns(80); break; - case MODE_Mouse1000 : - case MODE_Mouse1001 : - case MODE_Mouse1002 : - case MODE_Mouse1003 : + case MODE_Mouse1000: + case MODE_Mouse1001: + case MODE_Mouse1002: + case MODE_Mouse1003: emit programUsesMouseChanged(true); - break; + break; case MODE_BracketedPaste: emit programBracketedPasteModeChanged(false); - break; + break; - case MODE_AppScreen : + case MODE_AppScreen: _screen[0]->clearSelection(); setScreen(0); - break; - } - if (m < MODES_SCREEN || m == MODE_NewLine) - { - _screen[0]->resetMode(m); - _screen[1]->resetMode(m); - } + break; + } + if (m < MODES_SCREEN || m == MODE_NewLine) { + _screen[0]->resetMode(m); + _screen[1]->resetMode(m); + } } void Vt102Emulation::saveMode(int m) { - _savedModes.mode[m] = _currentModes.mode[m]; + _savedModes.mode[m] = _currentModes.mode[m]; } void Vt102Emulation::restoreMode(int m) { - if (_savedModes.mode[m]) - setMode(m); - else - resetMode(m); + if (_savedModes.mode[m]) + setMode(m); + else + resetMode(m); } bool Vt102Emulation::getMode(int m) { - return _currentModes.mode[m]; + return _currentModes.mode[m]; } char Vt102Emulation::eraseChar() const { - KeyboardTranslator::Entry entry = _keyTranslator->findEntry( - Qt::Key_Backspace, - Qt::NoModifier, - KeyboardTranslator::NoState); - if ( entry.text().count() > 0 ) - return entry.text().at(0); - else - return '\b'; + KeyboardTranslator::Entry entry = _keyTranslator->findEntry(Qt::Key_Backspace, Qt::NoModifier, + KeyboardTranslator::NoState); + if (entry.text().count() > 0) + return entry.text().at(0); + else + return '\b'; } void Vt102Emulation::reportDecodingError() { - if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) ) - return; - qCDebug(qtermwidgetLogger) << "Undecodable sequence:" << QString::fromWCharArray(tokenBuffer, tokenBufferPos); + if (tokenBufferPos == 0 || (tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32)) + return; + qCDebug(qtermwidgetLogger) << "Undecodable sequence:" + << QString::fromWCharArray(tokenBuffer, tokenBufferPos); } //#include "Vt102Emulation.moc" - diff --git a/lib/Vt102Emulation.h b/lib/Vt102Emulation.h index 214e50cc..6b54e871 100644 --- a/lib/Vt102Emulation.h +++ b/lib/Vt102Emulation.h @@ -35,34 +35,33 @@ #include "Emulation.h" #include "Screen.h" -#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1 -#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM) -#define MODE_AppKeyPad (MODES_SCREEN+2) // -#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release -#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking -#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking -#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking -#define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates -#define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates -#define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates -#define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM) -#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM) -#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode -#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode -#define MODE_total (MODES_SCREEN+14) - -namespace Konsole -{ +#define MODE_AppScreen (MODES_SCREEN + 0) // Mode #1 +#define MODE_AppCuKeys (MODES_SCREEN + 1) // Application cursor keys (DECCKM) +#define MODE_AppKeyPad (MODES_SCREEN + 2) // +#define MODE_Mouse1000 (MODES_SCREEN + 3) // Send mouse X,Y position on press and release +#define MODE_Mouse1001 (MODES_SCREEN + 4) // Use Hilight mouse tracking +#define MODE_Mouse1002 (MODES_SCREEN + 5) // Use cell motion mouse tracking +#define MODE_Mouse1003 (MODES_SCREEN + 6) // Use all motion mouse tracking +#define MODE_Mouse1005 (MODES_SCREEN + 7) // Xterm-style extended coordinates +#define MODE_Mouse1006 (MODES_SCREEN + 8) // 2nd Xterm-style extended coordinates +#define MODE_Mouse1015 (MODES_SCREEN + 9) // Urxvt-style extended coordinates +#define MODE_Ansi (MODES_SCREEN + 10) // Use US Ascii for character sets G0-G3 (DECANM) +#define MODE_132Columns (MODES_SCREEN + 11) // 80 <-> 132 column mode switch (DECCOLM) +#define MODE_Allow132Columns (MODES_SCREEN + 12) // Allow DECCOLM mode +#define MODE_BracketedPaste (MODES_SCREEN + 13) // Xterm-style bracketed paste mode +#define MODE_total (MODES_SCREEN + 14) + +namespace Konsole { struct CharCodes { - // coding info - char charset[4]; // - int cu_cs; // actual charset. - bool graphic; // Some VT100 tricks - bool pound ; // Some VT100 tricks - bool sa_graphic; // saved graphic - bool sa_pound; // saved pound + // coding info + char charset[4]; // + int cu_cs; // actual charset. + bool graphic; // Some VT100 tricks + bool pound; // Some VT100 tricks + bool sa_graphic; // saved graphic + bool sa_pound; // saved pound }; /** @@ -77,121 +76,120 @@ struct CharCodes */ class Vt102Emulation : public Emulation { -Q_OBJECT + Q_OBJECT public: - /** Constructs a new emulation */ - Vt102Emulation(); - ~Vt102Emulation() override; + /** Constructs a new emulation */ + Vt102Emulation(); + ~Vt102Emulation() override; - // reimplemented from Emulation - void clearEntireScreen() override; - void reset() override; - char eraseChar() const override; + // reimplemented from Emulation + void clearEntireScreen() override; + void reset() override; + char eraseChar() const override; public slots: - // reimplemented from Emulation - void sendString(const char*,int length = -1) override; - void sendText(const QString& text) override; - void sendKeyEvent(QKeyEvent*, bool fromPaste) override; - void sendMouseEvent(int buttons, int column, int line, int eventType) override; - virtual void focusLost(); - virtual void focusGained(); + // reimplemented from Emulation + void sendString(const char *, int length = -1) override; + void sendText(const QString &text) override; + void sendKeyEvent(QKeyEvent *, bool fromPaste) override; + void sendMouseEvent(int buttons, int column, int line, int eventType) override; + virtual void focusLost(); + virtual void focusGained(); protected: - // reimplemented from Emulation - void setMode(int mode) override; - void resetMode(int mode) override; - void receiveChar(wchar_t cc) override; + // reimplemented from Emulation + void setMode(int mode) override; + void resetMode(int mode) override; + void receiveChar(wchar_t cc) override; private slots: - //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates - //used to buffer multiple title updates - void updateTitle(); + // causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates + // used to buffer multiple title updates + void updateTitle(); private: - wchar_t applyCharset(wchar_t c); - void setCharset(int n, int cs); - void useCharset(int n); - void setAndUseCharset(int n, int cs); - void saveCursor(); - void restoreCursor(); - void resetCharset(int scrno); - - void setMargins(int top, int bottom); - //set margins for all screens back to their defaults - void setDefaultMargins(); - - // returns true if 'mode' is set or false otherwise - bool getMode (int mode); - // saves the current boolean value of 'mode' - void saveMode (int mode); - // restores the boolean value of 'mode' - void restoreMode(int mode); - // resets all modes - // (except MODE_Allow132Columns) - void resetModes(); - - void resetTokenizer(); - #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title) - void addToCurrentToken(wchar_t cc); - wchar_t tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? - int tokenBufferPos; + wchar_t applyCharset(wchar_t c); + void setCharset(int n, int cs); + void useCharset(int n); + void setAndUseCharset(int n, int cs); + void saveCursor(); + void restoreCursor(); + void resetCharset(int scrno); + + void setMargins(int top, int bottom); + // set margins for all screens back to their defaults + void setDefaultMargins(); + + // returns true if 'mode' is set or false otherwise + bool getMode(int mode); + // saves the current boolean value of 'mode' + void saveMode(int mode); + // restores the boolean value of 'mode' + void restoreMode(int mode); + // resets all modes + // (except MODE_Allow132Columns) + void resetModes(); + + void resetTokenizer(); +#define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title) + void addToCurrentToken(wchar_t cc); + wchar_t tokenBuffer[MAX_TOKEN_LENGTH]; // FIXME: overflow? + int tokenBufferPos; #define MAXARGS 15 - void addDigit(int dig); - void addArgument(); - int argv[MAXARGS]; - int argc; - void initTokenizer(); - int prevCC; - - // Set of flags for each of the ASCII characters which indicates - // what category they fall into (printable character, control, digit etc.) - // for the purposes of decoding terminal output - int charClass[256]; - - void reportDecodingError(); - - void processToken(int code, wchar_t p, int q); - void processWindowAttributeChange(); - void requestWindowAttribute(int); - - void reportTerminalType(); - void reportSecondaryAttributes(); - void reportStatus(); - void reportAnswerBack(); - void reportCursorPosition(); - void reportTerminalParms(int p); - - void onScrollLock(); - void scrollLock(const bool lock); - - // clears the screen and resizes it to the specified - // number of columns - void clearScreenAndSetColumns(int columnCount); - - CharCodes _charset[2]; - - class TerminalState - { - public: - // Initializes all modes to false - TerminalState() - { memset(&mode,false,MODE_total * sizeof(bool)); } - - bool mode[MODE_total]; - }; - - TerminalState _currentModes; - TerminalState _savedModes; - - //hash table and timer for buffering calls to the session instance - //to update the name of the session - //or window title. - //these calls occur when certain escape sequences are seen in the - //output from the terminal - QHash _pendingTitleUpdates; - QTimer* _titleUpdateTimer; + void addDigit(int dig); + void addArgument(); + int argv[MAXARGS]; + int argc; + void initTokenizer(); + int prevCC; + + // Set of flags for each of the ASCII characters which indicates + // what category they fall into (printable character, control, digit etc.) + // for the purposes of decoding terminal output + int charClass[256]; + + void reportDecodingError(); + + void processToken(int code, wchar_t p, int q); + void processWindowAttributeChange(); + void requestWindowAttribute(int); + + void reportTerminalType(); + void reportSecondaryAttributes(); + void reportStatus(); + void reportAnswerBack(); + void reportCursorPosition(); + void reportTerminalParms(int p); + + void onScrollLock(); + void scrollLock(const bool lock); + + // clears the screen and resizes it to the specified + // number of columns + void clearScreenAndSetColumns(int columnCount); + + CharCodes _charset[2]; + + class TerminalState + { + public: + // Initializes all modes to false + TerminalState() { memset(&mode, false, MODE_total * sizeof(bool)); } + + bool mode[MODE_total]; + }; + + TerminalState _currentModes; + TerminalState _savedModes; + + // hash table and timer for buffering calls to the session instance + // to update the name of the session + // or window title. + // these calls occur when certain escape sequences are seen in the + // output from the terminal + QHash _pendingTitleUpdates; + QTimer *_titleUpdateTimer; bool _reportFocusEvents; }; diff --git a/lib/konsole_wcwidth.cpp b/lib/konsole_wcwidth.cpp index cfb6c07a..fbd708b4 100644 --- a/lib/konsole_wcwidth.cpp +++ b/lib/konsole_wcwidth.cpp @@ -10,9 +10,9 @@ #include #ifdef HAVE_UTF8PROC -#include +# include #else -#include +# include #endif #include "konsole_wcwidth.h" @@ -20,24 +20,24 @@ int konsole_wcwidth(wchar_t ucs) { #ifdef HAVE_UTF8PROC - utf8proc_category_t cat = utf8proc_category( ucs ); + utf8proc_category_t cat = utf8proc_category(ucs); if (cat == UTF8PROC_CATEGORY_CO) { // Co: Private use area. libutf8proc makes them zero width, while tmux // assumes them to be width 1, and glibc's default width is also 1 return 1; } - return utf8proc_charwidth( ucs ); + return utf8proc_charwidth(ucs); #else - return wcwidth( ucs ); + return wcwidth(ucs); #endif } // single byte char: +1, multi byte char: +2 -int string_width( const std::wstring & wstr ) +int string_width(const std::wstring &wstr) { int w = 0; - for ( size_t i = 0; i < wstr.length(); ++i ) { - w += konsole_wcwidth( wstr[ i ] ); + for (size_t i = 0; i < wstr.length(); ++i) { + w += konsole_wcwidth(wstr[i]); } return w; } diff --git a/lib/konsole_wcwidth.h b/lib/konsole_wcwidth.h index 32aa882a..bb34e596 100644 --- a/lib/konsole_wcwidth.h +++ b/lib/konsole_wcwidth.h @@ -6,7 +6,6 @@ Rewritten for QT4 by e_k */ - #ifndef _KONSOLE_WCWIDTH_H_ #define _KONSOLE_WCWIDTH_H_ @@ -15,6 +14,6 @@ int konsole_wcwidth(wchar_t ucs); -int string_width( const std::wstring & wstr ); +int string_width(const std::wstring &wstr); #endif diff --git a/lib/kprocess.cpp b/lib/kprocess.cpp index 904e1bbf..74664262 100644 --- a/lib/kprocess.cpp +++ b/lib/kprocess.cpp @@ -32,33 +32,33 @@ #include #ifdef Q_OS_WIN -# include +# include #else -# include -# include +# include +# include #endif #ifndef Q_OS_WIN -# define STD_OUTPUT_HANDLE 1 -# define STD_ERROR_HANDLE 2 +# define STD_OUTPUT_HANDLE 1 +# define STD_ERROR_HANDLE 2 #endif #ifdef _WIN32_WCE -#include +# include #endif void KProcessPrivate::writeAll(const QByteArray &buf, int fd) { #ifdef Q_OS_WIN -#ifndef _WIN32_WCE +# ifndef _WIN32_WCE HANDLE h = GetStdHandle(fd); if (h) { DWORD wr; WriteFile(h, buf.data(), buf.size(), &wr, 0); } -#else - fwrite(buf.data(), 1, buf.size(), (FILE*)fd); -#endif +# else + fwrite(buf.data(), 1, buf.size(), (FILE *)fd); +# endif #else int off = 0; do { @@ -105,17 +105,13 @@ void KProcessPrivate::_k_forwardStderr() // public member functions // ///////////////////////////// -KProcess::KProcess(QObject *parent) : - QProcess(parent), - d_ptr(new KProcessPrivate) +KProcess::KProcess(QObject *parent) : QProcess(parent), d_ptr(new KProcessPrivate) { d_ptr->q_ptr = this; setOutputChannelMode(ForwardedChannels); } -KProcess::KProcess(KProcessPrivate *d, QObject *parent) : - QProcess(parent), - d_ptr(d) +KProcess::KProcess(KProcessPrivate *d, QObject *parent) : QProcess(parent), d_ptr(d) { d_ptr->q_ptr = this; setOutputChannelMode(ForwardedChannels); @@ -223,7 +219,7 @@ void KProcess::setProgram(const QStringList &argv) { Q_D(KProcess); - Q_ASSERT( !argv.isEmpty() ); + Q_ASSERT(!argv.isEmpty()); d->args = argv; d->prog = d->args.takeFirst(); #ifdef Q_OS_WIN @@ -276,18 +272,19 @@ void KProcess::setShellCommand(const QString &cmd) d->prog = KStandardDirs::findExe(d->args[0]); if (!d->prog.isEmpty()) { d->args.removeFirst(); -#ifdef Q_OS_WIN +# ifdef Q_OS_WIN setNativeArguments(QString()); -#endif +# endif return; } } d->args.clear(); -#ifdef Q_OS_UNIX +# ifdef Q_OS_UNIX // #ifdef NON_FREE // ... as they ship non-POSIX /bin/sh -# if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__GNU__) +# if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \ + && !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__GNU__) // If /bin/sh is a symlink, we can be pretty sure that it points to a // POSIX shell - the original bourne shell is about the only non-POSIX // shell still in use and it is always installed natively as /bin/sh. @@ -308,27 +305,27 @@ void KProcess::setShellCommand(const QString &cmd) } } } -# else +# else d->prog = QString::fromLatin1("/bin/sh"); -# endif +# endif d->args << QString::fromLatin1("-c") << cmd; -#else // Q_OS_UNIX +# else // Q_OS_UNIX // KMacroExpander::expandMacrosShellQuote(), KShell::quoteArg() and // KShell::joinArgs() may generate these for security reasons. setEnv(PERCENT_VARIABLE, QLatin1String("%")); -#ifndef _WIN32_WCE +# ifndef _WIN32_WCE WCHAR sysdir[MAX_PATH + 1]; UINT size = GetSystemDirectoryW(sysdir, MAX_PATH + 1); d->prog = QString::fromUtf16((const ushort *) sysdir, size); d->prog += QLatin1String("\\cmd.exe"); setNativeArguments(QLatin1String("/V:OFF /S /C \"") + cmd + QLatin1Char('"')); -#else +# else d->prog = QLatin1String("\\windows\\cmd.exe"); setNativeArguments(QLatin1String("/S /C \"") + cmd + QLatin1Char('"')); -#endif -#endif +# endif +# endif } #endif QStringList KProcess::program() const @@ -381,7 +378,7 @@ int KProcess::startDetached() qint64 pid; if (!QProcess::startDetached(d->prog, d->args, workingDirectory(), &pid)) return 0; - return (int) pid; + return (int)pid; } // static @@ -390,7 +387,7 @@ int KProcess::startDetached(const QString &exe, const QStringList &args) qint64 pid; if (!QProcess::startDetached(exe, args, QString(), &pid)) return 0; - return (int) pid; + return (int)pid; } // static diff --git a/lib/kprocess.h b/lib/kprocess.h index ad2f05ec..2ede78f7 100644 --- a/lib/kprocess.h +++ b/lib/kprocess.h @@ -55,23 +55,22 @@ class KProcess : public QProcess Q_DECLARE_PRIVATE(KProcess) public: - /** * Modes in which the output channels can be opened. */ enum OutputChannelMode { SeparateChannels = QProcess::SeparateChannels, - /**< Standard output and standard error are handled by KProcess - as separate channels */ + /**< Standard output and standard error are handled by KProcess + as separate channels */ MergedChannels = QProcess::MergedChannels, - /**< Standard output and standard error are handled by KProcess - as one channel */ + /**< Standard output and standard error are handled by KProcess + as one channel */ ForwardedChannels = QProcess::ForwardedChannels, - /**< Both standard output and standard error are forwarded - to the parent process' respective channel */ + /**< Both standard output and standard error are forwarded + to the parent process' respective channel */ OnlyStdoutChannel, - /**< Only standard output is handled; standard error is forwarded */ - OnlyStderrChannel /**< Only standard error is handled; standard output is forwarded */ + /**< Only standard output is handled; standard error is forwarded */ + OnlyStderrChannel /**< Only standard error is handled; standard output is forwarded */ }; /** @@ -182,7 +181,7 @@ class KProcess : public QProcess * @param arg the argument to add * @return a reference to this KProcess */ - KProcess &operator<<(const QString& arg); + KProcess &operator<<(const QString &arg); /** * @overload @@ -190,7 +189,7 @@ class KProcess : public QProcess * @param args the arguments to add * @return a reference to this KProcess */ - KProcess &operator<<(const QStringList& args); + KProcess &operator<<(const QStringList &args); /** * Clear the program and command line argument list. @@ -320,32 +319,28 @@ class KProcess : public QProcess /** * @internal */ - KProcessPrivate * const d_ptr; + KProcessPrivate *const d_ptr; private: // hide those - using QProcess::setReadChannelMode; + using QProcess::processChannelMode; using QProcess::readChannelMode; using QProcess::setProcessChannelMode; - using QProcess::processChannelMode; + using QProcess::setReadChannelMode; Q_PRIVATE_SLOT(d_func(), void _k_forwardStdout()) Q_PRIVATE_SLOT(d_func(), void _k_forwardStderr()) }; /* ----------- kprocess_p.h ---------------- */ -class KProcessPrivate { +class KProcessPrivate +{ Q_DECLARE_PUBLIC(KProcess) protected: - KProcessPrivate() : - openMode(QIODevice::ReadWrite) - { - } - virtual ~KProcessPrivate() - { - } + KProcessPrivate() : openMode(QIODevice::ReadWrite) { } + virtual ~KProcessPrivate() { } void writeAll(const QByteArray &buf, int fd); void forwardStd(KProcess::ProcessChannel good, int fd); void _k_forwardStdout(); @@ -360,4 +355,3 @@ class KProcessPrivate { }; /* ------------------------------------------- */ #endif - diff --git a/lib/kpty.cpp b/lib/kpty.cpp index 21dc7451..9832f994 100644 --- a/lib/kpty.cpp +++ b/lib/kpty.cpp @@ -26,47 +26,46 @@ #include - #if defined(__FreeBSD__) || defined(__DragonFly__) -#define HAVE_LOGIN -#define HAVE_LIBUTIL_H +# define HAVE_LOGIN +# define HAVE_LIBUTIL_H #endif #if defined(__OpenBSD__) -#define HAVE_LOGIN -#define HAVE_UTIL_H +# define HAVE_LOGIN +# define HAVE_UTIL_H #endif #if defined(__NetBSD__) -#define HAVE_LOGIN -#define HAVE_UTIL_H -#define HAVE_OPENPTY +# define HAVE_LOGIN +# define HAVE_UTIL_H +# define HAVE_OPENPTY #endif #if defined(__APPLE__) -#define HAVE_OPENPTY -#define HAVE_UTIL_H +# define HAVE_OPENPTY +# define HAVE_UTIL_H #endif #ifdef __sgi -#define __svr4__ +# define __svr4__ #endif #ifdef __osf__ -#define _OSF_SOURCE -#include +# define _OSF_SOURCE +# include #endif #ifdef _AIX -#define _ALL_SOURCE +# define _ALL_SOURCE #endif // __USE_XOPEN isn't defined by default in ICC // (needed for ptsname(), grantpt() and unlockpt()) #ifdef __INTEL_COMPILER -# ifndef __USE_XOPEN -# define __USE_XOPEN -# endif +# ifndef __USE_XOPEN +# define __USE_XOPEN +# endif #endif #include @@ -86,32 +85,32 @@ #include #if defined(HAVE_PTY_H) -# include +# include #endif #ifdef HAVE_LIBUTIL_H -# include +# include #elif defined(HAVE_UTIL_H) -# include +# include #endif #ifdef HAVE_UTEMPTER extern "C" { -# include +# include } #else -# include -# ifdef HAVE_UTMPX -# include -# endif -# if !defined(_PATH_UTMPX) && defined(_UTMPX_FILE) -# define _PATH_UTMPX _UTMPX_FILE -# endif -# ifdef HAVE_UPDWTMPX -# if !defined(_PATH_WTMPX) && defined(_WTMPX_FILE) -# define _PATH_WTMPX _WTMPX_FILE -# endif -# endif +# include +# ifdef HAVE_UTMPX +# include +# endif +# if !defined(_PATH_UTMPX) && defined(_UTMPX_FILE) +# define _PATH_UTMPX _UTMPX_FILE +# endif +# ifdef HAVE_UPDWTMPX +# if !defined(_PATH_WTMPX) && defined(_WTMPX_FILE) +# define _PATH_WTMPX _WTMPX_FILE +# endif +# endif #endif /* for HP-UX (some versions) the extern C is needed, and for other @@ -119,38 +118,42 @@ extern "C" { extern "C" { #include #if defined(HAVE_TERMIO_H) -# include // struct winsize on some systems +# include // struct winsize on some systems #endif } -#if defined (_HPUX_SOURCE) -# define _TERMIOS_INCLUDED -# include +#if defined(_HPUX_SOURCE) +# define _TERMIOS_INCLUDED +# include #endif #ifdef HAVE_SYS_STROPTS_H -# include // Defines I_PUSH -# define _NEW_TTY_CTRL +# include // Defines I_PUSH +# define _NEW_TTY_CTRL #endif -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__) -# define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) \ + || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) \ + || defined(__DragonFly__) +# define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode) #else -# if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__) || defined(__GNU__) -# define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode) -# else -# define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode) -# endif +# if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined(__CYGWIN__) || defined(__GNU__) +# define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode) +# else +# define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode) +# endif #endif -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__) -# define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) \ + || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) \ + || defined(__DragonFly__) +# define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode) #else -# if defined(_HPUX_SOURCE) || defined(__CYGWIN__) || defined(__GNU__) -# define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode) -# else -# define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode) -# endif +# if defined(_HPUX_SOURCE) || defined(__CYGWIN__) || defined(__GNU__) +# define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode) +# else +# define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode) +# endif #endif //#include @@ -158,7 +161,7 @@ extern "C" { // not defined on HP-UX for example #ifndef CTRL -# define CTRL(x) ((x) & 037) +# define CTRL(x) ((x)&037) #endif #define TTY_GROUP "tty" @@ -171,19 +174,16 @@ extern "C" { // private data // ////////////////// -KPtyPrivate::KPtyPrivate(KPty* parent) : - masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent) +KPtyPrivate::KPtyPrivate(KPty *parent) : masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent) { } -KPtyPrivate::~KPtyPrivate() -{ -} +KPtyPrivate::~KPtyPrivate() { } bool KPtyPrivate::chownpty(bool) { -// return !QProcess::execute(KStandardDirs::findExe("kgrantpty"), -// QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd)); + // return !QProcess::execute(KStandardDirs::findExe("kgrantpty"), + // QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd)); return true; } @@ -191,13 +191,9 @@ bool KPtyPrivate::chownpty(bool) // public member functions // ///////////////////////////// -KPty::KPty() : - d_ptr(new KPtyPrivate(this)) -{ -} +KPty::KPty() : d_ptr(new KPtyPrivate(this)) { } -KPty::KPty(KPtyPrivate *d) : - d_ptr(d) +KPty::KPty(KPtyPrivate *d) : d_ptr(d) { d_ptr->q_ptr = this; } @@ -229,7 +225,7 @@ bool KPty::open() #ifdef HAVE_OPENPTY char ptsn[PATH_MAX]; - if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0)) { + if (::openpty(&d->masterFd, &d->slaveFd, ptsn, 0, 0)) { d->masterFd = -1; d->slaveFd = -1; qWarning() << "Can't open a pseudo teletype"; @@ -239,58 +235,58 @@ bool KPty::open() #else -#ifdef HAVE__GETPTY // irix +# ifdef HAVE__GETPTY // irix - char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0); + char *ptsn = _getpty(&d->masterFd, O_RDWR | O_NOCTTY, S_IRUSR | S_IWUSR, 0); if (ptsn) { d->ttyName = ptsn; goto grantedpt; } -#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN) +# elif defined(HAVE_PTSNAME) || defined(TIOCGPTN) -#ifdef HAVE_POSIX_OPENPT - d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY); -#elif defined(HAVE_GETPT) +# ifdef HAVE_POSIX_OPENPT + d->masterFd = ::posix_openpt(O_RDWR | O_NOCTTY); +# elif defined(HAVE_GETPT) d->masterFd = ::getpt(); -#elif defined(PTM_DEVICE) - d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY); -#else -# error No method to open a PTY master detected. -#endif +# elif defined(PTM_DEVICE) + d->masterFd = ::open(PTM_DEVICE, O_RDWR | O_NOCTTY); +# else +# error No method to open a PTY master detected. +# endif if (d->masterFd >= 0) { -#ifdef HAVE_PTSNAME +# ifdef HAVE_PTSNAME char *ptsn = ptsname(d->masterFd); if (ptsn) { d->ttyName = ptsn; -#else - int ptyno; - if (ioctl(d->masterFd, TIOCGPTN, &ptyno) != -1) { - d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno); -#endif -#ifdef HAVE_GRANTPT +# else + int ptyno; + if (ioctl(d->masterFd, TIOCGPTN, &ptyno) != -1) { + d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno); +# endif +# ifdef HAVE_GRANTPT if (!grantpt(d->masterFd)) { goto grantedpt; } -#else +# else - goto gotpty; -#endif + goto gotpty; +# endif } ::close(d->masterFd); d->masterFd = -1; } -#endif // HAVE_PTSNAME || TIOCGPTN +# endif // HAVE_PTSNAME || TIOCGPTN // Linux device names, FIXME: Trouble on other systems? - for (const char * s3 = "pqrstuvwxyzabcde"; *s3; s3++) { - for (const char * s4 = "0123456789abcdef"; *s4; s4++) { + for (const char *s3 = "pqrstuvwxyzabcde"; *s3; s3++) { + for (const char *s4 = "0123456789abcdef"; *s4; s4++) { ptyName = QByteArrayLiteral("/dev/pty") + *s3 + *s4; d->ttyName = QByteArrayLiteral("/dev/tty") + *s3 + *s4; d->masterFd = ::open(ptyName.data(), O_RDWR); if (d->masterFd >= 0) { -#ifdef Q_OS_SOLARIS +# ifdef Q_OS_SOLARIS /* Need to check the process group of the pty. * If it exists, then the slave pty is in use, * and we need to get another one. @@ -301,17 +297,18 @@ bool KPty::open() d->masterFd = -1; continue; } -#endif /* Q_OS_SOLARIS */ - if (!access(d->ttyName.data(),R_OK|W_OK)) { // checks availability based on permission bits +# endif /* Q_OS_SOLARIS */ + if (!access(d->ttyName.data(), + R_OK | W_OK)) { // checks availability based on permission bits if (!geteuid()) { - struct group * p = getgrnam(TTY_GROUP); + struct group *p = getgrnam(TTY_GROUP); if (!p) { p = getgrnam("wheel"); } - gid_t gid = p ? p->gr_gid : getgid (); + gid_t gid = p ? p->gr_gid : getgid(); if (!chown(d->ttyName.data(), getuid(), gid)) { - chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP); + chmod(d->ttyName.data(), S_IRUSR | S_IWUSR | S_IWGRP); } } goto gotpty; @@ -332,29 +329,27 @@ bool KPty::open() // had it happen when pty #349 was allocated. I guess // there was some sort of leak? I only had a few open. } - if (((st.st_uid != getuid()) || - (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) && - !d->chownpty(true)) { - qWarning() - << "chownpty failed for device " << ptyName << "::" << d->ttyName - << "\nThis means the communication can be eavesdropped." - << Qt::endl; + if (((st.st_uid != getuid()) + || (st.st_mode & (S_IRGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH))) + && !d->chownpty(true)) { + qWarning() << "chownpty failed for device " << ptyName << "::" << d->ttyName + << "\nThis means the communication can be eavesdropped." << Qt::endl; } -#if defined (HAVE__GETPTY) || defined (HAVE_GRANTPT) +# if defined(HAVE__GETPTY) || defined(HAVE_GRANTPT) grantedpt: -#endif +# endif -#ifdef HAVE_REVOKE +# ifdef HAVE_REVOKE revoke(d->ttyName.data()); -#endif +# endif -#ifdef HAVE_UNLOCKPT +# ifdef HAVE_UNLOCKPT unlockpt(d->masterFd); -#elif defined(TIOCSPTLCK) +# elif defined(TIOCSPTLCK) int flag = 0; ioctl(d->masterFd, TIOCSPTLCK, &flag); -#endif +# endif d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY); if (d->slaveFd < 0) { @@ -364,11 +359,11 @@ bool KPty::open() return false; } -#if (defined(__svr4__) || defined(__sgi__)) +# if (defined(__svr4__) || defined(__sgi__)) // Solaris ioctl(d->slaveFd, I_PUSH, "ptem"); ioctl(d->slaveFd, I_PUSH, "ldterm"); -#endif +# endif #endif /* HAVE_OPENPTY */ @@ -381,23 +376,23 @@ bool KPty::open() bool KPty::open(int fd) { #if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN) - qWarning() << "Unsupported attempt to open pty with fd" << fd; - return false; + qWarning() << "Unsupported attempt to open pty with fd" << fd; + return false; #else Q_D(KPty); if (d->masterFd >= 0) { qWarning() << "Attempting to open an already open pty"; - return false; + return false; } d->ownMaster = false; -# ifdef HAVE_PTSNAME +# ifdef HAVE_PTSNAME char *ptsn = ptsname(fd); if (ptsn) { d->ttyName = ptsn; -# else +# else int ptyno; if (ioctl(fd, TIOCGPTN, &ptyno) != -1) { const size_t sz = 32; @@ -407,7 +402,7 @@ bool KPty::open(int fd) qWarning("KPty::open: Buffer too small\n"); } d->ttyName = buf; -# endif +# endif } else { qWarning() << "Failed to determine pty slave device for fd" << fd; return false; @@ -440,16 +435,16 @@ bool KPty::openSlave() Q_D(KPty); if (d->slaveFd >= 0) - return true; + return true; if (d->masterFd < 0) { - qDebug() << "Attempting to open pty slave while master is closed"; - return false; + qDebug() << "Attempting to open pty slave while master is closed"; + return false; } - //d->slaveFd = KDE_open(d->ttyName.data(), O_RDWR | O_NOCTTY); + // d->slaveFd = KDE_open(d->ttyName.data(), O_RDWR | O_NOCTTY); d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY); if (d->slaveFd < 0) { - qDebug() << "Can't open slave pseudo teletype"; - return false; + qDebug() << "Can't open slave pseudo teletype"; + return false; } fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC); return true; @@ -469,7 +464,7 @@ void KPty::close() struct stat st; if (!stat(d->ttyName.data(), &st)) { chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1); - chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + chmod(d->ttyName.data(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); } } else { fcntl(d->masterFd, F_SETFD, 0); @@ -507,7 +502,7 @@ void KPty::setCTty() #endif } -void KPty::login(const char * user, const char * remotehost) +void KPty::login(const char *user, const char *remotehost) { #ifdef HAVE_UTEMPTER Q_D(KPty); @@ -515,81 +510,80 @@ void KPty::login(const char * user, const char * remotehost) addToUtmp(d->ttyName.constData(), remotehost, d->masterFd); Q_UNUSED(user); #else -# ifdef HAVE_UTMPX +# ifdef HAVE_UTMPX struct utmpx l_struct; -# else +# else struct utmp l_struct; -# endif +# endif memset(&l_struct, 0, sizeof(l_struct)); // note: strncpy without terminators _is_ correct here. man 4 utmp if (user) { -# ifdef HAVE_UTMPX +# ifdef HAVE_UTMPX strncpy(l_struct.ut_user, user, sizeof(l_struct.ut_user)); -# else +# else strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name)); -# endif +# endif } if (remotehost) { strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host)); -# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN +# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host)); -# endif +# endif } -# ifndef __GLIBC__ +# ifndef __GLIBC__ Q_D(KPty); - const char * str_ptr = d->ttyName.data(); + const char *str_ptr = d->ttyName.data(); if (!memcmp(str_ptr, "/dev/", 5)) { str_ptr += 5; } strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line)); -# ifdef HAVE_STRUCT_UTMP_UT_ID - strncpy(l_struct.ut_id, - str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id), +# ifdef HAVE_STRUCT_UTMP_UT_ID + strncpy(l_struct.ut_id, str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id), sizeof(l_struct.ut_id)); -# endif -# endif +# endif +# endif -# ifdef HAVE_UTMPX +# ifdef HAVE_UTMPX gettimeofday(&l_struct.ut_tv, 0); -# else +# else l_struct.ut_time = time(nullptr); -# endif +# endif -# ifdef HAVE_LOGIN -# ifdef HAVE_LOGINX +# ifdef HAVE_LOGIN +# ifdef HAVE_LOGINX ::loginx(&l_struct); -# else +# else ::login(&l_struct); -# endif -# else -# ifdef HAVE_STRUCT_UTMP_UT_TYPE +# endif +# else +# ifdef HAVE_STRUCT_UTMP_UT_TYPE l_struct.ut_type = USER_PROCESS; -# endif -# ifdef HAVE_STRUCT_UTMP_UT_PID +# endif +# ifdef HAVE_STRUCT_UTMP_UT_PID l_struct.ut_pid = getpid(); -# ifdef HAVE_STRUCT_UTMP_UT_SESSION +# ifdef HAVE_STRUCT_UTMP_UT_SESSION l_struct.ut_session = getsid(0); -# endif -# endif -# ifdef HAVE_UTMPX +# endif +# endif +# ifdef HAVE_UTMPX utmpxname(_PATH_UTMPX); setutxent(); pututxline(&l_struct); endutxent(); -# ifdef HAVE_UPDWTMPX +# ifdef HAVE_UPDWTMPX updwtmpx(_PATH_WTMPX, &l_struct); -# endif -# else +# endif +# else utmpname(_PATH_UTMP); setutent(); pututline(&l_struct); endutent(); updwtmp(_PATH_WTMP, &l_struct); -# endif -# endif +# endif +# endif #endif } @@ -606,77 +600,77 @@ void KPty::logout() if (!memcmp(str_ptr, "/dev/", 5)) { str_ptr += 5; } -# ifdef __GLIBC__ +# ifdef __GLIBC__ else { - const char * sl_ptr = strrchr(str_ptr, '/'); + const char *sl_ptr = strrchr(str_ptr, '/'); if (sl_ptr) { str_ptr = sl_ptr + 1; } } -# endif -# ifdef HAVE_LOGIN -# ifdef HAVE_LOGINX +# endif +# ifdef HAVE_LOGIN +# ifdef HAVE_LOGINX ::logoutx(str_ptr, 0, DEAD_PROCESS); -# else +# else ::logout(str_ptr); -# endif -# else -# ifdef HAVE_UTMPX +# endif +# else +# ifdef HAVE_UTMPX struct utmpx l_struct, *ut; -# else +# else struct utmp l_struct, *ut; -# endif +# endif memset(&l_struct, 0, sizeof(l_struct)); strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line)); -# ifdef HAVE_UTMPX +# ifdef HAVE_UTMPX utmpxname(_PATH_UTMPX); setutxent(); if ((ut = getutxline(&l_struct))) { -# else +# else utmpname(_PATH_UTMP); setutent(); if ((ut = getutline(&l_struct))) { -# endif -# ifdef HAVE_UTMPX +# endif +# ifdef HAVE_UTMPX memset(ut->ut_user, 0, sizeof(*ut->ut_user)); -# else +# else memset(ut->ut_name, 0, sizeof(*ut->ut_name)); -# endif +# endif memset(ut->ut_host, 0, sizeof(*ut->ut_host)); -# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN +# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN ut->ut_syslen = 0; -# endif -# ifdef HAVE_STRUCT_UTMP_UT_TYPE +# endif +# ifdef HAVE_STRUCT_UTMP_UT_TYPE ut->ut_type = DEAD_PROCESS; -# endif -# ifdef HAVE_UTMPX +# endif +# ifdef HAVE_UTMPX gettimeofday(&ut->ut_tv, 0); pututxline(ut); } endutxent(); -# else - ut->ut_time = time(nullptr); - pututline(ut); -} -endutent(); -# endif -# endif +# else + ut->ut_time = time(nullptr); + pututline(ut); + } + endutent(); +# endif +# endif #endif } // XXX Supposedly, tc[gs]etattr do not work with the master on Solaris. // Please verify. -bool KPty::tcGetAttr(struct ::termios * ttmode) const +bool KPty::tcGetAttr(struct ::termios *ttmode) const { Q_D(const KPty); return _tcgetattr(d->masterFd, ttmode) == 0; } -bool KPty::tcSetAttr(struct ::termios * ttmode) +bool KPty::tcSetAttr(struct ::termios *ttmode) { Q_D(KPty); @@ -708,7 +702,7 @@ bool KPty::setEcho(bool echo) return tcSetAttr(&ttmode); } -const char * KPty::ttyName() const +const char *KPty::ttyName() const { Q_D(const KPty); diff --git a/lib/kpty.h b/lib/kpty.h index e9f8fa53..18427e43 100644 --- a/lib/kpty.h +++ b/lib/kpty.h @@ -32,11 +32,11 @@ struct termios; * Provides primitives for opening & closing a pseudo TTY pair, assigning the * controlling TTY, utmp registration and setting various terminal attributes. */ -class KPty { +class KPty +{ Q_DECLARE_PRIVATE(KPty) public: - /** * Constructor */ @@ -47,7 +47,7 @@ class KPty { * * If the pty is still open, it will be closed. Note, however, that * an utmp registration is @em not undone. - */ + */ ~KPty(); KPty(const KPty &) = delete; @@ -98,7 +98,7 @@ class KPty { * of the client. For local logins from inside an X session it should * be the name of the X display. Otherwise it should be empty. */ - void login(const char * user = nullptr, const char * remotehost = nullptr); + void login(const char *user = nullptr, const char *remotehost = nullptr); /** * Removes the utmp entry for this tty. @@ -118,7 +118,7 @@ class KPty { * the struct in your class, in your method. * @return @c true on success, false otherwise */ - bool tcGetAttr(struct ::termios * ttmode) const; + bool tcGetAttr(struct ::termios *ttmode) const; /** * Wrapper around tcsetattr(3) with mode TCSANOW. @@ -129,7 +129,7 @@ class KPty { * @return @c true on success, false otherwise. Note that success means * that @em at @em least @em one attribute could be set. */ - bool tcSetAttr(struct ::termios * ttmode); + bool tcSetAttr(struct ::termios *ttmode); /** * Change the logical (screen) size of the pty. @@ -162,7 +162,7 @@ class KPty { * * This function should be called only while the pty is open. */ - const char * ttyName() const; + const char *ttyName() const; /** * @return the file descriptor of the master pty @@ -182,13 +182,12 @@ class KPty { /** * @internal */ - KPty(KPtyPrivate * d); + KPty(KPtyPrivate *d); /** * @internal */ - KPtyPrivate * const d_ptr; + KPtyPrivate *const d_ptr; }; #endif - diff --git a/lib/kpty_p.h b/lib/kpty_p.h index 28ed2a5d..87d665f9 100644 --- a/lib/kpty_p.h +++ b/lib/kpty_p.h @@ -27,19 +27,19 @@ #include -class KPtyPrivate { +class KPtyPrivate +{ public: - Q_DECLARE_PUBLIC(KPty) - KPtyPrivate(KPty* parent); + KPtyPrivate(KPty *parent); virtual ~KPtyPrivate(); bool chownpty(bool grant); int masterFd; int slaveFd; - bool ownMaster:1; + bool ownMaster : 1; QByteArray ttyName; diff --git a/lib/kptydevice.cpp b/lib/kptydevice.cpp index 9af1545d..f34e6f19 100644 --- a/lib/kptydevice.cpp +++ b/lib/kptydevice.cpp @@ -41,26 +41,23 @@ #include #include #ifdef HAVE_SYS_FILIO_H -# include +# include #endif #ifdef HAVE_SYS_TIME_H -# include +# include #endif #if defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) - // "the other end's output queue size" - kinda braindead, huh? -# define PTY_BYTES_AVAILABLE TIOCOUTQ +// "the other end's output queue size" - kinda braindead, huh? +# define PTY_BYTES_AVAILABLE TIOCOUTQ #elif defined(TIOCINQ) - // "our end's input queue size" -# define PTY_BYTES_AVAILABLE TIOCINQ +// "our end's input queue size" +# define PTY_BYTES_AVAILABLE TIOCINQ #else - // likewise. more generic ioctl (theoretically) -# define PTY_BYTES_AVAILABLE FIONREAD +// likewise. more generic ioctl (theoretically) +# define PTY_BYTES_AVAILABLE FIONREAD #endif - - - ////////////////// // private data // ////////////////// @@ -78,7 +75,10 @@ static void qt_ignore_sigpipe() } } -#define NO_INTR(ret,func) do { ret = func; } while (ret < 0 && errno == EINTR) +#define NO_INTR(ret, func) \ + do { \ + ret = func; \ + } while (ret < 0 && errno == EINTR) bool KPtyDevicePrivate::_k_canRead() { @@ -90,7 +90,7 @@ bool KPtyDevicePrivate::_k_canRead() #else int available; #endif - if (::ioctl(q->masterFd(), PTY_BYTES_AVAILABLE, (char *) &available) != -1) { + if (::ioctl(q->masterFd(), PTY_BYTES_AVAILABLE, (char *)&available) != -1) { #ifdef Q_OS_SOLARIS // A Pty is a STREAMS module, and those can be activated // with 0 bytes available. This happens either when ^C is @@ -126,7 +126,7 @@ bool KPtyDevicePrivate::_k_canRead() #endif // Useless block braces except in Solaris { - NO_INTR(readBytes, read(q->masterFd(), ptr, available)); + NO_INTR(readBytes, read(q->masterFd(), ptr, available)); } if (readBytes < 0) { readBuffer.unreserve(available); @@ -160,9 +160,7 @@ bool KPtyDevicePrivate::_k_canWrite() qt_ignore_sigpipe(); int wroteBytes; - NO_INTR(wroteBytes, - write(q->masterFd(), - writeBuffer.readPointer(), writeBuffer.readSize())); + NO_INTR(wroteBytes, write(q->masterFd(), writeBuffer.readPointer(), writeBuffer.readSize())); if (wroteBytes < 0) { q->setErrorString(QLatin1String("Error writing to PTY")); return false; @@ -182,24 +180,24 @@ bool KPtyDevicePrivate::_k_canWrite() #ifndef timeradd // Lifted from GLIBC -# define timeradd(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ - if ((result)->tv_usec >= 1000000) { \ - ++(result)->tv_sec; \ - (result)->tv_usec -= 1000000; \ - } \ - } while (0) -# define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) +# define timeradd(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ + if ((result)->tv_usec >= 1000000) { \ + ++(result)->tv_sec; \ + (result)->tv_usec -= 1000000; \ + } \ + } while (0) +# define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) #endif bool KPtyDevicePrivate::doWait(int msecs, bool reading) @@ -286,11 +284,7 @@ void KPtyDevicePrivate::finishOpen(QIODevice::OpenMode mode) // public member functions // ///////////////////////////// -KPtyDevice::KPtyDevice(QObject *parent) : - QIODevice(parent), - KPty(new KPtyDevicePrivate(this)) -{ -} +KPtyDevice::KPtyDevice(QObject *parent) : QIODevice(parent), KPty(new KPtyDevicePrivate(this)) { } KPtyDevice::~KPtyDevice() { diff --git a/lib/kptydevice.h b/lib/kptydevice.h index 5040400a..ee3048d2 100644 --- a/lib/kptydevice.h +++ b/lib/kptydevice.h @@ -38,20 +38,26 @@ struct KPtyDevicePrivate; class QSocketNotifier; -#define Q_DECLARE_PRIVATE_MI(Class, SuperClass) \ - inline Class##Private* d_func() { return reinterpret_cast(SuperClass::d_ptr); } \ - inline const Class##Private* d_func() const { return reinterpret_cast(SuperClass::d_ptr); } \ +#define Q_DECLARE_PRIVATE_MI(Class, SuperClass) \ + inline Class##Private *d_func() \ + { \ + return reinterpret_cast(SuperClass::d_ptr); \ + } \ + inline const Class##Private *d_func() const \ + { \ + return reinterpret_cast(SuperClass::d_ptr); \ + } \ friend struct Class##Private; /** * Encapsulates KPty into a QIODevice, so it can be used with Q*Stream, etc. */ -class KPtyDevice : public QIODevice, public KPty { +class KPtyDevice : public QIODevice, public KPty +{ Q_OBJECT Q_DECLARE_PRIVATE_MI(KPtyDevice, KPty) public: - /** * Constructor */ @@ -144,7 +150,6 @@ class KPtyDevice : public QIODevice, public KPty { bool waitForBytesWritten(int msecs = -1) override; bool waitForReadyRead(int msecs = -1) override; - Q_SIGNALS: /** * Emitted when EOF is read from the PTY. @@ -175,10 +180,7 @@ class KPtyDevice : public QIODevice, public KPty { class KRingBuffer { public: - KRingBuffer() - { - clear(); - } + KRingBuffer() { clear(); } void clear() { @@ -190,15 +192,9 @@ class KRingBuffer totalSize = 0; } - inline bool isEmpty() const - { - return buffers.size() == 1 && !tail; - } + inline bool isEmpty() const { return buffers.size() == 1 && !tail; } - inline int size() const - { - return totalSize; - } + inline int size() const { return totalSize; } inline int readSize() const { @@ -266,10 +262,7 @@ class KRingBuffer tail -= bytes; } - inline void write(const char *data, int len) - { - memcpy(reserve(len), data, len); - } + inline void write(const char *data, int len) { memcpy(reserve(len), data, len); } // Find the first occurrence of c and return the index after it. // If c is not found until maxLength, maxLength is returned, provided @@ -286,8 +279,7 @@ class KRingBuffer return -1; const QByteArray &buf = *it; ++it; - int len = qMin((it == buffers.cend() ? tail : buf.size()) - start, - maxLength); + int len = qMin((it == buffers.cend() ? tail : buf.size()) - start, maxLength); const char *ptr = buf.data() + start; if (const char *rptr = (const char *)memchr(ptr, c, len)) return index + (rptr - ptr) + 1; @@ -297,15 +289,9 @@ class KRingBuffer } } - inline int lineSize(int maxLength = KMAXINT) const - { - return indexAfter('\n', maxLength); - } + inline int lineSize(int maxLength = KMAXINT) const { return indexAfter('\n', maxLength); } - inline bool canReadLine() const - { - return lineSize() != -1; - } + inline bool canReadLine() const { return lineSize() != -1; } int read(char *data, int maxLength) { @@ -332,14 +318,17 @@ class KRingBuffer int totalSize; }; -struct KPtyDevicePrivate : public KPtyPrivate { +struct KPtyDevicePrivate : public KPtyPrivate +{ Q_DECLARE_PUBLIC(KPtyDevice) - KPtyDevicePrivate(KPty* parent) : - KPtyPrivate(parent), - emittedReadyRead(false), emittedBytesWritten(false), - readNotifier(nullptr), writeNotifier(nullptr) + KPtyDevicePrivate(KPty *parent) + : KPtyPrivate(parent), + emittedReadyRead(false), + emittedBytesWritten(false), + readNotifier(nullptr), + writeNotifier(nullptr) { } @@ -358,4 +347,3 @@ struct KPtyDevicePrivate : public KPtyPrivate { }; #endif - diff --git a/lib/kptyprocess.cpp b/lib/kptyprocess.cpp index 5c829fd1..19084cde 100644 --- a/lib/kptyprocess.cpp +++ b/lib/kptyprocess.cpp @@ -27,7 +27,6 @@ Boston, MA 02110-1301, USA. */ - #include "kptyprocess.h" #include "kprocess.h" #include "kptydevice.h" @@ -37,8 +36,7 @@ #include #include -KPtyProcess::KPtyProcess(QObject *parent) : - KProcess(new KPtyProcessPrivate, parent) +KPtyProcess::KPtyProcess(QObject *parent) : KProcess(new KPtyProcessPrivate, parent) { Q_D(KPtyProcess); @@ -48,8 +46,8 @@ KPtyProcess::KPtyProcess(QObject *parent) : SLOT(_k_onStateChanged(QProcess::ProcessState))); } -KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent) : - KProcess(new KPtyProcessPrivate, parent) +KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent) + : KProcess(new KPtyProcessPrivate, parent) { Q_D(KPtyProcess); @@ -63,20 +61,18 @@ KPtyProcess::~KPtyProcess() { Q_D(KPtyProcess); - if (state() != QProcess::NotRunning) - { - if (d->addUtmp) - { + if (state() != QProcess::NotRunning) { + if (d->addUtmp) { d->pty->logout(); - disconnect(SIGNAL(stateChanged(QProcess::ProcessState)), - this, SLOT(_k_onStateChanged(QProcess::ProcessState))); + disconnect(SIGNAL(stateChanged(QProcess::ProcessState)), this, + SLOT(_k_onStateChanged(QProcess::ProcessState))); } } delete d->pty; waitForFinished(300); // give it some time to finish - if (state() != QProcess::NotRunning) - { - qWarning() << Q_FUNC_INFO << "the terminal process is still running, trying to stop it by SIGHUP"; + if (state() != QProcess::NotRunning) { + qWarning() << Q_FUNC_INFO + << "the terminal process is still running, trying to stop it by SIGHUP"; ::kill(static_cast(processId()), SIGHUP); waitForFinished(300); if (state() != QProcess::NotRunning) diff --git a/lib/kptyprocess.h b/lib/kptyprocess.h index 3491b352..83a7609d 100644 --- a/lib/kptyprocess.h +++ b/lib/kptyprocess.h @@ -102,9 +102,8 @@ class KPtyProcess : public KProcess bool isRunning() const { bool rval; - (processId() > 0) ? rval= true : rval= false; + (processId() > 0) ? rval = true : rval = false; return rval; - } /** * Query to which channels the PTY is assigned. @@ -150,18 +149,14 @@ class KPtyProcess : public KProcess Q_PRIVATE_SLOT(d_func(), void _k_onStateChanged(QProcess::ProcessState)) }; - ////////////////// // private data // ////////////////// -class KPtyProcessPrivate : public KProcessPrivate { +class KPtyProcessPrivate : public KProcessPrivate +{ public: - KPtyProcessPrivate() : - ptyChannels(KPtyProcess::NoChannels), - addUtmp(false) - { - } + KPtyProcessPrivate() : ptyChannels(KPtyProcess::NoChannels), addUtmp(false) { } void _k_onStateChanged(QProcess::ProcessState newState) { diff --git a/lib/qtermwidget.cpp b/lib/qtermwidget.cpp index 54f95e45..26ac642e 100644 --- a/lib/qtermwidget.cpp +++ b/lib/qtermwidget.cpp @@ -35,9 +35,9 @@ #ifdef Q_OS_MACOS // Qt does not support fontconfig on macOS, so we need to use a "real" font name. -#define DEFAULT_FONT_FAMILY "Menlo" +# define DEFAULT_FONT_FAMILY "Menlo" #else -#define DEFAULT_FONT_FAMILY "Monospace" +# define DEFAULT_FONT_FAMILY "Monospace" #endif #define STEP_ZOOM 1 @@ -46,29 +46,29 @@ using namespace Konsole; void *createTermWidget(int startnow, void *parent) { - return (void*) new QTermWidget(startnow, (QWidget*)parent); + return (void *)new QTermWidget(startnow, (QWidget *)parent); } -class TermWidgetImpl { +class TermWidgetImpl +{ public: - TermWidgetImpl(QWidget* parent = nullptr); + TermWidgetImpl(QWidget *parent = nullptr); TerminalDisplay *m_terminalDisplay; Session *m_session; - Session* createSession(QWidget* parent); - TerminalDisplay* createTerminalDisplay(Session *session, QWidget* parent); + Session *createSession(QWidget *parent); + TerminalDisplay *createTerminalDisplay(Session *session, QWidget *parent); }; -TermWidgetImpl::TermWidgetImpl(QWidget* parent) +TermWidgetImpl::TermWidgetImpl(QWidget *parent) { this->m_session = createSession(parent); this->m_terminalDisplay = createTerminalDisplay(this->m_session, parent); } - -Session *TermWidgetImpl::createSession(QWidget* parent) +Session *TermWidgetImpl::createSession(QWidget *parent) { Session *session = new Session(parent); @@ -79,14 +79,13 @@ Session *TermWidgetImpl::createSession(QWidget* parent) * better set it to the current $SHELL * Maybe you can also make a list available and then let the widget-owner decide what to use. * By setting it to $SHELL right away we actually make the first filecheck obsolete. - * But as iam not sure if you want to do anything else ill just let both checks in and set this to $SHELL anyway. + * But as iam not sure if you want to do anything else ill just let both checks in and set this + * to $SHELL anyway. */ - //session->setProgram("/bin/bash"); + // session->setProgram("/bin/bash"); session->setProgram(QString::fromLocal8Bit(qgetenv("SHELL"))); - - QStringList args = QStringList(QString()); session->setArguments(args); session->setAutoClose(true); @@ -102,10 +101,10 @@ Session *TermWidgetImpl::createSession(QWidget* parent) return session; } -TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget* parent) +TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget *parent) { -// TerminalDisplay* display = new TerminalDisplay(this); - TerminalDisplay* display = new TerminalDisplay(parent); + // TerminalDisplay* display = new TerminalDisplay(this); + TerminalDisplay *display = new TerminalDisplay(parent); display->setBellMode(TerminalDisplay::NotifyBell); display->setTerminalSizeHint(true); @@ -117,15 +116,12 @@ TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget return display; } - -QTermWidget::QTermWidget(int startnow, QWidget *parent) - : QWidget(parent) +QTermWidget::QTermWidget(int startnow, QWidget *parent) : QWidget(parent) { init(startnow); } -QTermWidget::QTermWidget(QWidget *parent) - : QWidget(parent) +QTermWidget::QTermWidget(QWidget *parent) : QWidget(parent) { init(1); } @@ -156,34 +152,37 @@ void QTermWidget::search(bool forwards, bool next) if (next) // search from just after current selection { - m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionEnd(startColumn, startLine); + m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionEnd(startColumn, + startLine); startColumn++; - } - else // search from start of current selection + } else // search from start of current selection { - m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionStart(startColumn, startLine); + m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionStart(startColumn, + startLine); } - //qDebug() << "current selection starts at: " << startColumn << startLine; - //qDebug() << "current cursor position: " << m_impl->m_terminalDisplay->screenWindow()->cursorPosition(); + // qDebug() << "current selection starts at: " << startColumn << startLine; + // qDebug() << "current cursor position: " << + // m_impl->m_terminalDisplay->screenWindow()->cursorPosition(); QRegExp regExp(m_searchBar->searchText()); - regExp.setPatternSyntax(m_searchBar->useRegularExpression() ? QRegExp::RegExp : QRegExp::FixedString); + regExp.setPatternSyntax(m_searchBar->useRegularExpression() ? QRegExp::RegExp + : QRegExp::FixedString); regExp.setCaseSensitivity(m_searchBar->matchCase() ? Qt::CaseSensitive : Qt::CaseInsensitive); - HistorySearch *historySearch = - new HistorySearch(m_impl->m_session->emulation(), regExp, forwards, startColumn, startLine, this); - connect(historySearch, SIGNAL(matchFound(int, int, int, int)), this, SLOT(matchFound(int, int, int, int))); + HistorySearch *historySearch = new HistorySearch(m_impl->m_session->emulation(), regExp, + forwards, startColumn, startLine, this); + connect(historySearch, SIGNAL(matchFound(int, int, int, int)), this, + SLOT(matchFound(int, int, int, int))); connect(historySearch, SIGNAL(noMatchFound()), this, SLOT(noMatchFound())); connect(historySearch, SIGNAL(noMatchFound()), m_searchBar, SLOT(noMatchFound())); historySearch->search(); } - void QTermWidget::matchFound(int startColumn, int startLine, int endColumn, int endLine) { - ScreenWindow* sw = m_impl->m_terminalDisplay->screenWindow(); - //qDebug() << "Scroll to" << startLine; + ScreenWindow *sw = m_impl->m_terminalDisplay->screenWindow(); + // qDebug() << "Scroll to" << startLine; sw->scrollTo(startLine); sw->setTrackOutput(false); sw->notifyOutputChanged(); @@ -193,7 +192,7 @@ void QTermWidget::matchFound(int startColumn, int startLine, int endColumn, int void QTermWidget::noMatchFound() { - m_impl->m_terminalDisplay->screenWindow()->clearSelection(); + m_impl->m_terminalDisplay->screenWindow()->clearSelection(); } int QTermWidget::getShellPID() @@ -201,7 +200,7 @@ int QTermWidget::getShellPID() return m_impl->m_session->processId(); } -void QTermWidget::changeDir(const QString & dir) +void QTermWidget::changeDir(const QString &dir) { /* this is a very hackish way of trying to determine if the shell is in @@ -239,7 +238,7 @@ bool QTermWidget::terminalSizeHint() void QTermWidget::startShellProgram() { - if ( m_impl->m_session->isRunning() ) { + if (m_impl->m_session->isRunning()) { return; } @@ -248,14 +247,14 @@ void QTermWidget::startShellProgram() void QTermWidget::startTerminalTeletype() { - if ( m_impl->m_session->isRunning() ) { + if (m_impl->m_session->isRunning()) { return; } m_impl->m_session->runEmptyPTY(); // redirect data from TTY to external recipient - connect( m_impl->m_session->emulation(), SIGNAL(sendData(const char *,int)), - this, SIGNAL(sendData(const char *,int)) ); + connect(m_impl->m_session->emulation(), SIGNAL(sendData(const char *, int)), this, + SIGNAL(sendData(const char *, int))); } void QTermWidget::init(int startnow) @@ -276,11 +275,12 @@ void QTermWidget::init(int startnow) m_translator = new QTranslator(this); - for (const QString& dir : qAsConst(dirs)) { - //qDebug() << "Trying to load translation file from dir" << dir; - if (m_translator->load(QLocale::system(), QLatin1String("qtermwidget"), QLatin1String(QLatin1String("_")), dir)) { + for (const QString &dir : qAsConst(dirs)) { + // qDebug() << "Trying to load translation file from dir" << dir; + if (m_translator->load(QLocale::system(), QLatin1String("qtermwidget"), + QLatin1String(QLatin1String("_")), dir)) { qApp->installTranslator(m_translator); - //qDebug() << "Translations found in" << dir; + // qDebug() << "Translations found in" << dir; break; } } @@ -288,12 +288,14 @@ void QTermWidget::init(int startnow) m_impl = new TermWidgetImpl(this); m_layout->addWidget(m_impl->m_terminalDisplay); - connect(m_impl->m_session, SIGNAL(bellRequest(QString)), m_impl->m_terminalDisplay, SLOT(bell(QString))); + connect(m_impl->m_session, SIGNAL(bellRequest(QString)), m_impl->m_terminalDisplay, + SLOT(bell(QString))); connect(m_impl->m_terminalDisplay, SIGNAL(notifyBell(QString)), this, SIGNAL(bell(QString))); connect(m_impl->m_session, SIGNAL(activity()), this, SIGNAL(activity())); connect(m_impl->m_session, SIGNAL(silence()), this, SIGNAL(silence())); - connect(m_impl->m_session, &Session::profileChangeCommandReceived, this, &QTermWidget::profileChanged); + connect(m_impl->m_session, &Session::profileChangeCommandReceived, this, + &QTermWidget::profileChanged); connect(m_impl->m_session, &Session::receivedData, this, &QTermWidget::receivedData); // That's OK, FilterChain's dtor takes care of UrlFilter. @@ -313,20 +315,18 @@ void QTermWidget::init(int startnow) m_impl->m_session->run(); } - this->setFocus( Qt::OtherFocusReason ); - this->setFocusPolicy( Qt::WheelFocus ); + this->setFocus(Qt::OtherFocusReason); + this->setFocusPolicy(Qt::WheelFocus); m_impl->m_terminalDisplay->resize(this->size()); this->setFocusProxy(m_impl->m_terminalDisplay); - connect(m_impl->m_terminalDisplay, SIGNAL(copyAvailable(bool)), - this, SLOT(selectionChanged(bool))); - connect(m_impl->m_terminalDisplay, SIGNAL(termGetFocus()), - this, SIGNAL(termGetFocus())); - connect(m_impl->m_terminalDisplay, SIGNAL(termLostFocus()), - this, SIGNAL(termLostFocus())); + connect(m_impl->m_terminalDisplay, SIGNAL(copyAvailable(bool)), this, + SLOT(selectionChanged(bool))); + connect(m_impl->m_terminalDisplay, SIGNAL(termGetFocus()), this, SIGNAL(termGetFocus())); + connect(m_impl->m_terminalDisplay, SIGNAL(termLostFocus()), this, SIGNAL(termLostFocus())); connect(m_impl->m_terminalDisplay, &TerminalDisplay::keyPressedSignal, - [this] (QKeyEvent* e, bool) { Q_EMIT termKeyPressed(e); }); -// m_impl->m_terminalDisplay->setSize(80, 40); + [this](QKeyEvent *e, bool) { Q_EMIT termKeyPressed(e); }); + // m_impl->m_terminalDisplay->setSize(80, 40); QFont font = QApplication::font(); font.setFamily(QLatin1String(DEFAULT_FONT_FAMILY)); @@ -346,14 +346,12 @@ void QTermWidget::init(int startnow) connect(m_impl->m_session, &Session::cursorChanged, this, &QTermWidget::cursorChanged); } - QTermWidget::~QTermWidget() { delete m_impl; emit destroyed(); } - void QTermWidget::setTerminalFont(const QFont &font) { m_impl->m_terminalDisplay->setVTFont(font); @@ -369,7 +367,7 @@ void QTermWidget::setTerminalOpacity(qreal level) m_impl->m_terminalDisplay->setOpacity(level); } -void QTermWidget::setTerminalBackgroundImage(const QString& backgroundImage) +void QTermWidget::setTerminalBackgroundImage(const QString &backgroundImage) { m_impl->m_terminalDisplay->setBackgroundImage(backgroundImage); } @@ -386,7 +384,7 @@ void QTermWidget::setShellProgram(const QString &program) m_impl->m_session->setProgram(program); } -void QTermWidget::setWorkingDirectory(const QString& dir) +void QTermWidget::setWorkingDirectory(const QString &dir) { if (!m_impl->m_session) return; @@ -399,12 +397,11 @@ QString QTermWidget::workingDirectory() return QString(); #ifdef Q_OS_LINUX - // Christian Surlykke: On linux we could look at /proc//cwd which should be a link to current - // working directory (: process id of the shell). I don't know about BSD. - // Maybe we could just offer it when running linux, for a start. + // Christian Surlykke: On linux we could look at /proc//cwd which should be a link to + // current working directory (: process id of the shell). I don't know about BSD. Maybe we + // could just offer it when running linux, for a start. QDir d(QString::fromLatin1("/proc/%1/cwd").arg(getShellPID())); - if (!d.exists()) - { + if (!d.exists()) { qDebug() << "Cannot find" << d.dirName(); goto fallback; } @@ -430,38 +427,29 @@ void QTermWidget::setTextCodec(QTextCodec *codec) m_impl->m_session->setCodec(codec); } -void QTermWidget::setColorScheme(const QString& origName) +void QTermWidget::setColorScheme(const QString &origName) { const ColorScheme *cs = nullptr; const bool isFile = QFile::exists(origName); - const QString& name = isFile ? - QFileInfo(origName).baseName() : - origName; + const QString &name = isFile ? QFileInfo(origName).baseName() : origName; // avoid legacy (int) solution - if (!availableColorSchemes().contains(name)) - { - if (isFile) - { + if (!availableColorSchemes().contains(name)) { + if (isFile) { if (ColorSchemeManager::instance()->loadCustomColorScheme(origName)) cs = ColorSchemeManager::instance()->findColorScheme(name); else - qWarning () << Q_FUNC_INFO - << "cannot load color scheme from" - << origName; + qWarning() << Q_FUNC_INFO << "cannot load color scheme from" << origName; } if (!cs) cs = ColorSchemeManager::instance()->defaultColorScheme(); - } - else + } else cs = ColorSchemeManager::instance()->findColorScheme(name); - if (! cs) - { - QMessageBox::information(this, - tr("Color Scheme Error"), + if (!cs) { + QMessageBox::information(this, tr("Color Scheme Error"), tr("Cannot load color scheme: %1").arg(name)); return; } @@ -474,12 +462,12 @@ QStringList QTermWidget::availableColorSchemes() { QStringList ret; const auto allColorSchemes = ColorSchemeManager::instance()->allColorSchemes(); - for (const ColorScheme* cs : allColorSchemes) + for (const ColorScheme *cs : allColorSchemes) ret.append(cs->name()); return ret; } -void QTermWidget::addCustomColorSchemeDir(const QString& custom_dir) +void QTermWidget::addCustomColorSchemeDir(const QString &custom_dir) { ColorSchemeManager::instance()->addCustomColorSchemeDir(custom_dir); } @@ -501,17 +489,17 @@ void QTermWidget::setHistorySize(int lines) int QTermWidget::historySize() const { - const HistoryType& currentHistory = m_impl->m_session->historyType(); + const HistoryType ¤tHistory = m_impl->m_session->historyType(); - if (currentHistory.isEnabled()) { - if (currentHistory.isUnlimited()) { - return -1; - } else { - return currentHistory.maximumLineCount(); - } - } else { - return 0; - } + if (currentHistory.isEnabled()) { + if (currentHistory.isUnlimited()) { + return -1; + } else { + return currentHistory.maximumLineCount(); + } + } else { + return 0; + } } void QTermWidget::setScrollBarPosition(ScrollBarPosition pos) @@ -534,19 +522,18 @@ void QTermWidget::sendKeyEvent(QKeyEvent *e) m_impl->m_session->sendKeyEvent(e); } -void QTermWidget::resizeEvent(QResizeEvent*) +void QTermWidget::resizeEvent(QResizeEvent *) { -//qDebug("global window resizing...with %d %d", this->size().width(), this->size().height()); + // qDebug("global window resizing...with %d %d", this->size().width(), this->size().height()); m_impl->m_terminalDisplay->resize(this->size()); } - void QTermWidget::sessionFinished() { emit finished(); } -void QTermWidget::bracketText(QString& text) +void QTermWidget::bracketText(QString &text) { m_impl->m_terminalDisplay->bracketText(text); } @@ -594,7 +581,7 @@ void QTermWidget::zoomOut() setZoom(-STEP_ZOOM); } -void QTermWidget::setKeyBindings(const QString & kb) +void QTermWidget::setKeyBindings(const QString &kb) { m_impl->m_session->setKeyBindings(kb); } @@ -639,14 +626,14 @@ void QTermWidget::setFlowControlWarningEnabled(bool enabled) } } -void QTermWidget::setEnvironment(const QStringList& environment) +void QTermWidget::setEnvironment(const QStringList &environment) { m_impl->m_session->setEnvironment(environment); } void QTermWidget::setMotionAfterPasting(int action) { - m_impl->m_terminalDisplay->setMotionAfterPasting((Konsole::MotionAfterPasting) action); + m_impl->m_terminalDisplay->setMotionAfterPasting((Konsole::MotionAfterPasting)action); } int QTermWidget::historyLinesCount() @@ -674,12 +661,12 @@ void QTermWidget::setSelectionEnd(int row, int column) m_impl->m_terminalDisplay->screenWindow()->screen()->setSelectionEnd(column, row); } -void QTermWidget::getSelectionStart(int& row, int& column) +void QTermWidget::getSelectionStart(int &row, int &column) { m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionStart(column, row); } -void QTermWidget::getSelectionEnd(int& row, int& column) +void QTermWidget::getSelectionEnd(int &row, int &column) { m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionEnd(column, row); } @@ -704,19 +691,19 @@ void QTermWidget::setSilenceTimeout(int seconds) m_impl->m_session->setMonitorSilenceSeconds(seconds); } -Filter::HotSpot* QTermWidget::getHotSpotAt(const QPoint &pos) const +Filter::HotSpot *QTermWidget::getHotSpotAt(const QPoint &pos) const { int row = 0, column = 0; m_impl->m_terminalDisplay->getCharacterPosition(pos, row, column); return getHotSpotAt(row, column); } -Filter::HotSpot* QTermWidget::getHotSpotAt(int row, int column) const +Filter::HotSpot *QTermWidget::getHotSpotAt(int row, int column) const { return m_impl->m_terminalDisplay->filterChain()->hotSpotAt(row, column); } -QList QTermWidget::filterActions(const QPoint& position) +QList QTermWidget::filterActions(const QPoint &position) { return m_impl->m_terminalDisplay->filterActions(position); } @@ -772,7 +759,8 @@ void QTermWidget::setAutoClose(bool enabled) m_impl->m_session->setAutoClose(enabled); } -void QTermWidget::cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) +void QTermWidget::cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, + bool blinkingCursorEnabled) { // TODO: A switch to enable/disable DECSCUSR? setKeyboardCursorShape(cursorShape); @@ -794,7 +782,8 @@ void QTermWidget::saveHistory(QIODevice *device) QTextStream stream(device); PlainTextDecoder decoder; decoder.begin(&stream); - m_impl->m_session->emulation()->writeToStream(&decoder, 0, m_impl->m_session->emulation()->lineCount()); + m_impl->m_session->emulation()->writeToStream(&decoder, 0, + m_impl->m_session->emulation()->lineCount()); } void QTermWidget::setDrawLineChars(bool drawLineChars) @@ -807,10 +796,12 @@ void QTermWidget::setBoldIntense(bool boldIntense) m_impl->m_terminalDisplay->setBoldIntense(boldIntense); } -void QTermWidget::setConfirmMultilinePaste(bool confirmMultilinePaste) { +void QTermWidget::setConfirmMultilinePaste(bool confirmMultilinePaste) +{ m_impl->m_terminalDisplay->setConfirmMultilinePaste(confirmMultilinePaste); } -void QTermWidget::setTrimPastedTrailingNewlines(bool trimPastedTrailingNewlines) { +void QTermWidget::setTrimPastedTrailingNewlines(bool trimPastedTrailingNewlines) +{ m_impl->m_terminalDisplay->setTrimPastedTrailingNewlines(trimPastedTrailingNewlines); } diff --git a/lib/qtermwidget.h b/lib/qtermwidget.h index dd9be66f..563ab193 100644 --- a/lib/qtermwidget.h +++ b/lib/qtermwidget.h @@ -16,7 +16,6 @@ Boston, MA 02110-1301, USA. */ - #ifndef _Q_TERM_WIDGET #define _Q_TERM_WIDGET @@ -32,10 +31,10 @@ class TermWidgetImpl; class SearchBar; class QUrl; -class QTERMWIDGET_EXPORT QTermWidget : public QWidget { +class QTERMWIDGET_EXPORT QTermWidget : public QWidget +{ Q_OBJECT public: - /** * This enum describes the location where the scroll bar is positioned in the display widget. */ @@ -50,22 +49,22 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { using KeyboardCursorShape = Konsole::Emulation::KeyboardCursorShape; - //Creation of widget + // Creation of widget QTermWidget(int startnow, // 1 = start shell programm immediatelly - QWidget * parent = nullptr); + QWidget *parent = nullptr); // A dummy constructor for Qt Designer. startnow is 1 by default QTermWidget(QWidget *parent = nullptr); ~QTermWidget() override; - //Initial size + // Initial size QSize sizeHint() const override; // expose TerminalDisplay::TerminalSizeHint, setTerminalSizeHint void setTerminalSizeHint(bool enabled); bool terminalSizeHint(); - //start shell program if it was not started in constructor + // start shell program if it was not started in constructor void startShellProgram(); /** @@ -77,43 +76,43 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { int getShellPID(); - void changeDir(const QString & dir); + void changeDir(const QString &dir); - //look-n-feel, if you don`t like defaults + // look-n-feel, if you don`t like defaults // Terminal font // Default is application font with family Monospace, size 10 // Beware of a performance penalty and display/alignment issues when using a proportional font. - void setTerminalFont(const QFont & font); + void setTerminalFont(const QFont &font); QFont getTerminalFont(); void setTerminalOpacity(qreal level); - void setTerminalBackgroundImage(const QString& backgroundImage); + void setTerminalBackgroundImage(const QString &backgroundImage); void setTerminalBackgroundMode(int mode); - //environment - void setEnvironment(const QStringList & environment); + // environment + void setEnvironment(const QStringList &environment); // Shell program, default is /bin/bash - void setShellProgram(const QString & program); + void setShellProgram(const QString &program); - //working directory - void setWorkingDirectory(const QString & dir); + // working directory + void setWorkingDirectory(const QString &dir); QString workingDirectory(); // Shell program args, default is none - void setArgs(const QStringList & args); + void setArgs(const QStringList &args); - //Text codec, default is UTF-8 - void setTextCodec(QTextCodec * codec); + // Text codec, default is UTF-8 + void setTextCodec(QTextCodec *codec); /** @brief Sets the color scheme, default is white on black * * @param[in] name The name of the color scheme, either returned from * availableColorSchemes() or a full path to a color scheme. */ - void setColorScheme(const QString & name); + void setColorScheme(const QString &name); static QStringList availableColorSchemes(); - static void addCustomColorSchemeDir(const QString& custom_dir); + static void addCustomColorSchemeDir(const QString &custom_dir); /** Sets the history size (in lines) * @@ -133,10 +132,10 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { void scrollToEnd(); // Send some text to terminal - void sendText(const QString & text); + void sendText(const QString &text); // Send key event to terminal - void sendKeyEvent(QKeyEvent* e); + void sendKeyEvent(QKeyEvent *e); // Sets whether flow control is enabled void setFlowControlEnabled(bool enabled); @@ -167,8 +166,8 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { void setSelectionStart(int row, int column); void setSelectionEnd(int row, int column); - void getSelectionStart(int& row, int& column); - void getSelectionEnd(int& row, int& column); + void getSelectionStart(int &row, int &column); + void getSelectionEnd(int &row, int &column); /** * Returns the currently selected text. @@ -188,18 +187,18 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { * @param[in] pos The point of interest in the QTermWidget coordinates. * @return Hotspot for the given position, or nullptr if no hotspot. */ - Filter::HotSpot* getHotSpotAt(const QPoint& pos) const; + Filter::HotSpot *getHotSpotAt(const QPoint &pos) const; /** Returns the available hotspots for the given row and column. * * @return Hotspot for the given position, or nullptr if no hotspot. */ - Filter::HotSpot* getHotSpotAt(int row, int column) const; + Filter::HotSpot *getHotSpotAt(int row, int column) const; /* * Proxy for TerminalDisplay::filterActions * */ - QList filterActions(const QPoint& position); + QList filterActions(const QPoint &position); /** * Returns a pty slave file descriptor. @@ -233,7 +232,7 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { bool isTitleChanged() const; /** change and wrap text corresponding to paste mode **/ - void bracketText(QString& text); + void bracketText(QString &text); /** forcefully disable bracketed paste mode **/ void disableBracketedPasteMode(bool disable); @@ -260,9 +259,9 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { void termKeyPressed(QKeyEvent *); - void urlActivated(const QUrl&, bool fromContextMenu); + void urlActivated(const QUrl &, bool fromContextMenu); - void bell(const QString& message); + void bell(const QString &message); void activity(); void silence(); @@ -272,9 +271,9 @@ class QTERMWIDGET_EXPORT QTermWidget : public QWidget { * (redirected for external recipient). It can be used for * control and display the remote terminal. */ - void sendData(const char *,int); + void sendData(const char *, int); - void profileChanged(const QString & profile); + void profileChanged(const QString &profile); void titleChanged(); @@ -303,7 +302,7 @@ public slots: /*! Set named key binding for given widget */ - void setKeyBindings(const QString & kb); + void setKeyBindings(const QString &kb); /*! Clear the terminal content and move to home position */ @@ -312,6 +311,7 @@ public slots: void toggleShowSearchBar(); void saveHistory(QIODevice *device); + protected: void resizeEvent(QResizeEvent *) override; @@ -329,25 +329,25 @@ private slots: * Emulation::cursorChanged() signal propogates to here and QTermWidget * sends the specified cursor states to the terminal display */ - void cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); + void cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, + bool blinkingCursorEnabled); private: void search(bool forwards, bool next); void setZoom(int step); void init(int startnow); - TermWidgetImpl * m_impl; - SearchBar* m_searchBar; + TermWidgetImpl *m_impl; + SearchBar *m_searchBar; QVBoxLayout *m_layout; QTranslator *m_translator; }; - -//Maybe useful, maybe not +// Maybe useful, maybe not #ifdef __cplusplus extern "C" #endif -void * createTermWidget(int startnow, void * parent); + void * + createTermWidget(int startnow, void *parent); #endif - diff --git a/lib/tools.cpp b/lib/tools.cpp index 4291fae6..09bc1e64 100644 --- a/lib/tools.cpp +++ b/lib/tools.cpp @@ -4,7 +4,6 @@ #include #include - Q_LOGGING_CATEGORY(qtermwidgetLogger, "qtermwidget", QtWarningMsg) /*! Helper function to get possible location of layout files. @@ -13,16 +12,15 @@ But in some cases (apple bundle) there can be more locations). */ QString get_kb_layout_dir() { -// qDebug() << __FILE__ << __FUNCTION__; + // qDebug() << __FILE__ << __FUNCTION__; QString rval = QString(); QString k(QLatin1String(KB_LAYOUT_DIR)); QDir d(k); - //qDebug() << "default KB_LAYOUT_DIR: " << k; + // qDebug() << "default KB_LAYOUT_DIR: " << k; - if (d.exists()) - { + if (d.exists()) { rval = k.append(QLatin1Char('/')); return rval; } @@ -30,7 +28,7 @@ QString get_kb_layout_dir() #ifdef Q_OS_MAC // subdir in the app location d.setPath(QCoreApplication::applicationDirPath() + QLatin1String("/kb-layouts/")); - //qDebug() << d.path(); + // qDebug() << d.path(); if (d.exists()) return QCoreApplication::applicationDirPath() + QLatin1String("/kb-layouts/"); @@ -38,16 +36,16 @@ QString get_kb_layout_dir() if (d.exists()) return QCoreApplication::applicationDirPath() + QLatin1String("/../Resources/kb-layouts/"); #endif - //qDebug() << "Cannot find KB_LAYOUT_DIR. Default:" << k; + // qDebug() << "Cannot find KB_LAYOUT_DIR. Default:" << k; return QString(); } /*! Helper function to add custom location of color schemes. -*/ + */ namespace { - QStringList custom_color_schemes_dirs; +QStringList custom_color_schemes_dirs; } -void add_custom_color_scheme_dir(const QString& custom_dir) +void add_custom_color_scheme_dir(const QString &custom_dir) { if (!custom_color_schemes_dirs.contains(custom_dir)) custom_color_schemes_dirs << custom_dir; @@ -59,13 +57,13 @@ But in some cases (apple bundle) there can be more locations). */ const QStringList get_color_schemes_dirs() { -// qDebug() << __FILE__ << __FUNCTION__; + // qDebug() << __FILE__ << __FUNCTION__; QStringList rval; QString k(QLatin1String(COLORSCHEMES_DIR)); QDir d(k); -// qDebug() << "default COLORSCHEMES_DIR: " << k; + // qDebug() << "default COLORSCHEMES_DIR: " << k; if (d.exists()) rval << k.append(QLatin1Char('/')); @@ -73,30 +71,29 @@ const QStringList get_color_schemes_dirs() #ifdef Q_OS_MAC // subdir in the app location d.setPath(QCoreApplication::applicationDirPath() + QLatin1String("/color-schemes/")); - //qDebug() << d.path(); - if (d.exists()) - { + // qDebug() << d.path(); + if (d.exists()) { if (!rval.isEmpty()) rval.clear(); rval << (QCoreApplication::applicationDirPath() + QLatin1String("/color-schemes/")); } - d.setPath(QCoreApplication::applicationDirPath() + QLatin1String("/../Resources/color-schemes/")); - if (d.exists()) - { + d.setPath(QCoreApplication::applicationDirPath() + + QLatin1String("/../Resources/color-schemes/")); + if (d.exists()) { if (!rval.isEmpty()) rval.clear(); - rval << (QCoreApplication::applicationDirPath() + QLatin1String("/../Resources/color-schemes/")); + rval << (QCoreApplication::applicationDirPath() + + QLatin1String("/../Resources/color-schemes/")); } #endif - for (const QString& custom_dir : qAsConst(custom_color_schemes_dirs)) - { + for (const QString &custom_dir : qAsConst(custom_color_schemes_dirs)) { d.setPath(custom_dir); if (d.exists()) rval << custom_dir; } #ifdef QT_DEBUG - if(!rval.isEmpty()) { + if (!rval.isEmpty()) { qDebug() << "Using color-schemes: " << rval; } else { qDebug() << "Cannot find color-schemes in any location!"; diff --git a/lib/tools.h b/lib/tools.h index 239689bd..627abe1a 100644 --- a/lib/tools.h +++ b/lib/tools.h @@ -6,7 +6,7 @@ #include QString get_kb_layout_dir(); -void add_custom_color_scheme_dir(const QString& custom_dir); +void add_custom_color_scheme_dir(const QString &custom_dir); const QStringList get_color_schemes_dirs(); Q_DECLARE_LOGGING_CATEGORY(qtermwidgetLogger)