]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
FormBase extends its reach into the codebase and gains a ButtonController
[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 "Dialogs.h"
22 #include "FormRef.h"
23 #include "LyXView.h"
24 #include "buffer.h"
25 #include "form_ref.h"
26 #include "lyxfunc.h"
27
28 #include <algorithm>
29
30 using std::sort;
31 using std::vector;
32
33 static int formw;
34 static int formh;
35
36 FormRef::FormRef(LyXView * lv, Dialogs * d)
37         : FormCommand(lv, d, _("Reference")), toggle(GOBACK), dialog_(0)
38 {
39         // let the dialog be shown
40         // These are permanent connections so we won't bother
41         // storing a copy because we won't be disconnecting.
42         d->showRef.connect(slot(this, &FormRef::showInset));
43         d->createRef.connect(slot(this, &FormRef::createInset));
44 }
45
46
47 FormRef::~FormRef()
48 {
49         delete dialog_;
50 }
51
52
53 void FormRef::clearStore()
54 {
55         refs.clear();
56 }
57
58
59 void FormRef::build()
60 {
61         dialog_ = build_ref();
62
63         fl_addto_choice(dialog_->type,
64                         _(" Ref | Page | TextRef | TextPage | PrettyRef "));
65
66         // XFORMS bug workaround
67         // Define the min/max dimensions. Actually applied in update()
68         formw = form()->w, formh = form()->h;
69
70         // Name is irrelevant to LaTeX documents
71         if( lv_->buffer()->isLatex() ) {
72                 fl_deactivate_object( dialog_->name );
73                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
74         }
75           
76         // Can change reference only through browser
77         fl_deactivate_object( dialog_->ref );
78
79         bc_.setOK( dialog_->ok );
80         bc_.setCancel( dialog_->cancel );
81         bc_.addReadOnly( dialog_->type );
82         bc_.refresh();
83 }
84
85
86 FL_FORM * const FormRef::form() const
87 {
88         if ( dialog_ ) // no need to test for dialog_->form_ref
89                 return dialog_->form;
90         else
91                 return 0;
92 }
93
94
95 void FormRef::update()
96 {
97         fl_set_input(dialog_->ref,  params.getContents().c_str());
98         fl_set_input(dialog_->name, params.getOptions().c_str());
99
100         Type type = getType();
101         fl_set_choice( dialog_->type, type+1 );
102
103         toggle = GOBACK;
104         fl_set_object_label(dialog_->go, _("Goto reference"));
105
106         refs.clear();
107         if( inset_ == 0 ) {
108                 refs = lv_->buffer()->getLabelList();
109                 updateBrowser( refs );
110                 showBrowser();
111         } else {
112                 hideBrowser();
113         }
114         bc_.readOnly( lv_->buffer()->isReadonly() );
115 }
116
117
118 void FormRef::updateBrowser( vector<string> keys ) const
119 {
120         if( fl_get_button( dialog_->sort ) )
121                 sort( keys.begin(), keys.end() );
122
123         fl_clear_browser( dialog_->browser );
124         for( vector<string>::const_iterator it = keys.begin();
125              it != keys.end(); ++it )
126                 fl_add_browser_line( dialog_->browser, (*it).c_str());
127
128         if( keys.empty() ) {
129                 fl_add_browser_line( dialog_->browser,
130                                      _("*** No labels found in document ***"));
131
132                 fl_deactivate_object( dialog_->browser );
133                 fl_deactivate_object( dialog_->update );
134                 fl_deactivate_object( dialog_->sort );
135                 fl_set_object_lcol( dialog_->browser, FL_INACTIVE );
136                 fl_set_object_lcol( dialog_->update, FL_INACTIVE );
137                 fl_set_object_lcol( dialog_->sort, FL_INACTIVE );
138         } else {
139                 fl_set_browser_topline( dialog_->browser, 1 );
140                 fl_activate_object( dialog_->browser );
141                 fl_set_object_lcol( dialog_->browser, FL_BLACK );
142                 fl_activate_object( dialog_->update );
143                 fl_set_object_lcol( dialog_->update, FL_BLACK );
144                 fl_activate_object( dialog_->sort );
145                 fl_set_object_lcol( dialog_->sort, FL_BLACK );
146         }
147 }
148
149
150 void FormRef::showBrowser() const
151 {
152         fl_show_object( dialog_->browser );
153         fl_show_object( dialog_->update );
154         fl_show_object( dialog_->sort );
155
156         setSize( formw, formh, 0 );
157
158         fl_deactivate_object( dialog_->type );
159         fl_set_object_lcol( dialog_->type, FL_INACTIVE );
160         fl_deactivate_object( dialog_->go );
161         fl_set_object_lcol( dialog_->go, FL_INACTIVE );
162         fl_set_object_lcol( dialog_->ref, FL_INACTIVE );
163         bc_.valid(false);
164 }
165
166
167 void FormRef::hideBrowser() const
168 {
169         fl_hide_object( dialog_->browser );
170         fl_hide_object( dialog_->update );
171         fl_hide_object( dialog_->sort );
172
173         setSize( 250, formh, 280 );
174
175         fl_activate_object( dialog_->type );
176         fl_set_object_lcol( dialog_->type, FL_BLACK );
177         fl_activate_object( dialog_->go );
178         fl_set_object_lcol( dialog_->go, FL_BLACK );
179         fl_set_object_lcol( dialog_->ref, FL_BLACK );
180         bc_.invalid();
181 }
182
183
184 void FormRef::setSize( int w, int h, int dx ) const
185 {
186         static int x1 = dialog_->name->x;
187         static int y1 = dialog_->name->y;
188         static int x2 = dialog_->ref->x;
189         static int y2 = dialog_->ref->y;
190         static int x3 = dialog_->type->x;
191         static int y3 = dialog_->type->y;
192         static int x4 = dialog_->go->x;
193         static int y4 = dialog_->go->y;
194         static int x5 = dialog_->ok->x;
195         static int y5 = dialog_->ok->y;
196         static int x6 = dialog_->cancel->x;
197         static int y6 = dialog_->cancel->y;
198
199         if( form()->w != w )
200                 fl_set_form_size( form(), w, h );
201
202         fl_set_form_minsize( form(), w, h );
203         fl_set_form_maxsize( form(), 2*w, h );
204
205         if( form()->w == w ) return;
206
207         fl_set_object_position( dialog_->name,   x1-dx, y1 );
208         fl_set_object_position( dialog_->ref,    x2-dx, y2 );
209         fl_set_object_position( dialog_->type,   x3-dx, y3 );
210         fl_set_object_position( dialog_->go,     x4-dx, y4 );
211         fl_set_object_position( dialog_->ok,     x5-dx, y5 );
212         fl_set_object_position( dialog_->cancel, x6-dx, y6 );
213
214         // These two must be reset apparently
215         // Name is irrelevant to LaTeX documents
216         if( lv_->buffer()->isLatex() ) {
217                 fl_deactivate_object( dialog_->name );
218                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
219         }
220           
221         // Can change reference only through browser
222         fl_deactivate_object( dialog_->ref );
223 }
224
225
226 void FormRef::apply()
227 {
228         if (!lv_->view()->available())
229                 return;
230
231         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
232         params.setCmdName(getName(type));
233
234         params.setOptions(fl_get_input(dialog_->name));
235
236         if (inset_ != 0) {
237                 // Only update if contents have changed
238                 if(params != inset_->params()) {
239                         inset_->setParams(params);
240                         lv_->view()->updateInset(inset_, true);
241                 }
242         } else {
243                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
244                                             params.getAsString());
245         }
246 }
247
248
249 #ifdef WITH_WARNINGS
250 #warning check use of buttoncontroller
251 // Seems okay except that goref and goback shouldn't
252 // affect the status of ok.
253 #endif
254 bool FormRef::input( long data )
255 {
256         bool activate( true );
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_set_object_lcol( dialog_->ref, FL_BLACK );
306         }
307         break;
308
309         // update or sort
310         case 3:
311         {
312                 fl_freeze_form( form() );
313                 updateBrowser( refs );
314                 fl_unfreeze_form( form() );
315         }
316         break;
317
318         // changed reference type
319         case 4:
320         {
321                 Type type = static_cast<Type>( fl_get_choice(dialog_->type)-1 );
322                 if( params.getCmdName() == getName( type )
323                     && inset_ ) {
324                         activate = false;
325                 }
326         }
327         break;
328
329         default:
330                 break;
331         }
332         return activate;
333 }
334
335
336 FormRef::Type FormRef::getType() const
337 {
338         Type type;
339
340         if( params.getCmdName() == "ref" )
341                 type = REF;
342
343         else if( params.getCmdName() == "pageref" )
344                 type = PAGEREF;
345
346         else if( params.getCmdName() == "vref" )
347                 type = VREF;
348
349         else if( params.getCmdName() == "vpageref" )
350                 type = VPAGEREF;
351
352         else
353                 type = PRETTYREF;
354         
355         return type;
356 }
357
358
359 string FormRef::getName( Type type ) const
360 {
361         string name;
362
363         switch( type ) {
364         case REF:
365                 name = "ref";
366                 break;
367         case PAGEREF:
368                 name = "pageref";
369                 break;
370         case VREF:
371                 name = "vref";
372                 break;
373         case VPAGEREF:
374                 name = "vpageref";
375                 break;
376         case PRETTYREF:
377                 name = "prettyref";
378                 break;
379         }
380         
381         return name;
382 }