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