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