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