]> git.lyx.org Git - lyx.git/blob - src/frontends/Dialogs.C
fix bug 1879
[lyx.git] / src / frontends / Dialogs.C
1 /**
2  * \file frontends/Dialogs.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  *
10  * Common to all frontends' Dialogs
11  */
12
13 #include <config.h>
14
15 #include "Dialogs.h"
16
17 #include "controllers/Dialog.h"
18
19 #include <boost/signal.hpp>
20 #include <boost/bind.hpp>
21
22
23 using std::string;
24 using lyx::frontend::Dialog;
25
26
27 // Note that static boost signals break some compilers, so this wrapper
28 // initialises the signal dynamically when it is first invoked.
29 template<typename Signal>
30 class BugfixSignal {
31 public:
32         Signal & operator()() { return thesignal(); }
33         Signal const & operator()() const { return thesignal(); }
34
35 private:
36         Signal & thesignal() const
37         {
38                 if (!signal_.get())
39                         signal_.reset(new Signal);
40                 return *signal_;
41         }
42
43         mutable boost::scoped_ptr<Signal> signal_;
44 };
45
46
47 boost::signal<void()> & Dialogs::redrawGUI()
48 {
49         static BugfixSignal<boost::signal<void()> > thesignal;
50         return thesignal();
51 }
52
53
54 namespace {
55
56 BugfixSignal<boost::signal<void(string const &, InsetBase*)> > hideSignal;
57
58 }
59
60
61 void Dialogs::hide(string const & name, InsetBase* inset)
62 {
63         hideSignal()(name, inset);
64 }
65
66
67 Dialogs::Dialogs(LyXView & lyxview)
68         : lyxview_(lyxview), in_show_(false)
69 {
70         // Connect signals
71         redrawGUI().connect(boost::bind(&Dialogs::redraw, this));
72         hideSignal().connect(boost::bind(&Dialogs::hideSlot, this, _1, _2));
73 }
74
75
76 Dialog * Dialogs::find_or_build(string const & name)
77 {
78         if (!isValidName(name))
79                 return 0;
80
81         std::map<string, DialogPtr>::iterator it =
82                 dialogs_.find(name);
83
84         if (it != dialogs_.end())
85                 return it->second.get();
86
87         dialogs_[name] = build(name);
88         return dialogs_[name].get();
89 }
90
91
92 void Dialogs::show(string const & name, string const & data)
93 {
94         if (in_show_) {
95                 return;
96         }
97         in_show_ = true;
98         Dialog * dialog = find_or_build(name);
99         if (dialog) {
100                 // FIXME! Should check that the dialog is NOT an inset dialog.
101                 dialog->show(data);
102         }
103         in_show_ = false;
104 }
105
106
107 void Dialogs::show(string const & name, string const & data, InsetBase * inset)
108 {
109         if (in_show_) {
110                 return;
111         }
112         in_show_ = true;
113         Dialog * dialog = find_or_build(name);
114         if (dialog) {
115                 // FIXME! Should check that the dialog IS an inset dialog.
116                 dialog->show(data);
117                 open_insets_[name] = inset;
118         }
119         in_show_ = false;
120 }
121
122
123 bool Dialogs::visible(string const & name) const
124 {
125         std::map<string, DialogPtr>::const_iterator it =
126                 dialogs_.find(name);
127         if (it == dialogs_.end())
128                 return false;
129         return it->second.get()->isVisible();
130 }
131
132
133 void Dialogs::update(string const & name, string const & data)
134 {
135         std::map<string, DialogPtr>::const_iterator it =
136                 dialogs_.find(name);
137         if (it == dialogs_.end())
138                 return;
139
140         Dialog * const dialog = it->second.get();
141         if (dialog->isVisible())
142                 dialog->update(data);
143 }
144
145
146 void Dialogs::hideSlot(string const & name, InsetBase * inset)
147 {
148         std::map<string, DialogPtr>::const_iterator it =
149                 dialogs_.find(name);
150         if (it == dialogs_.end())
151                 return;
152
153         if (inset && inset != getOpenInset(name))
154                 return;
155
156         Dialog * const dialog = it->second.get();
157         if (dialog->isVisible())
158                 dialog->hide();
159         open_insets_[name] = 0;
160 }
161
162
163 void Dialogs::disconnect(string const & name)
164 {
165         if (!isValidName(name))
166                 return;
167
168         open_insets_[name] = 0;
169 }
170
171
172 InsetBase * Dialogs::getOpenInset(string const & name) const
173 {
174         if (!isValidName(name))
175                 return 0;
176
177         std::map<string, InsetBase *>::const_iterator it =
178                 open_insets_.find(name);
179         return it == open_insets_.end() ? 0 : it->second;
180 }
181
182
183 void Dialogs::hideAll() const
184 {
185         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
186         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
187
188         for(; it != end; ++it) {
189                 it->second->hide();
190         }
191 }
192
193
194 void Dialogs::hideBufferDependent() const
195 {
196         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
197         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
198
199         for(; it != end; ++it) {
200                 Dialog * dialog =  it->second.get();
201                 if (dialog->controller().isBufferDependent())
202                         dialog->hide();
203         }
204 }
205
206
207 void Dialogs::updateBufferDependent(bool switched) const
208 {
209         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
210         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
211
212         for(; it != end; ++it) {
213                 Dialog * dialog =  it->second.get();
214                 if (switched && dialog->controller().isBufferDependent()) {
215                         dialog->hide();
216                 } else {
217                         // A bit clunky, but the dialog will request
218                         // that the kernel provides it with the necessary
219                         // data.
220                         dialog->RestoreButton();
221                 }
222         }
223 }
224
225
226 void Dialogs::redraw() const
227 {
228         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
229         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
230
231         for(; it != end; ++it) {
232                 it->second->redraw();
233         }
234 }
235
236
237 void Dialogs::checkStatus()
238 {
239         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
240         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
241
242         for(; it != end; ++it) {
243                 Dialog * const dialog = it->second.get();
244                 if (dialog->isVisible())
245                         dialog->checkStatus();
246         }
247 }