Cherry-picking upstream release: 0.9.0.

* Moved debian/.gitignore to ./.gitignore
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
* Removed cmake fix, applied upstream
* Added some options to rules
* Added some new symbols
ubuntu/cosmic
Alf Gaida 7 years ago
parent d22da04a0b
commit 61cadf1659

11
.gitignore vendored

@ -0,0 +1,11 @@
debian/*.debhelper
debian/*.log
debian/*.mangled
debian/*.substvars
debian/debhelper-build-stamp
debian/files
debian/libqtermwidget5-0-dev/
debian/libqtermwidget5-0/
debian/qtermwidget5-data/
debian/tmp/

@ -1,7 +1,40 @@
qtermwidget-0.8.0 / 2017-10-21 qtermwidget-0.9.0 / 2018-05-21
============================== ==============================
* Bumped minor version to 9
* Take transient scrollbars into account
* CMake: Prevent in-source builds
* Refactor and fixes Python binding
* kptyprocess: Try to terminate the shell process
* New color scheme: Ubuntu inspired
* Fixed some github pathes in uris
* Add a comment for potential future breakage
* Use wstring in TerminalCharacterDecoder for UCS-4 compatibility
* Support UTF-32 characters correctly
* Fix "bold and intensive" colors
* New color scheme: Tango (#167)
* Finish SGR mouse protocol (1006)
* Fix build of example with latest lxqt-build-tools
* Expose bracket text function
* Drop Qt foreach.
* Revert deletions in .sip file
* fix python bindings
* Expose terminal size hint API
* Remove class name
* Return something
* Expose bidi option
* Add an example for remote terminal
* Makes the use of libutempter optional
* Fix behavior of scroll up (SU)
* Install cmake files in LIBDIR as they are architecture dependend
* Check if utempter.h header exists (mainly for FreeBSD)
* Need lxqt-build-tools 0.4.0
0.8.0 / 2017-10-21
==================
* Release 0.8.0: Update changelog
* FIX: #46 fix vertical font truncation * FIX: #46 fix vertical font truncation
* bump versions * bump versions
* Really fallback to /bin/sh when $SHELL is missing or invalid * Really fallback to /bin/sh when $SHELL is missing or invalid

@ -6,15 +6,19 @@ include(GNUInstallDirs)
include(GenerateExportHeader) include(GenerateExportHeader)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckIncludeFile)
set(REQUIRED_QT_VERSION "5.6") set(REQUIRED_QT_VERSION "5.7.1")
set(LXQTBT_MINIMUM_VERSION "0.4.0") set(LXQTBT_MINIMUM_VERSION "0.5.0")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF) option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
option(BUILD_EXAMPLE "Build example application. Default OFF." OFF) option(BUILD_EXAMPLE "Build example application. Default OFF." OFF)
option(QTERMWIDGET_USE_UTEMPTER "Uses the libutempter library. Mainly for FreeBSD" OFF)
option(QTERMWIDGET_BUILD_PYTHON_BINDING "Build python binding" OFF)
# just change version for releases # just change version for releases
set(QTERMWIDGET_VERSION_MAJOR "0") set(QTERMWIDGET_VERSION_MAJOR "0")
set(QTERMWIDGET_VERSION_MINOR "8") set(QTERMWIDGET_VERSION_MINOR "9")
set(QTERMWIDGET_VERSION_PATCH "0") set(QTERMWIDGET_VERSION_PATCH "0")
set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}") set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}")
@ -31,6 +35,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets "${REQUIRED_QT_VERSION}" REQUIRED) find_package(Qt5Widgets "${REQUIRED_QT_VERSION}" REQUIRED)
find_package(Qt5LinguistTools "${REQUIRED_QT_VERSION}" REQUIRED) find_package(Qt5LinguistTools "${REQUIRED_QT_VERSION}" REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED) find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
include(LXQtPreventInSourceBuilds)
include(LXQtTranslateTs) include(LXQtTranslateTs)
include(LXQtCompilerSettings NO_POLICY_SCOPE) include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtCreatePkgConfigFile) include(LXQtCreatePkgConfigFile)
@ -160,6 +166,16 @@ if(HAVE_UPDWTMPX)
) )
endif() endif()
if (QTERMWIDGET_USE_UTEMPTER)
CHECK_INCLUDE_FILE(utempter.h HAVE_UTEMPTER)
if (HAVE_UTEMPTER)
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME} PRIVATE
"HAVE_UTEMPTER"
)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} ulog)
endif()
endif()
if (UTF8PROC_FOUND) if (UTF8PROC_FOUND)
target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME} target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
PRIVATE PRIVATE
@ -188,6 +204,7 @@ target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
"TRANSLATIONS_DIR=\"${TRANSLATIONS_DIR}\"" "TRANSLATIONS_DIR=\"${TRANSLATIONS_DIR}\""
"HAVE_POSIX_OPENPT" "HAVE_POSIX_OPENPT"
"HAVE_SYS_TIME_H" "HAVE_SYS_TIME_H"
"QT_NO_FOREACH"
) )
@ -213,13 +230,13 @@ write_basic_package_version_file(
install(FILES install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config-version.cmake" "${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel COMPONENT Devel
) )
install(EXPORT install(EXPORT
"${QTERMWIDGET_LIBRARY_NAME}-targets" "${QTERMWIDGET_LIBRARY_NAME}-targets"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel COMPONENT Devel
) )
@ -263,7 +280,7 @@ configure_file(
install(FILES install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake" "${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel COMPONENT Devel
) )
@ -290,6 +307,12 @@ if(BUILD_EXAMPLE)
endif() endif()
# end of example application # end of example application
# python binding
if (QTERMWIDGET_BUILD_PYTHON_BINDING)
add_subdirectory(pyqt)
endif()
# end of python binding
CONFIGURE_FILE( CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"

@ -16,7 +16,7 @@ This project is licensed under the terms of the [GPLv2](https://www.gnu.org/lice
### Compiling sources ### Compiling sources
The only runtime dependency is qtbase ≥ 5.6. 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. In order to build CMake ≥ 3.0.2 and [lxqt-build-tools](https://github.com/lxqt/lxqt-build-tools/) >= 0.4.0 are needed as well as Git to pull translations and optionally latest VCS checkouts.
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. 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.

11
debian/.gitignore vendored

@ -1,11 +0,0 @@
/*.debhelper
/*.log
/*.mangled
/*.substvars
/debhelper-build-stamp
/files
/libqtermwidget5-0-dev/
/libqtermwidget5-0/
/qtermwidget5-data/
/tmp/

11
debian/changelog vendored

@ -1,3 +1,14 @@
qtermwidget (0.9.0-1) unstable; urgency=medium
* Cherry-picking upstream release: 0.9.0.
* Moved debian/.gitignore to ./.gitignore
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
* Removed cmake fix, applied upstream
* Added some options to rules
* Added some new symbols
-- Alf Gaida <agaida@siduction.org> Thu, 24 May 2018 01:11:06 +0200
qtermwidget (0.8.0-6) unstable; urgency=medium qtermwidget (0.8.0-6) unstable; urgency=medium
* Bumped compat to 11 * Bumped compat to 11

2
debian/control vendored

@ -8,7 +8,7 @@ Priority: optional
Build-Depends: debhelper (>= 11~), Build-Depends: debhelper (>= 11~),
cmake, cmake,
libutf8proc-dev, libutf8proc-dev,
lxqt-build-tools (>= 0.4.0), lxqt-build-tools (>= 0.5.0~),
qtbase5-dev qtbase5-dev
Standards-Version: 4.1.4 Standards-Version: 4.1.4
Vcs-Browser: https://salsa.debian.org/lxqt-team/qtermwidget Vcs-Browser: https://salsa.debian.org/lxqt-team/qtermwidget

@ -6,6 +6,7 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"QTermWidget::availableColorSchemes()@Base" 0.6.0 (c++)"QTermWidget::availableColorSchemes()@Base" 0.6.0
(c++)"QTermWidget::availableKeyBindings()@Base" 0.6.0 (c++)"QTermWidget::availableKeyBindings()@Base" 0.6.0
(c++)"QTermWidget::bell(QString const&)@Base" 0.6.0 (c++)"QTermWidget::bell(QString const&)@Base" 0.6.0
(c++)"QTermWidget::bracketText(QString&)@Base" 0.9.0~
(c++)"QTermWidget::changeDir(QString const&)@Base" 0.6.0 (c++)"QTermWidget::changeDir(QString const&)@Base" 0.6.0
(c++)"QTermWidget::clear()@Base" 0.6.0 (c++)"QTermWidget::clear()@Base" 0.6.0
(c++)"QTermWidget::copyAvailable(bool)@Base" 0.6.0 (c++)"QTermWidget::copyAvailable(bool)@Base" 0.6.0
@ -27,6 +28,7 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"QTermWidget::historyLinesCount()@Base" 0.6.0 (c++)"QTermWidget::historyLinesCount()@Base" 0.6.0
(c++)"QTermWidget::icon() const@Base" 0.7.0 (c++)"QTermWidget::icon() const@Base" 0.7.0
(c++)"QTermWidget::init(int)@Base" 0.6.0 (c++)"QTermWidget::init(int)@Base" 0.6.0
(c++)"QTermWidget::isBidiEnabled()@Base" 0.9.0~
(c++)"QTermWidget::isTitleChanged() const@Base" 0.7.0 (c++)"QTermWidget::isTitleChanged() const@Base" 0.7.0
(c++)"QTermWidget::keyBindings()@Base" 0.6.0 (c++)"QTermWidget::keyBindings()@Base" 0.6.0
(c++)"QTermWidget::matchFound(int, int, int, int)@Base" 0.6.0 (c++)"QTermWidget::matchFound(int, int, int, int)@Base" 0.6.0
@ -50,6 +52,7 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"QTermWidget::sessionFinished()@Base" 0.6.0 (c++)"QTermWidget::sessionFinished()@Base" 0.6.0
(c++)"QTermWidget::setArgs(QStringList const&)@Base" 0.6.0 (c++)"QTermWidget::setArgs(QStringList const&)@Base" 0.6.0
(c++)"QTermWidget::setAutoClose(bool)@Base" 0.8.0 (c++)"QTermWidget::setAutoClose(bool)@Base" 0.8.0
(c++)"QTermWidget::setBidiEnabled(bool)@Base" 0.9.0~
(c++)"QTermWidget::setBlinkingCursor(bool)@Base" 0.8.0 (c++)"QTermWidget::setBlinkingCursor(bool)@Base" 0.8.0
(c++)"QTermWidget::setColorScheme(QString const&)@Base" 0.6.0 (c++)"QTermWidget::setColorScheme(QString const&)@Base" 0.6.0
(c++)"QTermWidget::setEnvironment(QStringList const&)@Base" 0.6.0 (c++)"QTermWidget::setEnvironment(QStringList const&)@Base" 0.6.0
@ -70,6 +73,7 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"QTermWidget::setTerminalBackgroundImage(QString)@Base" 0.7.1 (c++)"QTermWidget::setTerminalBackgroundImage(QString)@Base" 0.7.1
(c++)"QTermWidget::setTerminalFont(QFont const&)@Base" 0.6.0 (c++)"QTermWidget::setTerminalFont(QFont const&)@Base" 0.6.0
(c++)"QTermWidget::setTerminalOpacity(double)@Base" 0.6.0 (c++)"QTermWidget::setTerminalOpacity(double)@Base" 0.6.0
(c++)"QTermWidget::setTerminalSizeHint(bool)@Base" 0.9.0~
(c++)"QTermWidget::setTextCodec(QTextCodec*)@Base" 0.6.0 (c++)"QTermWidget::setTextCodec(QTextCodec*)@Base" 0.6.0
(c++)"QTermWidget::setWorkingDirectory(QString const&)@Base" 0.6.0 (c++)"QTermWidget::setWorkingDirectory(QString const&)@Base" 0.6.0
(c++)"QTermWidget::setZoom(int)@Base" 0.6.0 (c++)"QTermWidget::setZoom(int)@Base" 0.6.0
@ -81,6 +85,7 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"QTermWidget::termGetFocus()@Base" 0.6.0 (c++)"QTermWidget::termGetFocus()@Base" 0.6.0
(c++)"QTermWidget::termKeyPressed(QKeyEvent*)@Base" 0.6.0 (c++)"QTermWidget::termKeyPressed(QKeyEvent*)@Base" 0.6.0
(c++)"QTermWidget::termLostFocus()@Base" 0.6.0 (c++)"QTermWidget::termLostFocus()@Base" 0.6.0
(c++)"QTermWidget::terminalSizeHint()@Base" 0.9.0~
(c++)"QTermWidget::title() const@Base" 0.7.0 (c++)"QTermWidget::title() const@Base" 0.7.0
(c++)"QTermWidget::titleChanged()@Base" 0.7.0 (c++)"QTermWidget::titleChanged()@Base" 0.7.0
(c++)"QTermWidget::toggleShowSearchBar()@Base" 0.6.0 (c++)"QTermWidget::toggleShowSearchBar()@Base" 0.6.0
@ -92,4 +97,5 @@ libqtermwidget5.so.0 libqtermwidget5-0 #MINVER#
(c++)"non-virtual thunk to QTermWidget::~QTermWidget()@Base" 0.6.0 (c++)"non-virtual thunk to QTermWidget::~QTermWidget()@Base" 0.6.0
(c++)"typeinfo for QTermWidget@Base" 0.6.0 (c++)"typeinfo for QTermWidget@Base" 0.6.0
(c++)"typeinfo name for QTermWidget@Base" 0.6.0 (c++)"typeinfo name for QTermWidget@Base" 0.6.0
(c++)"void std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_construct<wchar_t const*>(wchar_t const*, wchar_t const*, std::forward_iterator_tag)@Base" 0.9.0~
(c++)"vtable for QTermWidget@Base" 0.6.0 (c++)"vtable for QTermWidget@Base" 0.6.0

@ -1,33 +0,0 @@
Description: Install cmake files arch-dependend
That will prevent file conflicts described at #880389
Author: Alf Gaida <agaida@siduction.org>
Last-Update: 2017-10-31
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -213,13 +213,13 @@
install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config-version.cmake"
- DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
install(EXPORT
"${QTERMWIDGET_LIBRARY_NAME}-targets"
- DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)
@@ -263,7 +263,7 @@
install(FILES
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
- DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
COMPONENT Devel
)

@ -1 +0,0 @@
fix-cmake-installdir.patch

4
debian/rules vendored

@ -14,5 +14,9 @@ override_dh_missing:
override_dh_auto_configure: override_dh_auto_configure:
dh_auto_configure -- \ dh_auto_configure -- \
-DPULL_TRANSLATIONS=OFF \ -DPULL_TRANSLATIONS=OFF \
-DUPDATE_TRANSLATIONS=OFF \
-DBUILD_EXAMPLE=OFF \
-DQTERMWIDGET_USE_UTEMPTER=OFF \
-DQTERMWIDGET_BUILD_PYTHON_BINDING=OFF \
-DUSE_UTF8PROC=ON \ -DUSE_UTF8PROC=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_BUILD_TYPE=RelWithDebInfo

@ -0,0 +1,8 @@
A simple example showing how to use QTermWidget to control and display a remote terminal.
To run this example, you should:
1. Build client-side program. In my PC, I use 'apt-get' to install the QTermWidget library.
2. Start the shell-srv.py with specific paramenters.This will expose a shell via socket.
3. Start the client-side program from commandline with specific paramenters.
Now you will get your own remote terminal work with QTermWidget.

@ -0,0 +1,34 @@
#-------------------------------------------------
#
# Project created by QtCreator 2017-10-31T00:37:59
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = RemoteTerm
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
remoteterm.cpp
HEADERS += \
remoteterm.h
unix:!macx: LIBS += -lqtermwidget5

@ -0,0 +1,19 @@
#include "remoteterm.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(a.arguments().size() != 3){
qDebug() << "Example(client-side) for remote terminal of QTermWidget.";
qDebug() << QString("Usage: %1 ipaddr port").arg(a.arguments()[0]);
return 1;
}
QString ipaddr = a.arguments().at(1);
quint16 port = a.arguments().at(2).toUShort();
RemoteTerm w(ipaddr,port);
w.show();
return a.exec();
}

@ -0,0 +1,32 @@
#include "remoteterm.h"
#include <QTcpSocket>
#include <QDebug>
#include <unistd.h>
RemoteTerm::RemoteTerm(const QString &ipaddr, quint16 port, QWidget *parent)
: QTermWidget(0,parent)
{
socket = new QTcpSocket(this);
// Write what we input to remote terminal via socket
connect(this, &RemoteTerm::sendData,[this](const char *data, int size){
this->socket->write(data, size);
});
// Read anything from remote terminal via socket and show it on widget.
connect(socket,&QTcpSocket::readyRead,[this](){
QByteArray data = socket->readAll();
write(this->getPtySlaveFd(), data.data(), data.size());
});
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(atError()));
// Here we start an empty pty.
this->startTerminalTeletype();
socket->connectToHost(ipaddr, port);
}
void RemoteTerm::atError()
{
qDebug() << socket->errorString();
}

@ -0,0 +1,19 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <qtermwidget5/qtermwidget.h>
class QTcpSocket;
class RemoteTerm : public QTermWidget
{
Q_OBJECT
public:
RemoteTerm(const QString &ipaddr, quint16 port, QWidget *parent = 0);
public slots:
void atError();
private:
QTcpSocket *socket;
};
#endif // WIDGET_H

@ -0,0 +1,37 @@
#!/usr/bin/env python
import sys
import os
import socket
import pty
def usage(program):
print "Example(server-side) for remote terminal of QTermWidget."
print "Usage: %s ipaddr port" %program
def main():
if len(sys.argv) != 3:
usage(sys.argv[0])
sys.exit(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((sys.argv[1], int(sys.argv[2])))
s.listen(0)
print "[+]Start Server."
except Exception as e:
print "[-]Error Happened: %s" %e.message
sys.exit(2)
while True:
c = s.accept()
os.dup2(c[0].fileno(), 0)
os.dup2(c[0].fileno(), 1)
os.dup2(c[0].fileno(), 2)
# It's important to use pty to spawn the shell.
pty.spawn("/bin/sh")
c[0].close()
if __name__ == "__main__":
main()

@ -55,7 +55,8 @@ int main(int argc, char *argv[])
// console->setColorScheme(COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW); // console->setColorScheme(COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW);
console->setScrollBarPosition(QTermWidget::ScrollBarRight); console->setScrollBarPosition(QTermWidget::ScrollBarRight);
foreach (QString arg, QApplication::arguments()) const auto arguments = QApplication::arguments();
for (const QString& arg : arguments)
{ {
if (console->availableColorSchemes().contains(arg)) if (console->availableColorSchemes().contains(arg))
console->setColorScheme(arg); console->setColorScheme(arg);

@ -78,7 +78,7 @@ public:
union union
{ {
/** The unicode character value for this character. */ /** The unicode character value for this character. */
quint16 character; wchar_t character;
/** /**
* Experimental addition which allows a single Character instance to contain more than * Experimental addition which allows a single Character instance to contain more than
* one unicode character. * one unicode character.

@ -205,13 +205,13 @@ public:
} }
/** /**
* Toggles the value of this color between a normal system color and the corresponding intensive * Set the value of this color from a normal system color to the corresponding intensive
* system color. * system color if it's not already an intensive system color.
* *
* This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM
* color spaces. * color spaces.
*/ */
void toggleIntensive(); void setIntensive();
/** /**
* Returns the color within the specified color @p palette * Returns the color within the specified color @p palette
@ -287,11 +287,11 @@ inline QColor CharacterColor::color(const ColorEntry* base) const
return QColor(); return QColor();
} }
inline void CharacterColor::toggleIntensive() inline void CharacterColor::setIntensive()
{ {
if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT)
{ {
_v = !_v; _v = 1;
} }
} }

@ -26,6 +26,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string>
// Qt // Qt
#include <QApplication> #include <QApplication>
@ -132,7 +133,7 @@ void Emulation::setScreen(int n)
if (_currentScreen != old) if (_currentScreen != old)
{ {
// tell all windows onto this emulation to switch to the newly active screen // tell all windows onto this emulation to switch to the newly active screen
foreach(ScreenWindow* window,_windows) for(ScreenWindow* window : const_cast<const QList<ScreenWindow*>&>(_windows))
window->setScreen(_currentScreen); window->setScreen(_currentScreen);
} }
} }
@ -188,7 +189,7 @@ QString Emulation::keyBindings() const
return _keyTranslator->name(); return _keyTranslator->name();
} }
void Emulation::receiveChar(int c) void Emulation::receiveChar(wchar_t c)
// process application unicode input to terminal // process application unicode input to terminal
// this is a trivial scanner // this is a trivial scanner
{ {
@ -238,11 +239,17 @@ void Emulation::receiveData(const char* text, int length)
bufferedUpdate(); bufferedUpdate();
QString unicodeText = _decoder->toUnicode(text,length); /* XXX: the following code involves encoding & decoding of "UTF-16
* surrogate pairs", which does not work with characters higher than
* U+10FFFF
* https://unicodebook.readthedocs.io/unicode_encodings.html#surrogates
*/
QString utf16Text = _decoder->toUnicode(text,length);
std::wstring unicodeText = utf16Text.toStdWString();
//send characters to terminal emulator //send characters to terminal emulator
for (int i=0;i<unicodeText.length();i++) for (size_t i=0;i<unicodeText.length();i++)
receiveChar(unicodeText[i].unicode()); receiveChar(unicodeText[i]);
//look for z-modem indicator //look for z-modem indicator
//-- someone who understands more about z-modems that I do may be able to move //-- someone who understands more about z-modems that I do may be able to move

@ -452,7 +452,7 @@ protected:
* Processes an incoming character. See receiveData() * Processes an incoming character. See receiveData()
* @p ch A unicode character code. * @p ch A unicode character code.
*/ */
virtual void receiveChar(int ch); virtual void receiveChar(wchar_t ch);
/** /**
* Sets the active screen. The terminal has two screens, primary and alternate. * Sets the active screen. The terminal has two screens, primary and alternate.

@ -224,7 +224,7 @@ void Filter::getLineColumn(int position , int& startLine , int& startColumn)
if ( _linePositions->value(i) <= position && position < nextLine ) if ( _linePositions->value(i) <= position && position < nextLine )
{ {
startLine = i; startLine = i;
startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i))); startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i)).toStdWString());
return; return;
} }
} }

@ -419,7 +419,7 @@ void Screen::updateEffectiveRendition()
} }
if (currentRendition & RE_BOLD) if (currentRendition & RE_BOLD)
effectiveForeground.toggleIntensive(); effectiveForeground.setIntensive();
} }
void Screen::copyFromHistory(Character* dest, int startLine, int count) const void Screen::copyFromHistory(Character* dest, int startLine, int count) const
@ -644,7 +644,7 @@ void Screen::checkSelection(int from, int to)
clearSelection(); clearSelection();
} }
void Screen::displayCharacter(unsigned short c) void Screen::displayCharacter(wchar_t c)
{ {
// Note that VT100 does wrapping BEFORE putting the character. // Note that VT100 does wrapping BEFORE putting the character.
// This has impact on the assumption of valid cursor positions. // This has impact on the assumption of valid cursor positions.
@ -751,13 +751,18 @@ QRect Screen::lastScrolledRegion() const
void Screen::scrollUp(int from, int n) void Screen::scrollUp(int from, int n)
{ {
if (n <= 0 || from + n > _bottomMargin) return; if (n <= 0)
return;
if (from > _bottomMargin)
return;
if (from + n > _bottomMargin)
n = _bottomMargin + 1 - from;
_scrolledLines -= n; _scrolledLines -= n;
_lastScrolledRegion = QRect(0,_topMargin,columns-1,(_bottomMargin-_topMargin)); _lastScrolledRegion = QRect(0,_topMargin,columns-1,(_bottomMargin-_topMargin));
//FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds. //FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds.
moveImage(loc(0,from),loc(0,from+n),loc(columns-1,_bottomMargin)); moveImage(loc(0,from),loc(0,from+n),loc(columns,_bottomMargin));
clearImage(loc(0,_bottomMargin-n+1),loc(columns-1,_bottomMargin),' '); clearImage(loc(0,_bottomMargin-n+1),loc(columns-1,_bottomMargin),' ');
} }

@ -346,7 +346,7 @@ public:
* is inserted at the current cursor position, otherwise it will replace the * is inserted at the current cursor position, otherwise it will replace the
* character already at the current cursor position. * character already at the current cursor position.
*/ */
void displayCharacter(unsigned short c); void displayCharacter(wchar_t c);
// Do composition with last shown character FIXME: Not implemented yet for KDE 4 // Do composition with last shown character FIXME: Not implemented yet for KDE 4
void compose(const QString& compose); void compose(const QString& compose);

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

@ -82,7 +82,7 @@ void PlainTextDecoder::decodeLine(const Character* const characters, int count,
//note: we build up a QString and send it to the text stream rather writing into the text //note: we build up a QString and send it to the text stream rather writing into the text
//stream a character at a time because it is more efficient. //stream a character at a time because it is more efficient.
//(since QTextStream always deals with QStrings internally anyway) //(since QTextStream always deals with QStrings internally anyway)
QString plainText; std::wstring plainText;
plainText.reserve(count); plainText.reserve(count);
int outputCount = count; int outputCount = count;
@ -93,7 +93,7 @@ void PlainTextDecoder::decodeLine(const Character* const characters, int count,
{ {
for (int i = count-1 ; i >= 0 ; i--) for (int i = count-1 ; i >= 0 ; i--)
{ {
if ( characters[i].character != ' ' ) if ( characters[i].character != L' ' )
break; break;
else else
outputCount--; outputCount--;
@ -102,10 +102,10 @@ void PlainTextDecoder::decodeLine(const Character* const characters, int count,
for (int i=0;i<outputCount;) for (int i=0;i<outputCount;)
{ {
plainText.append( QChar(characters[i].character) ); plainText.push_back( characters[i].character );
i += qMax(1,konsole_wcwidth(characters[i].character)); i += qMax(1,konsole_wcwidth(characters[i].character));
} }
*_output << plainText; *_output << QString::fromStdWString(plainText);
} }
HTMLDecoder::HTMLDecoder() : HTMLDecoder::HTMLDecoder() :
@ -121,23 +121,23 @@ void HTMLDecoder::begin(QTextStream* output)
{ {
_output = output; _output = output;
QString text; std::wstring text;
//open monospace span //open monospace span
openSpan(text,"font-family:monospace"); openSpan(text,"font-family:monospace");
*output << text; *output << QString::fromStdWString(text);
} }
void HTMLDecoder::end() void HTMLDecoder::end()
{ {
Q_ASSERT( _output ); Q_ASSERT( _output );
QString text; std::wstring text;
closeSpan(text); closeSpan(text);
*_output << text; *_output << QString::fromStdWString(text);
_output = 0; _output = 0;
@ -149,13 +149,13 @@ void HTMLDecoder::decodeLine(const Character* const characters, int count, LineP
{ {
Q_ASSERT( _output ); Q_ASSERT( _output );
QString text; std::wstring text;
int spaceCount = 0; int spaceCount = 0;
for (int i=0;i<count;i++) for (int i=0;i<count;i++)
{ {
QChar ch(characters[i].character); wchar_t ch(characters[i].character);
//check if appearance of character is different from previous char //check if appearance of character is different from previous char
if ( characters[i].rendition != _lastRendition || if ( characters[i].rendition != _lastRendition ||
@ -202,7 +202,7 @@ void HTMLDecoder::decodeLine(const Character* const characters, int count, LineP
} }
//handle whitespace //handle whitespace
if (ch.isSpace()) if (std::iswspace(ch))
spaceCount++; spaceCount++;
else else
spaceCount = 0; spaceCount = 0;
@ -213,15 +213,15 @@ void HTMLDecoder::decodeLine(const Character* const characters, int count, LineP
{ {
//escape HTML tag characters and just display others as they are //escape HTML tag characters and just display others as they are
if ( ch == '<' ) if ( ch == '<' )
text.append("&lt;"); text.append(L"&lt;");
else if (ch == '>') else if (ch == '>')
text.append("&gt;"); text.append(L"&gt;");
else else
text.append(ch); text.push_back(ch);
} }
else else
{ {
text.append("&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead text.append(L"&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
} }
} }
@ -231,18 +231,18 @@ void HTMLDecoder::decodeLine(const Character* const characters, int count, LineP
closeSpan(text); closeSpan(text);
//start new line //start new line
text.append("<br>"); text.append(L"<br>");
*_output << text; *_output << QString::fromStdWString(text);
} }
void HTMLDecoder::openSpan(QString& text , const QString& style) void HTMLDecoder::openSpan(std::wstring& text , const QString& style)
{ {
text.append( QString("<span style=\"%1\">").arg(style) ); text.append( QString("<span style=\"%1\">").arg(style).toStdWString() );
} }
void HTMLDecoder::closeSpan(QString& text) void HTMLDecoder::closeSpan(std::wstring& text)
{ {
text.append("</span>"); text.append(L"</span>");
} }
void HTMLDecoder::setColorTable(const ColorEntry* table) void HTMLDecoder::setColorTable(const ColorEntry* table)

@ -133,8 +133,8 @@ public:
virtual void end(); virtual void end();
private: private:
void openSpan(QString& text , const QString& style); void openSpan(std::wstring& text , const QString& style);
void closeSpan(QString& text); void closeSpan(std::wstring& text);
QTextStream* _output; QTextStream* _output;
const ColorEntry* _colorTable; const ColorEntry* _colorTable;

@ -194,10 +194,10 @@ void TerminalDisplay::setColorTable(const ColorEntry table[])
QCodec. QCodec.
*/ */
static inline bool isLineChar(quint16 c) { return ((c & 0xFF80) == 0x2500);} static inline bool isLineChar(wchar_t c) { return ((c & 0xFF80) == 0x2500);}
static inline bool isLineCharString(const QString& string) static inline bool isLineCharString(const std::wstring& string)
{ {
return (string.length() > 0) && (isLineChar(string.at(0).unicode())); return (string.length() > 0) && (isLineChar(string[0]));
} }
@ -377,6 +377,10 @@ TerminalDisplay::TerminalDisplay(QWidget *parent)
// create scroll bar for scrolling output up and down // create scroll bar for scrolling output up and down
// set the scroll bar's slider to occupy the whole area of the scroll bar initially // set the scroll bar's slider to occupy the whole area of the scroll bar initially
_scrollBar = new QScrollBar(this); _scrollBar = new QScrollBar(this);
// since the contrast with the terminal background may not be enough,
// the scrollbar should be auto-filled if not transient
if (!_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar))
_scrollBar->setAutoFillBackground(true);
setScroll(0,0); setScroll(0,0);
_scrollBar->setCursor( Qt::ArrowCursor ); _scrollBar->setCursor( Qt::ArrowCursor );
connect(_scrollBar, SIGNAL(valueChanged(int)), this, connect(_scrollBar, SIGNAL(valueChanged(int)), this,
@ -488,7 +492,7 @@ enum LineEncode
#include "LineFont.h" #include "LineFont.h"
static void drawLineChar(QPainter& paint, int x, int y, int w, int h, uchar code) static void drawLineChar(QPainter& paint, int x, int y, int w, int h, uint8_t code)
{ {
//Calculate cell midpoints, end points. //Calculate cell midpoints, end points.
int cx = x + w/2; int cx = x + w/2;
@ -635,7 +639,7 @@ static void drawOtherChar(QPainter& paint, int x, int y, int w, int h, uchar cod
} }
} }
void TerminalDisplay::drawLineCharString( QPainter& painter, int x, int y, const QString& str, void TerminalDisplay::drawLineCharString( QPainter& painter, int x, int y, const std::wstring& str,
const Character* attributes) const Character* attributes)
{ {
const QPen& currentPen = painter.pen(); const QPen& currentPen = painter.pen();
@ -647,9 +651,9 @@ void TerminalDisplay::drawLineCharString( QPainter& painter, int x, int y, co
painter.setPen( boldPen ); painter.setPen( boldPen );
} }
for (int i=0 ; i < str.length(); i++) for (size_t i=0 ; i < str.length(); i++)
{ {
uchar code = str[i].cell(); uint8_t code = static_cast<uint8_t>(str[i] & 0xffU);
if (LineChars[code]) if (LineChars[code])
drawLineChar(painter, x + (_fontWidth*i), y, _fontWidth, _fontHeight, code); drawLineChar(painter, x + (_fontWidth*i), y, _fontWidth, _fontHeight, code);
else else
@ -718,20 +722,9 @@ void TerminalDisplay::setBackgroundImage(QString backgroundImage)
void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const QColor& backgroundColor, bool useOpacitySetting ) void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const QColor& backgroundColor, bool useOpacitySetting )
{ {
// the area of the widget showing the contents of the terminal display is drawn // The whole widget rectangle is filled by the background color from
// using the background color from the color scheme set with setColorTable() // the color scheme set in setColorTable(), while the scrollbar is
// // left to the widget style for a consistent look.
// the area of the widget behind the scroll-bar is drawn using the background
// brush from the scroll-bar's palette, to give the effect of the scroll-bar
// being outside of the terminal display and visual consistency with other KDE
// applications.
//
QRect scrollBarArea = _scrollBar->isVisible() ?
rect.intersected(_scrollBar->geometry()) :
QRect();
QRegion contentsRegion = QRegion(rect).subtracted(scrollBarArea);
QRect contentsRect = contentsRegion.boundingRect();
if ( HAVE_TRANSPARENCY && qAlpha(_blendColor) < 0xff && useOpacitySetting ) if ( HAVE_TRANSPARENCY && qAlpha(_blendColor) < 0xff && useOpacitySetting )
{ {
if (_backgroundImage.isNull()) { if (_backgroundImage.isNull()) {
@ -740,14 +733,12 @@ void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const
painter.save(); painter.save();
painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(contentsRect, color); painter.fillRect(rect, color);
painter.restore(); painter.restore();
} }
} }
else else
painter.fillRect(contentsRect, backgroundColor); painter.fillRect(rect, backgroundColor);
painter.fillRect(scrollBarArea,_scrollBar->palette().background());
} }
void TerminalDisplay::drawCursor(QPainter& painter, void TerminalDisplay::drawCursor(QPainter& painter,
@ -804,7 +795,7 @@ void TerminalDisplay::drawCursor(QPainter& painter,
void TerminalDisplay::drawCharacters(QPainter& painter, void TerminalDisplay::drawCharacters(QPainter& painter,
const QRect& rect, const QRect& rect,
const QString& text, const std::wstring& text,
const Character* style, const Character* style,
bool invertCharacterColor) bool invertCharacterColor)
{ {
@ -859,12 +850,12 @@ void TerminalDisplay::drawCharacters(QPainter& painter,
painter.setLayoutDirection(Qt::LeftToRight); painter.setLayoutDirection(Qt::LeftToRight);
if (_bidiEnabled) { if (_bidiEnabled) {
painter.drawText(rect.x(), rect.y() + _fontAscent + _lineSpacing, text); painter.drawText(rect.x(), rect.y() + _fontAscent + _lineSpacing, QString::fromStdWString(text));
} else { } else {
{ {
QRect drawRect(rect.topLeft(), rect.size()); QRect drawRect(rect.topLeft(), rect.size());
drawRect.setHeight(rect.height() + _drawTextAdditionHeight); drawRect.setHeight(rect.height() + _drawTextAdditionHeight);
painter.drawText(drawRect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + text); painter.drawText(drawRect, Qt::AlignBottom, LTR_OVERRIDE_CHAR + QString::fromStdWString(text));
} }
} }
} }
@ -872,7 +863,7 @@ void TerminalDisplay::drawCharacters(QPainter& painter,
void TerminalDisplay::drawTextFragment(QPainter& painter , void TerminalDisplay::drawTextFragment(QPainter& painter ,
const QRect& rect, const QRect& rect,
const QString& text, const std::wstring& text,
const Character* style) const Character* style)
{ {
painter.save(); painter.save();
@ -1028,7 +1019,8 @@ void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion)
QRegion TerminalDisplay::hotSpotRegion() const QRegion TerminalDisplay::hotSpotRegion() const
{ {
QRegion region; QRegion region;
foreach( Filter::HotSpot* hotSpot , _filterChain->hotSpots() ) const auto hotSpots = _filterChain->hotSpots();
for( Filter::HotSpot* const hotSpot : hotSpots )
{ {
QRect r; QRect r;
if (hotSpot->startLine()==hotSpot->endLine()) { if (hotSpot->startLine()==hotSpot->endLine()) {
@ -1124,7 +1116,7 @@ void TerminalDisplay::updateImage()
const int linesToUpdate = qMin(this->_lines, qMax(0,lines )); const int linesToUpdate = qMin(this->_lines, qMax(0,lines ));
const int columnsToUpdate = qMin(this->_columns,qMax(0,columns)); const int columnsToUpdate = qMin(this->_columns,qMax(0,columns));
QChar *disstrU = new QChar[columnsToUpdate]; wchar_t *disstrU = new wchar_t[columnsToUpdate];
char *dirtyMask = new char[columnsToUpdate+2]; char *dirtyMask = new char[columnsToUpdate+2];
QRegion dirtyRegion; QRegion dirtyRegion;
@ -1163,7 +1155,7 @@ void TerminalDisplay::updateImage()
// where characters exceed their cell width. // where characters exceed their cell width.
if (dirtyMask[x]) if (dirtyMask[x])
{ {
quint16 c = newLine[x+0].character; wchar_t c = newLine[x+0].character;
if ( !c ) if ( !c )
continue; continue;
int p = 0; int p = 0;
@ -1194,7 +1186,7 @@ void TerminalDisplay::updateImage()
disstrU[p++] = c; //fontMap(c); disstrU[p++] = c; //fontMap(c);
} }
QString unistr(disstrU, p); std::wstring unistr(disstrU, p);
bool saveFixedFont = _fixedFont; bool saveFixedFont = _fixedFont;
if (lineDraw) if (lineDraw)
@ -1377,7 +1369,8 @@ void TerminalDisplay::paintEvent( QPaintEvent* pe )
} }
else else
{ {
foreach (const QRect &rect, (pe->region() & contentsRect()).rects()) const auto rects = (pe->region() & contentsRect()).rects();
for (const QRect &rect : rects)
{ {
drawBackground(paint,rect,palette().background().color(), drawBackground(paint,rect,palette().background().color(),
true /* use opacity setting */); true /* use opacity setting */);
@ -1411,7 +1404,7 @@ QRect TerminalDisplay::preeditRect() const
void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRect& rect) void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRect& rect)
{ {
if ( _inputMethodData.preeditString.isEmpty() ) if ( _inputMethodData.preeditString.empty() )
return; return;
const QPoint cursorPos = cursorPosition(); const QPoint cursorPos = cursorPosition();
@ -1440,7 +1433,9 @@ void TerminalDisplay::paintFilters(QPainter& painter)
QPoint cursorPos = mapFromGlobal(QCursor::pos()); QPoint cursorPos = mapFromGlobal(QCursor::pos());
int cursorLine; int cursorLine;
int cursorColumn; int cursorColumn;
int scrollBarWidth = (_scrollbarLocation == QTermWidget::ScrollBarLeft) ? _scrollBar->width() : 0; int scrollBarWidth = (_scrollbarLocation == QTermWidget::ScrollBarLeft
&& !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar))
? _scrollBar->width() : 0;
getCharacterPosition( cursorPos , cursorLine , cursorColumn ); getCharacterPosition( cursorPos , cursorLine , cursorColumn );
Character cursorCharacter = _image[loc(cursorColumn,cursorLine)]; Character cursorCharacter = _image[loc(cursorColumn,cursorLine)];
@ -1578,11 +1573,11 @@ void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
int rly = qMin(_usedLines-1, qMax(0,(rect.bottom() - tLy - _topMargin ) / _fontHeight)); int rly = qMin(_usedLines-1, qMax(0,(rect.bottom() - tLy - _topMargin ) / _fontHeight));
const int bufferSize = _usedColumns; const int bufferSize = _usedColumns;
QString unistr; std::wstring unistr;
unistr.reserve(bufferSize); unistr.reserve(bufferSize);
for (int y = luy; y <= rly; y++) for (int y = luy; y <= rly; y++)
{ {
quint16 c = _image[loc(lux,y)].character; quint32 c = _image[loc(lux,y)].character;
int x = lux; int x = lux;
if(!c && x) if(!c && x)
x--; // Search for start of multi-column character x--; // Search for start of multi-column character
@ -1593,7 +1588,6 @@ void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
// reset our buffer to the maximal size // reset our buffer to the maximal size
unistr.resize(bufferSize); unistr.resize(bufferSize);
QChar *disstrU = unistr.data();
// is this a single character or a sequence of characters ? // is this a single character or a sequence of characters ?
if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR ) if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR )
@ -1605,7 +1599,7 @@ void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
for ( int index = 0 ; index < extendedCharLength ; index++ ) for ( int index = 0 ; index < extendedCharLength ; index++ )
{ {
Q_ASSERT( p < bufferSize ); Q_ASSERT( p < bufferSize );
disstrU[p++] = chars[index]; unistr[p++] = chars[index];
} }
} }
else else
@ -1615,7 +1609,7 @@ void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
if (c) if (c)
{ {
Q_ASSERT( p < bufferSize ); Q_ASSERT( p < bufferSize );
disstrU[p++] = c; //fontMap(c); unistr[p++] = c; //fontMap(c);
} }
} }
@ -1633,7 +1627,7 @@ void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
isLineChar( c = _image[loc(x+len,y)].character) == lineDraw) // Assignment! isLineChar( c = _image[loc(x+len,y)].character) == lineDraw) // Assignment!
{ {
if (c) if (c)
disstrU[p++] = c; //fontMap(c); unistr[p++] = c; //fontMap(c);
if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if condition if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if condition
len++; // Skip trailing part of multi-column character len++; // Skip trailing part of multi-column character
len++; len++;
@ -1977,7 +1971,9 @@ void TerminalDisplay::mouseMoveEvent(QMouseEvent* ev)
{ {
int charLine = 0; int charLine = 0;
int charColumn = 0; int charColumn = 0;
int scrollBarWidth = (_scrollbarLocation == QTermWidget::ScrollBarLeft) ? _scrollBar->width() : 0; int scrollBarWidth = (_scrollbarLocation == QTermWidget::ScrollBarLeft
&& !_scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar))
? _scrollBar->width() : 0;
getCharacterPosition(ev->pos(),charLine,charColumn); getCharacterPosition(ev->pos(),charLine,charColumn);
@ -2322,9 +2318,9 @@ void TerminalDisplay::mouseReleaseEvent(QMouseEvent* ev)
// applies here, too. // applies here, too.
if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
emit mouseSignal( 3, // release emit mouseSignal( 0,
charColumn + 1, charColumn + 1,
charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0); charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 2);
} }
dragInfo.state = diNone; dragInfo.state = diNone;
} }
@ -2334,10 +2330,10 @@ void TerminalDisplay::mouseReleaseEvent(QMouseEvent* ev)
((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier)) ((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier))
|| ev->button() == Qt::MidButton) ) || ev->button() == Qt::MidButton) )
{ {
emit mouseSignal( 3, emit mouseSignal( ev->button() == Qt::MidButton ? 1 : 2,
charColumn + 1, charColumn + 1,
charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , charLine + 1 +_scrollBar->value() -_scrollBar->maximum() ,
0); 2);
} }
} }
@ -2660,11 +2656,7 @@ void TerminalDisplay::emitSelection(bool useXselection,bool appendReturn)
if ( ! text.isEmpty() ) if ( ! text.isEmpty() )
{ {
text.replace('\n', '\r'); text.replace('\n', '\r');
if ( bracketedPasteMode() ) bracketText(text);
{
text.prepend("\e[200~");
text.append("\e[201~");
}
QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text); QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
emit keyPressedSignal(&e); // expose as a big fat keypress event emit keyPressedSignal(&e); // expose as a big fat keypress event
@ -2672,6 +2664,15 @@ void TerminalDisplay::emitSelection(bool useXselection,bool appendReturn)
} }
} }
void TerminalDisplay::bracketText(QString& text)
{
if (bracketedPasteMode())
{
text.prepend("\033[200~");
text.append("\033[201~");
}
}
void TerminalDisplay::setSelection(const QString& t) void TerminalDisplay::setSelection(const QString& t)
{ {
QApplication::clipboard()->setText(t, QClipboard::Selection); QApplication::clipboard()->setText(t, QClipboard::Selection);
@ -2817,7 +2818,7 @@ void TerminalDisplay::inputMethodEvent( QInputMethodEvent* event )
QKeyEvent keyEvent(QEvent::KeyPress,0,Qt::NoModifier,event->commitString()); QKeyEvent keyEvent(QEvent::KeyPress,0,Qt::NoModifier,event->commitString());
emit keyPressedSignal(&keyEvent); emit keyPressedSignal(&keyEvent);
_inputMethodData.preeditString = event->preeditString(); _inputMethodData.preeditString = event->preeditString().toStdWString();
update(preeditRect() | _inputMethodData.previousPreeditRect); update(preeditRect() | _inputMethodData.previousPreeditRect);
event->accept(); event->accept();
@ -2996,6 +2997,8 @@ void TerminalDisplay::clearImage()
void TerminalDisplay::calcGeometry() void TerminalDisplay::calcGeometry()
{ {
_scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height()); _scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height());
int scrollBarWidth = _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar)
? 0 : _scrollBar->width();
switch(_scrollbarLocation) switch(_scrollbarLocation)
{ {
case QTermWidget::NoScrollBar : case QTermWidget::NoScrollBar :
@ -3003,13 +3006,13 @@ void TerminalDisplay::calcGeometry()
_contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN; _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN;
break; break;
case QTermWidget::ScrollBarLeft : case QTermWidget::ScrollBarLeft :
_leftMargin = DEFAULT_LEFT_MARGIN + _scrollBar->width(); _leftMargin = DEFAULT_LEFT_MARGIN + scrollBarWidth;
_contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width(); _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - scrollBarWidth;
_scrollBar->move(contentsRect().topLeft()); _scrollBar->move(contentsRect().topLeft());
break; break;
case QTermWidget::ScrollBarRight: case QTermWidget::ScrollBarRight:
_leftMargin = DEFAULT_LEFT_MARGIN; _leftMargin = DEFAULT_LEFT_MARGIN;
_contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width(); _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - scrollBarWidth;
_scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width()-1, 0)); _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width()-1, 0));
break; break;
} }
@ -3050,7 +3053,9 @@ void TerminalDisplay::makeImage()
// calculate the needed size, this must be synced with calcGeometry() // calculate the needed size, this must be synced with calcGeometry()
void TerminalDisplay::setSize(int columns, int lines) void TerminalDisplay::setSize(int columns, int lines)
{ {
int scrollBarWidth = _scrollBar->isHidden() ? 0 : _scrollBar->sizeHint().width(); int scrollBarWidth = (_scrollBar->isHidden()
|| _scrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, _scrollBar))
? 0 : _scrollBar->sizeHint().width();
int horizontalMargin = 2 * DEFAULT_LEFT_MARGIN; int horizontalMargin = 2 * DEFAULT_LEFT_MARGIN;
int verticalMargin = 2 * DEFAULT_TOP_MARGIN; int verticalMargin = 2 * DEFAULT_TOP_MARGIN;

@ -192,6 +192,9 @@ public:
void emitSelection(bool useXselection,bool appendReturn); void emitSelection(bool useXselection,bool appendReturn);
/** change and wrap text corresponding to paste mode **/
void bracketText(QString& text);
/** /**
* Sets the shape of the keyboard cursor. This is the cursor drawn * Sets the shape of the keyboard cursor. This is the cursor drawn
* at the position in the terminal where keyboard input will appear. * at the position in the terminal where keyboard input will appear.
@ -630,7 +633,7 @@ private:
// draws a section of text, all the text in this section // draws a section of text, all the text in this section
// has a common color and style // has a common color and style
void drawTextFragment(QPainter& painter, const QRect& rect, void drawTextFragment(QPainter& painter, const QRect& rect,
const QString& text, const Character* style); const std::wstring& text, const Character* style);
// draws the background for a text fragment // draws the background for a text fragment
// if useOpacitySetting is true then the color's alpha value will be set to // if useOpacitySetting is true then the color's alpha value will be set to
// the display's transparency (set with setOpacity()), otherwise the background // the display's transparency (set with setOpacity()), otherwise the background
@ -641,11 +644,11 @@ private:
void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor, void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor,
const QColor& backgroundColor , bool& invertColors); const QColor& backgroundColor , bool& invertColors);
// draws the characters or line graphics in a text fragment // draws the characters or line graphics in a text fragment
void drawCharacters(QPainter& painter, const QRect& rect, const QString& text, void drawCharacters(QPainter& painter, const QRect& rect, const std::wstring& text,
const Character* style, bool invertCharacterColor); const Character* style, bool invertCharacterColor);
// draws a string of line graphics // draws a string of line graphics
void drawLineCharString(QPainter& painter, int x, int y, void drawLineCharString(QPainter& painter, int x, int y,
const QString& str, const Character* attributes); const std::wstring& str, const Character* attributes);
// draws the preedit string for input methods // draws the preedit string for input methods
void drawInputMethodPreeditString(QPainter& painter , const QRect& rect); void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
@ -808,7 +811,7 @@ private:
struct InputMethodData struct InputMethodData
{ {
QString preeditString; std::wstring preeditString;
QRect previousPreeditRect; QRect previousPreeditRect;
}; };
InputMethodData _inputMethodData; InputMethodData _inputMethodData;

@ -198,7 +198,7 @@ void Vt102Emulation::addArgument()
argv[argc] = 0; argv[argc] = 0;
} }
void Vt102Emulation::addToCurrentToken(int cc) void Vt102Emulation::addToCurrentToken(wchar_t cc)
{ {
tokenBuffer[tokenBufferPos] = cc; tokenBuffer[tokenBufferPos] = cc;
tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1); tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1);
@ -277,7 +277,7 @@ void Vt102Emulation::initTokenizer()
#define DEL 127 #define DEL 127
// process an incoming unicode character // process an incoming unicode character
void Vt102Emulation::receiveChar(int cc) void Vt102Emulation::receiveChar(wchar_t cc)
{ {
if (cc == DEL) if (cc == DEL)
return; //VT100: ignore. return; //VT100: ignore.
@ -299,7 +299,7 @@ void Vt102Emulation::receiveChar(int cc)
// advance the state // advance the state
addToCurrentToken(cc); addToCurrentToken(cc);
int* s = tokenBuffer; wchar_t* s = tokenBuffer;
int p = tokenBufferPos; int p = tokenBufferPos;
if (getMode(MODE_Ansi)) if (getMode(MODE_Ansi))
@ -441,7 +441,7 @@ void Vt102Emulation::updateTitle()
about this mapping. about this mapping.
*/ */
void Vt102Emulation::processToken(int token, int p, int q) void Vt102Emulation::processToken(int token, wchar_t p, int q)
{ {
switch (token) switch (token)
{ {
@ -925,6 +925,11 @@ void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
if (cx < 1 || cy < 1) if (cx < 1 || cy < 1)
return; return;
// With the exception of the 1006 mode, button release is encoded in cb.
// Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only that.
if (eventType == 2 && !getMode(MODE_Mouse1006))
cb = 3;
// normal buttons are passed as 0x20 + button, // normal buttons are passed as 0x20 + button,
// mouse wheel (buttons 4,5) as 0x5c + button // mouse wheel (buttons 4,5) as 0x5c + button
if (cb >= 4) if (cb >= 4)
@ -1125,7 +1130,7 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
// Apply current character map. // Apply current character map.
unsigned short Vt102Emulation::applyCharset(unsigned short c) wchar_t Vt102Emulation::applyCharset(wchar_t c)
{ {
if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f]; if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
@ -1336,7 +1341,7 @@ char Vt102Emulation::eraseChar() const
} }
// print contents of the scan buffer // print contents of the scan buffer
static void hexdump(int* s, int len) static void hexdump(wchar_t* s, int len)
{ int i; { int i;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {

@ -102,7 +102,7 @@ protected:
// reimplemented from Emulation // reimplemented from Emulation
virtual void setMode(int mode); virtual void setMode(int mode);
virtual void resetMode(int mode); virtual void resetMode(int mode);
virtual void receiveChar(int cc); virtual void receiveChar(wchar_t cc);
private slots: private slots:
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
@ -110,7 +110,7 @@ private slots:
void updateTitle(); void updateTitle();
private: private:
unsigned short applyCharset(unsigned short c); wchar_t applyCharset(wchar_t c);
void setCharset(int n, int cs); void setCharset(int n, int cs);
void useCharset(int n); void useCharset(int n);
void setAndUseCharset(int n, int cs); void setAndUseCharset(int n, int cs);
@ -134,8 +134,8 @@ private:
void resetTokenizer(); void resetTokenizer();
#define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title) #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
void addToCurrentToken(int cc); void addToCurrentToken(wchar_t cc);
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? wchar_t tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
int tokenBufferPos; int tokenBufferPos;
#define MAXARGS 15 #define MAXARGS 15
void addDigit(int dig); void addDigit(int dig);
@ -151,7 +151,7 @@ private:
void reportDecodingError(); void reportDecodingError();
void processToken(int code, int p, int q); void processToken(int code, wchar_t p, int q);
void processWindowAttributeChange(); void processWindowAttributeChange();
void requestWindowAttribute(int); void requestWindowAttribute(int);

@ -0,0 +1,71 @@
[General]
Description=Tango
[Background]
Color=0,0,0
[BackgroundIntense]
Color=104,104,104
[Foreground]
;Color=211,215,207
Color=255,255,255
[ForegroundIntense]
Color=255,255,255
; black
[Color0]
Color=0,0,0
[Color0Intense]
Color=85,87,83
; red
[Color1]
Color=204,0,0
[Color1Intense]
Color=239,41,41
; green
[Color2]
Color=78,154,6
[Color2Intense]
Color=138,226,52
; yellow
[Color3]
Color=196,160,0
[Color3Intense]
Color=252,233,79
; blue
[Color4]
Color=52,101,164
[Color4Intense]
Color=114,159,207
; magenta
[Color5]
Color=117,80,123
[Color5Intense]
Color=173,127,168
; aqua
[Color6]
Color=6,152,154
[Color6Intense]
Color=52,226,226
; grey
[Color7]
Color=211,215,207
[Color7Intense]
Color=238,238,236

@ -0,0 +1,67 @@
[General]
Description=Ubuntu
Opacity=1
Wallpaper=
[Background]
Color=48,10,36
MaxRandomHue=0
MaxRandomSaturation=0
MaxRandomValue=0
[BackgroundIntense]
Color=48,10,36
[Color0]
Color=46,52,54
[Color0Intense]
Color=85,87,83
[Color1]
Color=204,0,0
[Color1Intense]
Color=239,41,41
[Color2]
Color=78,154,6
[Color2Intense]
Color=138,226,52
[Color3]
Color=196,160,0
[Color3Intense]
Color=252,233,79
[Color4]
Color=52,101,164
[Color4Intense]
Color=114,159,207
[Color5]
Color=117,80,123
[Color5Intense]
Color=173,127,168
[Color6]
Color=6,152,154
[Color6Intense]
Color=52,226,226
[Color7]
Color=211,215,207
[Color7Intense]
Color=238,238,236
[Foreground]
Color=238,238,236
[ForegroundIntense]
Color=238,238,236

@ -33,10 +33,9 @@ int konsole_wcwidth(wchar_t ucs)
} }
// single byte char: +1, multi byte char: +2 // single byte char: +1, multi byte char: +2
int string_width( const QString & txt ) int string_width( const std::wstring & wstr )
{ {
int w = 0; int w = 0;
std::wstring wstr = txt.toStdWString();
for ( size_t i = 0; i < wstr.length(); ++i ) { for ( size_t i = 0; i < wstr.length(); ++i ) {
w += konsole_wcwidth( wstr[ i ] ); w += konsole_wcwidth( wstr[ i ] );
} }

@ -10,11 +10,11 @@
#ifndef _KONSOLE_WCWIDTH_H_ #ifndef _KONSOLE_WCWIDTH_H_
#define _KONSOLE_WCWIDTH_H_ #define _KONSOLE_WCWIDTH_H_
// Qt // Standard
class QString; #include <string>
int konsole_wcwidth(wchar_t ucs); int konsole_wcwidth(wchar_t ucs);
int string_width( const QString & txt ); int string_width( const std::wstring & wstr );
#endif #endif

@ -34,6 +34,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>
#include <QDebug>
KPtyProcess::KPtyProcess(QObject *parent) : KPtyProcess::KPtyProcess(QObject *parent) :
KProcess(new KPtyProcessPrivate, parent) KProcess(new KPtyProcessPrivate, parent)
@ -61,11 +63,21 @@ KPtyProcess::~KPtyProcess()
{ {
Q_D(KPtyProcess); Q_D(KPtyProcess);
if (state() != QProcess::NotRunning && d->addUtmp) { if (state() != QProcess::NotRunning)
{
if (d->addUtmp)
{
d->pty->logout(); d->pty->logout();
disconnect(SIGNAL(stateChanged(QProcess::ProcessState)), disconnect(SIGNAL(stateChanged(QProcess::ProcessState)),
this, SLOT(_k_onStateChanged(QProcess::ProcessState))); this, SLOT(_k_onStateChanged(QProcess::ProcessState)));
} }
qWarning() << Q_FUNC_INFO << "the terminal process is still running, trying to stop it by SIGHUP";
::kill(pid(), SIGHUP);
waitForFinished(300);
if (state() != QProcess::NotRunning)
qCritical() << Q_FUNC_INFO << "process didn't stop upon SIGHUP and will be SIGKILL-ed";
}
delete d->pty; delete d->pty;
} }

@ -219,6 +219,20 @@ QSize QTermWidget::sizeHint() const
return size; return size;
} }
void QTermWidget::setTerminalSizeHint(bool on)
{
if (!m_impl->m_terminalDisplay)
return;
m_impl->m_terminalDisplay->setTerminalSizeHint(on);
}
bool QTermWidget::terminalSizeHint()
{
if (!m_impl->m_terminalDisplay)
return true;
return m_impl->m_terminalDisplay->terminalSizeHint();
}
void QTermWidget::startShellProgram() void QTermWidget::startShellProgram()
{ {
if ( m_impl->m_session->isRunning() ) { if ( m_impl->m_session->isRunning() ) {
@ -460,7 +474,8 @@ void QTermWidget::setColorScheme(const QString& origName)
QStringList QTermWidget::availableColorSchemes() QStringList QTermWidget::availableColorSchemes()
{ {
QStringList ret; QStringList ret;
foreach (const ColorScheme* cs, ColorSchemeManager::instance()->allColorSchemes()) const auto allColorSchemes = ColorSchemeManager::instance()->allColorSchemes();
for (const ColorScheme* cs : allColorSchemes)
ret.append(cs->name()); ret.append(cs->name());
return ret; return ret;
} }
@ -516,6 +531,11 @@ void QTermWidget::sessionFinished()
emit finished(); emit finished();
} }
void QTermWidget::bracketText(QString& text)
{
m_impl->m_terminalDisplay->bracketText(text);
}
void QTermWidget::copyClipboard() void QTermWidget::copyClipboard()
{ {
m_impl->m_terminalDisplay->copyClipboard(); m_impl->m_terminalDisplay->copyClipboard();
@ -698,6 +718,20 @@ void QTermWidget::setBlinkingCursor(bool blink)
m_impl->m_terminalDisplay->setBlinkingCursor(blink); m_impl->m_terminalDisplay->setBlinkingCursor(blink);
} }
void QTermWidget::setBidiEnabled(bool enabled)
{
if (!m_impl->m_terminalDisplay)
return;
m_impl->m_terminalDisplay->setBidiEnabled(enabled);
}
bool QTermWidget::isBidiEnabled()
{
if (!m_impl->m_terminalDisplay)
return false; // Default value
return m_impl->m_terminalDisplay->isBidiEnabled();
}
QString QTermWidget::title() const QString QTermWidget::title() const
{ {
QString title = m_impl->m_session->userTitle(); QString title = m_impl->m_session->userTitle();

@ -60,6 +60,10 @@ public:
//Initial size //Initial size
QSize sizeHint() const; QSize sizeHint() const;
// expose TerminalDisplay::TerminalSizeHint, setTerminalSizeHint
void setTerminalSizeHint(bool on);
bool terminalSizeHint();
//start shell program if it was not started in constructor //start shell program if it was not started in constructor
void startShellProgram(); void startShellProgram();
@ -199,6 +203,9 @@ public:
void setBlinkingCursor(bool blink); void setBlinkingCursor(bool blink);
/** Enables or disables bidi text in the terminal. */
void setBidiEnabled(bool enabled);
bool isBidiEnabled();
/** /**
* Automatically close the terminal session after the shell process exits or * Automatically close the terminal session after the shell process exits or
@ -212,6 +219,8 @@ public:
/** True if the title() or icon() was (ever) changed by the session. */ /** True if the title() or icon() was (ever) changed by the session. */
bool isTitleChanged() const; bool isTitleChanged() const;
/** change and wrap text corresponding to paste mode **/
void bracketText(QString& text);
signals: signals:
void finished(); void finished();
void copyAvailable(bool); void copyAvailable(bool);

@ -0,0 +1,61 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Match what's used in the main macros
cmake_policy(SET CMP0002 OLD)
find_package(PythonLibrary)
include(PythonMacros)
find_package(SIP)
include(SIPMacros)
if(SIP_VERSION STRLESS "040f03") # These version numbers also appear in ../CMakeLists.txt
message(FATAL_ERROR "The version of SIP found is too old. 4.15.3 or later is needed.")
endif()
find_package(PyQt5)
if(PYQT5_VERSION STRLESS "050101") # These version numbers also appear in ../CMakeLists.txt
message(FATAL_ERROR "The version of PyQt found is too old. 5.1.1 or later is required.")
endif()
set(SIP_INCLUDES ${PYQT5_SIP_DIR} sip)
set(SIP_CONCAT_PARTS 8)
set(SIP_TAGS ALL WS_X11 ${PYQT5_VERSION_TAG})
set(SIP_DISABLE_FEATURES VendorID PyQt_NoPrintRangeBug)
# Use an extra option when compiling on Python 3.
if (PYTHON_VERSION_MAJOR GREATER 2)
if(PYQT5_VERSION STRGREATER "040904")
# Disable for newer PyQt
set(SIP_EXTRA_OPTIONS -P -g)
else ()
set(SIP_EXTRA_OPTIONS -g)
endif()
else (PYTHON_VERSION_MAJOR GREATER 2)
if(PYQT5_VERSION STRGREATER "040904")
# Disable for newer PyQt
set(SIP_EXTRA_OPTIONS -P -g -x Py_v3)
else ()
set(SIP_EXTRA_OPTIONS -g -x Py_v3)
endif()
endif ()
include_directories(
"${SIP_INCLUDE_DIR}"
)
add_definitions(-D_REENTRANT -DSIP_PROTECTED_IS_PUBLIC -Dprotected=public)
file(GLOB qtermwidget_files_sip sip/*.sip)
set(SIP_EXTRA_FILES_DEPEND "${qtermwidget_files_sip}")
add_sip_python_module(QTermWidget sip/qtermwidget.sip qtermwidget5)
python_install(__init__.py "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/PyQt5/qtermwidget")
set (SIP_FILES_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/sip")
install(DIRECTORY sip/ DESTINATION "${SIP_FILES_INSTALL_DIR}/PyQt5/qtermwidget"
PATTERN "*~" EXCLUDE # This sucks, why can't I just whitelist what I _do_ want?
PATTERN ".svn" EXCLUDE
PATTERN "*.in" EXCLUDE
)

@ -1,36 +0,0 @@
PyQt5 Bindings for QTermWidget
==============================
INSTALL:
------------
####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.
####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
####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

@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,53 @@
# Find PyQt5
# ~~~~~~~~~~
# Copyright (c) 2014, Simon Edwards <simon@simonzone.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# PyQt5 website: http://www.riverbankcomputing.co.uk/pyqt/index.php
#
# Find the installed version of PyQt5. FindPyQt5 should only be called after
# Python has been found.
#
# This file defines the following variables:
#
# PYQT5_VERSION - The version of PyQt5 found expressed as a 6 digit hex number
# suitable for comparison as a string
#
# PYQT5_VERSION_STR - The version of PyQt5 as a human readable string.
#
# PYQT5_VERSION_TAG - The PyQt version tag using by PyQt's sip files.
#
# PYQT5_SIP_DIR - The directory holding the PyQt5 .sip files.
#
# PYQT5_SIP_FLAGS - The SIP flags used to build PyQt.
IF(EXISTS PYQT5_VERSION)
# Already in cache, be silent
SET(PYQT5_FOUND TRUE)
ELSE(EXISTS PYQT5_VERSION)
FIND_FILE(_find_pyqt5_py FindPyQt5.py PATHS ${CMAKE_MODULE_PATH})
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt5_py} OUTPUT_VARIABLE pyqt5_config)
IF(pyqt5_config)
STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT5_VERSION ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT5_VERSION_STR ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT5_VERSION_TAG ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT5_SIP_DIR ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT5_SIP_FLAGS ${pyqt5_config})
SET(PYQT5_FOUND TRUE)
ENDIF(pyqt5_config)
IF(PYQT5_FOUND)
IF(NOT PYQT5_FIND_QUIETLY)
MESSAGE(STATUS "Found PyQt5 version: ${PYQT5_VERSION_STR}")
ENDIF(NOT PYQT5_FIND_QUIETLY)
ELSE(PYQT5_FOUND)
IF(PYQT5_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find PyQt5.")
ENDIF(PYQT5_FIND_REQUIRED)
ENDIF(PYQT5_FOUND)
ENDIF(EXISTS PYQT5_VERSION)

@ -0,0 +1,28 @@
# Copyright (c) 2014, Simon Edwards <simon@simonzone.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
import PyQt5.Qt
import sys
import os.path
print("pyqt_version:%06.0x" % PyQt5.Qt.PYQT_VERSION)
print("pyqt_version_str:%s" % PyQt5.Qt.PYQT_VERSION_STR)
pyqt_version_tag = ""
in_t = False
for item in PyQt5.Qt.PYQT_CONFIGURATION["sip_flags"].split(' '):
if item=="-t":
in_t = True
elif in_t:
if item.startswith("Qt_5"):
pyqt_version_tag = item
else:
in_t = False
print("pyqt_version_tag:%s" % pyqt_version_tag)
# FIXME This next line is just a little bit too crude.
pyqt_sip_dir = os.path.join(sys.prefix, "share", "sip", "PyQt5")
print("pyqt_sip_dir:%s" % pyqt_sip_dir)
print("pyqt_sip_flags:%s" % PyQt5.Qt.PYQT_CONFIGURATION["sip_flags"])

@ -0,0 +1,73 @@
# Find Python
# ~~~~~~~~~~~
# Find the Python interpreter and related Python directories.
#
# This file defines the following variables:
#
# PYTHON_EXECUTABLE - The path and filename of the Python interpreter.
#
# PYTHON_SHORT_VERSION - The version of the Python interpreter found,
# excluding the patch version number. (e.g. 2.5 and not 2.5.1))
#
# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human
# readable string.
#
# PYTHON_SITE_PACKAGES_INSTALL_DIR - this cache variable can be used for installing
# own python modules. You may want to adjust this to be the
# same as ${PYTHON_SITE_PACKAGES_DIR}, but then admin
# privileges may be required for installation.
#
# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory.
#
# PYTHON_INCLUDE_PATH - Directory holding the python.h include file.
#
# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library.
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(FindPackageHandleStandardArgs)
find_package(PythonInterp)
if (PYTHONINTERP_FOUND)
option(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX "Install the Python files in the Python packages dir" FALSE)
# Set the Python libraries to what we actually found for interpreters
set(Python_ADDITIONAL_VERSIONS "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
# These are kept for compatibility
set(PYTHON_SHORT_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
set(PYTHON_LONG_VERSION ${PYTHON_VERSION_STRING})
find_package(PythonLibs QUIET)
if(PYTHONLIBS_FOUND)
set(PYTHON_LIBRARY ${PYTHON_LIBRARIES})
endif(PYTHONLIBS_FOUND)
# Auto detect Python site-packages directory
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Python system site-packages directory: ${PYTHON_SITE_PACKAGES_DIR}")
if(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX)
set(PYTHON_SITE_PACKAGES_INSTALL_DIR ${PYTHON_SITE_PACKAGES_DIR})
else()
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True, prefix='${CMAKE_INSTALL_PREFIX}'))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_INSTALL_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
if(NOT PYTHON_SITE_PACKAGES_INSTALL_DIR STREQUAL PYTHON_SITE_PACKAGES_DIR)
message(STATUS "The Python files will be installed to ${PYTHON_SITE_PACKAGES_INSTALL_DIR}. Make sure to add them to the Python search path (e.g. by setting PYTHONPATH)")
endif()
endif(PYTHONINTERP_FOUND)
find_package_handle_standard_args(PythonLibrary DEFAULT_MSG PYTHON_LIBRARY)

@ -0,0 +1,64 @@
# Find SIP
# ~~~~~~~~
#
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
#
# Find the installed version of SIP. FindSIP should be called after Python
# has been found.
#
# This file defines the following variables:
#
# SIP_VERSION - The version of SIP found expressed as a 6 digit hex number
# suitable for comparison as a string.
#
# SIP_VERSION_STR - The version of SIP found as a human readable string.
#
# SIP_EXECUTABLE - Path and filename of the SIP command line executable.
#
# SIP_INCLUDE_DIR - Directory holding the SIP C++ header file.
#
# SIP_DEFAULT_SIP_DIR - Default directory where .sip files should be installed
# into.
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF(SIP_VERSION)
# Already in cache, be silent
SET(SIP_FOUND TRUE)
ELSE(SIP_VERSION)
FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_sip_py} OUTPUT_VARIABLE sip_config)
IF(sip_config)
STRING(REGEX REPLACE "^sip_version:([^\n]+).*$" "\\1" SIP_VERSION ${sip_config})
STRING(REGEX REPLACE ".*\nsip_version_str:([^\n]+).*$" "\\1" SIP_VERSION_STR ${sip_config})
STRING(REGEX REPLACE ".*\nsip_bin:([^\n]+).*$" "\\1" SIP_EXECUTABLE ${sip_config})
IF(NOT SIP_DEFAULT_SIP_DIR)
STRING(REGEX REPLACE ".*\ndefault_sip_dir:([^\n]+).*$" "\\1" SIP_DEFAULT_SIP_DIR ${sip_config})
ENDIF(NOT SIP_DEFAULT_SIP_DIR)
STRING(REGEX REPLACE ".*\nsip_inc_dir:([^\n]+).*$" "\\1" SIP_INCLUDE_DIR ${sip_config})
FILE(TO_CMAKE_PATH ${SIP_DEFAULT_SIP_DIR} SIP_DEFAULT_SIP_DIR)
FILE(TO_CMAKE_PATH ${SIP_INCLUDE_DIR} SIP_INCLUDE_DIR)
IF(EXISTS ${SIP_EXECUTABLE})
SET(SIP_FOUND TRUE)
ELSE()
MESSAGE(STATUS "Found SIP configuration but the sip executable could not be found.")
ENDIF()
ENDIF(sip_config)
IF(SIP_FOUND)
IF(NOT SIP_FIND_QUIETLY)
MESSAGE(STATUS "Found SIP version: ${SIP_VERSION_STR}")
ENDIF(NOT SIP_FIND_QUIETLY)
ELSE(SIP_FOUND)
IF(SIP_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find SIP")
ENDIF(SIP_FIND_REQUIRED)
ENDIF(SIP_FOUND)
ENDIF(SIP_VERSION)

@ -0,0 +1,15 @@
# FindSIP.py
#
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
import sys
import sipconfig
sipcfg = sipconfig.Configuration()
print("sip_version:%06.0x" % sipcfg.sip_version)
print("sip_version_str:%s" % sipcfg.sip_version_str)
print("sip_bin:%s" % sipcfg.sip_bin)
print("default_sip_dir:%s" % sipcfg.default_sip_dir)
print("sip_inc_dir:%s" % sipcfg.sip_inc_dir)

@ -0,0 +1,4 @@
# By Simon Edwards <simon@simonzone.com>
# This file is in the public domain.
import py_compile, sys
sys.exit(py_compile.main())

@ -0,0 +1,82 @@
# Python macros
# ~~~~~~~~~~~~~
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
# Copyright (c) 2012, Rolf Eike Beer <eike@sf-mail.de>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# This file defines the following macros:
#
# PYTHON_INSTALL (SOURCE_FILE DESTINATION_DIR)
# Install the SOURCE_FILE, which is a Python .py file, into the
# destination directory during install. The file will be byte compiled
# and both the .py file and .pyc file will be installed.
set(PYTHON_MACROS_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
macro(PYTHON_INSTALL SOURCE_FILE DESTINATION_DIR)
find_file(_python_compile_py PythonCompile.py PATHS ${CMAKE_MODULE_PATH})
# Install the source file.
install(FILES ${SOURCE_FILE} DESTINATION ${DESTINATION_DIR})
# Byte compile and install the .pyc file, unless explicitly prevented by env..
if("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
get_filename_component(_absfilename ${SOURCE_FILE} ABSOLUTE)
get_filename_component(_filename ${SOURCE_FILE} NAME)
get_filename_component(_filenamebase ${SOURCE_FILE} NAME_WE)
get_filename_component(_basepath ${SOURCE_FILE} PATH)
if(WIN32)
# remove drive letter
string(REGEX REPLACE "^[a-zA-Z]:/" "/" _basepath "${_basepath}")
endif(WIN32)
set(_bin_py ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filename})
# Python 3.2 changed the pyc file location
if(PYTHON_VERSION_STRING VERSION_GREATER 3.1)
# To get the right version for suffix
set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/__pycache__/${_filenamebase}.cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}.pyc")
set(_py_install_dir "${DESTINATION_DIR}/__pycache__/")
else()
set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filenamebase}.pyc")
set(_py_install_dir "${DESTINATION_DIR}")
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_basepath})
# Setting because it will be displayed later, in compile_python_files
set(_message "Byte-compiling ${_bin_py} to ${_bin_pyc}")
string(REPLACE "/" "_" _rule_name "${_basepath}/${_bin_pyc}")
add_custom_target("${_rule_name}" ALL)
get_filename_component(_abs_bin_py ${_bin_py} ABSOLUTE)
if(_abs_bin_py STREQUAL _absfilename) # Don't copy the file onto itself.
add_custom_command(
TARGET "${_rule_name}"
COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
DEPENDS "${_absfilename}"
)
else()
add_custom_command(
TARGET "${_rule_name}"
COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
COMMAND "${CMAKE_COMMAND}" -E copy "${_absfilename}" "${_bin_py}"
COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
DEPENDS "${_absfilename}"
)
endif()
install(FILES ${_bin_pyc} DESTINATION "${_py_install_dir}")
unset(_py_install_dir)
unset(_message)
endif("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
endmacro(PYTHON_INSTALL)

@ -0,0 +1,124 @@
# Macros for SIP
# ~~~~~~~~~~~~~~
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
#
# This file defines the following macros:
#
# ADD_SIP_PYTHON_MODULE (MODULE_NAME MODULE_SIP [library1, libaray2, ...])
# Specifies a SIP file to be built into a Python module and installed.
# MODULE_NAME is the name of Python module including any path name. (e.g.
# os.sys, Foo.bar etc). MODULE_SIP the path and filename of the .sip file
# to process and compile. libraryN are libraries that the Python module,
# which is typically a shared library, should be linked to. The built
# module will also be install into Python's site-packages directory.
#
# The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a
# number of variables:
#
# SIP_INCLUDES - List of directories which SIP will scan through when looking
# for included .sip files. (Corresponds to the -I option for SIP.)
#
# SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t
# option for SIP.)
#
# SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code
# of each module should be split into. Defaults to 8. (Corresponds to the
# -j option for SIP.)
#
# SIP_DISABLE_FEATURES - List of feature names which should be disabled
# running SIP. (Corresponds to the -x option for SIP.)
#
# SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to
# SIP.
SET(SIP_INCLUDES)
SET(SIP_TAGS)
SET(SIP_CONCAT_PARTS 8)
SET(SIP_DISABLE_FEATURES)
SET(SIP_EXTRA_OPTIONS)
MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP)
SET(EXTRA_LINK_LIBRARIES ${ARGN})
STRING(REPLACE "." "/" _x ${MODULE_NAME})
GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH)
GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME)
GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH)
if(_module_path STREQUAL "")
set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
else(_module_path STREQUAL "")
set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_module_path}")
endif(_module_path STREQUAL "")
GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE)
# We give this target a long logical target name.
# (This is to avoid having the library name clash with any already
# install library names. If that happens then cmake dependancy
# tracking get confused.)
STRING(REPLACE "." "_" _logical_name ${MODULE_NAME})
SET(_logical_name "python_module_${_logical_name}")
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SIP_OUTPUT_DIR}) # Output goes in this dir.
SET(_sip_includes)
FOREACH (_inc ${SIP_INCLUDES})
GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE)
LIST(APPEND _sip_includes -I ${_abs_inc})
ENDFOREACH (_inc )
SET(_sip_tags)
FOREACH (_tag ${SIP_TAGS})
LIST(APPEND _sip_tags -t ${_tag})
ENDFOREACH (_tag)
SET(_sip_x)
FOREACH (_x ${SIP_DISABLE_FEATURES})
LIST(APPEND _sip_x -x ${_x})
ENDFOREACH (_x ${SIP_DISABLE_FEATURES})
SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}")
SET(_sip_output_files)
FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_SIP_OUTPUT_DIR}/sip${_child_module_name}part${CONCAT_NUM}.cpp )
ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
IF(NOT WIN32)
SET(TOUCH_COMMAND touch)
ELSE(NOT WIN32)
SET(TOUCH_COMMAND echo)
# instead of a touch command, give out the name and append to the files
# this is basically what the touch command does.
FOREACH(filename ${_sip_output_files})
FILE(APPEND filename "")
ENDFOREACH(filename ${_sip_output_files})
ENDIF(NOT WIN32)
ADD_CUSTOM_COMMAND(
OUTPUT ${_sip_output_files}
COMMAND ${CMAKE_COMMAND} -E echo ${message}
COMMAND ${TOUCH_COMMAND} ${_sip_output_files}
COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_SIP_OUTPUT_DIR} ${_sip_includes} ${_abs_module_sip}
DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND}
)
# not sure if type MODULE could be uses anywhere, limit to cygwin for now
IF (CYGWIN)
ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} )
ELSE (CYGWIN)
ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} )
ENDIF (CYGWIN)
TARGET_LINK_LIBRARIES(${_logical_name} ${PYTHON_LIBRARY})
TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES})
SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name})
INSTALL(TARGETS ${_logical_name} DESTINATION "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/${_parent_module_path}")
ENDMACRO(ADD_SIP_PYTHON_MODULE)

@ -1,85 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# PyQt4 bindings for th QTermWidget project.
#
# Copyright (C) 2009 Piotr "Riklaunim" Maliński <riklaunim@gmail.com>,
# Alexander Slesarev <alex.slesarev@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sipconfig
from PyQt4 import pyqtconfig
# The name of the SIP build file generated by SIP and used by the build
# system.
build_file = "qtermwidget.sbf"
# Get the PyQt configuration information.
config = pyqtconfig.Configuration()
# Get the extra SIP flags needed by the imported qt module. Note that
# this normally only includes those flags (-x and -t) that relate to SIP's
# versioning system.
qt_sip_flags = config.pyqt_sip_flags
# Run SIP to generate the code. Note that we tell SIP where to find the qt
# module's specification files using the -I flag.
os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I",
config.pyqt_sip_dir, qt_sip_flags, "qtermwidget.sip"]))
# We are going to install the SIP specification file for this module and
# its configuration module.
installs = []
installs.append(["qtermwidget.sip", os.path.join(config.default_sip_dir,
"qtermwidget")])
installs.append(["qtermwidgetconfig.py", config.default_mod_dir])
# Create the Makefile. The QtModuleMakefile class provided by the
# pyqtconfig module takes care of all the extra preprocessor, compiler and
# linker flags needed by the Qt library.
makefile = pyqtconfig.QtGuiModuleMakefile(
configuration = config,
build_file = build_file,
installs = installs)
# 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
# ".dll" extension on Windows).
makefile.extra_lib_dirs.append("..")
makefile.extra_libs = ["qtermwidget4"]
# Generate the Makefile itself.
makefile.generate()
# Now we create the configuration module. This is done by merging a Python
# dictionary (whose values are normally determined dynamically) with a
# (static) template.
content = {
# Publish where the SIP specifications for this module will be
# installed.
"qtermwidget_sip_dir": config.default_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": qt_sip_flags}
# This creates the qtermwidgetconfig.py module from the qtermwidgetconfig.py.in
# template and the dictionary.
sipconfig.create_config_module("qtermwidgetconfig.py", "config.py.in", content)

@ -1,104 +0,0 @@
import os
import sipconfig
import subprocess
import os
import site
import pprint
from distutils import sysconfig
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):
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"]))
installs = []
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"])
# 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
# ".dll" extension on Windows).
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
}
# This creates the qtermwidgetconfig.py module from the qtermwidgetconfig.py.in
# template and the dictionary.
sipconfig.create_config_module("qtermwidgetconfig.py", "config.py.in", content)

@ -1,5 +1,8 @@
%Module QTermWidget %Module QTermWidget
%ModuleHeaderCode
#pragma GCC visibility push(default)
%End
%Import QtGui/QtGuimod.sip %Import QtGui/QtGuimod.sip
%Import QtCore/QtCoremod.sip %Import QtCore/QtCoremod.sip
@ -19,7 +22,7 @@ public:
ScrollBarRight=2 ScrollBarRight=2
}; };
enum KeyboardCursorShape enum class KeyboardCursorShape
{ {
BlockCursor=0, BlockCursor=0,
UnderlineCursor=1, UnderlineCursor=1,
@ -30,6 +33,8 @@ public:
~QTermWidget(); ~QTermWidget();
void startTerminalTeletype(); void startTerminalTeletype();
QSize sizeHint() const; QSize sizeHint() const;
void setTerminalSizeHint(bool on);
bool terminalSizeHint();
void startShellProgram(); void startShellProgram();
int getShellPID(); int getShellPID();
void changeDir(const QString & dir); void changeDir(const QString & dir);
Loading…
Cancel
Save