2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 2000 The LyX Team.
9 * ======================================================
16 #include FORMS_H_LOCATION
19 #pragma implementation
24 #include "BufferView.h"
26 #include "FormCitation.h"
29 #include "form_citation.h"
31 #include "xform_macros.h"
32 #include "insets/insetcite.h"
33 #include "support/filetools.h"
41 C_RETURNCB(FormCitation, WMHideCB)
42 C_GENERICCB(FormCitation, OKCB)
43 C_GENERICCB(FormCitation, CancelCB)
44 C_GENERICCB(FormCitation, InputCB)
46 FormCitation::FormCitation(LyXView * lv, Dialogs * d)
47 : dialog_(0), lv_(lv), d_(d), u_(0), h_(0), ih_(0),
48 inset_(0), dialogIsOpen(false)
50 // let the dialog be shown
51 // These are permanent connections so we won't bother
52 // storing a copy because we won't be disconnecting.
53 d->showCitation.connect(slot(this, &FormCitation::showInset));
54 d->createCitation.connect(slot(this, &FormCitation::createInset));
58 FormCitation::~FormCitation()
64 void FormCitation::build()
66 dialog_ = build_citation();
70 void FormCitation::showInset( InsetCitation * inset )
72 if( dialogIsOpen || inset == 0 ) return;
75 ih_ = inset_->hide.connect(slot(this, &FormCitation::hide));
77 textAfter = inset->getOptions();
78 updateCitekeys(inset->getContents());
83 void FormCitation::createInset( string const & arg )
85 if( dialogIsOpen ) return;
88 if (contains(arg, "|")) {
89 keys = token(arg, '|', 0);
90 textAfter = token(arg, '|', 1);
101 void FormCitation::show()
105 fl_set_form_atclose(dialog_->form_citation,
106 C_FormCitationWMHideCB, 0);
109 update(); // make sure its up-to-date
112 if (dialog_->form_citation->visible) {
113 fl_raise_form(dialog_->form_citation);
115 fl_show_form(dialog_->form_citation,
116 FL_PLACE_MOUSE | FL_FREE_SIZE,
119 u_ = d_->updateBufferDependent.
120 connect(slot(this, &FormCitation::update));
121 h_ = d_->hideBufferDependent.
122 connect(slot(this, &FormCitation::hide));
127 void FormCitation::update()
132 vector<pair<string,string> > blist =
133 lv_->buffer()->getBibkeyList();
135 for( unsigned int i = 0; i < blist.size(); ++i ) {
136 bibkeys.push_back(blist[i].first);
137 bibkeysInfo.push_back(blist[i].second);
142 fl_freeze_form( dialog_->form_citation );
144 updateBrowser( dialog_->bibBrsr, bibkeys );
145 updateBrowser( dialog_->citeBrsr, citekeys );
146 fl_clear_browser( dialog_->infoBrsr );
148 // No keys have been selected yet, so...
149 setBibButtons( OFF );
150 setCiteButtons( OFF );
152 int noKeys = max( bibkeys.size(), citekeys.size() );
154 // Place bounds, so that 4 <= noKeys <= 15
155 noKeys = max( 4, min(15, noKeys) );
157 // Re-size the form to accommodate the new browser size
158 int size = 20 * noKeys;
159 bool bibPresent = ( bibkeys.size() > 0 );
160 setSize( size, bibPresent );
162 fl_set_input( dialog_->textAftr, textAfter.c_str() );
164 fl_unfreeze_form( dialog_->form_citation );
168 void FormCitation::updateCitekeys( string const & keysIn )
173 string keys = keysIn;
174 keys = frontStrip( split(keys, tmp, ',') );
175 while( !tmp.empty() ) {
176 citekeys.push_back( tmp );
177 keys = frontStrip( split(keys, tmp, ',') );
182 void FormCitation::updateBrowser( FL_OBJECT * browser,
183 vector<string> const & keys ) const
185 fl_clear_browser( browser );
187 for( unsigned int i = 0; i < keys.size(); ++i )
188 fl_add_browser_line( browser, keys[i].c_str() );
192 void FormCitation::setBibButtons( State status ) const
196 fl_activate_object( dialog_->addBtn );
197 fl_set_object_lcol( dialog_->addBtn, FL_BLACK );
201 fl_deactivate_object( dialog_->addBtn );
202 fl_set_object_lcol( dialog_->addBtn, FL_INACTIVE );
211 void FormCitation::setCiteButtons( State status ) const
216 fl_activate_object( dialog_->delBtn );
217 fl_set_object_lcol( dialog_->delBtn, FL_BLACK );
219 int sel = fl_get_browser( dialog_->citeBrsr );
222 fl_activate_object( dialog_->upBtn );
223 fl_set_object_lcol( dialog_->upBtn, FL_BLACK );
225 fl_deactivate_object( dialog_->upBtn );
226 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
229 if( sel != fl_get_browser_maxline(dialog_->citeBrsr)) {
230 fl_activate_object( dialog_->downBtn );
231 fl_set_object_lcol( dialog_->downBtn, FL_BLACK );
233 fl_deactivate_object( dialog_->downBtn );
234 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
241 fl_deactivate_object( dialog_->delBtn );
242 fl_set_object_lcol( dialog_->delBtn, FL_INACTIVE );
244 fl_deactivate_object( dialog_->upBtn );
245 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
247 fl_deactivate_object( dialog_->downBtn );
248 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
256 void FormCitation::setSize( int brsrHeight, bool bibPresent ) const
258 int const infoHeight = 110;
259 int const otherHeight = 140;
260 brsrHeight = max( brsrHeight, 175 );
261 int formHeight = brsrHeight + otherHeight;
263 if( bibPresent ) formHeight += infoHeight + 30;
264 fl_set_form_size( dialog_->form_citation, 430, formHeight );
266 // No resizing is alowed in the y-direction
267 fl_set_form_minsize( dialog_->form_citation, 430, formHeight );
268 fl_set_form_maxsize( dialog_->form_citation, 1000, formHeight );
271 fl_set_object_geometry( dialog_->box, 0, ypos, 430, formHeight );
273 fl_set_object_geometry( dialog_->citeBrsr, 10, ypos, 180, brsrHeight );
274 fl_set_object_geometry( dialog_->bibBrsr, 240, ypos, 180, brsrHeight );
276 fl_set_object_position( dialog_->addBtn, 200, ypos );
278 fl_set_object_position( dialog_->delBtn, 200, ypos );
280 fl_set_object_position( dialog_->upBtn, 200, ypos );
282 fl_set_object_position( dialog_->downBtn, 200, ypos );
284 ypos = brsrHeight+30; // base of Citation/Bibliography browsers
286 // awaiting natbib support
287 fl_hide_object( dialog_->style );
291 fl_set_object_position( dialog_->infoBrsr, 10, ypos );
292 fl_show_object( dialog_->infoBrsr );
296 fl_hide_object( dialog_->infoBrsr );
299 // awaiting natbib support
300 fl_hide_object( dialog_->textBefore );
302 fl_set_object_position( dialog_->textAftr, 100, ypos );
303 fl_set_object_position( dialog_->ok, 230, ypos+50 );
304 fl_set_object_position( dialog_->cancel, 330, ypos+50 );
308 void FormCitation::input( State cb )
313 fl_deselect_browser( dialog_->citeBrsr );
315 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
316 if( sel < 1 || sel > bibkeys.size() ) break;
318 // Put into infoBrsr the additional info associated with
319 // the selected bibBrsr key
320 fl_clear_browser( dialog_->infoBrsr );
321 fl_add_browser_line( dialog_->infoBrsr,
322 bibkeysInfo[sel-1].c_str() );
324 // Highlight the selected bibBrsr key in citeBrsr if present
325 vector<string>::iterator it =
326 find( citekeys.begin(), citekeys.end(), bibkeys[sel-1] );
328 if( it != citekeys.end() ) {
329 int n = it - citekeys.begin();
330 fl_select_browser_line( dialog_->citeBrsr, n+1 );
331 fl_set_browser_topline( dialog_->citeBrsr, n+1 );
334 if( !lv_->buffer()->isReadonly() ) {
335 if( it != citekeys.end() ) {
336 setBibButtons( OFF );
337 setCiteButtons( ON );
340 setCiteButtons( OFF );
347 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
348 if( sel < 1 || sel > citekeys.size() ) break;
350 if( !lv_->buffer()->isReadonly() ) {
351 setBibButtons( OFF );
352 setCiteButtons( ON );
355 // Highlight the selected citeBrsr key in bibBrsr
356 vector<string>::iterator it =
357 find( bibkeys.begin(), bibkeys.end(), citekeys[sel-1] );
359 if (it != bibkeys.end()) {
360 int n = it - bibkeys.begin();
361 fl_select_browser_line( dialog_->bibBrsr, n+1 );
362 fl_set_browser_topline( dialog_->bibBrsr, n+1 );
364 // Put into infoBrsr the additional info associated with
365 // the selected citeBrsr key
366 fl_clear_browser( dialog_->infoBrsr );
367 fl_add_browser_line( dialog_->infoBrsr,
368 bibkeysInfo[n].c_str() );
374 if( lv_->buffer()->isReadonly() ) break;
376 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
377 if( sel < 1 || sel > bibkeys.size() ) break;
379 // Add the selected bibBrsr key to citeBrsr
380 fl_addto_browser( dialog_->citeBrsr,
381 bibkeys[sel-1].c_str() );
382 citekeys.push_back( bibkeys[sel-1] );
384 int n = citekeys.size();
385 fl_select_browser_line( dialog_->citeBrsr, n );
387 setBibButtons( OFF );
388 setCiteButtons( ON );
393 if( lv_->buffer()->isReadonly() ) break;
395 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
396 if( sel < 1 || sel > citekeys.size() ) break;
398 // Remove the selected key from citeBrsr
399 fl_delete_browser_line( dialog_->citeBrsr, sel ) ;
400 citekeys.erase( citekeys.begin() + sel-1 );
403 setCiteButtons( OFF );
408 if( lv_->buffer()->isReadonly() ) break;
410 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
411 if( sel < 2 || sel > citekeys.size() ) break;
413 // Move the selected key up one line
414 vector<string>::iterator it = citekeys.begin() + sel-1;
417 fl_delete_browser_line( dialog_->citeBrsr, sel );
418 citekeys.erase( it );
420 fl_insert_browser_line( dialog_->citeBrsr, sel-1, tmp.c_str() );
421 fl_select_browser_line( dialog_->citeBrsr, sel-1 );
422 citekeys.insert( it-1, tmp );
423 setCiteButtons( ON );
428 if( lv_->buffer()->isReadonly() ) break;
430 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
431 if( sel < 1 || sel > citekeys.size()-1 ) break;
433 // Move the selected key down one line
434 vector<string>::iterator it = citekeys.begin() + sel-1;
437 fl_delete_browser_line( dialog_->citeBrsr, sel );
438 citekeys.erase( it );
440 fl_insert_browser_line( dialog_->citeBrsr, sel+1, tmp.c_str() );
441 fl_select_browser_line( dialog_->citeBrsr, sel+1 );
442 citekeys.insert( it+1, tmp );
443 setCiteButtons( ON );
452 void FormCitation::apply()
454 if( lv_->buffer()->isReadonly() ) return;
457 for( unsigned int i = 0; i < citekeys.size(); ++i ) {
458 if (i > 0) contents += ", ";
459 contents += citekeys[i];
462 textAfter = fl_get_input(dialog_->textAftr);
466 inset_->setContents( contents );
467 inset_->setOptions( textAfter );
468 lv_->view()->updateInset( inset_, true );
470 InsetCommandParams p( "cite", contents, textAfter );
471 lv_->getLyXFunc()->Dispatch( LFUN_INSERT_CITATION,
472 p.getAsString().c_str() );
477 void FormCitation::hide()
480 && dialog_->form_citation
481 && dialog_->form_citation->visible) {
482 fl_hide_form(dialog_->form_citation);
487 // free up the dialog for another inset
490 dialogIsOpen = false;
494 void FormCitation::free()
496 // we don't need to delete u and h here because
497 // hide() does that after disconnecting.
499 if (dialog_->form_citation
500 && dialog_->form_citation->visible) {
503 fl_free_form(dialog_->form_citation);
510 int FormCitation::WMHideCB(FL_FORM * form, void *)
512 // Ensure that the signals (u and h) are disconnected even if the
513 // window manager is used to close the dialog.
514 FormCitation * pre = static_cast<FormCitation*>(form->u_vdata);
520 void FormCitation::OKCB(FL_OBJECT * ob, long)
522 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
528 void FormCitation::CancelCB(FL_OBJECT * ob, long)
530 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
535 void FormCitation::InputCB(FL_OBJECT * ob, long data)
537 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
538 pre->input( static_cast<FormCitation::State>(data) );