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