Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continue the work from https://github.com/lxqt/qtermwidget/pull/468 #515

Closed
wants to merge 8 commits into from
132 changes: 83 additions & 49 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ option(BUILD_EXAMPLE "Build example application. Default OFF." OFF)
option(QTERMWIDGET_USE_UTEMPTER "Uses libutempter on Linux or libulog on FreeBSD for login records." OFF)
option(QTERMWIDGET_BUILD_PYTHON_BINDING "Build python binding" OFF)
option(USE_UTF8PROC "Use libutf8proc for better Unicode support. Default OFF" OFF)
option(USE_QT6 "Build with Qt 6 instead of Qt 5" OFF)

option(USE_QT5 "Use Qt 5 instead of Qt6 (if available). Default OFF" OFF)

# just change version for releases
# keep this in sync with the version in pyqt/pyproject.toml
set(QTERMWIDGET_VERSION_MAJOR "1")
set(QTERMWIDGET_VERSION_MINOR "3")
set(QTERMWIDGET_VERSION_MINOR "0")
set(QTERMWIDGET_VERSION_PATCH "0")

set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}")
Expand All @@ -32,24 +30,40 @@ set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINO
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
set(CMAKE_INCLUDE_CURRENT_DIR ON)

if(NOT USE_QT6)
set(QTERMWIDGET_LIBRARY_NAME qtermwidget5)
find_package(Qt5 "5.15.0" REQUIRED COMPONENTS Widgets LinguistTools)
find_package(lxqt-build-tools "0.13.0" REQUIRED)
# Minimum Versions
set(QT_MINIMUM_VERSION "5.15.0")
set(QT6_MINIMUM_VERSION "6.1.0")
set(LXQTBT_MINIMUM_VERSION "0.10.0")

if (NOT USE_QT5)
find_package(Qt6 COMPONENTS Widgets)
if (NOT Qt6_FOUND)
find_package(Qt5Widgets "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(Qt5LinguistTools "${QT_MINIMUM_VERSION}" REQUIRED)
endif()

if (Qt6_FOUND)
find_package(Qt6Widgets "${QT6_MINIMUM_VERSION}" REQUIRED)
find_package(Qt6LinguistTools "${QT6_MINIMUM_VERSION}" REQUIRED)
find_package(Qt6Core5Compat "${QT6_MINIMUM_VERSION}" REQUIRED)
endif()
else()
set(QTERMWIDGET_LIBRARY_NAME qtermwidget6)
find_package(Qt6 "6.3.0" REQUIRED COMPONENTS Widgets LinguistTools Core5Compat)
find_package(lxqt2-build-tools "2.0.0" REQUIRED)
find_package(Qt5Widgets "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(Qt5LinguistTools "${QT_MINIMUM_VERSION}" REQUIRED)
endif()

find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} QUIET)

if(USE_UTF8PROC)
find_package(Utf8Proc REQUIRED)
endif()

include(LXQtPreventInSourceBuilds)
include(LXQtTranslateTs)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtCreatePkgConfigFile)
if (LXQT_BUILD_TOOLS_FOUND)
include(LXQtPreventInSourceBuilds)
include(LXQtTranslateTs)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtCreatePkgConfigFile)
endif()

if(APPLE)
if(CMAKE_VERSION VERSION_GREATER 3.9)
Expand All @@ -58,6 +72,12 @@ if(APPLE)
endif()
endif()

if (NOT Qt6_FOUND)
set(QTERMWIDGET_LIBRARY_NAME qtermwidget5)
else()
set(QTERMWIDGET_LIBRARY_NAME qtermwidget6)
endif()

# main library

set(SRCS
Expand All @@ -84,6 +104,7 @@ set(SRCS
lib/TerminalDisplay.cpp
lib/tools.cpp
lib/Vt102Emulation.cpp
lib/qtermwidget_interface.h
)

# Only the Headers that need to be moc'd go here
Expand Down Expand Up @@ -113,7 +134,6 @@ set(HDRS_DISTRIB
lib/Emulation.h
lib/KeyboardTranslator.h
lib/Filter.h
lib/qtermwidget_interface.h
)

# dirs
Expand All @@ -130,34 +150,48 @@ set(QTERMWIDGET_INCLUDE_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${QTERMWIDGET_LIBR

CHECK_FUNCTION_EXISTS(updwtmpx HAVE_UPDWTMPX)

if(NOT USE_QT6)
if (NOT USE_QT5)
if (NOT Qt6_FOUND)
qt5_wrap_cpp(MOCS ${HDRS})
qt5_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt5Widgets")
else()
qt6_wrap_cpp(MOCS ${HDRS})
qt6_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt6Widgets")
endif()
else()
qt5_wrap_cpp(MOCS ${HDRS})
qt5_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt5Widgets")
else()
qt6_wrap_cpp(MOCS ${HDRS})
qt6_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt6Widgets")
endif()

lxqt_translate_ts(QTERMWIDGET_QM
TRANSLATION_DIR "lib/translations"
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${SRCS} ${HDRS} ${UI}
INSTALL_DIR
${TRANSLATIONS_DIR}
COMPONENT
Runtime
)
if (LXQT_BUILD_TOOLS_FOUND)
lxqt_translate_ts(QTERMWIDGET_QM
TRANSLATION_DIR "lib/translations"
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${SRCS} ${HDRS} ${UI}
INSTALL_DIR
${TRANSLATIONS_DIR}
COMPONENT
Runtime
)
endif()

add_library(${QTERMWIDGET_LIBRARY_NAME} SHARED ${SRCS} ${MOCS} ${UI_SRCS} ${QTERMWIDGET_QM})
if(NOT USE_QT6)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt5::Widgets)
if (NOT USE_QT5)
if (NOT Qt6_FOUND)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt5::Widgets)
else()
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt6::Widgets)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt6::Core5Compat)
endif()
else()
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt6::Widgets Qt6::Core5Compat)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt5::Widgets)
endif()

set_target_properties( ${QTERMWIDGET_LIBRARY_NAME} PROPERTIES
SOVERSION ${QTERMWIDGET_VERSION_MAJOR}
VERSION ${QTERMWIDGET_VERSION}
Expand Down Expand Up @@ -218,8 +252,6 @@ target_compile_definitions(${QTERMWIDGET_LIBRARY_NAME}
"TRANSLATIONS_DIR=\"${TRANSLATIONS_DIR}\""
"HAVE_POSIX_OPENPT"
"HAVE_SYS_TIME_H"
# https://www.kdab.com/un-deprecate-qt-project/
"QT_DISABLE_DEPRECATED_BEFORE=0x050e00"
)


Expand Down Expand Up @@ -275,17 +307,19 @@ install(DIRECTORY
FILES_MATCHING PATTERN "*.*schem*"
)

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
)
if (LXQT_BUILD_TOOLS_FOUND)
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
)
endif()

configure_file(
"${PROJECT_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}-config.cmake.in"
Expand Down Expand Up @@ -330,7 +364,7 @@ endif()

# python binding
if (QTERMWIDGET_BUILD_PYTHON_BINDING)
message(SEND_ERROR "QTERMWIDGET_BUILD_PYTHON_BINDING is no longer supported. Check README.md for how to build PyQt bindings.")
add_subdirectory(pyqt)
endif()
# end of python binding

Expand Down
6 changes: 3 additions & 3 deletions examples/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ int main(int argc, char *argv[])
QMenu *actionsMenu = new QMenu(QStringLiteral("Actions"), menuBar);
menuBar->addMenu(actionsMenu);
actionsMenu->addAction(QStringLiteral("Find..."), console, &QTermWidget::toggleShowSearchBar,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F));
QKeySequence(QLatin1String("Ctrl+Shift+F")));
actionsMenu->addAction(QStringLiteral("Copy"), console, &QTermWidget::copyClipboard,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C));
QKeySequence(QLatin1String("Ctrl+Shift+C")));
actionsMenu->addAction(QStringLiteral("Paste"), console, &QTermWidget::pasteClipboard,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
QKeySequence(QLatin1String("Ctrl+Shift+V")));
actionsMenu->addAction(QStringLiteral("About Qt"), &app, &QApplication::aboutQt);
mainWindow->setMenuBar(menuBar);

Expand Down
4 changes: 4 additions & 0 deletions lib/Character.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ class Character
union
{
/** The unicode character value for this character. */
#if QT_VERSION >= 0x060000
char16_t character;
#else
wchar_t character;
#endif
/**
* Experimental addition which allows a single Character instance to contain more than
* one unicode character.
Expand Down
20 changes: 16 additions & 4 deletions lib/ColorScheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#include <QDir>
#include <QRegularExpression>
#include <QRandomGenerator>

#if QT_VERSION >= 0x060000
#include <QStringView>
#endif

// KDE
//#include <KColorScheme>
Expand Down Expand Up @@ -339,7 +341,11 @@ void ColorScheme::readColorEntry(QSettings * s , int index)
bool ok = false;
// XXX: Undocumented(?) QSettings behavior: values with commas are parsed
// as QStringList and others QString
#if QT_VERSION >= 0x060000
if (colorValue.typeId() == QMetaType::QStringList)
#else
if (colorValue.type() == QVariant::StringList)
#endif
{
QStringList rgbList = colorValue.toStringList();
colorStr = rgbList.join(QLatin1Char(','));
Expand All @@ -364,9 +370,15 @@ void ColorScheme::readColorEntry(QSettings * s , int index)
if (hexColorPattern.match(colorStr).hasMatch())
{
// Parsing is always ok as already matched by the regexp
r = colorStr.mid(1, 2).toInt(nullptr, 16);
g = colorStr.mid(3, 2).toInt(nullptr, 16);
b = colorStr.mid(5, 2).toInt(nullptr, 16);
#if QT_VERSION >= 0x060000
r = QStringView{colorStr}.mid(1, 2).toInt(nullptr, 16);
g = QStringView{colorStr}.mid(3, 2).toInt(nullptr, 16);
b = QStringView{colorStr}.mid(5, 2).toInt(nullptr, 16);
#else
r = colorStr.midRef(1, 2).toInt(nullptr, 16);
g = colorStr.midRef(3, 2).toInt(nullptr, 16);
b = colorStr.midRef(5, 2).toInt(nullptr, 16);
#endif
ok = true;
}
}
Expand Down
40 changes: 22 additions & 18 deletions lib/Emulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
#include <QClipboard>
#include <QHash>
#include <QKeyEvent>
#include <QRegExp>
#include <QRegularExpression>
#include <QTextStream>
#include <QThread>

#include <QTime>
//TODO REMOVE THIS
#include <QDebug>

// KDE
//#include <kdebug.h>
Expand All @@ -52,8 +54,6 @@ using namespace Konsole;

Emulation::Emulation() :
_currentScreen(nullptr),
_codec(nullptr),
_decoder(nullptr),
_keyTranslator(nullptr),
_usesMouse(false),
_bracketedPasteMode(false)
Expand Down Expand Up @@ -129,7 +129,6 @@ Emulation::~Emulation()

delete _screen[0];
delete _screen[1];
delete _decoder;
}

void Emulation::setScreen(int n)
Expand Down Expand Up @@ -160,25 +159,28 @@ const HistoryType& Emulation::history() const
return _screen[0]->getScroll();
}

void Emulation::setCodec(const QTextCodec * qtc)
void Emulation::setCodec(QStringEncoder qtc)
{
if (qtc)
_codec = qtc;
if (qtc.isValid())
_fromUtf16 = std::move(qtc);
else
setCodec(LocaleCodec);

delete _decoder;
_decoder = _codec->makeDecoder();
setCodec(LocaleCodec);

_toUtf16 = QStringDecoder{utf8() ? QStringConverter::Encoding::Utf8 : QStringConverter::Encoding::System};
emit useUtf8Request(utf8());
}

bool Emulation::utf8() const
{
const auto enc = QStringConverter::encodingForName(_fromUtf16.name());
return enc && enc.value() == QStringConverter::Encoding::Utf8;
}

void Emulation::setCodec(EmulationCodec codec)
{
if ( codec == Utf8Codec )
setCodec( QTextCodec::codecForName("utf8") );
else if ( codec == LocaleCodec )
setCodec( QTextCodec::codecForLocale() );
setCodec( QStringEncoder{codec == Utf8Codec ?
QStringConverter::Encoding::Utf8 :
QStringConverter::Encoding::System} );
}

void Emulation::setKeyBindings(const QString& name)
Expand All @@ -199,7 +201,9 @@ void Emulation::receiveChar(wchar_t c)
// process application unicode input to terminal
// this is a trivial scanner
{
qDebug() << "Emulation::receiveChar: character " << c;
c &= 0xff;
qDebug() << "Emulation::receiveChar (after &=): character " << c;
switch (c)
{
case '\b' : _currentScreen->backspace(); break;
Expand Down Expand Up @@ -250,12 +254,12 @@ void Emulation::receiveData(const char* text, int length)
* U+10FFFF
* https://unicodebook.readthedocs.io/unicode_encodings.html#surrogates
*/
QString utf16Text = _decoder->toUnicode(text,length);
QString utf16Text = _toUtf16(QByteArray::fromRawData(text, length));
std::wstring unicodeText = utf16Text.toStdWString();

//send characters to terminal emulator
for (size_t i=0;i<unicodeText.length();i++)
receiveChar(unicodeText[i]);
for (wchar_t i : unicodeText)
receiveChar(i);

//look for z-modem indicator
//-- someone who understands more about z-modems that I do may be able to move
Expand Down
Loading