]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/InGuiThread.h
QDialogButtonBox for the remaining dialogs.
[lyx.git] / src / frontends / qt4 / InGuiThread.h
1 // -*- C++ -*-
2 /**
3  * \file InGuiThread.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Peter Kümmel
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef INGUITHREAD_H
13 #define INGUITHREAD_H
14
15 #include <QMutex>
16 #include <QObject>
17 #include <QWaitCondition>
18
19 #include "support/bind.h"
20 #include "support/functional.h"
21
22 namespace lyx {
23 namespace frontend {
24
25
26 class IntoGuiThreadMover : public QObject
27 {
28         Q_OBJECT
29
30 protected:
31
32         IntoGuiThreadMover();
33
34         void callInGuiThread();
35
36 Q_SIGNALS:
37         void triggerFunctionCall();
38
39 private Q_SLOTS:
40         void doFunctionCall();
41
42 private:
43         virtual void synchronousFunctionCall() = 0;
44
45         QWaitCondition condition_;
46         QMutex sync_mutex_;
47 };
48
49
50 template<class R>
51 class InGuiThread : private IntoGuiThreadMover
52 {
53 public:
54
55         // please coverity by explicitly initalizing this variable.
56         InGuiThread() : return_value_(R()) {}
57
58         template<class F>
59         R call(F f)
60         {
61                 func_ = f;
62                 callInGuiThread();
63                 return return_value_;
64         }
65
66         template<class F, class P1>
67         R call(F f, P1& p1)
68         {
69                 return call(lyx::bind(f, lyx::ref(p1)));
70         }
71
72         template<class F, class P1, class P2>
73         R call(F f, P1& p1, P2& p2)
74         {
75                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2)));
76         }
77
78         template<class F, class P1, class P2, class P3>
79         R call(F f, P1& p1, P2& p2, P3& p3)
80         {
81                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3)));
82         }
83
84         template<class F, class P1, class P2, class P3, class P4>
85         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
86         {
87                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4)));
88         }
89
90         /*
91           ...
92         */
93
94         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
95         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
96         {
97                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4),
98                         lyx::ref(p5), lyx::ref(p6), lyx::ref(p7), lyx::ref(p8)));
99         }
100
101 private:
102
103         void synchronousFunctionCall()
104         {
105                 return_value_ = func_();
106         }
107
108 private:
109         R return_value_;
110         function<R()> func_;
111 };
112
113
114 // void specialisation
115 template<>
116 class InGuiThread<void> : private IntoGuiThreadMover
117 {
118 public:
119
120         InGuiThread() {}
121
122         template<class F>
123         void call(F f)
124         {
125                 func_ = f;
126                 callInGuiThread();
127         }
128
129         template<class F, class P1>
130         void call(F f, P1& p1)
131         {
132                 call(lyx::bind(f, lyx::ref(p1)));
133         }
134
135         template<class F, class P1, class P2>
136         void call(F f, P1& p1, P2& p2)
137         {
138                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2)));
139         }
140
141         template<class F, class P1, class P2, class P3>
142         void call(F f, P1& p1, P2& p2, P3& p3)
143         {
144                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3)));
145         }
146
147         template<class F, class P1, class P2, class P3, class P4>
148         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
149         {
150                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4)));
151         }
152
153         /*
154           ...
155         */
156
157         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
158         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
159         {
160                 call(bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4), lyx::ref(p5),
161                         lyx::ref(p6), lyx::ref(p7), lyx::ref(p8)));
162         }
163
164 private:
165
166         void synchronousFunctionCall()
167         {
168                 func_();
169         }
170
171 private:
172         function<void()> func_;
173 };
174
175
176 } // namespace frontend
177 } // namespace lyx
178
179 #endif // INGUITHREAD_H