2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 2000 The LyX Team.
9 * ======================================================
14 #include FORMS_H_LOCATION
15 #include "BufferView.h"
17 #include "FormCitation.h"
20 #include "form_citation.h"
22 #include "xform_macros.h"
23 #include "insets/insetcite.h"
24 #include "support/filetools.h"
27 #pragma implementation
36 C_RETURNCB(FormCitation, WMHideCB)
37 C_GENERICCB(FormCitation, OKCB)
38 C_GENERICCB(FormCitation, CancelCB)
39 C_GENERICCB(FormCitation, InputCB)
41 FormCitation::FormCitation(LyXView * lv, Dialogs * d)
42 : dialog_(0), lv_(lv), d_(d), u_(0), h_(0), ih_(0),
43 inset_(0), dialogIsOpen(false)
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));
53 FormCitation::~FormCitation()
59 void FormCitation::build()
61 dialog_ = build_citation();
65 void FormCitation::showInset( InsetCitation * inset )
67 if( dialogIsOpen || inset == 0 ) return;
70 ih_ = inset_->hide.connect(slot(this, &FormCitation::hide));
72 textAfter = inset->getOptions();
73 updateCitekeys(inset->getContents());
78 void FormCitation::createInset( string const & arg )
80 if( dialogIsOpen ) return;
83 if (contains(arg, "|")) {
84 keys = token(arg, '|', 0);
85 textAfter = token(arg, '|', 1);
96 void FormCitation::show()
100 fl_set_form_atclose(dialog_->form_citation,
101 C_FormCitationWMHideCB, 0);
104 update(); // make sure its up-to-date
107 if (dialog_->form_citation->visible) {
108 fl_raise_form(dialog_->form_citation);
110 fl_show_form(dialog_->form_citation,
111 FL_PLACE_MOUSE | FL_FREE_SIZE,
114 u_ = d_->updateBufferDependent.
115 connect(slot(this, &FormCitation::update));
116 h_ = d_->hideBufferDependent.
117 connect(slot(this, &FormCitation::hide));
122 void FormCitation::update()
127 vector<pair<string,string> > blist =
128 lv_->buffer()->getBibkeyList();
130 for( unsigned int i = 0; i < blist.size(); ++i ) {
131 bibkeys.push_back(blist[i].first);
132 bibkeysInfo.push_back(blist[i].second);
137 fl_freeze_form( dialog_->form_citation );
139 updateBrowser( dialog_->bibBrsr, bibkeys );
140 updateBrowser( dialog_->citeBrsr, citekeys );
141 fl_clear_browser( dialog_->infoBrsr );
143 // No keys have been selected yet, so...
144 setBibButtons( OFF );
145 setCiteButtons( OFF );
147 int noKeys = max( bibkeys.size(), citekeys.size() );
149 // Place bounds, so that 4 <= noKeys <= 15
150 noKeys = max( 4, min(15, noKeys) );
152 // Re-size the form to accommodate the new browser size
153 int size = 20 * noKeys;
154 bool bibPresent = ( bibkeys.size() > 0 );
155 setSize( size, bibPresent );
157 fl_set_input( dialog_->textAftr, textAfter.c_str() );
159 fl_unfreeze_form( dialog_->form_citation );
163 void FormCitation::updateCitekeys( string const & keysIn )
168 string keys = keysIn;
169 keys = frontStrip( split(keys, tmp, ',') );
170 while( !tmp.empty() ) {
171 citekeys.push_back( tmp );
172 keys = frontStrip( split(keys, tmp, ',') );
177 void FormCitation::updateBrowser( FL_OBJECT * browser,
178 vector<string> const & keys ) const
180 fl_clear_browser( browser );
182 for( unsigned int i = 0; i < keys.size(); ++i )
183 fl_add_browser_line( browser, keys[i].c_str() );
187 void FormCitation::setBibButtons( State status ) const
191 fl_activate_object( dialog_->addBtn );
192 fl_set_object_lcol( dialog_->addBtn, FL_BLACK );
196 fl_deactivate_object( dialog_->addBtn );
197 fl_set_object_lcol( dialog_->addBtn, FL_INACTIVE );
206 void FormCitation::setCiteButtons( State status ) const
211 fl_activate_object( dialog_->delBtn );
212 fl_set_object_lcol( dialog_->delBtn, FL_BLACK );
214 int sel = fl_get_browser( dialog_->citeBrsr );
217 fl_activate_object( dialog_->upBtn );
218 fl_set_object_lcol( dialog_->upBtn, FL_BLACK );
220 fl_deactivate_object( dialog_->upBtn );
221 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
224 if( sel != fl_get_browser_maxline(dialog_->citeBrsr)) {
225 fl_activate_object( dialog_->downBtn );
226 fl_set_object_lcol( dialog_->downBtn, FL_BLACK );
228 fl_deactivate_object( dialog_->downBtn );
229 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
236 fl_deactivate_object( dialog_->delBtn );
237 fl_set_object_lcol( dialog_->delBtn, FL_INACTIVE );
239 fl_deactivate_object( dialog_->upBtn );
240 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
242 fl_deactivate_object( dialog_->downBtn );
243 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
251 void FormCitation::setSize( int brsrHeight, bool bibPresent ) const
253 int const infoHeight = 110;
254 int const otherHeight = 140;
255 brsrHeight = max( brsrHeight, 175 );
256 int formHeight = brsrHeight + otherHeight;
258 if( bibPresent ) formHeight += infoHeight + 30;
259 fl_set_form_size( dialog_->form_citation, 430, formHeight );
261 // No resizing is alowed in the y-direction
262 fl_set_form_minsize( dialog_->form_citation, 430, formHeight );
263 fl_set_form_maxsize( dialog_->form_citation, 1000, formHeight );
266 fl_set_object_geometry( dialog_->box, 0, ypos, 430, formHeight );
268 fl_set_object_geometry( dialog_->citeBrsr, 10, ypos, 180, brsrHeight );
269 fl_set_object_geometry( dialog_->bibBrsr, 240, ypos, 180, brsrHeight );
271 fl_set_object_position( dialog_->addBtn, 200, ypos );
273 fl_set_object_position( dialog_->delBtn, 200, ypos );
275 fl_set_object_position( dialog_->upBtn, 200, ypos );
277 fl_set_object_position( dialog_->downBtn, 200, ypos );
279 ypos = brsrHeight+30; // base of Citation/Bibliography browsers
281 // awaiting natbib support
282 fl_hide_object( dialog_->style );
286 fl_set_object_position( dialog_->infoBrsr, 10, ypos );
287 fl_show_object( dialog_->infoBrsr );
291 fl_hide_object( dialog_->infoBrsr );
294 // awaiting natbib support
295 fl_hide_object( dialog_->textBefore );
297 fl_set_object_position( dialog_->textAftr, 100, ypos );
298 fl_set_object_position( dialog_->ok, 230, ypos+50 );
299 fl_set_object_position( dialog_->cancel, 330, ypos+50 );
303 void FormCitation::input( State cb )
308 fl_deselect_browser( dialog_->citeBrsr );
310 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
311 if( sel < 1 || sel > bibkeys.size() ) break;
313 // Put into infoBrsr the additional info associated with
314 // the selected bibBrsr key
315 fl_clear_browser( dialog_->infoBrsr );
316 fl_add_browser_line( dialog_->infoBrsr,
317 bibkeysInfo[sel-1].c_str() );
319 // Highlight the selected bibBrsr key in citeBrsr if present
320 vector<string>::iterator it =
321 find( citekeys.begin(), citekeys.end(), bibkeys[sel-1] );
323 if( it != citekeys.end() ) {
324 int n = it - citekeys.begin();
325 fl_select_browser_line( dialog_->citeBrsr, n+1 );
326 fl_set_browser_topline( dialog_->citeBrsr, n+1 );
329 if( !lv_->buffer()->isReadonly() ) {
330 if( it != citekeys.end() ) {
331 setBibButtons( OFF );
332 setCiteButtons( ON );
335 setCiteButtons( OFF );
342 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
343 if( sel < 1 || sel > citekeys.size() ) break;
345 if( !lv_->buffer()->isReadonly() ) {
346 setBibButtons( OFF );
347 setCiteButtons( ON );
350 // Highlight the selected citeBrsr key in bibBrsr
351 vector<string>::iterator it =
352 find( bibkeys.begin(), bibkeys.end(), citekeys[sel-1] );
354 if (it != bibkeys.end()) {
355 int n = it - bibkeys.begin();
356 fl_select_browser_line( dialog_->bibBrsr, n+1 );
357 fl_set_browser_topline( dialog_->bibBrsr, n+1 );
359 // Put into infoBrsr the additional info associated with
360 // the selected citeBrsr key
361 fl_clear_browser( dialog_->infoBrsr );
362 fl_add_browser_line( dialog_->infoBrsr,
363 bibkeysInfo[n].c_str() );
369 if( lv_->buffer()->isReadonly() ) break;
371 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
372 if( sel < 1 || sel > bibkeys.size() ) break;
374 // Add the selected bibBrsr key to citeBrsr
375 fl_addto_browser( dialog_->citeBrsr,
376 bibkeys[sel-1].c_str() );
377 citekeys.push_back( bibkeys[sel-1] );
379 int n = citekeys.size();
380 fl_select_browser_line( dialog_->citeBrsr, n );
382 setBibButtons( OFF );
383 setCiteButtons( ON );
388 if( lv_->buffer()->isReadonly() ) break;
390 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
391 if( sel < 1 || sel > citekeys.size() ) break;
393 // Remove the selected key from citeBrsr
394 fl_delete_browser_line( dialog_->citeBrsr, sel ) ;
395 citekeys.erase( citekeys.begin() + sel-1 );
398 setCiteButtons( OFF );
403 if( lv_->buffer()->isReadonly() ) break;
405 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
406 if( sel < 2 || sel > citekeys.size() ) break;
408 // Move the selected key up one line
409 vector<string>::iterator it = citekeys.begin() + sel-1;
412 fl_delete_browser_line( dialog_->citeBrsr, sel );
413 citekeys.erase( it );
415 fl_insert_browser_line( dialog_->citeBrsr, sel-1, tmp.c_str() );
416 fl_select_browser_line( dialog_->citeBrsr, sel-1 );
417 citekeys.insert( it-1, tmp );
418 setCiteButtons( ON );
423 if( lv_->buffer()->isReadonly() ) break;
425 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
426 if( sel < 1 || sel > citekeys.size()-1 ) break;
428 // Move the selected key down one line
429 vector<string>::iterator it = citekeys.begin() + sel-1;
432 fl_delete_browser_line( dialog_->citeBrsr, sel );
433 citekeys.erase( it );
435 fl_insert_browser_line( dialog_->citeBrsr, sel+1, tmp.c_str() );
436 fl_select_browser_line( dialog_->citeBrsr, sel+1 );
437 citekeys.insert( it+1, tmp );
438 setCiteButtons( ON );
447 void FormCitation::apply()
449 if( lv_->buffer()->isReadonly() ) return;
452 for( unsigned int i = 0; i < citekeys.size(); ++i ) {
453 if (i > 0) contents += ", ";
454 contents += citekeys[i];
457 textAfter = fl_get_input(dialog_->textAftr);
461 inset_->setContents( contents );
462 inset_->setOptions( textAfter );
463 lv_->view()->updateInset( inset_, true );
465 InsetCommandParams p( "cite", contents, textAfter );
466 lv_->getLyXFunc()->Dispatch( LFUN_INSERT_CITATION,
467 p.getAsString().c_str() );
472 void FormCitation::hide()
475 && dialog_->form_citation
476 && dialog_->form_citation->visible) {
477 fl_hide_form(dialog_->form_citation);
482 // free up the dialog for another inset
485 dialogIsOpen = false;
489 void FormCitation::free()
491 // we don't need to delete u and h here because
492 // hide() does that after disconnecting.
494 if (dialog_->form_citation
495 && dialog_->form_citation->visible) {
498 fl_free_form(dialog_->form_citation);
505 int FormCitation::WMHideCB(FL_FORM * form, void *)
507 // Ensure that the signals (u and h) are disconnected even if the
508 // window manager is used to close the dialog.
509 FormCitation * pre = static_cast<FormCitation*>(form->u_vdata);
515 void FormCitation::OKCB(FL_OBJECT * ob, long)
517 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
523 void FormCitation::CancelCB(FL_OBJECT * ob, long)
525 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
530 void FormCitation::InputCB(FL_OBJECT * ob, long data)
532 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
533 pre->input( static_cast<FormCitation::State>(data) );