mirror of
				https://github.com/Swordfish90/cool-retro-term.git
				synced 2025-10-31 07:04:20 +00:00 
			
		
		
		
	Moved to new version of yat. Yat is no longer a submodule but is now integrated.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +0,0 @@ | |||||||
| [submodule "yat"] |  | ||||||
| 	path = yat |  | ||||||
| 	url = https://github.com/Swordifish90/yat |  | ||||||
| 	branch = stable |  | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| QT += widgets quick | QT += widgets quick core-private gui-private qml-private quick quick-private | ||||||
|  |  | ||||||
| include(yat/yat_declarative/yat_declarative.pro) | include(yat/yat_declarative/yat_declarative.pro) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,26 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 QtQuick 2.0 | ||||||
|  |  | ||||||
| Item { | Item { | ||||||
| @@ -5,15 +28,19 @@ Item { | |||||||
|  |  | ||||||
|     property real characterWidth: 0 |     property real characterWidth: 0 | ||||||
|     property real characterHeight: 0 |     property real characterHeight: 0 | ||||||
|     property int screenWidth: width / characterWidth |     property int screenWidth: 0 | ||||||
|  |  | ||||||
|     property point start |     property int startX | ||||||
|     property point end |     property int startY | ||||||
|  |  | ||||||
|  |     property int endX | ||||||
|  |     property int endY | ||||||
|  |  | ||||||
|     property color color: "grey" |     property color color: "grey" | ||||||
|  |  | ||||||
|  |     y: startY * characterHeight | ||||||
|     width: parent.width |     width: parent.width | ||||||
|     height: parent.height |     height: (endY - startY + 1) * characterHeight | ||||||
|  |  | ||||||
|     opacity: 0.8 |     opacity: 0.8 | ||||||
|  |  | ||||||
| @@ -48,27 +75,29 @@ Item { | |||||||
|     onCharacterHeightChanged: calculateRectangles(); |     onCharacterHeightChanged: calculateRectangles(); | ||||||
|     onScreenWidthChanged: calculateRectangles(); |     onScreenWidthChanged: calculateRectangles(); | ||||||
|  |  | ||||||
|     onStartChanged: calculateRectangles(); |     onStartXChanged: calculateRectangles(); | ||||||
|     onEndChanged: calculateRectangles(); |     onStartYChanged: calculateRectangles(); | ||||||
|  |     onEndXChanged: calculateRectangles(); | ||||||
|  |     onEndYChanged: calculateRectangles(); | ||||||
|  |  | ||||||
|     function calculateRectangles() { |     function calculateRectangles() { | ||||||
|         highlightArea.y = start.y * characterHeight; |         highlightArea.y = startY * characterHeight; | ||||||
|         begginning_rectangle.x = start.x * characterWidth; |         begginning_rectangle.x = startX * characterWidth; | ||||||
|         if (start.y === end.y) { |         if (startY === endY) { | ||||||
|             middle_rectangle.visible = false; |             middle_rectangle.visible = false; | ||||||
|             end_rectangle.visible = false |             end_rectangle.visible = false | ||||||
|             begginning_rectangle.width = (end.x - start.x) * characterWidth; |             begginning_rectangle.width = (endX - startX) * characterWidth; | ||||||
|         } else { |         } else { | ||||||
|             begginning_rectangle.width = (screenWidth - start.x) * characterWidth; |             begginning_rectangle.width = (screenWidth - startX) * characterWidth; | ||||||
|             if (start.y === end.y - 1) { |             if (startY === endY - 1) { | ||||||
|                 middle_rectangle.height = 0; |                 middle_rectangle.height = 0; | ||||||
|                 middle_rectangle.visible = false; |                 middle_rectangle.visible = false; | ||||||
|             }else { |             }else { | ||||||
|                 middle_rectangle.visible = true; |                 middle_rectangle.visible = true; | ||||||
|                 middle_rectangle.height = (end.y - start.y - 1) * characterHeight; |                 middle_rectangle.height = (endY - startY - 1) * characterHeight; | ||||||
|             } |             } | ||||||
|             end_rectangle.visible = true; |             end_rectangle.visible = true; | ||||||
|             end_rectangle.width = end.x * characterWidth; |             end_rectangle.width = endX * characterWidth; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								qml/cool-old-term/TerminalCursor.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								qml/cool-old-term/TerminalCursor.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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: cursor | ||||||
|  |  | ||||||
|  |     property real fontHeight | ||||||
|  |     property real fontWidth | ||||||
|  |  | ||||||
|  |     height: fontHeight | ||||||
|  |     width: fontWidth | ||||||
|  |     x: objectHandle.x * fontWidth | ||||||
|  |     y: objectHandle.y * fontHeight | ||||||
|  |     z: 1.1 | ||||||
|  |  | ||||||
|  |     visible: objectHandle.visible | ||||||
|  |  | ||||||
|  |     ShaderEffect { | ||||||
|  |         anchors.fill: parent | ||||||
|  |  | ||||||
|  |         property variant source: fragmentSource | ||||||
|  |  | ||||||
|  |         fragmentShader: | ||||||
|  |             "uniform lowp float qt_Opacity;" + | ||||||
|  |             "uniform sampler2D source;" + | ||||||
|  |             "varying highp vec2 qt_TexCoord0;" + | ||||||
|  |  | ||||||
|  |             "void main() {" + | ||||||
|  |             "   lowp vec4 color = texture2D(source, qt_TexCoord0 ) * qt_Opacity;" + | ||||||
|  |             "   gl_FragColor = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b, color.a);" + | ||||||
|  |             "}" | ||||||
|  |  | ||||||
|  |         ShaderEffectSource { | ||||||
|  |             id: fragmentSource | ||||||
|  |             sourceItem: background | ||||||
|  |             live: true | ||||||
|  |  | ||||||
|  |             sourceRect: Qt.rect(cursor.x,cursor.y,cursor.width,cursor.height); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -1,4 +1,28 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 QtQuick 2.0 | ||||||
|  | import QtQuick.Controls 1.1 | ||||||
|  |  | ||||||
| import org.yat 1.0 | import org.yat 1.0 | ||||||
|  |  | ||||||
| @@ -10,10 +34,35 @@ TerminalScreen { | |||||||
|     property real fontHeight: fontMetricText.paintedHeight |     property real fontHeight: fontMetricText.paintedHeight | ||||||
|  |  | ||||||
|     property var lineComponent : Qt.createComponent("TerminalLine.qml") |     property var lineComponent : Qt.createComponent("TerminalLine.qml") | ||||||
|  |     property var textComponent : Qt.createComponent("TerminalText.qml") | ||||||
|  |     property var cursorComponent : Qt.createComponent("TerminalCursor.qml") | ||||||
|  |  | ||||||
|     font.family: "Pet Me" |     font.family: "Pet Me" | ||||||
|     font.pointSize: 14 |     font.pixelSize: 20 | ||||||
|     //font.bold: true |     focus: true | ||||||
|  |  | ||||||
|  |     Action { | ||||||
|  |         id: copyAction | ||||||
|  |         shortcut: "Ctrl+Shift+C" | ||||||
|  |         onTriggered: screen.selection.sendToClipboard() | ||||||
|  |     } | ||||||
|  |     Action { | ||||||
|  |         id: paseAction | ||||||
|  |         shortcut: "Ctrl+Shift+V" | ||||||
|  |         onTriggered: screen.selection.pasteFromClipboard() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onActiveFocusChanged: { | ||||||
|  |         if (activeFocus) { | ||||||
|  |             Qt.inputMethod.show(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Keys.onPressed: { | ||||||
|  |         if (event.text === "?") { | ||||||
|  |             terminal.screen.printScreen() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Text { |     Text { | ||||||
|         id: fontMetricText |         id: fontMetricText | ||||||
| @@ -23,10 +72,47 @@ TerminalScreen { | |||||||
|         textFormat: Text.PlainText |         textFormat: Text.PlainText | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     Flickable { | ||||||
|  |         id: flickable | ||||||
|  |         anchors.top: parent.top | ||||||
|  |         anchors.left: parent.left | ||||||
|  |         contentWidth: width | ||||||
|  |         contentHeight: textContainer.height | ||||||
|  |         interactive: true | ||||||
|  |         flickableDirection: Flickable.VerticalFlick | ||||||
|  |         contentY: ((screen.contentHeight - screen.height) * screenItem.fontHeight) | ||||||
|  |  | ||||||
|  |         Item { | ||||||
|  |             id: textContainer | ||||||
|  |             width: parent.width | ||||||
|  |             height: screen.contentHeight * screenItem.fontHeight | ||||||
|             Rectangle { |             Rectangle { | ||||||
|                 id: background |                 id: background | ||||||
|                 anchors.fill: parent |                 anchors.fill: parent | ||||||
|         color: "black" |                 color: terminal.screen.defaultBackgroundColor | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             HighlightArea { | ||||||
|  |                 characterHeight: fontHeight | ||||||
|  |                 characterWidth: fontWidth | ||||||
|  |                 screenWidth: terminalWindow.width | ||||||
|  |  | ||||||
|  |                 startX: screen.selection.startX | ||||||
|  |                 startY: screen.selection.startY | ||||||
|  |  | ||||||
|  |                 endX: screen.selection.endX | ||||||
|  |                 endY: screen.selection.endY | ||||||
|  |  | ||||||
|  |                 visible: screen.selection.enable | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onContentYChanged: { | ||||||
|  |             if (!atYEnd) { | ||||||
|  |                 var top_line = Math.floor(Math.max(contentY,0) / screenItem.fontHeight); | ||||||
|  |                 screen.ensureVisiblePages(top_line); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Connections { |     Connections { | ||||||
| @@ -38,24 +124,44 @@ TerminalScreen { | |||||||
|             flashAnimation.start() |             flashAnimation.start() | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         onCursorPositionChanged: { |  | ||||||
|             cursor.x = x * fontWidth; |  | ||||||
|             cursor.y = y * fontHeight; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         onReset: { |         onReset: { | ||||||
|             resetScreenItems(); |             resetScreenItems(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         onLineCreated: { |         onTextCreated: { | ||||||
|             var lineVariable = lineComponent.createObject(screenItem, |             var textSegment = textComponent.createObject(screenItem, | ||||||
|                 { |                 { | ||||||
|                     "objectHandle" : line, |                     "parent" : background, | ||||||
|                     "font": screenItem.font, |                     "objectHandle" : text, | ||||||
|  |                     "font" : screenItem.font, | ||||||
|                     "fontWidth" : screenItem.fontWidth, |                     "fontWidth" : screenItem.fontWidth, | ||||||
|                     "fontHeight" : screenItem.fontHeight, |                     "fontHeight" : screenItem.fontHeight, | ||||||
|                 }) |                 }) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         onCursorCreated: { | ||||||
|  |             if (cursorComponent.status != Component.Ready) { | ||||||
|  |                 console.log(cursorComponent.errorString()); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             var cursorVariable = cursorComponent.createObject(screenItem, | ||||||
|  |                 { | ||||||
|  |                     "parent" : textContainer, | ||||||
|  |                     "objectHandle" : cursor, | ||||||
|  |                     "fontWidth" : screenItem.fontWidth, | ||||||
|  |                     "fontHeight" : screenItem.fontHeight, | ||||||
|  |                 }) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onRequestHeightChange: { | ||||||
|  |             terminalWindow.height = newHeight * screenItem.fontHeight; | ||||||
|  |             terminalWindow.contentItem.height = newHeight * screenItem.fontHeight; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onRequestWidthChange: { | ||||||
|  |             terminalWindow.width = newWidth * screenItem.fontWidth; | ||||||
|  |             terminalWindow.contentItem.width = newWidth * screenItem.fontWidth; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     onFontChanged: { |     onFontChanged: { | ||||||
| @@ -77,6 +183,7 @@ TerminalScreen { | |||||||
|     function setTerminalWidth() { |     function setTerminalWidth() { | ||||||
|         if (fontWidth > 0) { |         if (fontWidth > 0) { | ||||||
|             var pty_width = Math.floor(width / fontWidth); |             var pty_width = Math.floor(width / fontWidth); | ||||||
|  |             flickable.width = pty_width * fontWidth; | ||||||
|             screen.width = pty_width; |             screen.width = pty_width; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -84,50 +191,16 @@ TerminalScreen { | |||||||
|     function setTerminalHeight() { |     function setTerminalHeight() { | ||||||
|         if (fontHeight > 0) { |         if (fontHeight > 0) { | ||||||
|             var pty_height = Math.floor(height / fontHeight); |             var pty_height = Math.floor(height / fontHeight); | ||||||
|  |             flickable.height = pty_height * fontHeight; | ||||||
|             screen.height = pty_height; |             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: "white" |  | ||||||
| //        SequentialAnimation on opacity{ |  | ||||||
| //            NumberAnimation{from: 0; to: 1; duration: 500} |  | ||||||
| //            NumberAnimation{from: 1; to: 0; duration: 500} |  | ||||||
| //            loops: Animation.Infinite |  | ||||||
| //        } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Rectangle { |     Rectangle { | ||||||
|         id: flash |         id: flash | ||||||
|  |         z: 1.2 | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
|         color: "white" |         color: "grey" | ||||||
|         opacity: 0 |         opacity: 0 | ||||||
|         SequentialAnimation { |         SequentialAnimation { | ||||||
|             id: flashAnimation |             id: flashAnimation | ||||||
| @@ -149,39 +222,49 @@ TerminalScreen { | |||||||
|     MouseArea { |     MouseArea { | ||||||
|         id:mousArea |         id:mousArea | ||||||
|  |  | ||||||
|         property point drag_start |         property int drag_start_x | ||||||
|  |         property int drag_start_y | ||||||
|  |  | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
|         acceptedButtons: Qt.LeftButton | Qt.MiddleButton |         acceptedButtons: Qt.LeftButton | Qt.MiddleButton | ||||||
|         onPressed: { |         onPressed: { | ||||||
|             if (mouse.button == Qt.LeftButton) { |             if (mouse.button == Qt.LeftButton) { | ||||||
|                 hoverEnabled = true; |                 hoverEnabled = true; | ||||||
|                 var character = Math.floor((mouse.x / screen.charWidth)); |                 var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|                 var line = Math.floor(mouse.y / screen.lineHeight); |                 var character = Math.floor((transformed_mouse.x / fontWidth)); | ||||||
|  |                 var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|                 var start = Qt.point(character,line); |                 var start = Qt.point(character,line); | ||||||
|                 drag_start = start; |                 drag_start_x = character; | ||||||
|                 screen.selectionAreaStart = start; |                 drag_start_y = line; | ||||||
|                 screen.selectionAreaEnd = start; |                 screen.selection.startX = character; | ||||||
|  |                 screen.selection.startY = line; | ||||||
|  |                 screen.selection.endX = character; | ||||||
|  |                 screen.selection.endY = line; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         onPositionChanged: { |         onPositionChanged: { | ||||||
|             var character = Math.floor(mouse.x / screen.charWidth); |             var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|             var line = Math.floor(mouse.y / screen.lineHeight); |             var character = Math.floor(transformed_mouse.x / fontWidth); | ||||||
|  |             var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|             var current_pos = Qt.point(character,line); |             var current_pos = Qt.point(character,line); | ||||||
|             if (line < drag_start.y || (line === drag_start.y && character < drag_start.x)) { |             if (line < drag_start_y || (line === drag_start_y && character < drag_start_x)) { | ||||||
|                 screen.selectionAreaStart = current_pos; |                 screen.selection.startX = character; | ||||||
|                 screen.selectionAreaEnd = drag_start; |                 screen.selection.startY = line; | ||||||
|  |                 screen.selection.endX = drag_start_x; | ||||||
|  |                 screen.selection.endY = drag_start_y; | ||||||
|             }else { |             }else { | ||||||
|                 screen.selectionAreaEnd = current_pos; |                 screen.selection.startX = drag_start_x; | ||||||
|                 screen.selectionAreaStart = drag_start; |                 screen.selection.startY = drag_start_y; | ||||||
|  |                 screen.selection.endX = character; | ||||||
|  |                 screen.selection.endY = line; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         onReleased: { |         onReleased: { | ||||||
|             if (mouse.button == Qt.LeftButton) { |             if (mouse.button == Qt.LeftButton) { | ||||||
|                 hoverEnabled = false; |                 hoverEnabled = false; | ||||||
|                 screen.sendSelectionToSelection(); |                 screen.selection.sendToSelection(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -190,10 +273,12 @@ TerminalScreen { | |||||||
|                 screen.pasteFromSelection(); |                 screen.pasteFromSelection(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         onDoubleClicked: { |         onDoubleClicked: { | ||||||
|             if (mouse.button == Qt.LeftButton) { |             if (mouse.button == Qt.LeftButton) { | ||||||
|                 var character = Math.floor(mouse.x / screen.charWidth); |                 var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|                 var line = Math.floor(mouse.y / screen.lineHeight); |                 var character = Math.floor(transformed_mouse.x / fontWidth); | ||||||
|  |                 var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|                 screen.doubleClicked(Qt.point(character,line)); |                 screen.doubleClicked(Qt.point(character,line)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -29,9 +29,10 @@ ObjectDestructItem { | |||||||
|     id: textItem |     id: textItem | ||||||
|     property font font |     property font font | ||||||
|     property real fontWidth |     property real fontWidth | ||||||
|  |     property real fontHeight | ||||||
|  |  | ||||||
|     y: 0 |     y: objectHandle.line * fontHeight; | ||||||
|     x: 0 |     x: objectHandle.index * fontWidth; | ||||||
|  |  | ||||||
|     width: textElement.paintedWidth |     width: textElement.paintedWidth | ||||||
|     height: textElement.paintedHeight |     height: textElement.paintedHeight | ||||||
| @@ -40,39 +41,41 @@ ObjectDestructItem { | |||||||
|  |  | ||||||
|     Rectangle { |     Rectangle { | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
|         color: textItem.objectHandle.backgroundColor |         color: "black" //objectHandle.backgroundColor | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |         MonoText { | ||||||
|     Text { |  | ||||||
|             id: textElement |             id: textElement | ||||||
|             anchors.fill: parent |             anchors.fill: parent | ||||||
|             text: objectHandle.text |             text: objectHandle.text | ||||||
|         color: "white" |             color: "white" //objectHandle.foregroundColor | ||||||
|         font: textItem.font |             font.family: textItem.font.family | ||||||
|         textFormat: Text.PlainText |             font.pixelSize: textItem.font.pixelSize | ||||||
|  |             font.pointSize: textItem.font.pointSize | ||||||
|  |             font.bold: objectHandle.bold | ||||||
|  |             font.underline: objectHandle.underline | ||||||
|  |             latin: objectHandle.latin | ||||||
|  |  | ||||||
|  |             SequentialAnimation { | ||||||
|  |                 running: objectHandle.blinking | ||||||
|  |                 loops: Animation.Infinite | ||||||
|  |                 onRunningChanged: { | ||||||
|  |                     if (running === false) | ||||||
|  |                         textElement.opacity = 1 | ||||||
|  |                 } | ||||||
|  |                 NumberAnimation { | ||||||
|  |                     target: textElement | ||||||
|  |                     property: "opacity" | ||||||
|  |                     to: 0 | ||||||
|  |                     duration: 250 | ||||||
|  |                 } | ||||||
|  |                 NumberAnimation { | ||||||
|  |                     target: textElement | ||||||
|  |                     property: "opacity" | ||||||
|  |                     to: 1 | ||||||
|  |                     duration: 250 | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|     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 |  | ||||||
|     //} |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -229,13 +229,12 @@ ApplicationWindow{ | |||||||
|  |  | ||||||
|         TerminalScreen { |         TerminalScreen { | ||||||
|             id: terminal |             id: terminal | ||||||
|             anchors.centerIn: parent |             anchors.fill: parent | ||||||
|             width: mainwindow.width |  | ||||||
|             height: mainwindow.height |  | ||||||
|             visible: false |  | ||||||
|  |  | ||||||
|             //FIXME: Ugly forced clear terminal at the beginning |             //FIXME: Ugly forced clear terminal at the beginning | ||||||
|             Component.onCompleted: terminal.screen.sendKey("l", 76, 67108864); |             Component.onCompleted: { | ||||||
|  |                 terminal.screen.sendKey("l", 76, 67108864); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         RadialGradient{ |         RadialGradient{ | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								yat
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								yat
									
									
									
									
									
								
							 Submodule yat deleted from fb2266d7a1
									
								
							
							
								
								
									
										8
									
								
								yat/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								yat/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | forked at 8c3d6c85c3dc981bca817bd9052a693570e26e6e | ||||||
|  |  | ||||||
|  | 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. | ||||||
							
								
								
									
										41
									
								
								yat/backend/backend.pri
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								yat/backend/backend.pri
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | DEPENDPATH += $$PWD | ||||||
|  | INCLUDEPATH += $$PWD | ||||||
|  |  | ||||||
|  | LIBS += -lutil | ||||||
|  |  | ||||||
|  | CONFIG += c++11 | ||||||
|  |  | ||||||
|  | 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/block.h \ | ||||||
|  |            $$PWD/color_palette.h \ | ||||||
|  |            $$PWD/text_style.h \ | ||||||
|  |            $$PWD/screen_data.h \ | ||||||
|  |            $$PWD/cursor.h \ | ||||||
|  |            $$PWD/nrc_text_codec.h \ | ||||||
|  |            $$PWD/scrollback.h \ | ||||||
|  |            $$PWD/utf8_decoder.h \ | ||||||
|  |            $$PWD/selection.h | ||||||
|  |  | ||||||
|  | SOURCES += \ | ||||||
|  |            $$PWD/yat_pty.cpp \ | ||||||
|  |            $$PWD/text.cpp \ | ||||||
|  |            $$PWD/controll_chars.cpp \ | ||||||
|  |            $$PWD/parser.cpp \ | ||||||
|  |            $$PWD/screen.cpp \ | ||||||
|  |            $$PWD/block.cpp \ | ||||||
|  |            $$PWD/color_palette.cpp \ | ||||||
|  |            $$PWD/text_style.cpp \ | ||||||
|  |            $$PWD/screen_data.cpp \ | ||||||
|  |            $$PWD/cursor.cpp \ | ||||||
|  |            $$PWD/nrc_text_codec.cpp \ | ||||||
|  |            $$PWD/scrollback.cpp \ | ||||||
|  |            $$PWD/selection.cpp | ||||||
|  |  | ||||||
							
								
								
									
										557
									
								
								yat/backend/block.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										557
									
								
								yat/backend/block.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,557 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * 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 "block.h" | ||||||
|  |  | ||||||
|  | #include "text.h" | ||||||
|  | #include "screen.h" | ||||||
|  |  | ||||||
|  | #include <QtQuick/QQuickView> | ||||||
|  | #include <QtQuick/QQuickItem> | ||||||
|  |  | ||||||
|  | #include <QtCore/QDebug> | ||||||
|  |  | ||||||
|  | #include <algorithm> | ||||||
|  |  | ||||||
|  | Block::Block(Screen *screen) | ||||||
|  |     : m_screen(screen) | ||||||
|  |     , m_line(0) | ||||||
|  |     , m_new_line(-1) | ||||||
|  |     , m_screen_index(0) | ||||||
|  |     , m_width(m_screen->width()) | ||||||
|  |     , m_visible(true) | ||||||
|  |     , m_changed(true) | ||||||
|  |     , m_only_latin(true) | ||||||
|  | { | ||||||
|  |     clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Block::~Block() | ||||||
|  | { | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         m_style_list[i].releaseTextSegment(m_screen); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Screen *Block::screen() const | ||||||
|  | { | ||||||
|  |     return m_screen; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::clear() | ||||||
|  | { | ||||||
|  |     m_text_line.clear(); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         m_style_list[i].releaseTextSegment(m_screen); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_style_list.clear(); | ||||||
|  |  | ||||||
|  |     m_only_latin = true; | ||||||
|  |     m_changed = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::clearToEnd(int from) | ||||||
|  | { | ||||||
|  |     clearCharacters(from, m_text_line.size() - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::clearCharacters(int from, int to) | ||||||
|  | { | ||||||
|  |     if (from > m_text_line.size()) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     QString empty(to+1-from, QChar(' ')); | ||||||
|  |     const TextStyle &defaultTextStyle = m_screen->defaultTextStyle(); | ||||||
|  |     replaceAtPos(from, empty, defaultTextStyle); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::deleteCharacters(int from, int to) | ||||||
|  | { | ||||||
|  |     m_changed = true; | ||||||
|  |  | ||||||
|  |     int removed = 0; | ||||||
|  |     const int size = (to + 1) - from; | ||||||
|  |     bool found = false; | ||||||
|  |  | ||||||
|  |     int last_index = -1; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         TextStyleLine ¤t_style = m_style_list[i]; | ||||||
|  |         last_index = 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; | ||||||
|  |                     current_style.releaseTextSegment(m_screen); | ||||||
|  |                     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) { | ||||||
|  |                     current_style.releaseTextSegment(m_screen); | ||||||
|  |                     m_style_list.remove(i); | ||||||
|  |                     i--; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (last_index >= 0) { | ||||||
|  |         TextStyleLine &last_modified = m_style_list[last_index]; | ||||||
|  |         TextStyle defaultStyle = m_screen->defaultTextStyle(); | ||||||
|  |         if (last_modified.isCompatible(defaultStyle)) { | ||||||
|  |             last_modified.end_index += size; | ||||||
|  |             last_modified.text_dirty = true; | ||||||
|  |         } else { | ||||||
|  |             m_style_list.insert(last_index + 1, TextStyleLine(defaultStyle, | ||||||
|  |                         last_modified.end_index + 1, last_modified.end_index + size)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_text_line.remove(from, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::deleteToEnd(int from) | ||||||
|  | { | ||||||
|  |     deleteCharacters(from, m_text_line.size() - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::deleteLines(int from) | ||||||
|  | { | ||||||
|  |     if (from > lineCount()) | ||||||
|  |         return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::replaceAtPos(int pos, const QString &text, const TextStyle &style, bool only_latin) | ||||||
|  | { | ||||||
|  |     m_changed = true; | ||||||
|  |     m_only_latin = m_only_latin && only_latin; | ||||||
|  |  | ||||||
|  |     if (pos >= m_text_line.size()) { | ||||||
|  |         if (pos > m_text_line.size()) { | ||||||
|  |             int old_size = m_text_line.size(); | ||||||
|  |             QString filling(pos - m_text_line.size(), QChar(' ')); | ||||||
|  |             m_text_line.append(filling); | ||||||
|  |             m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(), old_size, old_size + filling.size() -1)); | ||||||
|  |         } | ||||||
|  |         m_text_line.append(text); | ||||||
|  |         m_style_list.append(TextStyleLine(style, pos, pos + text.size()-1)); | ||||||
|  |         return; | ||||||
|  |     } else if (pos + text.size() > m_text_line.size()) { | ||||||
|  |         m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(), pos + text.size() - m_text_line.size(), pos + text.size() -1)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     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() - 1) { | ||||||
|  |                 current_style.releaseTextSegment(m_screen); | ||||||
|  |                 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); | ||||||
|  |                         current_style.text_dirty = true; | ||||||
|  |                         current_style.style_dirty = true; | ||||||
|  |                     } 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() - 1) { | ||||||
|  |                         current_style.end_index = pos - 1; | ||||||
|  |                         current_style.text_dirty = true; | ||||||
|  |                         m_style_list.insert(i+1, TextStyleLine(style,pos, pos + text.size() - 1)); | ||||||
|  |                     } 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) { | ||||||
|  |                         if (i > 0 && m_style_list.at(i-1).isCompatible(style)) { | ||||||
|  |                             TextStyleLine &previous_style = m_style_list[i -1]; | ||||||
|  |                             previous_style.end_index+= text.size(); | ||||||
|  |                             previous_style.text_dirty = true; | ||||||
|  |                             current_style.releaseTextSegment(m_screen); | ||||||
|  |                             m_style_list.remove(i); | ||||||
|  |                             i--; | ||||||
|  |                         } else { | ||||||
|  |                             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; | ||||||
|  |                             current_style.index_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 Block::insertAtPos(int pos, const QString &text, const TextStyle &style, bool only_latin) | ||||||
|  | { | ||||||
|  |     m_changed = true; | ||||||
|  |     m_only_latin = m_only_latin && only_latin; | ||||||
|  |  | ||||||
|  |     m_text_line.insert(pos,text); | ||||||
|  |     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()) { | ||||||
|  |                 current_style.releaseTextSegment(m_screen); | ||||||
|  |                 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++; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QString *Block::textLine() | ||||||
|  | { | ||||||
|  |     return &m_text_line; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::setVisible(bool visible) | ||||||
|  | { | ||||||
|  |     if (visible != m_visible) { | ||||||
|  |         m_changed = true; | ||||||
|  |         m_visible = visible; | ||||||
|  |         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(visible); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Block::visible() const | ||||||
|  | { | ||||||
|  |     return m_visible; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Block *Block::split(int line) | ||||||
|  | { | ||||||
|  |     if (line >= lineCount()) | ||||||
|  |         return nullptr; | ||||||
|  |     m_changed = true; | ||||||
|  |     Block *to_return = new Block(m_screen); | ||||||
|  |     int start_index = line * m_width; | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         ensureStyleAlignWithLines(i); | ||||||
|  |         TextStyleLine ¤t_style = m_style_list[i]; | ||||||
|  |         if (current_style.start_index >= start_index) { | ||||||
|  |             current_style.start_index -= start_index; | ||||||
|  |             current_style.old_index = current_style.start_index - 1; | ||||||
|  |             current_style.end_index -= start_index; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             current_style.text_dirty = true; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             to_return->m_style_list.append(TextStyleLine(current_style, current_style.start_index, | ||||||
|  |                         current_style.end_index)); | ||||||
|  |             m_style_list.remove(i); | ||||||
|  |             i--; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     to_return->m_text_line = m_text_line.mid(start_index, m_text_line.size() - start_index); | ||||||
|  |     m_text_line.remove(start_index, m_text_line.size() - start_index); | ||||||
|  |     return to_return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Block *Block::takeLine(int line) | ||||||
|  | { | ||||||
|  |     if (line >= lineCount()) | ||||||
|  |         return nullptr; | ||||||
|  |     m_changed = true; | ||||||
|  |     Block *to_return = new Block(m_screen); | ||||||
|  |     int start_index = line * m_width; | ||||||
|  |     int end_index = start_index + (m_width - 1); | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         ensureStyleAlignWithLines(i); | ||||||
|  |         TextStyleLine ¤t_style = m_style_list[i]; | ||||||
|  |         if (current_style.start_index >= start_index && current_style.end_index <= end_index) { | ||||||
|  |             current_style.releaseTextSegment(m_screen); | ||||||
|  |             current_style.start_index -= start_index; | ||||||
|  |             current_style.end_index -= start_index; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             to_return->m_style_list.append(TextStyleLine(current_style, current_style.start_index, | ||||||
|  |                         current_style.end_index)); | ||||||
|  |             m_style_list.remove(i); | ||||||
|  |             i--; | ||||||
|  |         } else if (current_style.start_index > end_index) { | ||||||
|  |             current_style.start_index -= (end_index + 1) - start_index; | ||||||
|  |             current_style.end_index -= (end_index + 1) - start_index; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             current_style.text_dirty = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     to_return->m_text_line = m_text_line.mid(start_index, m_width); | ||||||
|  |     m_text_line.remove(start_index, m_width); | ||||||
|  |     return to_return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::removeLine(int line) | ||||||
|  | { | ||||||
|  |     if (line >= lineCount()) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     m_changed = true; | ||||||
|  |     int start_index = line * m_width; | ||||||
|  |     int end_index = start_index + (m_width - 1); | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         ensureStyleAlignWithLines(i); | ||||||
|  |         TextStyleLine ¤t_style = m_style_list[i]; | ||||||
|  |         if (current_style.start_index >= start_index && current_style.end_index <= end_index) { | ||||||
|  |             current_style.releaseTextSegment(m_screen); | ||||||
|  |             m_style_list.remove(i); | ||||||
|  |             i--; | ||||||
|  |         } else if (current_style.start_index > end_index) { | ||||||
|  |             current_style.start_index -= (end_index + 1) - start_index; | ||||||
|  |             current_style.end_index -= (end_index + 1) - start_index; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             current_style.text_dirty = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     m_text_line.remove(start_index, m_width); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::moveLinesFromBlock(Block *block, int start_line, int count) | ||||||
|  | { | ||||||
|  |     Q_ASSERT(block); | ||||||
|  |     Q_ASSERT(block->lineCount() >= start_line + count); | ||||||
|  |  | ||||||
|  |     int start_char = block->width() * start_line; | ||||||
|  |     int end_char = (block->width() * (start_line + count)) - 1; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < block->m_style_list.size(); i++) { | ||||||
|  |         TextStyleLine ¤t_style = block->m_style_list[i]; | ||||||
|  |         if (current_style.start_index >= start_char && current_style.end_index <= end_char) { | ||||||
|  |             current_style.start_index += (-start_char + m_text_line.size()); | ||||||
|  |             current_style.end_index += (-start_char + m_text_line.size()); | ||||||
|  |             current_style.releaseTextSegment(m_screen); | ||||||
|  |             m_style_list.append(TextStyleLine(current_style, current_style.start_index, | ||||||
|  |                         current_style.end_index)); | ||||||
|  |             block->m_style_list.remove(i); | ||||||
|  |             i--; | ||||||
|  |         } else if (current_style.start_index > end_char) { | ||||||
|  |             current_style.start_index -= (end_char + 1) - start_char; | ||||||
|  |             current_style.end_index -= (end_char + 1) - start_char; | ||||||
|  |             current_style.index_dirty = true; | ||||||
|  |             current_style.text_dirty = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_text_line.append(block->m_text_line.mid(start_char, (end_char + 1) - start_char)); | ||||||
|  |     block->m_text_line.remove(start_char, (end_char + 1) - start_char); | ||||||
|  |     m_changed = true; | ||||||
|  |     block->m_changed = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::dispatchEvents() | ||||||
|  | { | ||||||
|  |     if (!m_changed) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     mergeCompatibleStyles(); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         ensureStyleAlignWithLines(i); | ||||||
|  |         TextStyleLine ¤t_style = m_style_list[i]; | ||||||
|  |          if (current_style.text_segment == 0) { | ||||||
|  |              current_style.text_segment = m_screen->createTextSegment(current_style); | ||||||
|  |             current_style.text_segment->setLine(m_new_line, m_width, &m_text_line); | ||||||
|  |          } else if (m_new_line != m_line) { | ||||||
|  |             current_style.text_segment->setLine(m_new_line, m_width, &m_text_line); | ||||||
|  |          } | ||||||
|  |  | ||||||
|  |         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; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         current_style.text_segment->setLatin(m_only_latin); | ||||||
|  |         current_style.text_segment->dispatchEvents(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_changed = false; | ||||||
|  |     m_line = m_new_line; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::releaseTextObjects() | ||||||
|  | { | ||||||
|  |     m_changed = true; | ||||||
|  |     for (int i = 0; i < m_style_list.size(); i++) { | ||||||
|  |         TextStyleLine ¤tStyleLine = m_style_list[i]; | ||||||
|  |         currentStyleLine.releaseTextSegment(m_screen); | ||||||
|  |         currentStyleLine.text_dirty = true; | ||||||
|  |         currentStyleLine.style_dirty = true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QVector<TextStyleLine> Block::style_list() | ||||||
|  | { | ||||||
|  |     return m_style_list; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::printStyleList() const | ||||||
|  | { | ||||||
|  |     QDebug debug = qDebug(); | ||||||
|  |     printStyleList(debug); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::printStyleList(QDebug &debug) const | ||||||
|  | { | ||||||
|  |     QString text_line = m_text_line; | ||||||
|  |     debug << "  " << m_line << lineCount() << m_text_line.size() << (void *) this << text_line << "\n"; debug << "\t"; | ||||||
|  |     for (int i= 0; i < m_style_list.size(); i++) { | ||||||
|  |         debug << m_style_list.at(i); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::printStyleListWidthText() const | ||||||
|  | { | ||||||
|  |     QString text_line = m_text_line; | ||||||
|  |     for (int i= 0; i < m_style_list.size(); i++) { | ||||||
|  |         const TextStyleLine ¤tStyle = m_style_list.at(i); | ||||||
|  |         QDebug debug = qDebug(); | ||||||
|  |         debug << m_text_line.mid(currentStyle.start_index, (currentStyle.end_index + 1) - currentStyle.start_index) << currentStyle; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::mergeCompatibleStyles() | ||||||
|  | { | ||||||
|  |     for (int i = 1; i < m_style_list.size(); i++) { | ||||||
|  |         TextStyleLine ¤t = m_style_list[i]; | ||||||
|  |         if (m_style_list.at(i - 1).isCompatible(current) && | ||||||
|  |                 current.start_index % m_width != 0) { | ||||||
|  |             TextStyleLine &prev = m_style_list[i-1]; | ||||||
|  |             prev.end_index = current.end_index; | ||||||
|  |             prev.text_dirty = true; | ||||||
|  |             current.releaseTextSegment(m_screen); | ||||||
|  |             m_style_list.remove(i); | ||||||
|  |             i--; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Block::ensureStyleAlignWithLines(int i) | ||||||
|  | { | ||||||
|  |     int start_line = m_style_list[i].start_index / m_width; | ||||||
|  |     int end_line = m_style_list[i].end_index / m_width; | ||||||
|  |     if (start_line != end_line) { | ||||||
|  |         int remainder_start_line = ((m_width * (start_line + 1))-1) - m_style_list[i].start_index; | ||||||
|  |         int next_line_end_index = m_style_list[i].end_index; | ||||||
|  |         m_style_list[i].end_index = m_style_list[i].start_index + remainder_start_line; | ||||||
|  |         m_style_list.insert(i + 1, TextStyleLine(m_style_list[i], m_style_list[i].end_index + 1, next_line_end_index)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								yat/backend/block.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								yat/backend/block.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * 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 BLOCK_H | ||||||
|  | #define BLOCK_H | ||||||
|  |  | ||||||
|  | #include <QtCore/QObject> | ||||||
|  |  | ||||||
|  | #include "text_style.h" | ||||||
|  |  | ||||||
|  | class Text; | ||||||
|  | class Screen; | ||||||
|  |  | ||||||
|  | class Block | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     Block(Screen *screen); | ||||||
|  |     ~Block(); | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE Screen *screen() const; | ||||||
|  |  | ||||||
|  |     void clear(); | ||||||
|  |     void clearToEnd(int from); | ||||||
|  |     void clearCharacters(int from, int to); | ||||||
|  |     void deleteCharacters(int from, int to); | ||||||
|  |     void deleteToEnd(int from); | ||||||
|  |     void deleteLines(int from); | ||||||
|  |  | ||||||
|  |     void replaceAtPos(int i, const QString &text, const TextStyle &style, bool only_latin = true); | ||||||
|  |     void insertAtPos(int i, const QString &text, const TextStyle &style, bool only_latin = true); | ||||||
|  |  | ||||||
|  |     void setScreenIndex(int index) { m_screen_index = index; } | ||||||
|  |     int screenIndex() const { return m_screen_index; } | ||||||
|  |     size_t line() { return m_new_line; } | ||||||
|  |     void setLine(size_t line) { | ||||||
|  |         if (line != m_new_line) { | ||||||
|  |             m_changed = true; | ||||||
|  |             m_new_line = line; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     QString *textLine(); | ||||||
|  |     int textSize() { return m_text_line.size(); } | ||||||
|  |  | ||||||
|  |     int width() const { return m_width; } | ||||||
|  |     void setWidth(int width) { m_changed = true; m_width = width; } | ||||||
|  |     int lineCount() const { return (std::max((m_text_line.size() - 1),0) / m_width) + 1; } | ||||||
|  |     int lineCountAfterModified(int from_char, int text_size, bool replace) { | ||||||
|  |         int new_size = replace ? std::max(from_char + text_size, m_text_line.size()) | ||||||
|  |             : std::max(from_char, m_text_line.size()) + text_size; | ||||||
|  |         return ((new_size - 1) / m_width) + 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void setVisible(bool visible); | ||||||
|  |     bool visible() const; | ||||||
|  |  | ||||||
|  |     Block *split(int line); | ||||||
|  |     Block *takeLine(int line); | ||||||
|  |     void removeLine(int line); | ||||||
|  |  | ||||||
|  |     void moveLinesFromBlock(Block *block, int start_line, int count); | ||||||
|  |  | ||||||
|  |     void dispatchEvents(); | ||||||
|  |     void releaseTextObjects(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list(); | ||||||
|  |  | ||||||
|  |     void printStyleList() const; | ||||||
|  |     void printStyleList(QDebug &debug) const; | ||||||
|  |     void printStyleListWidthText() const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void mergeCompatibleStyles(); | ||||||
|  |     void ensureStyleAlignWithLines(int i); | ||||||
|  |     Screen *m_screen; | ||||||
|  |     QString m_text_line; | ||||||
|  |     QVector<TextStyleLine> m_style_list; | ||||||
|  |     size_t m_line; | ||||||
|  |     size_t m_new_line; | ||||||
|  |     int m_screen_index; | ||||||
|  |  | ||||||
|  |     int m_width; | ||||||
|  |  | ||||||
|  |     bool m_visible; | ||||||
|  |     bool m_changed; | ||||||
|  |     bool m_only_latin; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // BLOCK_H | ||||||
							
								
								
									
										265
									
								
								yat/backend/character_sets.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								yat/backend/character_sets.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,265 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 <QtCore/QString> | ||||||
|  |  | ||||||
|  | static const  QChar dec_special_graphics_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020, | ||||||
|  |     /*0x60*/ 0x25c6,0x2592,0x2409,0x240c,0x240d,0x240a,0x00b0,0x00b1, | ||||||
|  |     /*0x68*/ 0x2424,0x240b,0x2518,0x2510,0x250c,0x2514,0x253c,0x23ba, | ||||||
|  |     /*0x70*/ 0x23bb,0x2500,0x23bc,0x23bd,0x251c,0x2524,0x2534,0x252c, | ||||||
|  |     /*0x78*/ 0x2502,0x2264,0x2265,0x03c0,0x2260,0x00a3,0x00b7,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_british_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00a3,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_norwegian_danish_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00c6,0x00d8,0x00c5,0x00dc,0x0000, | ||||||
|  |     /*0x60*/ 0x00e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e6,0x00f8,0x00e5,0x00fc,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_dutch_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00a3,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x00be,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x0133,0x00bd,0x007c,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00a8,0x0066,0x00bc,0x00b4,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_finnish_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00c4,0x00d6,0x00c5,0x00dc,0x0000, | ||||||
|  |     /*0x60*/ 0x00e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e4,0x00f6,0x00e5,0x00fc,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_french_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00a3,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00b0,0x00e7,0x00a7,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e9,0x00f9,0x00e8,0x00a8,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_french_canadian_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00e2,0x00e7,0x00ea,0x00ee,0x0000, | ||||||
|  |     /*0x60*/ 0x00f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e9,0x00f9,0x00e8,0x00fb,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_german_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00c4,0x00d6,0x00dc,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e4,0x00f6,0x00fc,0x00df,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_italian_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00a3,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00b0,0x00e7,0x00e9,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x00f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e0,0x00f2,0x00e8,0x00ec,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_spanish_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00a3,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00a1,0x00d1,0x00bf,0x0000,0x0000, | ||||||
|  |     /*0x60*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00b0,0x00f1,0x00e7,0x0000,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_swedish_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00c4,0x00d6,0x00c5,0x00dc,0x0000, | ||||||
|  |     /*0x60*/ 0x00e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e4,0x00f6,0x00e5,0x00fc,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const QChar nrc_swiss_char_set[] = | ||||||
|  | { | ||||||
|  |     /*0x00*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x08*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x10*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x18*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x20*/ 0x0000,0x0000,0x0000,0x00f9,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x28*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x30*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x38*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x40*/ 0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x48*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x50*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x58*/ 0x0000,0x0000,0x0000,0x00e9,0x00e7,0x00ea,0x00ee,0x00e8, | ||||||
|  |     /*0x60*/ 0x00f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x68*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x70*/ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||||||
|  |     /*0x78*/ 0x0000,0x0000,0x0000,0x00e4,0x00f6,0x00fc,0x00fb,0x0000, | ||||||
|  | }; | ||||||
|  |  | ||||||
							
								
								
									
										66
									
								
								yat/backend/color_palette.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								yat/backend/color_palette.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | #include "color_palette.h" | ||||||
|  |  | ||||||
|  | #include <QDebug> | ||||||
|  | ColorPalette::ColorPalette(QObject *parent) | ||||||
|  |     : QObject(parent) | ||||||
|  |     , m_normalColors(numberOfColors) | ||||||
|  |     , m_lightColors(numberOfColors) | ||||||
|  |     , m_intenseColors(numberOfColors) | ||||||
|  |     , m_inverse_default(false) | ||||||
|  | { | ||||||
|  |     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].setRgb(0,0,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 (m_inverse_default) { | ||||||
|  |         if (color == DefaultForground) | ||||||
|  |             color = DefaultBackground; | ||||||
|  |         else if (color == DefaultBackground) | ||||||
|  |             color = DefaultForground; | ||||||
|  |     } | ||||||
|  |     if (bold) | ||||||
|  |         return m_lightColors.at(color); | ||||||
|  |  | ||||||
|  |     return m_normalColors.at(color); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor ColorPalette::normalColor(ColorPalette::Color color) const | ||||||
|  | { | ||||||
|  |     return this->color(color, false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor ColorPalette::lightColor(ColorPalette::Color color) const | ||||||
|  | { | ||||||
|  |     return this->color(color,true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ColorPalette::setInverseDefaultColors(bool inverse) | ||||||
|  | { | ||||||
|  |     bool emit_changed = inverse != m_inverse_default; | ||||||
|  |     if (emit_changed) { | ||||||
|  |         m_inverse_default = inverse; | ||||||
|  |         emit changed(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								yat/backend/color_palette.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								yat/backend/color_palette.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | #ifndef COLOR_PALETTE_H | ||||||
|  | #define COLOR_PALETTE_H | ||||||
|  |  | ||||||
|  | #include <QtCore/QVector> | ||||||
|  |  | ||||||
|  | #include <QtGui/QColor> | ||||||
|  |  | ||||||
|  | class ColorPalette : public QObject | ||||||
|  | { | ||||||
|  | Q_OBJECT | ||||||
|  | public: | ||||||
|  |     ColorPalette(QObject *parent = 0); | ||||||
|  |  | ||||||
|  |     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; | ||||||
|  |  | ||||||
|  |     void setInverseDefaultColors(bool inverse); | ||||||
|  | signals: | ||||||
|  |     void changed(); | ||||||
|  | private: | ||||||
|  |     QVector<QColor> m_normalColors; | ||||||
|  |     QVector<QColor> m_lightColors; | ||||||
|  |     QVector<QColor> m_intenseColors; | ||||||
|  |  | ||||||
|  |     bool m_inverse_default; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // COLOR_PALETTE_H | ||||||
							
								
								
									
										798
									
								
								yat/backend/controll_chars.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										798
									
								
								yat/backend/controll_chars.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,798 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 ESC: | ||||||
|  |             debug << "ESC"; | ||||||
|  |             break; | ||||||
|  |         case SCS_G0: | ||||||
|  |             debug << "SCS_G0"; | ||||||
|  |             break; | ||||||
|  |         case SCS_G1: | ||||||
|  |             debug << "SCS_G1"; | ||||||
|  |             break; | ||||||
|  |         case SCS_G2: | ||||||
|  |             debug << "SCS_G2"; | ||||||
|  |             break; | ||||||
|  |         case SCS_G3: | ||||||
|  |             debug << "SCS_G3"; | ||||||
|  |             break; | ||||||
|  |         case DECSC: | ||||||
|  |             debug << "DECSC"; | ||||||
|  |             break; | ||||||
|  |         case DECRC: | ||||||
|  |             debug << "DECRC"; | ||||||
|  |             break; | ||||||
|  |         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 IND: | ||||||
|  |             debug << "IND"; | ||||||
|  |             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 DECSTBM: | ||||||
|  |             debug << "DECSTBM"; | ||||||
|  |             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; | ||||||
|  | } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										299
									
								
								yat/backend/controll_chars.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								yat/backend/controll_chars.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 = 0x1b, | ||||||
|  |     ESC = 0x1b, | ||||||
|  |     SCS_G0 = 0x28, | ||||||
|  |     SCS_G1 = 0x29, | ||||||
|  |     SCS_G2 = 0x2a, | ||||||
|  |     SCS_G3 = 0x2b, | ||||||
|  |     DECSC = 0x37, | ||||||
|  |     DECRC = 0x38, | ||||||
|  |     NOT_DEFINED = 0x40, | ||||||
|  |     NOT_DEFINED1 = 0x41, | ||||||
|  |     BPH = 0x42, | ||||||
|  |     NBH = 0x43, | ||||||
|  |     IND = 0x44, | ||||||
|  |     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 = 0x59, | ||||||
|  |     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, | ||||||
|  |     DECSTBM = 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 | ||||||
							
								
								
									
										542
									
								
								yat/backend/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								yat/backend/cursor.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,542 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 "cursor.h" | ||||||
|  |  | ||||||
|  | #include "block.h" | ||||||
|  | #include "screen_data.h" | ||||||
|  |  | ||||||
|  | #include <QTextCodec> | ||||||
|  |  | ||||||
|  | Cursor::Cursor(Screen* screen) | ||||||
|  |     : QObject(screen) | ||||||
|  |     , m_screen(screen) | ||||||
|  |     , m_current_text_style(screen->defaultTextStyle()) | ||||||
|  |     , m_position(0,0) | ||||||
|  |     , m_new_position(0,0) | ||||||
|  |     , m_document_width(screen->width()) | ||||||
|  |     , m_document_height(screen->height()) | ||||||
|  |     , m_top_margin(0) | ||||||
|  |     , m_bottom_margin(0) | ||||||
|  |     , m_scroll_margins_set(false) | ||||||
|  |     , m_origin_at_margin(false) | ||||||
|  |     , m_notified(false) | ||||||
|  |     , m_visible(true) | ||||||
|  |     , m_new_visibillity(true) | ||||||
|  |     , m_blinking(false) | ||||||
|  |     , m_new_blinking(false) | ||||||
|  |     , m_wrap_around(true) | ||||||
|  |     , m_content_height_changed(false) | ||||||
|  |     , m_insert_mode(Replace) | ||||||
|  | { | ||||||
|  |     connect(screen, SIGNAL(widthAboutToChange(int)), this, SLOT(setDocumentWidth(int))); | ||||||
|  |     connect(screen, SIGNAL(heightAboutToChange(int, int, int)), this, SLOT(setDocumentHeight(int, int, int))); | ||||||
|  |     connect(screen, SIGNAL(contentHeightChanged()), this, SLOT(contentHeightChanged())); | ||||||
|  |  | ||||||
|  |     m_gl_text_codec = QTextCodec::codecForName("utf-8")->makeDecoder(); | ||||||
|  |     m_gr_text_codec = QTextCodec::codecForName("utf-8")->makeDecoder(); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_document_width; i++) { | ||||||
|  |         if (i % 8 == 0) { | ||||||
|  |             m_tab_stops.append(i); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Cursor::~Cursor() | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setDocumentWidth(int width) | ||||||
|  | { | ||||||
|  |     if (width > m_document_width) { | ||||||
|  |         for (int i = m_document_width -1; i < width; i++) { | ||||||
|  |             if (i % 8 == 0) { | ||||||
|  |                 m_tab_stops.append(i); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_document_width = width; | ||||||
|  |     if (new_x() >= width) { | ||||||
|  |         new_rx() = width - 1; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setDocumentHeight(int height, int currentCursorBlock, int currentScrollBackHeight) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(currentCursorBlock); | ||||||
|  |     resetScrollArea(); | ||||||
|  |     if (m_document_height > height) { | ||||||
|  |         const int to_remove = m_document_height - height; | ||||||
|  |         const int removeLinesBelowCursor = | ||||||
|  |             std::min(m_document_height - new_y(), to_remove); | ||||||
|  |         const int removeLinesAtTop = to_remove - removeLinesBelowCursor; | ||||||
|  |         if (!removeLinesAtTop) { | ||||||
|  |             new_ry() -= removeLinesAtTop; | ||||||
|  |             notifyChanged(); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         int height_diff = height - m_document_height; | ||||||
|  |         if (currentScrollBackHeight >= height_diff) { | ||||||
|  |             new_ry() += height_diff; | ||||||
|  |         } else if (currentScrollBackHeight > 0) { | ||||||
|  |             const int move = height_diff - currentScrollBackHeight; | ||||||
|  |             new_ry() += move; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_document_height = height; | ||||||
|  |  | ||||||
|  |     if (new_y() >= height) { | ||||||
|  |         new_ry() = height - 1; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  |     if (new_y() <= 0) { | ||||||
|  |         new_ry() = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Cursor::visible() const | ||||||
|  | { | ||||||
|  |     return m_visible; | ||||||
|  | } | ||||||
|  | void Cursor::setVisible(bool visible) | ||||||
|  | { | ||||||
|  |     m_new_visibillity = visible; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Cursor::blinking() const | ||||||
|  | { | ||||||
|  |     return m_blinking; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setBlinking(bool blinking) | ||||||
|  | { | ||||||
|  |     m_new_blinking = blinking; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setTextStyle(TextStyle::Style style, bool add) | ||||||
|  | { | ||||||
|  |     if (add) { | ||||||
|  |         m_current_text_style.style |= style; | ||||||
|  |     } else { | ||||||
|  |         m_current_text_style.style &= !style; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::resetStyle() | ||||||
|  | { | ||||||
|  |     m_current_text_style.background = ColorPalette::DefaultBackground; | ||||||
|  |     m_current_text_style.forground = ColorPalette::DefaultForground; | ||||||
|  |     m_current_text_style.style = TextStyle::Normal; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::scrollUp(int lines) | ||||||
|  | { | ||||||
|  |     if (new_y() < top() || new_y() > bottom()) | ||||||
|  |             return; | ||||||
|  |     for (int i = 0; i < lines; i++) { | ||||||
|  |         screen_data()->moveLine(bottom(), top()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::scrollDown(int lines) | ||||||
|  | { | ||||||
|  |     if (new_y() < top() || new_y() > bottom()) | ||||||
|  |         return; | ||||||
|  |     for (int i = 0; i < lines; i++) { | ||||||
|  |         screen_data()->moveLine(top(), bottom()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setTextCodec(QTextCodec *codec) | ||||||
|  | { | ||||||
|  |     m_gl_text_codec = codec->makeDecoder(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setInsertMode(InsertMode mode) | ||||||
|  | { | ||||||
|  |     m_insert_mode = mode; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TextStyle Cursor::currentTextStyle() const | ||||||
|  | { | ||||||
|  |     return m_current_text_style; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::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"; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ColorPalette *Cursor::colorPalette() const | ||||||
|  | { | ||||||
|  |     return m_screen->colorPalette(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QPoint Cursor::position() const | ||||||
|  | { | ||||||
|  |     return m_position; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Cursor::x() const | ||||||
|  | { | ||||||
|  |     return m_position.x(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Cursor::y() const | ||||||
|  | { | ||||||
|  |     return (m_screen->currentScreenData()->contentHeight() - m_screen->height()) + m_position.y(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveOrigin() | ||||||
|  | { | ||||||
|  |     m_new_position = QPoint(0,adjusted_top()); | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveBeginningOfLine() | ||||||
|  | { | ||||||
|  |     new_rx() = 0; | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveUp(int lines) | ||||||
|  | { | ||||||
|  |     int adjusted_new_y = this->adjusted_new_y(); | ||||||
|  |     if (!adjusted_new_y || !lines) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (lines < adjusted_new_y) { | ||||||
|  |         new_ry() -= lines; | ||||||
|  |     } else { | ||||||
|  |         new_ry() = adjusted_top(); | ||||||
|  |     } | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveDown(int lines) | ||||||
|  | { | ||||||
|  |     int bottom = adjusted_bottom(); | ||||||
|  |     if (new_y() == bottom || !lines) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (new_y() + lines <= bottom) { | ||||||
|  |         new_ry() += lines; | ||||||
|  |     } else { | ||||||
|  |         new_ry() = bottom; | ||||||
|  |     } | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveLeft(int positions) | ||||||
|  | { | ||||||
|  |     if (!new_x() || !positions) | ||||||
|  |         return; | ||||||
|  |     if (positions < new_x()) { | ||||||
|  |         new_rx() -= positions; | ||||||
|  |     } else { | ||||||
|  |         new_rx() = 0; | ||||||
|  |     } | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveRight(int positions) | ||||||
|  | { | ||||||
|  |     int width = m_screen->width(); | ||||||
|  |     if (new_x() == width -1 || !positions) | ||||||
|  |         return; | ||||||
|  |     if (positions < width - new_x()) { | ||||||
|  |         new_rx() += positions; | ||||||
|  |     } else { | ||||||
|  |         new_rx() = width -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::move(int new_x, int new_y) | ||||||
|  | { | ||||||
|  |     int width = m_screen->width(); | ||||||
|  |  | ||||||
|  |     if (m_origin_at_margin) { | ||||||
|  |         new_y += m_top_margin; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (new_x < 0) { | ||||||
|  |         new_x = 0; | ||||||
|  |     } else if (new_x >= width) { | ||||||
|  |         new_x = width - 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (new_y < adjusted_top()) { | ||||||
|  |         new_y = adjusted_top(); | ||||||
|  |     } else if (new_y > adjusted_bottom()) { | ||||||
|  |         new_y = adjusted_bottom(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (this->new_y() != new_y || this->new_x() != new_x) { | ||||||
|  |         m_new_position = QPoint(new_x, new_y); | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveToLine(int line) | ||||||
|  | { | ||||||
|  |     const int height = m_screen->height(); | ||||||
|  |     if (line < adjusted_top()) { | ||||||
|  |         line = 0; | ||||||
|  |     } else if (line > adjusted_bottom()) { | ||||||
|  |         line = height -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (line != new_y()) { | ||||||
|  |         new_rx() = line; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveToCharacter(int character) | ||||||
|  | { | ||||||
|  |     const int width = m_screen->width(); | ||||||
|  |     if (character < 0) { | ||||||
|  |         character = 1; | ||||||
|  |     } else if (character > width) { | ||||||
|  |         character = width; | ||||||
|  |     } | ||||||
|  |     if (character != new_x()) { | ||||||
|  |         new_rx() = character; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::moveToNextTab() | ||||||
|  | { | ||||||
|  |     for (int i = 0; i < m_tab_stops.size(); i++) { | ||||||
|  |         if (new_x() < m_tab_stops.at(i)) { | ||||||
|  |             moveToCharacter(std::min(m_tab_stops.at(i), m_document_width -1)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     moveToCharacter(m_document_width - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setTabStop() | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     for (i = 0; i < m_tab_stops.size(); i++) { | ||||||
|  |         if (new_x() == m_tab_stops.at(i)) | ||||||
|  |             return; | ||||||
|  |         if (new_x() > m_tab_stops.at(i)) { | ||||||
|  |             continue; | ||||||
|  |         } else { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     m_tab_stops.insert(i,new_x()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::removeTabStop() | ||||||
|  | { | ||||||
|  |     for (int i = 0; i < m_tab_stops.size(); i++) { | ||||||
|  |         if (new_x() == m_tab_stops.at(i)) { | ||||||
|  |             m_tab_stops.remove(i); | ||||||
|  |             return; | ||||||
|  |         } else if (new_x() < m_tab_stops.at(i)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearTabStops() | ||||||
|  | { | ||||||
|  |     m_tab_stops.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearToBeginningOfLine() | ||||||
|  | { | ||||||
|  |     screen_data()->clearToBeginningOfLine(m_new_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearToEndOfLine() | ||||||
|  | { | ||||||
|  |     screen_data()->clearToEndOfLine(m_new_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearToBeginningOfScreen() | ||||||
|  | { | ||||||
|  |     clearToBeginningOfLine(); | ||||||
|  |     if (new_y() > 0) | ||||||
|  |         screen_data()->clearToBeginningOfScreen(m_new_position.y()-1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearToEndOfScreen() | ||||||
|  | { | ||||||
|  |     clearToEndOfLine(); | ||||||
|  |     if (new_y() < m_screen->height() -1) { | ||||||
|  |         screen_data()->clearToEndOfScreen(m_new_position.y()+1); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::clearLine() | ||||||
|  | { | ||||||
|  |     screen_data()->clearLine(m_new_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::deleteCharacters(int characters) | ||||||
|  | { | ||||||
|  |     screen_data()->deleteCharacters(m_new_position, new_x() + characters -1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setWrapAround(bool wrap) | ||||||
|  | { | ||||||
|  |     m_wrap_around = wrap; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::addAtCursor(const QByteArray &data, bool only_latin) | ||||||
|  | { | ||||||
|  |     if (m_insert_mode == Replace) { | ||||||
|  |         replaceAtCursor(data, only_latin); | ||||||
|  |     } else { | ||||||
|  |         insertAtCursor(data, only_latin); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::replaceAtCursor(const QByteArray &data, bool only_latin) | ||||||
|  | { | ||||||
|  |     const QString text = m_gl_text_codec->toUnicode(data); | ||||||
|  |  | ||||||
|  |     if (!m_wrap_around && new_x() + text.size() > m_screen->width()) { | ||||||
|  |         const int size = m_document_width - new_x(); | ||||||
|  |         QString toBlock = text.mid(0,size); | ||||||
|  |         toBlock.replace(toBlock.size() - 1, 1, text.at(text.size()-1)); | ||||||
|  |         screen_data()->replace(m_new_position, toBlock, m_current_text_style, only_latin); | ||||||
|  |         new_rx() += toBlock.size(); | ||||||
|  |     } else { | ||||||
|  |         auto diff = screen_data()->replace(m_new_position, text, m_current_text_style, only_latin); | ||||||
|  |         new_rx() += diff.character; | ||||||
|  |         new_ry() += diff.line; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (new_y() >= m_document_height) | ||||||
|  |         new_ry() = m_document_height - 1; | ||||||
|  |  | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::insertAtCursor(const QByteArray &data, bool only_latin) | ||||||
|  | { | ||||||
|  |     const QString text = m_gl_text_codec->toUnicode(data); | ||||||
|  |     auto diff = screen_data()->insert(m_new_position, text, m_current_text_style, only_latin); | ||||||
|  |     new_rx() += diff.character; | ||||||
|  |     new_ry() += diff.line; | ||||||
|  |     if (new_y() >= m_document_height) | ||||||
|  |         new_ry() = m_document_height - 1; | ||||||
|  |     if (new_x() >= m_document_width) | ||||||
|  |         new_rx() = m_document_width - 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::lineFeed() | ||||||
|  | { | ||||||
|  |     if(new_y() >= bottom()) { | ||||||
|  |         screen_data()->insertLine(bottom(), top()); | ||||||
|  |     } else { | ||||||
|  |         new_ry()++; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::reverseLineFeed() | ||||||
|  | { | ||||||
|  |     if (new_y() == top()) { | ||||||
|  |         scrollUp(1); | ||||||
|  |     } else { | ||||||
|  |         new_ry()--; | ||||||
|  |         notifyChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setOriginAtMargin(bool atMargin) | ||||||
|  | { | ||||||
|  |     m_origin_at_margin = atMargin; | ||||||
|  |     m_new_position = QPoint(0, adjusted_top()); | ||||||
|  |     notifyChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::setScrollArea(int from, int to) | ||||||
|  | { | ||||||
|  |     m_top_margin = from; | ||||||
|  |     m_bottom_margin = std::min(to,m_document_height -1); | ||||||
|  |     m_scroll_margins_set = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::resetScrollArea() | ||||||
|  | { | ||||||
|  |     m_top_margin = 0; | ||||||
|  |     m_bottom_margin = 0; | ||||||
|  |     m_scroll_margins_set = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::dispatchEvents() | ||||||
|  | { | ||||||
|  |     if (m_new_position != m_position|| m_content_height_changed) { | ||||||
|  |         bool emit_x_changed = m_new_position.x() != m_position.x(); | ||||||
|  |         bool emit_y_changed = m_new_position.y() != m_position.y(); | ||||||
|  |         m_position = m_new_position; | ||||||
|  |         if (emit_x_changed) | ||||||
|  |             emit xChanged(); | ||||||
|  |         if (emit_y_changed || m_content_height_changed) | ||||||
|  |             emit yChanged(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_new_visibillity != m_visible) { | ||||||
|  |         m_visible = m_new_visibillity; | ||||||
|  |         emit visibilityChanged(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_new_blinking != m_blinking) { | ||||||
|  |         m_blinking = m_new_blinking; | ||||||
|  |         emit blinkingChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Cursor::contentHeightChanged() | ||||||
|  | { | ||||||
|  |     m_content_height_changed = true; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										175
									
								
								yat/backend/cursor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								yat/backend/cursor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 CURSOR_H | ||||||
|  | #define CURSOR_H | ||||||
|  |  | ||||||
|  | #include "text_style.h" | ||||||
|  | #include "screen.h" | ||||||
|  |  | ||||||
|  | #include <QtCore/QObject> | ||||||
|  |  | ||||||
|  | class Cursor : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  |     Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibilityChanged) | ||||||
|  |     Q_PROPERTY(bool blinking READ blinking WRITE setBlinking NOTIFY blinkingChanged) | ||||||
|  |     Q_PROPERTY(int x READ x NOTIFY xChanged) | ||||||
|  |     Q_PROPERTY(int y READ y NOTIFY yChanged) | ||||||
|  | public: | ||||||
|  |     enum InsertMode { | ||||||
|  |         Insert, | ||||||
|  |         Replace | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     Cursor(Screen *screen); | ||||||
|  |     ~Cursor(); | ||||||
|  |  | ||||||
|  |     bool visible() const; | ||||||
|  |     void setVisible(bool visible); | ||||||
|  |  | ||||||
|  |     bool blinking() const; | ||||||
|  |     void setBlinking(bool blinking); | ||||||
|  |  | ||||||
|  |     void setTextStyle(TextStyle::Style style, bool add = true); | ||||||
|  |     void resetStyle(); | ||||||
|  |     TextStyle currentTextStyle() const; | ||||||
|  |  | ||||||
|  |     void setTextStyleColor(ushort color); | ||||||
|  |     ColorPalette *colorPalette() const; | ||||||
|  |  | ||||||
|  |     QPoint position() const; | ||||||
|  |     int x() const; | ||||||
|  |     int y() const; | ||||||
|  |     int new_x() const { return m_new_position.x(); } | ||||||
|  |     int new_y() const { return m_new_position.y(); } | ||||||
|  |  | ||||||
|  |     void moveOrigin(); | ||||||
|  |     void moveBeginningOfLine(); | ||||||
|  |     void moveUp(int lines = 1); | ||||||
|  |     void moveDown(int lines = 1); | ||||||
|  |     void moveLeft(int positions = 1); | ||||||
|  |     void moveRight(int positions = 1); | ||||||
|  |     void move(int new_x, int new_y); | ||||||
|  |     void moveToLine(int line); | ||||||
|  |     void moveToCharacter(int character); | ||||||
|  |  | ||||||
|  |     void moveToNextTab(); | ||||||
|  |     void setTabStop(); | ||||||
|  |     void removeTabStop(); | ||||||
|  |     void clearTabStops(); | ||||||
|  |  | ||||||
|  |     void clearToBeginningOfLine(); | ||||||
|  |     void clearToEndOfLine(); | ||||||
|  |     void clearToBeginningOfScreen(); | ||||||
|  |     void clearToEndOfScreen(); | ||||||
|  |     void clearLine(); | ||||||
|  |  | ||||||
|  |     void deleteCharacters(int characters); | ||||||
|  |  | ||||||
|  |     void setWrapAround(bool wrap); | ||||||
|  |     void addAtCursor(const QByteArray &text, bool only_latin = true); | ||||||
|  |     void insertAtCursor(const QByteArray &text, bool only_latin = true); | ||||||
|  |     void replaceAtCursor(const QByteArray &text, bool only_latin = true); | ||||||
|  |  | ||||||
|  |     void lineFeed(); | ||||||
|  |     void reverseLineFeed(); | ||||||
|  |  | ||||||
|  |     void setOriginAtMargin(bool atMargin); | ||||||
|  |     void setScrollArea(int from, int to); | ||||||
|  |     void resetScrollArea(); | ||||||
|  |  | ||||||
|  |     void scrollUp(int lines); | ||||||
|  |     void scrollDown(int lines); | ||||||
|  |  | ||||||
|  |     void setTextCodec(QTextCodec *codec); | ||||||
|  |  | ||||||
|  |     void setInsertMode(InsertMode mode); | ||||||
|  |  | ||||||
|  |     inline void notifyChanged(); | ||||||
|  |     void dispatchEvents(); | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  |     void setDocumentWidth(int width); | ||||||
|  |     void setDocumentHeight(int height, int currentCursorBlock, int currentScrollBackHeight); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void xChanged(); | ||||||
|  |     void yChanged(); | ||||||
|  |     void visibilityChanged(); | ||||||
|  |     void blinkingChanged(); | ||||||
|  |  | ||||||
|  | private slots: | ||||||
|  |     void contentHeightChanged(); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     ScreenData *screen_data() const { return m_screen->currentScreenData(); } | ||||||
|  |     int &new_rx() { return m_new_position.rx(); } | ||||||
|  |     int &new_ry() { return m_new_position.ry(); } | ||||||
|  |     int adjusted_new_x() const { return m_origin_at_margin ? | ||||||
|  |         m_new_position.x() - m_top_margin : m_new_position.x(); } | ||||||
|  |     int adjusted_new_y() const { return m_origin_at_margin ? | ||||||
|  |         m_new_position.y() - m_top_margin : m_new_position.y(); } | ||||||
|  |     int adjusted_top() const { return m_origin_at_margin ? m_top_margin : 0; } | ||||||
|  |     int adjusted_bottom() const { return m_origin_at_margin ? m_bottom_margin : m_document_height - 1; } | ||||||
|  |     int top() const { return m_scroll_margins_set ? m_top_margin : 0; } | ||||||
|  |     int bottom() const { return m_scroll_margins_set ? m_bottom_margin : m_document_height - 1; } | ||||||
|  |     Screen *m_screen; | ||||||
|  |     TextStyle m_current_text_style; | ||||||
|  |     QPoint m_position; | ||||||
|  |     QPoint m_new_position; | ||||||
|  |  | ||||||
|  |     int m_document_width; | ||||||
|  |     int m_document_height; | ||||||
|  |  | ||||||
|  |     int m_top_margin; | ||||||
|  |     int m_bottom_margin; | ||||||
|  |     bool m_scroll_margins_set; | ||||||
|  |     bool m_origin_at_margin; | ||||||
|  |  | ||||||
|  |     QVector<int> m_tab_stops; | ||||||
|  |  | ||||||
|  |     bool m_notified; | ||||||
|  |     bool m_visible; | ||||||
|  |     bool m_new_visibillity; | ||||||
|  |     bool m_blinking; | ||||||
|  |     bool m_new_blinking; | ||||||
|  |     bool m_wrap_around; | ||||||
|  |     bool m_content_height_changed; | ||||||
|  |  | ||||||
|  |     QTextDecoder *m_gl_text_codec; | ||||||
|  |     QTextDecoder *m_gr_text_codec; | ||||||
|  |  | ||||||
|  |     InsertMode m_insert_mode; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void Cursor::notifyChanged() | ||||||
|  | { | ||||||
|  |     if (!m_notified) { | ||||||
|  |         m_notified = true; | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif //CUROSOR_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(); | ||||||
|  | } | ||||||
							
								
								
									
										124
									
								
								yat/backend/nrc_text_codec.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								yat/backend/nrc_text_codec.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 "nrc_text_codec.h" | ||||||
|  |  | ||||||
|  | static bool nrc_text_codec_init = false; | ||||||
|  | void NrcTextCodec::initialize() | ||||||
|  | { | ||||||
|  |     if (!nrc_text_codec_init) { | ||||||
|  |         nrc_text_codec_init = true; | ||||||
|  |         new NrcTextCodec("dec_special_graphics", 500001, dec_special_graphics_char_set); | ||||||
|  |         new NrcTextCodec("nrc_british", 500002, nrc_british_char_set); | ||||||
|  |         new NrcTextCodec("nrc_norwegian_danish", 5002, nrc_norwegian_danish_char_set); | ||||||
|  |         new NrcTextCodec("nrc_dutch", 5002, nrc_dutch_char_set); | ||||||
|  |         new NrcTextCodec("nrc_finnish", 5002, nrc_finnish_char_set); | ||||||
|  |         new NrcTextCodec("nrc_french", 5002, nrc_french_char_set); | ||||||
|  |         new NrcTextCodec("nrc_french_canadian", 5002, nrc_french_canadian_char_set); | ||||||
|  |         new NrcTextCodec("nrc_german", 5002, nrc_german_char_set); | ||||||
|  |         new NrcTextCodec("nrc_italian", 5002, nrc_italian_char_set); | ||||||
|  |         new NrcTextCodec("nrc_spanish", 5002, nrc_spanish_char_set); | ||||||
|  |         new NrcTextCodec("nrc_swedish", 5002, nrc_swedish_char_set); | ||||||
|  |         new NrcTextCodec("nrc_swiss", 5002, nrc_swiss_char_set); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NrcTextCodec::NrcTextCodec(const QByteArray &name, int mib, const QChar character_set[]) | ||||||
|  |     : QTextCodec() | ||||||
|  |     , m_name(name) | ||||||
|  |     , m_mib(mib) | ||||||
|  |     , m_character_set(character_set) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QByteArray  NrcTextCodec::name() const | ||||||
|  | { | ||||||
|  |     return m_name; | ||||||
|  | } | ||||||
|  | int NrcTextCodec::mibEnum() const | ||||||
|  | { | ||||||
|  |     return m_mib; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QString NrcTextCodec::convertToUnicode(const char *in, int length, QTextCodec::ConverterState *state) const | ||||||
|  | { | ||||||
|  |     QString ret_str; | ||||||
|  |     ret_str.reserve(length); | ||||||
|  |     for (int i = 0; i < length; i++) { | ||||||
|  |         uchar in_char = *(in + i); | ||||||
|  |         if (in_char < 128) { | ||||||
|  |             QChar unicode = m_character_set[in_char]; | ||||||
|  |             if (unicode.isNull()) | ||||||
|  |                 unicode = QChar(in_char); | ||||||
|  |             ret_str.append(unicode); | ||||||
|  |         } else { | ||||||
|  |             if (state) { | ||||||
|  |                 if (state->flags & QTextCodec::ConvertInvalidToNull) { | ||||||
|  |                     state->invalidChars++; | ||||||
|  |                     ret_str.append(0); | ||||||
|  |                 } else { | ||||||
|  |                     state->invalidChars++; | ||||||
|  |                     state->remainingChars = length - i; | ||||||
|  |                     return ret_str; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return ret_str; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QByteArray NrcTextCodec::convertFromUnicode(const QChar *in, int length, ConverterState *state) const | ||||||
|  | { | ||||||
|  |     QByteArray ret_array; | ||||||
|  |     ret_array.reserve(length); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < length; i++) { | ||||||
|  |         QChar out_char = *(in + i); | ||||||
|  |         if (out_char.unicode() < 128) { | ||||||
|  |             uchar out = out_char.unicode(); | ||||||
|  |             ret_array.append(out); | ||||||
|  |         } else { | ||||||
|  |             bool found = false; | ||||||
|  |             for (uchar n = 0; n < 128; n++) { | ||||||
|  |                 if (m_character_set[n] == out_char) { | ||||||
|  |                     ret_array.append(n); | ||||||
|  |                     found = true; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (!found && state) { | ||||||
|  |                 if (state->flags & QTextCodec::ConvertInvalidToNull) { | ||||||
|  |                     state->invalidChars++; | ||||||
|  |                     ret_array.append(char(0)); | ||||||
|  |                 } else { | ||||||
|  |                     state->invalidChars++; | ||||||
|  |                     state->remainingChars = length - i; | ||||||
|  |                     return ret_array; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return ret_array; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										45
									
								
								yat/backend/nrc_text_codec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								yat/backend/nrc_text_codec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 "character_sets.h" | ||||||
|  |  | ||||||
|  | #include <QtCore/QString> | ||||||
|  | #include <QtCore/QTextCodec> | ||||||
|  |  | ||||||
|  | class NrcTextCodec : public QTextCodec | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     NrcTextCodec(const QByteArray &name, int mib, const QChar character_set[]); | ||||||
|  |     QByteArray  name() const; | ||||||
|  |     int mibEnum() const; | ||||||
|  |  | ||||||
|  |     static void initialize(); | ||||||
|  | protected: | ||||||
|  |     QString convertToUnicode(const char *in, int length, ConverterState *state) const; | ||||||
|  |     QByteArray convertFromUnicode(const QChar *in, int length, ConverterState *state) const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     const QByteArray m_name; | ||||||
|  |     const int m_mib; | ||||||
|  |     const QChar *m_character_set; | ||||||
|  | }; | ||||||
							
								
								
									
										1329
									
								
								yat/backend/parser.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1329
									
								
								yat/backend/parser.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										110
									
								
								yat/backend/parser.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								yat/backend/parser.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 "controll_chars.h" | ||||||
|  | #include "utf8_decoder.h" | ||||||
|  |  | ||||||
|  | class Screen; | ||||||
|  |  | ||||||
|  | class Parser | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     Parser(Screen *screen); | ||||||
|  |  | ||||||
|  |     void addData(const QByteArray &data); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  |     enum DecodeState { | ||||||
|  |         PlainText, | ||||||
|  |         DecodeC0, | ||||||
|  |         DecodeC1_7bit, | ||||||
|  |         DecodeCSI, | ||||||
|  |         DecodeOSC, | ||||||
|  |         DecodeCharacterSet, | ||||||
|  |         DecodeFontSize | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     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 decodeCharacterSet(uchar character); | ||||||
|  |     void decodeFontSize(uchar character); | ||||||
|  |  | ||||||
|  |     void setMode(int mode); | ||||||
|  |     void setDecMode(int mode); | ||||||
|  |     void resetMode(int mode); | ||||||
|  |     void resetDecMode(int mode); | ||||||
|  |  | ||||||
|  |     void handleSGR(); | ||||||
|  |  | ||||||
|  |     void tokenFinished(); | ||||||
|  |  | ||||||
|  |     void appendParameter(); | ||||||
|  |     void handleDefaultParameters(int defaultValue); | ||||||
|  |  | ||||||
|  |     DecodeState m_decode_state; | ||||||
|  |     DecodeOSCState m_decode_osc_state; | ||||||
|  |  | ||||||
|  |     QByteArray m_current_data; | ||||||
|  |  | ||||||
|  |     int m_current_token_start; | ||||||
|  |     int m_current_position; | ||||||
|  |  | ||||||
|  |     QChar m_intermediate_char; | ||||||
|  |  | ||||||
|  |     QByteArray m_parameter_string; | ||||||
|  |     QVector<int> m_parameters; | ||||||
|  |     bool m_parameters_expecting_more; | ||||||
|  |     bool m_dec_mode; | ||||||
|  |     bool m_gt_param; | ||||||
|  |     bool m_lnm_mode_set; | ||||||
|  |     bool m_contains_only_latin; | ||||||
|  |  | ||||||
|  |     int m_decode_graphics_set; | ||||||
|  |     QTextCodec *m_graphic_codecs[4]; | ||||||
|  |     Utf8Decoder m_utf8_decoder; | ||||||
|  |  | ||||||
|  |     Screen *m_screen; | ||||||
|  |     friend QDebug operator<<(QDebug debug, DecodeState decodeState); | ||||||
|  | }; | ||||||
|  | QDebug operator<<(QDebug debug, Parser::DecodeState decodeState); | ||||||
|  |  | ||||||
|  | #endif // PARSER_H | ||||||
							
								
								
									
										620
									
								
								yat/backend/screen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										620
									
								
								yat/backend/screen.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,620 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  |  * 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 "screen_data.h" | ||||||
|  | #include "block.h" | ||||||
|  | #include "cursor.h" | ||||||
|  | #include "text.h" | ||||||
|  | #include "scrollback.h" | ||||||
|  | #include "selection.h" | ||||||
|  |  | ||||||
|  | #include "controll_chars.h" | ||||||
|  | #include "character_sets.h" | ||||||
|  |  | ||||||
|  | #include <QtCore/QTimer> | ||||||
|  | #include <QtCore/QSocketNotifier> | ||||||
|  | #include <QtGui/QGuiApplication> | ||||||
|  |  | ||||||
|  | #include <QtCore/QDebug> | ||||||
|  |  | ||||||
|  | #include <float.h> | ||||||
|  |  | ||||||
|  | Screen::Screen(QObject *parent) | ||||||
|  |     : QObject(parent) | ||||||
|  |     , m_palette(new ColorPalette(this)) | ||||||
|  |     , m_parser(this) | ||||||
|  |     , m_timer_event_id(0) | ||||||
|  |     , m_width(1) | ||||||
|  |     , m_height(0) | ||||||
|  |     , m_primary_data(new ScreenData(500, this)) | ||||||
|  |     , m_alternate_data(new ScreenData(0, this)) | ||||||
|  |     , m_current_data(m_primary_data) | ||||||
|  |     , m_old_current_data(m_primary_data) | ||||||
|  |     , m_selection(new Selection(this)) | ||||||
|  |     , m_flash(false) | ||||||
|  |     , m_cursor_changed(false) | ||||||
|  |     , m_application_cursor_key_mode(false) | ||||||
|  |     , m_fast_scroll(true) | ||||||
|  |     , m_default_background(m_palette->normalColor(ColorPalette::DefaultBackground)) | ||||||
|  | { | ||||||
|  |     Cursor *cursor = new Cursor(this); | ||||||
|  |     m_cursor_stack << cursor; | ||||||
|  |     m_new_cursors << cursor; | ||||||
|  |  | ||||||
|  |     connect(m_primary_data, SIGNAL(contentHeightChanged()), this, SIGNAL(contentHeightChanged())); | ||||||
|  |     connect(m_primary_data, &ScreenData::contentModified, | ||||||
|  |             this, &Screen::contentModified); | ||||||
|  |     connect(m_palette, SIGNAL(changed()), this, SLOT(paletteChanged())); | ||||||
|  |  | ||||||
|  |     setHeight(25); | ||||||
|  |     setWidth(80); | ||||||
|  |  | ||||||
|  |     connect(&m_pty, &YatPty::readyRead, this, &Screen::readData); | ||||||
|  |     connect(&m_pty, SIGNAL(hangupReceived()),qGuiApp, SLOT(quit())); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Screen::~Screen() | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     for(int i = 0; i < m_to_delete.size(); i++) { | ||||||
|  |         delete m_to_delete.at(i); | ||||||
|  |     } | ||||||
|  |     //m_to_delete.clear(); | ||||||
|  |  | ||||||
|  |     delete m_primary_data; | ||||||
|  |     delete m_alternate_data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | QColor Screen::defaultForgroundColor() const | ||||||
|  | { | ||||||
|  |     return m_palette->normalColor(ColorPalette::DefaultForground); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor Screen::defaultBackgroundColor() const | ||||||
|  | { | ||||||
|  |     return m_palette->normalColor(ColorPalette::DefaultBackground); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::emitRequestHeight(int newHeight) | ||||||
|  | { | ||||||
|  |     emit requestHeightChange(newHeight); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::setHeight(int height) | ||||||
|  | { | ||||||
|  |     if (height == m_height) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     emit heightAboutToChange(height, currentCursor()->new_y(), currentScreenData()->scrollback()->height()); | ||||||
|  |  | ||||||
|  |     m_height = height; | ||||||
|  |  | ||||||
|  |     m_pty.setHeight(height, height * 10); | ||||||
|  |  | ||||||
|  |     emit heightChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Screen::height() const | ||||||
|  | { | ||||||
|  |     return m_height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Screen::contentHeight() const | ||||||
|  | { | ||||||
|  |     return currentScreenData()->contentHeight(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::emitRequestWidth(int newWidth) | ||||||
|  | { | ||||||
|  |     emit requestWidthChange(newWidth); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::setWidth(int width) | ||||||
|  | { | ||||||
|  |     if (width == m_width) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     emit widthAboutToChange(width); | ||||||
|  |  | ||||||
|  |     m_width = width; | ||||||
|  |  | ||||||
|  |     m_pty.setWidth(width, width * 10); | ||||||
|  |  | ||||||
|  |     emit widthChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Screen::width() const | ||||||
|  | { | ||||||
|  |     return m_width; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::useAlternateScreenBuffer() | ||||||
|  | { | ||||||
|  |     if (m_current_data == m_primary_data) { | ||||||
|  |         disconnect(m_primary_data, SIGNAL(contentHeightChanged()), this, SIGNAL(contentHeightChanged())); | ||||||
|  |         disconnect(m_primary_data, &ScreenData::contentModified, this, &Screen::contentModified); | ||||||
|  |         m_current_data = m_alternate_data; | ||||||
|  |         m_current_data->clear(); | ||||||
|  |         connect(m_alternate_data, SIGNAL(contentHeightChanged()), this, SIGNAL(contentHeightChanged())); | ||||||
|  |         connect(m_primary_data, &ScreenData::contentModified, this, &Screen::contentModified); | ||||||
|  |         emit contentHeightChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::useNormalScreenBuffer() | ||||||
|  | { | ||||||
|  |     if (m_current_data == m_alternate_data) { | ||||||
|  |         disconnect(m_alternate_data, SIGNAL(contentHeightChanged()), this, SIGNAL(contentHeightChanged())); | ||||||
|  |         disconnect(m_alternate_data, &ScreenData::contentModified, this, &Screen::contentModified); | ||||||
|  |         m_current_data = m_primary_data; | ||||||
|  |         connect(m_primary_data, SIGNAL(contentHeightChanged()), this, SIGNAL(contentHeightChanged())); | ||||||
|  |         connect(m_alternate_data, &ScreenData::contentModified, this, &Screen::contentModified); | ||||||
|  |         emit contentHeightChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TextStyle Screen::defaultTextStyle() const | ||||||
|  | { | ||||||
|  |     TextStyle style; | ||||||
|  |     style.style = TextStyle::Normal; | ||||||
|  |     style.forground = ColorPalette::DefaultForground; | ||||||
|  |     style.background = ColorPalette::DefaultBackground; | ||||||
|  |     return style; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::saveCursor() | ||||||
|  | { | ||||||
|  |     Cursor *new_cursor = new Cursor(this); | ||||||
|  |     if (m_cursor_stack.size()) | ||||||
|  |         m_cursor_stack.last()->setVisible(false); | ||||||
|  |     m_cursor_stack << new_cursor; | ||||||
|  |     m_new_cursors << new_cursor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::restoreCursor() | ||||||
|  | { | ||||||
|  |     if (m_cursor_stack.size() <= 1) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     m_delete_cursors.append(m_cursor_stack.takeLast()); | ||||||
|  |     m_cursor_stack.last()->setVisible(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::clearScreen() | ||||||
|  | { | ||||||
|  |     currentScreenData()->clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ColorPalette *Screen::colorPalette() const | ||||||
|  | { | ||||||
|  |     return m_palette; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::fill(const QChar character) | ||||||
|  | { | ||||||
|  |     currentScreenData()->fill(character); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::clear() | ||||||
|  | { | ||||||
|  |     fill(QChar(' ')); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::setFastScroll(bool fast) | ||||||
|  | { | ||||||
|  |     m_fast_scroll = fast; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Screen::fastScroll() const | ||||||
|  | { | ||||||
|  |     return m_fast_scroll; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Selection *Screen::selection() const | ||||||
|  | { | ||||||
|  |     return m_selection; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::doubleClicked(const QPointF &clicked) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(clicked); | ||||||
|  |     //int start, end; | ||||||
|  |     //currentScreenData()->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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::printScreen() const | ||||||
|  | { | ||||||
|  |     currentScreenData()->printStyleInformation(); | ||||||
|  |     qDebug() << "Total height: " << currentScreenData()->contentHeight(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::scheduleEventDispatch() | ||||||
|  | { | ||||||
|  |     if (!m_timer_event_id) { | ||||||
|  |         m_timer_event_id = startTimer(1); | ||||||
|  |         m_time_since_initiated.restart(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_time_since_parsed.restart(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::dispatchChanges() | ||||||
|  | { | ||||||
|  |     if (m_old_current_data != m_current_data) { | ||||||
|  |         m_old_current_data->releaseTextObjects(); | ||||||
|  |         m_old_current_data = m_current_data; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     currentScreenData()->dispatchLineEvents(); | ||||||
|  |     emit dispatchTextSegmentChanges(); | ||||||
|  |  | ||||||
|  |     static int max_to_delete_size = 0; | ||||||
|  |     if (max_to_delete_size < m_to_delete.size()) { | ||||||
|  |         max_to_delete_size = m_to_delete.size(); | ||||||
|  |         qDebug() << "TO DELETE SIZE :" << max_to_delete_size; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_flash) { | ||||||
|  |         m_flash = false; | ||||||
|  |         emit flash(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_delete_cursors.size(); i++) { | ||||||
|  |         int new_index = m_new_cursors.indexOf(m_delete_cursors.at(i)); | ||||||
|  |         if (new_index >= 0) | ||||||
|  |             m_new_cursors.remove(new_index); | ||||||
|  |         delete m_delete_cursors.at(i); | ||||||
|  |     } | ||||||
|  |     m_delete_cursors.clear(); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_new_cursors.size(); i++) { | ||||||
|  |         emit cursorCreated(m_new_cursors.at(i)); | ||||||
|  |     } | ||||||
|  |     m_new_cursors.clear(); | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < m_cursor_stack.size(); i++) { | ||||||
|  |         m_cursor_stack[i]->dispatchEvents(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_selection->dispatchChanges(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::sendPrimaryDA() | ||||||
|  | { | ||||||
|  |     m_pty.write(QByteArrayLiteral("\033[?6c")); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::sendSecondaryDA() | ||||||
|  | { | ||||||
|  |     m_pty.write(QByteArrayLiteral("\033[>1;95;0c")); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::setApplicationCursorKeysMode(bool enable) | ||||||
|  | { | ||||||
|  |     m_application_cursor_key_mode = enable; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Screen::applicationCursorKeyMode() const | ||||||
|  | { | ||||||
|  |     return m_application_cursor_key_mode; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::ensureVisiblePages(int top_line) | ||||||
|  | { | ||||||
|  |     currentScreenData()->ensureVisiblePages(top_line); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | //    if (key == Qt::Key_Control) | ||||||
|  | //        printScreen(); | ||||||
|  |     /// UGH, this function 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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Text *Screen::createTextSegment(const TextStyleLine &style_line) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(style_line); | ||||||
|  |     Text *to_return; | ||||||
|  |     if (m_to_delete.size()) { | ||||||
|  |         to_return = m_to_delete.takeLast(); | ||||||
|  |         to_return->setVisible(true); | ||||||
|  |     } else { | ||||||
|  |         to_return = new Text(this); | ||||||
|  |         emit textCreated(to_return); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return to_return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::releaseTextSegment(Text *text) | ||||||
|  | { | ||||||
|  |     m_to_delete.append(text); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::readData(const QByteArray &data) | ||||||
|  | { | ||||||
|  |     m_parser.addData(data); | ||||||
|  |  | ||||||
|  |     scheduleEventDispatch(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Screen::paletteChanged() | ||||||
|  | { | ||||||
|  |     QColor new_default = m_palette->normalColor(ColorPalette::DefaultBackground); | ||||||
|  |     if (new_default != m_default_background) { | ||||||
|  |         m_default_background = new_default; | ||||||
|  |         emit defaultBackgroundColorChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Screen::timerEvent(QTimerEvent *) | ||||||
|  | { | ||||||
|  |     if (m_timer_event_id && (m_time_since_parsed.elapsed() > 3 || m_time_since_initiated.elapsed() > 8)) { | ||||||
|  |         killTimer(m_timer_event_id); | ||||||
|  |         m_timer_event_id = 0; | ||||||
|  |         dispatchChanges(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										188
									
								
								yat/backend/screen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								yat/backend/screen.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 "color_palette.h" | ||||||
|  | #include "parser.h" | ||||||
|  | #include "yat_pty.h" | ||||||
|  | #include "text_style.h" | ||||||
|  |  | ||||||
|  | #include <QtCore/QPoint> | ||||||
|  | #include <QtCore/QSize> | ||||||
|  | #include <QtCore/QStack> | ||||||
|  | #include <QtCore/QElapsedTimer> | ||||||
|  |  | ||||||
|  | class Block; | ||||||
|  | class Cursor; | ||||||
|  | class Text; | ||||||
|  | class ScreenData; | ||||||
|  | class Selection; | ||||||
|  |  | ||||||
|  | class Screen : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  |     Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) | ||||||
|  |     Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) | ||||||
|  |     Q_PROPERTY(int contentHeight READ contentHeight NOTIFY contentHeightChanged) | ||||||
|  |     Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY screenTitleChanged) | ||||||
|  |     Q_PROPERTY(Selection *selection READ selection CONSTANT) | ||||||
|  |     Q_PROPERTY(QColor defaultBackgroundColor READ defaultBackgroundColor NOTIFY defaultBackgroundColorChanged) | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     explicit Screen(QObject *parent = 0); | ||||||
|  |     ~Screen(); | ||||||
|  |  | ||||||
|  |     void emitRequestHeight(int newHeight); | ||||||
|  |     void setHeight(int height); | ||||||
|  |     int height() const; | ||||||
|  |     int contentHeight() const; | ||||||
|  |  | ||||||
|  |     void emitRequestWidth(int newWidth); | ||||||
|  |     void setWidth(int width); | ||||||
|  |     int width() const; | ||||||
|  |  | ||||||
|  |     ScreenData *currentScreenData() const { return m_current_data; } | ||||||
|  |     void useAlternateScreenBuffer(); | ||||||
|  |     void useNormalScreenBuffer(); | ||||||
|  |  | ||||||
|  |     Cursor *currentCursor() const { return  m_cursor_stack.last(); } | ||||||
|  |     void saveCursor(); | ||||||
|  |     void restoreCursor(); | ||||||
|  |  | ||||||
|  |     TextStyle defaultTextStyle() const; | ||||||
|  |  | ||||||
|  |     QColor defaultForgroundColor() const; | ||||||
|  |     QColor defaultBackgroundColor() const; | ||||||
|  |  | ||||||
|  |     ColorPalette *colorPalette() const; | ||||||
|  |  | ||||||
|  |     void clearScreen(); | ||||||
|  |  | ||||||
|  |     void fill(const QChar character); | ||||||
|  |     void clear(); | ||||||
|  |  | ||||||
|  |     void setFastScroll(bool fast); | ||||||
|  |     bool fastScroll() const; | ||||||
|  |  | ||||||
|  |     Selection *selection() const; | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE void doubleClicked(const QPointF &clicked); | ||||||
|  |  | ||||||
|  |     void setTitle(const QString &title); | ||||||
|  |     QString title() const; | ||||||
|  |  | ||||||
|  |     void scheduleFlash(); | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE void printScreen() const; | ||||||
|  |  | ||||||
|  |     void scheduleEventDispatch(); | ||||||
|  |     void dispatchChanges(); | ||||||
|  |  | ||||||
|  |     void sendPrimaryDA(); | ||||||
|  |     void sendSecondaryDA(); | ||||||
|  |  | ||||||
|  |     void setApplicationCursorKeysMode(bool enable); | ||||||
|  |     bool applicationCursorKeyMode() const; | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE void sendKey(const QString &text, Qt::Key key, Qt::KeyboardModifiers modifiers); | ||||||
|  |  | ||||||
|  |     YatPty *pty(); | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE void ensureVisiblePages(int top_line); | ||||||
|  |     Text *createTextSegment(const TextStyleLine &style_line); | ||||||
|  |     void releaseTextSegment(Text *text); | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  |     void readData(const QByteArray &data); | ||||||
|  |     void paletteChanged(); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void reset(); | ||||||
|  |  | ||||||
|  |     void flash(); | ||||||
|  |  | ||||||
|  |     void dispatchLineChanges(); | ||||||
|  |     void dispatchTextSegmentChanges(); | ||||||
|  |  | ||||||
|  |     void screenTitleChanged(); | ||||||
|  |  | ||||||
|  |     void textCreated(Text *text); | ||||||
|  |     void cursorCreated(Cursor *cursor); | ||||||
|  |  | ||||||
|  |     void requestHeightChange(int newHeight); | ||||||
|  |     void heightAboutToChange(int height, int currentCursorLine, int currentScrollBackHeight); | ||||||
|  |     void heightChanged(); | ||||||
|  |     void contentHeightChanged(); | ||||||
|  |  | ||||||
|  |     void requestWidthChange(int newWidth); | ||||||
|  |     void widthAboutToChange(int width); | ||||||
|  |     void widthChanged(); | ||||||
|  |  | ||||||
|  |     void defaultBackgroundColorChanged(); | ||||||
|  |  | ||||||
|  |     void contentModified(size_t lineModified, int lineDiff, int contentDiff); | ||||||
|  | protected: | ||||||
|  |     void timerEvent(QTimerEvent *); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     ColorPalette *m_palette; | ||||||
|  |     YatPty m_pty; | ||||||
|  |     Parser m_parser; | ||||||
|  |     QElapsedTimer m_time_since_parsed; | ||||||
|  |     QElapsedTimer m_time_since_initiated; | ||||||
|  |  | ||||||
|  |     int m_timer_event_id; | ||||||
|  |     int m_width; | ||||||
|  |     int m_height; | ||||||
|  |  | ||||||
|  |     ScreenData *m_primary_data; | ||||||
|  |     ScreenData *m_alternate_data; | ||||||
|  |     ScreenData *m_current_data; | ||||||
|  |     ScreenData *m_old_current_data; | ||||||
|  |  | ||||||
|  |     QVector<Cursor *> m_cursor_stack; | ||||||
|  |     QVector<Cursor *> m_new_cursors; | ||||||
|  |     QVector<Cursor *> m_delete_cursors; | ||||||
|  |  | ||||||
|  |     QString m_title; | ||||||
|  |  | ||||||
|  |     Selection *m_selection; | ||||||
|  |  | ||||||
|  |     bool m_flash; | ||||||
|  |     bool m_cursor_changed; | ||||||
|  |     bool m_application_cursor_key_mode; | ||||||
|  |     bool m_fast_scroll; | ||||||
|  |  | ||||||
|  |     QVector<Text *> m_to_delete; | ||||||
|  |  | ||||||
|  |     QColor m_default_background; | ||||||
|  |  | ||||||
|  |     friend class ScreenData; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // TERMINALSCREEN_H | ||||||
							
								
								
									
										530
									
								
								yat/backend/screen_data.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										530
									
								
								yat/backend/screen_data.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,530 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * 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 "block.h" | ||||||
|  | #include "screen.h" | ||||||
|  | #include "scrollback.h" | ||||||
|  | #include "cursor.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #include <QtGui/QGuiApplication> | ||||||
|  | #include <QtCore/QDebug> | ||||||
|  |  | ||||||
|  | ScreenData::ScreenData(size_t max_scrollback, Screen *screen) | ||||||
|  |     : QObject(screen) | ||||||
|  |     , m_screen(screen) | ||||||
|  |     , m_scrollback(new Scrollback(max_scrollback, this)) | ||||||
|  |     , m_screen_height(0) | ||||||
|  |     , m_height(0) | ||||||
|  |     , m_width(0) | ||||||
|  |     , m_block_count(0) | ||||||
|  |     , m_old_total_lines(0) | ||||||
|  | { | ||||||
|  |     connect(screen, SIGNAL(heightAboutToChange(int, int, int)), this, SLOT(setHeight(int, int, int))); | ||||||
|  |     connect(screen, SIGNAL(widthAboutToChange(int)), this, SLOT(setWidth(int))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ScreenData::~ScreenData() | ||||||
|  | { | ||||||
|  |     for (auto it = m_screen_blocks.begin(); it != m_screen_blocks.end(); ++it) { | ||||||
|  |         delete *it; | ||||||
|  |     } | ||||||
|  |     delete m_scrollback; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int ScreenData::contentHeight() const | ||||||
|  | { | ||||||
|  |     return m_height + m_scrollback->height(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::setHeight(int height, int currentCursorLine, int currentContentHeight) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(currentContentHeight); | ||||||
|  |     m_screen_height = height; | ||||||
|  |     if (height == m_height) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (m_height > height) { | ||||||
|  |         const int to_remove = m_height - height; | ||||||
|  |         const int remove_from_end = std::min((m_height -1) - currentCursorLine, to_remove); | ||||||
|  |         const int remove_from_start = to_remove - remove_from_end; | ||||||
|  |  | ||||||
|  |         if (remove_from_end) { | ||||||
|  |             remove_lines_from_end(remove_from_end); | ||||||
|  |         } | ||||||
|  |         if (remove_from_start) { | ||||||
|  |             push_at_most_to_scrollback(remove_from_start); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         ensure_at_least_height(height); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::setWidth(int width) | ||||||
|  | { | ||||||
|  |     m_width = width; | ||||||
|  |  | ||||||
|  |     for (Block *block : m_screen_blocks) { | ||||||
|  |         int before_count = block->lineCount(); | ||||||
|  |         block->setWidth(width); | ||||||
|  |         m_height += block->lineCount() - before_count; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_height > m_screen_height) { | ||||||
|  |         push_at_most_to_scrollback(m_height - m_screen_height); | ||||||
|  |     } else { | ||||||
|  |         ensure_at_least_height(m_screen_height); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_scrollback->setWidth(width); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void ScreenData::clearToEndOfLine(const QPoint &point) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row_ensure_single_line_block(point.y()); | ||||||
|  |     (*it)->clearToEnd(point.x()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearToEndOfScreen(int y) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row_ensure_single_line_block(y); | ||||||
|  |     while(it != m_screen_blocks.end()) { | ||||||
|  |         clearBlock(it); | ||||||
|  |         ++it; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearToBeginningOfLine(const QPoint &point) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row_ensure_single_line_block(point.y()); | ||||||
|  |     (*it)->clearCharacters(0,point.x()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearToBeginningOfScreen(int y) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row_ensure_single_line_block(y); | ||||||
|  |     if (it != m_screen_blocks.end()) | ||||||
|  |         (*it)->clear(); | ||||||
|  |     while(it != m_screen_blocks.begin()) { | ||||||
|  |         --it; | ||||||
|  |         clearBlock(it); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearLine(const QPoint &point) | ||||||
|  | { | ||||||
|  |     (*it_for_row_ensure_single_line_block(point.y()))->clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clear() | ||||||
|  | { | ||||||
|  |     for (auto it = m_screen_blocks.begin(); it != m_screen_blocks.end(); ++it) { | ||||||
|  |         clearBlock(it); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::releaseTextObjects() | ||||||
|  | { | ||||||
|  |     for (auto it = m_screen_blocks.begin(); it != m_screen_blocks.end(); ++it) { | ||||||
|  |         (*it)->releaseTextObjects(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearCharacters(const QPoint &point, int to) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row_ensure_single_line_block(point.y()); | ||||||
|  |     (*it)->clearCharacters(point.x(),to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::deleteCharacters(const QPoint &point, int to) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row(point.y()); | ||||||
|  |     if (it  == m_screen_blocks.end()) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     int line_in_block = point.y() - (*it)->screenIndex(); | ||||||
|  |     int chars_to_line = line_in_block * m_width; | ||||||
|  |  | ||||||
|  |     (*it)->deleteCharacters(chars_to_line + point.x(), chars_to_line + to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | CursorDiff ScreenData::replace(const QPoint &point, const QString &text, const TextStyle &style, bool only_latin) | ||||||
|  | { | ||||||
|  |     return modify(point,text,style,true, only_latin); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | CursorDiff ScreenData::insert(const QPoint &point, const QString &text, const TextStyle &style, bool only_latin) | ||||||
|  | { | ||||||
|  |     return modify(point,text,style,false, only_latin); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void ScreenData::moveLine(int from, int to) | ||||||
|  | { | ||||||
|  |     if (from == to) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     const size_t old_content_height = contentHeight(); | ||||||
|  |     const int orig_to = to; | ||||||
|  |     if (to > from) | ||||||
|  |         to++; | ||||||
|  |     auto from_it = it_for_row_ensure_single_line_block(from); | ||||||
|  |     auto to_it = it_for_row_ensure_single_line_block(to); | ||||||
|  |  | ||||||
|  |     (*from_it)->clear(); | ||||||
|  |     m_screen_blocks.splice(to_it, m_screen_blocks, from_it); | ||||||
|  |     qDebug() << Q_FUNC_INFO << to; | ||||||
|  |     emit contentModified(m_scrollback->height() + to, 1, content_height_diff(old_content_height)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::insertLine(int row, int topMargin) | ||||||
|  | { | ||||||
|  |     auto row_it = it_for_row(row + 1); | ||||||
|  |  | ||||||
|  |     const size_t old_content_height = contentHeight(); | ||||||
|  |  | ||||||
|  |     if (!topMargin && m_height >= m_screen_height) { | ||||||
|  |         push_at_most_to_scrollback(1); | ||||||
|  |     } else { | ||||||
|  |         auto row_top_margin = it_for_row_ensure_single_line_block(topMargin); | ||||||
|  |         if (row == topMargin) { | ||||||
|  |             (*row_top_margin)->clear(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         delete (*row_top_margin); | ||||||
|  |         m_screen_blocks.erase(row_top_margin); | ||||||
|  |         m_height--; | ||||||
|  |         m_block_count--; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Block *block_to_insert = new Block(m_screen); | ||||||
|  |     m_screen_blocks.insert(row_it,block_to_insert); | ||||||
|  |     m_height++; | ||||||
|  |     m_block_count++; | ||||||
|  |  | ||||||
|  |     emit contentModified(m_scrollback->height() + row + 1, 1, content_height_diff(old_content_height)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void ScreenData::fill(const QChar &character) | ||||||
|  | { | ||||||
|  |     clear(); | ||||||
|  |     auto it = --m_screen_blocks.end(); | ||||||
|  |     for (int i = 0; i < m_block_count; --it, i++) { | ||||||
|  |         QString fill_str(m_screen->width(), character); | ||||||
|  |         (*it)->replaceAtPos(0, fill_str, m_screen->defaultTextStyle()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::dispatchLineEvents() | ||||||
|  | { | ||||||
|  |     if (!m_block_count) | ||||||
|  |         return; | ||||||
|  |     const int scrollback_height = m_scrollback->height(); | ||||||
|  |     int i = 0; | ||||||
|  |     for (auto it = m_screen_blocks.begin(); it != m_screen_blocks.end(); ++it) { | ||||||
|  |         int line = scrollback_height + i; | ||||||
|  |         (*it)->setLine(line); | ||||||
|  |         //(*it)->setScreenIndex(i); | ||||||
|  |         (*it)->dispatchEvents(); | ||||||
|  |         i+= (*it)->lineCount(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (contentHeight() != m_old_total_lines) { | ||||||
|  |         m_old_total_lines = contentHeight(); | ||||||
|  |         emit contentHeightChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::printRuler(QDebug &debug) const | ||||||
|  | { | ||||||
|  |     QString ruler = QString("|----i----").repeated((m_width/10)+1).append("|"); | ||||||
|  |     debug << "    " << (void *) this << ruler; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::printStyleInformation() const | ||||||
|  | { | ||||||
|  |     auto it = m_screen_blocks.end(); | ||||||
|  |     std::advance(it, -m_block_count); | ||||||
|  |     for (int i = 0; it != m_screen_blocks.end(); ++it, i++) { | ||||||
|  |         if (i % 5 == 0) { | ||||||
|  |             QDebug debug = qDebug(); | ||||||
|  |             debug << "Ruler:"; | ||||||
|  |             printRuler(debug); | ||||||
|  |         } | ||||||
|  |         QDebug debug = qDebug(); | ||||||
|  |         (*it)->printStyleList(debug); | ||||||
|  |     } | ||||||
|  |     qDebug() << "On screen height" << m_height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Screen *ScreenData::screen() const | ||||||
|  | { | ||||||
|  |     return m_screen; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::ensureVisiblePages(int top_line) | ||||||
|  | { | ||||||
|  |     m_scrollback->ensureVisiblePages(top_line); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Scrollback *ScreenData::scrollback() const | ||||||
|  | { | ||||||
|  |     return m_scrollback; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::sendSelectionToClipboard(const QPoint &start, const QPoint &end, QClipboard::Mode mode) | ||||||
|  | { | ||||||
|  |     if (start.y() < 0) | ||||||
|  |         return; | ||||||
|  |     if (end.y() >= contentHeight()) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     QString to_clip_board_buffer; | ||||||
|  |  | ||||||
|  |     bool started_in_scrollback = false; | ||||||
|  |     if (size_t(start.y()) < m_scrollback->height()) { | ||||||
|  |         started_in_scrollback = true; | ||||||
|  |         QPoint end_scrollback = end; | ||||||
|  |         if (size_t(end.y()) >= m_scrollback->height()) { | ||||||
|  |             end_scrollback = QPoint(m_width, m_scrollback->height() - 1); | ||||||
|  |         } | ||||||
|  |         to_clip_board_buffer = m_scrollback->selection(start, end_scrollback); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (size_t(end.y()) >= m_scrollback->height()) { | ||||||
|  |         QPoint start_in_screen; | ||||||
|  |         if (started_in_scrollback) { | ||||||
|  |             start_in_screen = QPoint(0,0); | ||||||
|  |         } else { | ||||||
|  |             start_in_screen = start; | ||||||
|  |             start_in_screen.ry() -= m_scrollback->height(); | ||||||
|  |         } | ||||||
|  |         QPoint end_in_screen = end; | ||||||
|  |         end_in_screen.ry() -= m_scrollback->height(); | ||||||
|  |  | ||||||
|  |         auto it = it_for_row(start_in_screen.y()); | ||||||
|  |         size_t screen_index = (*it)->screenIndex(); | ||||||
|  |         int start_pos = (start_in_screen.y() - (*it)->screenIndex()) * m_width + start.x(); | ||||||
|  |         for (; it != m_screen_blocks.end(); ++it, start_pos = 0) { | ||||||
|  |             int end_pos = (*it)->textSize(); | ||||||
|  |             bool should_break = false; | ||||||
|  |             if (size_t(screen_index + (*it)->lineCount()) > size_t(end_in_screen.y())) { | ||||||
|  |                 end_pos = (end_in_screen.y() - screen_index) * m_width + end_in_screen.x(); | ||||||
|  |                 should_break = true; | ||||||
|  |             } | ||||||
|  |             if (to_clip_board_buffer.size()) | ||||||
|  |                 to_clip_board_buffer += '\n'; | ||||||
|  |             to_clip_board_buffer += (*it)->textLine()->mid(start_pos, end_pos - start_pos); | ||||||
|  |             if (should_break) | ||||||
|  |                 break; | ||||||
|  |             screen_index += (*it)->lineCount(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     QGuiApplication::clipboard()->setText(to_clip_board_buffer, mode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | CursorDiff ScreenData::modify(const QPoint &point, const QString &text, const TextStyle &style, bool replace, bool only_latin) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row(point.y()); | ||||||
|  |     Block *block = *it; | ||||||
|  |     const int start_char = (point.y() - block->screenIndex()) * m_width + point.x(); | ||||||
|  |     const size_t lines_before = block->lineCount(); | ||||||
|  |     const int lines_changed = | ||||||
|  |         block->lineCountAfterModified(start_char, text.size(), replace)  - lines_before; | ||||||
|  |     const size_t old_content_height = contentHeight(); | ||||||
|  |     m_height += lines_changed; | ||||||
|  |     if (lines_changed > 0) { | ||||||
|  |         int removed = 0; | ||||||
|  |         auto to_merge_inn = it; | ||||||
|  |         ++to_merge_inn; | ||||||
|  |         while(removed < lines_changed && to_merge_inn != m_screen_blocks.end()) { | ||||||
|  |             Block *to_be_reduced = *to_merge_inn; | ||||||
|  |             bool remove_block = removed + to_be_reduced->lineCount() <= lines_changed; | ||||||
|  |             int lines_to_remove = remove_block ? to_be_reduced->lineCount() : to_be_reduced->lineCount() - (lines_changed - removed); | ||||||
|  |             block->moveLinesFromBlock(to_be_reduced, 0, lines_to_remove); | ||||||
|  |             removed += lines_to_remove; | ||||||
|  |             if (remove_block) { | ||||||
|  |                 delete to_be_reduced; | ||||||
|  |                 to_merge_inn = m_screen_blocks.erase(to_merge_inn); | ||||||
|  |                 m_block_count--; | ||||||
|  |             } else { | ||||||
|  |                 ++to_merge_inn; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         m_height -= removed; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_height > m_screen_height) | ||||||
|  |         push_at_most_to_scrollback(m_height - m_screen_height); | ||||||
|  |  | ||||||
|  |     if (replace) { | ||||||
|  |         block->replaceAtPos(start_char, text, style, only_latin); | ||||||
|  |     } else { | ||||||
|  |         block->insertAtPos(start_char, text, style, only_latin); | ||||||
|  |     } | ||||||
|  |     int end_char = (start_char + text.size()) % m_width; | ||||||
|  |     if (end_char == 0) | ||||||
|  |         end_char = m_width -1; | ||||||
|  |  | ||||||
|  |     emit contentModified(m_scrollback->height() + point.y(), lines_changed, content_height_diff(old_content_height)); | ||||||
|  |     return { lines_changed, end_char - point.x()}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::clearBlock(std::list<Block *>::iterator line) | ||||||
|  | { | ||||||
|  |     int before_count = (*line)->lineCount(); | ||||||
|  |     (*line)->clear(); | ||||||
|  |     int diff_line = before_count - (*line)->lineCount(); | ||||||
|  |     if (diff_line > 0) { | ||||||
|  |         ++line; | ||||||
|  |         for (int i = 0; i < diff_line; i++) { | ||||||
|  |             m_screen_blocks.insert(line, new Block(m_screen)); | ||||||
|  |         } | ||||||
|  |         m_block_count+=diff_line; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::list<Block *>::iterator ScreenData::it_for_row_ensure_single_line_block(int row) | ||||||
|  | { | ||||||
|  |     auto it = it_for_row(row); | ||||||
|  |     const int index = (*it)->screenIndex(); | ||||||
|  |     const int lines = (*it)->lineCount(); | ||||||
|  |  | ||||||
|  |     if (index == row && lines == 1) { | ||||||
|  |         return it; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     int line_diff = row - index; | ||||||
|  |     return split_out_row_from_block(it, line_diff); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::list<Block *>::iterator ScreenData::split_out_row_from_block(std::list<Block *>::iterator it, int row_in_block) | ||||||
|  | { | ||||||
|  |     int lines = (*it)->lineCount(); | ||||||
|  |  | ||||||
|  |     if (row_in_block == 0 && lines == 1) | ||||||
|  |         return it; | ||||||
|  |  | ||||||
|  |     if (row_in_block == 0) { | ||||||
|  |         auto insert_before = (*it)->takeLine(0); | ||||||
|  |         insert_before->setScreenIndex(row_in_block); | ||||||
|  |         m_block_count++; | ||||||
|  |         return m_screen_blocks.insert(it,insert_before); | ||||||
|  |     } else if (row_in_block == lines -1) { | ||||||
|  |         auto insert_after = (*it)->takeLine(lines -1); | ||||||
|  |         insert_after->setScreenIndex(row_in_block); | ||||||
|  |         ++it; | ||||||
|  |         m_block_count++; | ||||||
|  |         return m_screen_blocks.insert(it, insert_after); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto half = (*it)->split(row_in_block); | ||||||
|  |     ++it; | ||||||
|  |     auto it_width_first = m_screen_blocks.insert(it, half); | ||||||
|  |     auto the_one = half->takeLine(0); | ||||||
|  |     m_block_count+=2; | ||||||
|  |     return m_screen_blocks.insert(it_width_first,the_one); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::push_at_most_to_scrollback(int lines) | ||||||
|  | { | ||||||
|  |     int pushed = 0; | ||||||
|  |     auto it = m_screen_blocks.begin(); | ||||||
|  |     while (it != m_screen_blocks.end() && pushed + (*it)->lineCount() <= lines) { | ||||||
|  |         m_block_count--; | ||||||
|  |         const int block_height = (*it)->lineCount(); | ||||||
|  |         m_height -= block_height; | ||||||
|  |         pushed += block_height; | ||||||
|  |         m_scrollback->addBlock(*it); | ||||||
|  |         it = m_screen_blocks.erase(it); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::reclaim_at_least(int lines) | ||||||
|  | { | ||||||
|  |     int lines_reclaimed = 0; | ||||||
|  |     while (m_scrollback->blockCount() && lines_reclaimed < lines) { | ||||||
|  |         Block *block = m_scrollback->reclaimBlock(); | ||||||
|  |         m_height += block->lineCount(); | ||||||
|  |         lines_reclaimed += block->lineCount(); | ||||||
|  |         m_block_count++; | ||||||
|  |         m_screen_blocks.push_front(block); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::remove_lines_from_end(int lines) | ||||||
|  | { | ||||||
|  |     int removed = 0; | ||||||
|  |     auto it = m_screen_blocks.end(); | ||||||
|  |     while (it != m_screen_blocks.begin() && removed < lines) { | ||||||
|  |         --it; | ||||||
|  |         const int block_height = (*it)->lineCount(); | ||||||
|  |         if (removed + block_height <= lines) { | ||||||
|  |             removed += block_height; | ||||||
|  |             m_height -= block_height; | ||||||
|  |             m_block_count--; | ||||||
|  |             delete (*it); | ||||||
|  |             it = m_screen_blocks.erase(it); | ||||||
|  |         } else { | ||||||
|  |             const int to_remove = lines - removed; | ||||||
|  |             removed += to_remove; | ||||||
|  |             m_height -= to_remove; | ||||||
|  |             Block *block = *it; | ||||||
|  |             for (int i = 0; i < to_remove; i++) { | ||||||
|  |                 block->removeLine(block->lineCount()-1); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ScreenData::ensure_at_least_height(int height) | ||||||
|  | { | ||||||
|  |     if (m_height > height) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     int to_grow = height - m_height; | ||||||
|  |     reclaim_at_least(to_grow); | ||||||
|  |  | ||||||
|  |     if (height > m_height) { | ||||||
|  |         int to_insert = height - m_height; | ||||||
|  |         for (int i = 0; i < to_insert; i++) { | ||||||
|  |             m_screen_blocks.push_back(new Block(m_screen)); | ||||||
|  |         } | ||||||
|  |         m_height += to_insert; | ||||||
|  |         m_block_count += to_insert; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ScreenData::content_height_diff(size_t old_content_height) | ||||||
|  | { | ||||||
|  |     const size_t content_height = contentHeight(); | ||||||
|  |     return old_content_height < content_height ? content_height - old_content_height : | ||||||
|  |         - int(old_content_height - content_height); | ||||||
|  | } | ||||||
							
								
								
									
										138
									
								
								yat/backend/screen_data.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								yat/backend/screen_data.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * 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 "text_style.h" | ||||||
|  | #include "block.h" | ||||||
|  |  | ||||||
|  | #include <QtCore/QVector> | ||||||
|  | #include <QtCore/QPoint> | ||||||
|  | #include <QtCore/QObject> | ||||||
|  | #include <QtGui/QClipboard> | ||||||
|  |  | ||||||
|  | #include <QtCore/QDebug> | ||||||
|  | class Screen; | ||||||
|  | class Scrollback; | ||||||
|  |  | ||||||
|  | class CursorDiff | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     int line; | ||||||
|  |     int character; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class ScreenData : public QObject | ||||||
|  | { | ||||||
|  | Q_OBJECT | ||||||
|  | public: | ||||||
|  |     ScreenData(size_t max_scrollback, Screen *screen); | ||||||
|  |     ~ScreenData(); | ||||||
|  |  | ||||||
|  |     int contentHeight() const; | ||||||
|  |  | ||||||
|  |     void clearToEndOfLine(const QPoint &pos); | ||||||
|  |     void clearToEndOfScreen(int y); | ||||||
|  |     void clearToBeginningOfLine(const QPoint &pos); | ||||||
|  |     void clearToBeginningOfScreen(int y); | ||||||
|  |     void clearLine(const QPoint &pos); | ||||||
|  |     void clear(); | ||||||
|  |     void releaseTextObjects(); | ||||||
|  |  | ||||||
|  |     void clearCharacters(const QPoint &pos, int to); | ||||||
|  |     void deleteCharacters(const QPoint &pos, int to); | ||||||
|  |  | ||||||
|  |     CursorDiff replace(const QPoint &pos, const QString &text, const TextStyle &style, bool only_latin); | ||||||
|  |     CursorDiff insert(const QPoint &pos, const QString &text, const TextStyle &style, bool only_latin); | ||||||
|  |  | ||||||
|  |     void moveLine(int from, int to); | ||||||
|  |     void insertLine(int insertAt, int topMargin); | ||||||
|  |  | ||||||
|  |     void fill(const QChar &character); | ||||||
|  |  | ||||||
|  |     void dispatchLineEvents(); | ||||||
|  |  | ||||||
|  |     void printRuler(QDebug &debug) const; | ||||||
|  |     void printStyleInformation() const; | ||||||
|  |  | ||||||
|  |     Screen *screen() const; | ||||||
|  |  | ||||||
|  |     void ensureVisiblePages(int top_line); | ||||||
|  |  | ||||||
|  |     Scrollback *scrollback() const; | ||||||
|  |  | ||||||
|  |     void sendSelectionToClipboard(const QPoint &start, const QPoint &end, QClipboard::Mode mode); | ||||||
|  |  | ||||||
|  |     inline std::list<Block *>::iterator it_for_row(int row); | ||||||
|  | public slots: | ||||||
|  |     void setHeight(int height, int currentCursorLine, int currentContentHeight); | ||||||
|  |     void setWidth(int width); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void contentHeightChanged(); | ||||||
|  |     void contentModified(size_t lineModified, int lineDiff, int contentDiff); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     CursorDiff modify(const QPoint &pos, const QString &text, const TextStyle &style, bool replace, bool only_latin); | ||||||
|  |     void clearBlock(std::list<Block *>::iterator line); | ||||||
|  |     std::list<Block *>::iterator it_for_row_ensure_single_line_block(int row); | ||||||
|  |     std::list<Block *>::iterator split_out_row_from_block(std::list<Block *>::iterator block_it, int row_in_block); | ||||||
|  |     void push_at_most_to_scrollback(int lines); | ||||||
|  |     void reclaim_at_least(int lines); | ||||||
|  |     void remove_lines_from_end(int lines); | ||||||
|  |     void ensure_at_least_height(int height); | ||||||
|  |     int content_height_diff(size_t old_content_height); | ||||||
|  |     Screen *m_screen; | ||||||
|  |     Scrollback *m_scrollback; | ||||||
|  |     int m_screen_height; | ||||||
|  |     int m_height; | ||||||
|  |     int m_width; | ||||||
|  |     int m_block_count; | ||||||
|  |     int m_old_total_lines; | ||||||
|  |  | ||||||
|  |     std::list<Block *> m_screen_blocks; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | std::list<Block *>::iterator ScreenData::it_for_row(int row) | ||||||
|  | { | ||||||
|  |     if (row >= m_screen_height) { | ||||||
|  |         return m_screen_blocks.end(); | ||||||
|  |     } | ||||||
|  |     auto it = m_screen_blocks.end(); | ||||||
|  |     int line_for_block = m_screen_height; | ||||||
|  |     size_t abs_line = contentHeight(); | ||||||
|  |     while (it != m_screen_blocks.begin()) { | ||||||
|  |         --it; | ||||||
|  |         line_for_block -= (*it)->lineCount(); | ||||||
|  |         abs_line -= (*it)->lineCount(); | ||||||
|  |         if (line_for_block <= row) { | ||||||
|  |             (*it)->setScreenIndex(line_for_block); | ||||||
|  |             (*it)->setLine(abs_line); | ||||||
|  |             return it; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return m_screen_blocks.end(); | ||||||
|  | } | ||||||
|  | #endif // SCREENDATA_H | ||||||
							
								
								
									
										215
									
								
								yat/backend/scrollback.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								yat/backend/scrollback.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 "scrollback.h" | ||||||
|  |  | ||||||
|  | #include "screen_data.h" | ||||||
|  | #include "screen.h" | ||||||
|  | #include "block.h" | ||||||
|  |  | ||||||
|  | #define P_VAR(variable) \ | ||||||
|  |     #variable ":" << variable | ||||||
|  |  | ||||||
|  | Scrollback::Scrollback(size_t max_size, ScreenData *screen_data) | ||||||
|  |     : m_screen_data(screen_data) | ||||||
|  |     , m_height(0) | ||||||
|  |     , m_width(0) | ||||||
|  |     , m_block_count(0) | ||||||
|  |     , m_max_size(max_size) | ||||||
|  |     , m_adjust_visible_pages(0) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::addBlock(Block *block) | ||||||
|  | { | ||||||
|  |     if (!m_max_size) { | ||||||
|  |         delete block; | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_blocks.push_back(block); | ||||||
|  |     block->releaseTextObjects(); | ||||||
|  |     m_block_count++; | ||||||
|  |     m_height += m_blocks.back()->lineCount(); | ||||||
|  |  | ||||||
|  |     while (m_height - m_blocks.front()->lineCount() >= m_max_size) { | ||||||
|  |         m_block_count--; | ||||||
|  |         m_height -= m_blocks.front()->lineCount(); | ||||||
|  |         delete m_blocks.front(); | ||||||
|  |         m_blocks.pop_front(); | ||||||
|  |         m_adjust_visible_pages++; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_visible_pages.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Block *Scrollback::reclaimBlock() | ||||||
|  | { | ||||||
|  |     if (m_blocks.empty()) | ||||||
|  |         return nullptr; | ||||||
|  |  | ||||||
|  |     Block *last = m_blocks.back(); | ||||||
|  |     last->setWidth(m_width); | ||||||
|  |     m_block_count--; | ||||||
|  |     m_height -= last->lineCount(); | ||||||
|  |     m_blocks.pop_back(); | ||||||
|  |  | ||||||
|  |     m_visible_pages.clear(); | ||||||
|  |     return last; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::ensureVisiblePages(int top_line) | ||||||
|  | { | ||||||
|  |     if (top_line < 0) | ||||||
|  |         return; | ||||||
|  |     if (size_t(top_line) >= m_height) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     uint height = std::max(m_screen_data->screen()->height(), 1); | ||||||
|  |  | ||||||
|  |     int complete_pages = m_height / height; | ||||||
|  |     int remainder = m_height - (complete_pages * height); | ||||||
|  |  | ||||||
|  |     int top_page = top_line / height; | ||||||
|  |     int bottom_page = top_page + 1; | ||||||
|  |  | ||||||
|  |     std::set<int> pages_to_update; | ||||||
|  |     pages_to_update.insert(top_page); | ||||||
|  |     if (bottom_page * height < m_height) | ||||||
|  |         pages_to_update.insert(bottom_page); | ||||||
|  |  | ||||||
|  |     for (auto it = m_visible_pages.begin(); it != m_visible_pages.end(); ++it) { | ||||||
|  |         Page &page = *it; | ||||||
|  |         if (pages_to_update.count(page.page_no) != 0) { | ||||||
|  |             if (page.page_no < complete_pages) { | ||||||
|  |                 ensurePageVisible(page, height); | ||||||
|  |             } else if (page.page_no == complete_pages) { | ||||||
|  |                 ensurePageVisible(page, remainder); | ||||||
|  |             } | ||||||
|  |             pages_to_update.erase(page.page_no); | ||||||
|  |         } else { | ||||||
|  |             ensurePageNotVisible(page); | ||||||
|  |             auto to_remove = it; | ||||||
|  |             --it; | ||||||
|  |             m_visible_pages.erase(to_remove); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (auto it = pages_to_update.begin(); it != pages_to_update.end(); ++it) { | ||||||
|  |         auto page_it = findIteratorForPage(*it); | ||||||
|  |         m_visible_pages.push_back( { *it, 0, page_it } ); | ||||||
|  |         if (*it < complete_pages) { | ||||||
|  |             ensurePageVisible(m_visible_pages.back(), height); | ||||||
|  |         } else if (*it == complete_pages) { | ||||||
|  |             ensurePageVisible(m_visible_pages.back(), remainder); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::ensurePageVisible(Page &page, int new_height) | ||||||
|  | { | ||||||
|  |     if (page.size == new_height || !m_block_count) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     int line_no = page.page_no * m_screen_data->screen()->height(); | ||||||
|  |     auto it = page.it; | ||||||
|  |     std::advance(it, page.size); | ||||||
|  |     for (int i = page.size; i < new_height; ++it, i++) { | ||||||
|  |         (*it)->setLine(line_no + i); | ||||||
|  |         (*it)->dispatchEvents(); | ||||||
|  |     } | ||||||
|  |     page.size = new_height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::ensurePageNotVisible(Page &page) | ||||||
|  | { | ||||||
|  |     auto it = page.it; | ||||||
|  |     for (int i = 0; i < page.size; ++it, i++) { | ||||||
|  |         (*it)->releaseTextObjects(); | ||||||
|  |     } | ||||||
|  |     page.size = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::list<Block *>::iterator Scrollback::findIteratorForPage(int page_no) | ||||||
|  | { | ||||||
|  |     uint line = page_no * m_screen_data->screen()->height(); | ||||||
|  |     Q_ASSERT(line < m_height); | ||||||
|  |     for (auto it = m_visible_pages.begin(); it != m_visible_pages.end(); ++it) { | ||||||
|  |         Page &page = *it; | ||||||
|  |         int diff = page_no - page.page_no; | ||||||
|  |         if (diff < 5 && diff > 5) { | ||||||
|  |             auto to_return = page.it; | ||||||
|  |             int advance = diff * m_screen_data->screen()->height(); | ||||||
|  |             std::advance(to_return, advance); | ||||||
|  |             return to_return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (line > m_height / 2) { | ||||||
|  |         auto to_return = m_blocks.end(); | ||||||
|  |         std::advance(to_return, line - m_height); | ||||||
|  |         return to_return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto to_return = m_blocks.begin(); | ||||||
|  |     std::advance(to_return, line); | ||||||
|  |     return to_return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::adjustVisiblePages() | ||||||
|  | { | ||||||
|  |     if (!m_adjust_visible_pages) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     for (auto it = m_visible_pages.begin(); it != m_visible_pages.end(); ++it) { | ||||||
|  |         Page &page = *it; | ||||||
|  |         const size_t line_for_page = page.page_no * m_screen_data->screen()->height(); | ||||||
|  |         if (line_for_page < m_adjust_visible_pages) { | ||||||
|  |             auto to_remove = it; | ||||||
|  |             --it; | ||||||
|  |             m_visible_pages.erase(to_remove); | ||||||
|  |         } else { | ||||||
|  |             page.size = 0; | ||||||
|  |             std::advance(page.it, m_adjust_visible_pages); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_adjust_visible_pages = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t Scrollback::height() const | ||||||
|  | { | ||||||
|  |     return m_height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Scrollback::setWidth(int width) | ||||||
|  | { | ||||||
|  |     m_width = width; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QString Scrollback::selection(const QPoint &start, const QPoint &end) const | ||||||
|  | { | ||||||
|  |     Q_UNUSED(start); | ||||||
|  |     Q_UNUSED(end); | ||||||
|  |     return QString(); | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								yat/backend/scrollback.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								yat/backend/scrollback.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 SCROLLBACK_H | ||||||
|  | #define SCROLLBACK_H | ||||||
|  |  | ||||||
|  | #include <set> | ||||||
|  | #include <list> | ||||||
|  |  | ||||||
|  | #include <QtCore/qglobal.h> | ||||||
|  | #include <QtCore/QPoint> | ||||||
|  | class ScreenData; | ||||||
|  | class Block; | ||||||
|  |  | ||||||
|  | struct Page { | ||||||
|  |     int page_no; | ||||||
|  |     int size; | ||||||
|  |     std::list<Block *>::iterator it; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class Scrollback | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     Scrollback(size_t max_size, ScreenData *screen_data); | ||||||
|  |  | ||||||
|  |     void addBlock(Block *block); | ||||||
|  |     Block *reclaimBlock(); | ||||||
|  |     void ensureVisiblePages(int top_line); | ||||||
|  |  | ||||||
|  |     size_t height() const; | ||||||
|  |  | ||||||
|  |     void setWidth(int width); | ||||||
|  |  | ||||||
|  |     size_t blockCount() { return m_block_count; } | ||||||
|  |  | ||||||
|  |     QString selection(const QPoint &start, const QPoint &end) const; | ||||||
|  | private: | ||||||
|  |     void ensurePageVisible(Page &page, int new_height); | ||||||
|  |     void ensurePageNotVisible(Page &page); | ||||||
|  |     std::list<Block *>::iterator findIteratorForPage(int page_no); | ||||||
|  |     void adjustVisiblePages(); | ||||||
|  |     ScreenData *m_screen_data; | ||||||
|  |  | ||||||
|  |     std::list<Block *> m_blocks; | ||||||
|  |     std::list<Page> m_visible_pages; | ||||||
|  |     size_t m_height; | ||||||
|  |     size_t m_width; | ||||||
|  |     size_t m_block_count; | ||||||
|  |     size_t m_max_size; | ||||||
|  |     size_t m_adjust_visible_pages; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif //SCROLLBACK_H | ||||||
							
								
								
									
										197
									
								
								yat/backend/selection.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								yat/backend/selection.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 "selection.h" | ||||||
|  |  | ||||||
|  | #include "screen.h" | ||||||
|  | #include "screen_data.h" | ||||||
|  |  | ||||||
|  | #include <QtGui/QGuiApplication> | ||||||
|  |  | ||||||
|  | Selection::Selection(Screen *screen) | ||||||
|  |     : QObject(screen) | ||||||
|  |     , m_screen(screen) | ||||||
|  |     , m_new_start_x(0) | ||||||
|  |     , m_start_x(0) | ||||||
|  |     , m_new_start_y(0) | ||||||
|  |     , m_start_y(0) | ||||||
|  |     , m_new_end_x(0) | ||||||
|  |     , m_end_x(0) | ||||||
|  |     , m_new_end_y(0) | ||||||
|  |     , m_end_y(0) | ||||||
|  |     , m_new_enable(false) | ||||||
|  | { | ||||||
|  |     connect(screen, &Screen::contentModified, this, &Selection::screenContentModified); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setStartX(int x) | ||||||
|  | { | ||||||
|  |     if (x != m_new_start_x) { | ||||||
|  |         m_new_start_x = x; | ||||||
|  |         setValidity(); | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Selection::startX() const | ||||||
|  | { | ||||||
|  |     return m_start_x; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setStartY(int y) | ||||||
|  | { | ||||||
|  |     if (y != m_new_start_y) { | ||||||
|  |         m_new_start_y = y; | ||||||
|  |         setValidity(); | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Selection::startY() const | ||||||
|  | { | ||||||
|  |     return m_start_y; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setEndX(int x) | ||||||
|  | { | ||||||
|  |     if (m_new_end_x != x) { | ||||||
|  |         m_new_end_x = x; | ||||||
|  |         setValidity(); | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Selection::endX() const | ||||||
|  | { | ||||||
|  |     return m_end_x; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setEndY(int y) | ||||||
|  | { | ||||||
|  |     if (m_new_end_y != y) { | ||||||
|  |         m_new_end_y = y; | ||||||
|  |         setValidity(); | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Selection::endY() const | ||||||
|  | { | ||||||
|  |     return m_end_y; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setEnable(bool enable) | ||||||
|  | { | ||||||
|  |     if (m_new_enable != enable) { | ||||||
|  |         m_new_enable = enable; | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::screenContentModified(size_t lineModified, int lineDiff, int contentDiff) | ||||||
|  | { | ||||||
|  |     if (!m_new_enable) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (lineModified >= size_t(m_new_start_y) && lineModified <= size_t(m_new_end_y)) { | ||||||
|  |         setEnable(false); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (size_t(m_new_end_y) < lineModified && lineModified != contentDiff) { | ||||||
|  |         m_new_end_y -= lineDiff - contentDiff; | ||||||
|  |         m_new_start_y -= lineDiff - contentDiff; | ||||||
|  |         if (m_new_end_y < 0) { | ||||||
|  |             setEnable(false); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (m_new_start_y < 0) { | ||||||
|  |             m_new_start_y = 0; | ||||||
|  |         } | ||||||
|  |         m_screen->scheduleEventDispatch(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::setValidity() | ||||||
|  | { | ||||||
|  |     if (m_new_end_y > m_new_start_y || | ||||||
|  |             (m_new_end_y == m_new_start_y && | ||||||
|  |              m_new_end_x > m_new_start_x)) { | ||||||
|  |         setEnable(true); | ||||||
|  |     } else { | ||||||
|  |         setEnable(false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::sendToClipboard() const | ||||||
|  | { | ||||||
|  |     m_screen->currentScreenData()->sendSelectionToClipboard(start_new_point(), end_new_point(), QClipboard::Clipboard); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::sendToSelection() const | ||||||
|  | { | ||||||
|  |     m_screen->currentScreenData()->sendSelectionToClipboard(start_new_point(), end_new_point(), QClipboard::Selection); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::pasteFromSelection() | ||||||
|  | { | ||||||
|  |     m_screen->pty()->write(QGuiApplication::clipboard()->text(QClipboard::Selection).toUtf8()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::pasteFromClipboard() | ||||||
|  | { | ||||||
|  |     m_screen->pty()->write(QGuiApplication::clipboard()->text(QClipboard::Clipboard).toUtf8()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Selection::dispatchChanges() | ||||||
|  | { | ||||||
|  |     if (!m_new_enable && !m_enable) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (m_new_start_y != m_start_y) { | ||||||
|  |         m_start_y = m_new_start_y; | ||||||
|  |         emit startYChanged(); | ||||||
|  |     } | ||||||
|  |     if (m_new_start_x != m_start_x) { | ||||||
|  |         m_start_x = m_new_start_x; | ||||||
|  |         emit startXChanged(); | ||||||
|  |     } | ||||||
|  |     if (m_new_end_y != m_end_y) { | ||||||
|  |         m_end_y = m_new_end_y; | ||||||
|  |         emit endYChanged(); | ||||||
|  |     } | ||||||
|  |     if (m_new_end_x != m_end_x) { | ||||||
|  |         m_end_x = m_new_end_x; | ||||||
|  |         emit endXChanged(); | ||||||
|  |     } | ||||||
|  |     if (m_new_enable != m_enable) { | ||||||
|  |         m_enable = m_new_enable; | ||||||
|  |         emit enableChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Selection::enable() const | ||||||
|  | { | ||||||
|  |     return m_enable; | ||||||
|  | } | ||||||
							
								
								
									
										93
									
								
								yat/backend/selection.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								yat/backend/selection.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 SELECTION_H | ||||||
|  | #define SELECTION_H | ||||||
|  |  | ||||||
|  | #include <QtCore/QObject> | ||||||
|  | #include <QtCore/QPoint> | ||||||
|  |  | ||||||
|  | class Screen; | ||||||
|  |  | ||||||
|  | class Selection : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  |     Q_PROPERTY(int startX READ startX WRITE setStartX NOTIFY startXChanged) | ||||||
|  |     Q_PROPERTY(int startY READ startY WRITE setStartY NOTIFY startYChanged) | ||||||
|  |     Q_PROPERTY(int endX READ endX WRITE setEndX NOTIFY endXChanged) | ||||||
|  |     Q_PROPERTY(int endY READ endY WRITE setEndY NOTIFY endYChanged) | ||||||
|  |     Q_PROPERTY(bool enable READ enable WRITE setEnable NOTIFY enableChanged) | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     explicit Selection(Screen *screen); | ||||||
|  |  | ||||||
|  |     void setStartX(int x); | ||||||
|  |     int startX() const; | ||||||
|  |  | ||||||
|  |     void setStartY(int y); | ||||||
|  |     int startY() const; | ||||||
|  |  | ||||||
|  |     void setEndX(int x); | ||||||
|  |     int endX() const; | ||||||
|  |  | ||||||
|  |     void setEndY(int y); | ||||||
|  |     int endY() const; | ||||||
|  |  | ||||||
|  |     void setEnable(bool enabled); | ||||||
|  |     bool enable() const; | ||||||
|  |  | ||||||
|  |     Q_INVOKABLE void sendToClipboard() const; | ||||||
|  |     Q_INVOKABLE void sendToSelection() const; | ||||||
|  |     Q_INVOKABLE void pasteFromSelection(); | ||||||
|  |     Q_INVOKABLE void pasteFromClipboard(); | ||||||
|  |  | ||||||
|  |     void dispatchChanges(); | ||||||
|  | signals: | ||||||
|  |     void startXChanged(); | ||||||
|  |     void startYChanged(); | ||||||
|  |     void endXChanged(); | ||||||
|  |     void endYChanged(); | ||||||
|  |     void enableChanged(); | ||||||
|  |  | ||||||
|  | private slots: | ||||||
|  |     void screenContentModified(size_t lineModified, int lineDiff, int contentDiff); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void setValidity(); | ||||||
|  |     QPoint start_new_point() const { return QPoint(m_new_start_x, m_new_start_y); } | ||||||
|  |     QPoint end_new_point() const { return QPoint(m_new_end_x, m_new_end_y); } | ||||||
|  |  | ||||||
|  |     Screen *m_screen; | ||||||
|  |     int m_new_start_x; | ||||||
|  |     int m_start_x; | ||||||
|  |     int m_new_start_y; | ||||||
|  |     int m_start_y; | ||||||
|  |     int m_new_end_x; | ||||||
|  |     int m_end_x; | ||||||
|  |     int m_new_end_y; | ||||||
|  |     int m_end_y; | ||||||
|  |     bool m_new_enable; | ||||||
|  |     bool m_enable; | ||||||
|  | }; | ||||||
|  | #endif | ||||||
							
								
								
									
										255
									
								
								yat/backend/text.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								yat/backend/text.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,255 @@ | |||||||
|  | /************************************************************************************************** | ||||||
|  | * 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 "block.h" | ||||||
|  | #include <QtQuick/QQuickItem> | ||||||
|  |  | ||||||
|  | #include <QtCore/QDebug> | ||||||
|  |  | ||||||
|  | Text::Text(Screen *screen) | ||||||
|  |     : QObject(screen) | ||||||
|  |     , m_screen(screen) | ||||||
|  |     , m_text_line(0) | ||||||
|  |     , m_start_index(0) | ||||||
|  |     , m_old_start_index(0) | ||||||
|  |     , m_end_index(0) | ||||||
|  |     , m_line(0) | ||||||
|  |     , m_old_line(0) | ||||||
|  |     , m_width(1) | ||||||
|  |     , m_style_dirty(true) | ||||||
|  |     , m_text_dirty(true) | ||||||
|  |     , m_visible(true) | ||||||
|  |     , m_visible_old(true) | ||||||
|  |     , m_latin(true) | ||||||
|  |     , m_latin_old(true) | ||||||
|  |     , m_forgroundColor(m_screen->defaultForgroundColor()) | ||||||
|  |     , m_backgroundColor(m_screen->defaultBackgroundColor()) | ||||||
|  | { | ||||||
|  |     connect(m_screen->colorPalette(), SIGNAL(changed()), this, SLOT(paletteChanged())); | ||||||
|  |     connect(m_screen, SIGNAL(dispatchTextSegmentChanges()), this, SLOT(dispatchEvents())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Text::~Text() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Text::index() const | ||||||
|  | { | ||||||
|  |     return m_start_index % m_width; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Text::line() const | ||||||
|  | { | ||||||
|  |     return m_line + (m_start_index / m_width); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::setLine(int line, int width, const QString *textLine) | ||||||
|  | { | ||||||
|  |     m_line = line; | ||||||
|  |     m_width = width; | ||||||
|  |     m_text_dirty = true; | ||||||
|  |     m_text_line = textLine; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | { | ||||||
|  |     return m_forgroundColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | QColor Text::backgroundColor() const | ||||||
|  | { | ||||||
|  |     return m_backgroundColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Text::bold() const | ||||||
|  | { | ||||||
|  |     return m_style.style & TextStyle::Bold; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Text::blinking() const | ||||||
|  | { | ||||||
|  |     return m_style.style & TextStyle::Blinking; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Text::underline() const | ||||||
|  | { | ||||||
|  |     return m_style.style & TextStyle::Underlined; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::setLatin(bool latin) | ||||||
|  | { | ||||||
|  |     m_latin = latin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Text::latin() const | ||||||
|  | { | ||||||
|  |     return m_latin_old; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool differentStyle(TextStyle::Styles a, TextStyle::Styles b, TextStyle::Style style) | ||||||
|  | { | ||||||
|  |     return (a & style) != (b & style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::dispatchEvents() | ||||||
|  | { | ||||||
|  |     int old_line = m_old_line + (m_old_start_index / m_width); | ||||||
|  |     int new_line = m_line + (m_start_index / m_width); | ||||||
|  |     if (old_line != new_line) { | ||||||
|  |         m_old_line = m_line; | ||||||
|  |         emit lineChanged(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_latin != m_latin_old) { | ||||||
|  |         m_latin_old = m_latin; | ||||||
|  |         emit latinChanged(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_old_start_index != m_start_index | ||||||
|  |             || m_text_dirty) { | ||||||
|  |         m_text_dirty = false; | ||||||
|  |         QString old_text = m_text; | ||||||
|  |         m_text = m_text_line->mid(m_start_index, m_end_index - m_start_index + 1); | ||||||
|  |         if (m_old_start_index != m_start_index) { | ||||||
|  |             m_old_start_index = m_start_index; | ||||||
|  |             emit indexChanged(); | ||||||
|  |         } | ||||||
|  |         emit textChanged(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     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; | ||||||
|  |         TextStyle::Styles new_style = m_new_style.style; | ||||||
|  |         TextStyle::Styles old_style = m_style.style; | ||||||
|  |  | ||||||
|  |         bool emit_bold = false; | ||||||
|  |         bool emit_blink = false; | ||||||
|  |         bool emit_underline = false; | ||||||
|  |         bool emit_inverse = false; | ||||||
|  |         if (new_style != old_style) { | ||||||
|  |             emit_bold = differentStyle(new_style, old_style, TextStyle::Bold); | ||||||
|  |             emit_blink = differentStyle(new_style, old_style, TextStyle::Blinking); | ||||||
|  |             emit_underline = differentStyle(new_style, old_style, TextStyle::Underlined); | ||||||
|  |             emit_inverse = differentStyle(new_style, old_style, TextStyle::Inverse); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         m_style = m_new_style; | ||||||
|  |         if (emit_inverse) { | ||||||
|  |             setForgroundColor(); | ||||||
|  |             setBackgroundColor(); | ||||||
|  |         } else { | ||||||
|  |             if (emit_forground || emit_bold) { | ||||||
|  |                 setForgroundColor(); | ||||||
|  |             } | ||||||
|  |             if (emit_background) { | ||||||
|  |                 setBackgroundColor(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (emit_bold) { | ||||||
|  |             emit boldChanged(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (emit_blink) { | ||||||
|  |             emit blinkingChanged(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (emit_underline) { | ||||||
|  |             emit underlineChanged(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     if (m_visible_old != m_visible) { | ||||||
|  |         m_visible_old = m_visible; | ||||||
|  |         emit visibleChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::paletteChanged() | ||||||
|  | { | ||||||
|  |     setBackgroundColor(); | ||||||
|  |     setForgroundColor(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::setBackgroundColor() | ||||||
|  | { | ||||||
|  |     QColor new_background; | ||||||
|  |     if (m_style.style & TextStyle::Inverse) { | ||||||
|  |         new_background = m_screen->colorPalette()->color(m_style.forground, false); | ||||||
|  |     } else { | ||||||
|  |         new_background = m_screen->colorPalette()->color(m_style.background, false); | ||||||
|  |     } | ||||||
|  |     if (new_background != m_backgroundColor) { | ||||||
|  |         m_backgroundColor = new_background; | ||||||
|  |         emit backgroundColorChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Text::setForgroundColor() | ||||||
|  | { | ||||||
|  |     QColor new_forground; | ||||||
|  |     if (m_style.style & TextStyle::Inverse) { | ||||||
|  |         new_forground = m_screen->colorPalette()->color(m_style.background, false); | ||||||
|  |     } else { | ||||||
|  |         new_forground = m_screen->colorPalette()->color(m_style.forground, false); | ||||||
|  |     } | ||||||
|  |     if (new_forground != m_forgroundColor) { | ||||||
|  |         m_forgroundColor = new_forground; | ||||||
|  |         emit forgroundColorChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										121
									
								
								yat/backend/text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								yat/backend/text.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | /************************************************************************************************** | ||||||
|  | * 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 QQuickItem; | ||||||
|  |  | ||||||
|  | class Text : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |     Q_PROPERTY(int index READ index NOTIFY indexChanged) | ||||||
|  |     Q_PROPERTY(int line READ line NOTIFY lineChanged) | ||||||
|  |     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(bool bold READ bold NOTIFY boldChanged) | ||||||
|  |     Q_PROPERTY(bool blinking READ blinking NOTIFY blinkingChanged) | ||||||
|  |     Q_PROPERTY(bool underline READ underline NOTIFY underlineChanged) | ||||||
|  |     Q_PROPERTY(bool latin READ latin NOTIFY latinChanged) | ||||||
|  | public: | ||||||
|  |     Text(Screen *screen); | ||||||
|  |     ~Text(); | ||||||
|  |  | ||||||
|  |     int index() const; | ||||||
|  |  | ||||||
|  |     int line() const; | ||||||
|  |     void setLine(int line, int width, const QString *textLine); | ||||||
|  |  | ||||||
|  |     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); | ||||||
|  |  | ||||||
|  |     bool bold() const; | ||||||
|  |     bool blinking() const; | ||||||
|  |     bool underline() const; | ||||||
|  |  | ||||||
|  |     void setLatin(bool latin); | ||||||
|  |     bool latin() const; | ||||||
|  |  | ||||||
|  |     QObject *item() const; | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  |     void dispatchEvents(); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void indexChanged(); | ||||||
|  |     void lineChanged(); | ||||||
|  |     void visibleChanged(); | ||||||
|  |     void textChanged(); | ||||||
|  |     void forgroundColorChanged(); | ||||||
|  |     void backgroundColorChanged(); | ||||||
|  |     void boldChanged(); | ||||||
|  |     void blinkingChanged(); | ||||||
|  |     void underlineChanged(); | ||||||
|  |     void latinChanged(); | ||||||
|  |  | ||||||
|  | private slots: | ||||||
|  |     void paletteChanged(); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void setBackgroundColor(); | ||||||
|  |     void setForgroundColor(); | ||||||
|  |  | ||||||
|  |     Screen *m_screen; | ||||||
|  |     QString m_text; | ||||||
|  |     const QString *m_text_line; | ||||||
|  |     int m_start_index; | ||||||
|  |     int m_old_start_index; | ||||||
|  |     int m_end_index; | ||||||
|  |     int m_line; | ||||||
|  |     int m_old_line; | ||||||
|  |     int m_width; | ||||||
|  |  | ||||||
|  |     TextStyle m_style; | ||||||
|  |     TextStyle m_new_style; | ||||||
|  |  | ||||||
|  |     bool m_style_dirty; | ||||||
|  |     bool m_text_dirty; | ||||||
|  |     bool m_visible; | ||||||
|  |     bool m_visible_old; | ||||||
|  |     bool m_latin; | ||||||
|  |     bool m_latin_old; | ||||||
|  |  | ||||||
|  |     QColor m_forgroundColor; | ||||||
|  |     QColor m_backgroundColor; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // TEXT_SEGMENT_H | ||||||
							
								
								
									
										36
									
								
								yat/backend/text_style.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								yat/backend/text_style.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | #include "text_style.h" | ||||||
|  |  | ||||||
|  | #include "screen.h" | ||||||
|  | #include "text.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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QDebug operator<<(QDebug debug, TextStyleLine line) | ||||||
|  | { | ||||||
|  |     debug << "[" << line.start_index << "(" << line.style << ":" << line.forground << ":" << line.background << ")" << line.end_index << "]"; | ||||||
|  |     return debug; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TextStyleLine::releaseTextSegment(Screen *screen) | ||||||
|  | { | ||||||
|  |     if (text_segment) { | ||||||
|  |         text_segment->setVisible(false); | ||||||
|  |         screen->releaseTextSegment(text_segment); | ||||||
|  |         text_segment = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										85
									
								
								yat/backend/text_style.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								yat/backend/text_style.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | #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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class Text; | ||||||
|  | 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) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void releaseTextSegment(Screen *screen); | ||||||
|  |  | ||||||
|  |     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); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif // TEXT_STYLE_H | ||||||
							
								
								
									
										109
									
								
								yat/backend/utf8_decoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								yat/backend/utf8_decoder.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 UTF8_DECODER | ||||||
|  | #define UTF8_DECODER | ||||||
|  |  | ||||||
|  | #include "controll_chars.h" | ||||||
|  |  | ||||||
|  | class Utf8Decoder | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     inline Utf8Decoder(); | ||||||
|  |  | ||||||
|  |     inline void addChar(uchar character); | ||||||
|  |  | ||||||
|  |     inline bool isLatin() const; | ||||||
|  |     inline bool isC1() const; | ||||||
|  |  | ||||||
|  |     inline void clear(); | ||||||
|  | private: | ||||||
|  |     short m_expected_length; | ||||||
|  |     short m_length; | ||||||
|  |     uint32_t m_unicode; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | Utf8Decoder::Utf8Decoder() | ||||||
|  | { | ||||||
|  |     clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Utf8Decoder::addChar(uchar character) | ||||||
|  | { | ||||||
|  |     if (m_length && m_length == m_expected_length) { | ||||||
|  |         clear(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (character < 0x80) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     fprintf(stderr, "Character: 0x%x\n", character); | ||||||
|  |     if (m_expected_length == 0) { | ||||||
|  |         //this is naive. There must be a faster way. | ||||||
|  |         if ((character & 0xfc) == 0xfc) { | ||||||
|  |             m_expected_length = 5; | ||||||
|  |             m_unicode = character & 0x01; | ||||||
|  |         } else if ((character & 0xf8) == 0xf8) { | ||||||
|  |             m_expected_length = 4; | ||||||
|  |             m_unicode = character & 0x03; | ||||||
|  |         } else if ((character & 0xf0) == 0xf0) { | ||||||
|  |             m_expected_length = 3; | ||||||
|  |             m_unicode = character & 0x07; | ||||||
|  |         } else if ((character & 0xe0) == 0xe0) { | ||||||
|  |             m_expected_length = 2; | ||||||
|  |             m_unicode = character & 0x0f; | ||||||
|  |         } else if ((character & 0xc0) == 0xc0) { | ||||||
|  |             m_expected_length = 1; | ||||||
|  |             m_unicode = character & 0x1f; | ||||||
|  |         } else { | ||||||
|  |             m_expected_length = 0; | ||||||
|  |             m_unicode = 0; | ||||||
|  |             qWarning("Utf8Decoder: invalid decoder character"); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         fprintf(stderr, "Before 0x%x adding 0x%x pure 0x%x\n", m_unicode,(character & 0x3f), character); | ||||||
|  |         m_unicode = (m_unicode << 6) |  (character & 0x3f); | ||||||
|  |         fprintf(stderr, "After 0x%x\n", m_unicode); | ||||||
|  |         m_length++; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Utf8Decoder::isLatin() const | ||||||
|  | { | ||||||
|  |     return m_expected_length < 2 && m_unicode < 0xff; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool Utf8Decoder::isC1() const | ||||||
|  | { | ||||||
|  |     return m_expected_length == 2 && m_length == m_expected_length && | ||||||
|  |         (m_unicode >= C1_8bit::C1_8bit_Start && m_unicode <= C1_8bit::C1_8bit_Stop); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Utf8Decoder::clear() | ||||||
|  | { | ||||||
|  |     m_expected_length = 0; | ||||||
|  |     m_length = 0; | ||||||
|  |     m_unicode = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										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-color", | ||||||
|  |     "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[1024]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #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 = \ | ||||||
|  |     block | ||||||
							
								
								
									
										8
									
								
								yat/tests/auto/block/block.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								yat/tests/auto/block/block.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | CONFIG += testcase | ||||||
|  | QT += testlib quick | ||||||
|  |  | ||||||
|  | include(../../../backend/backend.pri) | ||||||
|  |  | ||||||
|  | SOURCES += \ | ||||||
|  |     tst_block.cpp \ | ||||||
|  |  | ||||||
							
								
								
									
										950
									
								
								yat/tests/auto/block/tst_block.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										950
									
								
								yat/tests/auto/block/tst_block.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,950 @@ | |||||||
|  | #include "../../../backend/block.h" | ||||||
|  | #include <QtTest/QtTest> | ||||||
|  |  | ||||||
|  | #include <QtQml/QQmlEngine> | ||||||
|  | #include "../../../backend/screen.h" | ||||||
|  | #include "../../../backend/screen_data.h" | ||||||
|  |  | ||||||
|  | class BlockHandler | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     BlockHandler(bool fill) { | ||||||
|  |         screen.setHeight(5); | ||||||
|  |         int width = 100; | ||||||
|  |         screen.setWidth(width); | ||||||
|  |         (*screen.currentScreenData()->it_for_row(0))->clear(); | ||||||
|  |         if (fill) { | ||||||
|  |             QString spaces(width, QChar(' ')); | ||||||
|  |             block()->replaceAtPos(0, spaces, screen.defaultTextStyle()); | ||||||
|  |         } | ||||||
|  |         QCOMPARE(block()->style_list().size(), 1); | ||||||
|  |         default_style = block()->style_list().at(0); | ||||||
|  |         default_text_style = default_style.style; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Block *block() const | ||||||
|  |     { | ||||||
|  |         return *screen.currentScreenData()->it_for_row(0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void doneChanges() | ||||||
|  |     { | ||||||
|  |         screen.dispatchChanges(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     TextStyle default_style; | ||||||
|  |     TextStyle::Styles default_text_style; | ||||||
|  |     Screen screen; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class tst_Block: public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private slots: | ||||||
|  |     void replaceStart(); | ||||||
|  |     void replaceEdgeOfStyle(); | ||||||
|  |     void replaceCompatibleStyle(); | ||||||
|  |     void replaceCompatiblePreviousStyle(); | ||||||
|  |     void replaceCompatiblePreviousStyleShouldRemove(); | ||||||
|  |     void replaceCompatibleCurrentStyleShouldRemove(); | ||||||
|  |     void replaceIncompatibleStyle(); | ||||||
|  |     void replaceIncompaitibleStylesCrossesBoundary(); | ||||||
|  |     void replace3IncompatibleStyles(); | ||||||
|  |     void replaceIncomaptibleStylesCrosses2Boundaries(); | ||||||
|  |     void replaceIncompatibleColor(); | ||||||
|  |     void replaceRemoveOverlappedStyles(); | ||||||
|  |     void replaceSwapStyles(); | ||||||
|  |     void replaceEndBlock(); | ||||||
|  |     void clearBlock(); | ||||||
|  |     void clearToEndOfBlock1Segment(); | ||||||
|  |     void clearToEndOfBlock3Segment(); | ||||||
|  |     void clearToEndOfBlockMiddle3Segment(); | ||||||
|  |     void deleteCharacters1Segment(); | ||||||
|  |     void deleteCharacters2Segments(); | ||||||
|  |     void deleteCharacters3Segments(); | ||||||
|  |     void deleteCharactersRemoveSegmentEnd(); | ||||||
|  |     void deleteCharactersRemoveSegmentBeginning(); | ||||||
|  |     void deleteCharactersRemoveMiddle(); | ||||||
|  |     void insertCharacters(); | ||||||
|  |     void insertCharacters2Segments(); | ||||||
|  |     void insertCharacters3Segments(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void tst_Block::replaceStart() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> old_style_list = block->style_list(); | ||||||
|  |     QCOMPARE(old_style_list.size(), 1); | ||||||
|  |  | ||||||
|  |     QString replace_text("This is a test"); | ||||||
|  |     TextStyle textStyle; | ||||||
|  |     textStyle.style = TextStyle::Overlined; | ||||||
|  |     block->replaceAtPos(0,replace_text, textStyle); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> new_style_list = block->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_Block::replaceEdgeOfStyle() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("This is the First"); | ||||||
|  |     TextStyle textStyle; | ||||||
|  |     textStyle.style = TextStyle::Overlined; | ||||||
|  |     block->replaceAtPos(0,first_text, textStyle); | ||||||
|  |  | ||||||
|  |     QString second_text("This is the Second"); | ||||||
|  |     textStyle.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, textStyle); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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_Block::replaceCompatibleStyle() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceed Text"); | ||||||
|  |     block->replaceAtPos(10, replace_text, blockHandler.default_style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->style_list(); | ||||||
|  |     QCOMPARE(after_style_list.size(), 1); | ||||||
|  |     QCOMPARE(after_style_list.at(0).style, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceCompatiblePreviousStyle() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     TextStyle first_style = blockHandler.default_style; | ||||||
|  |     first_style.style = TextStyle::Blinking; | ||||||
|  |     QString first_text("first"); | ||||||
|  |     block->replaceAtPos(0,first_text, first_style); | ||||||
|  |  | ||||||
|  |     TextStyle second_style = blockHandler.default_style; | ||||||
|  |     second_style.style = TextStyle::Bold; | ||||||
|  |     QString second_text("this is the second text"); | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, second_style); | ||||||
|  |  | ||||||
|  |     QString third_text("third"); | ||||||
|  |     block->replaceAtPos(first_text.size(), third_text,first_style); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->style_list(); | ||||||
|  |     QCOMPARE(style_list.size(), 3); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &first_check_style = style_list.at(0); | ||||||
|  |     QCOMPARE(first_check_style.start_index, 0); | ||||||
|  |     QCOMPARE(first_check_style.end_index, (first_text.size() -1) + third_text.size()); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &second_check_style = style_list.at(1); | ||||||
|  |     QCOMPARE(second_check_style.start_index, first_text.size() + third_text.size()); | ||||||
|  |     QCOMPARE(second_check_style.end_index, (first_text.size() -1) + second_text.size()); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &third_check_style = style_list.at(2); | ||||||
|  |     QCOMPARE(third_check_style.start_index, first_text.size() + second_text.size()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceCompatiblePreviousStyleShouldRemove() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     TextStyle first_style = blockHandler.default_style; | ||||||
|  |     first_style.style = TextStyle::Blinking; | ||||||
|  |     QString first_text("first"); | ||||||
|  |     block->replaceAtPos(0,first_text, first_style); | ||||||
|  |  | ||||||
|  |     TextStyle second_style = blockHandler.default_style; | ||||||
|  |     second_style.style = TextStyle::Bold; | ||||||
|  |     QString second_text("second"); | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, second_style); | ||||||
|  |  | ||||||
|  |     QString third_text("this is the third"); | ||||||
|  |     block->replaceAtPos(first_text.size(), third_text,first_style); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->style_list(); | ||||||
|  |     QCOMPARE(style_list.size(), 2); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &first_check_style = style_list.at(0); | ||||||
|  |     QCOMPARE(first_check_style.start_index, 0); | ||||||
|  |     QCOMPARE(first_check_style.end_index, (first_text.size() -1) + third_text.size()); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &second_check_style = style_list.at(1); | ||||||
|  |     QCOMPARE(second_check_style.start_index, first_text.size() + third_text.size()); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceCompatibleCurrentStyleShouldRemove() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     TextStyle first_style = blockHandler.default_style; | ||||||
|  |     first_style.style = TextStyle::Blinking; | ||||||
|  |     QString first_text("first"); | ||||||
|  |     block->replaceAtPos(0,first_text, first_style); | ||||||
|  |  | ||||||
|  |     TextStyle second_style = blockHandler.default_style; | ||||||
|  |     second_style.style = TextStyle::Bold; | ||||||
|  |     QString second_text("second"); | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, second_style); | ||||||
|  |  | ||||||
|  |     QString third_text("second"); | ||||||
|  |     block->replaceAtPos(first_text.size(), third_text,first_style); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->style_list(); | ||||||
|  |     QCOMPARE(style_list.size(), 2); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &first_check_style = style_list.at(0); | ||||||
|  |     QCOMPARE(first_check_style.start_index, 0); | ||||||
|  |     QCOMPARE(first_check_style.end_index, (first_text.size() -1) + third_text.size()); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &second_check_style = style_list.at(1); | ||||||
|  |     QCOMPARE(second_check_style.start_index, first_text.size() + third_text.size()); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceIncompatibleStyle() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceed Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(10, replace_text, replace_style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->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, blockHandler.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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceIncompaitibleStylesCrossesBoundary() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceed Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(0, replace_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString crosses_boundary("New incompatible text"); | ||||||
|  |     replace_style.style = TextStyle::Framed; | ||||||
|  |     int replace_pos = replace_text.size()/2; | ||||||
|  |     block->replaceAtPos(replace_pos, crosses_boundary, replace_style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replace3IncompatibleStyles() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("First Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(0, first_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString second_text("Second Text"); | ||||||
|  |     replace_style.style = TextStyle::Italic; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString third_text("Third Text"); | ||||||
|  |     replace_style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->style_list().size(), 4); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->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_Block::replaceIncomaptibleStylesCrosses2Boundaries() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("First Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(0, first_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString second_text("Second Text"); | ||||||
|  |     replace_style.style = TextStyle::Italic; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString third_text("Third Text"); | ||||||
|  |     replace_style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->style_list().size(), 4); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> before_style_list = block->style_list(); | ||||||
|  |  | ||||||
|  |     QString overlap_first_third; | ||||||
|  |     overlap_first_third.fill(QChar('A'), second_text.size() + 4); | ||||||
|  |     replace_style.style = TextStyle::DoubleUnderlined; | ||||||
|  |     block->replaceAtPos(first_text.size() -2, overlap_first_third, replace_style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->style_list(); | ||||||
|  |     QCOMPARE(block->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, blockHandler.default_text_style); | ||||||
|  |     QCOMPARE(fourth_style.start_index, first_text.size() - 2 + overlap_first_third.size() + third_text.size() - 2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceIncompatibleColor() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("291 "); | ||||||
|  |     TextStyleLine replace_style; | ||||||
|  |     replace_style.forground = ColorPalette::Yellow; | ||||||
|  |     block->replaceAtPos(0,first_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString second_text("QPointF Screen::selectionAreaStart() "); | ||||||
|  |     replace_style.forground = blockHandler.default_style.forground; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString third_text("const"); | ||||||
|  |     replace_style.forground = ColorPalette::Green; | ||||||
|  |     block->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString brackets("()"); | ||||||
|  |     replace_style.forground = ColorPalette::Cyan; | ||||||
|  |     block->replaceAtPos(38, brackets, replace_style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> after_style_list = block->style_list(); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &first_style = after_style_list.at(0); | ||||||
|  |     QCOMPARE(first_style.forground, ColorPalette::Yellow); | ||||||
|  |     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.forground, blockHandler.default_style.forground); | ||||||
|  |     QCOMPARE(second_style.start_index, first_text.size()); | ||||||
|  |     QCOMPARE(second_style.end_index, 37); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &third_style = after_style_list.at(2); | ||||||
|  |     QCOMPARE(third_style.forground, ColorPalette::Cyan); | ||||||
|  |     QCOMPARE(third_style.start_index, 38); | ||||||
|  |     QCOMPARE(third_style.end_index, 38 + brackets.size() -1); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &fourth_style = after_style_list.at(3); | ||||||
|  |     QCOMPARE(fourth_style.forground, blockHandler.default_style.forground); | ||||||
|  |     QCOMPARE(fourth_style.start_index, 38 + brackets.size()); | ||||||
|  |     QCOMPARE(fourth_style.end_index, first_text.size() + second_text.size() -1); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceRemoveOverlappedStyles() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("First Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(0, first_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString second_text("Second Text"); | ||||||
|  |     replace_style.style = TextStyle::Italic; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString third_text("Third Text"); | ||||||
|  |     replace_style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString fourth_text = third_text + second_text; | ||||||
|  |     fourth_text.chop(1); | ||||||
|  |     replace_style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(first_text.size(), fourth_text, replace_style); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->style_list().size(), 4); | ||||||
|  | } | ||||||
|  | void tst_Block::replaceSwapStyles() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString first_text("First Text"); | ||||||
|  |     TextStyle replace_style; | ||||||
|  |     replace_style.style = TextStyle::Blinking; | ||||||
|  |     block->replaceAtPos(0, first_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString second_text("Second Text"); | ||||||
|  |     replace_style.style = TextStyle::Italic; | ||||||
|  |     block->replaceAtPos(first_text.size(), second_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString third_text("Third Text"); | ||||||
|  |     replace_style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(first_text.size() + second_text.size(), third_text, replace_style); | ||||||
|  |  | ||||||
|  |     QString replace_second("Dnoces Text"); | ||||||
|  |     replace_style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(first_text.size(), replace_second, replace_style); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->style_list().size(), 4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::replaceEndBlock() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     QString replace_text("at the end of the string"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(block_size - replace_text.size(), replace_text, style); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), block_size); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, block_size - replace_text.size() -1); | ||||||
|  |     QCOMPARE(first_style.style, blockHandler.default_text_style); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &second_style = style_list.at(1); | ||||||
|  |     QCOMPARE(second_style.start_index, block_size - replace_text.size()); | ||||||
|  |     QCOMPARE(second_style.end_index, block_size - 1); | ||||||
|  |     QCOMPARE(second_style.style, TextStyle::Bold); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::clearBlock() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QVERIFY(block->textLine()->size() > 0); | ||||||
|  |     QCOMPARE(block->textLine()->trimmed().size(), 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::clearToEndOfBlock1Segment() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("To be replaceed"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     int before_clear_size = block->textLine()->size(); | ||||||
|  |  | ||||||
|  |     block->clearCharacters(5, blockHandler.screen.width() -1); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     int after_clear_size = block->textLine()->size(); | ||||||
|  |     QCOMPARE(after_clear_size, before_clear_size); | ||||||
|  |     QVector<TextStyleLine> style_list = block->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(block->textLine()->trimmed(), cleared); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::clearToEndOfBlock3Segment() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("To be"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_text2(" or not to be"); | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block ->replaceAtPos(replace_text.size(), replace_text2, style); | ||||||
|  |  | ||||||
|  |     block->clearCharacters(replace_text.size(), blockHandler.screen.width() - 1); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::clearToEndOfBlockMiddle3Segment() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("To be"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_text2(" or not to be"); | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block ->replaceAtPos(replace_text.size(), replace_text2, style); | ||||||
|  |  | ||||||
|  |     block->clearCharacters(replace_text.size() + 3, blockHandler.screen.width() - 1); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharacters1Segment() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceing some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(10,14); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), block_size - 5); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharacters2Segments() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceing some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(15,25); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), block_size - 11); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharacters3Segments() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceing some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_more_text("Some more text"); | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(replace_text.size(), replace_more_text, style); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(10,15); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), block_size - 6); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharactersRemoveSegmentEnd() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceing some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_more_text("Some more text"); | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(replace_text.size(), replace_more_text, style); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(16,33); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), block_size - ((33 - 16) + 1)); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharactersRemoveSegmentBeginning() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString replace_text("replaceing some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(0, replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_more_text("Some more text"); | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(replace_text.size(), replace_more_text, style); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(replace_text.size(),replace_text.size() + replace_more_text.size() + 3); | ||||||
|  |  | ||||||
|  |     int expected_size = block_size -1 - ((replace_text.size() + replace_more_text.size() + 3 ) - replace_text.size()); | ||||||
|  |     QCOMPARE(block->textLine()->size(), expected_size); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::deleteCharactersRemoveMiddle() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString insert_text('A'); | ||||||
|  |     int old_width = blockHandler.screen.width(); | ||||||
|  |     QString empty(old_width - 2, ' '); | ||||||
|  |     insert_text += empty + 'B'; | ||||||
|  |     block->replaceAtPos(0, insert_text, blockHandler.default_style); | ||||||
|  |  | ||||||
|  |     Q_ASSERT(old_width == blockHandler.screen.width()); | ||||||
|  |     Q_ASSERT(insert_text == *block->textLine()); | ||||||
|  |  | ||||||
|  |     block->deleteCharacters(1, old_width - 2); | ||||||
|  |  | ||||||
|  |     Q_ASSERT(QString("AB") == block->textLine()->trimmed()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::insertCharacters() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     QString insert_text("inserting some text"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->insertAtPos(5, insert_text, style); | ||||||
|  |  | ||||||
|  |     int expected_size = block_size + insert_text.size(); | ||||||
|  |  | ||||||
|  |     QCOMPARE(block->textLine()->size(), expected_size); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.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, expected_size - 1); | ||||||
|  |     QCOMPARE(third_style.style, blockHandler.default_text_style); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::insertCharacters2Segments() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     QString replace_text("at the end of the string"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(block_size - replace_text.size(), replace_text, style); | ||||||
|  |  | ||||||
|  |     QString insert_text("inserting some text"); | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->insertAtPos(5, insert_text, style); | ||||||
|  |  | ||||||
|  |     int expected_size = block_size + insert_text.size(); | ||||||
|  |     QCOMPARE(block->textLine()->size(), expected_size); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> style_list = block->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, blockHandler.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, block_size -1 - replace_text.size() + insert_text.size()); | ||||||
|  |     QCOMPARE(third_style.style, blockHandler.default_text_style); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &fourth_style = style_list.at(3); | ||||||
|  |     QCOMPARE(fourth_style.start_index, block_size - replace_text.size() + insert_text.size()); | ||||||
|  |     QCOMPARE(fourth_style.end_index, expected_size - 1 ); | ||||||
|  |     QCOMPARE(fourth_style.style, TextStyle::Bold); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tst_Block::insertCharacters3Segments() | ||||||
|  | { | ||||||
|  |     BlockHandler blockHandler(true); | ||||||
|  |     Block *block = blockHandler.block(); | ||||||
|  |  | ||||||
|  |     QString *full_block = block->textLine(); | ||||||
|  |     int block_size = full_block->size(); | ||||||
|  |  | ||||||
|  |     QString replace_text("at the end of the string"); | ||||||
|  |     TextStyle style = blockHandler.default_style; | ||||||
|  |     style.style = TextStyle::Bold; | ||||||
|  |     block->replaceAtPos(block_size - replace_text.size(), replace_text, style); | ||||||
|  |  | ||||||
|  |     QString replace_text2("somewhere in the string"); | ||||||
|  |     style.style = TextStyle::Encircled; | ||||||
|  |     block->replaceAtPos(20,replace_text2, style); | ||||||
|  |  | ||||||
|  |     QVector<TextStyleLine> tmp_style_list = block->style_list(); | ||||||
|  |     QCOMPARE(tmp_style_list.size(), 4); | ||||||
|  |  | ||||||
|  |     QString insert_text("this text is longer than last segment"); | ||||||
|  |     style.style = TextStyle::Italic; | ||||||
|  |     block->insertAtPos(10, insert_text, style); | ||||||
|  |  | ||||||
|  |     blockHandler.doneChanges(); | ||||||
|  |  | ||||||
|  |     int expected_size = block_size + insert_text.size(); | ||||||
|  |     QCOMPARE(block->textLine()->size(), expected_size); | ||||||
|  |  | ||||||
|  |     block->printStyleList(); | ||||||
|  |     QVector<TextStyleLine> style_list = block->style_list(); | ||||||
|  |     QCOMPARE(style_list.size(), 6); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &first_style = style_list.at(0); | ||||||
|  |     QCOMPARE(first_style.start_index, 0); | ||||||
|  |     QCOMPARE(first_style.end_index, 9); | ||||||
|  |     QCOMPARE(first_style.style, blockHandler.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, blockHandler.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, block_size - replace_text.size() + insert_text.size() - 1); | ||||||
|  |     QCOMPARE(fith_style.style, blockHandler.default_text_style); | ||||||
|  |  | ||||||
|  |     const TextStyleLine &sixth_style = style_list.at(5); | ||||||
|  |     QCOMPARE(sixth_style.start_index, block_size - replace_text.size() + insert_text.size()); | ||||||
|  |     QCOMPARE(sixth_style.end_index, block_size + insert_text.size() - 1); | ||||||
|  |     QCOMPARE(sixth_style.style, TextStyle::Bold); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include <tst_block.moc> | ||||||
|  | QTEST_MAIN(tst_Block); | ||||||
							
								
								
									
										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 | ||||||
							
								
								
									
										46
									
								
								yat/yat_declarative/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								yat/yat_declarative/main.cpp
									
									
									
									
									
										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. | ||||||
|  | * | ||||||
|  | ***************************************************************************************************/ | ||||||
|  |  | ||||||
|  | #include <QtGui/QGuiApplication> | ||||||
|  | #include <QtCore/QResource> | ||||||
|  | #include <QtCore/QThread> | ||||||
|  |  | ||||||
|  | #include <QQmlEngine> | ||||||
|  |  | ||||||
|  | #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(); | ||||||
|  |  | ||||||
|  |     QQmlEngine engine; | ||||||
|  |     QQmlComponent component(&engine, QUrl("qrc:/qml/yat_declarative/main.qml")); | ||||||
|  |     auto errors = component.errors(); | ||||||
|  |     for (int i = 0; i < errors.size(); i++) { | ||||||
|  |         qDebug() << errors.at(i).toString(); | ||||||
|  |     } | ||||||
|  |     component.create(); | ||||||
|  |  | ||||||
|  |     return app.exec(); | ||||||
|  | } | ||||||
							
								
								
									
										249
									
								
								yat/yat_declarative/mono_text.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								yat/yat_declarative/mono_text.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | |||||||
|  | /****************************************************************************** | ||||||
|  | * 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 "mono_text.h" | ||||||
|  |  | ||||||
|  | #include <QtQuick/private/qsgadaptationlayer_p.h> | ||||||
|  | #include <QtQuick/private/qsgrenderer_p.h> | ||||||
|  | #include <QtQuick/private/qquickitem_p.h> | ||||||
|  | #include <QtQuick/private/qquicktextnode_p.h> | ||||||
|  | #include <QtGui/QTextLayout> | ||||||
|  |  | ||||||
|  | class MonoSGNode : public QSGTransformNode | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     MonoSGNode(QQuickItem *owner) | ||||||
|  |         : m_owner(owner) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void deleteContent() | ||||||
|  |     { | ||||||
|  |         QSGNode *subnode = firstChild(); | ||||||
|  |         while (subnode) { | ||||||
|  |             // We can't delete the node now as it might be in the preprocess list | ||||||
|  |             // It will be deleted in the next preprocess | ||||||
|  |             m_nodes_to_delete.append(subnode); | ||||||
|  |             subnode = subnode->nextSibling(); | ||||||
|  |         } | ||||||
|  |         removeAllChildNodes(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void preprocess() | ||||||
|  |     { | ||||||
|  |         while (m_nodes_to_delete.count()) | ||||||
|  |             delete m_nodes_to_delete.takeLast(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void setLatinText(const QString &text, const QFont &font, const QColor &color) { | ||||||
|  |         QRawFont raw_font = QRawFont::fromFont(font, QFontDatabase::Latin); | ||||||
|  |  | ||||||
|  |         if (raw_font != m_raw_font) { | ||||||
|  |             m_raw_font = raw_font; | ||||||
|  |             m_positions.clear(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (m_positions.size() < text.size()) { | ||||||
|  |             qreal x_pos = 0; | ||||||
|  |             qreal max_char_width = raw_font.averageCharWidth(); | ||||||
|  |             qreal ascent = raw_font.ascent(); | ||||||
|  |             if (m_positions.size()) | ||||||
|  |                 x_pos = m_positions.last().x() + max_char_width; | ||||||
|  |             int to_add = text.size() - m_positions.size(); | ||||||
|  |             for (int i = 0; i < to_add; i++) { | ||||||
|  |                 m_positions << QPointF(x_pos, ascent); | ||||||
|  |                 x_pos += max_char_width; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         deleteContent(); | ||||||
|  |         QSGRenderContext *sgr = QQuickItemPrivate::get(m_owner)->sceneGraphRenderContext(); | ||||||
|  |         QSGGlyphNode *node = sgr->sceneGraphContext()->createGlyphNode(sgr); | ||||||
|  |         node->setOwnerElement(m_owner); | ||||||
|  |         node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern); | ||||||
|  |         node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern); | ||||||
|  |         node->setStyle(QQuickText::Normal); | ||||||
|  |  | ||||||
|  |         node->setColor(color); | ||||||
|  |         QGlyphRun glyphrun; | ||||||
|  |         glyphrun.setRawFont(raw_font); | ||||||
|  |         glyphrun.setGlyphIndexes(raw_font.glyphIndexesForString(text)); | ||||||
|  |  | ||||||
|  |         glyphrun.setPositions(m_positions); | ||||||
|  |         node->setGlyphs(QPointF(0, raw_font.ascent()), glyphrun); | ||||||
|  |         node->update(); | ||||||
|  |         appendChildNode(node); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void setUnicodeText(const QString &text, const QFont &font, const QColor &color) | ||||||
|  |     { | ||||||
|  |         deleteContent(); | ||||||
|  |         QRawFont raw_font = QRawFont::fromFont(font, QFontDatabase::Latin); | ||||||
|  |         qreal line_width = raw_font.averageCharWidth() * text.size(); | ||||||
|  |         QSGRenderContext *sgr = QQuickItemPrivate::get(m_owner)->sceneGraphRenderContext(); | ||||||
|  |         QTextLayout layout(text,font); | ||||||
|  |         layout.beginLayout(); | ||||||
|  |         QTextLine line = layout.createLine(); | ||||||
|  |         line.setLineWidth(line_width); | ||||||
|  |         //Q_ASSERT(!layout.createLine().isValid()); | ||||||
|  |         layout.endLayout(); | ||||||
|  |         QList<QGlyphRun> glyphRuns = line.glyphRuns(); | ||||||
|  |         qreal xpos = 0; | ||||||
|  |         for (int i = 0; i < glyphRuns.size(); i++) { | ||||||
|  |             QSGGlyphNode *node = sgr->sceneGraphContext()->createGlyphNode(sgr); | ||||||
|  |             node->setOwnerElement(m_owner); | ||||||
|  |             node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern); | ||||||
|  |             node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern); | ||||||
|  |             node->setGlyphs(QPointF(xpos, raw_font.ascent()), glyphRuns.at(i)); | ||||||
|  |             node->setStyle(QQuickText::Normal); | ||||||
|  |             node->setColor(color); | ||||||
|  |             xpos += raw_font.averageCharWidth() * glyphRuns.at(i).positions().size(); | ||||||
|  |             node->update(); | ||||||
|  |             appendChildNode(node); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | private: | ||||||
|  |     QQuickItem *m_owner; | ||||||
|  |     QVector<QPointF> m_positions; | ||||||
|  |     QLinkedList<QSGNode *> m_nodes_to_delete; | ||||||
|  |     QRawFont m_raw_font; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | MonoText::MonoText(QQuickItem *parent) | ||||||
|  |     : QQuickItem(parent) | ||||||
|  |     , m_color_changed(false) | ||||||
|  |     , m_latin(true) | ||||||
|  |     , m_old_latin(true) | ||||||
|  | { | ||||||
|  |     setFlag(ItemHasContents, true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | MonoText::~MonoText() | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QString MonoText::text() const | ||||||
|  | { | ||||||
|  |     return m_text; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MonoText::setText(const QString &text) | ||||||
|  | { | ||||||
|  |     if (m_text != text) { | ||||||
|  |         m_text = text; | ||||||
|  |         emit textChanged(); | ||||||
|  |         polish(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QFont MonoText::font() const | ||||||
|  | { | ||||||
|  |     return m_font; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MonoText::setFont(const QFont &font) | ||||||
|  | { | ||||||
|  |     if (font != m_font) { | ||||||
|  |         m_font = font; | ||||||
|  |         emit fontChanged(); | ||||||
|  |         polish(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor MonoText::color() const | ||||||
|  | { | ||||||
|  |     return m_color; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MonoText::setColor(const QColor &color) | ||||||
|  | { | ||||||
|  |     if (m_color != color) { | ||||||
|  |         m_color = color; | ||||||
|  |         emit colorChanged(); | ||||||
|  |         update(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | qreal MonoText::paintedWidth() const | ||||||
|  | { | ||||||
|  |     return implicitWidth(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | qreal MonoText::paintedHeight() const | ||||||
|  | { | ||||||
|  |     return implicitHeight(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool MonoText::latin() const | ||||||
|  | { | ||||||
|  |     return m_latin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MonoText::setLatin(bool latin) | ||||||
|  | { | ||||||
|  |     if (latin == m_latin) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     m_latin = latin; | ||||||
|  |     emit latinChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QSGNode *MonoText::updatePaintNode(QSGNode *old, UpdatePaintNodeData *) | ||||||
|  | { | ||||||
|  |     if (m_text.size() == 0 || m_text.trimmed().size() == 0) { | ||||||
|  |         delete old; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     MonoSGNode *node = static_cast<MonoSGNode *>(old); | ||||||
|  |     if (!node) { | ||||||
|  |         node = new MonoSGNode(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_latin) { | ||||||
|  |         node->setLatinText(m_text, m_font, m_color); | ||||||
|  |     } else { | ||||||
|  |         node->setUnicodeText(m_text, m_font, m_color); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return node; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MonoText::updatePolish() | ||||||
|  | { | ||||||
|  |         QRawFont raw_font = QRawFont::fromFont(m_font, QFontDatabase::Latin); | ||||||
|  |  | ||||||
|  |         qreal height = raw_font.descent() + raw_font.ascent() + raw_font.lineThickness(); | ||||||
|  |         qreal width = raw_font.averageCharWidth() * m_text.size(); | ||||||
|  |  | ||||||
|  |         bool emit_text_width_changed = width != implicitWidth(); | ||||||
|  |         bool emit_text_height_changed = height != implicitHeight(); | ||||||
|  |         setImplicitSize(width, height); | ||||||
|  |  | ||||||
|  |         if (emit_text_width_changed) | ||||||
|  |             emit paintedWidthChanged(); | ||||||
|  |         if (emit_text_height_changed) | ||||||
|  |             emit paintedHeightChanged(); | ||||||
|  |  | ||||||
|  |         update(); | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								yat/yat_declarative/mono_text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								yat/yat_declarative/mono_text.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 MONO_TEXT_H | ||||||
|  | #define MONO_TEXT_H | ||||||
|  |  | ||||||
|  | #include <QtQuick/QQuickItem> | ||||||
|  | #include <QtGui/QRawFont> | ||||||
|  |  | ||||||
|  | class MonoText : public QQuickItem | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |     Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) | ||||||
|  |     Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) | ||||||
|  |     Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) | ||||||
|  |     Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedWidthChanged) | ||||||
|  |     Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedHeightChanged) | ||||||
|  |     Q_PROPERTY(bool latin READ latin WRITE setLatin NOTIFY latinChanged); | ||||||
|  | public: | ||||||
|  |     MonoText(QQuickItem *parent=0); | ||||||
|  |     ~MonoText(); | ||||||
|  |  | ||||||
|  |     QString text() const; | ||||||
|  |     void setText(const QString &text); | ||||||
|  |  | ||||||
|  |     QFont font() const; | ||||||
|  |     void setFont(const QFont &font); | ||||||
|  |  | ||||||
|  |     QColor color() const; | ||||||
|  |     void setColor(const QColor &color); | ||||||
|  |  | ||||||
|  |     qreal paintedWidth() const; | ||||||
|  |     qreal paintedHeight() const; | ||||||
|  |  | ||||||
|  |     bool latin() const; | ||||||
|  |     void setLatin(bool latin); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void textChanged(); | ||||||
|  |     void fontChanged(); | ||||||
|  |     void colorChanged(); | ||||||
|  |     void paintedWidthChanged(); | ||||||
|  |     void paintedHeightChanged(); | ||||||
|  |     void latinChanged(); | ||||||
|  | protected: | ||||||
|  |     QSGNode *updatePaintNode(QSGNode *old, UpdatePaintNodeData *data) Q_DECL_OVERRIDE; | ||||||
|  |     void updatePolish() Q_DECL_OVERRIDE; | ||||||
|  | private: | ||||||
|  |     Q_DISABLE_COPY(MonoText); | ||||||
|  |     void updateSize(); | ||||||
|  |  | ||||||
|  |     QString m_text; | ||||||
|  |     QFont m_font; | ||||||
|  |     QColor m_color; | ||||||
|  |     bool m_color_changed; | ||||||
|  |     bool m_latin; | ||||||
|  |     bool m_old_latin; | ||||||
|  |     QSizeF m_text_size; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										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 | ||||||
							
								
								
									
										104
									
								
								yat/yat_declarative/qml/yat_declarative/HighlightArea.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								yat/yat_declarative/qml/yat_declarative/HighlightArea.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 | ||||||
|  |  | ||||||
|  | Item { | ||||||
|  |     id: highlightArea | ||||||
|  |  | ||||||
|  |     property real characterWidth: 0 | ||||||
|  |     property real characterHeight: 0 | ||||||
|  |     property int screenWidth: 0 | ||||||
|  |  | ||||||
|  |     property int startX | ||||||
|  |     property int startY | ||||||
|  |  | ||||||
|  |     property int endX | ||||||
|  |     property int endY | ||||||
|  |  | ||||||
|  |     property color color: "grey" | ||||||
|  |  | ||||||
|  |     y: startY * characterHeight | ||||||
|  |     width: parent.width | ||||||
|  |     height: (endY - startY + 1) * characterHeight | ||||||
|  |  | ||||||
|  |     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(); | ||||||
|  |  | ||||||
|  |     onStartXChanged: calculateRectangles(); | ||||||
|  |     onStartYChanged: calculateRectangles(); | ||||||
|  |     onEndXChanged: calculateRectangles(); | ||||||
|  |     onEndYChanged: calculateRectangles(); | ||||||
|  |  | ||||||
|  |     function calculateRectangles() { | ||||||
|  |         highlightArea.y = startY * characterHeight; | ||||||
|  |         begginning_rectangle.x = startX * characterWidth; | ||||||
|  |         if (startY === endY) { | ||||||
|  |             middle_rectangle.visible = false; | ||||||
|  |             end_rectangle.visible = false | ||||||
|  |             begginning_rectangle.width = (endX - startX) * characterWidth; | ||||||
|  |         } else { | ||||||
|  |             begginning_rectangle.width = (screenWidth - startX) * characterWidth; | ||||||
|  |             if (startY === endY - 1) { | ||||||
|  |                 middle_rectangle.height = 0; | ||||||
|  |                 middle_rectangle.visible = false; | ||||||
|  |             }else { | ||||||
|  |                 middle_rectangle.visible = true; | ||||||
|  |                 middle_rectangle.height = (endY - startY - 1) * characterHeight; | ||||||
|  |             } | ||||||
|  |             end_rectangle.visible = true; | ||||||
|  |             end_rectangle.width = endX * characterWidth; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalCursor.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalCursor.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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: cursor | ||||||
|  |  | ||||||
|  |     property real fontHeight | ||||||
|  |     property real fontWidth | ||||||
|  |  | ||||||
|  |     height: fontHeight | ||||||
|  |     width: fontWidth | ||||||
|  |     x: objectHandle.x * fontWidth | ||||||
|  |     y: objectHandle.y * fontHeight | ||||||
|  |     z: 1.1 | ||||||
|  |  | ||||||
|  |     visible: objectHandle.visible | ||||||
|  |  | ||||||
|  |     ShaderEffect { | ||||||
|  |         anchors.fill: parent | ||||||
|  |  | ||||||
|  |         property variant source: fragmentSource | ||||||
|  |  | ||||||
|  |         fragmentShader: | ||||||
|  |             "uniform lowp float qt_Opacity;" + | ||||||
|  |             "uniform sampler2D source;" + | ||||||
|  |             "varying highp vec2 qt_TexCoord0;" + | ||||||
|  |  | ||||||
|  |             "void main() {" + | ||||||
|  |             "   lowp vec4 color = texture2D(source, qt_TexCoord0 ) * qt_Opacity;" + | ||||||
|  |             "   gl_FragColor = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b, color.a);" + | ||||||
|  |             "}" | ||||||
|  |  | ||||||
|  |         ShaderEffectSource { | ||||||
|  |             id: fragmentSource | ||||||
|  |             sourceItem: background | ||||||
|  |             live: true | ||||||
|  |  | ||||||
|  |             sourceRect: Qt.rect(cursor.x,cursor.y,cursor.width,cursor.height); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										285
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalScreen.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalScreen.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,285 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 QtQuick.Controls 1.1 | ||||||
|  |  | ||||||
|  | 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") | ||||||
|  |     property var textComponent : Qt.createComponent("TerminalText.qml") | ||||||
|  |     property var cursorComponent : Qt.createComponent("TerminalCursor.qml") | ||||||
|  |  | ||||||
|  |     font.family: "menlo" | ||||||
|  |     focus: true | ||||||
|  |  | ||||||
|  |     Action { | ||||||
|  |         id: copyAction | ||||||
|  |         shortcut: "Ctrl+Shift+C" | ||||||
|  |         onTriggered: screen.selection.sendToClipboard() | ||||||
|  |     } | ||||||
|  |     Action { | ||||||
|  |         id: paseAction | ||||||
|  |         shortcut: "Ctrl+Shift+V" | ||||||
|  |         onTriggered: screen.selection.pasteFromClipboard() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onActiveFocusChanged: { | ||||||
|  |         if (activeFocus) { | ||||||
|  |             Qt.inputMethod.show(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Keys.onPressed: { | ||||||
|  |         if (event.text === "?") { | ||||||
|  |             terminal.screen.printScreen() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Text { | ||||||
|  |         id: fontMetricText | ||||||
|  |         text: "B" | ||||||
|  |         font: parent.font | ||||||
|  |         visible: false | ||||||
|  |         textFormat: Text.PlainText | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Flickable { | ||||||
|  |         id: flickable | ||||||
|  |         anchors.top: parent.top | ||||||
|  |         anchors.left: parent.left | ||||||
|  |         contentWidth: width | ||||||
|  |         contentHeight: textContainer.height | ||||||
|  |         interactive: true | ||||||
|  |         flickableDirection: Flickable.VerticalFlick | ||||||
|  |         contentY: ((screen.contentHeight - screen.height) * screenItem.fontHeight) | ||||||
|  |  | ||||||
|  |         Item { | ||||||
|  |             id: textContainer | ||||||
|  |             width: parent.width | ||||||
|  |             height: screen.contentHeight * screenItem.fontHeight | ||||||
|  |             Rectangle { | ||||||
|  |                 id: background | ||||||
|  |                 anchors.fill: parent | ||||||
|  |                 color: terminal.screen.defaultBackgroundColor | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             HighlightArea { | ||||||
|  |                 characterHeight: fontHeight | ||||||
|  |                 characterWidth: fontWidth | ||||||
|  |                 screenWidth: terminalWindow.width | ||||||
|  |  | ||||||
|  |                 startX: screen.selection.startX | ||||||
|  |                 startY: screen.selection.startY | ||||||
|  |  | ||||||
|  |                 endX: screen.selection.endX | ||||||
|  |                 endY: screen.selection.endY | ||||||
|  |  | ||||||
|  |                 visible: screen.selection.enable | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onContentYChanged: { | ||||||
|  |             if (!atYEnd) { | ||||||
|  |                 var top_line = Math.floor(Math.max(contentY,0) / screenItem.fontHeight); | ||||||
|  |                 screen.ensureVisiblePages(top_line); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Connections { | ||||||
|  |         id: connections | ||||||
|  |  | ||||||
|  |         target: terminal.screen | ||||||
|  |  | ||||||
|  |         onFlash: { | ||||||
|  |             flashAnimation.start() | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onReset: { | ||||||
|  |             resetScreenItems(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onTextCreated: { | ||||||
|  |             var textSegment = textComponent.createObject(screenItem, | ||||||
|  |                 { | ||||||
|  |                     "parent" : background, | ||||||
|  |                     "objectHandle" : text, | ||||||
|  |                     "font" : screenItem.font, | ||||||
|  |                     "fontWidth" : screenItem.fontWidth, | ||||||
|  |                     "fontHeight" : screenItem.fontHeight, | ||||||
|  |                 }) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onCursorCreated: { | ||||||
|  |             if (cursorComponent.status != Component.Ready) { | ||||||
|  |                 console.log(cursorComponent.errorString()); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             var cursorVariable = cursorComponent.createObject(screenItem, | ||||||
|  |                 { | ||||||
|  |                     "parent" : textContainer, | ||||||
|  |                     "objectHandle" : cursor, | ||||||
|  |                     "fontWidth" : screenItem.fontWidth, | ||||||
|  |                     "fontHeight" : screenItem.fontHeight, | ||||||
|  |                 }) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onRequestHeightChange: { | ||||||
|  |             terminalWindow.height = newHeight * screenItem.fontHeight; | ||||||
|  |             terminalWindow.contentItem.height = newHeight * screenItem.fontHeight; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onRequestWidthChange: { | ||||||
|  |             terminalWindow.width = newWidth * screenItem.fontWidth; | ||||||
|  |             terminalWindow.contentItem.width = newWidth * screenItem.fontWidth; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onFontChanged: { | ||||||
|  |         setTerminalHeight(); | ||||||
|  |         setTerminalWidth(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onWidthChanged: { | ||||||
|  |         setTerminalWidth(); | ||||||
|  |     } | ||||||
|  |     onHeightChanged: { | ||||||
|  |         setTerminalHeight(); | ||||||
|  |     } | ||||||
|  |     Component.onCompleted: { | ||||||
|  |         setTerminalWidth(); | ||||||
|  |         setTerminalHeight(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function setTerminalWidth() { | ||||||
|  |         if (fontWidth > 0) { | ||||||
|  |             var pty_width = Math.floor(width / fontWidth); | ||||||
|  |             flickable.width = pty_width * fontWidth; | ||||||
|  |             screen.width = pty_width; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function setTerminalHeight() { | ||||||
|  |         if (fontHeight > 0) { | ||||||
|  |             var pty_height = Math.floor(height / fontHeight); | ||||||
|  |             flickable.height = pty_height * fontHeight; | ||||||
|  |             screen.height = pty_height; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Rectangle { | ||||||
|  |         id: flash | ||||||
|  |         z: 1.2 | ||||||
|  |         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 int drag_start_x | ||||||
|  |         property int drag_start_y | ||||||
|  |  | ||||||
|  |         anchors.fill: parent | ||||||
|  |         acceptedButtons: Qt.LeftButton | Qt.MiddleButton | ||||||
|  |         onPressed: { | ||||||
|  |             if (mouse.button == Qt.LeftButton) { | ||||||
|  |                 hoverEnabled = true; | ||||||
|  |                 var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|  |                 var character = Math.floor((transformed_mouse.x / fontWidth)); | ||||||
|  |                 var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|  |                 var start = Qt.point(character,line); | ||||||
|  |                 drag_start_x = character; | ||||||
|  |                 drag_start_y = line; | ||||||
|  |                 screen.selection.startX = character; | ||||||
|  |                 screen.selection.startY = line; | ||||||
|  |                 screen.selection.endX = character; | ||||||
|  |                 screen.selection.endY = line; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onPositionChanged: { | ||||||
|  |             var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|  |             var character = Math.floor(transformed_mouse.x / fontWidth); | ||||||
|  |             var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|  |             var current_pos = Qt.point(character,line); | ||||||
|  |             if (line < drag_start_y || (line === drag_start_y && character < drag_start_x)) { | ||||||
|  |                 screen.selection.startX = character; | ||||||
|  |                 screen.selection.startY = line; | ||||||
|  |                 screen.selection.endX = drag_start_x; | ||||||
|  |                 screen.selection.endY = drag_start_y; | ||||||
|  |             }else { | ||||||
|  |                 screen.selection.startX = drag_start_x; | ||||||
|  |                 screen.selection.startY = drag_start_y; | ||||||
|  |                 screen.selection.endX = character; | ||||||
|  |                 screen.selection.endY = line; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onReleased: { | ||||||
|  |             if (mouse.button == Qt.LeftButton) { | ||||||
|  |                 hoverEnabled = false; | ||||||
|  |                 screen.selection.sendToSelection(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onClicked: { | ||||||
|  |             if (mouse.button == Qt.MiddleButton) { | ||||||
|  |                 screen.pasteFromSelection(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         onDoubleClicked: { | ||||||
|  |             if (mouse.button == Qt.LeftButton) { | ||||||
|  |                 var transformed_mouse = mapToItem(textContainer, mouse.x, mouse.y); | ||||||
|  |                 var character = Math.floor(transformed_mouse.x / fontWidth); | ||||||
|  |                 var line = Math.floor(transformed_mouse.y / fontHeight); | ||||||
|  |                 screen.doubleClicked(Qt.point(character,line)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalText.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								yat/yat_declarative/qml/yat_declarative/TerminalText.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 | ||||||
|  |     property real fontHeight | ||||||
|  |  | ||||||
|  |     y: objectHandle.line * fontHeight; | ||||||
|  |     x: objectHandle.index * fontWidth; | ||||||
|  |  | ||||||
|  |     width: textElement.paintedWidth | ||||||
|  |     height: textElement.paintedHeight | ||||||
|  |  | ||||||
|  |     visible: objectHandle.visible | ||||||
|  |  | ||||||
|  |     Rectangle { | ||||||
|  |         anchors.fill: parent | ||||||
|  |         color: objectHandle.backgroundColor | ||||||
|  |  | ||||||
|  |         MonoText { | ||||||
|  |             id: textElement | ||||||
|  |             anchors.fill: parent | ||||||
|  |             text: objectHandle.text | ||||||
|  |             color: objectHandle.foregroundColor | ||||||
|  |             font.family: textItem.font.family | ||||||
|  |             font.pixelSize: textItem.font.pixelSize | ||||||
|  |             font.pointSize: textItem.font.pointSize | ||||||
|  |             font.bold: objectHandle.bold | ||||||
|  |             font.underline: objectHandle.underline | ||||||
|  |             latin: objectHandle.latin | ||||||
|  |  | ||||||
|  |             SequentialAnimation { | ||||||
|  |                 running: objectHandle.blinking | ||||||
|  |                 loops: Animation.Infinite | ||||||
|  |                 onRunningChanged: { | ||||||
|  |                     if (running === false) | ||||||
|  |                         textElement.opacity = 1 | ||||||
|  |                 } | ||||||
|  |                 NumberAnimation { | ||||||
|  |                     target: textElement | ||||||
|  |                     property: "opacity" | ||||||
|  |                     to: 0 | ||||||
|  |                     duration: 250 | ||||||
|  |                 } | ||||||
|  |                 NumberAnimation { | ||||||
|  |                     target: textElement | ||||||
|  |                     property: "opacity" | ||||||
|  |                     to: 1 | ||||||
|  |                     duration: 250 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								yat/yat_declarative/qml/yat_declarative/main.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								yat/yat_declarative/qml/yat_declarative/main.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  | * 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 QtQuick.Window 2.0 | ||||||
|  |  | ||||||
|  | Window { | ||||||
|  |     id: terminalWindow | ||||||
|  |     TerminalScreen { | ||||||
|  |         id: terminal | ||||||
|  |         anchors.fill: parent | ||||||
|  |         Component.onCompleted: terminalWindow.visible = true | ||||||
|  |     } | ||||||
|  |     width: 800 | ||||||
|  |     height: 600 | ||||||
|  |     color: terminal.screen.defaultBackgroundColor | ||||||
|  | } | ||||||
							
								
								
									
										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/TerminalScreen.qml</file> | ||||||
|  |         <file>qml/yat_declarative/TerminalText.qml</file> | ||||||
|  |         <file>qml/yat_declarative/TerminalCursor.qml</file> | ||||||
|  |         <file>qml/yat_declarative/HighlightArea.qml</file> | ||||||
|  |     </qresource> | ||||||
|  | </RCC> | ||||||
							
								
								
									
										22
									
								
								yat/yat_declarative/register_qml_types.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								yat/yat_declarative/register_qml_types.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | #include "register_qml_types.h" | ||||||
|  |  | ||||||
|  | #include <QtQml> | ||||||
|  |  | ||||||
|  | #include "terminal_screen.h" | ||||||
|  | #include "object_destruct_item.h" | ||||||
|  | #include "screen.h" | ||||||
|  | #include "text.h" | ||||||
|  | #include "cursor.h" | ||||||
|  | #include "mono_text.h" | ||||||
|  | #include "selection.h" | ||||||
|  |  | ||||||
|  | void register_qml_types() | ||||||
|  | { | ||||||
|  |     qmlRegisterType<TerminalScreen>("org.yat", 1, 0, "TerminalScreen"); | ||||||
|  |     qmlRegisterType<ObjectDestructItem>("org.yat", 1, 0, "ObjectDestructItem"); | ||||||
|  |     qmlRegisterType<MonoText>("org.yat", 1, 0, "MonoText"); | ||||||
|  |     qmlRegisterType<Screen>(); | ||||||
|  |     qmlRegisterType<Text>(); | ||||||
|  |     qmlRegisterType<Cursor>(); | ||||||
|  |     qmlRegisterType<Selection>(); | ||||||
|  | } | ||||||
							
								
								
									
										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 | ||||||
							
								
								
									
										65
									
								
								yat/yat_declarative/terminal_screen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								yat/yat_declarative/terminal_screen.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | /************************************************************************************************** | ||||||
|  | * 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)) | ||||||
|  | { | ||||||
|  |     setFlag(QQuickItem::ItemAcceptsInputMethod); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Screen *TerminalScreen::screen() const | ||||||
|  | { | ||||||
|  |     return m_screen; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QVariant TerminalScreen::inputMethodQuery(Qt::InputMethodQuery query) const | ||||||
|  | { | ||||||
|  |     switch (query) { | ||||||
|  |     case Qt::ImEnabled: | ||||||
|  |         return QVariant(true); | ||||||
|  |     case Qt::ImHints: | ||||||
|  |         return QVariant(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); | ||||||
|  |     default: | ||||||
|  |         return QVariant(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TerminalScreen::inputMethodEvent(QInputMethodEvent *event) | ||||||
|  | { | ||||||
|  |     QString commitString = event->commitString(); | ||||||
|  |     if (commitString.isEmpty()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Qt::Key key = Qt::Key_unknown; | ||||||
|  |     if (commitString == " ") { | ||||||
|  |         key = Qt::Key_Space; // screen requires | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_screen->sendKey(commitString, key, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TerminalScreen::keyPressEvent(QKeyEvent *event) | ||||||
|  | { | ||||||
|  |     m_screen->sendKey(event->text(), Qt::Key(event->key()), event->modifiers()); | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								yat/yat_declarative/terminal_screen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								yat/yat_declarative/terminal_screen.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 TERMINALITEM_H | ||||||
|  | #define TERMINALITEM_H | ||||||
|  |  | ||||||
|  | #include <QtCore/QObject> | ||||||
|  | #include <QtQuick/QQuickItem> | ||||||
|  | #include <QInputMethodEvent> | ||||||
|  | #include <QKeyEvent> | ||||||
|  |  | ||||||
|  | #include "screen.h" | ||||||
|  |  | ||||||
|  | class TerminalScreen : public QQuickItem | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  |     Q_PROPERTY(Screen *screen READ screen CONSTANT) | ||||||
|  | public: | ||||||
|  |     TerminalScreen(QQuickItem *parent = 0); | ||||||
|  |  | ||||||
|  |     Screen *screen() const; | ||||||
|  |  | ||||||
|  |     QVariant inputMethodQuery(Qt::InputMethodQuery query) const; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void inputMethodEvent(QInputMethodEvent *event); | ||||||
|  |     void keyPressEvent(QKeyEvent *event); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Screen *m_screen; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // TERMINALITEM_H | ||||||
							
								
								
									
										18
									
								
								yat/yat_declarative/yat_declarative.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								yat/yat_declarative/yat_declarative.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | QT += gui quick | ||||||
|  | TARGET = yat | ||||||
|  |  | ||||||
|  | include(../backend/backend.pri) | ||||||
|  |  | ||||||
|  | INCLUDEPATH += $$PWD | ||||||
|  |  | ||||||
|  | SOURCES += $$PWD/terminal_screen.cpp \ | ||||||
|  |     $$PWD/object_destruct_item.cpp \ | ||||||
|  |     $$PWD/register_qml_types.cpp \ | ||||||
|  |     $$PWD/mono_text.cpp \ | ||||||
|  |  | ||||||
|  | HEADERS += \ | ||||||
|  |     $$PWD/terminal_screen.h \ | ||||||
|  |     $$PWD/object_destruct_item.h \ | ||||||
|  |     $$PWD/register_qml_types.h \ | ||||||
|  |     $$PWD/mono_text.h \ | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user