]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/Dialog.cpp
fix scrolling bug: 3320 and 3652, maybe not perfect
[lyx.git] / src / frontends / controllers / Dialog.cpp
1 /**
2  * \file Dialog.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
11 #include <config.h>
12
13 #include "Dialog.h"
14
15 #include "ButtonController.h"
16 #include "BCView.h"
17
18 #include "frontends/LyXView.h"
19
20 #include "FuncRequest.h"
21 #include "FuncStatus.h"
22 #include "LyXFunc.h"
23
24
25 using std::string;
26
27 namespace lyx {
28 namespace frontend {
29
30 Dialog::Dialog(LyXView & lv, string const & name)
31         : is_closing_(false), kernel_(lv), name_(name),
32           bc_ptr_(new ButtonController)
33 {}
34
35
36 void Dialog::ApplyButton()
37 {
38         apply();
39         bc().apply();
40 }
41
42
43 void Dialog::OKButton()
44 {
45         is_closing_ = true;
46         apply();
47         is_closing_ = false;
48         hide();
49         bc().ok();
50 }
51
52
53 void Dialog::CancelButton()
54 {
55         hide();
56         bc().cancel();
57 }
58
59
60 void Dialog::RestoreButton()
61 {
62         // Tell the kernel that a request to refresh the dialog's contents
63         // has been received. It's up to the kernel to supply the necessary
64         // info by calling Dialog::update().
65         kernel().updateDialog(name_);
66         bc().restore();
67 }
68
69
70 void Dialog::show(string const & data)
71 {
72         if (controller().isBufferDependent() && !kernel().isBufferAvailable())
73                 return;
74
75         if (!controller().initialiseParams(data)) {
76                 lyxerr << "Dialog \"" << name_
77                        << "\" failed to translate the data "
78                         "string passed to show()" << std::endl;
79                 return;
80         }
81
82         bc().readOnly(kernel().isBufferReadonly());
83         view().show();
84
85         // The widgets may not be valid, so refresh the button controller
86         bc().refresh();
87 }
88
89
90 void Dialog::update(string const & data)
91 {
92         if (controller().isBufferDependent() && !kernel().isBufferAvailable())
93                 return;
94
95         if (!controller().initialiseParams(data)) {
96                 lyxerr << "Dialog \"" << name_
97                        << "\" could not be initialized" << std::endl;
98                 return;
99         }
100
101         bc().readOnly(kernel().isBufferReadonly());
102         view().update();
103
104         // The widgets may not be valid, so refresh the button controller
105         bc().refresh();
106 }
107
108
109 void Dialog::hide()
110 {
111         if (!view().isVisible())
112                 return;
113
114         controller().clearParams();
115         view().hide();
116         kernel().disconnect(name());
117 }
118
119
120 void Dialog::apply()
121 {
122         if (controller().isBufferDependent()) {
123                 if (!kernel().isBufferAvailable() ||
124                     kernel().isBufferReadonly())
125                         return;
126         }
127
128         view().apply();
129         controller().dispatchParams();
130
131         if (controller().disconnectOnApply() && !is_closing_) {
132                 kernel().disconnect(name());
133                 controller().initialiseParams(string());
134                 view().update();
135         }
136 }
137
138
139 bool Dialog::isVisible() const
140 {
141         return view().isVisible();
142 }
143
144
145 void Dialog::redraw()
146 {
147         view().redraw();
148 }
149
150
151 ButtonController & Dialog::bc() const
152 {
153         BOOST_ASSERT(bc_ptr_.get());
154         return *bc_ptr_.get();
155 }
156
157
158 void Dialog::setController(Controller * i)
159 {
160         BOOST_ASSERT(i && !controller_ptr_.get());
161         controller_ptr_.reset(i);
162 }
163
164
165 void Dialog::setView(View * v)
166 {
167         BOOST_ASSERT(v && !view_ptr_.get());
168         view_ptr_.reset(v);
169 }
170
171
172 void Dialog::checkStatus()
173 {
174         // buffer independant dialogs are always active.
175         // This check allows us leave canApply unimplemented for some dialogs.
176         if (!controller().isBufferDependent())
177                 return;
178
179         // deactivate the dialog if we have no buffer
180         if (!kernel().isBufferAvailable()) {
181                 bc().readOnly(true);
182                 return;
183         }
184
185         // check whether this dialog may be active
186         if (controller().canApply()) {
187                 bool const readonly = kernel().isBufferReadonly();
188                 bc().readOnly(readonly);
189                 // refreshReadOnly() is too generous in _enabling_ widgets
190                 // update dialog to disable disabled widgets again
191                 if (!readonly)
192                         view().update();
193         } else
194                 bc().readOnly(true);
195 }
196
197
198 Dialog::Controller::Controller(Dialog & parent)
199         : parent_(parent)
200 {}
201
202
203 bool Dialog::Controller::canApply() const
204 {
205         FuncRequest const fr(getLfun(), dialog().name());
206         FuncStatus const fs(getStatus(fr));
207         return fs.enabled();
208 }
209
210
211 Dialog::Controller & Dialog::controller() const
212 {
213         BOOST_ASSERT(controller_ptr_.get());
214         return *controller_ptr_.get();
215 }
216
217
218 Dialog::View::View(Dialog & parent, docstring title) :
219         p_(parent), title_(title)
220 {}
221
222
223 Dialog::View & Dialog::view() const
224 {
225         BOOST_ASSERT(view_ptr_.get());
226         return *view_ptr_.get();
227 }
228
229
230 void Dialog::View::setTitle(docstring const & newtitle)
231 {
232         title_ = newtitle;
233 }
234
235
236 docstring const & Dialog::View::getTitle() const
237 {
238         return title_;
239 }
240
241
242 void Dialog::View::partialUpdate(int)
243 {}
244
245 } // namespace frontend
246 } // namespace lyx