Cherry-picked upstream version 0.8.0.

ubuntu/cosmic
Alf Gaida 7 years ago
parent ccc166214d
commit e7d4039a1b

@ -1,7 +1,53 @@
qtermwidget-0.7.1 / 2016-12-21
qtermwidget-0.8.0 / 2017-10-21
==============================
* FIX: #46 fix vertical font truncation
* bump versions
* Really fallback to /bin/sh when $SHELL is missing or invalid
* README: don't recommend building from source
* Improve README
* Don't export github templates
* Support REP escape sequence defined in ECMA-48, section 8.3.103
* Fix build issue related to utmpx in Mac OSX Sierra
* Remove the deprecation notice
* Handle DECSCUSR signals
* Copied issue template
* Update building instructions
* Require Qt 5.6+
* This commit allows the consumer of qtermwidget to capture the (#111)
* Allow the terminal display to be smaller than the size hint (#123)
* Backport Vt102 emulation fixes (#113)
* Backport the default.keytab from Konsole
* Fixes (#122)
* Updated README, Added support for PyQT 5.7
* Fix memory leak in hotspot (URLs & emails) detection
* Adds superbuild support
* Use target_compile_definitions() instead of add_definitions()
* Update find_package() documentation
* Use the lxqt_create_pkgconfig_file
* Improve lxqt_translate_ts() use
* Adds COMPONENT to the install files
* Renames test app to example. Make it work
* Drop include_directories() for in tree dirs
* Use the CMake Targets way
* Pack Utf8Proc stuff
* Adds export header
* Use LXQtCompilerSettings
* Packs compile definitions
* Adds package version file
* Removes Qt4 stuff
* Add translation mechanism
* Use const iterators when possible.
* Enable strict iterators for debug builds
* TerminalDisplay: Make resizing "Size" translatable
* Exposes receivedData signal to users of QTermWidget
* Exposes sessions autoClose property to QTermWidget
0.7.1 / 2016-12-21
==================
* Release 0.7.1: Update changelog
* Bump patch version (#105)
* Added a modified Breeze color scheme (#104)
* Accept hex color strings as well (#101)

@ -3,54 +3,44 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(qtermwidget)
include(GNUInstallDirs)
include(GenerateExportHeader)
include(CMakePackageConfigHelpers)
include(CheckFunctionExists)
option(BUILD_TEST "Build test application. Default OFF." OFF)
set(REQUIRED_QT_VERSION "5.6")
set(LXQTBT_MINIMUM_VERSION "0.4.0")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
option(BUILD_EXAMPLE "Build example application. Default OFF." OFF)
# just change version for releases
set(QTERMWIDGET_VERSION_MAJOR "0")
set(QTERMWIDGET_VERSION_MINOR "7")
set(QTERMWIDGET_VERSION_PATCH "1")
set(QTERMWIDGET_VERSION_MINOR "8")
set(QTERMWIDGET_VERSION_PATCH "0")
set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}")
# additional cmake files
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. C++11 support is required")
endif()
include_directories(
"${CMAKE_SOURCE_DIR}/lib"
"${CMAKE_BINARY_DIR}/lib"
"${CMAKE_BINARY_DIR}"
)
add_definitions(-Wall)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets "${REQUIRED_QT_VERSION}" REQUIRED)
find_package(Qt5LinguistTools "${REQUIRED_QT_VERSION}" REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
include(LXQtTranslateTs)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtCreatePkgConfigFile)
set(QTERMWIDGET_LIBRARY_NAME qtermwidget5)
include(qtermwidget5_use)
option(USE_UTF8PROC "Use libutf8proc for better Unicode support. Default OFF" OFF)
if(USE_UTF8PROC)
find_package(Utf8Proc)
endif()
if (UTF8PROC_FOUND)
add_definitions(-DHAVE_UTF8PROC)
include_directories("${UTF8PROC_INCLUDE_DIRS}")
find_package(Utf8Proc REQUIRED)
endif()
# main library
@ -105,86 +95,200 @@ set(UI
# for distribution
set(HDRS_DISTRIB
lib/qtermwidget.h
lib/Emulation.h
lib/Filter.h
)
# dirs
set(KB_LAYOUT_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${QTERMWIDGET_LIBRARY_NAME}/kb-layouts")
message(STATUS "Keyboard layouts will be installed in: ${KB_LAYOUT_DIR}")
add_definitions(-DKB_LAYOUT_DIR="${KB_LAYOUT_DIR}")
set(COLORSCHEMES_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${QTERMWIDGET_LIBRARY_NAME}/color-schemes")
message(STATUS "Color schemes will be installed in: ${COLORSCHEMES_DIR}" )
add_definitions(-DCOLORSCHEMES_DIR="${COLORSCHEMES_DIR}")
set(TRANSLATIONS_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${QTERMWIDGET_LIBRARY_NAME}/translations")
message(STATUS "Translations will be installed in: ${TRANSLATIONS_DIR}")
set(QTERMWIDGET_INCLUDE_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}")
#| Defines
add_definitions(-DHAVE_POSIX_OPENPT -DHAVE_SYS_TIME_H)
if(APPLE)
add_definitions(-DHAVE_UTMPX -D_UTMPX_COMPAT)
endif()
CHECK_FUNCTION_EXISTS(updwtmpx HAVE_UPDWTMPX)
if(HAVE_UPDWTMPX)
add_definitions(-DHAVE_UPDWTMPX)
endif()
qt5_wrap_cpp(MOCS ${HDRS})
qt5_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt5Core, Qt5Xml, Qt5Widgets")
set(PKG_CONFIG_REQ "Qt5Widgets")
add_library(${QTERMWIDGET_LIBRARY_NAME} SHARED ${SRCS} ${MOCS} ${UI_SRCS})
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} ${QTERMWIDGET_QT_LIBRARIES})
lxqt_translate_ts(QTERMWIDGET_QM
TRANSLATION_DIR "lib/translations"
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${SRCS} ${HDRS} ${UI}
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
INSTALL_DIR
${TRANSLATIONS_DIR}
COMPONENT
Runtime
)
add_library(${QTERMWIDGET_LIBRARY_NAME} SHARED ${SRCS} ${MOCS} ${UI_SRCS} ${QTERMWIDGET_QM})
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt5::Widgets)
set_target_properties( ${QTERMWIDGET_LIBRARY_NAME} PROPERTIES
SOVERSION ${QTERMWIDGET_VERSION_MAJOR}
VERSION ${QTERMWIDGET_VERSION}
)
if(APPLE)
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
PRIVATE
"HAVE_UTMPX"
"UTMPX_COMPAT"
)
endif()
if(HAVE_UPDWTMPX)
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
PRIVATE
"HAVE_UPDWTMPX"
)
endif()
if (UTF8PROC_FOUND)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} ${UTF8PROC_LIBRARIES})
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
PRIVATE
"HAVE_UTF8PROC"
)
target_include_directories(${QTERMWIDGET_LIBRARY_NAME}
INTERFACE
${UTF8PROC_INCLUDE_DIRS}
)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME}
${UTF8PROC_LIBRARIES}
)
string(APPEND PKG_CONFIG_REQ ", libutf8proc")
endif()
if(APPLE)
set (CMAKE_SKIP_RPATH 1)
# this is a must to load the lib correctly
set_target_properties(${QTERMWIDGET_LIBRARY_NAME} PROPERTIES INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR})
endif()
install(TARGETS ${QTERMWIDGET_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(FILES ${HDRS_DISTRIB} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}")
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
PRIVATE
"KB_LAYOUT_DIR=\"${KB_LAYOUT_DIR}\""
"COLORSCHEMES_DIR=\"${COLORSCHEMES_DIR}\""
"TRANSLATIONS_DIR=\"${TRANSLATIONS_DIR}\""
"HAVE_POSIX_OPENPT"
"HAVE_SYS_TIME_H"
)
generate_export_header(${QTERMWIDGET_LIBRARY_NAME}
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/lib/qtermwidget_export.h"
EXPORT_MACRO_NAME QTERMWIDGET_EXPORT
)
target_include_directories(${QTERMWIDGET_LIBRARY_NAME}
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/lib>"
INTERFACE
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}>"
)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config-version.cmake"
VERSION ${QTERMWIDGET_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
install(EXPORT
"${QTERMWIDGET_LIBRARY_NAME}-targets"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
install(FILES
${HDRS_DISTRIB} "${CMAKE_CURRENT_BINARY_DIR}/lib/qtermwidget_export.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
# keyboard layouts
install(DIRECTORY lib/kb-layouts/ DESTINATION "${KB_LAYOUT_DIR}" FILES_MATCHING PATTERN "*.keytab" )
install(DIRECTORY
lib/kb-layouts/
DESTINATION "${KB_LAYOUT_DIR}"
COMPONENT Runtime
FILES_MATCHING PATTERN "*.keytab"
)
# color schemes
install(DIRECTORY lib/color-schemes/ DESTINATION "${COLORSCHEMES_DIR}" FILES_MATCHING PATTERN "*.*schem*")
install(DIRECTORY
lib/color-schemes/
DESTINATION "${COLORSCHEMES_DIR}"
COMPONENT Runtime
FILES_MATCHING PATTERN "*.*schem*"
)
include(create_pkgconfig_file)
create_pkgconfig_file(${QTERMWIDGET_LIBRARY_NAME}
"QTermWidget library for Qt ${QTERMWIDGET_VERSION_MAJOR}.x"
${PKG_CONFIG_REQ}
${QTERMWIDGET_LIBRARY_NAME}
${QTERMWIDGET_VERSION}
lxqt_create_pkgconfig_file(
PACKAGE_NAME ${QTERMWIDGET_LIBRARY_NAME}
DESCRIPTIVE_NAME ${QTERMWIDGET_LIBRARY_NAME}
DESCRIPTION "QTermWidget library for Qt ${QTERMWIDGET_VERSION_MAJOR}.x"
INCLUDEDIRS ${QTERMWIDGET_LIBRARY_NAME}
LIBS ${QTERMWIDGET_LIBRARY_NAME}
REQUIRES ${PKG_CONFIG_REQ}
VERSION ${QTERMWIDGET_VERSION}
INSTALL
COMPONENT Devel
)
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}-config.cmake.in"
"${PROJECT_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}-config.cmake.in"
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
@ONLY
)
install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
"${CMAKE_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}_use.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
install(TARGETS ${QTERMWIDGET_LIBRARY_NAME}
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
EXPORT "${QTERMWIDGET_LIBRARY_NAME}-targets"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
PUBLIC_HEADER
COMPONENT Runtime
)
export(TARGETS ${QTERMWIDGET_LIBRARY_NAME}
FILE "${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-targets.cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
)
# end of main library
# test application
if(BUILD_TEST)
set(TEST_SRC src/main.cpp)
add_executable(test ${TEST_SRC})
add_dependencies(test ${QTERMWIDGET_LIBRARY_NAME})
link_directories(${CMAKE_BINARY_DIR})
target_link_libraries(test ${QTERMWIDGET_QT_LIBRARIES} ${QTERMWIDGET_LIBRARY_NAME} util)
endif (BUILD_TEST)
# end of test application
# example application
if(BUILD_EXAMPLE)
set(EXAMPLE_SRC example/main.cpp)
add_executable(example ${EXAMPLE_SRC})
target_link_libraries(example ${QTERMWIDGET_LIBRARY_NAME})
endif()
# end of example application
CONFIGURE_FILE(

@ -2,27 +2,27 @@
## Overview
A terminal emulator widget for Qt 5.
A terminal emulator widget for Qt 5.
QTermWidget is an open-source project originally based on KDE4 Konsole application, but it took its own direction later.
The main goal of this project is to provide a unicode-enabled, embeddable Qt widget for using as a built-in console (or terminal emulation widget).
QTermWidget is an open-source project originally based on the KDE4 Konsole application, but it took its own direction later on.
The main goal of this project is to provide a unicode-enabled, embeddable Qt widget for using as a built-in console (or terminal emulation widget).
It is compatible with BSD, Linux and OS X.
It is compatible with BSD, Linux and OS X.
This project is licensed under the terms of the [GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version. See the LICENSE file for the full text of the license.
This project is licensed under the terms of the [GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version. See the LICENSE file for the full text of the license.
## Installation
### Compiling sources
The only runtime dependency is qtbase ≥ 5.4.
In order to build CMake ≥ 3.0 is needed as well as optionally Git to pull latest VCS checkouts.
The only runtime dependency is qtbase ≥ 5.6.
In order to build CMake ≥ 3.0.2 and [lxqt-build-tools](https://github.com/lxde/lxqt-build-tools/) >= 0.3 are needed as well as Git to pull translations and optionally latest VCS checkouts.
Code configuration is handled by CMake. Building out of source is strongly recommended. CMake variable `CMAKE_INSTALL_PREFIX` will normally have to be set to `/usr`, depending on the way library paths are dealt with on 64bit systems variables like `CMAKE_INSTALL_LIBDIR` may have to be set as well.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` will normally have to be set to `/usr`, depending on the way library paths are dealt with on 64bit systems variables like `CMAKE_INSTALL_LIBDIR` may have to be set as well.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
### Binary packages
The library is provided by all major Linux distributions like Arch Linux, Debian, Fedora and openSUSE.
The library is provided by all major Linux distributions like Arch Linux, Debian, Fedora and openSUSE.
Just use the distributions' package managers to search for string `qtermwidget`.

@ -1,29 +0,0 @@
#
# Write a pkg-config pc file for given "name" with "decription"
# Arguments:
# name: a library name (withoud "lib" prefix and "so" suffixes
# desc: a desription string
# requires: required libraries
# include_rel_dir: include directory, relative to includedir
# version: package version
#
macro (create_pkgconfig_file name desc requires include_rel_dir version)
set(_pkgfname "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc")
message(STATUS "${name}: writing pkgconfig file ${_pkgfname}")
file(WRITE "${_pkgfname}"
"prefix=${CMAKE_INSTALL_PREFIX}\n"
"libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n"
"includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}\n"
"\n"
"Name: ${name}\n"
"Description: ${desc}\n"
"Version: ${version}\n"
"Requires: ${requires}\n"
"Libs: -L\${libdir} -l${name}\n"
"Cflags: -I\${includedir} -I\${includedir}/${include_rel_dir}\n"
"\n"
)
install(FILES ${_pkgfname} DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endmacro()

@ -1,8 +0,0 @@
find_package(Qt4 REQUIRED QUIET)
include(${QT_USE_FILE})
set(QTERMWIDGET_QT_LIBRARIES ${QT_LIBRARIES})
include_directories(${QTERMWIDGET_INCLUDE_DIRS})

@ -1,41 +1,20 @@
# - Find the QTermWidget include and library dirs and define a some macros
#
# The module defines the following variables
# QTERMWIDGET_FOUND - Set to TRUE if all of the above has been found
#
# QTERMWIDGET_INCLUDE_DIR - The QTermWidget include directory
#
# QTERMWIDGET_INCLUDE_DIRS - The QTermWidget include directory
#
# QTERMWIDGET_LIBRARIES - The libraries needed to use QTermWidget
#
# QTERMWIDGET_USE_FILE - The variable QTERMWIDGET_USE_FILE is set which is the path
# to a CMake file that can be included to compile qtermwidget
# applications and libraries. It sets up the compilation
# environment for include directories and populates a
# QTERMWIDGET_LIBRARIES variable.
#
# QTERMWIDGET_QT_LIBRARIES - The Qt libraries needed by QTermWidget
# - Find the QTermWidget include and library
#
# Typical usage:
# find_package(QTERMWIDGET5)
# find_package(QTermWidget5 REQUIRED)
#
# include(${QTERMWIDGET_USE_FILE})
# add_executable(foo main.cpp)
# target_link_libraries(foo ${QTERMWIDGET_QT_LIBRARIES} ${QTERMWIDGET_LIBRARIES})
set(QTERMWIDGET_INCLUDE_DIR @QTERMWIDGET_INCLUDE_DIR@)
set(QTERMWIDGET_LIBRARY @QTERMWIDGET_LIBRARY_NAME@)
set(QTERMWIDGET_LIBRARIES ${QTERMWIDGET_LIBRARY})
set(QTERMWIDGET_INCLUDE_DIRS "${QTERMWIDGET_INCLUDE_DIR}")
# target_link_libraries(foo qtermwidget5)
set(QTERMWIDGET_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/qtermwidget5_use.cmake")
set(QTERMWIDGET_FOUND 1)
@PACKAGE_INIT@
set(QTERMWIDGET_VERSION_MAJOR @QTERMWIDGET_VERSION_MAJOR@)
set(QTERMWIDGET_VERSION_MINOR @QTERMWIDGET_VERSION_MINOR@)
set(QTERMWIDGET_VERSION_PATCH @QTERMWIDGET_VERSION_PATCH@)
set(QTERMWIDGET_VERSION @QTERMWIDGET_VERSION@)
if (CMAKE_VERSION VERSION_LESS 3.0.2)
message(FATAL_ERROR \"qtermwidget requires at least CMake version 3.0.2\")
endif()
mark_as_advanced(QTERMWIDGET_LIBRARY QTERMWIDGET_INCLUDE_DIR)
if (NOT TARGET @QTERMWIDGET_LIBRARY_NAME@)
if (POLICY CMP0024)
cmake_policy(SET CMP0024 NEW)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@QTERMWIDGET_LIBRARY_NAME@-targets.cmake")
endif()

@ -1,9 +0,0 @@
find_package(Qt5Widgets REQUIRED)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
add_definitions(${Qt5Core_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
set(QTERMWIDGET_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
include_directories(${QTERMWIDGET_INCLUDE_DIRS})

@ -48,6 +48,10 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2);
#define RE_ITALIC (1 << 4)
#define RE_CURSOR (1 << 5)
#define RE_EXTENDED_CHAR (1 << 6)
#define RE_FAINT (1 << 7)
#define RE_STRIKEOUT (1 << 8)
#define RE_CONCEAL (1 << 9)
#define RE_OVERLINE (1 << 10)
/**
* A single character in the terminal which consists of a unicode character

@ -70,6 +70,11 @@ Emulation::Emulation() :
SLOT(usesMouseChanged(bool)));
connect(this , SIGNAL(programBracketedPasteModeChanged(bool)) ,
SLOT(bracketedPasteModeChanged(bool)));
connect(this, &Emulation::cursorChanged, [this] (KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) {
emit titleChanged( 50, QString("CursorShape=%1;BlinkingCursorEnabled=%2")
.arg(static_cast<int>(cursorShape)).arg(blinkingCursorEnabled) );
});
}
bool Emulation::programUsesMouse() const

@ -126,6 +126,26 @@ Q_OBJECT
public:
/**
* This enum describes the available shapes for the keyboard cursor.
* See setKeyboardCursorShape()
*/
enum class KeyboardCursorShape {
/** A rectangular block which covers the entire area of the cursor character. */
BlockCursor = 0,
/**
* A single flat line which occupies the space at the bottom of the cursor
* character's area.
*/
UnderlineCursor = 1,
/**
* An cursor shaped like the capital letter 'I', similar to the IBeam
* cursor used in Qt/KDE text editors.
*/
IBeamCursor = 2
};
/** Constructs a new terminal emulation */
Emulation();
~Emulation();
@ -415,6 +435,15 @@ signals:
*/
void flowControlKeyPressed(bool suspendKeyPressed);
/**
* Emitted when the cursor shape or its blinking state is changed via
* DECSCUSR sequences.
*
* @param cursorShape One of 3 possible values in KeyboardCursorShape enum
* @param blinkingCursorEnabled Whether to enable blinking or not
*/
void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled);
protected:
virtual void setMode(int mode) = 0;
virtual void resetMode(int mode) = 0;

@ -26,6 +26,7 @@
// Qt
#include <QAction>
#include <QApplication>
#include <QtAlgorithms>
#include <QClipboard>
#include <QString>
#include <QTextStream>
@ -194,6 +195,7 @@ Filter::~Filter()
}
void Filter::reset()
{
qDeleteAll(_hotspotList);
_hotspots.clear();
_hotspotList.clear();
}
@ -416,7 +418,7 @@ UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endCol
UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
{
QString url = capturedTexts().first();
QString url = capturedTexts().constFirst();
if ( FullUrlRegExp.exactMatch(url) )
return StandardUrl;
@ -428,7 +430,7 @@ UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
void UrlFilter::HotSpot::activate(const QString& actionName)
{
QString url = capturedTexts().first();
QString url = capturedTexts().constFirst();
const UrlType kind = urlType();

@ -321,6 +321,10 @@ bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTransl
command = KeyboardTranslator::ScrollLineDownCommand;
else if ( text.compare("scrolllock",Qt::CaseInsensitive) == 0 )
command = KeyboardTranslator::ScrollLockCommand;
else if ( text.compare("scrolluptotop",Qt::CaseInsensitive) == 0)
command = KeyboardTranslator::ScrollUpToTopCommand;
else if ( text.compare("scrolldowntobottom",Qt::CaseInsensitive) == 0)
command = KeyboardTranslator::ScrollDownToBottomCommand;
else
return false;
@ -543,27 +547,27 @@ QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const
if ( title.exactMatch(text) )
{
Token titleToken = { Token::TitleKeyword , QString() };
Token textToken = { Token::TitleText , title.capturedTexts()[1] };
Token textToken = { Token::TitleText , title.capturedTexts().at(1) };
list << titleToken << textToken;
}
else if ( key.exactMatch(text) )
{
Token keyToken = { Token::KeyKeyword , QString() };
Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
Token sequenceToken = { Token::KeySequence , key.capturedTexts().value(1).remove(' ') };
list << keyToken << sequenceToken;
if ( key.capturedTexts()[3].isEmpty() )
if ( key.capturedTexts().at(3).isEmpty() )
{
// capturedTexts()[2] is a command
Token commandToken = { Token::Command , key.capturedTexts()[2] };
Token commandToken = { Token::Command , key.capturedTexts().at(2) };
list << commandToken;
}
else
{
// capturedTexts()[3] is the output string
Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
Token outputToken = { Token::OutputText , key.capturedTexts().at(3) };
list << outputToken;
}
}
@ -785,6 +789,10 @@ QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::Keybo
return "ScrollLineDown";
else if ( _command == ScrollLockCommand )
return "ScrollLock";
else if (_command == ScrollUpToTopCommand)
return "ScrollUpToTop";
else if (_command == ScrollDownToBottomCommand)
return "ScrollDownToBottom";
return QString();
}
@ -852,10 +860,11 @@ void KeyboardTranslator::removeEntry(const Entry& entry)
}
KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
{
foreach(const Entry& entry, _entries.values(keyCode))
for (auto it = _entries.cbegin(), end = _entries.cend(); it != end; ++it)
{
if ( entry.matches(keyCode,modifiers,state) )
return entry;
if (it.key() == keyCode)
if ( it.value().matches(keyCode,modifiers,state) )
return *it;
}
return Entry(); // entry not found
}

@ -111,8 +111,12 @@ public:
ScrollLineDownCommand = 16,
/** Toggles scroll lock mode */
ScrollLockCommand = 32,
/** Scroll the terminal display up to the start of history */
ScrollUpToTopCommand = 64,
/** Scroll the terminal display down to the end of history */
ScrollDownToBottomCommand = 128,
/** Echos the operating system specific erase character. */
EraseCommand = 64
EraseCommand = 256
};
Q_DECLARE_FLAGS(Commands,Command)

@ -226,6 +226,28 @@ void Screen::insertChars(int n)
screenLines[cuY].resize(columns);
}
void Screen::repeatChars(int count)
//=REP
{
if (count == 0)
{
count = 1;
}
/**
* From ECMA-48 version 5, section 8.3.103
* If the character preceding REP is a control function or part of a
* control function, the effect of REP is not defined by this Standard.
*
* So, a "normal" program should always use REP immediately after a visible
* character (those other than escape sequences). So, lastDrawnChar can be
* safely used.
*/
for (int i = 0; i < count; i++)
{
displayCharacter(lastDrawnChar);
}
}
void Screen::deleteLines(int n)
{
if (n == 0) n = 1; // Default
@ -663,6 +685,8 @@ void Screen::displayCharacter(unsigned short c)
currentChar.backgroundColor = effectiveBackground;
currentChar.rendition = effectiveRendition;
lastDrawnChar = c;
int i = 0;
int newCursorX = cuX + w--;
while(w)

@ -197,6 +197,11 @@ public:
* If @p n is 0 then one character is inserted.
*/
void insertChars(int n);
/**
* Repeat the preceeding graphic character @count times, including SPACE.
* If @count is 0 then the character is repeated once.
*/
void repeatChars(int count);
/**
* Removes @p n lines beginning from the current cursor position.
* The position of the cursor is not altered.
@ -667,6 +672,9 @@ private:
// last position where we added a character
int lastPos;
// used in REP (repeating char)
unsigned short lastDrawnChar;
static Character defaultChar;
};

@ -99,6 +99,8 @@ Session::Session(QObject* parent) :
this, SLOT(onEmulationSizeChange(QSize)));
connect(_emulation, SIGNAL(imageSizeChanged(int, int)),
this, SLOT(onViewSizeChange(int, int)));
connect(_emulation, &Vt102Emulation::cursorChanged,
this, &Session::cursorChanged);
//connect teletype to emulation backend
_shellProcess->setUtf8Mode(_emulation->utf8());
@ -256,8 +258,10 @@ void Session::run()
// here we expect full path. If there is no fullpath let's expect it's
// a custom shell (eg. python, etc.) available in the PATH.
if (exec.startsWith("/"))
if (exec.startsWith("/") || exec.isEmpty())
{
const QString defaultShell{"/bin/sh"};
QFile excheck(exec);
if ( exec.isEmpty() || !excheck.exists() ) {
exec = getenv("SHELL");
@ -265,7 +269,8 @@ void Session::run()
excheck.setFileName(exec);
if ( exec.isEmpty() || !excheck.exists() ) {
exec = "/bin/sh";
qWarning() << "Neither default shell nor $SHELL is set to a correct path. Fallback to" << defaultShell;
exec = defaultShell;
}
}

@ -28,6 +28,7 @@
#include <QStringList>
#include <QWidget>
#include "Emulation.h"
#include "History.h"
class KProcess;
@ -477,6 +478,11 @@ signals:
*/
void flowControlEnabledChanged(bool enabled);
/**
* Broker for Emulation::cursorChanged() signal
*/
void cursorChanged(Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled);
void silence();
void activity();

@ -96,8 +96,9 @@ QStringList ShellCommand::expand(const QStringList & items)
{
QStringList result;
foreach( QString item , items )
result << expand(item);
foreach(const QString &item, items ) {
result << expand(item);
}
return result;
}

@ -241,9 +241,32 @@ void TerminalDisplay::fontChange(const QFont&)
emit changedFontMetricSignal( _fontHeight, _fontWidth );
propagateSize();
// We will run paint event testing procedure.
// Although this operation will destory the orignal content,
// the content will be drawn again after the test.
_drawTextTestFlag = true;
update();
}
void TerminalDisplay::calDrawTextAdditionHeight(QPainter& painter)
{
QRect test_rect, feedback_rect;
test_rect.setRect(1, 1, _fontWidth * 4, _fontHeight);
painter.drawText(test_rect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + QString("Mq"), &feedback_rect);
//qDebug() << "test_rect:" << test_rect << "feeback_rect:" << feedback_rect;
_drawTextAdditionHeight = (feedback_rect.height() - _fontHeight) / 2;
if(_drawTextAdditionHeight < 0) {
_drawTextAdditionHeight = 0;
}
// update the original content
_drawTextTestFlag = false;
update();
}
void TerminalDisplay::setVTFont(const QFont& f)
{
QFont font = f;
@ -334,9 +357,13 @@ TerminalDisplay::TerminalDisplay(QWidget *parent)
,_colorsInverted(false)
,_blendColor(qRgba(0,0,0,0xff))
,_filterChain(new TerminalImageFilterChain())
,_cursorShape(QTermWidget::BlockCursor)
,_cursorShape(Emulation::KeyboardCursorShape::BlockCursor)
,mMotionAfterPasting(NoMoveScreenWindow)
{
// variables for draw text
_drawTextAdditionHeight = 0;
_drawTextTestFlag = false;
// terminal applications are not designed with Right-To-Left in mind,
// so the layout is forced to Left-To-Right
setLayoutDirection(Qt::LeftToRight);
@ -739,7 +766,7 @@ void TerminalDisplay::drawCursor(QPainter& painter,
else
painter.setPen(foregroundColor);
if ( _cursorShape == QTermWidget::BlockCursor )
if ( _cursorShape == Emulation::KeyboardCursorShape::BlockCursor )
{
// draw the cursor outline, adjusting the area so that
// it is draw entirely inside 'rect'
@ -761,12 +788,12 @@ void TerminalDisplay::drawCursor(QPainter& painter,
}
}
}
else if ( _cursorShape == QTermWidget::UnderlineCursor )
else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor )
painter.drawLine(cursorRect.left(),
cursorRect.bottom(),
cursorRect.right(),
cursorRect.bottom());
else if ( _cursorShape == QTermWidget::IBeamCursor )
else if ( _cursorShape == Emulation::KeyboardCursorShape::IBeamCursor )
painter.drawLine(cursorRect.left(),
cursorRect.top(),
cursorRect.left(),
@ -783,23 +810,30 @@ void TerminalDisplay::drawCharacters(QPainter& painter,
{
// don't draw text which is currently blinking
if ( _blinking && (style->rendition & RE_BLINK) )
return;
// don't draw concealed characters
if (style->rendition & RE_CONCEAL)
return;
// setup bold and underline
bool useBold;
ColorEntry::FontWeight weight = style->fontWeight(_colorTable);
if (weight == ColorEntry::UseCurrentFormat)
useBold = ((style->rendition & RE_BOLD) && _boldIntense) || font().bold();
else
useBold = (weight == ColorEntry::Bold) ? true : false;
bool useUnderline = style->rendition & RE_UNDERLINE || font().underline();
bool useBold = ((style->rendition & RE_BOLD) && _boldIntense) || font().bold();
const bool useUnderline = style->rendition & RE_UNDERLINE || font().underline();
const bool useItalic = style->rendition & RE_ITALIC || font().italic();
const bool useStrikeOut = style->rendition & RE_STRIKEOUT || font().strikeOut();
const bool useOverline = style->rendition & RE_OVERLINE || font().overline();
QFont font = painter.font();
if ( font.bold() != useBold
|| font.underline() != useUnderline )
{
|| font.underline() != useUnderline
|| font.italic() != useItalic
|| font.strikeOut() != useStrikeOut
|| font.overline() != useOverline) {
font.setBold(useBold);
font.setUnderline(useUnderline);
font.setItalic(useItalic);
font.setStrikeOut(useStrikeOut);
font.setOverline(useOverline);
painter.setFont(font);
}
@ -818,16 +852,21 @@ void TerminalDisplay::drawCharacters(QPainter& painter,
drawLineCharString(painter,rect.x(),rect.y(),text,style);
else
{
// the drawText(rect,flags,string) overload is used here with null flags
// instead of drawText(rect,string) because the (rect,string) overload causes
// the application's default layout direction to be used instead of
// the widget-specific layout direction, which should always be
// Qt::LeftToRight for this widget
// This was discussed in: http://lists.kde.org/?t=120552223600002&r=1&w=2
if (_bidiEnabled)
painter.drawText(rect,0,text);
else
painter.drawText(rect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + text);
// Force using LTR as the document layout for the terminal area, because
// there is no use cases for RTL emulator and RTL terminal application.
//
// This still allows RTL characters to be rendered in the RTL way.
painter.setLayoutDirection(Qt::LeftToRight);
if (_bidiEnabled) {
painter.drawText(rect.x(), rect.y() + _fontAscent + _lineSpacing, text);
} else {
{
QRect drawRect(rect.topLeft(), rect.size());
drawRect.setHeight(rect.height() + _drawTextAdditionHeight);
painter.drawText(drawRect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + text);
}
}
}
}
@ -1241,8 +1280,9 @@ void TerminalDisplay::showResizeNotification()
}
if (!_resizeWidget)
{
_resizeWidget = new QLabel("Size: XXX x XXX", this);
_resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().width("Size: XXX x XXX"));
const QString label = tr("Size: XXX x XXX");
_resizeWidget = new QLabel(label, this);
_resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().width(label));
_resizeWidget->setMinimumHeight(_resizeWidget->sizeHint().height());
_resizeWidget->setAlignment(Qt::AlignCenter);
@ -1252,8 +1292,7 @@ void TerminalDisplay::showResizeNotification()
_resizeTimer->setSingleShot(true);
connect(_resizeTimer, SIGNAL(timeout()), _resizeWidget, SLOT(hide()));
}
QString sizeStr = QString("Size: %1 x %2").arg(_columns).arg(_lines);
_resizeWidget->setText(sizeStr);
_resizeWidget->setText(tr("Size: %1 x %2").arg(_columns).arg(_lines));
_resizeWidget->move((width()-_resizeWidget->width())/2,
(height()-_resizeWidget->height())/2+20);
_resizeWidget->show();
@ -1332,14 +1371,21 @@ void TerminalDisplay::paintEvent( QPaintEvent* pe )
paint.fillRect(contentsRect(), background);
}
foreach (const QRect &rect, (pe->region() & contentsRect()).rects())
if(_drawTextTestFlag)
{
calDrawTextAdditionHeight(paint);
}
else
{
drawBackground(paint,rect,palette().background().color(),
true /* use opacity setting */);
drawContents(paint, rect);
foreach (const QRect &rect, (pe->region() & contentsRect()).rects())
{
drawBackground(paint,rect,palette().background().color(),
true /* use opacity setting */);
drawContents(paint, rect);
}
drawInputMethodPreeditString(paint,preeditRect());
paintFilters(paint);
}
drawInputMethodPreeditString(paint,preeditRect());
paintFilters(paint);
}
QPoint TerminalDisplay::cursorPosition() const

@ -677,6 +677,8 @@ private:
void paintFilters(QPainter& painter);
void calDrawTextAdditionHeight(QPainter& painter);
// returns a region covering all of the areas of the widget which contain
// a hotspot
QRegion hotSpotRegion() const;
@ -702,6 +704,8 @@ private:
int _fontWidth; // width
int _fontAscent; // ascend
bool _boldIntense; // Whether intense colors should be rendered with bold font
int _drawTextAdditionHeight; // additional height to prevent font trancation
bool _drawTextTestFlag; // indicate it is a testing or not
int _leftMargin; // offset
int _topMargin; // offset

@ -133,6 +133,7 @@ void Vt102Emulation::reset()
- ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
- CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
- CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
- CSI_PS_SP - Escape codes of the form <ESC>'[' {Pn} ';' ... {Space} C
- CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
- CSI_PE - Escape codes of the form <ESC>'[' '!' {Pn} ';' ... C
- VT52 - VT52 escape codes
@ -160,6 +161,7 @@ void Vt102Emulation::reset()
#define TY_CSI_PS(A,N) TY_CONSTRUCT(5,A,N)
#define TY_CSI_PN(A ) TY_CONSTRUCT(6,A,0)
#define TY_CSI_PR(A,N) TY_CONSTRUCT(7,A,N)
#define TY_CSI_PS_SP(A,N) TY_CONSTRUCT(11,A,N)
#define TY_VT52(A) TY_CONSTRUCT(8,A,0)
#define TY_CSI_PG(A) TY_CONSTRUCT(9,A,0)
@ -203,7 +205,6 @@ void Vt102Emulation::addToCurrentToken(int cc)
}
// Character Class flags used while decoding
#define CTL 1 // Control character
#define CHR 2 // Printable character
#define CPN 4 // TODO: Document me
@ -223,7 +224,7 @@ void Vt102Emulation::initTokenizer()
charClass[i] |= CTL;
for(i = 32;i < 256; ++i)
charClass[i] |= CHR;
for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s)
for(s = (quint8*)"@ABCDGHILMPSTXZbcdfry"; *s; ++s)
charClass[*s] |= CPN;
// resize = \e[8;<row>;<col>t
for(s = (quint8*)"t"; *s; ++s)
@ -266,17 +267,19 @@ void Vt102Emulation::initTokenizer()
#define epp( ) (p >= 3 && s[2] == '?')
#define epe( ) (p >= 3 && s[2] == '!')
#define egt( ) (p >= 3 && s[2] == '>')
#define esp( ) (p == 4 && s[3] == ' ')
#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
#define Xte (Xpe && cc == 7 )
#define Xte (Xpe && (cc == 7 || cc == 33))
#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
#define ESC 27
#define CNTL(c) ((c)-'@')
#define ESC 27
#define DEL 127
// process an incoming unicode character
void Vt102Emulation::receiveChar(int cc)
{
if (cc == 127)
if (cc == DEL)
return; //VT100: ignore.
if (ces(CTL))
@ -314,6 +317,12 @@ void Vt102Emulation::receiveChar(int cc)
if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0); resetTokenizer(); return; }
if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0); resetTokenizer(); return; }
if (eps( CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]); resetTokenizer(); return; }
if (esp( )) { return; }
if (lec(5, 4, 'q') && s[3] == ' ') {
processToken( TY_CSI_PS_SP(cc, argv[0]), argv[0], 0);
resetTokenizer();
return;
}
// resize = \e[8;<row>;<col>t
if (eps(CPS))
@ -531,7 +540,7 @@ void Vt102Emulation::processToken(int token, int p, int q)
case TY_ESC_DE('8' ) : _currentScreen->helpAlign ( ); break;
// resize = \e[8;<row>;<col>t
case TY_CSI_PS('t', 8) : setImageSize( q /* columns */, p /* lines */ );
case TY_CSI_PS('t', 8) : setImageSize( p /*lines */, q /* columns */ );
emit imageResizeRequest(QSize(q, p));
break;
@ -557,18 +566,27 @@ void Vt102Emulation::processToken(int token, int p, int q)
case TY_CSI_PS('m', 0) : _currentScreen->setDefaultRendition ( ); break;
case TY_CSI_PS('m', 1) : _currentScreen-> setRendition (RE_BOLD ); break; //VT100
case TY_CSI_PS('m', 2) : _currentScreen-> setRendition (RE_FAINT ); break;
case TY_CSI_PS('m', 3) : _currentScreen-> setRendition (RE_ITALIC ); break; //VT100
case TY_CSI_PS('m', 4) : _currentScreen-> setRendition (RE_UNDERLINE); break; //VT100
case TY_CSI_PS('m', 5) : _currentScreen-> setRendition (RE_BLINK ); break; //VT100
case TY_CSI_PS('m', 7) : _currentScreen-> setRendition (RE_REVERSE ); break;
case TY_CSI_PS('m', 8) : _currentScreen-> setRendition (RE_CONCEAL ); break;
case TY_CSI_PS('m', 9) : _currentScreen-> setRendition (RE_STRIKEOUT); break;
case TY_CSI_PS('m', 53) : _currentScreen-> setRendition (RE_OVERLINE ); break;
case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD ); break;
case TY_CSI_PS('m', 21) : _currentScreen->resetRendition (RE_BOLD ); break;
case TY_CSI_PS('m', 22) : _currentScreen->resetRendition (RE_BOLD );
_currentScreen->resetRendition (RE_FAINT ); break;
case TY_CSI_PS('m', 23) : _currentScreen->resetRendition (RE_ITALIC ); break; //VT100
case TY_CSI_PS('m', 24) : _currentScreen->resetRendition (RE_UNDERLINE); break;
case TY_CSI_PS('m', 25) : _currentScreen->resetRendition (RE_BLINK ); break;
case TY_CSI_PS('m', 27) : _currentScreen->resetRendition (RE_REVERSE ); break;
case TY_CSI_PS('m', 28) : _currentScreen->resetRendition (RE_CONCEAL ); break;
case TY_CSI_PS('m', 29) : _currentScreen->resetRendition (RE_STRIKEOUT); break;
case TY_CSI_PS('m', 55) : _currentScreen->resetRendition (RE_OVERLINE ); break;
case TY_CSI_PS('m', 30) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 0); break;
case TY_CSI_PS('m', 31) : _currentScreen->setForeColor (COLOR_SPACE_SYSTEM, 1); break;
@ -624,6 +642,14 @@ void Vt102Emulation::processToken(int token, int p, int q)
case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
case TY_CSI_PS_SP('q', 0) : /* fall through */
case TY_CSI_PS_SP('q', 1) : emit cursorChanged(KeyboardCursorShape::BlockCursor, true ); break;
case TY_CSI_PS_SP('q', 2) : emit cursorChanged(KeyboardCursorShape::BlockCursor, false); break;
case TY_CSI_PS_SP('q', 3) : emit cursorChanged(KeyboardCursorShape::UnderlineCursor, true ); break;
case TY_CSI_PS_SP('q', 4) : emit cursorChanged(KeyboardCursorShape::UnderlineCursor, false); break;
case TY_CSI_PS_SP('q', 5) : emit cursorChanged(KeyboardCursorShape::IBeamCursor, true ); break;
case TY_CSI_PS_SP('q', 6) : emit cursorChanged(KeyboardCursorShape::IBeamCursor, false); break;
case TY_CSI_PN('@' ) : _currentScreen->insertChars (p ); break;
case TY_CSI_PN('A' ) : _currentScreen->cursorUp (p ); break; //VT100
case TY_CSI_PN('B' ) : _currentScreen->cursorDown (p ); break; //VT100
@ -641,6 +667,7 @@ void Vt102Emulation::processToken(int token, int p, int q)
case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break;
case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break;
case TY_CSI_PN('Z' ) : _currentScreen->backtab (p ); break;
case TY_CSI_PN('b' ) : _currentScreen->repeatChars (p ); break;
case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX
case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100
@ -885,12 +912,12 @@ void Vt102Emulation::reportAnswerBack()
/*!
`cx',`cy' are 1-based.
`eventType' indicates the button pressed (0-2)
or a general mouse release (3).
`cb' indicates the button pressed or released (0-2) or scroll event (4-5).
eventType represents the kind of mouse action that occurred:
0 = Mouse button press or release
0 = Mouse button press
1 = Mouse drag
2 = Mouse button release
*/
void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
@ -905,10 +932,31 @@ void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
//Mouse motion handling
if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
cb += 0x20; //add 32 to signify motion event
cb += 0x20; //add 32 to signify motion event
char command[32];
command[0] = '\0';
// Check the extensions in decreasing order of preference. Encoding the release event above assumes that 1006 comes first.
if (getMode(MODE_Mouse1006)) {
snprintf(command, sizeof(command), "\033[<%d;%d;%d%c", cb, cx, cy, eventType == 2 ? 'm' : 'M');
} else if (getMode(MODE_Mouse1015)) {
snprintf(command, sizeof(command), "\033[%d;%d;%dM", cb + 0x20, cx, cy);
} else if (getMode(MODE_Mouse1005)) {
if (cx <= 2015 && cy <= 2015) {
// The xterm extension uses UTF-8 (up to 2 bytes) to encode
// coordinate+32, no matter what the locale is. We could easily
// convert manually, but QString can also do it for us.
QChar coords[2];
coords[0] = cx + 0x20;
coords[1] = cy + 0x20;
QString coordsStr = QString(coords, 2);
QByteArray utf8 = coordsStr.toUtf8();
snprintf(command, sizeof(command), "\033[M%c%s", cb + 0x20, utf8.constData());
}
} else if (cx <= 223 && cy <= 223) {
snprintf(command, sizeof(command), "\033[M%c%c%c", cb + 0x20, cx + 0x20, cy + 0x20);
}
char command[20];
sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
sendString(command);
}
@ -965,10 +1013,15 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
// check flow control state
if (modifiers & Qt::ControlModifier)
{
if (event->key() == Qt::Key_S)
switch (event->key()) {
case Qt::Key_S:
emit flowControlKeyPressed(true);
else if (event->key() == Qt::Key_Q)
break;
case Qt::Key_Q:
case Qt::Key_C: // cancel flow control
emit flowControlKeyPressed(false);
break;
}
}
// lookup key binding
@ -987,6 +1040,7 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
// (unless there is an entry defined for this particular combination
// in the keyboard modifier)
bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
bool wantsMetaModifier = entry.modifiers() & entry.modifierMask() & Qt::MetaModifier;
bool wantsAnyModifier = entry.state() &
entry.stateMask() & KeyboardTranslator::AnyModifierState;
@ -995,6 +1049,11 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
{
textToSend.prepend("\033");
}
if ( modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier)
&& !event->text().isEmpty() )
{
textToSend.prepend("\030@s");
}
if ( entry.command() != KeyboardTranslator::NoCommand )
{
@ -1169,6 +1228,9 @@ void Vt102Emulation::resetModes()
resetMode(MODE_Mouse1001); saveMode(MODE_Mouse1001);
resetMode(MODE_Mouse1002); saveMode(MODE_Mouse1002);
resetMode(MODE_Mouse1003); saveMode(MODE_Mouse1003);
resetMode(MODE_Mouse1005); saveMode(MODE_Mouse1005);
resetMode(MODE_Mouse1006); saveMode(MODE_Mouse1006);
resetMode(MODE_Mouse1015); saveMode(MODE_Mouse1015);
resetMode(MODE_BracketedPaste); saveMode(MODE_BracketedPaste);
resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
@ -1268,7 +1330,7 @@ char Vt102Emulation::eraseChar() const
0,
0);
if ( entry.text().count() > 0 )
return entry.text()[0];
return entry.text().at(0);
else
return '\b';
}

@ -133,7 +133,7 @@ private:
void resetModes();
void resetTokenizer();
#define MAX_TOKEN_LENGTH 80
#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;
@ -153,6 +153,7 @@ private:
void processToken(int code, int p, int q);
void processWindowAttributeChange();
void requestWindowAttribute(int);
void reportTerminalType();
void reportSecondaryAttributes();

@ -62,6 +62,11 @@ key Down -Shift+AnyMod+Ansi : "\E[1;*B"
key Right -Shift+AnyMod+Ansi : "\E[1;*C"
key Left -Shift+AnyMod+Ansi : "\E[1;*D"
key Up +Shift+AppScreen : "\E[1;*A"
key Down +Shift+AppScreen : "\E[1;*B"
key Left +Shift+AppScreen : "\E[1;*D"
key Right +Shift+AppScreen : "\E[1;*C"
# Keypad keys with NumLock ON
# (see "Numeric Keypad" section at http://www.nw.com/nw/WWW/products/wizcon/vt100.html )
#
@ -99,10 +104,10 @@ key End +AppCuKeys+KeyPad : "\EOF"
key Home -AppCuKeys+KeyPad : "\E[H"
key End -AppCuKeys+KeyPad : "\E[F"
key Insert +KeyPad : "\E[2~"
key Delete +KeyPad : "\E[3~"
key Prior -Shift+KeyPad : "\E[5~"
key Next -Shift+KeyPad : "\E[6~"
key Insert +KeyPad : "\E[2~"
key Delete +KeyPad : "\E[3~"
key PgUp -Shift+KeyPad : "\E[5~"
key PgDown -Shift+KeyPad : "\E[6~"
# other grey PC keys
@ -121,10 +126,10 @@ key Delete -AnyMod : "\E[3~"
key Insert +AnyMod : "\E[2;*~"
key Delete +AnyMod : "\E[3;*~"
key Prior -Shift-AnyMod : "\E[5~"
key Next -Shift-AnyMod : "\E[6~"
key Prior -Shift+AnyMod : "\E[5;*~"
key Next -Shift+AnyMod : "\E[6;*~"
key PgUp -Shift-AnyMod : "\E[5~"
key PgDown -Shift-AnyMod : "\E[6~"
key PgUp -Shift+AnyMod : "\E[5;*~"
key PgDown -Shift+AnyMod : "\E[6;*~"
# Function keys
key F1 -AnyMod : "\EOP"
@ -160,10 +165,12 @@ key Space +Control : "\x00"
# Some keys are used by konsole to cause operations.
# The scroll* operations refer to the history buffer.
key Up +Shift-AppScreen : scrollLineUp
key Prior +Shift-AppScreen : scrollPageUp
key Down +Shift-AppScreen : scrollLineDown
key Next +Shift-AppScreen : scrollPageDown
key Up +Shift-AppScreen : scrollLineUp
key PgUp +Shift-AppScreen : scrollPageUp
key Home +Shift-AppScreen : scrollUpToTop
key Down +Shift-AppScreen : scrollLineDown
key PgDown +Shift-AppScreen : scrollPageDown
key End +Shift-AppScreen : scrollDownToBottom
key ScrollLock : scrollLock

@ -102,9 +102,9 @@ key F12 : "\E[24~"
key Home : "\E[H"
key End : "\E[F"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
key Insert-Shift : "\E[2~"
key PgUp -Shift : "\E[5~"
key PgDown -Shift : "\E[6~"
key Insert -Shift : "\E[2~"
# Keypad-Enter. See comment on Return above.
@ -115,10 +115,10 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
key Up +Shift : scrollLineUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key PgDown +Shift : scrollPageDown
key ScrollLock : scrollLock

@ -36,8 +36,8 @@ key Home : "\E[1~"
key Insert-Shift : "\E[2~"
key Delete : "\E[3~"
key End : "\E[4~"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
key PgUp -Shift : "\E[5~"
key PgDown -Shift : "\E[6~"
# function keys
@ -61,10 +61,10 @@ key Space +Control : "\x00"
# Some keys are used by konsole to cause operations.
# The scroll* operations refer to the history buffer.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
key Up +Shift : scrollLineUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key PgDown +Shift : scrollPageDown
key ScrollLock : scrollLock

@ -108,9 +108,9 @@ key F12 : "\E[24~"
key Home : "\E[1~"
key End : "\E[4~"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
key Insert-Shift : "\E[2~"
key PgUp -Shift : "\E[5~"
key PgDown -Shift : "\E[6~"
key Insert -Shift : "\E[2~"
# Keypad-Enter. See comment on Return above.
@ -121,10 +121,10 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
key Up +Shift : scrollLineUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key PgDown +Shift : scrollPageDown
key ScrollLock : scrollLock

@ -99,10 +99,10 @@ key Delete -AnyMod : "\E[3~"
key Insert +AnyMod : "\E[2;*~"
key Delete +AnyMod : "\E[3;*~"
key Prior -Shift-AnyMod : "\E[5~"
key Next -Shift-AnyMod : "\E[6~"
key Prior -Shift+AnyMod : "\E[5;*~"
key Next -Shift+AnyMod : "\E[6;*~"
key PgUp -Shift-AnyMod : "\E[5~"
key PgDown -Shift-AnyMod : "\E[6~"
key PgUp -Shift+AnyMod : "\E[5;*~"
key PgDown -Shift+AnyMod : "\E[6;*~"
# Function keys
#key F1 -AnyMod : "\EOP"
@ -160,10 +160,10 @@ key Space +Control : "\x00"
# Some keys are used by konsole to cause operations.
# The scroll* operations refer to the history buffer.
key Up +Shift-AppScreen : scrollLineUp
key Prior +Shift-AppScreen : scrollPageUp
key Down +Shift-AppScreen : scrollLineDown
key Next +Shift-AppScreen : scrollPageDown
key Up +Shift-AppScreen : scrollLineUp
key PgUp +Shift-AppScreen : scrollPageUp
key Down +Shift-AppScreen : scrollLineDown
key PgDown +Shift-AppScreen : scrollPageDown
#key Up +Shift : scrollLineUp
#key Prior +Shift : scrollPageUp

@ -72,8 +72,8 @@ key Home : "\E[1~"
key Insert-Shift : "\E[2~"
key Delete : "\E[3~"
key End : "\E[4~"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
key PgUp -Shift : "\E[5~"
key PgDown -Shift : "\E[6~"
# function keys
@ -99,10 +99,10 @@ key Space +Control : "\x00"
#key Left +Shift : prevSession
#key Right +Shift : nextSession
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
key Up +Shift : scrollLineUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key PgDown +Shift : scrollPageDown
#key Insert+Shift : emitSelection
# keypad characters are not offered differently by Qt.

@ -138,9 +138,9 @@ key F12+Shift : "\E[24;2~"
key Home : "\E[H"
key End : "\E[F"
key Prior -Shift : "\E[5~"
key Next -Shift : "\E[6~"
key Insert-Shift : "\E[2~"
key PgUp -Shift : "\E[5~"
key PgDown -Shift : "\E[6~"
key Insert -Shift : "\E[2~"
# Keypad-Enter. See comment on Return above.
@ -151,10 +151,10 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
key Up +Shift : scrollLineUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key PgDown +Shift : scrollPageDown
key ScrollLock : scrollLock

@ -503,7 +503,11 @@ void KPty::login(const char * user, const char * remotehost)
// note: strncpy without terminators _is_ correct here. man 4 utmp
if (user) {
# ifdef HAVE_UTMPX
strncpy(l_struct.ut_user, user, sizeof(l_struct.ut_user));
# else
strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
# endif
}
if (remotehost) {
@ -614,7 +618,11 @@ void KPty::logout()
setutent();
if ((ut = getutline(&l_struct))) {
# endif
# ifdef HAVE_UTMPX
memset(ut->ut_user, 0, sizeof(*ut->ut_user));
# else
memset(ut->ut_name, 0, sizeof(*ut->ut_name));
# endif
memset(ut->ut_host, 0, sizeof(*ut->ut_host));
# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
ut->ut_syslen = 0;

@ -278,7 +278,7 @@ public:
{
int index = 0;
int start = head;
QLinkedList<QByteArray>::ConstIterator it = buffers.begin();
QLinkedList<QByteArray>::ConstIterator it = buffers.constBegin();
forever {
if (!maxLength)
return index;

@ -246,8 +246,28 @@ void QTermWidget::init(int startnow)
m_layout->setMargin(0);
setLayout(m_layout);
// translations
// First check $XDG_DATA_DIRS. This follows the implementation in libqtxdg
QString d = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
QStringList dirs = d.split(QLatin1Char(':'), QString::SkipEmptyParts);
if (dirs.isEmpty()) {
dirs.append(QString::fromLatin1("/usr/local/share"));
dirs.append(QString::fromLatin1("/usr/share"));
}
dirs.append(QFile::decodeName(TRANSLATIONS_DIR));
m_translator = new QTranslator(this);
for (const QString& dir : dirs) {
qDebug() << "Trying to load translation file from dir" << dir;
if (m_translator->load(QLocale::system(), "qtermwidget", "_", dir)) {
qApp->installTranslator(m_translator);
qDebug() << "Translations found in" << dir;
break;
}
}
m_impl = new TermWidgetImpl(this);
m_impl->m_terminalDisplay->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_layout->addWidget(m_impl->m_terminalDisplay);
connect(m_impl->m_session, SIGNAL(bellRequest(QString)), m_impl->m_terminalDisplay, SLOT(bell(QString)));
@ -255,6 +275,8 @@ void QTermWidget::init(int startnow)
connect(m_impl->m_session, SIGNAL(activity()), this, SIGNAL(activity()));
connect(m_impl->m_session, SIGNAL(silence()), this, SIGNAL(silence()));
connect(m_impl->m_session, &Session::profileChangeCommandReceived, this, &QTermWidget::profileChanged);
connect(m_impl->m_session, &Session::receivedData, this, &QTermWidget::receivedData);
// That's OK, FilterChain's dtor takes care of UrlFilter.
UrlFilter *urlFilter = new UrlFilter();
@ -296,13 +318,14 @@ void QTermWidget::init(int startnow)
m_searchBar->setFont(font);
setScrollBarPosition(NoScrollBar);
setKeyboardCursorShape(BlockCursor);
setKeyboardCursorShape(Emulation::KeyboardCursorShape::BlockCursor);
m_impl->m_session->addView(m_impl->m_terminalDisplay);
connect(m_impl->m_session, SIGNAL(resizeRequest(QSize)), this, SLOT(setSize(QSize)));
connect(m_impl->m_session, SIGNAL(finished()), this, SLOT(sessionFinished()));
connect(m_impl->m_session, &Session::titleChanged, this, &QTermWidget::titleChanged);
connect(m_impl->m_session, &Session::cursorChanged, this, &QTermWidget::cursorChanged);
}
@ -668,6 +691,13 @@ void QTermWidget::setKeyboardCursorShape(KeyboardCursorShape shape)
m_impl->m_terminalDisplay->setKeyboardCursorShape(shape);
}
void QTermWidget::setBlinkingCursor(bool blink)
{
if (!m_impl->m_terminalDisplay)
return;
m_impl->m_terminalDisplay->setBlinkingCursor(blink);
}
QString QTermWidget::title() const
{
QString title = m_impl->m_session->userTitle();
@ -688,3 +718,15 @@ bool QTermWidget::isTitleChanged() const
{
return m_impl->m_session->isTitleChanged();
}
void QTermWidget::setAutoClose(bool autoClose)
{
m_impl->m_session->setAutoClose(autoClose);
}
void QTermWidget::cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled)
{
// TODO: A switch to enable/disable DECSCUSR?
setKeyboardCursorShape(cursorShape);
setBlinkingCursor(blinkingCursorEnabled);
}

@ -20,15 +20,18 @@
#ifndef _Q_TERM_WIDGET
#define _Q_TERM_WIDGET
#include <QTranslator>
#include <QWidget>
#include "Emulation.h"
#include "Filter.h"
#include "qtermwidget_export.h"
class QVBoxLayout;
struct TermWidgetImpl;
class SearchBar;
class QUrl;
class QTermWidget : public QWidget {
class QTERMWIDGET_EXPORT QTermWidget : public QWidget {
Q_OBJECT
public:
@ -44,24 +47,7 @@ public:
ScrollBarRight = 2
};
/**
* This enum describes the available shapes for the keyboard cursor.
* See setKeyboardCursorShape()
*/
enum KeyboardCursorShape {
/** A rectangular block which covers the entire area of the cursor character. */
BlockCursor = 0,
/**
* A single flat line which occupies the space at the bottom of the cursor
* character's area.
*/
UnderlineCursor = 1,
/**
* An cursor shaped like the capital letter 'I', similar to the IBeam
* cursor used in Qt/KDE text editors.
*/
IBeamCursor = 2
};
using KeyboardCursorShape = Konsole::Emulation::KeyboardCursorShape;
//Creation of widget
QTermWidget(int startnow, // 1 = start shell programm immediatelly
@ -211,6 +197,15 @@ public:
*/
void setKeyboardCursorShape(KeyboardCursorShape shape);
void setBlinkingCursor(bool blink);
/**
* Automatically close the terminal session after the shell process exits or
* keep it running.
*/
void setAutoClose(bool);
QString title() const;
QString icon() const;
@ -240,8 +235,16 @@ signals:
*/
void sendData(const char *,int);
void profileChanged(const QString & profile);
void titleChanged();
/**
* Signals that we received new data from the process running in the
* terminal emulator
*/
void receivedData(const QString &text);
public slots:
// Copy selection to clipboard
void copyClipboard();
@ -282,6 +285,11 @@ private slots:
void findPrevious();
void matchFound(int startColumn, int startLine, int endColumn, int endLine);
void noMatchFound();
/**
* Emulation::cursorChanged() signal propogates to here and QTermWidget
* sends the specified cursor states to the terminal display
*/
void cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled);
private:
void search(bool forwards, bool next);
@ -290,6 +298,7 @@ private:
TermWidgetImpl * m_impl;
SearchBar* m_searchBar;
QVBoxLayout *m_layout;
QTranslator *m_translator;
};

@ -92,7 +92,7 @@ const QStringList get_color_schemes_dirs()
rval << (QCoreApplication::applicationDirPath() + "/../Resources/color-schemes/");
}
#endif
for (const QString& custom_dir : custom_color_schemes_dirs)
for (const QString& custom_dir : const_cast<const QStringList&>(custom_color_schemes_dirs))
{
d.setPath(custom_dir);
if (d.exists())

@ -4,31 +4,33 @@ PyQt5 Bindings for QTermWidget
INSTALL:
------------
####1. Download QTermWidget -> https://github.com/lxde/qtermwidget
####2. Compile and install it:
$ mkdir build && cd build
####1. Download, compile and install QTermWidget:
$ git clone https://github.com/lxde/qtermwidget.git
$ cd qtermwidget && mkdir build && cd build
$ cmake ..
$ make
$ sudo make install
If `make install` command will not work just copy the `qtermwidget.so*` files to /usr/lib directory.
####3. Install PyQt5 and PyQt5-devel if not yet installed.
####4. Configure, compile and install bindings. Execute in terminal in the qtermwidget bindings folder:
$ python config.py
####2. Install PyQt5 and PyQt5-devel if not yet installed.
####3. Configure, compile and install Python bindings. Execute in terminal in the qtermwidget bindings folder:
$ cd pyqt/
$ QT_SELECT=5 python config.py
$ make
$ sudo make install
####5. You can run ./test.py to test the installed module.
####4. You can run ./test.py to test the installed module.
ABOUT:
---------
Curently maintained by:
- Pawel Koston <pawelkoston@gmail.com>
Based on previous PyQt4 bindings by:
- Piotr "Riklaunim" Maliński <riklaunim@gmail.com>,
- Alexander Slesarev <alex.slesarev@gmail.com>
PyQt5 QTermWidget Bindings
License: GPL3

@ -5,66 +5,74 @@ import os
import site
import pprint
from distutils import sysconfig
import pyqtconfig
from PyQt5 import QtCore
import PyQt5
class Configuration(sipconfig.Configuration):
"""The class that represents PyQt configuration values.
"""
def getEnv(self,name, default):
return os.environ.get(name) or default
def __init__(self):
qtconfig = subprocess.check_output(["/usr/lib64/qt5/bin/qmake", "-query"], universal_newlines=True)
qtconfig = dict(x.split(":", 1) for x in qtconfig.splitlines())
self.pyQtIncludePath = self.getEnv('PYQT_INCLUDE_PATH','/usr/share/sip/PyQt5' )
pyqtconfig = {
"pyqt_config_args": "--confirm-license -v "+str(self.pyQtIncludePath)+" --qsci-api -q /usr/lib64/qt5/bin/qmake",
"pyqt_version": QtCore.PYQT_VERSION,
"pyqt_version_str": QtCore.PYQT_VERSION_STR,
"pyqt_bin_dir": PyQt5.__path__[0],
"pyqt_mod_dir": PyQt5.__path__[0],
"pyqt_sip_dir": str(self.pyQtIncludePath),
"pyqt_modules": "QtCore QtGui QtWidgets", #... and many more
"pyqt_sip_flags": QtCore.PYQT_CONFIGURATION['sip_flags'],
"qt_version": QtCore.QT_VERSION,
"qt_edition": "free",
"qt_winconfig": "shared",
"qt_framework": 0,
"qt_threaded": 1,
"qt_dir": qtconfig['QT_INSTALL_PREFIX'],
"qt_data_dir": qtconfig['QT_INSTALL_DATA'],
"qt_archdata_dir": qtconfig['QT_INSTALL_DATA'],
"qt_inc_dir": qtconfig['QT_INSTALL_HEADERS'],
"qt_lib_dir": qtconfig['QT_INSTALL_LIBS']
}
macros = sipconfig._default_macros.copy()
macros['INCDIR_QT'] = qtconfig['QT_INSTALL_HEADERS']
macros['LIBDIR_QT'] = qtconfig['QT_INSTALL_LIBS']
macros['MOC'] = os.path.join(qtconfig['QT_INSTALL_BINS'], 'moc')
sipconfig.Configuration.__init__(self, [pyqtconfig])
self.set_build_macros(macros)
## The name of the SIP build file generated by SIP and used by the build system.
"""The class that represents PyQt configuration values.
"""
def getEnv(self, name, default):
return os.environ.get(name) or default
def __init__(self):
qmake_bin = subprocess.check_output(
["which", "qmake"], universal_newlines=True).strip(' \t\n\r')
qtconfig = subprocess.check_output(
[qmake_bin, "-query"], universal_newlines=True)
qtconfig = dict(x.split(":", 1) for x in qtconfig.splitlines())
self.pyQtIncludePath = self.getEnv(
'PYQT_INCLUDE_PATH', '/usr/share/sip/PyQt5')
pyqtconfig = {
"pyqt_config_args": "--confirm-license -v " + str(self.pyQtIncludePath) + " --qsci-api -q " + qmake_bin,
"pyqt_version": QtCore.PYQT_VERSION,
"pyqt_version_str": QtCore.PYQT_VERSION_STR,
"pyqt_bin_dir": PyQt5.__path__[0],
"pyqt_mod_dir": PyQt5.__path__[0],
"pyqt_sip_dir": str(self.pyQtIncludePath),
"pyqt_modules": "QtCore QtGui QtWidgets", # ... and many more
"pyqt_sip_flags": QtCore.PYQT_CONFIGURATION['sip_flags'],
"qt_version": QtCore.QT_VERSION,
"qt_edition": "free",
"qt_winconfig": "shared",
"qt_framework": 0,
"qt_threaded": 1,
"qt_dir": qtconfig['QT_INSTALL_PREFIX'],
"qt_data_dir": qtconfig['QT_INSTALL_DATA'],
"qt_archdata_dir": qtconfig['QT_INSTALL_DATA'],
"qt_inc_dir": qtconfig['QT_INSTALL_HEADERS'],
"qt_lib_dir": qtconfig['QT_INSTALL_LIBS']
}
macros = sipconfig._default_macros.copy()
macros['INCDIR_QT'] = qtconfig['QT_INSTALL_HEADERS']
macros['LIBDIR_QT'] = qtconfig['QT_INSTALL_LIBS']
macros['MOC'] = os.path.join(qtconfig['QT_INSTALL_BINS'], 'moc')
sipconfig.Configuration.__init__(self, [pyqtconfig])
self.set_build_macros(macros)
# The name of the SIP build file generated by SIP and used by the build system.
build_file = "qtermwidget.sbf"
# Get the SIP configuration information.
config = Configuration()
# Run SIP to generate the build_file
os.system(" ".join([config.sip_bin, '-I' , str(config.pyQtIncludePath), str(config.pyqt_sip_flags), "-b", build_file,"-o", "-c", ". " " qtermwidget.sip"]))
os.system(" ".join([config.sip_bin, '-I', str(config.pyQtIncludePath), str(
config.pyqt_sip_flags), "-b", build_file, "-o", "-c", ". " " qtermwidget.sip"]))
installs = []
installs.append(["qtermwidget.sip", os.path.join(config.pyqt_sip_dir,"qtermwidget")])
installs.append(["qtermwidget.sip", os.path.join(
config.pyqt_sip_dir, "qtermwidget")])
installs.append(["qtermwidgetconfig.py", config.pyqt_mod_dir])
makefile = sipconfig.SIPModuleMakefile( configuration = config, build_file = build_file, installs = installs, qt=["QtCore" ,"QtGui", "QtWidgets"] )
makefile = sipconfig.SIPModuleMakefile(
configuration=config, build_file=build_file, installs=installs, qt=["QtCore", "QtGui", "QtWidgets"])
# Add the library we are wrapping. The name doesn't include any platform
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
@ -73,20 +81,23 @@ makefile.extra_lib_dirs.append("../lib/")
makefile.extra_lib_dirs.append("..")
makefile.extra_libs = ["qtermwidget5"]
# Support for C++11
makefile.extra_cxxflags.append('-std=c++11')
# Generate the Makefile itself.
makefile.generate()
content = {
# Publish where the SIP specifications for this module will be
# installed.
"qtermwidget_sip_dir": config.pyqt_sip_dir,
# Publish the set of SIP flags needed by this module. As these are the
# same flags needed by the qt module we could leave it out, but this
# allows us to change the flags at a later date without breaking
# scripts that import the configuration module.
"qtermwidget_sip_flags": config.pyqt_sip_flags
}
# Publish where the SIP specifications for this module will be
# installed.
"qtermwidget_sip_dir": config.pyqt_sip_dir,
# Publish the set of SIP flags needed by this module. As these are the
# same flags needed by the qt module we could leave it out, but this
# allows us to change the flags at a later date without breaking
# scripts that import the configuration module.
"qtermwidget_sip_flags": config.pyqt_sip_flags
}
# This creates the qtermwidgetconfig.py module from the qtermwidgetconfig.py.in
# template and the dictionary.

@ -1,8 +1,6 @@
%Module QTermWidget
%Import QtGui/QtGuimod.sip
%Import QtCore/QtCoremod.sip
%Import QtWidgets/QtWidgetsmod.sip
@ -21,9 +19,16 @@ public:
ScrollBarRight=2
};
enum KeyboardCursorShape
{
BlockCursor=0,
UnderlineCursor=1,
IBeamCursor=2
};
QTermWidget(int startnow = 1, QWidget *parent = 0);
~QTermWidget();
void startTerminalTeletype();
QSize sizeHint() const;
void startShellProgram();
int getShellPID();
@ -35,10 +40,11 @@ public:
void setShellProgram(const QString & progname);
void setWorkingDirectory(const QString & dir);
QString workingDirectory();
void setArgs(QStringList &args);
void setArgs(QStringList & args);
void setTextCodec(QTextCodec *codec);
void setColorScheme(const QString & name);
static QStringList availableColorSchemes();
static void addCustomColorSchemeDir(const QString& custom_dir);
void setHistorySize(int lines);
void setScrollBarPosition(ScrollBarPosition);
void scrollToEnd();
@ -59,28 +65,48 @@ public:
void setMonitorActivity(bool);
void setMonitorSilence(bool);
void setSilenceTimeout(int seconds);
int getPtySlaveFd() const;
void setKeyboardCursorShape(KeyboardCursorShape shape);
void setAutoClose(bool);
QString title() const;
QString icon() const;
signals:
void finished();
void copyAvailable(bool);
void termGetFocus();
void termLostFocus();
void termKeyPressed(QKeyEvent *);
void urlActivated(const QUrl&);
void urlActivated(const QUrl&, bool fromContextMenu);
void bell(const QString& message);
void activity();
void silence();
void sendData(const char *,int);
void titleChanged();
void receivedData(const QString &text);
void profileChanged(const QString & profile);
public slots:
void copyClipboard();
void pasteClipboard();
void pasteSelection();
void zoomIn();
void zoomOut();
void setSize(const QSize &);
void setKeyBindings(const QString & kb);
void clear();
void toggleShowSearchBar();
void setSize(const QSize&);
protected:
void resizeEvent(QResizeEvent *e);
virtual void resizeEvent(QResizeEvent *);
protected slots:
void sessionFinished();
void selectionChanged(bool textSelected);
private:
void *createTermWidget(int startnow, void *parent);
void search(bool forwards, bool next);
void setZoom(int step);
void init(int startnow);
private slots:
void find();
void findNext();
void findPrevious();
void matchFound(int startColumn, int startLine, int endColumn, int endLine);
void noMatchFound();
};

Loading…
Cancel
Save