2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 2000 The LyX Team.
9 * ======================================================
16 #include FORMS_H_LOCATION
17 #include "xform_macros.h"
18 #include "FormCitation.h"
22 #include "insets/insetcite.h"
23 #include "form_citation.h"
25 #include "BufferView.h"
26 #include "support/filetools.h"
29 #pragma implementation
38 C_RETURNCB(FormCitation, WMHideCB)
39 C_GENERICCB(FormCitation, OKCB)
40 C_GENERICCB(FormCitation, CancelCB)
41 C_GENERICCB(FormCitation, InputCB)
43 FormCitation::FormCitation(LyXView * lv, Dialogs * d)
44 : dialog_(0), lv_(lv), d_(d), h_(0), inset_(0), dialogIsOpen(false)
46 // let the dialog be shown
47 // These are permanent connections so we won't bother
48 // storing a copy because we won't be disconnecting.
49 d->showCitation.connect(slot(this, &FormCitation::showInset));
50 d->createCitation.connect(slot(this, &FormCitation::createInset));
51 d->hideCitation.connect(slot(this, &FormCitation::hideInset));
55 FormCitation::~FormCitation()
61 void FormCitation::build()
63 dialog_ = build_citation();
67 void FormCitation::showInset( InsetCitation * inset )
69 if( dialogIsOpen || inset == 0 ) return;
73 textAfter = inset->getOptions();
74 updateCitekeys(inset->getContents());
79 void FormCitation::createInset( string const & arg )
81 if( dialogIsOpen ) return;
84 if (contains(arg, "|")) {
85 keys = token(arg, '|', 0);
86 textAfter = token(arg, '|', 1);
97 void FormCitation::hideInset(InsetCitation * ti)
106 void FormCitation::show()
110 fl_set_form_atclose(dialog_->form_citation,
111 C_FormCitationWMHideCB, 0);
114 update(); // make sure its up-to-date
117 if (dialog_->form_citation->visible) {
118 fl_raise_form(dialog_->form_citation);
120 fl_show_form(dialog_->form_citation,
121 FL_PLACE_MOUSE | FL_FREE_SIZE,
124 u_ = d_->updateBufferDependent.
125 connect(slot(this, &FormCitation::update));
126 h_ = d_->hideBufferDependent.
127 connect(slot(this, &FormCitation::hide));
132 void FormCitation::update()
137 vector<pair<string,string> > blist =
138 lv_->buffer()->getBibkeyList();
140 for( unsigned int i = 0; i < blist.size(); ++i ) {
141 bibkeys.push_back(blist[i].first);
142 bibkeysInfo.push_back(blist[i].second);
147 fl_freeze_form( dialog_->form_citation );
149 updateBrowser( dialog_->bibBrsr, bibkeys );
150 updateBrowser( dialog_->citeBrsr, citekeys );
151 fl_clear_browser( dialog_->infoBrsr );
153 // No keys have been selected yet, so...
154 setBibButtons( OFF );
155 setCiteButtons( OFF );
157 int noKeys = max( bibkeys.size(), citekeys.size() );
159 // Place bounds, so that 4 <= noKeys <= 15
160 noKeys = max( 4, min(15, noKeys) );
162 // Re-size the form to accommodate the new browser size
163 int size = 20 * noKeys;
164 bool bibPresent = ( bibkeys.size() > 0 );
165 setSize( size, bibPresent );
167 fl_set_input( dialog_->textAftr, textAfter.c_str() );
169 fl_unfreeze_form( dialog_->form_citation );
173 void FormCitation::updateCitekeys( string const & keysIn )
178 string keys = keysIn;
179 keys = frontStrip( split(keys, tmp, ',') );
180 while( !tmp.empty() ) {
181 citekeys.push_back( tmp );
182 keys = frontStrip( split(keys, tmp, ',') );
187 void FormCitation::updateBrowser( FL_OBJECT * browser,
188 vector<string> const & keys ) const
190 fl_clear_browser( browser );
192 for( unsigned int i = 0; i < keys.size(); ++i )
193 fl_add_browser_line( browser, keys[i].c_str() );
197 void FormCitation::setBibButtons( State status ) const
201 fl_activate_object( dialog_->addBtn );
202 fl_set_object_lcol( dialog_->addBtn, FL_BLACK );
206 fl_deactivate_object( dialog_->addBtn );
207 fl_set_object_lcol( dialog_->addBtn, FL_INACTIVE );
216 void FormCitation::setCiteButtons( State status ) const
221 fl_activate_object( dialog_->delBtn );
222 fl_set_object_lcol( dialog_->delBtn, FL_BLACK );
224 int sel = fl_get_browser( dialog_->citeBrsr );
227 fl_activate_object( dialog_->upBtn );
228 fl_set_object_lcol( dialog_->upBtn, FL_BLACK );
230 fl_deactivate_object( dialog_->upBtn );
231 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
234 if( sel != fl_get_browser_maxline(dialog_->citeBrsr)) {
235 fl_activate_object( dialog_->downBtn );
236 fl_set_object_lcol( dialog_->downBtn, FL_BLACK );
238 fl_deactivate_object( dialog_->downBtn );
239 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
246 fl_deactivate_object( dialog_->delBtn );
247 fl_set_object_lcol( dialog_->delBtn, FL_INACTIVE );
249 fl_deactivate_object( dialog_->upBtn );
250 fl_set_object_lcol( dialog_->upBtn, FL_INACTIVE );
252 fl_deactivate_object( dialog_->downBtn );
253 fl_set_object_lcol( dialog_->downBtn, FL_INACTIVE );
261 void FormCitation::setSize( int brsrHeight, bool bibPresent ) const
263 int const infoHeight = 110;
264 int const otherHeight = 140;
265 brsrHeight = max( brsrHeight, 175 );
266 int formHeight = brsrHeight + otherHeight;
268 if( bibPresent ) formHeight += infoHeight + 30;
269 fl_set_form_size( dialog_->form_citation, 430, formHeight );
271 // No resizing is alowed in the y-direction
272 fl_set_form_minsize( dialog_->form_citation, 430, formHeight );
273 fl_set_form_maxsize( dialog_->form_citation, 1000, formHeight );
276 fl_set_object_geometry( dialog_->box, 0, ypos, 430, formHeight );
278 fl_set_object_geometry( dialog_->citeBrsr, 10, ypos, 180, brsrHeight );
279 fl_set_object_geometry( dialog_->bibBrsr, 240, ypos, 180, brsrHeight );
280 fl_set_object_geometry( dialog_->addBtn, 200, ypos, 30, 30 );
282 fl_set_object_geometry( dialog_->delBtn, 200, ypos, 30, 30 );
284 fl_set_object_geometry( dialog_->upBtn, 200, ypos, 30, 30 );
286 fl_set_object_geometry( dialog_->downBtn, 200, ypos, 30, 30 );
288 ypos = brsrHeight+30; // base of Citation/Bibliography browsers
290 // awaiting natbib support
291 fl_hide_object( dialog_->style );
295 fl_set_object_geometry( dialog_->infoBrsr, 10, ypos, 410, infoHeight );
296 fl_show_object( dialog_->infoBrsr );
300 fl_hide_object( dialog_->infoBrsr );
303 // awaiting natbib support
304 fl_hide_object( dialog_->textBefore );
306 fl_set_object_position(dialog_->textAftr, 100, ypos);
307 // fl_set_object_geometry( dialog_->textAftr, 100, ypos, 250, 30 );
308 fl_set_object_geometry( dialog_->ok, 230, ypos+50, 90, 30 );
309 fl_set_object_geometry( dialog_->cancel, 330, ypos+50, 90, 30 );
313 void FormCitation::input( State cb )
318 fl_deselect_browser( dialog_->citeBrsr );
320 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
321 if( sel < 1 || sel > bibkeys.size() ) break;
323 // Put into infoBrsr the additional info associated with
324 // the selected bibBrsr key
325 fl_clear_browser( dialog_->infoBrsr );
326 fl_add_browser_line( dialog_->infoBrsr,
327 bibkeysInfo[sel-1].c_str() );
329 // Highlight the selected bibBrsr key in citeBrsr if present
330 vector<string>::iterator it =
331 find( citekeys.begin(), citekeys.end(), bibkeys[sel-1] );
333 if( it != citekeys.end() ) {
334 int n = it - citekeys.begin();
335 fl_select_browser_line( dialog_->citeBrsr, n+1 );
336 fl_set_browser_topline( dialog_->citeBrsr, n+1 );
339 if( !lv_->buffer()->isReadonly() ) {
340 if( it != citekeys.end() ) {
341 setBibButtons( OFF );
342 setCiteButtons( ON );
345 setCiteButtons( OFF );
352 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
353 if( sel < 1 || sel > citekeys.size() ) break;
355 if( !lv_->buffer()->isReadonly() ) {
356 setBibButtons( OFF );
357 setCiteButtons( ON );
360 // Highlight the selected citeBrsr key in bibBrsr
361 vector<string>::iterator it =
362 find( bibkeys.begin(), bibkeys.end(), citekeys[sel-1] );
364 if (it != bibkeys.end()) {
365 int n = it - bibkeys.begin();
366 fl_select_browser_line( dialog_->bibBrsr, n+1 );
367 fl_set_browser_topline( dialog_->bibBrsr, n+1 );
369 // Put into infoBrsr the additional info associated with
370 // the selected citeBrsr key
371 fl_clear_browser( dialog_->infoBrsr );
372 fl_add_browser_line( dialog_->infoBrsr,
373 bibkeysInfo[n].c_str() );
379 if( lv_->buffer()->isReadonly() ) break;
381 unsigned int sel = fl_get_browser( dialog_->bibBrsr );
382 if( sel < 1 || sel > bibkeys.size() ) break;
384 // Add the selected bibBrsr key to citeBrsr
385 fl_addto_browser( dialog_->citeBrsr,
386 bibkeys[sel-1].c_str() );
387 citekeys.push_back( bibkeys[sel-1] );
389 int n = citekeys.size();
390 fl_select_browser_line( dialog_->citeBrsr, n );
392 setBibButtons( OFF );
393 setCiteButtons( ON );
398 if( lv_->buffer()->isReadonly() ) break;
400 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
401 if( sel < 1 || sel > citekeys.size() ) break;
403 // Remove the selected key from citeBrsr
404 fl_delete_browser_line( dialog_->citeBrsr, sel ) ;
405 citekeys.erase( citekeys.begin() + sel-1 );
408 setCiteButtons( OFF );
413 if( lv_->buffer()->isReadonly() ) break;
415 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
416 if( sel < 2 || sel > citekeys.size() ) break;
418 // Move the selected key up one line
419 vector<string>::iterator it = citekeys.begin() + sel-1;
422 fl_delete_browser_line( dialog_->citeBrsr, sel );
423 citekeys.erase( it );
425 fl_insert_browser_line( dialog_->citeBrsr, sel-1, tmp.c_str() );
426 fl_select_browser_line( dialog_->citeBrsr, sel-1 );
427 citekeys.insert( it-1, tmp );
428 setCiteButtons( ON );
433 if( lv_->buffer()->isReadonly() ) break;
435 unsigned int sel = fl_get_browser( dialog_->citeBrsr );
436 if( sel < 1 || sel > citekeys.size()-1 ) break;
438 // Move the selected key down one line
439 vector<string>::iterator it = citekeys.begin() + sel-1;
442 fl_delete_browser_line( dialog_->citeBrsr, sel );
443 citekeys.erase( it );
445 fl_insert_browser_line( dialog_->citeBrsr, sel+1, tmp.c_str() );
446 fl_select_browser_line( dialog_->citeBrsr, sel+1 );
447 citekeys.insert( it+1, tmp );
448 setCiteButtons( ON );
457 void FormCitation::apply()
459 if( lv_->buffer()->isReadonly() ) return;
462 for( unsigned int i = 0; i < citekeys.size(); ++i ) {
463 if (i > 0) tmp += ", ";
467 textAfter = fl_get_input(dialog_->textAftr);
471 inset_->setContents( tmp );
472 inset_->setOptions( textAfter );
473 lv_->view()->updateInset( inset_, true );
475 string arg = tmp + '|' + textAfter;
476 lv_->getLyXFunc()->Dispatch( LFUN_INSERT_CITATION, arg.c_str() );
481 void FormCitation::hide()
484 && dialog_->form_citation
485 && dialog_->form_citation->visible) {
486 fl_hide_form(dialog_->form_citation);
491 // free up the dialog for another inset
493 dialogIsOpen = false;
497 void FormCitation::free()
499 // we don't need to delete u and h here because
500 // hide() does that after disconnecting.
502 if (dialog_->form_citation
503 && dialog_->form_citation->visible) {
506 fl_free_form(dialog_->form_citation);
513 int FormCitation::WMHideCB(FL_FORM * form, void *)
515 // Ensure that the signals (u and h) are disconnected even if the
516 // window manager is used to close the dialog.
517 FormCitation * pre = static_cast<FormCitation*>(form->u_vdata);
523 void FormCitation::OKCB(FL_OBJECT * ob, long)
525 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
531 void FormCitation::CancelCB(FL_OBJECT * ob, long)
533 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
538 void FormCitation::InputCB(FL_OBJECT * ob, long data)
540 FormCitation * pre = static_cast<FormCitation*>(ob->form->u_vdata);
541 pre->input( static_cast<FormCitation::State>(data) );