mirror of
https://github.com/Swordfish90/cool-retro-term.git
synced 2025-02-20 20:09:14 +00:00
Merge pull request #103 from Swordfish90/improvemouse
Improved mouse behavior. Enabled mouse support for applications.
This commit is contained in:
commit
98b2511660
@ -133,41 +133,34 @@ Item{
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onWheel:{
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
var lines = wheel.angleDelta.y > 0 ? -2 : 2;
|
||||
kterminal.scrollWheel(coord.width, coord.height, lines);
|
||||
}
|
||||
onClicked: {
|
||||
if (mouse.button == Qt.RightButton){
|
||||
contextmenu.popup();
|
||||
} else if (mouse.button == Qt.MiddleButton){
|
||||
kterminal.pasteSelection();
|
||||
if(wheel.modifiers & Qt.ControlModifier){
|
||||
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
|
||||
} else {
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
var lines = wheel.angleDelta.y > 0 ? -1 : 1;
|
||||
kterminal.scrollWheelEvent(coord, lines);
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseDoubleClick(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressedButtons & Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseMove(coord.width, coord.height);
|
||||
}
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers);
|
||||
}
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
if((!kterminal.usesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
|
||||
contextmenu.popup();
|
||||
} else {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mousePress(coord.width, coord.height);
|
||||
kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers)
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseRelease(coord.width, coord.height);
|
||||
}
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseReleaseEvent(coord, mouse.button, mouse.modifiers);
|
||||
}
|
||||
onPositionChanged: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseMoveEvent(coord, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
|
||||
//Frame displacement properties
|
||||
property real dtop: frame.item.displacementTop
|
||||
@ -185,7 +178,7 @@ Item{
|
||||
var cc = Qt.size(0.5 - x, 0.5 - y);
|
||||
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
|
||||
|
||||
return Qt.size((x - cc.width * (1+distortion) * distortion) * width,
|
||||
return Qt.point((x - cc.width * (1+distortion) * distortion) * width,
|
||||
(y - cc.height * (1+distortion) * distortion) * height)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of Konsole, KDE's terminal.
|
||||
|
||||
|
||||
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||
|
||||
@ -53,7 +53,7 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2);
|
||||
class Character
|
||||
{
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* Constructs a new character.
|
||||
*
|
||||
* @param _c The unicode character value of this character.
|
||||
@ -71,25 +71,25 @@ public:
|
||||
{
|
||||
/** The unicode character value for this character. */
|
||||
quint16 character;
|
||||
/**
|
||||
/**
|
||||
* Experimental addition which allows a single Character instance to contain more than
|
||||
* one unicode character.
|
||||
*
|
||||
* charSequence is a hash code which can be used to look up the unicode
|
||||
* character sequence in the ExtendedCharTable used to create the sequence.
|
||||
*/
|
||||
quint16 charSequence;
|
||||
quint16 charSequence;
|
||||
};
|
||||
|
||||
/** A combination of RENDITION flags which specify options for drawing the character. */
|
||||
quint8 rendition;
|
||||
|
||||
/** The foreground color used to draw this character. */
|
||||
CharacterColor foregroundColor;
|
||||
CharacterColor foregroundColor;
|
||||
/** The color used to draw this character's background. */
|
||||
CharacterColor backgroundColor;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns true if this character has a transparent background when
|
||||
* it is drawn with the specified @p palette.
|
||||
*/
|
||||
@ -97,16 +97,16 @@ public:
|
||||
/**
|
||||
* Returns true if this character should always be drawn in bold when
|
||||
* it is drawn with the specified @p palette, independent of whether
|
||||
* or not the character has the RE_BOLD rendition flag.
|
||||
* or not the character has the RE_BOLD rendition flag.
|
||||
*/
|
||||
ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* returns true if the format (color, rendition flag) of the compared characters is equal
|
||||
*/
|
||||
bool equalsFormat(const Character &other) const;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Compares two characters and returns true if they have the same unicode character value,
|
||||
* rendition and colors.
|
||||
*/
|
||||
@ -119,36 +119,36 @@ public:
|
||||
};
|
||||
|
||||
inline bool operator == (const Character& a, const Character& b)
|
||||
{
|
||||
return a.character == b.character &&
|
||||
a.rendition == b.rendition &&
|
||||
a.foregroundColor == b.foregroundColor &&
|
||||
{
|
||||
return a.character == b.character &&
|
||||
a.rendition == b.rendition &&
|
||||
a.foregroundColor == b.foregroundColor &&
|
||||
a.backgroundColor == b.backgroundColor;
|
||||
}
|
||||
|
||||
inline bool operator != (const Character& a, const Character& b)
|
||||
{
|
||||
return a.character != b.character ||
|
||||
a.rendition != b.rendition ||
|
||||
a.foregroundColor != b.foregroundColor ||
|
||||
return a.character != b.character ||
|
||||
a.rendition != b.rendition ||
|
||||
a.foregroundColor != b.foregroundColor ||
|
||||
a.backgroundColor != b.backgroundColor;
|
||||
}
|
||||
|
||||
inline bool Character::isTransparent(const ColorEntry* base) const
|
||||
{
|
||||
return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
|
||||
return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
|
||||
base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
|
||||
|| ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
|
||||
|| ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
|
||||
base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
|
||||
}
|
||||
|
||||
inline bool Character::equalsFormat(const Character& other) const
|
||||
{
|
||||
return
|
||||
return
|
||||
backgroundColor==other.backgroundColor &&
|
||||
foregroundColor==other.foregroundColor &&
|
||||
rendition==other.rendition;
|
||||
}
|
||||
}
|
||||
|
||||
inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
|
||||
{
|
||||
@ -193,7 +193,7 @@ public:
|
||||
* which was added to the table using createExtendedChar().
|
||||
*
|
||||
* @param hash The hash key returned by createExtendedChar()
|
||||
* @param length This variable is set to the length of the
|
||||
* @param length This variable is set to the length of the
|
||||
* character sequence.
|
||||
*
|
||||
* @return A unicode character sequence of size @p length.
|
||||
@ -205,7 +205,7 @@ public:
|
||||
private:
|
||||
// calculates the hash key of a sequence of unicode points of size 'length'
|
||||
ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
|
||||
// tests whether the entry in the table specified by 'hash' matches the
|
||||
// tests whether the entry in the table specified by 'hash' matches the
|
||||
// character sequence 'unicodePoints' of size 'length'
|
||||
bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
|
||||
// internal, maps hash keys to character sequence buffers. The first ushort
|
||||
|
@ -376,6 +376,12 @@ signals:
|
||||
*/
|
||||
void imageSizeChanged(int lineCount , int columnCount);
|
||||
|
||||
/**
|
||||
* Emitted after receiving the escape sequence which asks to change
|
||||
* the terminal emulator's size
|
||||
*/
|
||||
void imageResizeRequest(const QSize& sizz);
|
||||
|
||||
/**
|
||||
* Emitted when the terminal program requests to change various properties
|
||||
* of the terminal display.
|
||||
|
@ -48,9 +48,10 @@
|
||||
#include "ShellCommand.h" // REUSE THIS
|
||||
#include "Vt102Emulation.h" // REUSE THIS
|
||||
|
||||
|
||||
int Session::lastSessionId = 0;
|
||||
|
||||
using namespace Konsole;
|
||||
|
||||
Session::Session() :
|
||||
_shellProcess(0)
|
||||
, _emulation(0)
|
||||
@ -199,14 +200,9 @@ void Session::addView(KTerminalDisplay * widget)
|
||||
|
||||
// allow emulation to notify view when the foreground process
|
||||
// indicates whether or not it is interested in mouse signals
|
||||
|
||||
// TODO Disabled since at the moment it is not working properly.
|
||||
// Remember to reenable that once it' is's working.
|
||||
|
||||
//connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
|
||||
// SLOT(setUsesMouse(bool)) );
|
||||
|
||||
//widget->setUsesMouse( _emulation->programUsesMouse() );
|
||||
connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
|
||||
SLOT(setUsesMouse(bool)) );
|
||||
widget->setUsesMouse( _emulation->programUsesMouse() );
|
||||
|
||||
widget->setScreenWindow(_emulation->createWindow());
|
||||
}
|
||||
|
@ -447,92 +447,377 @@ QStringList KTerminalDisplay::availableColorSchemes()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){
|
||||
void KTerminalDisplay::scrollWheelEvent(QPoint position, int lines){
|
||||
if(_mouseMarks){
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(QPoint(x,y) , charLine , charColumn);
|
||||
|
||||
emit mouseSignal(lines > 0 ? 5 : 4,
|
||||
charColumn + 1,
|
||||
charLine + 1,
|
||||
0);
|
||||
} else {
|
||||
if(_screenWindow->lineCount() == _screenWindow->windowLines()){
|
||||
const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up;
|
||||
QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier);
|
||||
|
||||
emit keyPressedSignal(&keyEvent);
|
||||
emit keyPressedSignal(&keyEvent);
|
||||
} else {
|
||||
_screenWindow->scrollBy( ScreenWindow::ScrollLines, lines );
|
||||
_screenWindow->scrollCount();
|
||||
updateImage();
|
||||
}
|
||||
} else {
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
|
||||
emit mouseSignal(lines > 0 ? 5 : 4,
|
||||
charColumn + 1,
|
||||
charLine + 1,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
void KTerminalDisplay::mousePress(qreal x, qreal y){
|
||||
if (m_focusOnClick) forcedFocus();
|
||||
if (m_showVKBonClick) ShowVKB(true);
|
||||
void KTerminalDisplay::doPaste(QString text, bool appendReturn)
|
||||
{
|
||||
if (!_screenWindow)
|
||||
return;
|
||||
|
||||
if (appendReturn)
|
||||
text.append("\r");
|
||||
|
||||
if (!text.isEmpty()) {
|
||||
text.replace('\n', '\r');
|
||||
// if (bracketedPasteMode()) {
|
||||
// text.prepend("\e[200~");
|
||||
// text.append("\e[201~");
|
||||
// }
|
||||
// perform paste by simulating keypress events
|
||||
QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
|
||||
emit keyPressedSignal(&e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::pasteFromClipboard(bool appendEnter)
|
||||
{
|
||||
QString text = QGuiApplication::clipboard()->text(QClipboard::Clipboard);
|
||||
doPaste(text, appendEnter);
|
||||
}
|
||||
|
||||
void KTerminalDisplay::pasteFromX11Selection(bool appendEnter)
|
||||
{
|
||||
QString text = QGuiApplication::clipboard()->text(QClipboard::Selection);
|
||||
doPaste(text, appendEnter);
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers)
|
||||
{
|
||||
if (_mouseMarks || (modifiers & Qt::ShiftModifier)) {
|
||||
const bool appendEnter = modifiers & Qt::ControlModifier;
|
||||
|
||||
if (true /*_middleClickPasteMode == Enum::PasteFromX11Selection*/) {
|
||||
pasteFromX11Selection(appendEnter);
|
||||
} else if (false /*_middleClickPasteMode == Enum::PasteFromClipboard*/) {
|
||||
pasteFromClipboard(appendEnter);
|
||||
} else {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
} else {
|
||||
int charLine = 0;
|
||||
int charColumn = 0;
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
|
||||
emit mouseSignal(1, charColumn + 1, charLine + 1, 0);
|
||||
//emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::mousePressEvent(QPoint position, int but, int mod)
|
||||
{
|
||||
Qt::MouseButton button = (Qt::MouseButton) but;
|
||||
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
|
||||
// if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) {
|
||||
// mouseTripleClickEvent(ev);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!_screenWindow) return;
|
||||
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(QPoint(x,y), charLine, charColumn);
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
QPoint pos = QPoint(charColumn, charLine);
|
||||
|
||||
_wordSelectionMode = false;
|
||||
_lineSelectionMode = false;
|
||||
if (button == Qt::LeftButton) {
|
||||
_lineSelectionMode = false;
|
||||
_wordSelectionMode = false;
|
||||
|
||||
if(_mouseMarks){
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
|
||||
} else {
|
||||
QPoint pos = QPoint(charColumn, charLine);
|
||||
_preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier));
|
||||
_columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier);
|
||||
|
||||
_screenWindow->clearSelection();
|
||||
_iPntSel = _pntSel = pos;
|
||||
_actSel = 1; // left mouse button pressed but nothing selected yet.
|
||||
if (_mouseMarks || (modifiers == Qt::ShiftModifier)) {
|
||||
// Only extend selection for programs not interested in mouse
|
||||
if (_mouseMarks && (modifiers == Qt::ShiftModifier)) {
|
||||
extendSelection(position);
|
||||
} else {
|
||||
_screenWindow->clearSelection();
|
||||
|
||||
//pos.ry() += _scrollBar->value();
|
||||
_iPntSel = _pntSel = pos;
|
||||
_actSel = 1; // left mouse button pressed but nothing selected yet.
|
||||
}
|
||||
} else {
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
|
||||
}
|
||||
} else if (button == Qt::MidButton) {
|
||||
processMidButtonClick(position, modifiers);
|
||||
} else if (button == Qt::RightButton) {
|
||||
if (!_mouseMarks)
|
||||
emit mouseSignal(2, charColumn + 1, charLine + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void KTerminalDisplay::mouseMove(qreal x, qreal y){
|
||||
QPoint pos(x, y);
|
||||
void KTerminalDisplay::mouseMoveEvent(QPoint position, int but, int buts, int mod)
|
||||
{
|
||||
Qt::MouseButton button = (Qt::MouseButton) but;
|
||||
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
|
||||
Qt::MouseButtons buttons = (Qt::MouseButtons) buts;
|
||||
|
||||
if(_mouseMarks){
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(pos, charLine, charColumn);
|
||||
int charLine = 0;
|
||||
int charColumn = 0;
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1, 1);
|
||||
} else {
|
||||
extendSelection(pos);
|
||||
// for auto-hiding the cursor, we need mouseTracking
|
||||
if (buttons == Qt::NoButton) return;
|
||||
|
||||
// if the terminal is interested in mouse movements
|
||||
// then emit a mouse movement signal, unless the shift
|
||||
// key is being held down, which overrides this.
|
||||
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) {
|
||||
int button = 3;
|
||||
if (buttons & Qt::LeftButton)
|
||||
button = 0;
|
||||
if (buttons & Qt::MidButton)
|
||||
button = 1;
|
||||
if (buttons & Qt::RightButton)
|
||||
button = 2;
|
||||
|
||||
emit mouseSignal(button, charColumn + 1, charLine + 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actSel == 0) return;
|
||||
|
||||
// don't extend selection while pasting
|
||||
if (buttons & Qt::MidButton) return;
|
||||
|
||||
extendSelection(position);
|
||||
}
|
||||
|
||||
void KTerminalDisplay::mouseDoubleClick(qreal x, qreal y){
|
||||
QPoint pos(x, y);
|
||||
|
||||
if(_mouseMarks){
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(pos, charLine, charColumn);
|
||||
QPoint KTerminalDisplay::findWordEnd(const QPoint &pnt)
|
||||
{
|
||||
const int regSize = qMax(_screenWindow->windowLines(), 10);
|
||||
const int curLine = _screenWindow->currentLine();
|
||||
int i = pnt.y();
|
||||
int x = pnt.x();
|
||||
int y = i + curLine;
|
||||
int j = loc(x, i);
|
||||
QVector<LineProperty> lineProperties = _lineProperties;
|
||||
Screen *screen = _screenWindow->screen();
|
||||
Character *image = _image;
|
||||
Character *tmp_image = NULL;
|
||||
const QChar selClass = charClass(image[j]);
|
||||
const int imageSize = regSize * _columns;
|
||||
const int maxY = _screenWindow->lineCount() - 1;
|
||||
const int maxX = _columns - 1;
|
||||
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
|
||||
//emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
|
||||
} else {
|
||||
_wordSelectionMode = true;
|
||||
extendSelection(pos);
|
||||
while (true) {
|
||||
const int lineCount = lineProperties.count();
|
||||
for (;;j++, x++) {
|
||||
if (x < maxX) {
|
||||
if (charClass(image[j + 1]) == selClass)
|
||||
continue;
|
||||
goto out;
|
||||
} else if (i < lineCount - 1) {
|
||||
if (lineProperties[i] & LINE_WRAPPED &&
|
||||
charClass(image[j + 1]) == selClass) {
|
||||
x = -1;
|
||||
i++;
|
||||
y++;
|
||||
continue;
|
||||
}
|
||||
goto out;
|
||||
} else if (y < maxY) {
|
||||
if (i < lineCount && !(lineProperties[i] & LINE_WRAPPED))
|
||||
goto out;
|
||||
break;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
int newRegEnd = qMin(y + regSize - 1, maxY);
|
||||
lineProperties = screen->getLineProperties(y, newRegEnd);
|
||||
i = 0;
|
||||
if (!tmp_image) {
|
||||
tmp_image = new Character[imageSize];
|
||||
image = tmp_image;
|
||||
}
|
||||
screen->getImage(tmp_image, imageSize, y, newRegEnd);
|
||||
x--;
|
||||
j = loc(x, i);
|
||||
}
|
||||
out:
|
||||
y -= curLine;
|
||||
// In word selection mode don't select @ (64) if at end of word.
|
||||
if (((image[j].rendition & RE_EXTENDED_CHAR) == 0) &&
|
||||
(QChar(image[j].character) == '@') &&
|
||||
(y > pnt.y() || x > pnt.x())) {
|
||||
if (x > 0) {
|
||||
x--;
|
||||
} else {
|
||||
y--;
|
||||
}
|
||||
}
|
||||
if (tmp_image) {
|
||||
delete[] tmp_image;
|
||||
}
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
void KTerminalDisplay::mouseRelease(qreal x, qreal y){
|
||||
_actSel = 0;
|
||||
QPoint KTerminalDisplay::findWordStart(const QPoint &pnt)
|
||||
{
|
||||
const int regSize = qMax(_screenWindow->windowLines(), 10);
|
||||
const int curLine = _screenWindow->currentLine();
|
||||
int i = pnt.y();
|
||||
int x = pnt.x();
|
||||
int y = i + curLine;
|
||||
int j = loc(x, i);
|
||||
QVector<LineProperty> lineProperties = _lineProperties;
|
||||
Screen *screen = _screenWindow->screen();
|
||||
Character *image = _image;
|
||||
Character *tmp_image = NULL;
|
||||
const QChar selClass = charClass(image[j]);
|
||||
const int imageSize = regSize * _columns;
|
||||
|
||||
if(_mouseMarks){
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(QPoint(x,y), charLine, charColumn);
|
||||
while (true) {
|
||||
for (;;j--, x--) {
|
||||
if (x > 0) {
|
||||
if (charClass(image[j - 1]) == selClass)
|
||||
continue;
|
||||
goto out;
|
||||
} else if (i > 0) {
|
||||
if (lineProperties[i - 1] & LINE_WRAPPED &&
|
||||
charClass(image[j - 1]) == selClass) {
|
||||
x = _columns;
|
||||
i--;
|
||||
y--;
|
||||
continue;
|
||||
}
|
||||
goto out;
|
||||
} else if (y > 0) {
|
||||
break;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
int newRegStart = qMax(0, y - regSize);
|
||||
lineProperties = screen->getLineProperties(newRegStart, y - 1);
|
||||
i = y - newRegStart;
|
||||
if (!tmp_image) {
|
||||
tmp_image = new Character[imageSize];
|
||||
image = tmp_image;
|
||||
}
|
||||
screen->getImage(tmp_image, imageSize, newRegStart, y - 1);
|
||||
j = loc(x, i);
|
||||
}
|
||||
out:
|
||||
if (tmp_image) {
|
||||
delete[] tmp_image;
|
||||
}
|
||||
return QPoint(x, y - curLine);
|
||||
}
|
||||
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1, 2);
|
||||
|
||||
|
||||
void KTerminalDisplay::mouseDoubleClickEvent(QPoint position, int but, int mod)
|
||||
{
|
||||
Qt::MouseButton button = (Qt::MouseButton) but;
|
||||
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
|
||||
|
||||
if (button != Qt::LeftButton) return;
|
||||
if (!_screenWindow) return;
|
||||
|
||||
int charLine = 0;
|
||||
int charColumn = 0;
|
||||
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
|
||||
// If the application is interested in mouse events. They have already been forwarded.
|
||||
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
|
||||
return;
|
||||
|
||||
_screenWindow->clearSelection();
|
||||
|
||||
_wordSelectionMode = true;
|
||||
_actSel = 2; // within selection
|
||||
|
||||
_iPntSel = QPoint(charColumn, charLine);
|
||||
const QPoint bgnSel = findWordStart(_iPntSel);
|
||||
const QPoint endSel = findWordEnd(_iPntSel);
|
||||
|
||||
_screenWindow->setSelectionStart(bgnSel.x() , bgnSel.y() , false);
|
||||
_screenWindow->setSelectionEnd(endSel.x() , endSel.y());
|
||||
copyToX11Selection();
|
||||
|
||||
//TODO implement triple click.
|
||||
// _possibleTripleClick = true;
|
||||
|
||||
// QTimer::singleShot(QApplication::doubleClickInterval(), this,
|
||||
// SLOT(tripleClickTimeout()));
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::copyToX11Selection()
|
||||
{
|
||||
if (!_screenWindow)
|
||||
return;
|
||||
|
||||
QString text = _screenWindow->selectedText(_preserveLineBreaks);
|
||||
if (text.isEmpty())
|
||||
return;
|
||||
|
||||
QGuiApplication::clipboard()->setText(text, QClipboard::Selection);
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::mouseReleaseEvent(QPoint position, int but, int mod)
|
||||
{
|
||||
Qt::MouseButton button = (Qt::MouseButton) but;
|
||||
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
|
||||
|
||||
if (!_screenWindow)
|
||||
return;
|
||||
|
||||
int charLine;
|
||||
int charColumn;
|
||||
getCharacterPosition(position, charLine, charColumn);
|
||||
|
||||
if (button == Qt::LeftButton) {
|
||||
if (_actSel > 1) {
|
||||
copyToX11Selection();
|
||||
}
|
||||
|
||||
_actSel = 0;
|
||||
|
||||
//FIXME: emits a release event even if the mouse is
|
||||
// outside the range. The procedure used in `mouseMoveEvent'
|
||||
// applies here, too.
|
||||
|
||||
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
|
||||
emit mouseSignal(0, charColumn + 1, charLine + 1 , 2);
|
||||
}
|
||||
|
||||
if (!_mouseMarks &&
|
||||
(button == Qt::RightButton || button == Qt::MidButton) &&
|
||||
!(modifiers & Qt::ShiftModifier)) {
|
||||
emit mouseSignal(button == Qt::MidButton ? 1 : 2, charColumn + 1, charLine + 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,7 +831,12 @@ void KTerminalDisplay::scrollScreenWindow(enum ScreenWindow::RelativeScrollMode
|
||||
|
||||
|
||||
void KTerminalDisplay::setUsesMouse(bool usesMouse){
|
||||
_mouseMarks = !usesMouse;
|
||||
_mouseMarks = usesMouse;
|
||||
emit usesMouseChanged();
|
||||
}
|
||||
|
||||
bool KTerminalDisplay::getUsesMouse(){
|
||||
return !_mouseMarks;
|
||||
}
|
||||
|
||||
void KTerminalDisplay::setAutoFocus(bool au)
|
||||
@ -1361,16 +1651,33 @@ void KTerminalDisplay::updateLineProperties()
|
||||
_lineProperties = _screenWindow->getLineProperties();
|
||||
}
|
||||
|
||||
QChar KTerminalDisplay::charClass(QChar qch) const
|
||||
QChar KTerminalDisplay::charClass(const Character& ch) const
|
||||
{
|
||||
if ( qch.isSpace() ) return ' ';
|
||||
if (ch.rendition & RE_EXTENDED_CHAR) {
|
||||
ushort extendedCharLength = 0;
|
||||
const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(ch.character, extendedCharLength);
|
||||
if (chars && extendedCharLength > 0) {
|
||||
const QString s = QString::fromUtf16(chars, extendedCharLength);
|
||||
if (_wordCharacters.contains(s, Qt::CaseInsensitive))
|
||||
return 'a';
|
||||
bool allLetterOrNumber = true;
|
||||
for (int i = 0; allLetterOrNumber && i < s.size(); ++i)
|
||||
allLetterOrNumber = s.at(i).isLetterOrNumber();
|
||||
return allLetterOrNumber ? 'a' : s.at(0);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
const QChar qch(ch.character);
|
||||
if (qch.isSpace()) return ' ';
|
||||
|
||||
if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) )
|
||||
return 'a';
|
||||
if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive))
|
||||
return 'a';
|
||||
|
||||
return qch;
|
||||
return qch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KTerminalDisplay::setWordCharacters(const QString& wc)
|
||||
{
|
||||
_wordCharacters = wc;
|
||||
|
@ -70,6 +70,7 @@ class KONSOLEPRIVATE_EXPORT KTerminalDisplay : public QQuickPaintedItem
|
||||
Q_PROPERTY(bool ShowIMEOnClick READ autoVKB WRITE setAutoVKB NOTIFY changedAutoVKB)
|
||||
Q_PROPERTY(QSize terminalSize READ getTerminalSize NOTIFY terminalSizeChanged)
|
||||
Q_PROPERTY(QSize paintedFontSize READ getFontSize NOTIFY paintedFontSizeChanged)
|
||||
Q_PROPERTY(bool usesMouse READ getUsesMouse NOTIFY usesMouseChanged)
|
||||
|
||||
|
||||
public:
|
||||
@ -311,15 +312,10 @@ public slots:
|
||||
void setColorScheme(const QString &name);
|
||||
QStringList availableColorSchemes();
|
||||
|
||||
void scrollWheel(qreal x, qreal y, int lines);
|
||||
void mousePress(qreal x, qreal y);
|
||||
void mouseMove(qreal x, qreal y);
|
||||
void mouseDoubleClick(qreal x, qreal y);
|
||||
void mouseRelease(qreal x, qreal y);
|
||||
|
||||
void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount);
|
||||
|
||||
void setUsesMouse(bool usesMouse);
|
||||
bool getUsesMouse(void);
|
||||
|
||||
bool autoFocus() { return m_focusOnClick; }
|
||||
void setAutoFocus(bool au);
|
||||
@ -425,6 +421,8 @@ signals:
|
||||
|
||||
void mouseSignal(int,int,int,int);
|
||||
|
||||
void usesMouseChanged();
|
||||
|
||||
void terminalSizeChanged();
|
||||
void paintedFontSizeChanged();
|
||||
|
||||
@ -477,7 +475,11 @@ protected:
|
||||
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
|
||||
QRect geometryRound(const QRectF &r) const;
|
||||
|
||||
//void mousePressEvent(QMouseEvent*ev);
|
||||
Q_INVOKABLE void mousePressEvent(QPoint position, int but, int mod);
|
||||
Q_INVOKABLE void mouseReleaseEvent(QPoint position, int but, int mod);
|
||||
Q_INVOKABLE void mouseDoubleClickEvent(QPoint position, int but, int mod);
|
||||
Q_INVOKABLE void mouseMoveEvent(QPoint position, int but, int buts, int mod);
|
||||
Q_INVOKABLE void scrollWheelEvent(QPoint position, int lines);
|
||||
//void mouseReleaseEvent( QMouseEvent* );
|
||||
//void mouseMoveEvent( QMouseEvent* );
|
||||
|
||||
@ -497,7 +499,7 @@ protected:
|
||||
// - A space (returns ' ')
|
||||
// - Part of a word (returns 'a')
|
||||
// - Other characters (returns the input character)
|
||||
QChar charClass(QChar ch) const;
|
||||
QChar charClass(const Character& ch) const;
|
||||
|
||||
void clearImage();
|
||||
|
||||
@ -594,6 +596,14 @@ private:
|
||||
// redraws the cursor
|
||||
void updateCursor();
|
||||
|
||||
QPoint findWordStart(const QPoint &pnt);
|
||||
QPoint findWordEnd(const QPoint &pnt);
|
||||
void processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers);
|
||||
void copyToX11Selection();
|
||||
void pasteFromClipboard(bool appendEnter);
|
||||
void pasteFromX11Selection(bool appendEnter);
|
||||
void doPaste(QString text, bool appendReturn);
|
||||
|
||||
bool handleShortcutOverrideEvent(QKeyEvent* event);
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of Konsole, an X terminal.
|
||||
|
||||
|
||||
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||
|
||||
@ -23,168 +23,169 @@
|
||||
#ifndef VT102EMULATION_H
|
||||
#define VT102EMULATION_H
|
||||
|
||||
// Standard Library
|
||||
#include <stdio.h>
|
||||
|
||||
// Qt
|
||||
#include <QtGui/QKeyEvent>
|
||||
// Qt
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
// Konsole
|
||||
#include "Emulation.h"
|
||||
#include "Screen.h"
|
||||
#include "ScreenWindow.h"
|
||||
#include "TerminalDisplay.h"
|
||||
|
||||
class QTimer;
|
||||
class QKeyEvent;
|
||||
|
||||
#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1
|
||||
#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM)
|
||||
#define MODE_AppKeyPad (MODES_SCREEN+2) //
|
||||
#define MODE_AppKeyPad (MODES_SCREEN+2) //
|
||||
#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release
|
||||
#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking
|
||||
#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking
|
||||
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
|
||||
#define MODE_Ansi (MODES_SCREEN+7) // Use US Ascii for character sets G0-G3 (DECANM)
|
||||
#define MODE_132Columns (MODES_SCREEN+8) // 80 <-> 132 column mode switch (DECCOLM)
|
||||
#define MODE_Allow132Columns (MODES_SCREEN+9) // Allow DECCOLM mode
|
||||
#define MODE_total (MODES_SCREEN+10)
|
||||
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
|
||||
#define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates
|
||||
#define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates
|
||||
#define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates
|
||||
#define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM)
|
||||
#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM)
|
||||
#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode
|
||||
#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode
|
||||
#define MODE_total (MODES_SCREEN+14)
|
||||
|
||||
|
||||
struct CharCodes
|
||||
namespace Konsole
|
||||
{
|
||||
// coding info
|
||||
char charset[4]; //
|
||||
int cu_cs; // actual charset.
|
||||
bool graphic; // Some VT100 tricks
|
||||
bool pound ; // Some VT100 tricks
|
||||
bool sa_graphic; // saved graphic
|
||||
bool sa_pound; // saved pound
|
||||
extern unsigned short vt100_graphics[32];
|
||||
|
||||
struct CharCodes {
|
||||
// coding info
|
||||
char charset[4]; //
|
||||
int cu_cs; // actual charset.
|
||||
bool graphic; // Some VT100 tricks
|
||||
bool pound; // Some VT100 tricks
|
||||
bool sa_graphic; // saved graphic
|
||||
bool sa_pound; // saved pound
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
|
||||
* A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
|
||||
*
|
||||
* In addition, various additional xterm escape sequences are supported to provide
|
||||
*
|
||||
* In addition, various additional xterm escape sequences are supported to provide
|
||||
* features such as mouse input handling.
|
||||
* See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
|
||||
* sequences.
|
||||
* sequences.
|
||||
*
|
||||
*/
|
||||
class Vt102Emulation : public Emulation
|
||||
{
|
||||
Q_OBJECT
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/** Constructs a new emulation */
|
||||
Vt102Emulation();
|
||||
~Vt102Emulation();
|
||||
|
||||
// reimplemented from Emulation
|
||||
virtual void clearEntireScreen();
|
||||
virtual void reset();
|
||||
virtual char eraseChar() const;
|
||||
|
||||
public slots:
|
||||
// reimplemented from Emulation
|
||||
virtual void sendString(const char*,int length = -1);
|
||||
virtual void sendText(const QString& text);
|
||||
virtual void sendKeyEvent(QKeyEvent*);
|
||||
virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
|
||||
|
||||
/** Constructs a new emulation */
|
||||
Vt102Emulation();
|
||||
~Vt102Emulation();
|
||||
|
||||
// reimplemented from Emulation
|
||||
virtual void clearEntireScreen();
|
||||
virtual void reset();
|
||||
virtual char eraseChar() const;
|
||||
|
||||
public slots:
|
||||
// reimplemented from Emulation
|
||||
virtual void sendString(const char*, int length = -1);
|
||||
virtual void sendText(const QString& text);
|
||||
virtual void sendKeyEvent(QKeyEvent*);
|
||||
virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
|
||||
|
||||
protected:
|
||||
// reimplemented from Emulation
|
||||
virtual void setMode(int mode);
|
||||
virtual void resetMode(int mode);
|
||||
virtual void receiveChar(int cc);
|
||||
|
||||
// reimplemented from Emulation
|
||||
virtual void setMode(int mode);
|
||||
virtual void resetMode(int mode);
|
||||
virtual void receiveChar(int cc);
|
||||
|
||||
private slots:
|
||||
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
|
||||
//used to buffer multiple title updates
|
||||
void updateTitle();
|
||||
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
|
||||
//used to buffer multiple title updates
|
||||
void updateTitle();
|
||||
|
||||
private:
|
||||
unsigned short applyCharset(unsigned short c);
|
||||
void setCharset(int n, int cs);
|
||||
void useCharset(int n);
|
||||
void setAndUseCharset(int n, int cs);
|
||||
void saveCursor();
|
||||
void restoreCursor();
|
||||
void resetCharset(int scrno);
|
||||
unsigned short applyCharset(unsigned short c);
|
||||
void setCharset(int n, int cs);
|
||||
void useCharset(int n);
|
||||
void setAndUseCharset(int n, int cs);
|
||||
void saveCursor();
|
||||
void restoreCursor();
|
||||
void resetCharset(int scrno);
|
||||
|
||||
void setMargins(int top, int bottom);
|
||||
//set margins for all screens back to their defaults
|
||||
void setDefaultMargins();
|
||||
void setMargins(int top, int bottom);
|
||||
//set margins for all screens back to their defaults
|
||||
void setDefaultMargins();
|
||||
|
||||
// returns true if 'mode' is set or false otherwise
|
||||
bool getMode (int mode);
|
||||
// saves the current boolean value of 'mode'
|
||||
void saveMode (int mode);
|
||||
// restores the boolean value of 'mode'
|
||||
void restoreMode(int mode);
|
||||
// resets all modes
|
||||
// (except MODE_Allow132Columns)
|
||||
void resetModes();
|
||||
// returns true if 'mode' is set or false otherwise
|
||||
bool getMode(int mode);
|
||||
// saves the current boolean value of 'mode'
|
||||
void saveMode(int mode);
|
||||
// restores the boolean value of 'mode'
|
||||
void restoreMode(int mode);
|
||||
// resets all modes
|
||||
// (except MODE_Allow132Columns)
|
||||
void resetModes();
|
||||
|
||||
void resetTokenizer();
|
||||
#define MAX_TOKEN_LENGTH 80
|
||||
void addToCurrentToken(int cc);
|
||||
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
|
||||
int tokenBufferPos;
|
||||
void resetTokenizer();
|
||||
#define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
|
||||
void addToCurrentToken(int cc);
|
||||
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
|
||||
int tokenBufferPos;
|
||||
#define MAXARGS 15
|
||||
void addDigit(int dig);
|
||||
void addArgument();
|
||||
int argv[MAXARGS];
|
||||
int argc;
|
||||
void initTokenizer();
|
||||
void addDigit(int dig);
|
||||
void addArgument();
|
||||
int argv[MAXARGS];
|
||||
int argc;
|
||||
void initTokenizer();
|
||||
|
||||
// Set of flags for each of the ASCII characters which indicates
|
||||
// what category they fall into (printable character, control, digit etc.)
|
||||
// for the purposes of decoding terminal output
|
||||
int charClass[256];
|
||||
// Set of flags for each of the ASCII characters which indicates
|
||||
// what category they fall into (printable character, control, digit etc.)
|
||||
// for the purposes of decoding terminal output
|
||||
int charClass[256];
|
||||
|
||||
void reportDecodingError();
|
||||
void reportDecodingError();
|
||||
|
||||
void processToken(int code, int p, int q);
|
||||
void processWindowAttributeChange();
|
||||
void processToken(int code, int p, int q);
|
||||
void processWindowAttributeChange();
|
||||
|
||||
void reportTerminalType();
|
||||
void reportSecondaryAttributes();
|
||||
void reportStatus();
|
||||
void reportAnswerBack();
|
||||
void reportCursorPosition();
|
||||
void reportTerminalParms(int p);
|
||||
void reportTerminalType();
|
||||
void reportSecondaryAttributes();
|
||||
void reportStatus();
|
||||
void reportAnswerBack();
|
||||
void reportCursorPosition();
|
||||
void reportTerminalParms(int p);
|
||||
|
||||
void onScrollLock();
|
||||
void scrollLock(const bool lock);
|
||||
// clears the screen and resizes it to the specified
|
||||
// number of columns
|
||||
void clearScreenAndSetColumns(int columnCount);
|
||||
|
||||
// clears the screen and resizes it to the specified
|
||||
// number of columns
|
||||
void clearScreenAndSetColumns(int columnCount);
|
||||
CharCodes _charset[2];
|
||||
|
||||
CharCodes _charset[2];
|
||||
class TerminalState
|
||||
{
|
||||
public:
|
||||
// Initializes all modes to false
|
||||
TerminalState() {
|
||||
memset(&mode, false, MODE_total * sizeof(bool));
|
||||
}
|
||||
|
||||
class TerminalState
|
||||
{
|
||||
public:
|
||||
// Initializes all modes to false
|
||||
TerminalState()
|
||||
{ memset(&mode,false,MODE_total * sizeof(bool)); }
|
||||
bool mode[MODE_total];
|
||||
};
|
||||
|
||||
bool mode[MODE_total];
|
||||
};
|
||||
TerminalState _currentModes;
|
||||
TerminalState _savedModes;
|
||||
|
||||
TerminalState _currentModes;
|
||||
TerminalState _savedModes;
|
||||
|
||||
//hash table and timer for buffering calls to the session instance
|
||||
//to update the name of the session
|
||||
//or window title.
|
||||
//these calls occur when certain escape sequences are seen in the
|
||||
//output from the terminal
|
||||
QHash<int,QString> _pendingTitleUpdates;
|
||||
QTimer* _titleUpdateTimer;
|
||||
//hash table and timer for buffering calls to the session instance
|
||||
//to update the name of the session
|
||||
//or window title.
|
||||
//these calls occur when certain escape sequences are seen in the
|
||||
//output from the terminal
|
||||
QHash<int, QString> _pendingTitleUpdates;
|
||||
QTimer* _titleUpdateTimer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VT102EMULATION_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user