]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlInset.h
bug 183
[lyx.git] / src / frontends / controllers / ControlInset.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 2001 The LyX Team.
8  *
9  * ======================================================
10  *
11  * \file ControlInsets.h
12  * \author Angus Leeming <a.leeming@ic.ac.uk>
13  *
14  * ControlInset is to be used as a parent class for dialogs that display and
15  * can perhaps modify the contents of an individual inset. An example being the
16  * ubiquitous Citation dialog.
17  */
18
19 #ifndef CONTROLINSET_H
20 #define CONTROLINSET_H
21
22 #include "support/LAssert.h"
23 #include "debug.h" 
24 #include "ControlConnections.h"
25
26 class Inset;
27
28 template <class Inset, class Params>
29 class ControlInset : public ControlConnectBD
30 {
31 public:
32         ///
33         ControlInset(LyXView &, Dialogs &);
34         /// Allow the View access to the local copy.
35         Params & params();
36         ///
37         Params const & params() const;
38
39 protected:
40         /// Slots connected in the daughter classes c-tor.
41         /// Slot launching dialog to (possibly) create a new inset.
42         void createInset(string const &);
43         /// Slot launching dialog to an existing inset.
44         void showInset(Inset *);
45         /// Allow the daughter methods to access the inset.
46         Inset * inset() const;
47
48 private:
49         /** These 7 methods are all that the individual daughter classes
50             should need to instantiate. */
51
52         /// if the inset exists then do this...
53         virtual void applyParamsToInset() = 0;
54         /// else this...
55         virtual void applyParamsNoInset() = 0;
56
57         /// get the parameters from the string passed to createInset.
58         virtual Params const getParams(string const &) = 0;
59         /// get the parameters from the inset passed to showInset.
60         virtual Params const getParams(Inset const &) = 0;
61
62         /** Most derived classes won't need these two, so they default to empty.
63          */
64
65         /// set any daughter class-particular data on show().
66         virtual void setDaughterParams() {}
67         /// clean-up any daughter class-particular data on hide().
68         virtual void clearDaughterParams() {}
69
70         /** Some dialogs may find it beneficial to disconnect from the inset
71          when the Apply button is pressed. E.g., doing this with the citation
72          dialog allows multiple citiations to be inserted easily. */
73         virtual bool disconnectOnApply() { return false; }
74
75
76         
77         /// Instantiation of ControlButtons virtual methods.
78
79         /// Get changed parameters and Dispatch them to the kernel.
80         virtual void apply();
81         /// Disconnect signals and hide View.
82         virtual void hide();
83         /// Update the dialog.
84         virtual void update();
85
86         /** Instantiation of ControlConnectBD private virtual method.
87             Slot connected to update signal. */
88         virtual void updateSlot(bool);
89
90         /// Show the dialog.
91         void show(Params const &);
92         /// Connect signals
93         void connectInset(Inset * = 0);
94
95         /// pointer to the inset passed through connectInset
96         Inset * inset_; 
97         /// inset::hide connection.
98         SigC::Connection ih_;
99         /** A local copy of the inset's params.
100             Memory is allocated only whilst the dialog is visible.
101         */
102         Params * params_;
103
104         /// is the dialog built ?
105         bool dialog_built_;
106  
107 };
108
109
110 template <class Inset, class Params>
111 ControlInset<Inset, Params>::ControlInset(LyXView & lv, Dialogs & d)
112         : ControlConnectBD(lv, d),
113           inset_(0), ih_(0), params_(0), dialog_built_(false)
114 {}
115
116
117 template <class Inset, class Params>
118 void ControlInset<Inset, Params>::showInset(Inset * inset)
119 {
120         if (inset == 0) return;  // maybe we should Assert this?
121
122         connectInset(inset);
123         show(getParams(*inset));
124 }
125
126
127 template <class Inset, class Params>
128 void ControlInset<Inset, Params>::createInset(string const & arg)
129 {
130         connectInset();
131
132         if (!arg.empty())
133                 bc().valid(); // so that the user can press Ok
134
135         show(getParams(arg));
136 }
137
138
139 template <class Inset, class Params>
140 void ControlInset<Inset, Params>::show(Params const & params)
141 {
142         if (params_) delete params_;
143         params_ = new Params(params);
144
145         setDaughterParams();
146         if (emergency_exit_) {
147                 hide();
148                 return;
149         }
150
151         if (!dialog_built_) {
152                 view().build();
153                 dialog_built_ = true;
154         }
155
156         bc().readOnly(isReadonly());
157         view().show();
158 }
159
160
161 template <class Inset, class Params>
162 void ControlInset<Inset, Params>::hide()
163 {
164         emergency_exit_ = false;
165         if (params_) {
166                 delete params_;
167                 params_ = 0;
168         }
169         inset_ = 0;
170
171         clearDaughterParams();
172
173         ih_.disconnect();
174         disconnect();
175         view().hide();
176 }
177
178
179 template <class Inset, class Params>
180 void ControlInset<Inset, Params>::update()
181 {
182         if (params_) delete params_;
183
184         if (inset_)
185                 params_ = new Params(getParams(*inset_));
186         else
187                 params_ = new Params();
188
189         if (emergency_exit_) {
190                 hide();
191                 return;
192         }
193
194         bc().readOnly(isReadonly());
195         view().update();
196 }
197
198
199 template <class Inset, class Params>
200 void ControlInset<Inset, Params>::apply()
201 {
202         if (lv_.buffer()->isReadonly())
203                 return;
204
205         view().apply();
206
207         if (inset_ && params() != getParams(*inset_))
208                 applyParamsToInset();
209         else
210                 applyParamsNoInset();
211
212         if (disconnectOnApply() && !isClosing()) {
213                 *params_ = getParams(string());
214                 inset_ = 0;
215                 ih_.disconnect();
216
217                 view().update();
218         }
219 }
220
221
222 template <class Inset, class Params>
223 Params & ControlInset<Inset, Params>::params()
224 {
225         lyx::Assert(params_);
226         return *params_;
227 }
228
229
230 template <class Inset, class Params>
231 Params  const & ControlInset<Inset, Params>::params() const
232 {
233         lyx::Assert(params_);
234         return *params_;
235 }
236
237
238 template <class Inset, class Params>
239 Inset * ControlInset<Inset, Params>::inset() const
240 {
241         lyx::Assert(inset_);
242         return inset_;
243 }
244
245
246 template <class Inset, class Params>
247 void ControlInset<Inset, Params>::updateSlot(bool switched)
248 {
249         if (switched)
250                 hide();
251         else
252                 update();
253 }
254
255
256 template <class Inset, class Params>
257 void ControlInset<Inset, Params>::connectInset(Inset * inset)
258 {
259         // If connected to another inset, disconnect from it.
260         if (inset_) {
261                 ih_.disconnect();
262                 inset_ = 0;
263         }
264
265         if (inset) {
266                 inset_ = inset;
267                 ih_ = inset->hideDialog.connect(
268                         SigC::slot(this, &ControlInset::hide));
269         }
270         connect();
271 }
272 #endif // CONTROLINSET_H