mirror of
				https://github.com/Swordfish90/cool-retro-term.git
				synced 2025-10-30 22:54:21 +00:00 
			
		
		
		
	Switched to my version of yat
This commit is contained in:
		
							
								
								
									
										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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user