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")
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})
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} ${QTERMWIDGET_QT_LIBRARIES})
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(

@ -4,7 +4,7 @@
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.
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.
@ -15,10 +15,10 @@ This project is licensed under the terms of the [GPLv2](https://www.gnu.org/lice
### 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.

@ -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 )
foreach(const QString &item, items ) {
result << expand(item);
}
return result;
}

@ -241,6 +241,29 @@ 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();
}
@ -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(),
@ -785,21 +812,28 @@ void TerminalDisplay::drawCharacters(QPainter& painter,
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,6 +1371,12 @@ void TerminalDisplay::paintEvent( QPaintEvent* pe )
paint.fillRect(contentsRect(), background);
}
if(_drawTextTestFlag)
{
calDrawTextAdditionHeight(paint);
}
else
{
foreach (const QRect &rect, (pe->region() & contentsRect()).rects())
{
drawBackground(paint,rect,palette().background().color(),
@ -1340,6 +1385,7 @@ void TerminalDisplay::paintEvent( QPaintEvent* pe )
}
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 )
@ -907,8 +934,29 @@ void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
cb += 0x20; //add 32 to signify motion event
char command[20];
sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
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);
}
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 )
#
@ -101,8 +106,8 @@ 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 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"
@ -161,9 +166,11 @@ key Space +Control : "\x00"
# The scroll* operations refer to the history buffer.
key Up +Shift-AppScreen : scrollLineUp
key Prior +Shift-AppScreen : scrollPageUp
key PgUp +Shift-AppScreen : scrollPageUp
key Home +Shift-AppScreen : scrollUpToTop
key Down +Shift-AppScreen : scrollLineDown
key Next +Shift-AppScreen : scrollPageDown
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.
@ -116,9 +116,9 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
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
@ -62,9 +62,9 @@ key Space +Control : "\x00"
# The scroll* operations refer to the history buffer.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
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.
@ -122,9 +122,9 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
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"
@ -161,9 +161,9 @@ key Space +Control : "\x00"
# The scroll* operations refer to the history buffer.
key Up +Shift-AppScreen : scrollLineUp
key Prior +Shift-AppScreen : scrollPageUp
key PgUp +Shift-AppScreen : scrollPageUp
key Down +Shift-AppScreen : scrollLineDown
key Next +Shift-AppScreen : scrollPageDown
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
@ -100,9 +100,9 @@ key Space +Control : "\x00"
#key Left +Shift : prevSession
#key Right +Shift : nextSession
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
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.
@ -152,9 +152,9 @@ key Space +Control : "\x00"
# some of keys are used by konsole.
key Up +Shift : scrollLineUp
key Prior +Shift : scrollPageUp
key PgUp +Shift : scrollPageUp
key Down +Shift : scrollLineDown
key Next +Shift : scrollPageDown
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,30 +5,35 @@ 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):
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)
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' )
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_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_modules": "QtCore QtGui QtWidgets", # ... and many more
"pyqt_sip_flags": QtCore.PYQT_CONFIGURATION['sip_flags'],
"qt_version": QtCore.QT_VERSION,
"qt_edition": "free",
@ -51,20 +56,23 @@ class Configuration(sipconfig.Configuration):
self.set_build_macros(macros)
## The name of the SIP build file generated by SIP and used by the build system.
# 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,6 +81,9 @@ 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()
@ -86,7 +97,7 @@ content = {
# 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