]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormCitation.C
Dekel's lyxrc.example; Angus's FormDocument; John's build-listerrors; POTFILES.in...
[lyx.git] / src / frontends / xforms / FormCitation.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 #include <algorithm>
17
18 #ifdef __GNUG__
19 #pragma implementation
20 #endif
21
22
23 #include "Dialogs.h"
24 #include "FormCitation.h"
25 #include "LyXView.h"
26 #include "buffer.h"
27 #include "form_citation.h"
28 #include "lyxfunc.h"
29 #include "support/filetools.h"
30
31 using std::vector;
32 using std::pair;
33 using std::max;
34 using std::min;
35 using std::find;
36
37 static int min_wform;
38
39 FormCitation::FormCitation(LyXView * lv, Dialogs * d)
40         : FormCommand(lv, d, _("Citation")), dialog_(0)
41 {
42         // let the dialog be shown
43         // These are permanent connections so we won't bother
44         // storing a copy because we won't be disconnecting.
45         d->showCitation.connect(slot(this, &FormCitation::showInset));
46         d->createCitation.connect(slot(this, &FormCitation::createInset));
47 }
48
49
50 FormCitation::~FormCitation()
51 {
52         delete dialog_;
53 }
54
55
56 FL_FORM * FormCitation::form() const
57 {
58         if ( dialog_ ) return dialog_->form;
59         return 0;
60 }
61
62
63 void FormCitation::clearStore()
64 {
65         citekeys.clear();
66         bibkeys.clear();
67         bibkeysInfo.clear();
68 }
69
70
71 void FormCitation::build()
72 {
73         dialog_ = build_citation();
74         min_wform = dialog_->form->w;
75 }
76
77
78 void FormCitation::update()
79 {
80         bibkeys.clear();
81         bibkeysInfo.clear();
82
83         vector<pair<string,string> > blist =
84                 lv_->buffer()->getBibkeyList();
85
86         for( unsigned int i = 0; i < blist.size(); ++i ) {
87                 bibkeys.push_back(blist[i].first);
88                 bibkeysInfo.push_back(blist[i].second);
89         }
90         blist.clear();
91
92         citekeys.clear();
93         string tmp, keys( params.getContents() );
94         keys = frontStrip( split(keys, tmp, ',') );
95         while( !tmp.empty() ) {
96                 citekeys.push_back( tmp );
97                 keys = frontStrip( split(keys, tmp, ',') );
98         }
99
100         updateBrowser( dialog_->bibBrsr,  bibkeys );
101         updateBrowser( dialog_->citeBrsr, citekeys );
102         fl_clear_browser( dialog_->infoBrsr );
103
104         // No keys have been selected yet, so...
105         setBibButtons( OFF );
106         setCiteButtons( OFF );
107
108         int noKeys = static_cast<int>( max( bibkeys.size(), citekeys.size() ) );
109
110         // Place bounds, so that 4 <= noKeys <= 10
111         noKeys = max(4, min(10, noKeys) );
112
113         // Re-size the form to accommodate the new browser size
114         int size = 20 * noKeys;
115         bool bibPresent = ( bibkeys.size() > 0 );
116         setSize( size, bibPresent );
117
118         fl_set_input( dialog_->textAftr, params.getOptions().c_str() );
119 }
120
121
122 void FormCitation::updateBrowser( FL_OBJECT * browser,
123                                   vector<string> const & keys ) const
124 {
125         fl_clear_browser( browser );
126
127         for( unsigned int i = 0; i < keys.size(); ++i )
128                 fl_add_browser_line( browser, keys[i].c_str() );
129 }
130
131
132 void FormCitation::setBibButtons( State status ) const
133 {
134         switch (status) {
135         case ON:
136                 fl_activate_object( dialog_->addBtn );
137                 fl_set_object_lcol( dialog_->addBtn, FL_BLACK );
138                 break;
139
140         case OFF:
141                 fl_deactivate_object( dialog_->addBtn );
142                 fl_set_object_lcol( dialog_->addBtn, FL_INACTIVE );
143                 break;
144
145         default:
146                 break;
147         }
148 }
149
150
151 void FormCitation::setCiteButtons( State status ) const
152 {
153         switch( status ) {
154         case ON:
155         {
156                 fl_activate_object( dialog_->delBtn );
157                 fl_set_object_lcol( dialog_->delBtn, FL_BLACK );
158
159                 int sel = fl_get_browser( dialog_->citeBrsr );
160
161                 if ( sel != 1 ) {
162                         fl_activate_object( dialog_->upBtn );
163                         fl_set_object_lcol( dialog_->upBtn, FL_BLACK );
164                 } else {
165                         fl_deactivate_object( dialog_->upBtn );
166                         fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
167                 }
168
169                 if ( sel != fl_get_browser_maxline(dialog_->citeBrsr)) {
170                         fl_activate_object( dialog_->downBtn );
171                         fl_set_object_lcol( dialog_->downBtn, FL_BLACK );
172                 } else {
173                         fl_deactivate_object( dialog_->downBtn );
174                         fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
175                 }
176
177                 break;
178         }
179         case OFF:
180         {
181                 fl_deactivate_object( dialog_->delBtn );
182                 fl_set_object_lcol( dialog_->delBtn, FL_INACTIVE );
183
184                 fl_deactivate_object( dialog_->upBtn );
185                 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
186
187                 fl_deactivate_object( dialog_->downBtn );
188                 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
189         }
190         default:
191                 break;
192         }
193 }
194
195
196 void FormCitation::setSize( int hbrsr, bool bibPresent ) const
197 {
198         bool const natbib = false; // will eventually be input
199         hbrsr = max( hbrsr, 175 ); // limit max size of cite/bib brsrs
200
201         // dh1, dh2, dh3 are the vertical separation between elements.
202         // These can be specified because the browser height is fixed
203         // so they are not changed by dynamic resizing
204         static int const dh1 = 30; // top of form to top of cite/bib brsrs;
205                                    // bottom of cite/bib brsrs to top of info;
206                                    // bottom of info to top next element;
207                                    // bottom of style to top textBefore;
208                                    // bottom of text to top ok/cancel buttons.
209         static int const dh2 = 10; // bottom of textBefore to top textAftr;
210                                    // bottom of ok/cancel buttons to bottom form
211         static int const dh3 = 5;  // spacing between add/delete/... buttons.
212
213         int const wbrsr  = dialog_->citeBrsr->w;
214         static int const hinfo  = dialog_->infoBrsr->h;
215         static int const hstyle = dialog_->style->h;
216         static int const htext  = dialog_->textAftr->h;
217         static int const hok    = dialog_->button_ok->h;
218
219         int const wform = dialog_->form->w;
220         int hform = dh1 + hbrsr + dh1;
221         if ( bibPresent ) hform += hinfo + dh1;
222         if ( natbib ) hform += hstyle + dh1 + htext + dh2;
223         hform += htext + dh1 + hok + dh2;
224
225         bool const sizeSet = ( hform != dialog_->form->h );
226         if ( sizeSet ) fl_set_form_size( dialog_->form, wform, hform );
227
228         // No vertical resizing is allowed
229         // min_wform set in build()
230         fl_set_form_minsize( dialog_->form, min_wform,   hform );
231         fl_set_form_maxsize( dialog_->form, 3*min_wform, hform );
232
233         if ( !sizeSet ) return;
234
235         int x = 0;
236         int y = 0;
237         fl_set_object_geometry( dialog_->box, x, y, wform, hform );
238
239         x = dialog_->citeBrsr->x;
240         y += dh1; 
241         fl_set_object_geometry( dialog_->citeBrsr, x, y, wbrsr, hbrsr );
242         x = dialog_->bibBrsr->x;
243         fl_set_object_geometry( dialog_->bibBrsr,  x, y, wbrsr, hbrsr );
244
245         x = dialog_->addBtn->x;
246         fl_set_object_position( dialog_->addBtn,  x, y );
247         y += dh3 + dialog_->addBtn->h;
248         fl_set_object_position( dialog_->delBtn,  x, y );
249         y += dh3 + dialog_->delBtn->h;
250         fl_set_object_position( dialog_->upBtn,   x, y );
251         y += dh3 + dialog_->upBtn->h;
252         fl_set_object_position( dialog_->downBtn, x, y );
253
254         y = dh1 + hbrsr + dh1; // in position for next element
255
256         if ( bibPresent ) {
257                 x = dialog_->infoBrsr->x;
258                 fl_set_object_position( dialog_->infoBrsr, x, y );
259                 fl_show_object( dialog_->infoBrsr );
260                 y += hinfo + dh1;
261         } else
262                 fl_hide_object( dialog_->infoBrsr );
263
264         if ( natbib ) {
265                 x = dialog_->style->x;
266                 fl_set_object_position( dialog_->style, x, y );
267                 fl_show_object( dialog_->style );
268                 x = dialog_->textBefore->x;
269                 y += hstyle + dh1;
270                 fl_set_object_position( dialog_->textBefore, x, y );
271                 fl_show_object( dialog_->textBefore );
272                 y += htext + dh2;
273         } else {
274                 fl_hide_object( dialog_->style );
275                 fl_hide_object( dialog_->textBefore );
276         }
277
278         x = dialog_->textAftr->x;
279         fl_set_object_position( dialog_->textAftr, x, y );
280
281         x = dialog_->button_ok->x;
282         y += htext + dh1;
283         fl_set_object_position( dialog_->button_ok,       x, y );
284         x = dialog_->button_cancel->x;
285         fl_set_object_position( dialog_->button_cancel,   x, y );
286 }
287
288
289 #ifdef WITH_WARNINGS
290 #warning convert this to use the buttoncontroller
291 #endif
292 bool FormCitation::input( FL_OBJECT *, long data )
293 {
294         State cb = static_cast<State>( data );
295
296         switch( cb ) {
297         case BIBBRSR:
298         {
299                 fl_deselect_browser( dialog_->citeBrsr );
300                 
301                 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
302                 if ( sel < 1 || sel > bibkeys.size() ) break;
303
304                 // Put into infoBrsr the additional info associated with
305                 // the selected bibBrsr key
306                 fl_clear_browser( dialog_->infoBrsr );
307                 fl_add_browser_line( dialog_->infoBrsr,
308                                      bibkeysInfo[sel-1].c_str() );
309
310                 // Highlight the selected bibBrsr key in citeBrsr if present
311                 vector<string>::iterator it =
312                         find( citekeys.begin(), citekeys.end(), bibkeys[sel-1] );
313
314                 if ( it != citekeys.end() ) {
315                         int n = static_cast<int>( it - citekeys.begin() );
316                         fl_select_browser_line( dialog_->citeBrsr, n+1 );
317                         fl_set_browser_topline( dialog_->citeBrsr, n+1 );
318                 }
319
320                 if ( !lv_->buffer()->isReadonly() ) {
321                         if ( it != citekeys.end() ) {
322                                 setBibButtons( OFF );
323                                 setCiteButtons( ON );
324                         } else {
325                                 setBibButtons( ON );
326                                 setCiteButtons( OFF );
327                         }
328                 }
329         }
330         break;
331         case CITEBRSR:
332         {
333                 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
334                 if ( sel < 1 || sel > citekeys.size() ) break;
335
336                 if ( !lv_->buffer()->isReadonly() ) {
337                         setBibButtons( OFF );
338                         setCiteButtons( ON );
339                 }
340
341                 // Highlight the selected citeBrsr key in bibBrsr
342                 vector<string>::iterator it =
343                         find( bibkeys.begin(), bibkeys.end(), citekeys[sel-1] );
344
345                 if (it != bibkeys.end()) {
346                         int n = static_cast<int>( it - bibkeys.begin() );
347                         fl_select_browser_line( dialog_->bibBrsr, n+1 );
348                         fl_set_browser_topline( dialog_->bibBrsr, n+1 );
349
350                         // Put into infoBrsr the additional info associated with
351                         // the selected citeBrsr key
352                         fl_clear_browser( dialog_->infoBrsr );
353                         fl_add_browser_line( dialog_->infoBrsr,
354                                              bibkeysInfo[n].c_str() );
355                 }
356         }
357         break;
358         case ADD:
359         {
360                 if ( lv_->buffer()->isReadonly() ) break;
361
362                 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
363                 if ( sel < 1 || sel > bibkeys.size() ) break;
364
365                 // Add the selected bibBrsr key to citeBrsr
366                 fl_addto_browser( dialog_->citeBrsr,
367                                   bibkeys[sel-1].c_str() );
368                 citekeys.push_back( bibkeys[sel-1] );
369
370                 int n = static_cast<int>( citekeys.size() );
371                 fl_select_browser_line( dialog_->citeBrsr, n );
372
373                 setBibButtons( OFF );
374                 setCiteButtons( ON );
375         }
376         break;
377         case DELETE:
378         {
379                 if ( lv_->buffer()->isReadonly() ) break;
380
381                 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
382                 if ( sel < 1 || sel > citekeys.size() ) break;
383
384                 // Remove the selected key from citeBrsr
385                 fl_delete_browser_line( dialog_->citeBrsr, sel ) ;
386                 citekeys.erase( citekeys.begin() + sel-1 );
387
388                 setBibButtons( ON );
389                 setCiteButtons( OFF );
390         }
391         break;
392         case UP:
393         {
394                 if ( lv_->buffer()->isReadonly() ) break;
395
396                 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
397                 if ( sel < 2 || sel > citekeys.size() ) break;
398
399                 // Move the selected key up one line
400                 vector<string>::iterator it = citekeys.begin() + sel-1;
401                 string tmp = *it;
402
403                 fl_delete_browser_line( dialog_->citeBrsr, sel );
404                 citekeys.erase( it );
405
406                 fl_insert_browser_line( dialog_->citeBrsr, sel-1, tmp.c_str() );
407                 fl_select_browser_line( dialog_->citeBrsr, sel-1 );
408                 citekeys.insert( it-1, tmp );
409                 setCiteButtons( ON );
410         }
411         break;
412         case DOWN:
413         {
414                 if ( lv_->buffer()->isReadonly() ) break;
415
416                 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
417                 if ( sel < 1 || sel > citekeys.size()-1 ) break;
418
419                 // Move the selected key down one line
420                 vector<string>::iterator it = citekeys.begin() + sel-1;
421                 string tmp = *it;
422
423                 fl_delete_browser_line( dialog_->citeBrsr, sel );
424                 citekeys.erase( it );
425
426                 fl_insert_browser_line( dialog_->citeBrsr, sel+1, tmp.c_str() );
427                 fl_select_browser_line( dialog_->citeBrsr, sel+1 );
428                 citekeys.insert( it+1, tmp );
429                 setCiteButtons( ON );
430         }
431         break;
432         default:
433                 break;
434         }
435         return true;
436 }
437
438
439 void FormCitation::apply()
440 {
441         if (lv_->buffer()->isReadonly()) return;
442
443         string contents;
444         for(unsigned int i = 0; i < citekeys.size(); ++i) {
445                 if (i > 0) contents += ", ";
446                 contents += citekeys[i];
447         }
448
449         params.setContents(contents);
450         params.setOptions(fl_get_input(dialog_->textAftr));
451
452         if (inset_ != 0) {
453                 // Only update if contents have changed
454                 if (params != inset_->params()) {
455                         inset_->setParams(params);
456                         lv_->view()->updateInset(inset_, true);
457                 }
458         } else {
459                 lv_->getLyXFunc()->Dispatch(LFUN_CITATION_INSERT,
460                                             params.getAsString());
461         }
462 }