]> git.lyx.org Git - features.git/blob - src/frontends/qt4/InGuiThread.h
f27317f4c891b30541283a153e713d1671fea771
[features.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 "frontends/Application.h"
20 #include "support/bind.h"
21 #include "support/functional.h"
22
23 namespace lyx {
24 namespace frontend {
25
26
27 class IntoGuiThreadMover : public QObject
28 {
29         Q_OBJECT
30
31 protected:
32
33         IntoGuiThreadMover();
34
35         void callInGuiThread();
36
37 Q_SIGNALS:
38         void triggerFunctionCall();
39
40 private Q_SLOTS:
41         void doFunctionCall();
42
43 private:
44         virtual void synchronousFunctionCall() = 0;
45
46         QWaitCondition condition_;
47         QMutex sync_mutex_;
48 };
49
50
51 template<class R>
52 class InGuiThread : private IntoGuiThreadMover
53 {
54 public:
55
56         InGuiThread() {}
57
58         template<class F>
59         R call(F f)
60         {
61                 func_ = f;
62                 if (theApp() == 0)
63                         synchronousFunctionCall();
64                 else 
65                         callInGuiThread();
66                 return return_value_;
67         }
68
69         template<class F, class P1>
70         R call(F f, P1& p1)
71         {
72                 return call(bind(f, ref(p1)));
73         }
74
75         template<class F, class P1, class P2>
76         R call(F f, P1& p1, P2& p2)
77         {
78                 return call(bind(f, ref(p1), ref(p2)));
79         }
80
81         template<class F, class P1, class P2, class P3>
82         R call(F f, P1& p1, P2& p2, P3& p3)
83         {
84                 return call(bind(f, ref(p1), ref(p2), ref(p3)));
85         }
86
87         template<class F, class P1, class P2, class P3, class P4>
88         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
89         {
90                 return call(bind(f, ref(p1), ref(p2), ref(p3), ref(p4)));
91         }
92
93         /*
94           ...
95         */
96
97         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
98         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
99         {
100                 return call(bind(f, ref(p1), ref(p2), ref(p3), ref(p4), ref(p5), ref(p6), ref(p7), ref(p8)));
101         }
102
103 private:
104
105         void synchronousFunctionCall()
106         {
107                 return_value_ = func_();
108         }
109
110 private:
111         R return_value_;
112         function<R()> func_;
113 };
114
115
116 // void specialisation
117 template<>
118 class InGuiThread<void> : private IntoGuiThreadMover
119 {
120 public:
121
122         InGuiThread() {}
123
124         template<class F>
125         void call(F f)
126         {
127                 func_ = f;
128                 if (theApp() == 0)
129                         synchronousFunctionCall();
130                 else 
131                         callInGuiThread();
132         }
133
134         template<class F, class P1>
135         void call(F f, P1& p1)
136         {
137                 call(bind(f, ref(p1)));
138         }
139
140         template<class F, class P1, class P2>
141         void call(F f, P1& p1, P2& p2)
142         {
143                 call(bind(f, ref(p1), ref(p2)));
144         }
145
146         template<class F, class P1, class P2, class P3>
147         void call(F f, P1& p1, P2& p2, P3& p3)
148         {
149                 call(bind(f, ref(p1), ref(p2), ref(p3)));
150         }
151
152         template<class F, class P1, class P2, class P3, class P4>
153         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
154         {
155                 call(bind(f, ref(p1), ref(p2), ref(p3), ref(p4)));
156         }
157
158         /*
159           ...
160         */
161
162         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
163         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
164         {
165                 call(bind(f, ref(p1), ref(p2), ref(p3), ref(p4), ref(p5), ref(p6), ref(p7), ref(p8)));
166         }
167
168 private:
169
170         void synchronousFunctionCall()
171         {
172                 func_();
173         }
174
175 private:
176         function<void()> func_;
177 };
178
179
180 } // namespace frontend
181 } // namespace lyx
182
183 #endif // INGUITHREAD_H