aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Gottfried <sebastian.gottfried@posteo.de>2016-10-12 12:26:50 (GMT)
committerSebastian Gottfried <sebastian.gottfried@posteo.de>2016-10-12 12:26:50 (GMT)
commit0e9b3907861120f61bcb8cbd891e970c5738f2b2 (patch)
tree6631800f4565af8288a160f3fb92c6edfc410403
parentb51ab8575bf37e9fa6d7af272cd93845d3287c1f (diff)
Fix Crash On Exit
The QML engine deletes all parentless QObject it sees on shutdown. So we can't expose the main window directly to it. Move all QML interface code in to a dedicated class which is instantiated as a child object of the main window.
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/ktouchcontext.cpp202
-rw-r--r--src/ktouchcontext.h70
-rw-r--r--src/mainwindow.cpp164
-rw-r--r--src/mainwindow.h32
5 files changed, 279 insertions, 190 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d770f30..8cb3d39 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -81,6 +81,7 @@ set(ktouch_SRCS
trainingconfigwidget.cpp
colorsconfigwidget.cpp
customlessoneditordialog.cpp
+ ktouchcontext.cpp
)
# compile UI files
diff --git a/src/ktouchcontext.cpp b/src/ktouchcontext.cpp
new file mode 100644
index 0000000..3a03da1
--- /dev/null
+++ b/src/ktouchcontext.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2016 Sebastian Gottfried <sebastian.gottfried@posteo.de>
+ *
+ * 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 2 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/>.
+ */
+
+#include "ktouchcontext.h"
+
+#include <QMenu>
+#include <QPointer>
+#include <QDialogButtonBox>
+#include <QMenu>
+#include <QQuickWidget>
+
+#include "application.h"
+#include "colorsconfigwidget.h"
+#include "editor/resourceeditor.h"
+#include "customlessoneditordialog.h"
+#include "preferences.h"
+#include "trainingconfigwidget.h"
+
+#include <KActionCollection>
+#include <KStandardAction>
+#include <KHelpMenu>
+#include <KToggleFullScreenAction>
+#include <KShortcutsDialog>
+#include <KConfigDialog>
+#include <KCMultiDialog>
+#include <KLocalizedString>
+
+#ifdef KTOUCH_BUILD_WITH_X11
+#include "x11_helper.h"
+#else
+#include "keyboardlayoutmenu.h"
+#endif
+
+
+
+const QString keyboardKCMName = "kcm_keyboard";
+
+KTouchContext::KTouchContext(KMainWindow* mainWindow, QQuickWidget* view, QObject *parent) :
+ QObject(parent),
+ m_actionCollection(new KActionCollection(this)),
+ m_menu(new QMenu(mainWindow)),
+ m_mainWindow(mainWindow),
+ m_view(view)
+{
+#ifdef KTOUCH_BUILD_WITH_X11
+ m_XEventNotifier = new XEventNotifier();
+ m_XEventNotifier->start();
+ connect(m_XEventNotifier, SIGNAL(layoutChanged()), SIGNAL(keyboardLayoutNameChanged()));
+#else
+ m_keyboardLayoutMenu = new KeyboardLayoutMenu(this);
+ m_keyboardLayoutMenu->setDataIndex(Application::dataIndex());
+ connect(m_keyboardLayoutMenu, SIGNAL(keyboardLayoutNameChanged()), SIGNAL(keyboardLayoutNameChanged()));
+#endif
+ init();
+}
+
+KTouchContext::~KTouchContext()
+{
+#ifdef KTOUCH_BUILD_WITH_X11
+ m_XEventNotifier->stop();
+ delete m_XEventNotifier;
+#endif
+}
+
+QString KTouchContext::keyboardLayoutName() const
+{
+#ifdef KTOUCH_BUILD_WITH_X11
+ return X11Helper::getCurrentLayout().toString();
+#else
+ return m_keyboardLayoutMenu->keyboardLayoutName();
+#endif
+}
+
+DataIndex* KTouchContext::dataIndex()
+{
+ return Application::dataIndex();
+}
+
+void KTouchContext::showMenu(int xPos, int yPos)
+{
+ m_menu->popup(m_view->mapToGlobal(QPoint(xPos, yPos)));
+}
+
+void KTouchContext::showResourceEditor()
+{
+ QSharedPointer<ResourceEditor>& resourceEditorRef = Application::resourceEditorRef();
+ if (resourceEditorRef.isNull())
+ {
+ resourceEditorRef = QSharedPointer<ResourceEditor>(new ResourceEditor());
+ }
+
+ ResourceEditor* resourceEditor = resourceEditorRef.data();
+
+ resourceEditor->show();
+ resourceEditor->activateWindow();
+}
+
+bool KTouchContext::showCustomLessonDialog(Lesson* lesson, KeyboardLayout* keyboardLayout)
+{
+ CustomLessonEditorDialog* dialog = new CustomLessonEditorDialog(m_mainWindow);
+
+ dialog->setLesson(lesson);
+ dialog->setKeyboardLayout(keyboardLayout);
+
+ bool result = dialog->exec() == QDialog::Accepted;
+
+ delete dialog;
+
+ return result;
+}
+
+void KTouchContext::showConfigDialog()
+{
+ if (KConfigDialog::showDialog("preferences"))
+ {
+ return;
+ }
+
+ KConfigDialog* dialog = new KConfigDialog(m_mainWindow, "preferences", Preferences::self());
+ dialog->setFaceType(KPageDialog::List);
+ dialog->setModal(true);
+ dialog->addPage(new TrainingConfigWidget(), i18n("Training"), "chronometer", i18n("Training Settings"));
+ dialog->addPage(new ColorsConfigWidget(), i18n("Colors"), "preferences-desktop-color", i18n("Color Settings"));
+ dialog->show();
+}
+
+void KTouchContext::configureShortcuts()
+{
+ KShortcutsDialog::configure(m_actionCollection, KShortcutsEditor::LetterShortcutsDisallowed, m_mainWindow);
+}
+
+void KTouchContext::configureKeyboard()
+{
+ QPointer<KCMultiDialog> kcm = new KCMultiDialog(m_mainWindow);
+
+ kcm->setWindowTitle(i18n("Configure Keyboard"));
+ kcm->addModule(keyboardKCMName);
+ kcm->exec();
+
+ delete kcm;
+}
+
+void KTouchContext::setFullscreen(bool fullScreen)
+{
+ KToggleFullScreenAction::setFullScreen(m_mainWindow, fullScreen);
+}
+
+void KTouchContext::init()
+{
+ m_actionCollection->addAssociatedWidget(m_mainWindow);
+ m_menu->addAction(KStandardAction::fullScreen(this, SLOT(setFullscreen(bool)), m_mainWindow, m_actionCollection));
+ m_menu->addSeparator();
+ QAction* editorAction = new QAction(i18n("Course and Keyboard Layout Editor..."), this);
+ connect(editorAction, &QAction::triggered, this, &KTouchContext::showResourceEditor);
+ m_actionCollection->addAction("editor", editorAction);
+ m_menu->addAction(editorAction);
+ m_menu->addSeparator();
+ m_menu->addAction(KStandardAction::preferences(this, SLOT(showConfigDialog()), m_actionCollection));
+ m_menu->addAction(KStandardAction::keyBindings(this, SLOT(configureShortcuts()), m_actionCollection));
+
+
+#ifdef KTOUCH_BUILD_WITH_X11
+ if (testKCMAvailibility(keyboardKCMName))
+ {
+ QAction* configureKeyboardAction = new QAction(i18n("Configure Keyboard..."), this);
+ m_menu->addAction(configureKeyboardAction);
+ connect(configureKeyboardAction, &QAction::triggered, this, &KTouchContext::configureKeyboard);
+ }
+#else
+ m_menu->addMenu(m_keyboardLayoutMenu);
+#endif
+
+ m_menu->addSeparator();
+ KHelpMenu* helpMenu = new KHelpMenu(m_mainWindow);
+ m_menu->addMenu(helpMenu->menu());
+}
+
+bool KTouchContext::testKCMAvailibility(const QString& name)
+{
+ KService::Ptr service = KService::serviceByStorageId(name + ".desktop");
+
+ if (!service)
+ {
+ return false;
+ }
+
+ return service->hasServiceType("KCModule") && !service->noDisplay();
+}
diff --git a/src/ktouchcontext.h b/src/ktouchcontext.h
new file mode 100644
index 0000000..ac99b2d
--- /dev/null
+++ b/src/ktouchcontext.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Sebastian Gottfried <sebastian.gottfried@posteo.de>
+ *
+ * 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 2 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/>.
+ */
+
+#ifndef KTOUCHCONTEXT_H
+#define KTOUCHCONTEXT_H
+
+#include <QObject>
+
+class QMenu;
+class QQuickWidget;
+
+class KActionCollection;
+class KMainWindow;
+
+class DataIndex;
+class KeyboardLayout;
+class KeyboardLayoutMenu;
+class Lesson;
+class XEventNotifier;
+
+class KTouchContext : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString keyboardLayoutName READ keyboardLayoutName NOTIFY keyboardLayoutNameChanged)
+ Q_PROPERTY(DataIndex* globalDataIndex READ dataIndex CONSTANT)
+public:
+ explicit KTouchContext(KMainWindow* mainWindow, QQuickWidget* view, QObject* parent = 0);
+ ~KTouchContext();
+ QString keyboardLayoutName() const;
+ DataIndex* dataIndex();
+ Q_INVOKABLE void showMenu(int xPos, int yPos);
+public slots:
+ void showResourceEditor();
+ bool showCustomLessonDialog(Lesson* lesson, KeyboardLayout* keyboardLayout);
+private slots:
+ void showConfigDialog();
+ void configureShortcuts();
+ void configureKeyboard();
+ void setFullscreen(bool fullscreen);
+signals:
+ void keyboardLayoutNameChanged();
+private:
+ void init();
+ bool testKCMAvailibility(const QString& name);
+ KActionCollection* m_actionCollection;
+ QMenu* m_menu;
+ KMainWindow* m_mainWindow;
+ QQuickWidget* m_view;
+#ifdef KTOUCH_BUILD_WITH_X11
+ XEventNotifier* m_XEventNotifier;
+#else
+ KeyboardLayoutMenu* m_keyboardLayoutMenu;
+#endif
+};
+
+#endif // KTOUCHCONTEXT_H
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index aff8c7b..6bd6cc0 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -18,195 +18,37 @@
#include "mainwindow.h"
#include <QQuickWidget>
-#include <QMenu>
-#include <QPointer>
#include <QVariant>
-#include <QDialogButtonBox>
#include <QStandardPaths>
-#include <QMenu>
#include <QQmlContext>
-#include <KActionCollection>
-#include <KStandardAction>
-#include <KHelpMenu>
-#include <KToggleFullScreenAction>
-#include <KShortcutsDialog>
-#include <KConfigDialog>
-#include <KCMultiDialog>
#include <KLocalizedString>
-#include "editor/resourceeditor.h"
#include "application.h"
-#include "preferences.h"
-#include "trainingconfigwidget.h"
-#include "colorsconfigwidget.h"
-#include "customlessoneditordialog.h"
-
-#ifdef KTOUCH_BUILD_WITH_X11
-#include "x11_helper.h"
-#else
-#include "keyboardlayoutmenu.h"
-#endif
-
-
-const QString keyboardKCMName = "kcm_keyboard";
+#include "ktouchcontext.h"
MainWindow::MainWindow(QWidget* parent):
KMainWindow(parent),
m_view(new QQuickWidget(this)),
- m_actionCollection(new KActionCollection(this)),
- m_menu(new QMenu(this))
+ m_context(new KTouchContext(this, m_view, this))
{
-#ifdef KTOUCH_BUILD_WITH_X11
- m_XEventNotifier = new XEventNotifier();
- m_XEventNotifier->start();
- connect(m_XEventNotifier, SIGNAL(layoutChanged()), SIGNAL(keyboardLayoutNameChanged()));
-#else
- m_keyboardLayoutMenu = new KeyboardLayoutMenu(this);
- m_keyboardLayoutMenu->setDataIndex(Application::dataIndex());
- connect(m_keyboardLayoutMenu, SIGNAL(keyboardLayoutNameChanged()), SIGNAL(keyboardLayoutNameChanged()));
-#endif
init();
}
MainWindow::~MainWindow()
{
-#ifdef KTOUCH_BUILD_WITH_X11
- m_XEventNotifier->stop();
- delete m_XEventNotifier;
-#endif
-}
-
-QString MainWindow::keyboardLayoutName() const
-{
-#ifdef KTOUCH_BUILD_WITH_X11
- return X11Helper::getCurrentLayout().toString();
-#else
- return m_keyboardLayoutMenu->keyboardLayoutName();
-#endif
-}
-
-DataIndex *MainWindow::dataIndex()
-{
- return Application::dataIndex();
-}
-
-void MainWindow::showMenu(int xPos, int yPos)
-{
- m_menu->popup(m_view->mapToGlobal(QPoint(xPos, yPos)));
-}
-
-void MainWindow::showResourceEditor()
-{
- QSharedPointer<ResourceEditor>& resourceEditorRef = Application::resourceEditorRef();
- if (resourceEditorRef.isNull())
- {
- resourceEditorRef = QSharedPointer<ResourceEditor>(new ResourceEditor());
- }
-
- ResourceEditor* resourceEditor = resourceEditorRef.data();
-
- resourceEditor->show();
- resourceEditor->activateWindow();
-}
-
-bool MainWindow::showCustomLessonDialog(Lesson* lesson, KeyboardLayout* keyboardLayout)
-{
- CustomLessonEditorDialog* dialog = new CustomLessonEditorDialog(this);
-
- dialog->setLesson(lesson);
- dialog->setKeyboardLayout(keyboardLayout);
-
- bool result = dialog->exec() == QDialog::Accepted;
-
- delete dialog;
-
- return result;
-}
-
-void MainWindow::showConfigDialog()
-{
- if (KConfigDialog::showDialog("preferences"))
- {
- return;
- }
-
- KConfigDialog* dialog = new KConfigDialog(this, "preferences", Preferences::self());
- dialog->setFaceType(KPageDialog::List);
- dialog->setModal(true);
- dialog->addPage(new TrainingConfigWidget(), i18n("Training"), "chronometer", i18n("Training Settings"));
- dialog->addPage(new ColorsConfigWidget(), i18n("Colors"), "preferences-desktop-color", i18n("Color Settings"));
- dialog->show();
-}
-
-void MainWindow::configureShortcuts()
-{
- KShortcutsDialog::configure(m_actionCollection, KShortcutsEditor::LetterShortcutsDisallowed, this);
}
-void MainWindow::configureKeyboard()
-{
- QPointer<KCMultiDialog> kcm = new KCMultiDialog(this);
-
- kcm->setWindowTitle(i18n("Configure Keyboard"));
- kcm->addModule(keyboardKCMName);
- kcm->exec();
-
- delete kcm;
-}
-
-void MainWindow::setFullscreen(bool fullScreen)
-{
- KToggleFullScreenAction::setFullScreen(this, fullScreen);
-}
void MainWindow::init()
{
- m_actionCollection->addAssociatedWidget(this);
- m_menu->addAction(KStandardAction::fullScreen(this, SLOT(setFullscreen(bool)), this, m_actionCollection));
- m_menu->addSeparator();
- QAction* editorAction = new QAction(i18n("Course and Keyboard Layout Editor..."), this);
- connect(editorAction, &QAction::triggered, this, &MainWindow::showResourceEditor);
- m_actionCollection->addAction("editor", editorAction);
- m_menu->addAction(editorAction);
- m_menu->addSeparator();
- m_menu->addAction(KStandardAction::preferences(this, SLOT(showConfigDialog()), m_actionCollection));
- m_menu->addAction(KStandardAction::keyBindings(this, SLOT(configureShortcuts()), m_actionCollection));
-
-
-#ifdef KTOUCH_BUILD_WITH_X11
- if (testKCMAvailibility(keyboardKCMName))
- {
- QAction* configureKeyboardAction = new QAction(i18n("Configure Keyboard..."), this);
- m_menu->addAction(configureKeyboardAction);
- connect(configureKeyboardAction, &QAction::triggered, this, &MainWindow::configureKeyboard);
- }
-#else
- m_menu->addMenu(m_keyboardLayoutMenu);
-#endif
-
- m_menu->addSeparator();
- KHelpMenu* helpMenu = new KHelpMenu(this);
- m_menu->addMenu(helpMenu->menu());
setCentralWidget(m_view);
Application::setupDeclarativeBindings(m_view->engine());
m_view->setMinimumSize(1000, 700);
- m_view->rootContext()->setContextProperty(QStringLiteral("ktouch"), this);
+ m_view->rootContext()->setContextProperty(QStringLiteral("ktouch"), m_context);
m_view->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_view->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::DataLocation, "qml/main.qml")));
}
-
-bool MainWindow::testKCMAvailibility(const QString& name)
-{
- KService::Ptr service = KService::serviceByStorageId(name + ".desktop");
-
- if (!service)
- {
- return false;
- }
-
- return service->hasServiceType("KCModule") && !service->noDisplay();
-}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index feccd96..797d268 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -23,12 +23,8 @@
#include <QWeakPointer>
class QQuickWidget;
-class QMenu;
-class KActionCollection;
-class DataIndex;
-class ResourceEditor;
-class KeyboardLayout;
-class Lesson;
+
+class KTouchContext;
#ifdef KTOUCH_BUILD_WITH_X11
class XEventNotifier;
@@ -39,35 +35,13 @@ class KeyboardLayoutMenu;
class MainWindow : public KMainWindow
{
Q_OBJECT
- Q_PROPERTY(QString keyboardLayoutName READ keyboardLayoutName NOTIFY keyboardLayoutNameChanged)
- Q_PROPERTY(DataIndex* globalDataIndex READ dataIndex CONSTANT)
public:
explicit MainWindow(QWidget* parent = 0);
~MainWindow();
- QString keyboardLayoutName() const;
- DataIndex* dataIndex();
- Q_INVOKABLE void showMenu(int xPos, int yPos);
-public slots:
- void showResourceEditor();
- bool showCustomLessonDialog(Lesson* lesson, KeyboardLayout* keyboardLayout);
-signals:
- void keyboardLayoutNameChanged();
-private slots:
- void showConfigDialog();
- void configureShortcuts();
- void configureKeyboard();
- void setFullscreen(bool fullscreen);
private:
void init();
- bool testKCMAvailibility(const QString& name);
QQuickWidget* m_view;
- KActionCollection* m_actionCollection;
- QMenu* m_menu;
-#ifdef KTOUCH_BUILD_WITH_X11
- XEventNotifier* m_XEventNotifier;
-#else
- KeyboardLayoutMenu* m_keyboardLayoutMenu;
-#endif
+ KTouchContext* m_context;
};
#endif // MAINWINDOW_H