summaryrefslogtreecommitdiffstats
path: root/src/MainWindow.h
blob: c493b5b2523f77c98545f2464dbc3b20a9661637 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <functional>

#include <QHash>
#include <QQuickView>
#include <QSharedPointer>
#include <QSystemTrayIcon>

#include "UserSettingsPage.h"
#include "dock/Dock.h"

class ChatPage;
class RegisterPage;
class WelcomePage;

class TrayIcon;
class UserSettings;
class MxcImageProvider;

namespace mtx {
namespace requests {
struct CreateRoom;
}
}

namespace dialogs {
class CreateRoom;
class InviteUsers;
class MemberList;
}

class NhekoFixupPaletteEventFilter final : public QObject
{
    Q_OBJECT

public:
    NhekoFixupPaletteEventFilter(QObject *parent)
      : QObject(parent)
    {
    }

    bool eventFilter(QObject *obj, QEvent *event) override;
};

class MainWindow : public QQuickView
{
    Q_OBJECT
    QML_ELEMENT
    QML_SINGLETON

public:
    explicit MainWindow(QWindow *parent);

    static MainWindow *instance() { return instance_; }
    static MainWindow *create(QQmlEngine *qmlEngine, QJSEngine *)
    {
        // The instance has to exist before it is used. We cannot replace it.
        Q_ASSERT(instance_);

        // The engine has to have the same thread affinity as the singleton.
        Q_ASSERT(qmlEngine->thread() == instance_->thread());

        // There can only be one engine accessing the singleton.
        static QJSEngine *s_engine = nullptr;
        if (s_engine)
            Q_ASSERT(qmlEngine == s_engine);
        else
            s_engine = qmlEngine;

        QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
        return instance_;
    }

    void saveCurrentWindowSize();

    void openJoinRoomDialog(std::function<void(const QString &room_id)> callback);

    MxcImageProvider *imageProvider() { return imgProvider; }

    //! Show the chat page and start communicating with the given access token.
    void showChatPage();

#ifdef NHEKO_DBUS_SYS
    bool dbusAvailable() const { return dbusAvailable_; }
#endif

    Q_INVOKABLE void addPerRoomWindow(const QString &room, QWindow *window);
    Q_INVOKABLE void removePerRoomWindow(const QString &room, QWindow *window);
    QWindow *windowForRoom(const QString &room);
    QString focusedRoom() const;

protected:
    void closeEvent(QCloseEvent *event) override;
    // HACK: https://bugreports.qt.io/browse/QTBUG-83972, qtwayland cannot auto hide menu
    void mousePressEvent(QMouseEvent *) override;

private slots:
    //! Handle interaction with the tray icon.
    void iconActivated(QSystemTrayIcon::ActivationReason reason);

    virtual void setWindowTitle(int notificationCount);

signals:
    // HACK: https://bugreports.qt.io/browse/QTBUG-83972, qtwayland cannot auto hide menu
    void hideMenu();
    void reload();
    void secretsChanged();

    void showNotification(QString msg);

    void switchToChatPage();
    void switchToWelcomePage();
    void switchToLoginPage(QString error);

private:
    void showDialog(QWidget *dialog);
    bool hasActiveUser();
    void restoreWindowSize();
    //! Check if the current page supports the "minimize to tray" functionality.
    bool pageSupportsTray() const;

    void registerQmlTypes();

    static MainWindow *instance_;

    //! The initial welcome screen.
    WelcomePage *welcome_page_;
    //! The register page.
    RegisterPage *register_page_;
    //! The main chat area.
    ChatPage *chat_page_;
    QSharedPointer<UserSettings> userSettings_;
    //! Tray icon that shows the unread message count.
    TrayIcon *trayIcon_;
    Dock *dock_;

    MxcImageProvider *imgProvider = nullptr;

    QMultiHash<QString, QWindow *> roomWindows_;

#ifdef NHEKO_DBUS_SYS
    bool dbusAvailable_{false};
#endif
};