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