]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormRef.C
8acdaa65028dbfcffffdcace320d2195d9650fc6
[features.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 FormRef::FormRef(LyXView * lv, Dialogs * d)
34         : FormCommand(lv, d, _("Reference")), toggle(GOBACK), dialog_(0)
35 {
36         // let the dialog be shown
37         // These are permanent connections so we won't bother
38         // storing a copy because we won't be disconnecting.
39         d->showRef.connect(slot(this, &FormRef::showInset));
40         d->createRef.connect(slot(this, &FormRef::createInset));
41 }
42
43
44 FormRef::~FormRef()
45 {
46         delete dialog_;
47 }
48
49
50 FL_FORM * FormRef::form() const
51 {
52         if ( dialog_ ) return dialog_->form;
53         return 0;
54 }
55
56
57 void FormRef::connect()
58 {
59         fl_set_form_maxsize( form(), 2*minw_, minh_ );
60         FormCommand::connect();
61 }
62         
63
64 void FormRef::disconnect()
65 {
66         refs.clear();
67         FormCommand::disconnect();
68 }
69
70
71 void FormRef::build()
72 {
73         dialog_ = build_ref();
74
75         fl_addto_choice(dialog_->type,
76                         _(" Ref | Page | TextRef | TextPage | PrettyRef "));
77
78         // Workaround dumb xforms sizing bug
79         minw_ = form()->w;
80         minh_ = form()->h;
81
82         // Name is irrelevant to LaTeX documents
83         if ( lv_->buffer()->isLatex() ) {
84                 fl_deactivate_object( dialog_->name );
85                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
86         }
87           
88         // Can change reference only through browser
89         fl_deactivate_object( dialog_->ref );
90
91         bc_.setOK( dialog_->button_ok );
92         bc_.setCancel( dialog_->button_cancel );
93         bc_.addReadOnly( dialog_->type );
94         bc_.refresh();
95 }
96
97
98 void FormRef::update()
99 {
100         fl_set_input(dialog_->ref,  params.getContents().c_str());
101         fl_set_input(dialog_->name, params.getOptions().c_str());
102
103         Type type = getType();
104         fl_set_choice( dialog_->type, type+1 );
105
106         toggle = GOBACK;
107         fl_set_object_label(dialog_->button_go, _("Goto reference"));
108
109         refs.clear();
110         if ( inset_ == 0 ) {
111                 refs = lv_->buffer()->getLabelList();
112                 updateBrowser( refs );
113                 showBrowser();
114         } else {
115                 hideBrowser();
116         }
117         bc_.readOnly( lv_->buffer()->isReadonly() );
118 }
119
120
121 void FormRef::updateBrowser( vector<string> keys ) const
122 {
123         if ( fl_get_button( dialog_->sort ) )
124                 sort( keys.begin(), keys.end() );
125
126         fl_clear_browser( dialog_->browser );
127         for( vector<string>::const_iterator it = keys.begin();
128              it != keys.end(); ++it )
129                 fl_add_browser_line( dialog_->browser, (*it).c_str());
130
131         if ( keys.empty() ) {
132                 fl_add_browser_line( dialog_->browser,
133                                      _("*** No labels found in document ***"));
134
135                 fl_deactivate_object( dialog_->browser );
136                 fl_deactivate_object( dialog_->button_update );
137                 fl_deactivate_object( dialog_->sort );
138                 fl_set_object_lcol( dialog_->browser, FL_INACTIVE );
139                 fl_set_object_lcol( dialog_->button_update, FL_INACTIVE );
140                 fl_set_object_lcol( dialog_->sort, FL_INACTIVE );
141         } else {
142                 fl_set_browser_topline( dialog_->browser, 1 );
143                 fl_activate_object( dialog_->browser );
144                 fl_set_object_lcol( dialog_->browser, FL_BLACK );
145                 fl_activate_object( dialog_->button_update );
146                 fl_set_object_lcol( dialog_->button_update, FL_BLACK );
147                 fl_activate_object( dialog_->sort );
148                 fl_set_object_lcol( dialog_->sort, FL_BLACK );
149         }
150 }
151
152
153 void FormRef::showBrowser() const
154 {
155         fl_show_object( dialog_->browser );
156         fl_show_object( dialog_->button_update );
157         fl_show_object( dialog_->sort );
158
159         setSize( minw_, minh_, 0 );
160
161         fl_deactivate_object( dialog_->type );
162         fl_set_object_lcol( dialog_->type, FL_INACTIVE );
163         fl_deactivate_object( dialog_->button_go );
164         fl_set_object_lcol( dialog_->button_go, FL_INACTIVE );
165         fl_set_object_lcol( dialog_->ref, FL_INACTIVE );
166         bc_.valid(false);
167 }
168
169
170 void FormRef::hideBrowser() const
171 {
172         fl_hide_object( dialog_->browser );
173         fl_hide_object( dialog_->button_update );
174         fl_hide_object( dialog_->sort );
175
176         setSize( 250, minh_, 280 );
177
178         fl_activate_object( dialog_->type );
179         fl_set_object_lcol( dialog_->type, FL_BLACK );
180         fl_activate_object( dialog_->button_go );
181         fl_set_object_lcol( dialog_->button_go, FL_BLACK );
182         fl_set_object_lcol( dialog_->ref, FL_BLACK );
183         bc_.invalid();
184 }
185
186
187 void FormRef::setSize( int w, int h, int dx ) const
188 {
189         static int x1 = dialog_->name->x;
190         static int y1 = dialog_->name->y;
191         static int x2 = dialog_->ref->x;
192         static int y2 = dialog_->ref->y;
193         static int x3 = dialog_->type->x;
194         static int y3 = dialog_->type->y;
195         static int x4 = dialog_->button_go->x;
196         static int y4 = dialog_->button_go->y;
197         static int x5 = dialog_->button_ok->x;
198         static int y5 = dialog_->button_ok->y;
199         static int x6 = dialog_->button_cancel->x;
200         static int y6 = dialog_->button_cancel->y;
201
202         if ( form()->w != w ) {
203                 minw_ = w;
204                 minh_ = h;
205                 fl_set_form_size( form(), minw_, minh_ );
206         } else
207                 return;
208         
209         fl_set_object_position( dialog_->name,   x1-dx, y1 );
210         fl_set_object_position( dialog_->ref,    x2-dx, y2 );
211         fl_set_object_position( dialog_->type,   x3-dx, y3 );
212         fl_set_object_position( dialog_->button_go,     x4-dx, y4 );
213         fl_set_object_position( dialog_->button_ok,     x5-dx, y5 );
214         fl_set_object_position( dialog_->button_cancel, x6-dx, y6 );
215
216         // These two must be reset apparently
217         // Name is irrelevant to LaTeX documents
218         if ( lv_->buffer()->isLatex() ) {
219                 fl_deactivate_object( dialog_->name );
220                 fl_set_object_lcol( dialog_->name, FL_INACTIVE );
221         }
222           
223         // Can change reference only through browser
224         fl_deactivate_object( dialog_->ref );
225 }
226
227
228 void FormRef::apply()
229 {
230         if (!lv_->view()->available())
231                 return;
232
233         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
234         params.setCmdName(getName(type));
235
236         params.setOptions(fl_get_input(dialog_->name));
237
238         if (inset_ != 0) {
239                 // Only update if contents have changed
240                 if (params != inset_->params()) {
241                         inset_->setParams(params);
242                         lv_->view()->updateInset(inset_, true);
243                 }
244         } else {
245                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
246                                             params.getAsString());
247         }
248 }
249
250
251 #ifdef WITH_WARNINGS
252 #warning check use of buttoncontroller
253 // Seems okay except that goref and goback shouldn't
254 // affect the status of ok.
255 #endif
256 bool FormRef::input( FL_OBJECT *, long data )
257 {
258         bool activate( true );
259         switch( data ) {
260         // goto reference / go back
261         case 1:
262         {
263                 toggle = static_cast<Goto>(toggle + 1);
264                 if ( toggle == GOFIRST ) toggle = GOREF;
265         
266                 switch (toggle) {
267                 case GOREF:
268                 {
269                         lv_->getLyXFunc()->
270                                 Dispatch(LFUN_REF_GOTO,
271                                          params.getContents());
272                         fl_set_object_label(dialog_->button_go, _("Go back"));
273                 }
274                 break;
275
276                 case GOBACK:
277                 {
278                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
279                         fl_set_object_label(dialog_->button_go,
280                                             _("Goto reference"));
281                 }
282                 break;
283
284                 default:
285                         break;
286                 }
287         }
288         break;
289
290         // choose browser key
291         case 2:
292         {
293                 unsigned int sel = fl_get_browser( dialog_->browser );
294                 if ( sel < 1 || sel > refs.size() ) break;
295
296                 string s = fl_get_browser_line( dialog_->browser, sel );
297                 fl_set_input( dialog_->ref, s.c_str());
298                 params.setContents( s );
299
300                 toggle = GOBACK;
301                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
302                 fl_set_object_label(dialog_->button_go, _("Goto reference"));
303
304                 fl_activate_object( dialog_->type );
305                 fl_set_object_lcol( dialog_->type, FL_BLACK );
306                 fl_activate_object( dialog_->button_go );
307                 fl_set_object_lcol( dialog_->button_go, FL_BLACK );
308                 fl_set_object_lcol( dialog_->ref, FL_BLACK );
309         }
310         break;
311
312         // update or sort
313         case 3:
314         {
315                 fl_freeze_form( form() );
316                 updateBrowser( refs );
317                 fl_unfreeze_form( form() );
318         }
319         break;
320
321         // changed reference type
322         case 4:
323         {
324                 Type type = static_cast<Type>( 
325                         fl_get_choice(dialog_->type) - 1 );
326                 if ( params.getCmdName() == getName( type )
327                     && inset_ ) {
328                         activate = false;
329                 }
330         }
331         break;
332
333         default:
334                 break;
335         }
336         return activate;
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 }