Commit 570d74cb authored by Sebastian Gottfried's avatar Sebastian Gottfried
Browse files

Port to Qt5/KF5: It builds!

Only the C++ part is ported, no changes to the QML files yet. This means
the app compiles, but is far from functional. In fact it just presents
an empty windows so far.

Porting was straight-forward, no earth-shattering changes. Just the
usual stuff.
parent 0a6cddf3
......@@ -3,22 +3,56 @@
project(ktouch)
find_package(KDE4 4.9.95 REQUIRED)
include(KDE4Defaults)
cmake_minimum_required(VERSION 2.8.12)
find_package(ECM 1.0.0 REQUIRED NO_MODULE)
find_package(KF5DocTools)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${QT4_INCLUDES})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include(KDEInstallDirs)
include(ECMAddTests)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMInstallIcons)
include(ECMOptionalAddSubdirectory)
include(ECMSetupVersion)
include(FeatureSummary)
find_package(Qt5 REQUIRED COMPONENTS
Widgets
Sql
Script
XmlPatterns
Qml
Quick
QuickWidgets
Test
)
find_package(KF5 REQUIRED COMPONENTS
Config
ConfigWidgets
CoreAddons
Declarative
I18n
KIO
NewStuff
WidgetsAddons
XmlGui
ItemViews
KCMUtils
TextEditor
)
# subdirectories to build
add_subdirectory(data)
add_subdirectory(doc)
add_subdirectory(src)
# add_subdirectory(sounds) # excluded because of the lack of sound support
add_subdirectory(images)
add_subdirectory(icons)
ecm_optional_add_subdirectory(data)
ecm_optional_add_subdirectory(doc)
ecm_optional_add_subdirectory(src)
# ecm_optional_add_subdirectory(sounds)
ecm_optional_add_subdirectory(images)
ecm_optional_add_subdirectory(icons)
# files to install in the ktouch project root directory
install( PROGRAMS ktouch.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
install(PROGRAMS ktouch.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES ktouch.appdata.xml DESTINATION ${SHARE_INSTALL_PREFIX}/appdata/)
macro_display_feature_log()
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
add_subdirectory(keyboardlayouts)
add_subdirectory(courses)
install( FILES "data.xml" DESTINATION ${DATA_INSTALL_DIR}/ktouch )
ecm_optional_add_subdirectory(keyboardlayouts)
ecm_optional_add_subdirectory(courses)
install( FILES "data.xml" DESTINATION ${DATA_INSTALL_DIR}/ktouch )
########### install files ###############
#
#
kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR ktouch)
kde4_create_manpage(man-ktouch.1.docbook 1 INSTALL_DESTINATION ${MAN_INSTALL_DIR})
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR ktouch)
kdoctools_create_manpage(man-ktouch.1.docbook 1 INSTALL_DESTINATION ${MAN_INSTALL_DIR})
kde4_install_icons( ${ICON_INSTALL_DIR} )
ecm_install_icons(
ICONS
hi16-app-ktouch.png
hi22-app-ktouch.png
hi32-app-ktouch.png
hi48-app-ktouch.png
hi128-app-ktouch.png
hisc-app-ktouch.svgz
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor
)
# CMakeList.txt for the KTouch source directory
include(MacroLogFeature)
find_package(KDeclarative REQUIRED)
ecm_setup_version(2.3.0
VARIABLE_PREFIX KTOUCH
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KTouchConfigVersion.cmake"
)
# Currently it is called by FindQt4, but call it explicitly
find_package(X11)
macro_log_feature(X11_Xkbfile_FOUND "libxkbfile" "X Keyboard Extension" "http://www.x.org/wiki/XKB" FALSE "" "Support for keyboard layout auto-detection in KTouch")
# macro_log_feature(X11_Xkbfile_FOUND "libxkbfile" "X Keyboard Extension" "http://www.x.org/wiki/XKB" FALSE "" "Support for keyboard layout auto-detection in KTouch")
add_subdirectory(qml)
add_subdirectory(schemata)
ecm_optional_add_subdirectory(qml)
ecm_optional_add_subdirectory(schemata)
# set include directories
include_directories(${QT_INCLUDE} ${KDE4_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${ktouch_SOURCE_DIR}
)
# add compilation options
option(KDEEDU_KTOUCH_BUILD_WITH_PHONON "Enables compilation of sound output using Phonon." ON)
mark_as_advanced(KDEEDU_KTOUCH_BUILD_WITH_PHONON)
# configure the local configuration file
configure_file(ktouch_build_config.h.in ktouch_build_config.h)
# add ui files, all files in directory ui are Qt4 only
kde4_add_ui_files(ktouch_UIS
ui/colorsconfigwidget.ui
ui/trainingconfigwidget.ui
ui/resourceeditorwidget.ui
ui/resourcetypeswidget.ui
ui/newcoursewidget.ui
ui/newkeyboardlayoutwidget.ui
ui/resourcetemplatewidget.ui
ui/courseeditor.ui
ui/lessontexteditor.ui
ui/keyboardlayouteditor.ui
ui/keyboardlayoutpropertieswidget.ui
ui/customlessoneditorwidget.ui
)
# set the source code files from which KTouch is compiled
set(ktouch_SRCS
......@@ -44,8 +28,6 @@ set(ktouch_SRCS
mainwindow.cpp
bindings/utils.cpp
bindings/stringformatter.cpp
declarativeitems/applicationbackground.cpp
declarativeitems/cursorshapearea.cpp
declarativeitems/griditem.cpp
declarativeitems/lessonpainter.cpp
declarativeitems/preferencesproxy.cpp
......@@ -98,6 +80,22 @@ set(ktouch_SRCS
customlessoneditorwidget.cpp
)
# compile UI files
qt5_wrap_ui(ktouch_SRCS
ui/colorsconfigwidget.ui
ui/trainingconfigwidget.ui
ui/resourceeditorwidget.ui
ui/resourcetypeswidget.ui
ui/newcoursewidget.ui
ui/newkeyboardlayoutwidget.ui
ui/resourcetemplatewidget.ui
ui/courseeditor.ui
ui/lessontexteditor.ui
ui/keyboardlayouteditor.ui
ui/keyboardlayoutpropertieswidget.ui
ui/customlessoneditorwidget.ui
)
if (X11_Xkbfile_FOUND)
add_definitions(-DKTOUCH_BUILD_WITH_X11)
include_directories(${X11_Xkbfile_INCLUDE_PATH})
......@@ -106,19 +104,36 @@ else (X11_Xkbfile_FOUND)
set(ktouch_SRCS ${ktouch_SRCS} keyboardlayoutmenu.cpp)
endif (X11_Xkbfile_FOUND)
kde4_add_kcfg_files(ktouch_SRCS preferences.kcfgc )
#uncomment this if oxygen icons for ktouch are available
#kde4_add_app_icon(ktouch_SRCS "${KDE4_ICON_DIR}/oxygen/*/apps/ktouch.png")
kde4_add_app_icon(ktouch_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../icons/hi*-app-ktouch.png")
kde4_add_executable(ktouch ${ktouch_UIS} ${ktouch_SRCS})
target_link_libraries(ktouch ${KDECLARATIVE_LIBRARIES} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KCMUTILS_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTXMLPATTERNS_LIBRARY} ${QT_QTSQL_LIBRARY})
kconfig_add_kcfg_files(ktouch_SRCS preferences.kcfgc)
add_executable(ktouch ${ktouch_SRCS})
target_link_libraries(ktouch
LINK_PUBLIC
Qt5::Qml
Qt5::Quick
Qt5::QuickWidgets
Qt5::Script
Qt5::Sql
Qt5::XmlPatterns
KF5::ConfigWidgets
KF5::Declarative
KF5::KIOWidgets
KF5::ItemViews
KF5::NewStuff
KF5::XmlGui
KF5::I18n
KF5::KCMUtils
KF5::TextEditor
)
if (X11_Xkbfile_FOUND)
target_link_libraries(ktouch ${X11_Xkbfile_LIB} ${X11_LIBRARIES})
endif (X11_Xkbfile_FOUND)
#uncomment this if oxygen icons for ktouch are available
#kde4_add_app_icon(ktouch_SRCS "${KDE4_ICON_DIR}/oxygen/*/apps/ktouch.png")
#kde4_add_app_icon(ktouch_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../icons/hi*-app-ktouch.png")
install(TARGETS ktouch ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ktouch.kcfg DESTINATION ${KCFG_INSTALL_DIR})
......@@ -17,18 +17,13 @@
#include "application.h"
#include <qdeclarative.h>
#include <QGraphicsDropShadowEffect>
#include <QScriptValue>
#include <QScriptEngine>
#include <QKeyEvent>
#include <QQmlEngine>
#include <QJSValue>
#include <kdeclarative.h>
#include <KDeclarative/KDeclarative>
#include "bindings/utils.h"
#include "bindings/stringformatter.h"
#include "declarativeitems/applicationbackground.h"
#include "declarativeitems/cursorshapearea.h"
#include "declarativeitems/griditem.h"
#include "declarativeitems/lessonpainter.h"
#include "declarativeitems/preferencesproxy.h"
......@@ -51,8 +46,9 @@
#include "models/learningprogressmodel.h"
#include "models/errorsmodel.h"
Application::Application() :
KApplication(true),
Application::Application(int& argc, char** argv, int flags):
QApplication(argc, argv, flags),
m_dataIndex(new DataIndex(this))
{
registerQmlTypes();
......@@ -68,33 +64,27 @@ DataIndex* Application::dataIndex()
return app->m_dataIndex;
}
QWeakPointer<ResourceEditor>& Application::resourceEditorRef()
QSharedPointer<ResourceEditor>& Application::resourceEditorRef()
{
Application* app = qobject_cast<Application*>(QCoreApplication::instance());
return app->m_resourceEditorRef;
}
void Application::setupDeclarativeBindings(QDeclarativeEngine* declarativeEngine)
void Application::setupDeclarativeBindings(QQmlEngine* qmlEngine)
{
KDeclarative kDeclarative;
kDeclarative.setDeclarativeEngine(declarativeEngine);
kDeclarative.initialize();
KDeclarative::KDeclarative kDeclarative;
kDeclarative.setDeclarativeEngine(qmlEngine);
kDeclarative.setupBindings();
QScriptEngine* engine = kDeclarative.scriptEngine();
QScriptValue globalObject = engine->globalObject();
QJSValue globalObject = qmlEngine->globalObject();
globalObject.setProperty("findImage", engine->newFunction(findImage));
globalObject.setProperty("getSecondsOfQTime", engine->newFunction(getSecondsOfQTime));
globalObject.setProperty("getMinutesOfQTime", engine->newFunction(getMinutesOfQTime));
globalObject.setProperty("uuid", engine->newFunction(uuid));
globalObject.setProperty("strFormatter", engine->newQObject(new StringFormatter(), QScriptEngine::ScriptOwnership));
globalObject.setProperty("utils", qmlEngine->newQObject(new Utils()));
globalObject.setProperty("strFormatter", qmlEngine->newQObject(new StringFormatter()));
}
void Application::registerQmlTypes()
{
qmlRegisterType<QGraphicsDropShadowEffect>("Effects",1,0,"DropShadow");
qmlRegisterType<KeyboardLayout>("ktouch", 1, 0, "KeyboardLayout");
qmlRegisterType<AbstractKey>("ktouch", 1, 0, "AbstractKey");
qmlRegisterType<Key>("ktouch", 1, 0, "Key");
......@@ -117,8 +107,6 @@ void Application::registerQmlTypes()
qmlRegisterType<LearningProgressModel>("ktouch", 1, 0, "LearningProgressModel");
qmlRegisterType<ErrorsModel>("ktouch", 1, 0, "ErrorsModel");
qmlRegisterType<ApplicationBackground>("ktouch", 1, 0, "ApplicationBackground");
qmlRegisterType<CursorShapeArea>("ktouch", 1, 0 , "CursorShapeArea");
qmlRegisterType<GridItem>("ktouch", 1, 0 , "Grid");
qmlRegisterType<ScaleBackgroundItem>("ktouch", 1, 0, "ScaleBackgroundItem");
qmlRegisterType<LessonPainter>("ktouch", 1, 0, "LessonPainter");
......
......@@ -18,27 +18,26 @@
#ifndef APPLICATION_H
#define APPLICATION_H
#include <KApplication>
#include <QWeakPointer>
#include <QApplication>
#include <QSharedPointer>
#include "editor/resourceeditor.h"
class QDeclarativeEngine;
class QQmlEngine;
class DataIndex;
class Application : public KApplication
class Application : public QApplication
{
Q_OBJECT
public:
explicit Application();
Application(int& argc, char** argv, int flags = ApplicationFlags);
static DataIndex* dataIndex();
static void setupDeclarativeBindings(QDeclarativeEngine* declarativeEngine);
static QWeakPointer<ResourceEditor>& resourceEditorRef();
static void setupDeclarativeBindings(QQmlEngine* qmlEngine);
static QSharedPointer<ResourceEditor>& resourceEditorRef();
private:
void registerQmlTypes();
DataIndex* m_dataIndex;
QWeakPointer<ResourceEditor> m_resourceEditorRef;
QSharedPointer<ResourceEditor> m_resourceEditorRef;
};
#endif // APPLICATION_H
......@@ -17,103 +17,52 @@
#include "utils.h"
#include <QScriptContext>
#include <QTime>
#include <QUuid>
#include <QtDebug>
#include <QStandardPaths>
#include <KStandardDirs>
#include <KDebug>
QScriptValue findImage(QScriptContext *context, QScriptEngine *engine)
Utils::Utils(QObject* parent):
QObject(parent)
{
Q_UNUSED(engine);
if (context->argumentCount() == 0)
{
kWarning() << "got no arguments, expected one";
return QScriptValue("");
}
if (context->argumentCount() > 1)
{
kWarning() << "expected one argument, got more";
}
}
const QString imageName = context->argument(0).toString();
const QString relPath = QString("images/") + imageName;
const QString path = KGlobal::dirs()->findResource("appdata", relPath);
QString Utils::findImage(QString name)
{
const QString relPath = QString("images/") + name;
const QString path = QStandardPaths::locate(QStandardPaths::DataLocation, relPath);
if (path.isNull())
{
kWarning() << "can't find image resource:" << imageName;
qWarning() << "can't find image resource:" << name;
}
return QScriptValue(path);
return path;
}
QScriptValue getSecondsOfQTime(QScriptContext *context, QScriptEngine *engine)
int Utils::getMinutesOfQTime(const QTime& time)
{
Q_UNUSED(engine);
if (context->argumentCount() == 0)
{
kWarning() << "got no arguments, expected one";
return QScriptValue("");
}
if (context->argumentCount() > 1)
{
kWarning() << "expected one argument, got more";
}
const QTime time = context->argument(0).toVariant().toTime();
if (!time.isValid())
{
kWarning() << "invalid QTime passed";
return QScriptValue(0);
qWarning() << "invalid QTime passed";
return 0;
}
return QScriptValue(time.second());
return time.minute();
}
QScriptValue getMinutesOfQTime(QScriptContext *context, QScriptEngine *engine)
int Utils::getSecondsOfQTime(const QTime& time)
{
Q_UNUSED(engine);
if (context->argumentCount() == 0)
{
kWarning() << "got no arguments, expected one";
return QScriptValue("");
}
if (context->argumentCount() > 1)
{
kWarning() << "expected one argument, got more";
}
const QTime time = context->argument(0).toVariant().toTime();
if (!time.isValid())
{
kWarning() << "invalid QTime passed";
return QScriptValue(0);
qWarning() << "invalid QTime passed";
return 0;
}
return QScriptValue(time.minute());
return time.second();
}
QScriptValue uuid(QScriptContext *context, QScriptEngine *engine)
QString Utils::uuid()
{
Q_UNUSED(engine)
if (context->argumentCount() > 0)
{
kWarning() << "uuid() expects no arguments, got more";
}
const QString uuid = QUuid::createUuid().toString();
return QScriptValue(uuid);
return QUuid::createUuid().toString();
}
......@@ -18,16 +18,20 @@
#ifndef UTILS_H
#define UTILS_H
#include <QScriptValue>
#include <QObject>
#include <QTime>
class QScriptContext;
class QScriptEngine;
class Utils : public QObject
{
Q_OBJECT
public:
explicit Utils(QObject* parent = 0);
Q_INVOKABLE QString findImage(QString name);
Q_INVOKABLE int getMinutesOfQTime(const QTime& time);
Q_INVOKABLE int getSecondsOfQTime(const QTime& time);
Q_INVOKABLE QString uuid();
QScriptValue findImage(QScriptContext* context, QScriptEngine* engine);
};
QScriptValue getSecondsOfQTime(QScriptContext* context, QScriptEngine* engine);
QScriptValue getMinutesOfQTime(QScriptContext* context, QScriptEngine* engine);
QScriptValue uuid(QScriptContext* context, QScriptEngine* engine);
#endif // UTILS_H
......@@ -19,10 +19,6 @@
#include <QSignalMapper>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kdebug.h>
#include "lesson.h"
#include "dataindex.h"
......
......@@ -17,14 +17,15 @@
#include "dbaccess.h"
#include <QDebug>
#include <QUuid>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QStandardPaths>
#include <KLocalizedString>
#include <KStandardDirs>
#include <KDebug>
#include <KLocale>
DbAccess::DbAccess(QObject* parent) :
QObject(parent),
......@@ -41,12 +42,12 @@ QSqlDatabase DbAccess::database()
{
if (!QSqlDatabase::contains(QSqlDatabase::defaultConnection))
{
QString dbPath = KGlobal::dirs()->locateLocal("appdata", "profiles.db");
QString dbPath = QStandardPaths::locate(QStandardPaths::DataLocation, "profiles.db");
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(dbPath);
if (!db.open())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return db;
}
......@@ -79,7 +80,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -88,7 +89,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -115,20 +116,20 @@ bool DbAccess::checkDbSchema()
{
if (!db.transaction())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
db.exec("INSERT INTO metadata (key, value) VALUES ('version', '1.1')");
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
if (!db.commit())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -143,7 +144,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -161,7 +162,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -175,7 +176,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -190,7 +191,7 @@ bool DbAccess::checkDbSchema()
if (db.lastError().isValid())
{
kWarning() << db.lastError().text();
qWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
......@@ -204,7 +205,7 @@ bool DbAccess::checkDbSchema()