]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
allow derived classes to manipulate signal connections
[lyx.git] / src / frontends / xforms / FormRef.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 2000 The LyX Team.
8  *
9  * ======================================================
10  */
11
12 #include <config.h>
13
14 #include FORMS_H_LOCATION
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif
19
20
21 #include "gettext.h"
22 #include "Dialogs.h"
23 #include "FormRef.h"
24 #include "LyXView.h"
25 #include "buffer.h"
26 #include "form_ref.h"
27 #include "lyxfunc.h"
28
29 #include <algorithm>
30
31 using std::sort;
32 using std::vector;
33
34 static int formw;
35 static int formh;
36
37 FormRef::FormRef(LyXView * lv, Dialogs * d)
38         : FormCommand(lv, d, _("Reference")), toggle(GOBACK), dialog_(0)
39 {
40         // let the dialog be shown
41         // These are permanent connections so we won't bother
42         // storing a copy because we won't be disconnecting.
43         d->showRef.connect(slot(this, &FormRef::showInset));
44         d->createRef.connect(slot(this, &FormRef::createInset));
45 }
46
47
48 FormRef::~FormRef()
49 {
50         delete dialog_;
51 }
52
53
54 void FormRef::clearStore()
55 {
56         refs.clear();
57 }
58
59
60 void FormRef::build()
61 {
62         dialog_ = build_ref();
63
64         fl_addto_choice(dialog_->type,
65                         _(" Ref | Page | TextRef | TextPage | PrettyRef "));
66
67         // XFORMS bug workaround
68         // Define the min/max dimensions. Actually applied in update()
69         formw = form()->w, formh = form()->h;
70
71         // Name is irrelevant to LaTeX documents
72         if( lv_->buffer()->isLatex() ) {
73                 fl_deactivate_object( dialog_->name );
74                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
75         }
76           
77         // Can change reference only through browser
78         fl_deactivate_object( dialog_->ref );
79
80         if( lv_->buffer()->isReadonly() ) {
81                 fl_deactivate_object( dialog_->type );
82                 fl_deactivate_object( dialog_->ok );
83                 fl_set_object_lcol( dialog_->ok, FL_INACTIVE );
84         } else {
85                 fl_activate_object( dialog_->type );
86                 fl_activate_object( dialog_->ok );
87                 fl_set_object_lcol( dialog_->ok, FL_BLACK );
88         }
89 }
90
91
92 FL_FORM * const FormRef::form() const
93 {
94         if ( dialog_ ) // no need to test for dialog_->form_ref
95                 return dialog_->form;
96         else
97                 return 0;
98 }
99
100
101 void FormRef::update()
102 {
103         fl_set_input(dialog_->ref,  params.getContents().c_str());
104         fl_set_input(dialog_->name, params.getOptions().c_str());
105
106         Type type = getType();
107         fl_set_choice( dialog_->type, type+1 );
108
109         toggle = GOBACK;
110         fl_set_object_label(dialog_->go, _("Goto reference"));
111
112         refs.clear();
113         if( inset_ == 0 ) {
114                 refs = lv_->buffer()->getLabelList();
115                 updateBrowser( refs );
116                 showBrowser();
117         } else
118                 hideBrowser();
119 }
120
121
122 void FormRef::updateBrowser( vector<string> keys ) const
123 {
124         if( fl_get_button( dialog_->sort ) )
125                 sort( keys.begin(), keys.end() );
126
127         fl_clear_browser( dialog_->browser );
128         for( vector<string>::const_iterator it = keys.begin();
129              it != keys.end(); ++it )
130                 fl_add_browser_line( dialog_->browser, (*it).c_str());
131
132         if( keys.empty() ) {
133                 fl_add_browser_line( dialog_->browser,
134                                      _("*** No labels found in document ***"));
135
136                 fl_deactivate_object( dialog_->browser );
137                 fl_deactivate_object( dialog_->update );
138                 fl_deactivate_object( dialog_->sort );
139                 fl_set_object_lcol( dialog_->browser, FL_INACTIVE );
140                 fl_set_object_lcol( dialog_->update, FL_INACTIVE );
141                 fl_set_object_lcol( dialog_->sort, FL_INACTIVE );
142         } else {
143                 fl_set_browser_topline( dialog_->browser, 1 );
144                 fl_activate_object( dialog_->browser );
145                 fl_set_object_lcol( dialog_->browser, FL_BLACK );
146                 fl_activate_object( dialog_->update );
147                 fl_set_object_lcol( dialog_->update, FL_BLACK );
148                 fl_activate_object( dialog_->sort );
149                 fl_set_object_lcol( dialog_->sort, FL_BLACK );
150         }
151 }
152
153
154 void FormRef::showBrowser() const
155 {
156         fl_show_object( dialog_->browser );
157         fl_show_object( dialog_->update );
158         fl_show_object( dialog_->sort );
159
160         setSize( formw, formh, 0 );
161
162         fl_deactivate_object( dialog_->type );
163         fl_set_object_lcol( dialog_->type, FL_INACTIVE );
164         fl_deactivate_object( dialog_->go );
165         fl_set_object_lcol( dialog_->go, FL_INACTIVE );
166         fl_deactivate_object( dialog_->ok );
167         fl_set_object_lcol( dialog_->ok, FL_INACTIVE );
168         fl_set_object_lcol( dialog_->ref, FL_INACTIVE );
169 }
170
171
172 void FormRef::hideBrowser() const
173 {
174         fl_hide_object( dialog_->browser );
175         fl_hide_object( dialog_->update );
176         fl_hide_object( dialog_->sort );
177
178         setSize( 250, formh, 280 );
179
180         fl_activate_object( dialog_->type );
181         fl_set_object_lcol( dialog_->type, FL_BLACK );
182         fl_activate_object( dialog_->go );
183         fl_set_object_lcol( dialog_->go, FL_BLACK );
184         fl_deactivate_object( dialog_->ok );
185         fl_set_object_lcol( dialog_->ok, FL_INACTIVE );
186         fl_set_object_lcol( dialog_->ref, FL_BLACK );
187 }
188
189
190 void FormRef::setSize( int w, int h, int dx ) const
191 {
192         static int x1 = dialog_->name->x;
193         static int y1 = dialog_->name->y;
194         static int x2 = dialog_->ref->x;
195         static int y2 = dialog_->ref->y;
196         static int x3 = dialog_->type->x;
197         static int y3 = dialog_->type->y;
198         static int x4 = dialog_->go->x;
199         static int y4 = dialog_->go->y;
200         static int x5 = dialog_->ok->x;
201         static int y5 = dialog_->ok->y;
202         static int x6 = dialog_->cancel->x;
203         static int y6 = dialog_->cancel->y;
204
205         if( form()->w != w )
206                 fl_set_form_size( form(), w, h );
207
208         fl_set_form_minsize( form(), w, h );
209         fl_set_form_maxsize( form(), 2*w, h );
210
211         if( form()->w == w ) return;
212
213         fl_set_object_position( dialog_->name,   x1-dx, y1 );
214         fl_set_object_position( dialog_->ref,    x2-dx, y2 );
215         fl_set_object_position( dialog_->type,   x3-dx, y3 );
216         fl_set_object_position( dialog_->go,     x4-dx, y4 );
217         fl_set_object_position( dialog_->ok,     x5-dx, y5 );
218         fl_set_object_position( dialog_->cancel, x6-dx, y6 );
219
220         // These two must be reset apparently
221         // Name is irrelevant to LaTeX documents
222         if( lv_->buffer()->isLatex() ) {
223                 fl_deactivate_object( dialog_->name );
224                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
225         }
226           
227         // Can change reference only through browser
228         fl_deactivate_object( dialog_->ref );
229 }
230
231
232 void FormRef::apply()
233 {
234         if (!lv_->view()->available())
235                 return;
236
237         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
238         params.setCmdName(getName(type));
239
240         params.setOptions(fl_get_input(dialog_->name));
241
242         if (inset_ != 0) {
243                 // Only update if contents have changed
244                 if(params != inset_->params()) {
245                         inset_->setParams(params);
246                         lv_->view()->updateInset(inset_, true);
247                 }
248         } else {
249                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
250                                             params.getAsString());
251         }
252 }
253
254
255 void FormRef::input( long data )
256 {
257         switch( data ) {
258         // goto reference / go back
259         case 1:
260         {
261                 toggle = static_cast<Goto>(toggle + 1);
262                 if( toggle == GOFIRST ) toggle = GOREF;
263         
264                 switch (toggle) {
265                 case GOREF:
266                 {
267                         lv_->getLyXFunc()->
268                                 Dispatch(LFUN_REF_GOTO,
269                                          params.getContents());
270                         fl_set_object_label(dialog_->go, _("Go back"));
271                 }
272                 break;
273
274                 case GOBACK:
275                 {
276                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
277                         fl_set_object_label(dialog_->go, _("Goto reference"));
278                 }
279                 break;
280
281                 default:
282                         break;
283                 }
284         }
285         break;
286
287         // choose browser key
288         case 2:
289         {
290                 unsigned int sel = fl_get_browser( dialog_->browser );
291                 if( sel < 1 || sel > refs.size() ) break;
292
293                 string s = fl_get_browser_line( dialog_->browser, sel );
294                 fl_set_input( dialog_->ref, s.c_str());
295                 params.setContents( s );
296
297                 toggle = GOBACK;
298                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
299                 fl_set_object_label(dialog_->go, _("Goto reference"));
300
301                 fl_activate_object( dialog_->type );
302                 fl_set_object_lcol( dialog_->type, FL_BLACK );
303                 fl_activate_object( dialog_->go );
304                 fl_set_object_lcol( dialog_->go, FL_BLACK );
305                 fl_activate_object( dialog_->ok );
306                 fl_set_object_lcol( dialog_->ok, FL_BLACK );
307                 fl_set_object_lcol( dialog_->ref, FL_BLACK );
308         }
309         break;
310
311         // update or sort
312         case 3:
313         {
314                 fl_freeze_form( form() );
315                 updateBrowser( refs );
316                 fl_unfreeze_form( form() );
317         }
318         break;
319
320         // changed reference type
321         case 4:
322         {
323                 Type type = static_cast<Type>( fl_get_choice(dialog_->type)-1 );
324                 if( params.getCmdName() != getName( type ) ) {
325                         fl_activate_object( dialog_->ok );
326                         fl_set_object_lcol( dialog_->ok, FL_BLACK );
327                 } else if( inset_ != 0 ) {
328                         fl_deactivate_object( dialog_->ok );
329                         fl_set_object_lcol( dialog_->ok, FL_INACTIVE );
330                 }
331         }
332         break;
333
334         default:
335                 break;
336         }
337 }
338
339
340 FormRef::Type FormRef::getType() const
341 {
342         Type type;
343
344         if( params.getCmdName() == "ref" )
345                 type = REF;
346
347         else if( params.getCmdName() == "pageref" )
348                 type = PAGEREF;
349
350         else if( params.getCmdName() == "vref" )
351                 type = VREF;
352
353         else if( params.getCmdName() == "vpageref" )
354                 type = VPAGEREF;
355
356         else
357                 type = PRETTYREF;
358         
359         return type;
360 }
361
362
363 string FormRef::getName( Type type ) const
364 {
365         string name;
366
367         switch( type ) {
368         case REF:
369                 name = "ref";
370                 break;
371         case PAGEREF:
372                 name = "pageref";
373                 break;
374         case VREF:
375                 name = "vref";
376                 break;
377         case VPAGEREF:
378                 name = "vpageref";
379                 break;
380         case PRETTYREF:
381                 name = "prettyref";
382                 break;
383         }
384         
385         return name;
386 }