aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.cpp87
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.h4
-rw-r--r--desktop-utilities/lumina-terminal/TtyProcess.cpp9
-rw-r--r--desktop-utilities/lumina-terminal/TtyProcess.h7
4 files changed, 93 insertions, 14 deletions
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.cpp b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
index 1756d0b1..c08c9d81 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.cpp
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
@@ -40,21 +40,90 @@ void TerminalWidget::aboutToClose(){
}
// ==================
+// PRIVATE
+// ==================
+void TerminalWidget::applyData(QByteArray data){
+ //Quick global replacement (this widget reads both as newlines)
+ data = data.replace("\r\n","\n");
+ //Iterate through the data and apply it when possible
+ for(int i=0; i<data.size(); i++){
+ if( data.at(i)=='\b' ){
+ //Simple Backspace
+ this->textCursor().deletePreviousChar();
+
+ }else if( data.at(i)=='\x1B' ){
+ //ANSI Control Code start
+ //Look for the end of the code
+ int end = -1;
+ for(int j=1; j<(data.size()-i) && end<0; j++){
+ if(QChar(data.at(i+j)).isLetter()){ end = j; }
+ }
+ if(end<0){ return; } //skip everything else - no end to code found
+ applyANSI(data.mid(i, end));
+ i+=end; //move the final loop along - already handled these bytes
+
+ }else{
+ //Plaintext character - just add it here
+ this->insertPlainText( QChar(data.at(i)) );
+ }
+
+ } //end loop over data
+}
+
+void TerminalWidget::applyANSI(QByteArray code){
+ //Note: the first byte is often the "[" character
+ //CURSOR MOVEMENT
+ if( code.endsWith("A") ){ //Move Up
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::Up, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("B")){ //Move Down
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("C")){ //Move Forward
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("D")){ //Move Back
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("E")){ //Move Next/down Lines (go to beginning)
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::NextRow, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("F")){ //Move Previous/up Lines (go to beginning)
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().movePosition(QTextCursor::PreviousRow, QTextCursor::MoveAnchor, num);
+ }else if(code.endsWith("G")){ //Move to specific column
+ int num = 1;
+ if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ this->textCursor().setPosition(num);
+ }else if(code.endsWith("H")){ //Move to specific position (row/column)
+ int mid = code.indexOf(";");
+ if(mid>0){
+ int numR, numC; numR = numC = 1;
+ if(mid >=3){ numR = code.mid(1,mid-1).toInt(); }
+ if(mid < code.size()-1){ numC = code.mid(mid+1,code.size()-mid-1).toInt(); }
+ //this->textCursor().setPosition(
+ qDebug() << "Set Text Position (absolute):" << "Row:" << numR << "Col:" << numC;
+ // TO-DO
+ }
+ }else if(code.endsWith("J")){ //ED - Erase Display
+
+ }
+}
+
+// ==================
// PRIVATE SLOTS
// ==================
void TerminalWidget::UpdateText(){
//read the data from the process
//qDebug() << "UpdateText";
if(!PROC->isOpen()){ return; }
- QByteArray buffer = PROC->readTTY();
- QString text = QString(buffer);
- text.replace("\r\n","\n");
- //Special Cursor handling
- while(text.startsWith("\b")){
- this->textCursor().deletePreviousChar();
- text = text.remove(0,1);
- }
- this->insertPlainText(text);
+ applyData(PROC->readTTY());
//adjust the scrollbar as needed
this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum());
}
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.h b/desktop-utilities/lumina-terminal/TerminalWidget.h
index 49b255ff..18f0054f 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.h
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.h
@@ -25,9 +25,11 @@ public:
private:
TTYProcess *PROC;
- //QProcess *PROC;
QSocketNotifier *sn;
+
+ void applyData(QByteArray data); //overall data parsing
+ void applyANSI(QByteArray code); //individual code application
private slots:
void UpdateText();
diff --git a/desktop-utilities/lumina-terminal/TtyProcess.cpp b/desktop-utilities/lumina-terminal/TtyProcess.cpp
index 15094f64..8121b365 100644
--- a/desktop-utilities/lumina-terminal/TtyProcess.cpp
+++ b/desktop-utilities/lumina-terminal/TtyProcess.cpp
@@ -75,7 +75,10 @@ void TTYProcess::writeQtKey(int key){
ba.append("\x1b[D\x1b[K");
break;
case Qt::Key_Left:
+ ba.append("\x1b[D");
+ break;
case Qt::Key_Right:
+ ba.append("\x1b[C");
break;
case Qt::Key_Up:
ba.append("\x1b[A");
@@ -150,7 +153,7 @@ QByteArray TTYProcess::CleanANSI(QByteArray raw, bool &incomplete){
index = raw.indexOf("\x1B]");
}
- // GENERIC ANSI CODES
+ // GENERIC ANSI CODES ((Make sure the output is not cut off in the middle of a code)
index = raw.indexOf("\x1B[");
while(index>=0){
//CURSOR MOVEMENT
@@ -162,10 +165,8 @@ QByteArray TTYProcess::CleanANSI(QByteArray raw, bool &incomplete){
end = i; //found the end of the control code
}
}
- raw = raw.remove(index, 1+end); //control character +1 byte
- index = raw.indexOf("\x1B[");
+ index = raw.indexOf("\x1B[",index+1); //now find the next one
}
- //qDebug() << " - Removed Color Codes:" << raw;
// SYSTEM BELL
index = raw.indexOf("\x07");
diff --git a/desktop-utilities/lumina-terminal/TtyProcess.h b/desktop-utilities/lumina-terminal/TtyProcess.h
index 04f294a2..b1703fb7 100644
--- a/desktop-utilities/lumina-terminal/TtyProcess.h
+++ b/desktop-utilities/lumina-terminal/TtyProcess.h
@@ -9,6 +9,13 @@
// to be used for terminal-like apps (shells) which directly modify the terminal output
// rather than stick to input/output channels for communication.
//===========================================
+// IMPLEMENTATION NOTE
+//======================
+// The process requires/uses ANSI control codes (\x1B[<something>) for special operations
+// such as moving the cursor, erasing characters, etc..
+// It is recommended that you pair this class with the graphical "TerminalWidget.h" class
+// or some other ANSI-compatible display widget.
+//===========================================
#ifndef _LUMINA_DESKTOP_UTILITIES_TERMINAL_TTY_PROCESS_WIDGET_H
#define _LUMINA_DESKTOP_UTILITIES_TERMINAL_TTY_PROCESS_WIDGET_H
bgstack15