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