FreeCAD

Форк
0
/
WaitCursor.cpp 
191 строка · 5.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23

24
#include "PreCompiled.h"
25

26
#ifndef _PreComp_
27
# include <QApplication>
28
# include <QMessageBox>
29
# include <QProgressDialog>
30
# include <QWindow>
31
# ifdef FC_OS_WIN32
32
#   include <windows.h>
33
# endif
34
#endif
35

36
#include "WaitCursor.h"
37

38
using namespace Gui;
39

40
namespace Gui {
41
class WaitCursorP : public QObject
42
{
43
public:
44
    static WaitCursorP* getInstance();
45
    void setBusy(bool);
46
    WaitCursor::FilterEventsFlags ignoreEvents() const;
47
    void setIgnoreEvents(WaitCursor::FilterEventsFlags flags);
48

49
protected:
50
    bool eventFilter(QObject*, QEvent*) override;
51
    bool isModalDialog(QObject* o) const;
52

53
private:
54
    WaitCursorP(); // Disable constructor
55
    static WaitCursorP* _instance;
56
    bool isOn{false};
57
    WaitCursor::FilterEventsFlags flags{WaitCursor::AllEvents};
58
};
59
} // namespace Gui
60

61
WaitCursorP* WaitCursorP::_instance = nullptr;
62

63
WaitCursorP::WaitCursorP() : QObject(nullptr)
64
{
65
}
66

67
WaitCursorP* WaitCursorP::getInstance()
68
{
69
    if (!_instance)
70
        _instance = new WaitCursorP();
71
    return _instance;
72
}
73

74
void WaitCursorP::setBusy(bool on)
75
{
76
    if (on == this->isOn)
77
        return;
78

79
    if (on) {
80
        qApp->installEventFilter(this);
81
        QApplication::setOverrideCursor(Qt::WaitCursor);
82
    }
83
    else {
84
        qApp->removeEventFilter(this);
85
        QApplication::restoreOverrideCursor();
86
    }
87

88
    this->isOn = on;
89
}
90

91
WaitCursor::FilterEventsFlags WaitCursorP::ignoreEvents() const
92
{
93
    return this->flags;
94
}
95

96
void WaitCursorP::setIgnoreEvents(WaitCursor::FilterEventsFlags flags)
97
{
98
    this->flags = flags;
99
}
100

101
bool WaitCursorP::isModalDialog(QObject* o) const
102
{
103
    QWidget* parent = qobject_cast<QWidget*>(o);
104
    if (!parent) {
105
        QWindow* window = qobject_cast<QWindow*>(o);
106
        if (window)
107
            parent = QWidget::find(window->winId());
108
    }
109
    while (parent) {
110
        auto dlg = qobject_cast<QMessageBox*>(parent);
111
        if (dlg && dlg->isModal())
112
            return true;
113
        auto pd = qobject_cast<QProgressDialog*>(parent);
114
        if (pd)
115
            return true;
116
        parent = parent->parentWidget();
117
    }
118

119
    return false;
120
}
121

122
bool WaitCursorP::eventFilter(QObject* o, QEvent* e)
123
{
124
    // Note: This might cause problems when we want to open a modal dialog at the lifetime
125
    // of a WaitCursor instance because the incoming events are still filtered.
126
    if (e->type() == QEvent::KeyPress ||
127
        e->type() == QEvent::KeyRelease) {
128
        if (isModalDialog(o))
129
            return false;
130
        if (this->flags & WaitCursor::KeyEvents)
131
            return true;
132
    }
133
    if (e->type() == QEvent::MouseButtonPress ||
134
        e->type() == QEvent::MouseButtonRelease ||
135
        e->type() == QEvent::MouseButtonDblClick) {
136
        if (isModalDialog(o))
137
            return false;
138
        if (this->flags & WaitCursor::MouseEvents)
139
            return true;
140
    }
141
    return false;
142
}
143

144
int WaitCursor::instances = 0;
145

146
/**
147
 * Constructs this object and shows the wait cursor immediately. If you need to open a dialog as
148
 * long as an instance of WaitCursor exists you must call restoreCursor() before and setWaitCursor()
149
 * afterwards because all key events and mouse button events are filtered, otherwise you will run
150
 * into strange behaviour.
151
 */
152
WaitCursor::WaitCursor()
153
{
154
    if (instances++ == 0)
155
        setWaitCursor();
156
    filter = WaitCursorP::getInstance()->ignoreEvents();
157
}
158

159
/** Restores the last cursor again. */
160
WaitCursor::~WaitCursor()
161
{
162
    if (--instances == 0)
163
        restoreCursor();
164
    WaitCursorP::getInstance()->setIgnoreEvents(filter);
165
}
166

167
/**
168
 * Sets the wait cursor if needed.
169
 */
170
void WaitCursor::setWaitCursor()
171
{
172
    WaitCursorP::getInstance()->setBusy(true);
173
}
174

175
/**
176
 * Restores the last cursor if needed.
177
 */
178
void WaitCursor::restoreCursor()
179
{
180
    WaitCursorP::getInstance()->setBusy(false);
181
}
182

183
WaitCursor::FilterEventsFlags WaitCursor::ignoreEvents() const
184
{
185
    return WaitCursorP::getInstance()->ignoreEvents();
186
}
187

188
void WaitCursor::setIgnoreEvents(FilterEventsFlags flags)
189
{
190
    WaitCursorP::getInstance()->setIgnoreEvents(flags);
191
}
192

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.