]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlInset.h
The reference dialog now disconnects from the inset on Apply. Its behaviour
[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
147         if (!dialog_built_) {
148                 view().build();
149                 dialog_built_ = true;
150         }
151
152         bc().readOnly(isReadonly());
153         view().show();
154 }
155
156
157 template <class Inset, class Params>
158 void ControlInset<Inset, Params>::hide()
159 {
160         if (params_) {
161                 delete params_;
162                 params_ = 0;
163         }
164         inset_ = 0;
165
166         clearDaughterParams();
167
168         ih_.disconnect();
169         disconnect();
170         view().hide();
171 }
172
173
174 template <class Inset, class Params>
175 void ControlInset<Inset, Params>::update()
176 {
177         if (params_) delete params_;
178
179         if (inset_)
180                 params_ = new Params(getParams(*inset_));
181         else
182                 params_ = new Params();
183
184         bc().readOnly(isReadonly());
185         view().update();
186 }
187
188
189 template <class Inset, class Params>
190 void ControlInset<Inset, Params>::apply()
191 {
192         if (lv_.buffer()->isReadonly())
193                 return;
194
195         view().apply();
196
197         if (inset_ && params() != getParams(*inset_))
198                 applyParamsToInset();
199         else
200                 applyParamsNoInset();
201
202         if (disconnectOnApply() && !isClosing()) {
203                 *params_ = getParams(string());
204                 inset_ = 0;
205                 ih_.disconnect();
206
207                 view().update();
208         }
209 }
210
211
212 template <class Inset, class Params>
213 Params & ControlInset<Inset, Params>::params()
214 {
215         lyx::Assert(params_);
216         return *params_;
217 }
218
219
220 template <class Inset, class Params>
221 Params  const & ControlInset<Inset, Params>::params() const
222 {
223         lyx::Assert(params_);
224         return *params_;
225 }
226
227
228 template <class Inset, class Params>
229 Inset * ControlInset<Inset, Params>::inset() const
230 {
231         lyx::Assert(inset_);
232         return inset_;
233 }
234
235
236 template <class Inset, class Params>
237 void ControlInset<Inset, Params>::updateSlot(bool switched)
238 {
239         if (switched)
240                 hide();
241         else
242                 update();
243 }
244
245
246 template <class Inset, class Params>
247 void ControlInset<Inset, Params>::connectInset(Inset * inset)
248 {
249         // If connected to another inset, disconnect from it.
250         if (inset_) {
251                 ih_.disconnect();
252                 inset_ = 0;
253         }
254
255         if (inset) {
256                 inset_ = inset;
257                 ih_ = inset->hideDialog.connect(
258                         SigC::slot(this, &ControlInset::hide));
259         }
260         connect();
261 }
262 #endif // CONTROLINSET_H