]> git.lyx.org Git - lyx.git/blob - src/frontends/Dialogs.cpp
35d4e013d72574b089c637e4a79b656ccaa5f44d
[lyx.git] / src / frontends / Dialogs.cpp
1 /**
2  * \file frontends/Dialogs.cpp
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 "callback.h"
18
19 #include "controllers/Dialog.h"
20
21 #include <boost/signal.hpp>
22 #include <boost/bind.hpp>
23
24
25 namespace lyx {
26
27
28 using std::string;
29 using lyx::frontend::Dialog;
30
31
32 // Note that static boost signals break some compilers, so this wrapper
33 // initialises the signal dynamically when it is first invoked.
34 template<typename Signal>
35 class BugfixSignal {
36 public:
37         Signal & operator()() { return thesignal(); }
38         Signal const & operator()() const { return thesignal(); }
39
40 private:
41         Signal & thesignal() const
42         {
43                 if (!signal_.get())
44                         signal_.reset(new Signal);
45                 return *signal_;
46         }
47
48         mutable boost::scoped_ptr<Signal> signal_;
49 };
50
51
52 namespace {
53
54 BugfixSignal<boost::signal<void(string const &, Inset*)> > hideSignal;
55
56 }
57
58
59 void Dialogs::hide(string const & name, Inset* inset)
60 {
61         // Don't send the signal if we are quitting, because on MSVC it is
62         // destructed before the cut stack in CutAndPaste.cpp, and this method
63         // is called from some inset destructor if the cut stack is not empty
64         // on exit.
65         if (!quitting)
66                 hideSignal()(name, inset);
67 }
68
69
70 Dialogs::Dialogs(LyXView & lyxview)
71         : lyxview_(lyxview), in_show_(false)
72 {
73         // Connect signals
74         hideSignal().connect(boost::bind(&Dialogs::hideSlot, this, _1, _2));
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] = build(name);
90         return dialogs_[name].get();
91 }
92
93
94 void Dialogs::show(string const & name, string const & data)
95 {
96         if (in_show_) {
97                 return;
98         }
99         in_show_ = true;
100         Dialog * dialog = find_or_build(name);
101         if (dialog) {
102                 // FIXME! Should check that the dialog is NOT an inset dialog.
103                 dialog->show(data);
104         }
105         in_show_ = false;
106 }
107
108
109 void Dialogs::show(string const & name, string const & data, Inset * inset)
110 {
111         if (in_show_) {
112                 return;
113         }
114         in_show_ = true;
115         Dialog * dialog = find_or_build(name);
116         if (dialog) {
117                 // FIXME! Should check that the dialog IS an inset dialog.
118                 dialog->show(data);
119                 open_insets_[name] = inset;
120         }
121         in_show_ = false;
122 }
123
124
125 bool Dialogs::visible(string const & name) const
126 {
127         std::map<string, DialogPtr>::const_iterator it =
128                 dialogs_.find(name);
129         if (it == dialogs_.end())
130                 return false;
131         return it->second.get()->isVisible();
132 }
133
134
135 void Dialogs::update(string const & name, string const & data)
136 {
137         std::map<string, DialogPtr>::const_iterator it =
138                 dialogs_.find(name);
139         if (it == dialogs_.end())
140                 return;
141
142         Dialog * const dialog = it->second.get();
143         if (dialog->isVisible())
144                 dialog->update(data);
145 }
146
147
148 void Dialogs::hideSlot(string const & name, Inset * inset)
149 {
150         std::map<string, DialogPtr>::const_iterator it =
151                 dialogs_.find(name);
152         if (it == dialogs_.end())
153                 return;
154
155         if (inset && inset != getOpenInset(name))
156                 return;
157
158         Dialog * const dialog = it->second.get();
159         if (dialog->isVisible())
160                 dialog->hide();
161         open_insets_[name] = 0;
162 }
163
164
165 void Dialogs::disconnect(string const & name)
166 {
167         if (!isValidName(name))
168                 return;
169
170         if (open_insets_.find(name) != open_insets_.end())
171                 open_insets_[name] = 0;
172 }
173
174
175 Inset * Dialogs::getOpenInset(string const & name) const
176 {
177         if (!isValidName(name))
178                 return 0;
179
180         std::map<string, Inset *>::const_iterator it =
181                 open_insets_.find(name);
182         return it == open_insets_.end() ? 0 : it->second;
183 }
184
185
186 void Dialogs::hideAll() const
187 {
188         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
189         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
190
191         for(; it != end; ++it) {
192                 it->second->hide();
193         }
194 }
195
196
197 void Dialogs::hideBufferDependent() const
198 {
199         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
200         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
201
202         for(; it != end; ++it) {
203                 Dialog * dialog =  it->second.get();
204                 if (dialog->controller().isBufferDependent())
205                         dialog->hide();
206         }
207 }
208
209
210 void Dialogs::updateBufferDependent(bool switched) const
211 {
212         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
213         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
214
215         for(; it != end; ++it) {
216                 Dialog * dialog =  it->second.get();
217                 if (switched && dialog->controller().isBufferDependent()) {
218                         if (dialog->isVisible() && dialog->controller().initialiseParams(""))
219                                 dialog->view().update();
220                         else
221                                 dialog->hide();
222                 } else {
223                         // A bit clunky, but the dialog will request
224                         // that the kernel provides it with the necessary
225                         // data.
226                         dialog->RestoreButton();
227                 }
228         }
229 }
230
231
232 void Dialogs::redraw() const
233 {
234         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
235         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
236
237         for(; it != end; ++it) {
238                 it->second->redraw();
239         }
240 }
241
242
243 void Dialogs::checkStatus()
244 {
245         std::map<string, DialogPtr>::const_iterator it  = dialogs_.begin();
246         std::map<string, DialogPtr>::const_iterator end = dialogs_.end();
247
248         for(; it != end; ++it) {
249                 Dialog * const dialog = it->second.get();
250                 if (dialog->isVisible())
251                         dialog->checkStatus();
252         }
253 }
254
255
256 } // namespace lyx