mirror of
https://github.com/Swordfish90/cool-retro-term.git
synced 2025-01-18 12:15:27 +00:00
Switched to my version of yat
This commit is contained in:
parent
c8cb00d240
commit
735d1e5dbb
10
yat/.gitignore
vendored
Normal file
10
yat/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
Makefile
|
||||
.moc
|
||||
.obj
|
||||
yat
|
||||
yat.pro.user
|
||||
yat.pro.user.1.3
|
||||
yat.pro.user.2.6pre1
|
||||
yat_declarative/qrc_qml_sources.cpp
|
||||
|
||||
|
6
yat/README
Normal file
6
yat/README
Normal file
@ -0,0 +1,6 @@
|
||||
YAT is a terminal emulator written in qml and c++
|
||||
|
||||
The main goal of the project was to find out if it was possible to use qml to
|
||||
write a terminal emulator which performed on par with xterm and konsole.
|
||||
|
||||
Turns out, it's possible.
|
31
yat/backend/backend.pri
Normal file
31
yat/backend/backend.pri
Normal file
@ -0,0 +1,31 @@
|
||||
DEPENDPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
LIBS += -lutil -L/home/jlind/install/lib
|
||||
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = .obj
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/yat_pty.h \
|
||||
$$PWD/text.h \
|
||||
$$PWD/controll_chars.h \
|
||||
$$PWD/parser.h \
|
||||
$$PWD/screen.h \
|
||||
$$PWD/line.h \
|
||||
$$PWD/color_palette.h \
|
||||
$$PWD/text_style.h \
|
||||
$$PWD/update_action.h \
|
||||
$$PWD/screen_data.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/yat_pty.cpp \
|
||||
$$PWD/text.cpp \
|
||||
$$PWD/controll_chars.cpp \
|
||||
$$PWD/parser.cpp \
|
||||
$$PWD/screen.cpp \
|
||||
$$PWD/line.cpp \
|
||||
$$PWD/color_palette.cpp \
|
||||
$$PWD/text_style.cpp \
|
||||
$$PWD/update_action.cpp \
|
||||
$$PWD/screen_data.cpp
|
49
yat/backend/color_palette.cpp
Normal file
49
yat/backend/color_palette.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "color_palette.h"
|
||||
|
||||
ColorPalette::ColorPalette()
|
||||
: m_normalColors(numberOfColors)
|
||||
, m_lightColors(numberOfColors)
|
||||
, m_intenseColors(numberOfColors)
|
||||
{
|
||||
m_normalColors[0].setRgb(0,0,0);
|
||||
m_normalColors[1].setRgb(194,54,33);
|
||||
m_normalColors[2].setRgb(37,188,36);
|
||||
m_normalColors[3].setRgb(173,173,39);
|
||||
m_normalColors[4].setRgb(63,84,255);
|
||||
m_normalColors[5].setRgb(211,56,211);
|
||||
m_normalColors[6].setRgb(51,187,199);
|
||||
m_normalColors[7].setRgb(229,229,229);
|
||||
m_normalColors[8].setRgb(178,178,178);
|
||||
m_normalColors[9].setAlpha(0);
|
||||
|
||||
m_lightColors[0].setRgb(129,131,131);
|
||||
m_lightColors[1].setRgb(252,57,31);
|
||||
m_lightColors[2].setRgb(49,231,34);
|
||||
m_lightColors[3].setRgb(234,236,35);
|
||||
m_lightColors[4].setRgb(88,51,255);
|
||||
m_lightColors[5].setRgb(249,53,248);
|
||||
m_lightColors[6].setRgb(20,240,240);
|
||||
m_lightColors[7].setRgb(233,233,233);
|
||||
m_lightColors[8].setRgb(220,220,220);
|
||||
m_lightColors[9].setRgb(50,50,50);
|
||||
|
||||
}
|
||||
|
||||
QColor ColorPalette::color(ColorPalette::Color color, bool bold) const
|
||||
{
|
||||
if (bold)
|
||||
return m_lightColors.at(color);
|
||||
|
||||
return m_normalColors.at(color);
|
||||
}
|
||||
|
||||
QColor ColorPalette::normalColor(ColorPalette::Color color) const
|
||||
{
|
||||
return m_normalColors.at(color);
|
||||
}
|
||||
|
||||
QColor ColorPalette::lightColor(ColorPalette::Color color) const
|
||||
{
|
||||
return m_lightColors.at(color);
|
||||
}
|
||||
|
38
yat/backend/color_palette.h
Normal file
38
yat/backend/color_palette.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef COLOR_PALETTE_H
|
||||
#define COLOR_PALETTE_H
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include <QtGui/QColor>
|
||||
|
||||
class ColorPalette
|
||||
{
|
||||
public:
|
||||
ColorPalette();
|
||||
|
||||
|
||||
enum Color {
|
||||
Black,
|
||||
Red,
|
||||
Green,
|
||||
Yellow,
|
||||
Blue,
|
||||
Magenta,
|
||||
Cyan,
|
||||
White,
|
||||
DefaultForground,
|
||||
DefaultBackground,
|
||||
numberOfColors
|
||||
};
|
||||
|
||||
QColor color(Color color, bool bold) const;
|
||||
QColor normalColor(Color color) const;
|
||||
QColor lightColor(Color color) const;
|
||||
|
||||
private:
|
||||
QVector<QColor> m_normalColors;
|
||||
QVector<QColor> m_lightColors;
|
||||
QVector<QColor> m_intenseColors;
|
||||
};
|
||||
|
||||
#endif // COLOR_PALETTE_H
|
776
yat/backend/controll_chars.cpp
Normal file
776
yat/backend/controll_chars.cpp
Normal file
@ -0,0 +1,776 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#include "controll_chars.h"
|
||||
|
||||
namespace C0 {
|
||||
QDebug operator<<(QDebug debug, C0 character) {
|
||||
bool insert_space = debug.autoInsertSpaces();
|
||||
debug.setAutoInsertSpaces(false);
|
||||
debug << "C0::";
|
||||
switch (character) {
|
||||
case NUL:
|
||||
debug << "NUL";
|
||||
break;
|
||||
case SOH:
|
||||
debug << "SOH";
|
||||
break;
|
||||
case STX:
|
||||
debug << "STX";
|
||||
break;
|
||||
case ETX:
|
||||
debug << "ETX";
|
||||
break;
|
||||
case EOT:
|
||||
debug << "EOT";
|
||||
break;
|
||||
case ENQ:
|
||||
debug << "ENQ";
|
||||
break;
|
||||
case ACK:
|
||||
debug << "ACK";
|
||||
break;
|
||||
case BEL:
|
||||
debug << "BEL";
|
||||
break;
|
||||
case BS:
|
||||
debug << "BS";
|
||||
break;
|
||||
case HT:
|
||||
debug << "HT";
|
||||
break;
|
||||
case LF:
|
||||
debug << "LF";
|
||||
break;
|
||||
case VT:
|
||||
debug << "VT";
|
||||
break;
|
||||
case FF:
|
||||
debug << "FF";
|
||||
break;
|
||||
case CR:
|
||||
debug << "CR";
|
||||
break;
|
||||
case SOorLS1:
|
||||
debug << "SOorLS1";
|
||||
break;
|
||||
case SIorLS0:
|
||||
debug << "SIorLS0";
|
||||
break;
|
||||
case DLE:
|
||||
debug << "DLE";
|
||||
break;
|
||||
case DC1:
|
||||
debug << "DC1";
|
||||
break;
|
||||
case DC2:
|
||||
debug << "DC2";
|
||||
break;
|
||||
case DC3:
|
||||
debug << "DC3";
|
||||
break;
|
||||
case DC4:
|
||||
debug << "DC4";
|
||||
break;
|
||||
case NAK:
|
||||
debug << "NAK";
|
||||
break;
|
||||
case SYN:
|
||||
debug << "SYN";
|
||||
break;
|
||||
case ETB:
|
||||
debug << "ETB";
|
||||
break;
|
||||
case CAN:
|
||||
debug << "CAN";
|
||||
break;
|
||||
case EM:
|
||||
debug << "EM";
|
||||
break;
|
||||
case SUB:
|
||||
debug << "SUB";
|
||||
break;
|
||||
case ESC:
|
||||
debug << "ESC";
|
||||
break;
|
||||
case IS4:
|
||||
debug << "IS4";
|
||||
break;
|
||||
case IS3:
|
||||
debug << "IS3";
|
||||
break;
|
||||
case IS2:
|
||||
debug << "IS2";
|
||||
break;
|
||||
case IS1:
|
||||
debug << "IS1";
|
||||
break;
|
||||
case C0_END:
|
||||
debug << "C0_END";
|
||||
break;
|
||||
default:
|
||||
debug << qPrintable(QString("0x%1").arg(character,0,16));
|
||||
break;
|
||||
}
|
||||
debug.setAutoInsertSpaces(insert_space);
|
||||
return debug;
|
||||
}
|
||||
}
|
||||
|
||||
namespace C1_7bit {
|
||||
QDebug operator<<(QDebug debug, C1_7bit character) {
|
||||
bool insert_space = debug.autoInsertSpaces();
|
||||
debug.setAutoInsertSpaces(false);
|
||||
debug << "C1_7bit::";
|
||||
switch(character) {
|
||||
case NOT_DEFINED:
|
||||
debug << "NOT_DEFINED";
|
||||
break;
|
||||
case NOT_DEFINED1:
|
||||
debug << "NOT_DEFINED1";
|
||||
break;
|
||||
case BPH:
|
||||
debug << "BPH";
|
||||
break;
|
||||
case NBH:
|
||||
debug << "NBH";
|
||||
break;
|
||||
case NOT_DEFINED2:
|
||||
debug << "NOT_DEFINED2";
|
||||
break;
|
||||
case NEL:
|
||||
debug << "NEL";
|
||||
break;
|
||||
case SSA:
|
||||
debug << "SSA";
|
||||
break;
|
||||
case ESA:
|
||||
debug << "ESA";
|
||||
break;
|
||||
case HTS:
|
||||
debug << "HTS";
|
||||
break;
|
||||
case HTJ:
|
||||
debug << "HTJ";
|
||||
break;
|
||||
case VTS:
|
||||
debug << "VTS";
|
||||
break;
|
||||
case PLD:
|
||||
debug << "PLD";
|
||||
break;
|
||||
case PLU:
|
||||
debug << "PLU";
|
||||
break;
|
||||
case RI :
|
||||
debug << "RI ";
|
||||
break;
|
||||
case SS2:
|
||||
debug << "SS2";
|
||||
break;
|
||||
case SS3:
|
||||
debug << "SS3";
|
||||
break;
|
||||
case DCS:
|
||||
debug << "DCS";
|
||||
break;
|
||||
case PU1:
|
||||
debug << "PU1";
|
||||
break;
|
||||
case PU2:
|
||||
debug << "PU2";
|
||||
break;
|
||||
case STS:
|
||||
debug << "STS";
|
||||
break;
|
||||
case CCH:
|
||||
debug << "CCH";
|
||||
break;
|
||||
case MW :
|
||||
debug << "MW ";
|
||||
break;
|
||||
case SPA:
|
||||
debug << "SPA";
|
||||
break;
|
||||
case EPA:
|
||||
debug << "EPA";
|
||||
break;
|
||||
case SOS:
|
||||
debug << "SOS";
|
||||
break;
|
||||
case NOT_DEFINED3:
|
||||
debug << "NOT_DEFINED3";
|
||||
break;
|
||||
case SCI:
|
||||
debug << "SCI";
|
||||
break;
|
||||
case CSI:
|
||||
debug << "CSI";
|
||||
break;
|
||||
case ST :
|
||||
debug << "ST ";
|
||||
break;
|
||||
case OSC:
|
||||
debug << "OSC";
|
||||
break;
|
||||
case PM :
|
||||
debug << "PM ";
|
||||
break;
|
||||
case APC:
|
||||
debug << "APC";
|
||||
break;
|
||||
case C1_7bit_Stop:
|
||||
debug << "C1_7bit_Stop";
|
||||
break;
|
||||
default:
|
||||
debug << qPrintable(QString("0x%1").arg(character,0,16));
|
||||
break;
|
||||
}
|
||||
debug.setAutoInsertSpaces(insert_space);
|
||||
return debug;
|
||||
}
|
||||
}
|
||||
|
||||
namespace C1_8bit {
|
||||
QDebug operator<<(QDebug debug, C1_8bit character) {
|
||||
bool insert_space = debug.autoInsertSpaces();
|
||||
debug.setAutoInsertSpaces(false);
|
||||
debug << "C1_8bit::";
|
||||
switch(character) {
|
||||
case NOT_DEFINED:
|
||||
debug << "NOT_DEFINED";
|
||||
break;
|
||||
case NOT_DEFINED1:
|
||||
debug << "NOT_DEFINED1";
|
||||
break;
|
||||
case BPH:
|
||||
debug << "BPH";
|
||||
break;
|
||||
case NBH:
|
||||
debug << "NBH";
|
||||
break;
|
||||
case NOT_DEFINED2:
|
||||
debug << "NOT_DEFINED2";
|
||||
break;
|
||||
case NEL:
|
||||
debug << "NEL";
|
||||
break;
|
||||
case SSA:
|
||||
debug << "SSA";
|
||||
break;
|
||||
case ESA:
|
||||
debug << "ESA";
|
||||
break;
|
||||
case HTS:
|
||||
debug << "HTS";
|
||||
break;
|
||||
case HTJ:
|
||||
debug << "HTJ";
|
||||
break;
|
||||
case VTS:
|
||||
debug << "VTS";
|
||||
break;
|
||||
case PLD:
|
||||
debug << "PLD";
|
||||
break;
|
||||
case PLU:
|
||||
debug << "PLU";
|
||||
break;
|
||||
case RI :
|
||||
debug << "RI ";
|
||||
break;
|
||||
case SS2:
|
||||
debug << "SS2";
|
||||
break;
|
||||
case SS3:
|
||||
debug << "SS3";
|
||||
break;
|
||||
case DCS:
|
||||
debug << "DCS";
|
||||
break;
|
||||
case PU1:
|
||||
debug << "PU1";
|
||||
break;
|
||||
case PU2C1_7bit:
|
||||
debug << "PU2C1_7bit";
|
||||
break;
|
||||
case STS:
|
||||
debug << "STS";
|
||||
break;
|
||||
case CCH:
|
||||
debug << "CCH";
|
||||
break;
|
||||
case MW :
|
||||
debug << "MW ";
|
||||
break;
|
||||
case SPA:
|
||||
debug << "SPA";
|
||||
break;
|
||||
case EPA:
|
||||
debug << "EPA";
|
||||
break;
|
||||
case SOS:
|
||||
debug << "SOS";
|
||||
break;
|
||||
case NOT_DEFINED3:
|
||||
debug << "NOT_DEFINED3";
|
||||
break;
|
||||
case SCI:
|
||||
debug << "SCI";
|
||||
break;
|
||||
case CSI:
|
||||
debug << "CSI";
|
||||
break;
|
||||
case ST :
|
||||
debug << "ST ";
|
||||
break;
|
||||
case OSC:
|
||||
debug << "OSC";
|
||||
break;
|
||||
case PM :
|
||||
debug << "PM ";
|
||||
break;
|
||||
case APC:
|
||||
debug << "APC";
|
||||
break;
|
||||
case C1_8bit_Stop:
|
||||
debug << "C1_8bit_Stop";
|
||||
break;
|
||||
default:
|
||||
debug << qPrintable(QString("0x%1").arg(character,0,16));
|
||||
break;
|
||||
}
|
||||
debug.setAutoInsertSpaces(insert_space);
|
||||
return debug;
|
||||
}
|
||||
}
|
||||
namespace FinalBytesNoIntermediate {
|
||||
QDebug operator<<(QDebug debug, FinalBytesNoIntermediate character) {
|
||||
bool insert_space = debug.autoInsertSpaces();
|
||||
debug.setAutoInsertSpaces(false);
|
||||
debug << "FinalBytesNoIntermediate::";
|
||||
switch(character) {
|
||||
case ICH:
|
||||
debug << "ICH";
|
||||
break;
|
||||
case CUU:
|
||||
debug << "CUU";
|
||||
break;
|
||||
case CUD:
|
||||
debug << "CUD";
|
||||
break;
|
||||
case CUF:
|
||||
debug << "CUF";
|
||||
break;
|
||||
case CUB:
|
||||
debug << "CUB";
|
||||
break;
|
||||
case CNL:
|
||||
debug << "CNL";
|
||||
break;
|
||||
case CPL:
|
||||
debug << "CPL";
|
||||
break;
|
||||
case CHA:
|
||||
debug << "CHA";
|
||||
break;
|
||||
case CUP:
|
||||
debug << "CUP";
|
||||
break;
|
||||
case CHT:
|
||||
debug << "CHT";
|
||||
break;
|
||||
case ED:
|
||||
debug << "ED";
|
||||
break;
|
||||
case EL:
|
||||
debug << "EL";
|
||||
break;
|
||||
case IL:
|
||||
debug << "IL";
|
||||
break;
|
||||
case DL:
|
||||
debug << "DL";
|
||||
break;
|
||||
case EF:
|
||||
debug << "EF";
|
||||
break;
|
||||
case EA:
|
||||
debug << "EA";
|
||||
break;
|
||||
case DCH:
|
||||
debug << "DCH";
|
||||
break;
|
||||
case SSE:
|
||||
debug << "SSE";
|
||||
break;
|
||||
case CPR:
|
||||
debug << "CPR";
|
||||
break;
|
||||
case SU:
|
||||
debug << "SU";
|
||||
break;
|
||||
case SD:
|
||||
debug << "SD";
|
||||
break;
|
||||
case NP:
|
||||
debug << "NP";
|
||||
break;
|
||||
case PP:
|
||||
debug << "PP";
|
||||
break;
|
||||
case CTC:
|
||||
debug << "CTC";
|
||||
break;
|
||||
case ECH:
|
||||
debug << "ECH";
|
||||
break;
|
||||
case CVT:
|
||||
debug << "CVT";
|
||||
break;
|
||||
case CBT:
|
||||
debug << "CBT";
|
||||
break;
|
||||
case SRS:
|
||||
debug << "SRS";
|
||||
break;
|
||||
case PTX:
|
||||
debug << "PTX";
|
||||
break;
|
||||
case SDS:
|
||||
debug << "SDS";
|
||||
break;
|
||||
case SIMD:
|
||||
debug << "SIMD";
|
||||
break;
|
||||
case NOT_DEFINED:
|
||||
debug << "NOT_DEFINED";
|
||||
break;
|
||||
case HPA:
|
||||
debug << "HPA";
|
||||
break;
|
||||
case HPR:
|
||||
debug << "HPR";
|
||||
break;
|
||||
case REP:
|
||||
debug << "REP";
|
||||
break;
|
||||
case DA:
|
||||
debug << "DA";
|
||||
break;
|
||||
case VPA:
|
||||
debug << "VPA";
|
||||
break;
|
||||
case VPR:
|
||||
debug << "VPR";
|
||||
break;
|
||||
case HVP:
|
||||
debug << "HVP";
|
||||
break;
|
||||
case TBC:
|
||||
debug << "TBC";
|
||||
break;
|
||||
case SM:
|
||||
debug << "SM";
|
||||
break;
|
||||
case MC:
|
||||
debug << "MC";
|
||||
break;
|
||||
case HPB:
|
||||
debug << "HPB";
|
||||
break;
|
||||
case VPB:
|
||||
debug << "VPB";
|
||||
break;
|
||||
case RM:
|
||||
debug << "RM";
|
||||
break;
|
||||
case SGR:
|
||||
debug << "SGR";
|
||||
break;
|
||||
case DSR:
|
||||
debug << "DSR";
|
||||
break;
|
||||
case DAQ:
|
||||
debug << "DAQ";
|
||||
break;
|
||||
case Reserved0:
|
||||
debug << "Reserved0";
|
||||
break;
|
||||
case Reserved1:
|
||||
debug << "Reserved1";
|
||||
break;
|
||||
case Reserved2:
|
||||
debug << "Reserved2";
|
||||
break;
|
||||
case Reserved3:
|
||||
debug << "Reserved3";
|
||||
break;
|
||||
case Reserved4:
|
||||
debug << "Reserved4";
|
||||
break;
|
||||
case Reserved5:
|
||||
debug << "Reserved5";
|
||||
break;
|
||||
case Reserved6:
|
||||
debug << "Reserved6";
|
||||
break;
|
||||
case Reserved7:
|
||||
debug << "Reserved7";
|
||||
break;
|
||||
case Reserved8:
|
||||
debug << "Reserved8";
|
||||
break;
|
||||
case Reserved9:
|
||||
debug << "Reserved9";
|
||||
break;
|
||||
case Reserveda:
|
||||
debug << "Reserveda";
|
||||
break;
|
||||
case Reservedb:
|
||||
debug << "Reservedb";
|
||||
break;
|
||||
case Reservedc:
|
||||
debug << "Reservedc";
|
||||
break;
|
||||
case Reservedd:
|
||||
debug << "Reservedd";
|
||||
break;
|
||||
case Reservede:
|
||||
debug << "Reservede";
|
||||
break;
|
||||
case Reservedf:
|
||||
debug << "Reservedf";
|
||||
break;
|
||||
default:
|
||||
debug << qPrintable(QString("0x%1").arg(character,0,16));
|
||||
break;
|
||||
}
|
||||
debug.setAutoInsertSpaces(insert_space);
|
||||
return debug;
|
||||
}
|
||||
}
|
||||
|
||||
namespace FinalBytesSingleIntermediate {
|
||||
QDebug operator<<(QDebug debug, FinalBytesSingleIntermediate character)
|
||||
{
|
||||
bool insert_space = debug.autoInsertSpaces();
|
||||
debug.setAutoInsertSpaces(false);
|
||||
debug << "FinalBytesSingleIntermediate::";
|
||||
switch(character) {
|
||||
case SL:
|
||||
debug << "SL";
|
||||
break;
|
||||
case SR:
|
||||
debug << "SR";
|
||||
break;
|
||||
case GSM:
|
||||
debug << "GSM";
|
||||
break;
|
||||
case GSS:
|
||||
debug << "GSS";
|
||||
break;
|
||||
case FNT:
|
||||
debug << "FNT";
|
||||
break;
|
||||
case TSS:
|
||||
debug << "TSS";
|
||||
break;
|
||||
case JFY:
|
||||
debug << "JFY";
|
||||
break;
|
||||
case SPI:
|
||||
debug << "SPI";
|
||||
break;
|
||||
case QUAD:
|
||||
debug << "QUAD";
|
||||
break;
|
||||
case SSU:
|
||||
debug << "SSU";
|
||||
break;
|
||||
case PFS:
|
||||
debug << "PFS";
|
||||
break;
|
||||
case SHS:
|
||||
debug << "SHS";
|
||||
break;
|
||||
case SVS:
|
||||
debug << "SVS";
|
||||
break;
|
||||
case IGS:
|
||||
debug << "IGS";
|
||||
break;
|
||||
case NOT_DEFINED:
|
||||
debug << "NOT_DEFINED";
|
||||
break;
|
||||
case IDCS:
|
||||
debug << "IDCS";
|
||||
break;
|
||||
case PPA:
|
||||
debug << "PPA";
|
||||
break;
|
||||
case PPR:
|
||||
debug << "PPR";
|
||||
break;
|
||||
case PPB:
|
||||
debug << "PPB";
|
||||
break;
|
||||
case SPD:
|
||||
debug << "SPD";
|
||||
break;
|
||||
case DTA:
|
||||
debug << "DTA";
|
||||
break;
|
||||
case SHL:
|
||||
debug << "SHL";
|
||||
break;
|
||||
case SLL:
|
||||
debug << "SLL";
|
||||
break;
|
||||
case FNK:
|
||||
debug << "FNK";
|
||||
break;
|
||||
case SPQR:
|
||||
debug << "SPQR";
|
||||
break;
|
||||
case SEF:
|
||||
debug << "SEF";
|
||||
break;
|
||||
case PEC:
|
||||
debug << "PEC";
|
||||
break;
|
||||
case SSW:
|
||||
debug << "SSW";
|
||||
break;
|
||||
case SACS:
|
||||
debug << "SACS";
|
||||
break;
|
||||
case SAPV:
|
||||
debug << "SAPV";
|
||||
break;
|
||||
case STAB:
|
||||
debug << "STAB";
|
||||
break;
|
||||
case GCC:
|
||||
debug << "GCC";
|
||||
break;
|
||||
case TATE:
|
||||
debug << "TATE";
|
||||
break;
|
||||
case TALE:
|
||||
debug << "TALE";
|
||||
break;
|
||||
case TAC:
|
||||
debug << "TAC";
|
||||
break;
|
||||
case TCC:
|
||||
debug << "TCC";
|
||||
break;
|
||||
case TSR:
|
||||
debug << "TSR";
|
||||
break;
|
||||
case SCO:
|
||||
debug << "SCO";
|
||||
break;
|
||||
case SRCS:
|
||||
debug << "SRCS";
|
||||
break;
|
||||
case SCS:
|
||||
debug << "SCS";
|
||||
break;
|
||||
case SLS:
|
||||
debug << "SLS";
|
||||
break;
|
||||
case NOT_DEFINED2:
|
||||
debug << "NOT_DEFINED2";
|
||||
break;
|
||||
case NOT_DEFINED3:
|
||||
debug << "NOT_DEFINED3";
|
||||
break;
|
||||
case SCP:
|
||||
debug << "SCP";
|
||||
break;
|
||||
case NOT_DEFINED4:
|
||||
debug << "NOT_DEFINED4";
|
||||
break;
|
||||
case NOT_DEFINED5:
|
||||
debug << "NOT_DEFINED5";
|
||||
break;
|
||||
case NOT_DEFINED6:
|
||||
debug << "NOT_DEFINED6";
|
||||
break;
|
||||
case NOT_DEFINED7:
|
||||
debug << "NOT_DEFINED7";
|
||||
break;
|
||||
case Reserved0:
|
||||
debug << "Reserved0";
|
||||
break;
|
||||
case Reserved1:
|
||||
debug << "Reserved1";
|
||||
break;
|
||||
case Reserved2:
|
||||
debug << "Reserved2";
|
||||
break;
|
||||
case Reserved3:
|
||||
debug << "Reserved3";
|
||||
break;
|
||||
case Reserved4:
|
||||
debug << "Reserved4";
|
||||
break;
|
||||
case Reserved5:
|
||||
debug << "Reserved5";
|
||||
break;
|
||||
case Reserved6:
|
||||
debug << "Reserved6";
|
||||
break;
|
||||
case Reserved7:
|
||||
debug << "Reserved7";
|
||||
break;
|
||||
case Reserved8:
|
||||
debug << "Reserved8";
|
||||
break;
|
||||
case Reserved9:
|
||||
debug << "Reserved9";
|
||||
break;
|
||||
case Reserveda:
|
||||
debug << "Reserveda";
|
||||
break;
|
||||
case Reservedb:
|
||||
debug << "Reservedb";
|
||||
break;
|
||||
case Reservedc:
|
||||
debug << "Reservedc";
|
||||
break;
|
||||
case Reservedd:
|
||||
debug << "Reservedd";
|
||||
break;
|
||||
case Reservedf:
|
||||
debug << "Reservedf";
|
||||
break;
|
||||
default:
|
||||
debug << qPrintable(QString("0x%1").arg(character,0,16));
|
||||
break;
|
||||
}
|
||||
debug.setAutoInsertSpaces(insert_space);
|
||||
return debug;
|
||||
}
|
||||
}
|
289
yat/backend/controll_chars.h
Normal file
289
yat/backend/controll_chars.h
Normal file
@ -0,0 +1,289 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef CONTROLL_CHARS_H
|
||||
#define CONTROLL_CHARS_H
|
||||
|
||||
//This is taken largely from Standard ECMA-48
|
||||
//http://www.ecma-international.org/publications/standards/Ecma-048.htm
|
||||
//Also to heres a few handy references
|
||||
//http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
//http://www.vt100.net/docs/vt100-ug/chapter3.html
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace C0 {
|
||||
enum C0 {
|
||||
NUL = 0x00,
|
||||
SOH = 0x01,
|
||||
STX = 0x02,
|
||||
ETX = 0x03,
|
||||
EOT = 0x04,
|
||||
ENQ = 0x05,
|
||||
ACK = 0x06,
|
||||
BEL = 0x07,
|
||||
BS = 0x08,
|
||||
HT = 0x09,
|
||||
LF = 0x0a,
|
||||
VT = 0x0b,
|
||||
FF = 0x0c,
|
||||
CR = 0x0d,
|
||||
SOorLS1 = 0x0e,
|
||||
SIorLS0 = 0x0f,
|
||||
DLE = 0x10,
|
||||
DC1 = 0x11,
|
||||
DC2 = 0x12,
|
||||
DC3 = 0x13,
|
||||
DC4 = 0x14,
|
||||
NAK = 0x15,
|
||||
SYN = 0x16,
|
||||
ETB = 0x17,
|
||||
CAN = 0x18,
|
||||
EM = 0x19,
|
||||
SUB = 0x1a,
|
||||
ESC = 0x1b,
|
||||
IS4 = 0x1c,
|
||||
IS3 = 0x1d,
|
||||
IS2 = 0x1e,
|
||||
IS1 = 0x1f,
|
||||
C0_END = 0x20
|
||||
};
|
||||
QDebug operator<<(QDebug debug, C0 character);
|
||||
}
|
||||
|
||||
namespace C1_7bit {
|
||||
enum C1_7bit {
|
||||
C1_7bit_Start = 0x80,
|
||||
NOT_DEFINED = C1_7bit_Start,
|
||||
NOT_DEFINED1 = 0x81,
|
||||
BPH = 0x42,
|
||||
NBH = 0x43,
|
||||
NOT_DEFINED2 = 0x82,
|
||||
NEL = 0x45,
|
||||
SSA = 0x46,
|
||||
ESA = 0x47,
|
||||
HTS = 0x48,
|
||||
HTJ = 0x49,
|
||||
VTS = 0x4a,
|
||||
PLD = 0x4b,
|
||||
PLU = 0x4c,
|
||||
RI = 0x4d,
|
||||
SS2 = 0x4e,
|
||||
SS3 = 0x4f,
|
||||
DCS = 0x50,
|
||||
PU1 = 0x51,
|
||||
PU2 = 0x52,
|
||||
STS = 0x53,
|
||||
CCH = 0x54,
|
||||
MW = 0x55,
|
||||
SPA = 0x56,
|
||||
EPA = 0x57,
|
||||
SOS = 0x58,
|
||||
NOT_DEFINED3 = 0x99,
|
||||
SCI = 0x5a,
|
||||
CSI = 0x5b,
|
||||
ST = 0x5c,
|
||||
OSC = 0x5d,
|
||||
PM = 0x5e,
|
||||
APC = 0x5f,
|
||||
C1_7bit_Stop = 0x60
|
||||
};
|
||||
QDebug operator<<(QDebug debug, C1_7bit character);
|
||||
}
|
||||
namespace C1_8bit {
|
||||
enum C1_8bit {
|
||||
C1_8bit_Start = 0x80,
|
||||
NOT_DEFINED = C1_8bit_Start,
|
||||
NOT_DEFINED1 = 0x81,
|
||||
BPH = 0x82,
|
||||
NBH = 0x83,
|
||||
NOT_DEFINED2 = 0x84,
|
||||
NEL = 0x85,
|
||||
SSA = 0x86,
|
||||
ESA = 0x87,
|
||||
HTS = 0x88,
|
||||
HTJ = 0x89,
|
||||
VTS = 0x8a,
|
||||
PLD = 0x8b,
|
||||
PLU = 0x8c,
|
||||
RI = 0x8d,
|
||||
SS2 = 0x8e,
|
||||
SS3 = 0x8f,
|
||||
DCS = 0x90,
|
||||
PU1 = 0x91,
|
||||
PU2C1_7bit = 0x92,
|
||||
STS = 0x93,
|
||||
CCH = 0x94,
|
||||
MW = 0x95,
|
||||
SPA = 0x96,
|
||||
EPA = 0x97,
|
||||
SOS = 0x98,
|
||||
NOT_DEFINED3 = 0x99,
|
||||
SCI = 0x9a,
|
||||
CSI = 0x9b,
|
||||
ST = 0x9c,
|
||||
OSC = 0x9d,
|
||||
PM = 0x9e,
|
||||
APC = 0x9f,
|
||||
C1_8bit_Stop = 0xa0
|
||||
};
|
||||
QDebug operator<<(QDebug debug, C1_8bit character);
|
||||
}
|
||||
|
||||
namespace FinalBytesNoIntermediate {
|
||||
enum FinalBytesNoIntermediate {
|
||||
ICH = 0x40,
|
||||
CUU = 0x41,
|
||||
CUD = 0x42,
|
||||
CUF = 0x43,
|
||||
CUB = 0x44,
|
||||
CNL = 0x45,
|
||||
CPL = 0x46,
|
||||
CHA = 0x47,
|
||||
CUP = 0x48,
|
||||
CHT = 0x49,
|
||||
ED = 0x4a,
|
||||
EL = 0x4b,
|
||||
IL = 0x4c,
|
||||
DL = 0x4d,
|
||||
EF = 0x4e,
|
||||
EA = 0x4f,
|
||||
DCH = 0x50,
|
||||
SSE = 0x51,
|
||||
CPR = 0x52,
|
||||
SU = 0x53,
|
||||
SD = 0x54,
|
||||
NP = 0x55,
|
||||
PP = 0x56,
|
||||
CTC = 0x57,
|
||||
ECH = 0x58,
|
||||
CVT = 0x59,
|
||||
CBT = 0x5a,
|
||||
SRS = 0x5b,
|
||||
PTX = 0x5c,
|
||||
SDS = 0x5d,
|
||||
SIMD = 0x5e,
|
||||
NOT_DEFINED = 0x5f,
|
||||
HPA = 0x60,
|
||||
HPR = 0x61,
|
||||
REP = 0x62,
|
||||
DA = 0x63,
|
||||
VPA = 0x64,
|
||||
VPR = 0x65,
|
||||
HVP = 0x66,
|
||||
TBC = 0x67,
|
||||
SM = 0x68,
|
||||
MC = 0x69,
|
||||
HPB = 0x6a,
|
||||
VPB = 0x6b,
|
||||
RM = 0x6c,
|
||||
SGR = 0x6d,
|
||||
DSR = 0x6e,
|
||||
DAQ = 0x6f,
|
||||
Reserved0 = 0x70,
|
||||
Reserved1 = 0x71,
|
||||
Reserved2 = 0x72,
|
||||
Reserved3 = 0x73,
|
||||
Reserved4 = 0x74,
|
||||
Reserved5 = 0x75,
|
||||
Reserved6 = 0x76,
|
||||
Reserved7 = 0x77,
|
||||
Reserved8 = 0x78,
|
||||
Reserved9 = 0x79,
|
||||
Reserveda = 0x7a,
|
||||
Reservedb = 0x7b,
|
||||
Reservedc = 0x7c,
|
||||
Reservedd = 0x7d,
|
||||
Reservede = 0x7e,
|
||||
Reservedf = 0x7f
|
||||
};
|
||||
QDebug operator<<(QDebug debug, FinalBytesNoIntermediate character);
|
||||
}
|
||||
|
||||
namespace FinalBytesSingleIntermediate {
|
||||
enum FinalBytesSingleIntermediate {
|
||||
SL = 0x40,
|
||||
SR = 0x41,
|
||||
GSM = 0x42,
|
||||
GSS = 0x43,
|
||||
FNT = 0x44,
|
||||
TSS = 0x45,
|
||||
JFY = 0x46,
|
||||
SPI = 0x47,
|
||||
QUAD = 0x48,
|
||||
SSU = 0x49,
|
||||
PFS = 0x4a,
|
||||
SHS = 0x4b,
|
||||
SVS = 0x4c,
|
||||
IGS = 0x4d,
|
||||
NOT_DEFINED = 0x4e,
|
||||
IDCS = 0x4f,
|
||||
PPA = 0x50,
|
||||
PPR = 0x51,
|
||||
PPB = 0x52,
|
||||
SPD = 0x53,
|
||||
DTA = 0x54,
|
||||
SHL = 0x55,
|
||||
SLL = 0x56,
|
||||
FNK = 0x57,
|
||||
SPQR = 0x58,
|
||||
SEF = 0x59,
|
||||
PEC = 0x5a,
|
||||
SSW = 0x5b,
|
||||
SACS = 0x5c,
|
||||
SAPV = 0x5d,
|
||||
STAB = 0x5e,
|
||||
GCC = 0x5f,
|
||||
TATE = 0x60,
|
||||
TALE = 0x61,
|
||||
TAC = 0x62,
|
||||
TCC = 0x63,
|
||||
TSR = 0x64,
|
||||
SCO = 0x65,
|
||||
SRCS = 0x66,
|
||||
SCS = 0x67,
|
||||
SLS = 0x68,
|
||||
NOT_DEFINED2 = 0x69,
|
||||
NOT_DEFINED3 = 0x6a,
|
||||
SCP = 0x6b,
|
||||
NOT_DEFINED4 = 0x6c,
|
||||
NOT_DEFINED5 = 0x6d,
|
||||
NOT_DEFINED6 = 0x6e,
|
||||
NOT_DEFINED7 = 0x6f,
|
||||
Reserved0 = 0x70,
|
||||
Reserved1 = 0x71,
|
||||
Reserved2 = 0x72,
|
||||
Reserved3 = 0x73,
|
||||
Reserved4 = 0x74,
|
||||
Reserved5 = 0x75,
|
||||
Reserved6 = 0x76,
|
||||
Reserved7 = 0x77,
|
||||
Reserved8 = 0x78,
|
||||
Reserved9 = 0x79,
|
||||
Reserveda = 0x7a,
|
||||
Reservedb = 0x7b,
|
||||
Reservedc = 0x7c,
|
||||
Reservedd = 0x7d,
|
||||
Reservedf = 0x7f
|
||||
};
|
||||
QDebug operator<<(QDebug debug, FinalBytesSingleIntermediate character);
|
||||
}
|
||||
|
||||
#endif // CONTROLL_CHARS_H
|
437
yat/backend/line.cpp
Normal file
437
yat/backend/line.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "line.h"
|
||||
|
||||
#include "text.h"
|
||||
#include "screen.h"
|
||||
|
||||
#include <QtQuick/QQuickView>
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
QDebug operator<<(QDebug debug, TextStyleLine line)
|
||||
{
|
||||
debug << "TextStyleLine: [" << line.start_index << ":" << line.end_index << "] : style:" << line.style;
|
||||
return debug;
|
||||
}
|
||||
|
||||
Line::Line(Screen *screen)
|
||||
: QObject(screen)
|
||||
, m_screen(screen)
|
||||
, m_index(0)
|
||||
, m_old_index(-1)
|
||||
, m_visible(true)
|
||||
, m_changed(true)
|
||||
{
|
||||
m_text_line.resize(screen->width());
|
||||
m_style_list.reserve(25);
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
Line::~Line()
|
||||
{
|
||||
releaseTextObjects();
|
||||
}
|
||||
|
||||
Screen *Line::screen() const
|
||||
{
|
||||
return m_screen;
|
||||
}
|
||||
|
||||
void Line::releaseTextObjects()
|
||||
{
|
||||
m_changed = true;
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
if (m_style_list.at(i).text_segment) {
|
||||
m_style_list.at(i).text_segment->setVisible(false);
|
||||
delete m_style_list.at(i).text_segment;
|
||||
m_style_list[i].text_segment = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Line::clear()
|
||||
{
|
||||
m_text_line.fill(QChar(' '));
|
||||
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
if (m_style_list.at(i).text_segment)
|
||||
releaseTextSegment(m_style_list.at(i).text_segment);
|
||||
}
|
||||
|
||||
m_style_list.clear();
|
||||
m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(),0,m_text_line.size() -1));
|
||||
|
||||
m_changed = true;
|
||||
}
|
||||
|
||||
void Line::clearToEndOfLine(int index)
|
||||
{
|
||||
m_changed = true;
|
||||
|
||||
QString empty(m_text_line.size() - index, QChar(' '));
|
||||
m_text_line.replace(index, m_text_line.size()-index,empty);
|
||||
bool found = false;
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
const TextStyleLine current_style = m_style_list.at(i);
|
||||
if (found) {
|
||||
if (current_style.text_segment)
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
} else {
|
||||
if (index <= current_style.end_index) {
|
||||
found = true;
|
||||
if (current_style.start_index == index) {
|
||||
if (current_style.text_segment)
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
} else {
|
||||
m_style_list[i].end_index = index - 1;
|
||||
m_style_list[i].text_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_style_list.size() && m_style_list.last().isCompatible(m_screen->defaultTextStyle())) {
|
||||
m_style_list.last().end_index = m_text_line.size() -1;
|
||||
} else {
|
||||
m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(),index, m_text_line.size() -1));
|
||||
}
|
||||
}
|
||||
|
||||
void Line::clearCharacters(int from, int to)
|
||||
{
|
||||
QString empty(to-from, QChar(' '));
|
||||
const TextStyle &defaultTextStyle = m_screen->defaultTextStyle();
|
||||
replaceAtPos(from, empty, defaultTextStyle);
|
||||
}
|
||||
|
||||
void Line::deleteCharacters(int from, int to)
|
||||
{
|
||||
m_changed = true;
|
||||
|
||||
int removed = 0;
|
||||
const int size = (to + 1) - from;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
TextStyleLine ¤t_style = m_style_list[i];
|
||||
if (found) {
|
||||
current_style.start_index -= removed;
|
||||
current_style.end_index -= removed;
|
||||
current_style.index_dirty = true;
|
||||
if (removed != size) {
|
||||
int current_style_size = current_style.end_index + 1 - current_style.start_index;
|
||||
if (current_style_size <= size - removed) {
|
||||
removed += current_style.end_index + 1 - current_style.start_index;
|
||||
if (current_style.text_segment)
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
} else {
|
||||
current_style.end_index -= size - removed;
|
||||
removed = size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (current_style.start_index <= from && current_style.end_index >= from) {
|
||||
found = true;
|
||||
int left_in_style = (current_style.end_index + 1) - from;
|
||||
int subtract = std::min(left_in_style, size);
|
||||
current_style.end_index -= subtract;
|
||||
current_style.text_dirty = true;
|
||||
removed = subtract;
|
||||
if (current_style.end_index < current_style.start_index) {
|
||||
if (current_style.text_segment)
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextStyle defaultStyle = m_screen->defaultTextStyle();
|
||||
if (m_style_list.last().isCompatible(defaultStyle)) {
|
||||
m_style_list.last().end_index += size;
|
||||
m_style_list.last().text_dirty = true;
|
||||
} else {
|
||||
m_style_list.append(TextStyleLine(defaultStyle, m_style_list.last().end_index + 1,
|
||||
m_style_list.last().end_index + size));
|
||||
}
|
||||
|
||||
m_text_line.remove(from, size);
|
||||
QString empty(size,' ');
|
||||
m_text_line.append(empty);
|
||||
}
|
||||
|
||||
void Line::setWidth(int width)
|
||||
{
|
||||
bool emit_changed = m_text_line.size() != width;
|
||||
if (m_text_line.size() > width) {
|
||||
m_text_line.chop(m_text_line.size() - width);
|
||||
} else if (m_text_line.size() < width) {
|
||||
m_text_line.append(QString(width - m_text_line.size(), QChar(' ')));
|
||||
}
|
||||
|
||||
if (emit_changed)
|
||||
emit widthChanged();
|
||||
}
|
||||
|
||||
int Line::width() const
|
||||
{
|
||||
return m_style_list.size();
|
||||
}
|
||||
|
||||
void Line::replaceAtPos(int pos, const QString &text, const TextStyle &style)
|
||||
{
|
||||
Q_ASSERT(pos + text.size() <= m_text_line.size());
|
||||
|
||||
m_changed = true;
|
||||
|
||||
m_text_line.replace(pos,text.size(),text);
|
||||
bool found = false;
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
TextStyleLine ¤t_style = m_style_list[i];
|
||||
if (found) {
|
||||
if (current_style.end_index <= pos + text.size()) {
|
||||
if (current_style.text_segment)
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
} else if (current_style.start_index <= pos + text.size()) {
|
||||
current_style.start_index = pos + text.size();
|
||||
current_style.style_dirty = true;
|
||||
current_style.text_dirty = true;
|
||||
current_style.index_dirty = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (pos >= current_style.start_index && pos <= current_style.end_index) {
|
||||
found = true;
|
||||
if (pos + text.size() -1 <= current_style.end_index) {
|
||||
if (current_style.isCompatible(style)) {
|
||||
current_style.text_dirty = true;
|
||||
} else {
|
||||
if (current_style.start_index == pos && current_style.end_index == pos + text.size() - 1) {
|
||||
current_style.setStyle(style);
|
||||
} else if (current_style.start_index == pos) {
|
||||
current_style.start_index = pos + text.size();
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i, TextStyleLine(style,pos, pos+text.size() -1));
|
||||
} else if (current_style.end_index == pos + text.size()) {
|
||||
current_style.end_index = pos - 1;
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i+1, TextStyleLine(style,pos, pos+text.size()));
|
||||
} else {
|
||||
int old_end = current_style.end_index;
|
||||
current_style.end_index = pos - 1;
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i+1, TextStyleLine(style,pos, pos + text.size() - 1));
|
||||
if (pos + text.size() < m_text_line.size()) {
|
||||
m_style_list.insert(i+2, TextStyleLine(current_style,pos + text.size(), old_end));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (current_style.isCompatible(style)) {
|
||||
current_style.end_index = pos + text.size() - 1;
|
||||
current_style.text_dirty = true;
|
||||
} else {
|
||||
if (current_style.start_index == pos) {
|
||||
current_style.end_index = pos + text.size() - 1;
|
||||
current_style.style = style.style;
|
||||
current_style.forground = style.forground;
|
||||
current_style.background = style.background;
|
||||
current_style.text_dirty = true;
|
||||
current_style.style_dirty = true;
|
||||
} else {
|
||||
current_style.end_index = pos - 1;
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i+1, TextStyleLine(style, pos, pos + text.size() -1));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Line::insertAtPos(int pos, const QString &text, const TextStyle &style)
|
||||
{
|
||||
m_changed = true;
|
||||
|
||||
m_text_line.insert(pos,text);
|
||||
m_text_line.chop(text.size());
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
TextStyleLine ¤t_style = m_style_list[i];
|
||||
if (found) {
|
||||
current_style.start_index += text.size();
|
||||
current_style.end_index += text.size();
|
||||
current_style.index_dirty = true;
|
||||
if (current_style.start_index >= m_text_line.size()) {
|
||||
releaseTextSegment(current_style.text_segment);
|
||||
m_style_list.remove(i);
|
||||
i--;
|
||||
} else if (current_style.end_index >= m_text_line.size()) {
|
||||
current_style.end_index = m_text_line.size()-1;
|
||||
}
|
||||
} else if (pos >= current_style.start_index && pos <= current_style.end_index) {
|
||||
found = true;
|
||||
if (current_style.start_index == pos) {
|
||||
current_style.start_index += text.size();
|
||||
current_style.end_index += text.size();
|
||||
current_style.index_dirty = true;
|
||||
m_style_list.insert(i, TextStyleLine(style, pos, pos+ text.size() - 1));
|
||||
i++;
|
||||
} else if (current_style.end_index == pos) {
|
||||
current_style.end_index--;
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i+1, TextStyleLine(style, pos, pos+ text.size() - 1));
|
||||
i++;
|
||||
} else {
|
||||
int old_end = current_style.end_index;
|
||||
current_style.end_index = pos -1;
|
||||
current_style.text_dirty = true;
|
||||
m_style_list.insert(i+1, TextStyleLine(style, pos, pos + text.size() - 1));
|
||||
if (pos + text.size() < m_text_line.size()) {
|
||||
int segment_end = std::min(m_text_line.size() -1, old_end + text.size());
|
||||
m_style_list.insert(i+2, TextStyleLine(current_style, pos + text.size(), segment_end));
|
||||
i+=2;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Line::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
void Line::setIndex(int index)
|
||||
{
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
QString *Line::textLine()
|
||||
{
|
||||
return &m_text_line;
|
||||
}
|
||||
|
||||
void Line::setVisible(bool visible)
|
||||
{
|
||||
if (visible != m_visible) {
|
||||
m_visible = visible;
|
||||
emit visibleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool Line::visible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
void Line::dispatchEvents()
|
||||
{
|
||||
if (m_index != m_old_index) {
|
||||
m_old_index = m_index;
|
||||
emit indexChanged();
|
||||
}
|
||||
|
||||
if (!m_changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_style_list.size(); i++) {
|
||||
TextStyleLine ¤t_style = m_style_list[i];
|
||||
|
||||
if (current_style.text_segment == 0) {
|
||||
current_style.text_segment = createTextSegment(current_style);
|
||||
}
|
||||
|
||||
if (current_style.style_dirty) {
|
||||
current_style.text_segment->setTextStyle(current_style);
|
||||
current_style.style_dirty = false;
|
||||
}
|
||||
|
||||
if (current_style.index_dirty || current_style.text_dirty) {
|
||||
current_style.text_segment->setStringSegment(current_style.start_index, current_style.end_index, current_style.text_dirty);
|
||||
current_style.index_dirty = false;
|
||||
current_style.text_dirty = false;
|
||||
}
|
||||
|
||||
m_style_list.at(i).text_segment->dispatchEvents();
|
||||
}
|
||||
|
||||
m_changed = false;
|
||||
|
||||
for (int i = 0; i< m_to_delete.size(); i++) {
|
||||
delete m_to_delete[i];
|
||||
}
|
||||
m_to_delete.clear();
|
||||
}
|
||||
|
||||
QVector<TextStyleLine> Line::style_list()
|
||||
{
|
||||
return m_style_list;
|
||||
}
|
||||
|
||||
Text *Line::createTextSegment(const TextStyleLine &style_line)
|
||||
{
|
||||
Text *to_return;
|
||||
if (m_to_delete.size()) {
|
||||
to_return = m_to_delete.takeLast();
|
||||
} else {
|
||||
to_return = new Text(screen());
|
||||
to_return->setLine(this);
|
||||
emit textCreated(to_return);
|
||||
}
|
||||
|
||||
to_return->setVisible(true);
|
||||
|
||||
return to_return;
|
||||
}
|
||||
|
||||
void Line::releaseTextSegment(Text *text)
|
||||
{
|
||||
text->setVisible(false);
|
||||
m_to_delete.append(text);
|
||||
}
|
||||
|
||||
void Line::printStyleList() const
|
||||
{
|
||||
for (int i= 0; i < m_style_list.size(); i++) {
|
||||
qDebug() << "i" << m_style_list.at(i);
|
||||
}
|
||||
}
|
137
yat/backend/line.h
Normal file
137
yat/backend/line.h
Normal file
@ -0,0 +1,137 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef TEXT_SEGMENT_LINE_H
|
||||
#define TEXT_SEGMENT_LINE_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "text.h"
|
||||
|
||||
class Screen;
|
||||
class QQuickItem;
|
||||
|
||||
class TextStyleLine : public TextStyle {
|
||||
public:
|
||||
TextStyleLine(const TextStyle &style, int start_index, int end_index)
|
||||
: TextStyle(style)
|
||||
, start_index(start_index)
|
||||
, end_index(end_index)
|
||||
, old_index(-1)
|
||||
, text_segment(0)
|
||||
, style_dirty(true)
|
||||
, index_dirty(true)
|
||||
, text_dirty(true)
|
||||
{
|
||||
}
|
||||
|
||||
TextStyleLine()
|
||||
: start_index(0)
|
||||
, end_index(0)
|
||||
, old_index(-1)
|
||||
, text_segment(0)
|
||||
, style_dirty(false)
|
||||
, index_dirty(false)
|
||||
, text_dirty(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int start_index;
|
||||
int end_index;
|
||||
|
||||
int old_index;
|
||||
Text *text_segment;
|
||||
bool style_dirty;
|
||||
bool index_dirty;
|
||||
bool text_dirty;
|
||||
|
||||
void setStyle(const TextStyle &style) {
|
||||
forground = style.forground;
|
||||
background = style.background;
|
||||
this->style = style.style;
|
||||
}
|
||||
};
|
||||
QDebug operator<<(QDebug debug, TextStyleLine line);
|
||||
|
||||
class Line : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int index READ index NOTIFY indexChanged)
|
||||
Q_PROPERTY(Screen *screen READ screen CONSTANT)
|
||||
Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
|
||||
Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged)
|
||||
public:
|
||||
Line(Screen *screen);
|
||||
~Line();
|
||||
|
||||
Q_INVOKABLE Screen *screen() const;
|
||||
|
||||
void releaseTextObjects();
|
||||
|
||||
void clear();
|
||||
void clearToEndOfLine(int index);
|
||||
void clearCharacters(int from, int to);
|
||||
void deleteCharacters(int from, int to);
|
||||
|
||||
void setWidth(int width);
|
||||
int width() const;
|
||||
|
||||
void replaceAtPos(int i, const QString &text, const TextStyle &style);
|
||||
void insertAtPos(int i, const QString &text, const TextStyle &style);
|
||||
|
||||
int index() const;
|
||||
void setIndex(int index);
|
||||
|
||||
QString *textLine();
|
||||
|
||||
void setVisible(bool visible);
|
||||
bool visible() const;
|
||||
|
||||
void dispatchEvents();
|
||||
|
||||
QVector<TextStyleLine> style_list();
|
||||
|
||||
void printStyleList() const;
|
||||
signals:
|
||||
void indexChanged();
|
||||
void visibleChanged();
|
||||
void widthChanged();
|
||||
|
||||
void textCreated(Text *text);
|
||||
private:
|
||||
Text *createTextSegment(const TextStyleLine &style_line);
|
||||
void releaseTextSegment(Text *text);
|
||||
|
||||
Screen *m_screen;
|
||||
QString m_text_line;
|
||||
QVector<TextStyleLine> m_style_list;
|
||||
int m_index;
|
||||
int m_old_index;
|
||||
|
||||
bool m_visible;
|
||||
QVector<Text *> m_to_delete;
|
||||
bool m_changed;
|
||||
|
||||
bool m_delete_handle;
|
||||
};
|
||||
|
||||
#endif // TEXT_SEGMENT_LINE_H
|
32
yat/backend/main.cpp
Normal file
32
yat/backend/main.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "terminal_state.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
TerminalState state;
|
||||
|
||||
return app.exec();
|
||||
}
|
793
yat/backend/parser.cpp
Normal file
793
yat/backend/parser.cpp
Normal file
@ -0,0 +1,793 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
#include "controll_chars.h"
|
||||
#include "screen.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
|
||||
static bool yat_parser_debug = qEnvironmentVariableIsSet("YAT_PARSER_DEBUG");
|
||||
|
||||
Parser::Parser(Screen *screen)
|
||||
: m_decode_state(PlainText)
|
||||
, m_current_token_start(0)
|
||||
, m_currrent_position(0)
|
||||
, m_intermediate_char(QChar())
|
||||
, m_parameters(10)
|
||||
, m_screen(screen)
|
||||
{
|
||||
}
|
||||
|
||||
void Parser::addData(const QByteArray &data)
|
||||
{
|
||||
m_current_token_start = 0;
|
||||
m_current_data = data;
|
||||
for (m_currrent_position = 0; m_currrent_position < data.size(); m_currrent_position++) {
|
||||
uchar character = data.at(m_currrent_position);
|
||||
switch (m_decode_state) {
|
||||
case PlainText:
|
||||
//UTF-8
|
||||
if (character > 127)
|
||||
continue;
|
||||
if (character < C0::C0_END ||
|
||||
(character >= C1_8bit::C1_8bit_Start &&
|
||||
character <= C1_8bit::C1_8bit_Stop)) {
|
||||
if (m_currrent_position != m_current_token_start) {
|
||||
m_screen->replaceAtCursor(QString::fromUtf8(data.mid(m_current_token_start,
|
||||
m_currrent_position - m_current_token_start)));
|
||||
tokenFinished();
|
||||
m_current_token_start--;
|
||||
}
|
||||
m_decode_state = DecodeC0;
|
||||
decodeC0(data.at(m_currrent_position));
|
||||
}
|
||||
break;
|
||||
case DecodeC0:
|
||||
decodeC0(character);
|
||||
break;
|
||||
case DecodeC1_7bit:
|
||||
decodeC1_7bit(character);
|
||||
break;
|
||||
case DecodeCSI:
|
||||
decodeCSI(character);
|
||||
break;
|
||||
case DecodeOSC:
|
||||
decodeOSC(character);
|
||||
break;
|
||||
case DecodeOtherEscape:
|
||||
decodeOtherEscape(character);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (m_decode_state == PlainText) {
|
||||
QByteArray text = data.mid(m_current_token_start);
|
||||
if (text.size()) {
|
||||
m_screen->replaceAtCursor(QString::fromUtf8(text));
|
||||
tokenFinished();
|
||||
}
|
||||
}
|
||||
m_current_data = QByteArray();
|
||||
}
|
||||
|
||||
void Parser::decodeC0(uchar character)
|
||||
{
|
||||
if (yat_parser_debug)
|
||||
qDebug() << C0::C0(character);
|
||||
switch (character) {
|
||||
case C0::NUL:
|
||||
case C0::SOH:
|
||||
case C0::STX:
|
||||
case C0::ETX:
|
||||
case C0::EOT:
|
||||
case C0::ENQ:
|
||||
case C0::ACK:
|
||||
qDebug() << "Unhandled" << C0::C0(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::BEL:
|
||||
m_screen->scheduleFlash();
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::BS:
|
||||
m_screen->backspace();
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::HT: {
|
||||
int x = m_screen->cursorPosition().x();
|
||||
int spaces = 8 - (x % 8);
|
||||
m_screen->replaceAtCursor(QString(spaces,' '));
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::LF:
|
||||
m_screen->lineFeed();
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::VT:
|
||||
case C0::FF:
|
||||
qDebug() << "Unhandled" << C0::C0(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::CR:
|
||||
m_screen->moveCursorHome();
|
||||
tokenFinished();
|
||||
//next should be a linefeed;
|
||||
break;
|
||||
case C0::SOorLS1:
|
||||
case C0::SIorLS0:
|
||||
case C0::DLE:
|
||||
case C0::DC1:
|
||||
case C0::DC2:
|
||||
case C0::DC3:
|
||||
case C0::DC4:
|
||||
case C0::NAK:
|
||||
case C0::SYN:
|
||||
case C0::ETB:
|
||||
case C0::CAN:
|
||||
case C0::EM:
|
||||
case C0::SUB:
|
||||
qDebug() << "Unhandled" << C0::C0(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case C0::ESC:
|
||||
m_decode_state = DecodeC1_7bit;
|
||||
break;
|
||||
case C0::IS4:
|
||||
case C0::IS3:
|
||||
case C0::IS2:
|
||||
case C0::IS1:
|
||||
default:
|
||||
qDebug() << "Unhandled" << C0::C0(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::decodeC1_7bit(uchar character)
|
||||
{
|
||||
if (yat_parser_debug)
|
||||
qDebug() << C1_7bit::C1_7bit(character);
|
||||
switch(character) {
|
||||
case C1_7bit::CSI:
|
||||
m_decode_state = DecodeCSI;
|
||||
break;
|
||||
case C1_7bit::OSC:
|
||||
m_decode_state = DecodeOSC;
|
||||
break;
|
||||
case C1_7bit::RI:
|
||||
m_screen->reverseLineFeed();
|
||||
tokenFinished();
|
||||
break;
|
||||
case '%':
|
||||
case '#':
|
||||
case '(':
|
||||
m_parameters.append(-character);
|
||||
m_decode_state = DecodeOtherEscape;
|
||||
break;
|
||||
case '=':
|
||||
qDebug() << "Application keypad";
|
||||
tokenFinished();
|
||||
break;
|
||||
case '>':
|
||||
qDebug() << "Normal keypad mode";
|
||||
tokenFinished();
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unhandled" << C1_7bit::C1_7bit(character);
|
||||
tokenFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::decodeParameters(uchar character)
|
||||
{
|
||||
switch (character) {
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
case 0x35:
|
||||
case 0x36:
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
m_parameter_string.append(character);
|
||||
break;
|
||||
case 0x3a:
|
||||
qDebug() << "Encountered special delimiter in parameterbyte";
|
||||
break;
|
||||
case 0x3b:
|
||||
appendParameter();
|
||||
break;
|
||||
case 0x3c:
|
||||
case 0x3d:
|
||||
case 0x3e:
|
||||
case 0x3f:
|
||||
appendParameter();
|
||||
m_parameters.append(-character);
|
||||
break;
|
||||
default:
|
||||
//this is undefined for now
|
||||
qDebug() << "Encountered undefined parameter byte";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::decodeCSI(uchar character)
|
||||
{
|
||||
if (character >= 0x30 && character <= 0x3f) {
|
||||
decodeParameters(character);
|
||||
} else {
|
||||
if (character >= 0x20 && character <= 0x2f) {
|
||||
if (m_intermediate_char.unicode())
|
||||
qDebug() << "Warning!: double intermediate bytes found in CSI";
|
||||
m_intermediate_char = character;
|
||||
} else if (character >= 0x40 && character <= 0x7d) {
|
||||
if (m_intermediate_char.unicode()) {
|
||||
if (yat_parser_debug)
|
||||
qDebug() << FinalBytesSingleIntermediate::FinalBytesSingleIntermediate(character);
|
||||
switch (character) {
|
||||
case FinalBytesSingleIntermediate::SL:
|
||||
case FinalBytesSingleIntermediate::SR:
|
||||
case FinalBytesSingleIntermediate::GSM:
|
||||
case FinalBytesSingleIntermediate::GSS:
|
||||
case FinalBytesSingleIntermediate::FNT:
|
||||
case FinalBytesSingleIntermediate::TSS:
|
||||
case FinalBytesSingleIntermediate::JFY:
|
||||
case FinalBytesSingleIntermediate::SPI:
|
||||
case FinalBytesSingleIntermediate::QUAD:
|
||||
case FinalBytesSingleIntermediate::SSU:
|
||||
case FinalBytesSingleIntermediate::PFS:
|
||||
case FinalBytesSingleIntermediate::SHS:
|
||||
case FinalBytesSingleIntermediate::SVS:
|
||||
case FinalBytesSingleIntermediate::IGS:
|
||||
case FinalBytesSingleIntermediate::IDCS:
|
||||
case FinalBytesSingleIntermediate::PPA:
|
||||
case FinalBytesSingleIntermediate::PPR:
|
||||
case FinalBytesSingleIntermediate::PPB:
|
||||
case FinalBytesSingleIntermediate::SPD:
|
||||
case FinalBytesSingleIntermediate::DTA:
|
||||
case FinalBytesSingleIntermediate::SHL:
|
||||
case FinalBytesSingleIntermediate::SLL:
|
||||
case FinalBytesSingleIntermediate::FNK:
|
||||
case FinalBytesSingleIntermediate::SPQR:
|
||||
case FinalBytesSingleIntermediate::SEF:
|
||||
case FinalBytesSingleIntermediate::PEC:
|
||||
case FinalBytesSingleIntermediate::SSW:
|
||||
case FinalBytesSingleIntermediate::SACS:
|
||||
case FinalBytesSingleIntermediate::SAPV:
|
||||
case FinalBytesSingleIntermediate::STAB:
|
||||
case FinalBytesSingleIntermediate::GCC:
|
||||
case FinalBytesSingleIntermediate::TATE:
|
||||
case FinalBytesSingleIntermediate::TALE:
|
||||
case FinalBytesSingleIntermediate::TAC:
|
||||
case FinalBytesSingleIntermediate::TCC:
|
||||
case FinalBytesSingleIntermediate::TSR:
|
||||
case FinalBytesSingleIntermediate::SCO:
|
||||
case FinalBytesSingleIntermediate::SRCS:
|
||||
case FinalBytesSingleIntermediate::SCS:
|
||||
case FinalBytesSingleIntermediate::SLS:
|
||||
case FinalBytesSingleIntermediate::SCP:
|
||||
default:
|
||||
qDebug() << "unhandled CSI" << FinalBytesSingleIntermediate::FinalBytesSingleIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (yat_parser_debug)
|
||||
qDebug() << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
switch (character) {
|
||||
case FinalBytesNoIntermediate::ICH: {
|
||||
appendParameter();
|
||||
int n_chars = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
qDebug() << "ICH WITH n_chars" << n_chars;
|
||||
m_screen->insertEmptyCharsAtCursor(n_chars);
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CUU: {
|
||||
appendParameter();
|
||||
Q_ASSERT(m_parameters.size() < 2);
|
||||
int move_up = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
m_screen->moveCursorUp(move_up);
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CUD:
|
||||
tokenFinished();
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CUF:{
|
||||
appendParameter();
|
||||
Q_ASSERT(m_parameters.size() < 2);
|
||||
int move_right = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
m_screen->moveCursorRight(move_right);
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CUB:
|
||||
case FinalBytesNoIntermediate::CNL:
|
||||
case FinalBytesNoIntermediate::CPL:
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CHA: {
|
||||
appendParameter();
|
||||
Q_ASSERT(m_parameters.size() < 2);
|
||||
int move_to_pos_on_line = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
m_screen->moveCursorToCharacter(move_to_pos_on_line);
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CUP:
|
||||
appendParameter();
|
||||
if (!m_parameters.size()) {
|
||||
m_screen->moveCursorTop();
|
||||
m_screen->moveCursorHome();
|
||||
} else if (m_parameters.size() == 2){
|
||||
m_screen->moveCursor(m_parameters.at(1), m_parameters.at(0));
|
||||
} else {
|
||||
qDebug() << "OHOHOHOH";
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::CHT:
|
||||
tokenFinished();
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
break;
|
||||
case FinalBytesNoIntermediate::ED:
|
||||
appendParameter();
|
||||
if (!m_parameters.size()) {
|
||||
m_screen->eraseFromCurrentLineToEndOfScreen();
|
||||
} else {
|
||||
switch (m_parameters.at(0)) {
|
||||
case 1:
|
||||
m_screen->eraseFromCurrentLineToBeginningOfScreen();
|
||||
break;
|
||||
case 2:
|
||||
m_screen->eraseScreen();
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Invalid parameter value for FinalBytesNoIntermediate::ED";
|
||||
}
|
||||
}
|
||||
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::EL:
|
||||
appendParameter();
|
||||
if (!m_parameters.size() || m_parameters.at(0) == 0) {
|
||||
m_screen->eraseFromCursorPositionToEndOfLine();
|
||||
} else if (m_parameters.at(0) == 1) {
|
||||
m_screen->eraseToCursorPosition();
|
||||
} else if (m_parameters.at(0) == 2) {
|
||||
m_screen->eraseLine();
|
||||
} else{
|
||||
qDebug() << "Fault when processing FinalBytesNoIntermediate::EL";
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::IL: {
|
||||
appendParameter();
|
||||
int count = 1;
|
||||
if (m_parameters.size()) {
|
||||
count = m_parameters.at(0);
|
||||
}
|
||||
m_screen->insertLines(count);
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::DL: {
|
||||
appendParameter();
|
||||
int count = 1;
|
||||
if (m_parameters.size()) {
|
||||
count = m_parameters.at(0);
|
||||
}
|
||||
m_screen->deleteLines(count);
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::EF:
|
||||
case FinalBytesNoIntermediate::EA:
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::DCH:{
|
||||
appendParameter();
|
||||
Q_ASSERT(m_parameters.size() < 2);
|
||||
int n_chars = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
m_screen->deleteCharacters(n_chars);
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::SSE:
|
||||
case FinalBytesNoIntermediate::CPR:
|
||||
case FinalBytesNoIntermediate::SU:
|
||||
case FinalBytesNoIntermediate::SD:
|
||||
case FinalBytesNoIntermediate::NP:
|
||||
case FinalBytesNoIntermediate::PP:
|
||||
case FinalBytesNoIntermediate::CTC:
|
||||
case FinalBytesNoIntermediate::ECH:
|
||||
case FinalBytesNoIntermediate::CVT:
|
||||
case FinalBytesNoIntermediate::CBT:
|
||||
case FinalBytesNoIntermediate::SRS:
|
||||
case FinalBytesNoIntermediate::PTX:
|
||||
case FinalBytesNoIntermediate::SDS:
|
||||
case FinalBytesNoIntermediate::SIMD:
|
||||
case FinalBytesNoIntermediate::HPA:
|
||||
case FinalBytesNoIntermediate::HPR:
|
||||
case FinalBytesNoIntermediate::REP:
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::DA:
|
||||
appendParameter();
|
||||
if (m_parameters.size()) {
|
||||
switch (m_parameters.at(0)) {
|
||||
case -'>':
|
||||
m_screen->sendSecondaryDA();
|
||||
break;
|
||||
case -'?':
|
||||
qDebug() << "WHAT!!!";
|
||||
break; //ignore
|
||||
case 0:
|
||||
default:
|
||||
m_screen->sendPrimaryDA();
|
||||
}
|
||||
} else {
|
||||
m_screen->sendPrimaryDA();
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::VPA: {
|
||||
appendParameter();
|
||||
Q_ASSERT(m_parameters.size() < 2);
|
||||
int move_to_line = m_parameters.size() ? m_parameters.at(0) : 1;
|
||||
m_screen->moveCursorToLine(move_to_line);
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::VPR:
|
||||
case FinalBytesNoIntermediate::HVP:
|
||||
case FinalBytesNoIntermediate::TBC:
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::SM:
|
||||
appendParameter();
|
||||
if (m_parameters.size() && m_parameters.at(0) == -'?') {
|
||||
if (m_parameters.size() > 1) {
|
||||
switch (m_parameters.at(1)) {
|
||||
case 1:
|
||||
m_screen->setApplicationCursorKeysMode(true);
|
||||
break;
|
||||
case 4:
|
||||
qDebug() << "Insertion mode";
|
||||
break;
|
||||
case 7:
|
||||
qDebug() << "MODE 7";
|
||||
break;
|
||||
case 12:
|
||||
m_screen->setCursorBlinking(true);
|
||||
break;
|
||||
case 25:
|
||||
m_screen->setCursorVisible(true);
|
||||
break;
|
||||
case 1034:
|
||||
//I don't know what this sequence is
|
||||
break;
|
||||
case 1049:
|
||||
m_screen->saveCursor();
|
||||
m_screen->saveScreenData();
|
||||
break;
|
||||
default:
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM ? with parameter:" << m_parameters.at(1);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM ?";
|
||||
}
|
||||
} else {
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM";
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::MC:
|
||||
case FinalBytesNoIntermediate::HPB:
|
||||
case FinalBytesNoIntermediate::VPB:
|
||||
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::RM:
|
||||
appendParameter();
|
||||
if (m_parameters.size()) {
|
||||
switch(m_parameters.at(0)) {
|
||||
case -'?':
|
||||
if (m_parameters.size() > 1) {
|
||||
switch(m_parameters.at(1)) {
|
||||
case 1:
|
||||
qDebug() << "Normal cursor keys";
|
||||
break;
|
||||
case 12:
|
||||
m_screen->setCursorBlinking(false);
|
||||
break;
|
||||
case 25:
|
||||
m_screen->setCursorVisible(false);
|
||||
break;
|
||||
case 1049:
|
||||
m_screen->restoreCursor();
|
||||
m_screen->restoreScreenData();
|
||||
break;
|
||||
default:
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM? with "
|
||||
"parameter " << m_parameters.at(1);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM";
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
m_screen->setInsertMode(Screen::Replace);
|
||||
default:
|
||||
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM";
|
||||
break;
|
||||
}
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::SGR: {
|
||||
appendParameter();
|
||||
|
||||
if (!m_parameters.size())
|
||||
m_parameters << 0;
|
||||
|
||||
for (int i = 0; i < m_parameters.size();i++) {
|
||||
switch(m_parameters.at(i)) {
|
||||
case 0:
|
||||
// m_screen->setTextStyle(TextStyle::Normal);
|
||||
m_screen->resetStyle();
|
||||
break;
|
||||
case 1:
|
||||
m_screen->setTextStyle(TextStyle::Bold);
|
||||
break;
|
||||
case 5:
|
||||
m_screen->setTextStyle(TextStyle::Blinking);
|
||||
break;
|
||||
case 7:
|
||||
m_screen->setTextStyle(TextStyle::Inverse);
|
||||
break;
|
||||
case 8:
|
||||
qDebug() << "SGR: Hidden text not supported";
|
||||
break;
|
||||
case 22:
|
||||
m_screen->setTextStyle(TextStyle::Normal);
|
||||
break;
|
||||
case 24:
|
||||
m_screen->setTextStyle(TextStyle::Underlined, false);
|
||||
break;
|
||||
case 25:
|
||||
m_screen->setTextStyle(TextStyle::Blinking, false);
|
||||
break;
|
||||
case 27:
|
||||
m_screen->setTextStyle(TextStyle::Inverse, false);
|
||||
break;
|
||||
case 28:
|
||||
qDebug() << "SGR: Visible text is allways on";
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
case 36:
|
||||
case 37:
|
||||
// case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
// case 38:
|
||||
case 49:
|
||||
m_screen->setTextStyleColor(m_parameters.at(i));
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
qDebug() << "Unknown SGR" << m_parameters.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
tokenFinished();
|
||||
}
|
||||
break;
|
||||
case FinalBytesNoIntermediate::DSR:
|
||||
qDebug() << "report";
|
||||
case FinalBytesNoIntermediate::DAQ:
|
||||
case FinalBytesNoIntermediate::Reserved0:
|
||||
case FinalBytesNoIntermediate::Reserved1:
|
||||
qDebug() << "Unhandeled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::Reserved2:
|
||||
appendParameter();
|
||||
if (m_parameters.size() == 2) {
|
||||
if (m_parameters.at(0) >= 0) {
|
||||
m_screen->setScrollArea(m_parameters.at(0),m_parameters.at(1));
|
||||
} else {
|
||||
qDebug() << "Unknown value for scrollRegion";
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Unknown parameterset for scrollRegion";
|
||||
}
|
||||
tokenFinished();
|
||||
break;
|
||||
case FinalBytesNoIntermediate::Reserved3:
|
||||
case FinalBytesNoIntermediate::Reserved4:
|
||||
case FinalBytesNoIntermediate::Reserved5:
|
||||
case FinalBytesNoIntermediate::Reserved6:
|
||||
case FinalBytesNoIntermediate::Reserved7:
|
||||
case FinalBytesNoIntermediate::Reserved8:
|
||||
case FinalBytesNoIntermediate::Reserved9:
|
||||
case FinalBytesNoIntermediate::Reserveda:
|
||||
case FinalBytesNoIntermediate::Reservedb:
|
||||
case FinalBytesNoIntermediate::Reservedc:
|
||||
case FinalBytesNoIntermediate::Reservedd:
|
||||
case FinalBytesNoIntermediate::Reservede:
|
||||
case FinalBytesNoIntermediate::Reservedf:
|
||||
default:
|
||||
qDebug() << "Unhandeled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
||||
tokenFinished();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::decodeOSC(uchar character)
|
||||
{
|
||||
if (!m_parameters.size() &&
|
||||
character >= 0x30 && character <= 0x3f) {
|
||||
decodeParameters(character);
|
||||
} else {
|
||||
if (m_decode_osc_state == None) {
|
||||
appendParameter();
|
||||
if (m_parameters.size() != 1) {
|
||||
tokenFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_parameters.at(0)) {
|
||||
case 0:
|
||||
m_decode_osc_state = ChangeWindowAndIconName;
|
||||
break;
|
||||
case 1:
|
||||
m_decode_osc_state = ChangeIconTitle;
|
||||
break;
|
||||
case 2:
|
||||
m_decode_osc_state = ChangeWindowTitle;
|
||||
break;
|
||||
default:
|
||||
m_decode_osc_state = Unknown;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (character == 0x07) {
|
||||
if (m_decode_osc_state == ChangeWindowAndIconName ||
|
||||
m_decode_osc_state == ChangeWindowTitle) {
|
||||
QString title = QString::fromUtf8(m_current_data.mid(m_current_token_start+4,
|
||||
m_currrent_position - m_current_token_start -1));
|
||||
m_screen->setTitle(title);
|
||||
}
|
||||
tokenFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::decodeOtherEscape(uchar character)
|
||||
{
|
||||
Q_ASSERT(m_parameters.size());
|
||||
switch(m_parameters.at(0)) {
|
||||
case -'(':
|
||||
switch(character) {
|
||||
case 0:
|
||||
m_screen->setCharacterMap("DEC Special Character and Line Drawing Set");
|
||||
break;
|
||||
case 'A':
|
||||
m_screen->setCharacterMap("UK");
|
||||
break;
|
||||
case 'B':
|
||||
m_screen->setCharacterMap("USASCII");
|
||||
break;
|
||||
case '4':
|
||||
m_screen->setCharacterMap("Dutch");
|
||||
break;
|
||||
case 'C':
|
||||
case '5':
|
||||
m_screen->setCharacterMap("Finnish");
|
||||
break;
|
||||
case 'R':
|
||||
m_screen->setCharacterMap("French");
|
||||
break;
|
||||
case 'Q':
|
||||
m_screen->setCharacterMap("FrenchCanadian");
|
||||
break;
|
||||
case 'K':
|
||||
m_screen->setCharacterMap("German");
|
||||
break;
|
||||
case 'Y':
|
||||
m_screen->setCharacterMap("Italian");
|
||||
break;
|
||||
case 'E':
|
||||
case '6':
|
||||
m_screen->setCharacterMap("NorDan");
|
||||
break;
|
||||
case 'Z':
|
||||
m_screen->setCharacterMap("Spanish");
|
||||
break;
|
||||
case 'H':
|
||||
case '7':
|
||||
m_screen->setCharacterMap("Sweedish");
|
||||
break;
|
||||
case '=':
|
||||
m_screen->setCharacterMap("Swiss");
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Not supported Character set!";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Other Escape sequence not recognized";
|
||||
}
|
||||
tokenFinished();
|
||||
}
|
||||
|
||||
void Parser::tokenFinished()
|
||||
{
|
||||
m_decode_state = PlainText;
|
||||
m_decode_osc_state = None;
|
||||
|
||||
m_parameters.clear();
|
||||
m_parameter_string.clear();
|
||||
|
||||
m_current_token_start = m_currrent_position + 1;
|
||||
m_intermediate_char = 0;
|
||||
}
|
||||
|
||||
void Parser::appendParameter()
|
||||
{
|
||||
if (m_parameter_string.size()) {
|
||||
m_parameters.append(m_parameter_string.toUShort());
|
||||
m_parameter_string.clear();
|
||||
}
|
||||
}
|
||||
|
83
yat/backend/parser.h
Normal file
83
yat/backend/parser.h
Normal file
@ -0,0 +1,83 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QLinkedList>
|
||||
|
||||
#include "text.h"
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(Screen *screen);
|
||||
|
||||
void addData(const QByteArray &data);
|
||||
|
||||
private:
|
||||
|
||||
enum DecodeState {
|
||||
PlainText,
|
||||
DecodeC0,
|
||||
DecodeC1_7bit,
|
||||
DecodeCSI,
|
||||
DecodeOSC,
|
||||
DecodeOtherEscape
|
||||
};
|
||||
|
||||
enum DecodeOSCState {
|
||||
None,
|
||||
ChangeWindowAndIconName,
|
||||
ChangeIconTitle,
|
||||
ChangeWindowTitle,
|
||||
Unknown
|
||||
};
|
||||
|
||||
void decodeC0(uchar character);
|
||||
void decodeC1_7bit(uchar character);
|
||||
void decodeParameters(uchar character);
|
||||
void decodeCSI(uchar character);
|
||||
void decodeOSC(uchar character);
|
||||
void decodeOtherEscape(uchar character);
|
||||
|
||||
void tokenFinished();
|
||||
|
||||
void appendParameter();
|
||||
|
||||
DecodeState m_decode_state;
|
||||
DecodeOSCState m_decode_osc_state;
|
||||
|
||||
QByteArray m_current_data;
|
||||
|
||||
int m_current_token_start;
|
||||
int m_currrent_position;
|
||||
|
||||
QChar m_intermediate_char;
|
||||
|
||||
QByteArray m_parameter_string;
|
||||
QVector<int> m_parameters;
|
||||
|
||||
Screen *m_screen;
|
||||
};
|
||||
|
||||
#endif // PARSER_H
|
958
yat/backend/screen.cpp
Normal file
958
yat/backend/screen.cpp
Normal file
@ -0,0 +1,958 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#include "line.h"
|
||||
|
||||
#include "controll_chars.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQuick/QQuickView>
|
||||
#include <QtQml/QQmlComponent>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <float.h>
|
||||
|
||||
Screen::Screen(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_parser(this)
|
||||
, m_timer_event_id(0)
|
||||
, m_cursor_visible(true)
|
||||
, m_cursor_visible_changed(false)
|
||||
, m_cursor_blinking(true)
|
||||
, m_cursor_blinking_changed(false)
|
||||
, m_insert_mode(Replace)
|
||||
, m_selection_valid(false)
|
||||
, m_selection_moved(0)
|
||||
, m_flash(false)
|
||||
, m_cursor_changed(false)
|
||||
, m_reset(false)
|
||||
, m_application_cursor_key_mode(false)
|
||||
{
|
||||
connect(&m_pty, &YatPty::readyRead, this, &Screen::readData);
|
||||
|
||||
m_screen_stack.reserve(2);
|
||||
|
||||
m_cursor_stack << QPoint(0,0);
|
||||
|
||||
m_current_text_style.style = TextStyle::Normal;
|
||||
m_current_text_style.forground = ColorPalette::DefaultForground;
|
||||
m_current_text_style.background = ColorPalette::DefaultBackground;
|
||||
|
||||
connect(&m_pty, SIGNAL(hangupReceived()),qGuiApp, SLOT(quit()));
|
||||
}
|
||||
|
||||
Screen::~Screen()
|
||||
{
|
||||
for (int i = 0; i < m_screen_stack.size(); i++) {
|
||||
delete m_screen_stack.at(i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QColor Screen::screenBackground()
|
||||
{
|
||||
return QColor(Qt::black);
|
||||
}
|
||||
|
||||
QColor Screen::defaultForgroundColor() const
|
||||
{
|
||||
return m_palette.normalColor(ColorPalette::DefaultForground);
|
||||
}
|
||||
|
||||
QColor Screen::defaultBackgroundColor() const
|
||||
{
|
||||
return QColor(Qt::transparent);
|
||||
}
|
||||
|
||||
void Screen::setHeight(int height)
|
||||
{
|
||||
if (!m_screen_stack.size()) {
|
||||
m_screen_stack << new ScreenData(this);
|
||||
}
|
||||
|
||||
ScreenData *data = current_screen_data();
|
||||
int size_difference = data->height() - height;
|
||||
|
||||
if (!size_difference)
|
||||
return;
|
||||
|
||||
data->setHeight(height);
|
||||
|
||||
if (size_difference > 0) {
|
||||
if (current_cursor_y() > 0)
|
||||
current_cursor_pos().ry()--;
|
||||
}
|
||||
|
||||
m_pty.setHeight(height, height * 10);
|
||||
dispatchChanges();
|
||||
}
|
||||
|
||||
void Screen::setWidth(int width)
|
||||
{
|
||||
if (!m_screen_stack.size())
|
||||
m_screen_stack << new ScreenData(this);
|
||||
|
||||
current_screen_data()->setWidth(width);
|
||||
m_pty.setWidth(width, width * 10);
|
||||
|
||||
}
|
||||
|
||||
int Screen::width() const
|
||||
{
|
||||
return m_pty.size().width();
|
||||
}
|
||||
|
||||
void Screen::saveScreenData()
|
||||
{
|
||||
ScreenData *new_data = new ScreenData(this);
|
||||
QSize pty_size = m_pty.size();
|
||||
new_data->setHeight(pty_size.height());
|
||||
new_data->setWidth(pty_size.width());
|
||||
|
||||
for (int i = 0; i < new_data->height(); i++) {
|
||||
current_screen_data()->at(i)->setVisible(false);
|
||||
}
|
||||
|
||||
m_screen_stack << new_data;
|
||||
|
||||
setSelectionEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
void Screen::restoreScreenData()
|
||||
{
|
||||
ScreenData *data = current_screen_data();
|
||||
m_screen_stack.remove(m_screen_stack.size()-1);
|
||||
delete data;
|
||||
|
||||
QSize pty_size = m_pty.size();
|
||||
current_screen_data()->setHeight(pty_size.height());
|
||||
current_screen_data()->setWidth(pty_size.width());
|
||||
|
||||
for (int i = 0; i < current_screen_data()->height(); i++) {
|
||||
current_screen_data()->at(i)->setVisible(true);
|
||||
}
|
||||
|
||||
setSelectionEnabled(false);
|
||||
}
|
||||
|
||||
int Screen::height() const
|
||||
{
|
||||
return current_screen_data()->height();
|
||||
}
|
||||
|
||||
void Screen::setInsertMode(InsertMode mode)
|
||||
{
|
||||
m_insert_mode = mode;
|
||||
}
|
||||
|
||||
void Screen::setTextStyle(TextStyle::Style style, bool add)
|
||||
{
|
||||
if (add) {
|
||||
m_current_text_style.style |= style;
|
||||
} else {
|
||||
m_current_text_style.style &= !style;
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::resetStyle()
|
||||
{
|
||||
m_current_text_style.background = ColorPalette::DefaultBackground;
|
||||
m_current_text_style.forground = ColorPalette::DefaultForground;
|
||||
m_current_text_style.style = TextStyle::Normal;
|
||||
}
|
||||
|
||||
TextStyle Screen::currentTextStyle() const
|
||||
{
|
||||
return m_current_text_style;
|
||||
}
|
||||
|
||||
TextStyle Screen::defaultTextStyle() const
|
||||
{
|
||||
TextStyle style;
|
||||
style.style = TextStyle::Normal;
|
||||
style.forground = ColorPalette::DefaultForground;
|
||||
style.background = ColorPalette::DefaultBackground;
|
||||
return style;
|
||||
}
|
||||
|
||||
QPoint Screen::cursorPosition() const
|
||||
{
|
||||
return QPoint(current_cursor_x(),current_cursor_y());
|
||||
}
|
||||
|
||||
void Screen::moveCursorHome()
|
||||
{
|
||||
current_cursor_pos().setX(0);
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorTop()
|
||||
{
|
||||
current_cursor_pos().setY(0);
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorUp(int n_positions)
|
||||
{
|
||||
if (!current_cursor_pos().y())
|
||||
return;
|
||||
|
||||
if (n_positions <= current_cursor_pos().y()) {
|
||||
current_cursor_pos().ry() -= n_positions;
|
||||
} else {
|
||||
current_cursor_pos().ry() = 0;
|
||||
}
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorDown()
|
||||
{
|
||||
current_cursor_pos().ry() += 1;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorLeft()
|
||||
{
|
||||
current_cursor_pos().rx() -= 1;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorRight(int n_positions)
|
||||
{
|
||||
current_cursor_pos().rx() += n_positions;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursor(int x, int y)
|
||||
{
|
||||
if (x != 0)
|
||||
x--;
|
||||
if (y != 0)
|
||||
y--;
|
||||
current_cursor_pos().setX(x);
|
||||
int height = this->height();
|
||||
if (y >= height) {
|
||||
current_cursor_pos().setY(height-1);
|
||||
} else {
|
||||
current_cursor_pos().setY(y);
|
||||
}
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorToLine(int line)
|
||||
{
|
||||
current_cursor_pos().setY(line-1);
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::moveCursorToCharacter(int character)
|
||||
{
|
||||
current_cursor_pos().setX(character-1);
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::deleteCharacters(int characters)
|
||||
{
|
||||
switch (m_insert_mode) {
|
||||
case Insert:
|
||||
current_screen_data()->clearCharacters(current_cursor_y(), current_cursor_x(), current_cursor_x() + characters -1);
|
||||
break;
|
||||
case Replace:
|
||||
current_screen_data()->deleteCharacters(current_cursor_y(), current_cursor_x(), current_cursor_x() + characters -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::setCursorVisible(bool visible)
|
||||
{
|
||||
m_cursor_visible = visible;
|
||||
m_cursor_visible_changed = true;
|
||||
}
|
||||
|
||||
bool Screen::cursorVisible()
|
||||
{
|
||||
return m_cursor_visible;
|
||||
}
|
||||
|
||||
void Screen::setCursorBlinking(bool blinking)
|
||||
{
|
||||
m_cursor_blinking = blinking;
|
||||
m_cursor_blinking_changed = true;
|
||||
}
|
||||
|
||||
bool Screen::cursorBlinking()
|
||||
{
|
||||
return m_cursor_blinking;
|
||||
}
|
||||
|
||||
void Screen::saveCursor()
|
||||
{
|
||||
QPoint point = current_cursor_pos();
|
||||
m_cursor_stack << point;
|
||||
}
|
||||
|
||||
void Screen::restoreCursor()
|
||||
{
|
||||
if (m_cursor_stack.size() <= 1)
|
||||
return;
|
||||
|
||||
m_cursor_stack.remove(m_screen_stack.size()-1);
|
||||
}
|
||||
|
||||
void Screen::replaceAtCursor(const QString &text)
|
||||
{
|
||||
if (m_selection_valid ) {
|
||||
if (current_cursor_y() >= m_selection_start.y() && current_cursor_y() <= m_selection_end.y())
|
||||
//don't need to schedule as event since it will only happen once
|
||||
setSelectionEnabled(false);
|
||||
}
|
||||
|
||||
if (current_cursor_x() + text.size() <= width()) {
|
||||
Line *line = current_screen_data()->at(current_cursor_y());
|
||||
line->replaceAtPos(current_cursor_x(), text, m_current_text_style);
|
||||
current_cursor_pos().rx() += text.size();
|
||||
} else {
|
||||
for (int i = 0; i < text.size();) {
|
||||
if (current_cursor_x() == width()) {
|
||||
current_cursor_pos().setX(0);
|
||||
lineFeed();
|
||||
}
|
||||
QString toLine = text.mid(i,current_screen_data()->width() - current_cursor_x());
|
||||
Line *line = current_screen_data()->at(current_cursor_y());
|
||||
line->replaceAtPos(current_cursor_x(),toLine, m_current_text_style);
|
||||
i+= toLine.size();
|
||||
current_cursor_pos().rx() += toLine.size();
|
||||
}
|
||||
}
|
||||
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::insertEmptyCharsAtCursor(int len)
|
||||
{
|
||||
if (m_selection_valid) {
|
||||
if (current_cursor_y() >= m_selection_start.y() && current_cursor_y() <= m_selection_end.y())
|
||||
//don't need to schedule as event since it will only happen once
|
||||
setSelectionEnabled(false);
|
||||
}
|
||||
|
||||
Line *line = current_screen_data()->at(current_cursor_y());
|
||||
QString empty(len, QChar(' '));
|
||||
line->insertAtPos(current_cursor_x(), empty, defaultTextStyle());
|
||||
}
|
||||
|
||||
void Screen::backspace()
|
||||
{
|
||||
current_cursor_pos().rx()--;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
|
||||
void Screen::eraseLine()
|
||||
{
|
||||
current_screen_data()->clearLine(current_cursor_y());
|
||||
}
|
||||
|
||||
void Screen::eraseFromCursorPositionToEndOfLine()
|
||||
{
|
||||
current_screen_data()->clearToEndOfLine(current_cursor_y(), current_cursor_x());
|
||||
}
|
||||
|
||||
void Screen::eraseFromCursorPosition(int n_chars)
|
||||
{
|
||||
current_screen_data()->clearCharacters(current_cursor_y(), current_cursor_x(), current_cursor_x() + n_chars - 1);
|
||||
}
|
||||
|
||||
void Screen::eraseFromCurrentLineToEndOfScreen()
|
||||
{
|
||||
current_screen_data()->clearToEndOfScreen(current_cursor_y());
|
||||
}
|
||||
|
||||
void Screen::eraseFromCurrentLineToBeginningOfScreen()
|
||||
{
|
||||
current_screen_data()->clearToBeginningOfScreen(current_cursor_y());
|
||||
|
||||
}
|
||||
|
||||
void Screen::eraseToCursorPosition()
|
||||
{
|
||||
qDebug() << "eraseToCursorPosition NOT IMPLEMENTED!";
|
||||
}
|
||||
|
||||
void Screen::eraseScreen()
|
||||
{
|
||||
current_screen_data()->clear();
|
||||
}
|
||||
|
||||
void Screen::setTextStyleColor(ushort color)
|
||||
{
|
||||
Q_ASSERT(color >= 30 && color < 50);
|
||||
if (color < 38) {
|
||||
m_current_text_style.forground = ColorPalette::Color(color - 30);
|
||||
} else if (color == 39) {
|
||||
m_current_text_style.forground = ColorPalette::DefaultForground;
|
||||
} else if (color >= 40 && color < 48) {
|
||||
m_current_text_style.background = ColorPalette::Color(color - 40);
|
||||
} else if (color == 49) {
|
||||
m_current_text_style.background = ColorPalette::DefaultBackground;
|
||||
} else {
|
||||
qDebug() << "Failed to set color";
|
||||
}
|
||||
}
|
||||
|
||||
const ColorPalette *Screen::colorPalette() const
|
||||
{
|
||||
return &m_palette;
|
||||
}
|
||||
|
||||
void Screen::lineFeed()
|
||||
{
|
||||
int cursor_y = current_cursor_y();
|
||||
if(cursor_y == current_screen_data()->scrollAreaEnd()) {
|
||||
m_selection_start.ry()--;
|
||||
m_selection_end.ry()--;
|
||||
m_selection_moved = true;
|
||||
moveLine(current_screen_data()->scrollAreaStart(),cursor_y);
|
||||
} else {
|
||||
current_cursor_pos().ry()++;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::reverseLineFeed()
|
||||
{
|
||||
int cursor_y = current_cursor_y();
|
||||
if (cursor_y == current_screen_data()->scrollAreaStart()) {
|
||||
m_selection_start.ry()++;
|
||||
m_selection_end.ry()++;
|
||||
m_selection_moved = true;
|
||||
moveLine(current_screen_data()->scrollAreaEnd(), cursor_y);
|
||||
} else {
|
||||
current_cursor_pos().ry()--;
|
||||
m_cursor_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::insertLines(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
moveLine(current_screen_data()->scrollAreaEnd(),current_cursor_y());
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::deleteLines(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
moveLine(current_cursor_y(),current_screen_data()->scrollAreaEnd());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Screen::setScrollArea(int from, int to)
|
||||
{
|
||||
from--;
|
||||
to--;
|
||||
current_screen_data()->setScrollArea(from,to);
|
||||
}
|
||||
|
||||
QPointF Screen::selectionAreaStart() const
|
||||
{
|
||||
return m_selection_start;
|
||||
}
|
||||
|
||||
void Screen::setSelectionAreaStart(const QPointF &start)
|
||||
{
|
||||
bool emitChanged = m_selection_start != start;
|
||||
m_selection_start = start;
|
||||
setSelectionValidity();
|
||||
if (emitChanged)
|
||||
emit selectionAreaStartChanged();
|
||||
}
|
||||
|
||||
QPointF Screen::selectionAreaEnd() const
|
||||
{
|
||||
return m_selection_end;
|
||||
}
|
||||
|
||||
void Screen::setSelectionAreaEnd(const QPointF &end)
|
||||
{
|
||||
bool emitChanged = m_selection_end != end;
|
||||
m_selection_end = end;
|
||||
setSelectionValidity();
|
||||
if (emitChanged)
|
||||
emit selectionAreaEndChanged();
|
||||
}
|
||||
|
||||
bool Screen::selectionEnabled() const
|
||||
{
|
||||
return m_selection_valid;
|
||||
}
|
||||
|
||||
void Screen::setSelectionEnabled(bool enabled)
|
||||
{
|
||||
bool emitchanged = m_selection_valid != enabled;
|
||||
m_selection_valid = enabled;
|
||||
if (emitchanged)
|
||||
emit selectionEnabledChanged();
|
||||
}
|
||||
|
||||
void Screen::sendSelectionToClipboard() const
|
||||
{
|
||||
current_screen_data()->sendSelectionToClipboard(m_selection_start, m_selection_end, QClipboard::Clipboard);
|
||||
}
|
||||
|
||||
void Screen::sendSelectionToSelection() const
|
||||
{
|
||||
current_screen_data()->sendSelectionToClipboard(m_selection_start, m_selection_end, QClipboard::Selection);
|
||||
}
|
||||
|
||||
void Screen::pasteFromSelection()
|
||||
{
|
||||
m_pty.write(QGuiApplication::clipboard()->text(QClipboard::Selection).toUtf8());
|
||||
}
|
||||
|
||||
void Screen::pasteFromClipboard()
|
||||
{
|
||||
m_pty.write(QGuiApplication::clipboard()->text(QClipboard::Clipboard).toUtf8());
|
||||
}
|
||||
|
||||
void Screen::doubleClicked(const QPointF &clicked)
|
||||
{
|
||||
int start, end;
|
||||
current_screen_data()->getDoubleClickSelectionArea(clicked, &start, &end);
|
||||
setSelectionAreaStart(QPointF(start,clicked.y()));
|
||||
setSelectionAreaEnd(QPointF(end,clicked.y()));
|
||||
}
|
||||
|
||||
void Screen::setTitle(const QString &title)
|
||||
{
|
||||
m_title = title;
|
||||
emit screenTitleChanged();
|
||||
}
|
||||
|
||||
QString Screen::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void Screen::scheduleFlash()
|
||||
{
|
||||
m_flash = true;
|
||||
}
|
||||
|
||||
Line *Screen::at(int i) const
|
||||
{
|
||||
return current_screen_data()->at(i);
|
||||
}
|
||||
|
||||
void Screen::printScreen() const
|
||||
{
|
||||
current_screen_data()->printStyleInformation();
|
||||
}
|
||||
|
||||
void Screen::dispatchChanges()
|
||||
{
|
||||
if (m_reset) {
|
||||
emit reset();
|
||||
m_update_actions.clear();
|
||||
m_reset = false;
|
||||
} else {
|
||||
qint16 begin_move = -1;
|
||||
qint16 end_move = -1;
|
||||
for (int i = 0; i < m_update_actions.size(); i++) {
|
||||
UpdateAction action = m_update_actions.at(i);
|
||||
switch(action.action) {
|
||||
case UpdateAction::MoveLine: {
|
||||
if (begin_move < 0) {
|
||||
begin_move = qMin(action.to_line, action.from_line);
|
||||
end_move = qMax(action.to_line, action.from_line);
|
||||
} else
|
||||
if (action.from_line > action.to_line) {
|
||||
begin_move = qMin(action.to_line, begin_move);
|
||||
end_move = qMax(action.from_line, end_move);
|
||||
} else {
|
||||
begin_move = qMin(action.from_line, begin_move);
|
||||
end_move = qMax(action.to_line, end_move);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qDebug() << "unhandeled UpdatAction in TerminalScreen";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (begin_move >= 0) {
|
||||
current_screen_data()->updateIndexes(begin_move, end_move);
|
||||
}
|
||||
|
||||
current_screen_data()->dispatchLineEvents();
|
||||
emit dispatchTextSegmentChanges();
|
||||
}
|
||||
|
||||
if (m_flash) {
|
||||
m_flash = false;
|
||||
emit flash();
|
||||
}
|
||||
|
||||
if (m_cursor_changed) {
|
||||
m_cursor_changed = false;
|
||||
emit cursorPositionChanged(current_cursor_x(), current_cursor_y());
|
||||
}
|
||||
|
||||
if (m_cursor_visible_changed) {
|
||||
m_cursor_visible_changed = false;
|
||||
emit cursorVisibleChanged();
|
||||
}
|
||||
|
||||
if (m_cursor_blinking_changed) {
|
||||
m_cursor_blinking_changed = false;
|
||||
emit cursorBlinkingChanged();
|
||||
|
||||
}
|
||||
|
||||
if (m_selection_valid && m_selection_moved) {
|
||||
if (m_selection_start.y() < 0 ||
|
||||
m_selection_end.y() >= current_screen_data()->height()) {
|
||||
setSelectionEnabled(false);
|
||||
} else {
|
||||
emit selectionAreaStartChanged();
|
||||
emit selectionAreaEndChanged();
|
||||
}
|
||||
}
|
||||
|
||||
m_update_actions.clear();
|
||||
}
|
||||
|
||||
void Screen::sendPrimaryDA()
|
||||
{
|
||||
m_pty.write(QByteArrayLiteral("\033[?6c"));
|
||||
|
||||
}
|
||||
|
||||
void Screen::sendSecondaryDA()
|
||||
{
|
||||
m_pty.write(QByteArrayLiteral("\033[>1;95;0c"));
|
||||
}
|
||||
|
||||
void Screen::setCharacterMap(const QString &string)
|
||||
{
|
||||
m_character_map = string;
|
||||
}
|
||||
|
||||
QString Screen::characterMap() const
|
||||
{
|
||||
return m_character_map;
|
||||
}
|
||||
|
||||
void Screen::setApplicationCursorKeysMode(bool enable)
|
||||
{
|
||||
m_application_cursor_key_mode = enable;
|
||||
}
|
||||
|
||||
bool Screen::applicationCursorKeyMode() const
|
||||
{
|
||||
return m_application_cursor_key_mode;
|
||||
}
|
||||
|
||||
static bool hasControll(Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
return modifiers & Qt::MetaModifier;
|
||||
#else
|
||||
return modifiers & Qt::ControlModifier;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool hasMeta(Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
return modifiers & Qt::ControlModifier;
|
||||
#else
|
||||
return modifiers & Qt::MetaModifier;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::sendKey(const QString &text, Qt::Key key, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
/// UGH, this functions should be re-written
|
||||
char escape = '\0';
|
||||
char control = '\0';
|
||||
char code = '\0';
|
||||
QVector<ushort> parameters;
|
||||
bool found = true;
|
||||
|
||||
switch(key) {
|
||||
case Qt::Key_Up:
|
||||
escape = C0::ESC;
|
||||
if (m_application_cursor_key_mode)
|
||||
control = C1_7bit::SS3;
|
||||
else
|
||||
control = C1_7bit::CSI;
|
||||
|
||||
code = 'A';
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
escape = C0::ESC;
|
||||
if (m_application_cursor_key_mode)
|
||||
control = C1_7bit::SS3;
|
||||
else
|
||||
control = C1_7bit::CSI;
|
||||
|
||||
code = 'C';
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
escape = C0::ESC;
|
||||
if (m_application_cursor_key_mode)
|
||||
control = C1_7bit::SS3;
|
||||
else
|
||||
control = C1_7bit::CSI;
|
||||
|
||||
code = 'B';
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
escape = C0::ESC;
|
||||
if (m_application_cursor_key_mode)
|
||||
control = C1_7bit::SS3;
|
||||
else
|
||||
control = C1_7bit::CSI;
|
||||
|
||||
code = 'D';
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(2);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_Delete:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(3);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(1);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(4);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(5);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
parameters.append(6);
|
||||
code = '~';
|
||||
break;
|
||||
case Qt::Key_F1:
|
||||
case Qt::Key_F2:
|
||||
case Qt::Key_F3:
|
||||
case Qt::Key_F4:
|
||||
if (m_application_cursor_key_mode) {
|
||||
parameters.append((key & 0xff) - 37);
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
code = '~';
|
||||
}
|
||||
break;
|
||||
case Qt::Key_F5:
|
||||
case Qt::Key_F6:
|
||||
case Qt::Key_F7:
|
||||
case Qt::Key_F8:
|
||||
case Qt::Key_F9:
|
||||
case Qt::Key_F10:
|
||||
case Qt::Key_F11:
|
||||
case Qt::Key_F12:
|
||||
if (m_application_cursor_key_mode) {
|
||||
parameters.append((key & 0xff) - 36);
|
||||
escape = C0::ESC;
|
||||
control = C1_7bit::CSI;
|
||||
code = '~';
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_Shift:
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_AltGr:
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
found = false;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
int term_mods = 0;
|
||||
if (modifiers & Qt::ShiftModifier)
|
||||
term_mods |= 1;
|
||||
if (modifiers & Qt::AltModifier)
|
||||
term_mods |= 2;
|
||||
if (modifiers & Qt::ControlModifier)
|
||||
term_mods |= 4;
|
||||
|
||||
QByteArray toPty;
|
||||
|
||||
if (term_mods) {
|
||||
term_mods++;
|
||||
parameters.append(term_mods);
|
||||
}
|
||||
if (escape)
|
||||
toPty.append(escape);
|
||||
if (control)
|
||||
toPty.append(control);
|
||||
if (parameters.size()) {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
if (i)
|
||||
toPty.append(';');
|
||||
toPty.append(QByteArray::number(parameters.at(i)));
|
||||
}
|
||||
}
|
||||
if (code)
|
||||
toPty.append(code);
|
||||
m_pty.write(toPty);
|
||||
|
||||
} else {
|
||||
QString verifiedText = text.simplified();
|
||||
if (verifiedText.isEmpty()) {
|
||||
switch (key) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
verifiedText = "\r";
|
||||
break;
|
||||
case Qt::Key_Backspace:
|
||||
verifiedText = "\010";
|
||||
break;
|
||||
case Qt::Key_Tab:
|
||||
verifiedText = "\t";
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_Meta:
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_Shift:
|
||||
return;
|
||||
case Qt::Key_Space:
|
||||
verifiedText = " ";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
QByteArray to_pty;
|
||||
QByteArray key_text;
|
||||
if (hasControll(modifiers)) {
|
||||
char key_char = verifiedText.toLocal8Bit().at(0);
|
||||
key_text.append(key_char & 0x1F);
|
||||
} else {
|
||||
key_text = verifiedText.toUtf8();
|
||||
}
|
||||
|
||||
if (modifiers & Qt::AltModifier) {
|
||||
to_pty.append(C0::ESC);
|
||||
}
|
||||
|
||||
if (hasMeta(modifiers)) {
|
||||
to_pty.append(C0::ESC);
|
||||
to_pty.append('@');
|
||||
to_pty.append(FinalBytesNoIntermediate::Reserved3);
|
||||
}
|
||||
|
||||
to_pty.append(key_text);
|
||||
m_pty.write(to_pty);
|
||||
}
|
||||
}
|
||||
|
||||
YatPty *Screen::pty()
|
||||
{
|
||||
return &m_pty;
|
||||
}
|
||||
|
||||
Line *Screen::line_at_cursor() const
|
||||
{
|
||||
return current_screen_data()->at(current_cursor_y());
|
||||
}
|
||||
|
||||
void Screen::readData(const QByteArray &data)
|
||||
{
|
||||
m_parser.addData(data);
|
||||
|
||||
if (!m_timer_event_id)
|
||||
m_timer_event_id = startTimer(3);
|
||||
m_time_since_parsed.restart();
|
||||
}
|
||||
|
||||
void Screen::moveLine(qint16 from, qint16 to)
|
||||
{
|
||||
current_screen_data()->moveLine(from,to);
|
||||
scheduleMoveSignal(from,to);
|
||||
}
|
||||
|
||||
void Screen::scheduleMoveSignal(qint16 from, qint16 to)
|
||||
{
|
||||
if (m_update_actions.size() &&
|
||||
m_update_actions.last().action == UpdateAction::MoveLine &&
|
||||
m_update_actions.last().from_line == from &&
|
||||
m_update_actions.last().to_line == to) {
|
||||
m_update_actions.last().count++;
|
||||
} else {
|
||||
m_update_actions << UpdateAction(UpdateAction::MoveLine, from, to, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Screen::setSelectionValidity()
|
||||
{
|
||||
if (m_selection_end.y() > m_selection_start.y() ||
|
||||
(m_selection_end.y() == m_selection_start.y() &&
|
||||
m_selection_end.x() > m_selection_start.x())) {
|
||||
setSelectionEnabled(true);
|
||||
} else {
|
||||
setSelectionEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Screen::timerEvent(QTimerEvent *)
|
||||
{
|
||||
if (m_timer_event_id && m_time_since_parsed.elapsed() > 3) {
|
||||
killTimer(m_timer_event_id);
|
||||
m_timer_event_id = 0;
|
||||
dispatchChanges();
|
||||
}
|
||||
}
|
243
yat/backend/screen.h
Normal file
243
yat/backend/screen.h
Normal file
@ -0,0 +1,243 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef TERMINALSCREEN_H
|
||||
#define TERMINALSCREEN_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "text.h"
|
||||
#include "color_palette.h"
|
||||
#include "parser.h"
|
||||
#include "yat_pty.h"
|
||||
#include "update_action.h"
|
||||
#include "screen_data.h"
|
||||
|
||||
#include <QtCore/QPoint>
|
||||
#include <QtCore/QSize>
|
||||
#include <QtCore/QStack>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
|
||||
class Line;
|
||||
class QQuickItem;
|
||||
class QQmlEngine;
|
||||
class QQmlComponent;
|
||||
|
||||
class Screen : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int height READ height WRITE setHeight)
|
||||
Q_PROPERTY(int width READ width WRITE setWidth)
|
||||
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY screenTitleChanged)
|
||||
Q_PROPERTY(bool cursorVisible READ cursorVisible NOTIFY cursorVisibleChanged)
|
||||
Q_PROPERTY(bool cursorBlinking READ cursorBlinking NOTIFY cursorBlinkingChanged)
|
||||
Q_PROPERTY(bool selectionEnabled READ selectionEnabled NOTIFY selectionEnabledChanged)
|
||||
Q_PROPERTY(QPointF selectionAreaStart READ selectionAreaStart WRITE setSelectionAreaStart NOTIFY selectionAreaStartChanged)
|
||||
Q_PROPERTY(QPointF selectionAreaEnd READ selectionAreaEnd WRITE setSelectionAreaEnd NOTIFY selectionAreaEndChanged)
|
||||
|
||||
public:
|
||||
enum InsertMode {
|
||||
Insert,
|
||||
Replace
|
||||
};
|
||||
|
||||
explicit Screen(QObject *parent = 0);
|
||||
~Screen();
|
||||
|
||||
void setHeight(int height);
|
||||
int height() const;
|
||||
void setWidth(int width);
|
||||
int width() const;
|
||||
|
||||
void saveScreenData();
|
||||
void restoreScreenData();
|
||||
|
||||
void setInsertMode(InsertMode mode);
|
||||
|
||||
void setTextStyle(TextStyle::Style style, bool add = true);
|
||||
void resetStyle();
|
||||
TextStyle currentTextStyle() const;
|
||||
TextStyle defaultTextStyle() const;
|
||||
|
||||
Q_INVOKABLE QColor screenBackground();
|
||||
QColor defaultForgroundColor() const;
|
||||
QColor defaultBackgroundColor() const;
|
||||
|
||||
void setTextStyleColor(ushort color);
|
||||
const ColorPalette *colorPalette() const;
|
||||
|
||||
QPoint cursorPosition() const;
|
||||
|
||||
void moveCursorHome();
|
||||
void moveCursorTop();
|
||||
void moveCursorUp(int n_positions = 1);
|
||||
void moveCursorDown();
|
||||
void moveCursorLeft();
|
||||
void moveCursorRight(int n_positions);
|
||||
void moveCursor(int x, int y);
|
||||
void moveCursorToLine(int line);
|
||||
void moveCursorToCharacter(int character);
|
||||
|
||||
void deleteCharacters(int characters);
|
||||
|
||||
void setCursorVisible(bool visible);
|
||||
bool cursorVisible();
|
||||
void setCursorBlinking(bool blinking);
|
||||
bool cursorBlinking();
|
||||
void saveCursor();
|
||||
void restoreCursor();
|
||||
|
||||
void replaceAtCursor(const QString &text);
|
||||
|
||||
void insertEmptyCharsAtCursor(int len);
|
||||
|
||||
void backspace();
|
||||
|
||||
void eraseLine();
|
||||
void eraseFromCursorPositionToEndOfLine();
|
||||
void eraseFromCursorPosition(int n_chars);
|
||||
void eraseFromCurrentLineToEndOfScreen();
|
||||
void eraseFromCurrentLineToBeginningOfScreen();
|
||||
void eraseToCursorPosition();
|
||||
void eraseScreen();
|
||||
|
||||
void lineFeed();
|
||||
void reverseLineFeed();
|
||||
void insertLines(int count);
|
||||
void deleteLines(int count);
|
||||
|
||||
void setScrollArea(int from, int to);
|
||||
|
||||
QPointF selectionAreaStart() const;
|
||||
void setSelectionAreaStart(const QPointF &start);
|
||||
QPointF selectionAreaEnd() const;
|
||||
void setSelectionAreaEnd(const QPointF &end);
|
||||
|
||||
bool selectionEnabled() const;
|
||||
Q_INVOKABLE void setSelectionEnabled(bool enabled);
|
||||
|
||||
Q_INVOKABLE void sendSelectionToClipboard() const;
|
||||
Q_INVOKABLE void sendSelectionToSelection() const;
|
||||
Q_INVOKABLE void pasteFromSelection();
|
||||
Q_INVOKABLE void pasteFromClipboard();
|
||||
|
||||
Q_INVOKABLE void doubleClicked(const QPointF &clicked);
|
||||
|
||||
void setTitle(const QString &title);
|
||||
QString title() const;
|
||||
|
||||
void scheduleFlash();
|
||||
|
||||
Q_INVOKABLE Line *at(int i) const;
|
||||
|
||||
Q_INVOKABLE void printScreen() const;
|
||||
|
||||
void dispatchChanges();
|
||||
|
||||
void sendPrimaryDA();
|
||||
void sendSecondaryDA();
|
||||
|
||||
void setCharacterMap(const QString &string);
|
||||
QString characterMap() const;
|
||||
void setApplicationCursorKeysMode(bool enable);
|
||||
bool applicationCursorKeyMode() const;
|
||||
|
||||
Q_INVOKABLE void sendKey(const QString &text, Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
YatPty *pty();
|
||||
|
||||
//For tests
|
||||
Line *line_at_cursor() const;
|
||||
public slots:
|
||||
void readData(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void moveLines(int from_line, int to_line, int count);
|
||||
|
||||
void reset();
|
||||
|
||||
void flash();
|
||||
|
||||
void dispatchLineChanges();
|
||||
void dispatchTextSegmentChanges();
|
||||
|
||||
void selectionAreaStartChanged();
|
||||
void selectionAreaEndChanged();
|
||||
void selectionEnabledChanged();
|
||||
|
||||
void screenTitleChanged();
|
||||
|
||||
void cursorPositionChanged(int x, int y);
|
||||
void cursorVisibleChanged();
|
||||
void cursorBlinkingChanged();
|
||||
|
||||
void lineCreated(Line *line);
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
private:
|
||||
void moveLine(qint16 from, qint16 to);
|
||||
void scheduleMoveSignal(qint16 from, qint16 to);
|
||||
|
||||
ScreenData *current_screen_data() const { return m_screen_stack[m_screen_stack.size()-1]; }
|
||||
QPoint ¤t_cursor_pos() { return m_cursor_stack[m_cursor_stack.size()-1]; }
|
||||
int current_cursor_x() const { return m_cursor_stack.at(m_cursor_stack.size()-1).x(); }
|
||||
int current_cursor_y() const { return m_cursor_stack.at(m_cursor_stack.size()-1).y(); }
|
||||
|
||||
void setSelectionValidity();
|
||||
|
||||
ColorPalette m_palette;
|
||||
YatPty m_pty;
|
||||
Parser m_parser;
|
||||
QElapsedTimer m_time_since_parsed;
|
||||
|
||||
int m_timer_event_id;
|
||||
|
||||
QVector<ScreenData *> m_screen_stack;
|
||||
QVector<QPoint> m_cursor_stack;
|
||||
|
||||
bool m_cursor_visible;
|
||||
bool m_cursor_visible_changed;
|
||||
bool m_cursor_blinking;
|
||||
bool m_cursor_blinking_changed;
|
||||
|
||||
TextStyle m_current_text_style;
|
||||
QString m_title;
|
||||
|
||||
InsertMode m_insert_mode;
|
||||
|
||||
bool m_selection_valid;
|
||||
bool m_selection_moved;
|
||||
QPointF m_selection_start;
|
||||
QPointF m_selection_end;
|
||||
|
||||
QString m_character_map;
|
||||
|
||||
QList<UpdateAction> m_update_actions;
|
||||
bool m_flash;
|
||||
bool m_cursor_changed;
|
||||
bool m_reset;
|
||||
bool m_application_cursor_key_mode;
|
||||
|
||||
friend class ScreenData;
|
||||
};
|
||||
|
||||
#endif // TERMINALSCREEN_H
|
317
yat/backend/screen_data.cpp
Normal file
317
yat/backend/screen_data.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "screen_data.h"
|
||||
|
||||
#include "line.h"
|
||||
#include "screen.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
ScreenData::ScreenData(Screen *screen)
|
||||
: m_screen(screen)
|
||||
, m_scroll_start(0)
|
||||
, m_scroll_end(0)
|
||||
, m_scroll_area_set(false)
|
||||
{
|
||||
}
|
||||
|
||||
ScreenData::~ScreenData()
|
||||
{
|
||||
for (int i = 0; i < m_screen_lines.size(); i++) {
|
||||
delete m_screen_lines.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ScreenData::width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
void ScreenData::setWidth(int width)
|
||||
{
|
||||
if (width == m_width)
|
||||
return;
|
||||
|
||||
m_width = width;
|
||||
|
||||
for (int i = 0; i < m_screen_lines.size(); i++) {
|
||||
m_screen_lines.at(i)->setWidth(width);
|
||||
}
|
||||
}
|
||||
|
||||
int ScreenData::height() const
|
||||
{
|
||||
return m_screen_lines.size();
|
||||
}
|
||||
|
||||
void ScreenData::setHeight(int height)
|
||||
{
|
||||
if (height == m_screen_lines.size())
|
||||
return;
|
||||
|
||||
if (m_screen_lines.size() > height) {
|
||||
int removeElements = m_screen_lines.size() - height;
|
||||
for (int i = 0; i < m_screen_lines.size(); i++) {
|
||||
if (i <removeElements) {
|
||||
int not_broadcasted = m_new_lines.indexOf(m_screen_lines.at(i));
|
||||
if (not_broadcasted >= 0)
|
||||
m_new_lines.remove(not_broadcasted);
|
||||
delete m_screen_lines[i];
|
||||
} else {
|
||||
m_screen_lines.at(i)->setIndex(i - removeElements);
|
||||
}
|
||||
}
|
||||
m_screen_lines.remove(0, removeElements);
|
||||
} else if (m_screen_lines.size() < height){
|
||||
int rowsToAdd = height - m_screen_lines.size();
|
||||
for (int i = 0; i < rowsToAdd; i++) {
|
||||
Line *newLine = new Line(m_screen);
|
||||
m_screen_lines.append(newLine);
|
||||
m_new_lines.append(newLine);
|
||||
newLine->setIndex(m_screen_lines.size()-1);
|
||||
}
|
||||
}
|
||||
if (!m_scroll_area_set)
|
||||
m_scroll_end = height - 1;
|
||||
}
|
||||
|
||||
int ScreenData::scrollAreaStart() const
|
||||
{
|
||||
return m_scroll_start;
|
||||
}
|
||||
|
||||
int ScreenData::scrollAreaEnd() const
|
||||
{
|
||||
return m_scroll_end;
|
||||
}
|
||||
|
||||
Line *ScreenData::at(int index) const
|
||||
{
|
||||
return m_screen_lines.at(index);
|
||||
}
|
||||
|
||||
void ScreenData::clearToEndOfLine(int row, int from_char)
|
||||
{
|
||||
m_screen_lines.at(row)->clearToEndOfLine(from_char);
|
||||
}
|
||||
|
||||
void ScreenData::clearToEndOfScreen(int row)
|
||||
{
|
||||
for(int i = row; i < m_screen_lines.size(); i++) {
|
||||
Line *line = m_screen_lines.at(i);
|
||||
line->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::clearToBeginningOfScreen(int row)
|
||||
{
|
||||
for (int i = row; i >= 0; i--) {
|
||||
Line *line = m_screen_lines.at(i);
|
||||
line->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::clearLine(int index)
|
||||
{
|
||||
m_screen_lines.at(index)->clear();
|
||||
}
|
||||
|
||||
void ScreenData::clear()
|
||||
{
|
||||
for (int i = 0; i < m_screen_lines.size(); i++) {
|
||||
Line *line = m_screen_lines.at(i);
|
||||
line->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::clearCharacters(int line, int from, int to)
|
||||
{
|
||||
Line *line_item = m_screen_lines.at(line);
|
||||
line_item->clearCharacters(from,to);
|
||||
}
|
||||
|
||||
void ScreenData::deleteCharacters(int line, int from, int to)
|
||||
{
|
||||
Line *line_item = m_screen_lines.at(line);
|
||||
line_item->deleteCharacters(from,to);
|
||||
}
|
||||
|
||||
void ScreenData::setScrollArea(int from, int to)
|
||||
{
|
||||
m_scroll_area_set = true;
|
||||
m_scroll_start = from;
|
||||
m_scroll_end = to;
|
||||
}
|
||||
|
||||
void ScreenData::moveLine(int from, int to)
|
||||
{
|
||||
if (from == to)
|
||||
return;
|
||||
|
||||
if (from < to) {
|
||||
int lines_to_shift = to - from;
|
||||
Line *from_line = m_screen_lines.at(from);
|
||||
Line **from_line_ptr = m_screen_lines.data() + from;
|
||||
memmove(from_line_ptr, from_line_ptr+1, sizeof(from_line_ptr) * lines_to_shift);
|
||||
from_line->clear();
|
||||
m_screen_lines.replace(to,from_line);
|
||||
} else {
|
||||
int lines_to_shift = from - to;
|
||||
Line *from_line = m_screen_lines.at(from);
|
||||
Line **to_line_ptr = const_cast<Line **>(m_screen_lines.constData() + to);
|
||||
memmove(to_line_ptr + 1, to_line_ptr, sizeof(to_line_ptr) * lines_to_shift);
|
||||
from_line->clear();
|
||||
m_screen_lines.replace(to,from_line);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::updateIndexes(int from, int to)
|
||||
{
|
||||
if (to < 0) {
|
||||
to = m_screen_lines.size() -1;
|
||||
}
|
||||
for (int i = from; i <= to; i++) {
|
||||
m_screen_lines.at(i)->setIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::sendSelectionToClipboard(const QPointF &start, const QPointF &end, QClipboard::Mode clipboard)
|
||||
{
|
||||
QString data;
|
||||
int start_line = qMax((int)start.y(), 0);
|
||||
int end_line = qMin((int)end.y(), m_screen_lines.size()-1);
|
||||
for (int i = start_line; i <= end_line; i++) {
|
||||
int char_start = 0;
|
||||
int char_end = m_width - 1;
|
||||
if (i == start_line)
|
||||
char_start = start.x();
|
||||
else
|
||||
data.append(QChar('\n'));
|
||||
if (i == end_line)
|
||||
char_end = end.x();
|
||||
data += m_screen_lines.at(i)->textLine()->mid(char_start, char_end - char_start).trimmed();
|
||||
}
|
||||
|
||||
QGuiApplication::clipboard()->setText(data, clipboard);
|
||||
}
|
||||
|
||||
void ScreenData::getDoubleClickSelectionArea(const QPointF &cliked, int *start_ret, int *end_ret) const
|
||||
{
|
||||
static const QChar delimiter_list[] = {
|
||||
' ',
|
||||
'<',
|
||||
'>',
|
||||
')',
|
||||
'(',
|
||||
'{',
|
||||
'}',
|
||||
'[',
|
||||
']'
|
||||
};
|
||||
static const int size_of_delimiter_list = sizeof delimiter_list / sizeof *delimiter_list;
|
||||
|
||||
*start_ret = -1;
|
||||
*end_ret = -1;
|
||||
bool find_equals = false;
|
||||
|
||||
QStringRef to_return(m_screen_lines.at(cliked.y())->textLine());
|
||||
|
||||
QChar clicked_char = to_return.at(cliked.x());
|
||||
|
||||
for (int i=0; i<size_of_delimiter_list; i++) {
|
||||
if (clicked_char == delimiter_list[i])
|
||||
find_equals = true;
|
||||
}
|
||||
|
||||
for (int i = cliked.x() - 1; i >= 0; i--) {
|
||||
if (find_equals) {
|
||||
if (clicked_char != to_return.at(i)) {
|
||||
*start_ret = i + 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int delimiter_i = 0; delimiter_i < size_of_delimiter_list; delimiter_i++) {
|
||||
if (to_return.at(i) == delimiter_list[delimiter_i]) {
|
||||
*start_ret = i + 1;
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*start_ret < 0)
|
||||
*start_ret = 0;
|
||||
|
||||
for (int i = cliked.x() + 1; i < to_return.size(); i++) {
|
||||
if (find_equals) {
|
||||
if (clicked_char != to_return.at(i)) {
|
||||
*end_ret = i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int delimiter_i = 0; delimiter_i < size_of_delimiter_list; delimiter_i++) {
|
||||
if (to_return.at(i) == delimiter_list[delimiter_i]) {
|
||||
*end_ret = i;
|
||||
i = to_return.size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*end_ret < 0)
|
||||
*end_ret = to_return.size();
|
||||
|
||||
}
|
||||
|
||||
void ScreenData::dispatchLineEvents()
|
||||
{
|
||||
for (int i = 0; i < m_new_lines.size(); i++) {
|
||||
emit m_screen->lineCreated(m_new_lines.at(i));
|
||||
}
|
||||
m_new_lines.clear();
|
||||
|
||||
for (int i = 0; i < m_screen_lines.size(); i++) {
|
||||
m_screen_lines.at(i)->dispatchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::printScreen() const
|
||||
{
|
||||
for (int line = 0; line < m_screen_lines.size(); line++) {
|
||||
// for (int i = 0; i < m_screen_lines.at(line)->size(); i++) {
|
||||
// fprintf(stderr, "%s", qPrintable(m_screen_lines.at(line)->at(i)->text()));
|
||||
// }
|
||||
// fprintf(stderr, "\n");
|
||||
fprintf(stderr, "%s\n", qPrintable(*m_screen_lines.at(line)->textLine()));
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenData::printStyleInformation() const
|
||||
{
|
||||
for (int line_number = 0; line_number < m_screen_lines.size(); line_number++) {
|
||||
const Line *line = m_screen_lines.at(line_number);
|
||||
line->printStyleList();
|
||||
}
|
||||
}
|
81
yat/backend/screen_data.h
Normal file
81
yat/backend/screen_data.h
Normal file
@ -0,0 +1,81 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef SCREENDATA_H
|
||||
#define SCREENDATA_H
|
||||
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QPoint>
|
||||
#include <QtGui/QClipboard>
|
||||
|
||||
class Line;
|
||||
class Screen;
|
||||
|
||||
class ScreenData
|
||||
{
|
||||
public:
|
||||
ScreenData(Screen *screen);
|
||||
~ScreenData();
|
||||
|
||||
int width() const;
|
||||
void setWidth(int width);
|
||||
int height() const;
|
||||
void setHeight(int height);
|
||||
|
||||
int scrollAreaStart() const;
|
||||
int scrollAreaEnd() const;
|
||||
|
||||
Line *at(int index) const;
|
||||
|
||||
void clearToEndOfLine(int row, int from_char);
|
||||
void clearToEndOfScreen(int row);
|
||||
void clearToBeginningOfScreen(int row);
|
||||
void clearLine(int index);
|
||||
void clear();
|
||||
|
||||
void clearCharacters(int line, int from, int to);
|
||||
void deleteCharacters(int line, int from, int to);
|
||||
|
||||
void setScrollArea(int from, int to);
|
||||
|
||||
void moveLine(int from, int to);
|
||||
|
||||
void updateIndexes(int from = 0, int to = -1);
|
||||
|
||||
void sendSelectionToClipboard(const QPointF &start, const QPointF &end, QClipboard::Mode clipboard);
|
||||
|
||||
void getDoubleClickSelectionArea(const QPointF &cliked, int *start_ret, int *end_ret) const;
|
||||
|
||||
void dispatchLineEvents();
|
||||
|
||||
void printScreen() const;
|
||||
|
||||
void printStyleInformation() const;
|
||||
private:
|
||||
Screen *m_screen;
|
||||
int m_width;
|
||||
QVector<Line *> m_screen_lines;
|
||||
QVector<Line *> m_new_lines;
|
||||
int m_scroll_start;
|
||||
int m_scroll_end;
|
||||
bool m_scroll_area_set;
|
||||
};
|
||||
|
||||
#endif // SCREENDATA_H
|
147
yat/backend/text.cpp
Normal file
147
yat/backend/text.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "text.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "line.h"
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
Text::Text(Screen *screen)
|
||||
: QObject(screen)
|
||||
, m_style_dirty(true)
|
||||
, m_text_dirty(true)
|
||||
, m_visible(true)
|
||||
, m_visible_old(true)
|
||||
, m_line(0)
|
||||
{
|
||||
}
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
emit aboutToBeDestroyed();
|
||||
}
|
||||
|
||||
void Text::setLine(Line *line)
|
||||
{
|
||||
if (line == m_line)
|
||||
return;
|
||||
m_line = line;
|
||||
if (m_line) {
|
||||
m_text_line = line->textLine();
|
||||
}
|
||||
}
|
||||
|
||||
int Text::index() const
|
||||
{
|
||||
return m_start_index;
|
||||
}
|
||||
|
||||
bool Text::visible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
void Text::setVisible(bool visible)
|
||||
{
|
||||
m_visible = visible;
|
||||
}
|
||||
|
||||
QString Text::text() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
QColor Text::foregroundColor() const
|
||||
{
|
||||
if (m_style.style & TextStyle::Inverse) {
|
||||
if (m_style.background == ColorPalette::DefaultBackground)
|
||||
return screen()->screenBackground();
|
||||
return screen()->colorPalette()->color(m_style.background, m_style.style & TextStyle::Bold);
|
||||
}
|
||||
|
||||
return screen()->colorPalette()->color(m_style.forground, m_style.style & TextStyle::Bold);
|
||||
}
|
||||
|
||||
|
||||
QColor Text::backgroundColor() const
|
||||
{
|
||||
if (m_style.style & TextStyle::Inverse)
|
||||
return screen()->colorPalette()->color(m_style.forground, false);
|
||||
|
||||
return screen()->colorPalette()->color(m_style.background, false);
|
||||
}
|
||||
|
||||
void Text::setStringSegment(int start_index, int end_index, bool text_changed)
|
||||
{
|
||||
m_start_index = start_index;
|
||||
m_end_index = end_index;
|
||||
|
||||
m_text_dirty = text_changed;
|
||||
}
|
||||
|
||||
void Text::setTextStyle(const TextStyle &style)
|
||||
{
|
||||
m_new_style = style;
|
||||
m_style_dirty = true;
|
||||
}
|
||||
|
||||
Screen *Text::screen() const
|
||||
{
|
||||
return m_line->screen();
|
||||
}
|
||||
|
||||
void Text::dispatchEvents()
|
||||
{
|
||||
if (m_style_dirty) {
|
||||
m_style_dirty = false;
|
||||
|
||||
bool emit_forground = m_new_style.forground != m_style.forground;
|
||||
bool emit_background = m_new_style.background != m_style.background;
|
||||
bool emit_text_style = m_new_style.style != m_style.style;
|
||||
|
||||
m_style = m_new_style;
|
||||
if (emit_forground)
|
||||
emit forgroundColorChanged();
|
||||
if (emit_background)
|
||||
emit backgroundColorChanged();
|
||||
if (emit_text_style)
|
||||
emit textStyleChanged();
|
||||
}
|
||||
|
||||
if (m_old_start_index != m_start_index
|
||||
|| m_text_dirty) {
|
||||
m_text_dirty = false;
|
||||
m_text = m_text_line->mid(m_start_index, m_end_index + 1 - m_start_index);
|
||||
if (m_old_start_index != m_start_index) {
|
||||
m_old_start_index = m_start_index;
|
||||
emit indexChanged();
|
||||
}
|
||||
emit textChanged();
|
||||
}
|
||||
|
||||
if (m_visible_old != m_visible) {
|
||||
m_visible_old = m_visible;
|
||||
emit visibleChanged();
|
||||
}
|
||||
}
|
||||
|
96
yat/backend/text.h
Normal file
96
yat/backend/text.h
Normal file
@ -0,0 +1,96 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef TEXT_SEGMENT_H
|
||||
#define TEXT_SEGMENT_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QColor>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QSize>
|
||||
|
||||
#include "text_style.h"
|
||||
|
||||
class Screen;
|
||||
class Line;
|
||||
class QQuickItem;
|
||||
|
||||
class Text : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int index READ index NOTIFY indexChanged)
|
||||
Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
|
||||
Q_PROPERTY(QString text READ text NOTIFY textChanged)
|
||||
Q_PROPERTY(QColor foregroundColor READ foregroundColor NOTIFY forgroundColorChanged)
|
||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundColorChanged)
|
||||
Q_PROPERTY(Screen *screen READ screen CONSTANT)
|
||||
public:
|
||||
Text(Screen *screen);
|
||||
~Text();
|
||||
|
||||
void setLine(Line *line);
|
||||
|
||||
int index() const;
|
||||
|
||||
bool visible() const;
|
||||
void setVisible(bool visible);
|
||||
|
||||
QString text() const;
|
||||
QColor foregroundColor() const;
|
||||
QColor backgroundColor() const;
|
||||
|
||||
void setStringSegment(int start_index, int end_index, bool textChanged);
|
||||
void setTextStyle(const TextStyle &style);
|
||||
|
||||
Screen *screen() const;
|
||||
|
||||
QObject *item() const;
|
||||
|
||||
public slots:
|
||||
void dispatchEvents();
|
||||
|
||||
signals:
|
||||
void indexChanged();
|
||||
void visibleChanged();
|
||||
void textChanged();
|
||||
void forgroundColorChanged();
|
||||
void backgroundColorChanged();
|
||||
void textStyleChanged();
|
||||
|
||||
void aboutToBeDestroyed();
|
||||
private:
|
||||
|
||||
QString m_text;
|
||||
QString *m_text_line;
|
||||
int m_start_index;
|
||||
int m_old_start_index;
|
||||
int m_end_index;
|
||||
TextStyle m_style;
|
||||
TextStyle m_new_style;
|
||||
|
||||
bool m_style_dirty;
|
||||
bool m_text_dirty;
|
||||
bool m_visible;
|
||||
bool m_visible_old;
|
||||
|
||||
Line *m_line;
|
||||
};
|
||||
|
||||
#endif // TEXT_SEGMENT_H
|
17
yat/backend/text_style.cpp
Normal file
17
yat/backend/text_style.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "text_style.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
TextStyle::TextStyle()
|
||||
: style(Normal)
|
||||
, forground(ColorPalette::DefaultForground)
|
||||
, background(ColorPalette::DefaultBackground)
|
||||
{
|
||||
|
||||
}
|
||||
bool TextStyle::isCompatible(const TextStyle &other) const
|
||||
{
|
||||
return forground == other.forground
|
||||
&& background == other.background
|
||||
&& style == other.style;
|
||||
}
|
37
yat/backend/text_style.h
Normal file
37
yat/backend/text_style.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef TEXT_STYLE_H
|
||||
#define TEXT_STYLE_H
|
||||
|
||||
#include <QtGui/QColor>
|
||||
|
||||
#include "color_palette.h"
|
||||
class Screen;
|
||||
|
||||
class TextStyle
|
||||
{
|
||||
public:
|
||||
enum Style {
|
||||
Normal = 0x0000,
|
||||
Italic = 0x0001,
|
||||
Bold = 0x0002,
|
||||
Underlined = 0x0004,
|
||||
Blinking = 0x0008,
|
||||
FastBlinking = 0x0010,
|
||||
Gothic = 0x0020,
|
||||
DoubleUnderlined = 0x0040,
|
||||
Framed = 0x0080,
|
||||
Overlined = 0x0100,
|
||||
Encircled = 0x0200,
|
||||
Inverse = 0x0400
|
||||
};
|
||||
Q_DECLARE_FLAGS(Styles, Style)
|
||||
|
||||
TextStyle();
|
||||
|
||||
Styles style;
|
||||
ColorPalette::Color forground;
|
||||
ColorPalette::Color background;
|
||||
|
||||
bool isCompatible(const TextStyle &other) const;
|
||||
};
|
||||
|
||||
#endif // TEXT_STYLE_H
|
21
yat/backend/update_action.cpp
Normal file
21
yat/backend/update_action.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "update_action.h"
|
54
yat/backend/update_action.h
Normal file
54
yat/backend/update_action.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef UPDATE_ACTION_H
|
||||
#define UPDATE_ACTION_H
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
class UpdateAction
|
||||
{
|
||||
public:
|
||||
enum Action {
|
||||
InvalidAction,
|
||||
MoveLine
|
||||
};
|
||||
|
||||
UpdateAction(Action action, qint16 from_line, qint16 to_line, qint16 count)
|
||||
: action(action)
|
||||
, from_line(from_line)
|
||||
, to_line(to_line)
|
||||
, count(count)
|
||||
{ }
|
||||
|
||||
UpdateAction(Action action, int count)
|
||||
: action(action)
|
||||
, from_line(0)
|
||||
, to_line(0)
|
||||
, count(count)
|
||||
{ }
|
||||
|
||||
Action action;
|
||||
qint16 from_line;
|
||||
qint16 to_line;
|
||||
qint16 count;
|
||||
};
|
||||
|
||||
#endif // UPDATE_ACTION_H
|
139
yat/backend/yat_pty.cpp
Normal file
139
yat/backend/yat_pty.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "yat_pty.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef LINUX
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef Q_OS_MAC
|
||||
#include <util.h>
|
||||
#else
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
|
||||
#include <QtCore/QSize>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
static char env_variables[][255] = {
|
||||
"TERM=xterm",
|
||||
"COLORTERM=xterm",
|
||||
"COLORFGBG=15;0",
|
||||
"LINES",
|
||||
"COLUMNS",
|
||||
"TERMCAP"
|
||||
};
|
||||
static int env_variables_size = sizeof(env_variables) / sizeof(env_variables[0]);
|
||||
|
||||
YatPty::YatPty()
|
||||
: m_winsize(0)
|
||||
{
|
||||
m_terminal_pid = forkpty(&m_master_fd,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (m_terminal_pid == 0) {
|
||||
for (int i = 0; i < env_variables_size; i++) {
|
||||
::putenv(env_variables[i]);
|
||||
}
|
||||
::execl("/bin/bash", "/bin/bash", "--login", (const char *) 0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
QSocketNotifier *reader = new QSocketNotifier(m_master_fd,QSocketNotifier::Read,this);
|
||||
connect(reader, &QSocketNotifier::activated, this, &YatPty::readData);
|
||||
}
|
||||
|
||||
YatPty::~YatPty()
|
||||
{
|
||||
}
|
||||
|
||||
void YatPty::write(const QByteArray &data)
|
||||
{
|
||||
if (::write(m_master_fd, data.constData(), data.size()) < 0) {
|
||||
qDebug() << "Something whent wrong when writing to m_master_fd";
|
||||
}
|
||||
}
|
||||
|
||||
void YatPty::setWidth(int width, int pixelWidth)
|
||||
{
|
||||
if (!m_winsize) {
|
||||
m_winsize = new struct winsize;
|
||||
m_winsize->ws_row = 25;
|
||||
m_winsize->ws_ypixel = 0;
|
||||
}
|
||||
|
||||
m_winsize->ws_col = width;
|
||||
m_winsize->ws_xpixel = pixelWidth;
|
||||
ioctl(m_master_fd, TIOCSWINSZ, m_winsize);
|
||||
}
|
||||
|
||||
void YatPty::setHeight(int height, int pixelHeight)
|
||||
{
|
||||
if (!m_winsize) {
|
||||
m_winsize = new struct winsize;
|
||||
m_winsize->ws_col = 80;
|
||||
m_winsize->ws_xpixel = 0;
|
||||
}
|
||||
m_winsize->ws_row = height;
|
||||
m_winsize->ws_ypixel = pixelHeight;
|
||||
ioctl(m_master_fd, TIOCSWINSZ, m_winsize);
|
||||
|
||||
}
|
||||
|
||||
QSize YatPty::size() const
|
||||
{
|
||||
if (!m_winsize) {
|
||||
YatPty *that = const_cast<YatPty *>(this);
|
||||
that->m_winsize = new struct winsize;
|
||||
ioctl(m_master_fd, TIOCGWINSZ, m_winsize);
|
||||
}
|
||||
return QSize(m_winsize->ws_col, m_winsize->ws_row);
|
||||
}
|
||||
|
||||
int YatPty::masterDevice() const
|
||||
{
|
||||
return m_master_fd;
|
||||
}
|
||||
|
||||
|
||||
void YatPty::readData()
|
||||
{
|
||||
int size_of_buffer = sizeof m_data_buffer / sizeof *m_data_buffer;
|
||||
ssize_t read_size = ::read(m_master_fd,m_data_buffer,size_of_buffer);
|
||||
if (read_size > 0) {
|
||||
QByteArray to_return = QByteArray::fromRawData(m_data_buffer,read_size);
|
||||
emit readyRead(to_return);
|
||||
} else if (read_size < 0) {
|
||||
emit hangupReceived();
|
||||
} else {
|
||||
emit hangupReceived();
|
||||
}
|
||||
}
|
59
yat/backend/yat_pty.h
Normal file
59
yat/backend/yat_pty.h
Normal file
@ -0,0 +1,59 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef YAT_PTY_H
|
||||
#define YAT_PTY_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QLinkedList>
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
class YatPty : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YatPty();
|
||||
~YatPty();
|
||||
|
||||
void write(const QByteArray &data);
|
||||
|
||||
void setWidth(int width, int pixelWidth = 0);
|
||||
void setHeight(int height, int pixelHeight = 0);
|
||||
QSize size() const;
|
||||
|
||||
int masterDevice() const;
|
||||
|
||||
signals:
|
||||
void hangupReceived();
|
||||
void readyRead(const QByteArray &data);
|
||||
|
||||
private:
|
||||
void readData();
|
||||
|
||||
pid_t m_terminal_pid;
|
||||
int m_master_fd;
|
||||
char m_slave_file_name[PATH_MAX];
|
||||
struct winsize *m_winsize;
|
||||
char m_data_buffer[4096];
|
||||
};
|
||||
|
||||
#endif //YAT_PTY_H
|
BIN
yat/docs/Ecma-048.pdf
Normal file
BIN
yat/docs/Ecma-048.pdf
Normal file
Binary file not shown.
4841
yat/docs/Xterm Control Sequences.html
Normal file
4841
yat/docs/Xterm Control Sequences.html
Normal file
File diff suppressed because it is too large
Load Diff
3
yat/tests/auto/auto.pro
Normal file
3
yat/tests/auto/auto.pro
Normal file
@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
line
|
8
yat/tests/auto/line/line.pro
Normal file
8
yat/tests/auto/line/line.pro
Normal file
@ -0,0 +1,8 @@
|
||||
CONFIG += testcase
|
||||
QT += testlib quick
|
||||
|
||||
include(../../../backend/backend.pri)
|
||||
|
||||
SOURCES += \
|
||||
tst_line.cpp \
|
||||
|
724
yat/tests/auto/line/tst_line.cpp
Normal file
724
yat/tests/auto/line/tst_line.cpp
Normal file
@ -0,0 +1,724 @@
|
||||
#include "../../../backend/line.h"
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <QtQml/QQmlEngine>
|
||||
#include "../../../backend/screen.h"
|
||||
|
||||
class LineHandler
|
||||
{
|
||||
public:
|
||||
LineHandler() {
|
||||
screen.setHeight(50);
|
||||
screen.setWidth(100);
|
||||
screen.line_at_cursor()->clear();
|
||||
QCOMPARE(line()->style_list().size(), 1);
|
||||
default_style = line()->style_list().at(0);
|
||||
default_text_style = default_style.style;
|
||||
}
|
||||
|
||||
Line *line() const
|
||||
{
|
||||
return screen.line_at_cursor();
|
||||
}
|
||||
|
||||
TextStyle default_style;
|
||||
TextStyle::Styles default_text_style;
|
||||
Screen screen;
|
||||
};
|
||||
|
||||
class tst_Line: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void replaceStart();
|
||||
void replaceEdgeOfStyle();
|
||||
void replaceCompatibleStyle();
|
||||
void replaceIncompatibleStyle();
|
||||
void replaceIncompaitibleStylesCrossesBoundary();
|
||||
void replace3IncompatibleStyles();
|
||||
void replaceIncomaptibleStylesCrosses2Boundaries();
|
||||
void replaceSwapStyles();
|
||||
void replaceEndLine();
|
||||
void clearLine();
|
||||
void clearToEndOfLine1Segment();
|
||||
void clearToEndOfLine3Segment();
|
||||
void clearToEndOfLineMiddle3Segment();
|
||||
void deleteCharacters1Segment();
|
||||
void deleteCharacters2Segments();
|
||||
void deleteCharacters3Segments();
|
||||
void deleteCharactersRemoveSegmentEnd();
|
||||
void deleteCharactersRemoveSegmentBeginning();
|
||||
void insertCharacters();
|
||||
void insertCharacters2Segments();
|
||||
void insertCharacters3Segments();
|
||||
};
|
||||
|
||||
void tst_Line::replaceStart()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QVector<TextStyleLine> old_style_list = line->style_list();
|
||||
QCOMPARE(old_style_list.size(), 1);
|
||||
|
||||
QString replace_text("This is a test");
|
||||
TextStyle textStyle;
|
||||
textStyle.style = TextStyle::Overlined;
|
||||
line->replaceAtPos(0,replace_text, textStyle);
|
||||
|
||||
QVector<TextStyleLine> new_style_list = line->style_list();
|
||||
TextStyleLine first_style = new_style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, replace_text.size() - 1);
|
||||
QCOMPARE(new_style_list.size(), 2);
|
||||
|
||||
}
|
||||
|
||||
void tst_Line::replaceEdgeOfStyle()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString first_text("This is the First");
|
||||
TextStyle textStyle;
|
||||
textStyle.style = TextStyle::Overlined;
|
||||
line->replaceAtPos(0,first_text, textStyle);
|
||||
|
||||
QString second_text("This is the Second");
|
||||
textStyle.style = TextStyle::Bold;
|
||||
line->replaceAtPos(first_text.size(), second_text, textStyle);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
|
||||
QCOMPARE(style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.style, TextStyle::Overlined);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, first_text.size() - 1);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.style, TextStyle::Bold);
|
||||
QCOMPARE(second_style.start_index, first_text.size());
|
||||
QCOMPARE(second_style.end_index, first_text.size()+ second_text.size() - 1);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.style, TextStyle::Normal);
|
||||
QCOMPARE(third_style.start_index, first_text.size()+ second_text.size());
|
||||
}
|
||||
|
||||
void tst_Line::replaceCompatibleStyle()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceed Text");
|
||||
line->replaceAtPos(10, replace_text, lineHandler.default_style);
|
||||
|
||||
QVector<TextStyleLine> after_style_list = line->style_list();
|
||||
QCOMPARE(after_style_list.size(), 1);
|
||||
QCOMPARE(after_style_list.at(0).style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::replaceIncompatibleStyle()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
|
||||
QString replace_text("replaceed Text");
|
||||
TextStyle replace_style;
|
||||
replace_style.style = TextStyle::Blinking;
|
||||
line->replaceAtPos(10, replace_text, replace_style);
|
||||
|
||||
QVector<TextStyleLine> after_style_list = line->style_list();
|
||||
QCOMPARE(after_style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = after_style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 9);
|
||||
QCOMPARE(first_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &second_style = after_style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 10);
|
||||
QCOMPARE(second_style.end_index, 10 + replace_text.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Blinking);
|
||||
|
||||
const TextStyleLine &third_style = after_style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, 10 + replace_text.size());
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::replaceIncompaitibleStylesCrossesBoundary()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceed Text");
|
||||
TextStyle replace_style;
|
||||
replace_style.style = TextStyle::Blinking;
|
||||
line->replaceAtPos(0, replace_text, replace_style);
|
||||
|
||||
QString crosses_boundary("New incompatible text");
|
||||
replace_style.style = TextStyle::Framed;
|
||||
int replace_pos = replace_text.size()/2;
|
||||
line->replaceAtPos(replace_pos, crosses_boundary, replace_style);
|
||||
|
||||
QVector<TextStyleLine> after_style_list = line->style_list();
|
||||
QCOMPARE(after_style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = after_style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, replace_pos -1);
|
||||
QCOMPARE(first_style.style, TextStyle::Blinking);
|
||||
|
||||
const TextStyleLine &second_style = after_style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, replace_pos);
|
||||
QCOMPARE(second_style.end_index, replace_pos + crosses_boundary.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Framed);
|
||||
|
||||
const TextStyleLine &third_style = after_style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, replace_pos + crosses_boundary.size());
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::replace3IncompatibleStyles()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString first_text("First Text");
|
||||
TextStyle replace_style;
|
||||
replace_style.style = TextStyle::Blinking;
|
||||
line->replaceAtPos(0, first_text, replace_style);
|
||||
|
||||
QString second_text("Second Text");
|
||||
replace_style.style = TextStyle::Italic;
|
||||
line->replaceAtPos(first_text.size(), second_text, replace_style);
|
||||
|
||||
QString third_text("Third Text");
|
||||
replace_style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style);
|
||||
|
||||
QCOMPARE(line->style_list().size(), 4);
|
||||
|
||||
QVector<TextStyleLine> after_style_list = line->style_list();
|
||||
|
||||
const TextStyleLine &first_style = after_style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, first_text.size() -1);
|
||||
|
||||
const TextStyleLine &second_style = after_style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, first_text.size());
|
||||
QCOMPARE(second_style.end_index, first_text.size() + second_text.size() - 1);
|
||||
QCOMPARE(second_style.style, TextStyle::Italic);
|
||||
|
||||
const TextStyleLine &third_style = after_style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, first_text.size() + second_text.size());
|
||||
QCOMPARE(third_style.end_index, first_text.size() + second_text.size() + third_text.size() - 1);
|
||||
QCOMPARE(third_style.style, TextStyle::Encircled);
|
||||
|
||||
const TextStyleLine &fourth_style = after_style_list.at(3);
|
||||
QCOMPARE(fourth_style.start_index, first_text.size() + second_text.size() + third_text.size());
|
||||
}
|
||||
void tst_Line::replaceIncomaptibleStylesCrosses2Boundaries()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString first_text("First Text");
|
||||
TextStyle replace_style;
|
||||
replace_style.style = TextStyle::Blinking;
|
||||
line->replaceAtPos(0, first_text, replace_style);
|
||||
|
||||
QString second_text("Second Text");
|
||||
replace_style.style = TextStyle::Italic;
|
||||
line->replaceAtPos(first_text.size(), second_text, replace_style);
|
||||
|
||||
QString third_text("Third Text");
|
||||
replace_style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style);
|
||||
|
||||
QCOMPARE(line->style_list().size(), 4);
|
||||
|
||||
QVector<TextStyleLine> before_style_list = line->style_list();
|
||||
|
||||
QString overlap_first_third;
|
||||
overlap_first_third.fill(QChar('A'), second_text.size() + 4);
|
||||
replace_style.style = TextStyle::DoubleUnderlined;
|
||||
line->replaceAtPos(first_text.size() -2, overlap_first_third, replace_style);
|
||||
|
||||
QVector<TextStyleLine> after_style_list = line->style_list();
|
||||
QCOMPARE(line->style_list().size(), 4);
|
||||
|
||||
const TextStyleLine &first_style = after_style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, first_text.size() - 3);
|
||||
QCOMPARE(first_style.style, TextStyle::Blinking);
|
||||
|
||||
const TextStyleLine &second_style = after_style_list.at(1);
|
||||
QCOMPARE(second_style.style, TextStyle::DoubleUnderlined);
|
||||
QCOMPARE(second_style.start_index, first_text.size() - 2);
|
||||
QCOMPARE(second_style.end_index, first_text.size() - 2 + overlap_first_third.size() -1);
|
||||
|
||||
const TextStyleLine &third_style = after_style_list.at(2);
|
||||
QCOMPARE(third_style.style, TextStyle::Encircled);
|
||||
QCOMPARE(third_style.start_index, first_text.size() - 2 + overlap_first_third.size());
|
||||
QCOMPARE(third_style.end_index, first_text.size() - 2 + overlap_first_third.size() + third_text.size() - 1 - 2);
|
||||
|
||||
const TextStyleLine &fourth_style = after_style_list.at(3);
|
||||
QCOMPARE(fourth_style.style, lineHandler.default_text_style);
|
||||
QCOMPARE(fourth_style.start_index, first_text.size() - 2 + overlap_first_third.size() + third_text.size() - 2);
|
||||
}
|
||||
|
||||
void tst_Line::replaceSwapStyles()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString first_text("First Text");
|
||||
TextStyle replace_style;
|
||||
replace_style.style = TextStyle::Blinking;
|
||||
line->replaceAtPos(0, first_text, replace_style);
|
||||
|
||||
QString second_text("Second Text");
|
||||
replace_style.style = TextStyle::Italic;
|
||||
line->replaceAtPos(first_text.size(), second_text, replace_style);
|
||||
|
||||
QString third_text("Third Text");
|
||||
replace_style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style);
|
||||
|
||||
QString replace_second("Dnoces Text");
|
||||
replace_style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(first_text.size(), replace_second, replace_style);
|
||||
|
||||
QCOMPARE(line->style_list().size(), 4);
|
||||
}
|
||||
|
||||
void tst_Line::replaceEndLine()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
QString replace_text("at the end of the string");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(line_size - replace_text.size(), replace_text, style);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, line_size - replace_text.size() -1);
|
||||
QCOMPARE(first_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, line_size - replace_text.size());
|
||||
QCOMPARE(second_style.end_index, line_size - 1);
|
||||
QCOMPARE(second_style.style, TextStyle::Bold);
|
||||
}
|
||||
|
||||
void tst_Line::clearLine()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QVERIFY(line->textLine()->size() > 0);
|
||||
QCOMPARE(line->textLine()->trimmed().size(), 0);
|
||||
}
|
||||
|
||||
void tst_Line::clearToEndOfLine1Segment()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("To be replaceed");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
int before_clear_size = line->textLine()->size();
|
||||
line->clearToEndOfLine(5);
|
||||
|
||||
int after_clear_size = line->textLine()->size();
|
||||
QCOMPARE(after_clear_size, before_clear_size);
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 4);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 5);
|
||||
|
||||
QString cleared("To be");
|
||||
QCOMPARE(line->textLine()->trimmed(), cleared);
|
||||
}
|
||||
|
||||
void tst_Line::clearToEndOfLine3Segment()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("To be");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString replace_text2(" or not to be");
|
||||
style.style = TextStyle::Bold;
|
||||
line ->replaceAtPos(replace_text.size(), replace_text2, style);
|
||||
|
||||
line->clearToEndOfLine(replace_text.size());
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, replace_text.size() - 1);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, replace_text.size());
|
||||
QCOMPARE(second_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::clearToEndOfLineMiddle3Segment()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("To be");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString replace_text2(" or not to be");
|
||||
style.style = TextStyle::Bold;
|
||||
line ->replaceAtPos(replace_text.size(), replace_text2, style);
|
||||
|
||||
line->clearToEndOfLine(replace_text.size() + 3);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, replace_text.size() - 1);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, replace_text.size());
|
||||
QCOMPARE(second_style.end_index, replace_text.size() + 2);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, replace_text.size() + 3);
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::deleteCharacters1Segment()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceing some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
line->deleteCharacters(10,14);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 14);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 15);
|
||||
QCOMPARE(second_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::deleteCharacters2Segments()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceing some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
line->deleteCharacters(15,25);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 14);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 15);
|
||||
QCOMPARE(second_style.style, lineHandler.default_text_style);
|
||||
|
||||
}
|
||||
|
||||
void tst_Line::deleteCharacters3Segments()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceing some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString replace_more_text("Some more text");
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(replace_text.size(), replace_more_text, style);
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
line->deleteCharacters(10,15);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 13);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 14);
|
||||
QCOMPARE(second_style.end_index, 14 + replace_more_text.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Bold);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, 14 + replace_more_text.size());
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::deleteCharactersRemoveSegmentEnd()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceing some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString replace_more_text("Some more text");
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(replace_text.size(), replace_more_text, style);
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
line->deleteCharacters(16,33);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 15);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 16);
|
||||
QCOMPARE(second_style.style, lineHandler.default_text_style);
|
||||
|
||||
}
|
||||
|
||||
void tst_Line::deleteCharactersRemoveSegmentBeginning()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString replace_text("replaceing some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(0, replace_text, style);
|
||||
|
||||
QString replace_more_text("Some more text");
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(replace_text.size(), replace_more_text, style);
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
line->deleteCharacters(replace_text.size(),replace_text.size() + replace_more_text.size() + 3);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 2);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, replace_text.size() - 1);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, replace_text.size());
|
||||
QCOMPARE(second_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::insertCharacters()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
QString insert_text("inserting some text");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Encircled;
|
||||
line->insertAtPos(5, insert_text, style);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 3);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 4);
|
||||
QCOMPARE(first_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 5);
|
||||
QCOMPARE(second_style.end_index, 5 + insert_text.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Encircled);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, 5 + insert_text.size());
|
||||
QCOMPARE(third_style.end_index, line_size - 1);
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
void tst_Line::insertCharacters2Segments()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
QString replace_text("at the end of the string");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(line_size - replace_text.size(), replace_text, style);
|
||||
|
||||
QString insert_text("inserting some text");
|
||||
style.style = TextStyle::Encircled;
|
||||
line->insertAtPos(5, insert_text, style);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 4);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 4);
|
||||
QCOMPARE(first_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 5);
|
||||
QCOMPARE(second_style.end_index, 5 + insert_text.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Encircled);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, 5 + insert_text.size());
|
||||
QCOMPARE(third_style.end_index, line_size -1 - replace_text.size() + insert_text.size());
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &fourth_style = style_list.at(3);
|
||||
QCOMPARE(fourth_style.start_index, line_size - replace_text.size() + insert_text.size());
|
||||
QCOMPARE(fourth_style.end_index, line_size -1 );
|
||||
QCOMPARE(fourth_style.style, TextStyle::Bold);
|
||||
}
|
||||
|
||||
void tst_Line::insertCharacters3Segments()
|
||||
{
|
||||
LineHandler lineHandler;
|
||||
Line *line = lineHandler.line();
|
||||
|
||||
QString *full_line = line->textLine();
|
||||
int line_size = full_line->size();
|
||||
|
||||
QString replace_text("at the end of the string");
|
||||
TextStyle style = lineHandler.default_style;
|
||||
style.style = TextStyle::Bold;
|
||||
line->replaceAtPos(line_size - replace_text.size(), replace_text, style);
|
||||
|
||||
QString replace_text2("somewhere in the string");
|
||||
style.style = TextStyle::Encircled;
|
||||
line->replaceAtPos(20,replace_text2, style);
|
||||
|
||||
QVector<TextStyleLine> tmp_style_list = line->style_list();
|
||||
QCOMPARE(tmp_style_list.size(), 4);
|
||||
|
||||
QString insert_text("this text is longer than last segment");
|
||||
style.style = TextStyle::Italic;
|
||||
line->insertAtPos(10, insert_text, style);
|
||||
|
||||
QCOMPARE(line->textLine()->size(), line_size);
|
||||
|
||||
QVector<TextStyleLine> style_list = line->style_list();
|
||||
QCOMPARE(style_list.size(), 5);
|
||||
|
||||
const TextStyleLine &first_style = style_list.at(0);
|
||||
QCOMPARE(first_style.start_index, 0);
|
||||
QCOMPARE(first_style.end_index, 9);
|
||||
QCOMPARE(first_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &second_style = style_list.at(1);
|
||||
QCOMPARE(second_style.start_index, 10);
|
||||
QCOMPARE(second_style.end_index, 10 + insert_text.size() -1);
|
||||
QCOMPARE(second_style.style, TextStyle::Italic);
|
||||
|
||||
const TextStyleLine &third_style = style_list.at(2);
|
||||
QCOMPARE(third_style.start_index, 10 + insert_text.size());
|
||||
QCOMPARE(third_style.end_index, 20 + insert_text.size() - 1);
|
||||
QCOMPARE(third_style.style, lineHandler.default_text_style);
|
||||
|
||||
const TextStyleLine &fourth_style = style_list.at(3);
|
||||
QCOMPARE(fourth_style.start_index, 20 + insert_text.size());
|
||||
QCOMPARE(fourth_style.end_index, 20 + insert_text.size() + replace_text2.size() - 1);
|
||||
QCOMPARE(fourth_style.style, TextStyle::Encircled);
|
||||
|
||||
const TextStyleLine &fith_style = style_list.at(4);
|
||||
QCOMPARE(fith_style.start_index, 20 + insert_text.size() + replace_text2.size());
|
||||
QCOMPARE(fith_style.end_index, line_size - 1);
|
||||
QCOMPARE(fith_style.style, lineHandler.default_text_style);
|
||||
}
|
||||
|
||||
#include <tst_line.moc>
|
||||
QTEST_MAIN(tst_Line);
|
3
yat/tests/tests.pro
Normal file
3
yat/tests/tests.pro
Normal file
@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
auto
|
5
yat/yat.pro
Normal file
5
yat/yat.pro
Normal file
@ -0,0 +1,5 @@
|
||||
TEMPLATE=subdirs
|
||||
CONFIG += ordered
|
||||
SUBDIRS= \
|
||||
yat_declarative \
|
||||
tests
|
43
yat/yat_declarative/main.cpp
Normal file
43
yat/yat_declarative/main.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtCore/QResource>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <QtQuick/QQuickView>
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#include "register_qml_types.h"
|
||||
#include "terminal_screen.h"
|
||||
#include "yat_pty.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
register_qml_types();
|
||||
|
||||
QQuickView view(QUrl("qrc:/qml/yat_declarative/main.qml"));
|
||||
|
||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
view.show();
|
||||
return app.exec();
|
||||
}
|
55
yat/yat_declarative/object_destruct_item.cpp
Normal file
55
yat/yat_declarative/object_destruct_item.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "object_destruct_item.h"
|
||||
|
||||
ObjectDestructItem::ObjectDestructItem(QQuickItem *parent)
|
||||
: QQuickItem(parent)
|
||||
, m_object(0)
|
||||
{
|
||||
}
|
||||
|
||||
QObject *ObjectDestructItem::objectHandle() const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
void ObjectDestructItem::setObjectHandle(QObject *object)
|
||||
{
|
||||
bool emit_changed = m_object != object;
|
||||
if (m_object) {
|
||||
m_object->disconnect(this);
|
||||
}
|
||||
|
||||
m_object = object;
|
||||
connect(m_object, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
|
||||
|
||||
if (emit_changed)
|
||||
emit objectHandleChanged();
|
||||
}
|
||||
|
||||
void ObjectDestructItem::objectDestroyed()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
52
yat/yat_declarative/object_destruct_item.h
Normal file
52
yat/yat_declarative/object_destruct_item.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef OBJECT_DESTRUCT_ITEM_H
|
||||
#define OBJECT_DESTRUCT_ITEM_H
|
||||
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class ObjectDestructItem : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QObject *objectHandle READ objectHandle WRITE setObjectHandle NOTIFY objectHandleChanged)
|
||||
|
||||
public:
|
||||
ObjectDestructItem(QQuickItem *parent = 0);
|
||||
|
||||
QObject *objectHandle() const;
|
||||
void setObjectHandle(QObject *line);
|
||||
|
||||
signals:
|
||||
void objectHandleChanged();
|
||||
|
||||
private slots:
|
||||
void objectDestroyed();
|
||||
|
||||
private:
|
||||
QObject *m_object;
|
||||
};
|
||||
|
||||
#endif //OBJECT_DESTRUCT_ITEM_H
|
75
yat/yat_declarative/qml/yat_declarative/HighlightArea.qml
Normal file
75
yat/yat_declarative/qml/yat_declarative/HighlightArea.qml
Normal file
@ -0,0 +1,75 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: highlightArea
|
||||
|
||||
property real characterWidth: 0
|
||||
property real characterHeight: 0
|
||||
property int screenWidth: width / characterWidth
|
||||
|
||||
property point start
|
||||
property point end
|
||||
|
||||
property color color: "grey"
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
opacity: 0.8
|
||||
|
||||
Rectangle {
|
||||
id: begginning_rectangle
|
||||
color: parent.color
|
||||
opacity: parent.opacity
|
||||
y:0
|
||||
height: characterHeight
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: middle_rectangle
|
||||
color: parent.color
|
||||
opacity: parent.opacity
|
||||
width: parent.width
|
||||
x: 0
|
||||
anchors.top: begginning_rectangle.bottom
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: end_rectangle
|
||||
color: parent.color
|
||||
opacity: parent.opacity
|
||||
x: 0
|
||||
height: characterHeight
|
||||
anchors.top: middle_rectangle.bottom
|
||||
}
|
||||
|
||||
onCharacterWidthChanged: calculateRectangles();
|
||||
onCharacterHeightChanged: calculateRectangles();
|
||||
onScreenWidthChanged: calculateRectangles();
|
||||
|
||||
onStartChanged: calculateRectangles();
|
||||
onEndChanged: calculateRectangles();
|
||||
|
||||
function calculateRectangles() {
|
||||
highlightArea.y = start.y * characterHeight;
|
||||
begginning_rectangle.x = start.x * characterWidth;
|
||||
if (start.y === end.y) {
|
||||
middle_rectangle.visible = false;
|
||||
end_rectangle.visible = false
|
||||
begginning_rectangle.width = (end.x - start.x) * characterWidth;
|
||||
} else {
|
||||
begginning_rectangle.width = (screenWidth - start.x) * characterWidth;
|
||||
if (start.y === end.y - 1) {
|
||||
middle_rectangle.height = 0;
|
||||
middle_rectangle.visible = false;
|
||||
}else {
|
||||
middle_rectangle.visible = true;
|
||||
middle_rectangle.height = (end.y - start.y - 1) * characterHeight;
|
||||
}
|
||||
end_rectangle.visible = true;
|
||||
end_rectangle.width = end.x * characterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
34
yat/yat_declarative/qml/yat_declarative/TerminalLine.qml
Normal file
34
yat/yat_declarative/qml/yat_declarative/TerminalLine.qml
Normal file
@ -0,0 +1,34 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
import org.yat 1.0
|
||||
|
||||
ObjectDestructItem {
|
||||
id: textLine
|
||||
|
||||
property var textComponent : Qt.createComponent("TerminalText.qml")
|
||||
property font font
|
||||
property real fontHeight
|
||||
property real fontWidth
|
||||
|
||||
height: fontHeight
|
||||
width: parent.width
|
||||
visible: objectHandle.visible
|
||||
|
||||
Connections {
|
||||
target: objectHandle
|
||||
|
||||
onIndexChanged: {
|
||||
y = objectHandle.index * fontHeight;
|
||||
}
|
||||
|
||||
onTextCreated: {
|
||||
var textSegment = textComponent.createObject(textLine,
|
||||
{
|
||||
"objectHandle" : text,
|
||||
"font" : textLine.font,
|
||||
"fontWidth" : textLine.fontWidth,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
194
yat/yat_declarative/qml/yat_declarative/TerminalScreen.qml
Normal file
194
yat/yat_declarative/qml/yat_declarative/TerminalScreen.qml
Normal file
@ -0,0 +1,194 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
import org.yat 1.0
|
||||
|
||||
TerminalScreen {
|
||||
id: screenItem
|
||||
|
||||
property font font
|
||||
property real fontWidth: fontMetricText.paintedWidth
|
||||
property real fontHeight: fontMetricText.paintedHeight
|
||||
|
||||
property var lineComponent : Qt.createComponent("TerminalLine.qml")
|
||||
|
||||
font.family: "courier"
|
||||
|
||||
Text {
|
||||
id: fontMetricText
|
||||
text: "B"
|
||||
font: parent.font
|
||||
visible: false
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: connections
|
||||
|
||||
target: terminal.screen
|
||||
|
||||
onFlash: {
|
||||
flashAnimation.start()
|
||||
}
|
||||
|
||||
onCursorPositionChanged: {
|
||||
cursor.x = x * fontWidth;
|
||||
cursor.y = y * fontHeight;
|
||||
}
|
||||
|
||||
onReset: {
|
||||
resetScreenItems();
|
||||
}
|
||||
|
||||
onLineCreated: {
|
||||
var lineVariable = lineComponent.createObject(screenItem,
|
||||
{
|
||||
"objectHandle" : line,
|
||||
"font": screenItem.font,
|
||||
"fontWidth" : screenItem.fontWidth,
|
||||
"fontHeight" : screenItem.fontHeight,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onFontChanged: {
|
||||
setTerminalHeight();
|
||||
setTerminalWidth();
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
setTerminalWidth();
|
||||
}
|
||||
onHeightChanged: {
|
||||
setTerminalHeight();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
setTerminalWidth();
|
||||
setTerminalHeight();
|
||||
}
|
||||
|
||||
function setTerminalWidth() {
|
||||
if (fontWidth > 0) {
|
||||
var pty_width = Math.floor(width / fontWidth);
|
||||
screen.width = pty_width;
|
||||
}
|
||||
}
|
||||
|
||||
function setTerminalHeight() {
|
||||
if (fontHeight > 0) {
|
||||
var pty_height = Math.floor(height / fontHeight);
|
||||
screen.height = pty_height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: keyHandler
|
||||
focus: true
|
||||
Keys.onPressed: {
|
||||
terminal.screen.sendKey(event.text, event.key, event.modifiers);
|
||||
if (event.text === "?") {
|
||||
terminal.screen.printScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HighlightArea {
|
||||
characterHeight: fontHeight
|
||||
characterWidth: fontWidth
|
||||
|
||||
start: screen.selectionAreaStart
|
||||
end: screen.selectionAreaEnd
|
||||
|
||||
visible: screen.selectionEnabled
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: cursor
|
||||
width: fontWidth
|
||||
height: fontHeight
|
||||
x: 0
|
||||
y: 0
|
||||
color: "grey"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: flash
|
||||
anchors.fill: parent
|
||||
color: "grey"
|
||||
opacity: 0
|
||||
SequentialAnimation {
|
||||
id: flashAnimation
|
||||
NumberAnimation {
|
||||
target: flash
|
||||
property: "opacity"
|
||||
to: 1
|
||||
duration: 75
|
||||
}
|
||||
NumberAnimation {
|
||||
target: flash
|
||||
property: "opacity"
|
||||
to: 0
|
||||
duration: 75
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id:mousArea
|
||||
|
||||
property point drag_start
|
||||
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
hoverEnabled = true;
|
||||
var character = Math.floor((mouse.x / screen.charWidth));
|
||||
var line = Math.floor(mouse.y / screen.lineHeight);
|
||||
var start = Qt.point(character,line);
|
||||
drag_start = start;
|
||||
screen.selectionAreaStart = start;
|
||||
screen.selectionAreaEnd = start;
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
var character = Math.floor(mouse.x / screen.charWidth);
|
||||
var line = Math.floor(mouse.y / screen.lineHeight);
|
||||
var current_pos = Qt.point(character,line);
|
||||
if (line < drag_start.y || (line === drag_start.y && character < drag_start.x)) {
|
||||
screen.selectionAreaStart = current_pos;
|
||||
screen.selectionAreaEnd = drag_start;
|
||||
}else {
|
||||
screen.selectionAreaEnd = current_pos;
|
||||
screen.selectionAreaStart = drag_start;
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
hoverEnabled = false;
|
||||
screen.sendSelectionToSelection();
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (mouse.button == Qt.MiddleButton) {
|
||||
screen.pasteFromSelection();
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
var character = Math.floor(mouse.x / screen.charWidth);
|
||||
var line = Math.floor(mouse.y / screen.lineHeight);
|
||||
screen.doubleClicked(Qt.point(character,line));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
yat/yat_declarative/qml/yat_declarative/TerminalText.qml
Normal file
78
yat/yat_declarative/qml/yat_declarative/TerminalText.qml
Normal file
@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
import org.yat 1.0
|
||||
|
||||
ObjectDestructItem {
|
||||
id: textItem
|
||||
property font font
|
||||
property real fontWidth
|
||||
|
||||
y: 0
|
||||
x: 0
|
||||
|
||||
width: textElement.paintedWidth
|
||||
height: textElement.paintedHeight
|
||||
|
||||
visible: objectHandle.visible
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: textItem.objectHandle.backgroundColor
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: textElement
|
||||
anchors.fill: parent
|
||||
text: objectHandle.text
|
||||
color: objectHandle.foregroundColor
|
||||
font: textItem.font
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: objectHandle
|
||||
|
||||
onIndexChanged: {
|
||||
textItem.x = objectHandle.index * textItem.fontWidth;
|
||||
}
|
||||
}
|
||||
|
||||
//Component.onCompleted: {
|
||||
// //color = randomBg();
|
||||
//}
|
||||
//function randomBg()
|
||||
//{
|
||||
// var hex1=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var hex2=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var hex3=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var hex4=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var hex5=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var hex6=new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
// var bg="#"+hex1[Math.floor(Math.random()*hex1.length)]+hex2[Math.floor(Math.random()*hex2.length)]+hex3[Math.floor(Math.random()*hex3.length)]+hex4[Math.floor(Math.random()*hex4.length)]+hex5[Math.floor(Math.random()*hex5.length)]+hex6[Math.floor(Math.random()*hex6.length)]
|
||||
// return bg
|
||||
//}
|
||||
}
|
7
yat/yat_declarative/qml/yat_declarative/main.qml
Normal file
7
yat/yat_declarative/qml/yat_declarative/main.qml
Normal file
@ -0,0 +1,7 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
TerminalScreen {
|
||||
id: terminal
|
||||
width: 800
|
||||
height: 600
|
||||
}
|
9
yat/yat_declarative/qml_sources.qrc
Normal file
9
yat/yat_declarative/qml_sources.qrc
Normal file
@ -0,0 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/yat_declarative/main.qml</file>
|
||||
<file>qml/yat_declarative/TerminalLine.qml</file>
|
||||
<file>qml/yat_declarative/TerminalScreen.qml</file>
|
||||
<file>qml/yat_declarative/TerminalText.qml</file>
|
||||
<file>qml/yat_declarative/HighlightArea.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
18
yat/yat_declarative/register_qml_types.cpp
Normal file
18
yat/yat_declarative/register_qml_types.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "register_qml_types.h"
|
||||
|
||||
#include <QtQml>
|
||||
|
||||
#include "terminal_screen.h"
|
||||
#include "object_destruct_item.h"
|
||||
#include "screen.h"
|
||||
#include "text.h"
|
||||
#include "line.h"
|
||||
|
||||
void register_qml_types()
|
||||
{
|
||||
qmlRegisterType<TerminalScreen>("org.yat", 1, 0, "TerminalScreen");
|
||||
qmlRegisterType<ObjectDestructItem>("org.yat", 1, 0, "ObjectDestructItem");
|
||||
qmlRegisterType<Screen>();
|
||||
qmlRegisterType<Text>();
|
||||
qmlRegisterType<Line>();
|
||||
}
|
6
yat/yat_declarative/register_qml_types.h
Normal file
6
yat/yat_declarative/register_qml_types.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef REGISTER_QML_TYPES_H
|
||||
#define REGISTER_QML_TYPES_H
|
||||
|
||||
void register_qml_types();
|
||||
|
||||
#endif // REGISTER_QML_TYPES_H
|
32
yat/yat_declarative/terminal_screen.cpp
Normal file
32
yat/yat_declarative/terminal_screen.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/**************************************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "terminal_screen.h"
|
||||
|
||||
TerminalScreen::TerminalScreen(QQuickItem *parent)
|
||||
: QQuickItem(parent)
|
||||
, m_screen(new Screen(this))
|
||||
{
|
||||
}
|
||||
|
||||
Screen *TerminalScreen::screen() const
|
||||
{
|
||||
return m_screen;
|
||||
}
|
46
yat/yat_declarative/terminal_screen.h
Normal file
46
yat/yat_declarative/terminal_screen.h
Normal file
@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2012 Jørgen Lind
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef TERMINALITEM_H
|
||||
#define TERMINALITEM_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
class TerminalScreen : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Screen *screen READ screen CONSTANT)
|
||||
public:
|
||||
TerminalScreen(QQuickItem *parent = 0);
|
||||
|
||||
Screen *screen() const;
|
||||
|
||||
private:
|
||||
Screen *m_screen;
|
||||
};
|
||||
|
||||
#endif // TERMINALITEM_H
|
27
yat/yat_declarative/yat_declarative.pro
Normal file
27
yat/yat_declarative/yat_declarative.pro
Normal file
@ -0,0 +1,27 @@
|
||||
QT += gui quick
|
||||
TARGET = yat
|
||||
|
||||
include(../backend/backend.pri)
|
||||
|
||||
SOURCES += main.cpp \
|
||||
terminal_screen.cpp \
|
||||
object_destruct_item.cpp \
|
||||
register_qml_types.cpp \
|
||||
|
||||
HEADERS += \
|
||||
terminal_screen.h \
|
||||
object_destruct_item.h \
|
||||
register_qml_types.h \
|
||||
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
OTHER_FILES += \
|
||||
qml/yat_declarative/main.qml \
|
||||
qml/yat_declarative/TerminalLine.qml \
|
||||
qml/yat_declarative/TerminalScreen.qml \
|
||||
qml/yat_declarative/TerminalText.qml \
|
||||
qml/yat_declarative/HighlightArea.qml
|
||||
|
||||
RESOURCES += \
|
||||
qml_sources.qrc
|
||||
|
Loading…
Reference in New Issue
Block a user