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