]> git.lyx.org Git - lyx.git/blob - src/frontends/Dialogs.C
Don't build a dialog prior to hiding it...
[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/signals/signal2.hpp>
20 #include <boost/bind.hpp>
21
22
23 // Note that static boost signals break some compilers, so this wrapper
24 // initialises the signal dynamically when it is first invoked.
25 template<typename Signal>
26 class BugfixSignal {
27 public:
28         Signal & operator()() { return thesignal(); }
29         Signal const & operator()() const { return thesignal(); }
30
31 private:
32         Signal & thesignal() const
33         {
34                 if (!signal_.get())
35                         signal_.reset(new Signal);
36                 return *signal_;
37         }
38
39         mutable boost::scoped_ptr<Signal> signal_;
40 };
41
42
43 boost::signal0<void> & Dialogs::redrawGUI()
44 {
45         static BugfixSignal<boost::signal0<void> > thesignal;
46         return thesignal();
47 }
48
49
50 namespace {
51
52 BugfixSignal<boost::signal2<void, string const &, InsetBase*> > hideSignal;
53
54 }
55
56
57 void Dialogs::hide(string const & name, InsetBase* inset)
58 {
59         hideSignal()(name, inset);
60 }
61
62
63 Dialogs::Dialogs(LyXView & lyxview)
64         : lyxview_(lyxview)
65 {
66         // Connect signals
67         redrawGUI().connect(boost::bind(&Dialogs::redraw, this));
68         hideSignal().connect(boost::bind(&Dialogs::hideSlot, this, _1, _2));
69
70         // All this is slated to go
71         init_pimpl();
72         // reduce the number of connections needed in
73         // dialogs by a simple connection here.
74         hideAllSignal.connect(hideBufferDependentSignal);
75 }
76
77
78 Dialog * Dialogs::find_or_build(string const & name)
79 {
80         if (!isValidName(name))
81                 return 0;
82
83         std::map<string, DialogPtr>::iterator it =
84                 dialogs_.find(name);
85
86         if (it != dialogs_.end())
87                 return it->second.get();
88
89         dialogs_[name] = DialogPtr(build(name));
90         return dialogs_[name].get();
91 }
92
93
94 void Dialogs::show(string const & name, string const & data)
95 {
96         Dialog * dialog = find_or_build(name);
97         if (!dialog)
98                 return;
99
100         // FIXME! Should check that the dialog is NOT an inset dialog.
101         dialog->show(data);
102 }
103
104
105 void Dialogs::show(string const & name, string const & data, InsetBase * inset)
106 {
107         Dialog * dialog = find_or_build(name);
108         if (!dialog)
109                 return;
110
111         // FIXME! Should check that the dialog IS an inset dialog.
112         dialog->show(data);
113         open_insets_[name] = inset;
114 }
115
116
117 bool Dialogs::visible(string const & name) const
118 {
119         std::map<string, DialogPtr>::const_iterator it =
120                 dialogs_.find(name);
121         if (it == dialogs_.end())
122                 return false;
123         return it->second.get()->isVisible();
124 }
125
126
127 void Dialogs::update(string const & name, string const & data)
128 {
129         std::map<string, DialogPtr>::const_iterator it =
130                 dialogs_.find(name);
131         if (it == dialogs_.end())
132                 return;
133
134         Dialog * const dialog = it->second.get();
135         if (dialog->isVisible())
136                 dialog->update(data);
137 }
138
139
140 void Dialogs::hideSlot(string const & name, InsetBase * inset)
141 {
142         std::map<string, DialogPtr>::const_iterator it =
143                 dialogs_.find(name);
144         if (it == dialogs_.end())
145                 return;
146
147         if (inset && inset != getOpenInset(name))
148                 return;
149
150         Dialog * const dialog = it->second.get();
151         if (dialog->isVisible())
152                 dialog->hide();
153         open_insets_[name] = 0;
154 }
155
156
157 void Dialogs::disconnect(string const & name)
158 {
159         if (!isValidName(name))
160                 return;
161
162         open_insets_[name] = 0;
163 }
164
165
166 InsetBase * Dialogs::getOpenInset(string const & name) const
167 {
168         if (!isValidName(name))
169                 return 0;
170
171         std::map<string, InsetBase *>::const_iterator it =
172                 open_insets_.find(name);
173         return it == open_insets_.end() ? 0 : it->second;
174 }
175
176
177 void Dialogs::hideAll() const
178 {
179         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
180         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
181
182         for(; it != end; ++it) {
183                 it->second->hide();
184         }
185         hideAllSignal();
186 }
187
188
189 void Dialogs::hideBufferDependent() const
190 {
191         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
192         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
193
194         for(; it != end; ++it) {
195                 Dialog * dialog =  it->second.get();
196                 if (dialog->controller().isBufferDependent())
197                         dialog->hide();
198         }
199         hideBufferDependentSignal();
200 }
201
202
203 void Dialogs::updateBufferDependent(bool switched) const
204 {
205         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
206         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
207
208         for(; it != end; ++it) {
209                 Dialog * dialog =  it->second.get();
210                 if (switched && dialog->controller().isBufferDependent()) {
211                         dialog->hide();
212                 } else {
213                         // A bit clunky, but the dialog will request
214                         // that the kernel provides it with the necessary
215                         // data.
216                         dialog->RestoreButton();
217                 }
218         }
219         updateBufferDependentSignal(switched);
220 }
221
222
223 void Dialogs::redraw() const
224 {
225         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
226         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
227
228         for(; it != end; ++it) {
229                 it->second->redraw();
230         }
231 }