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