11 #include FORMS_H_LOCATION
16 #include "lyx_gui_misc.h"
17 #include "BufferView.h"
21 #include "support/filetools.h"
23 extern BufferView * current_view;
25 FD_citation_form * citation_form = 0;
26 FD_bibitem_form * bibitem_form = 0;
27 static Combox * bibcombox = 0;
29 extern void UpdateInset(Inset* inset, bool mark_dirty = true);
30 void BibitemUpdate(Combox *);
31 FD_citation_form * create_form_citation_form(void);
32 FD_bibitem_form * create_form_bibitem_form(void);
35 extern "C" void bibitem_cb(FL_OBJECT *, long data)
38 case 1: // OK, citation
40 if(!current_view->buffer()->isReadonly()) {
41 InsetCommand * inset = static_cast<InsetCommand*>(citation_form->citation_form->u_vdata);
42 inset->setContents(bibcombox->getline());
43 inset->setOptions(fl_get_input(citation_form->label));
44 fl_hide_form(citation_form->citation_form);
45 // shouldn't mark the buffer dirty unless something
46 // was actually altered
50 // fall through to Cancel on RO-mode
52 case 0: fl_hide_form(citation_form->citation_form);
54 case 3: // OK, bibitem
56 if(!current_view->buffer()->isReadonly()) {
57 InsetCommand *inset = static_cast<InsetCommand*>(bibitem_form->bibitem_form->u_vdata);
58 inset->setContents(fl_get_input(bibitem_form->key));
59 inset->setOptions(fl_get_input(bibitem_form->label));
60 fl_hide_form(bibitem_form->bibitem_form);
61 // Does look like a hack? It is! (but will change at 0.13)
62 current_view->buffer()->text->RedoParagraph();
63 current_view->buffer()->update(1);
65 } // fall through to Cancel on RO-mode
67 case 2: // Cancel, bibitem
68 fl_hide_form(bibitem_form->bibitem_form); // Cancel, bibitem
73 FD_citation_form *create_form_citation_form(void)
76 FD_citation_form *fdui = (FD_citation_form *) fl_calloc(1, sizeof(FD_citation_form));
78 fdui->citation_form = fl_bgn_form(FL_NO_BOX, 220, 130);
79 obj = fl_add_box(FL_UP_BOX, 0, 0, 220, 130, "");
80 fdui->key = obj = fl_add_text(FL_NORMAL_TEXT, 20, 10, 60, 30, _("Key:"));
81 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
82 fl_set_object_lalign(obj, FL_ALIGN_RIGHT);
84 bibcombox = new Combox(FL_COMBOX_INPUT);
85 bibcombox->add(80, 10, 130, 30, 120);
87 obj = fl_add_button(FL_RETURN_BUTTON, 20, 90, 90, 30, _("OK"));
88 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
89 fl_set_object_callback(obj, bibitem_cb, 1);
90 obj = fl_add_button(FL_NORMAL_BUTTON, 120, 90, 90, 30, idex(_("Cancel|^[")));
91 fl_set_button_shortcut(obj, scex(_("Cancel|^[")), 1);
92 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
93 fl_set_object_callback(obj, bibitem_cb, 0);
94 fdui->label = obj = fl_add_input(FL_NORMAL_INPUT, 80, 50, 130, 30, idex(_("Remark:|#R")));
95 fl_set_input_shortcut(obj, scex(_("Remark:|#R")), 1);
96 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
99 //fdui->citation_form->fdui = fdui;
103 /*---------------------------------------*/
105 FD_bibitem_form *create_form_bibitem_form(void)
108 FD_bibitem_form *fdui = (FD_bibitem_form *) fl_calloc(1, sizeof(FD_bibitem_form));
110 fdui->bibitem_form = fl_bgn_form(FL_NO_BOX, 220, 130);
111 obj = fl_add_box(FL_UP_BOX, 0, 0, 220, 130, "");
112 fdui->key = obj = fl_add_input(FL_NORMAL_INPUT, 80, 10, 130, 30, idex(_("Key:|#K")));
113 fl_set_input_shortcut(obj, scex(_("Key:|#K")), 1);
114 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
115 obj = fl_add_button(FL_RETURN_BUTTON, 20, 90, 90, 30, _("OK"));
116 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
117 fl_set_object_callback(obj, bibitem_cb, 3);
118 obj = fl_add_button(FL_NORMAL_BUTTON, 120, 90, 90, 30, idex(_("Cancel|^[")));
119 fl_set_button_shortcut(obj, scex(_("Cancel|^[")), 1);
120 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
121 fl_set_object_callback(obj, bibitem_cb, 2);
122 fdui->label = obj = fl_add_input(FL_NORMAL_INPUT, 80, 50, 130, 30, idex(_("Label:|#L")));
123 fl_set_input_shortcut(obj, scex(_("Label:|#L")), 1);
124 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
127 //fdui->bibitem_form->fdui = fdui;
131 /*---------------------------------------*/
134 InsetCitation::InsetCitation(string const & key, string const & note):
135 InsetCommand("cite", key, note)
139 InsetCitation::~InsetCitation()
141 if(citation_form && citation_form->citation_form
142 && citation_form->citation_form->visible
143 && citation_form->citation_form->u_vdata == this)
144 fl_hide_form(citation_form->citation_form);
148 void InsetCitation::Edit(int, int)
150 if(current_view->buffer()->isReadonly())
153 if (!citation_form) {
154 citation_form = create_form_citation_form();
155 fl_set_form_atclose(citation_form->citation_form,
156 CancelCloseBoxCB, 0);
158 citation_form->citation_form->u_vdata = this;
160 BibitemUpdate(bibcombox);
161 if (!bibcombox->select_text(getContents().c_str()))
162 bibcombox->addline(getContents().c_str());
164 fl_set_input(citation_form->label, getOptions().c_str());
165 if (citation_form->citation_form->visible) {
166 fl_raise_form(citation_form->citation_form);
168 fl_show_form(citation_form->citation_form, FL_PLACE_MOUSE, FL_FULLBORDER,
174 string InsetCitation::getScreenLabel() const
180 if (!options.empty()) {
181 temp += ", " + options;
188 InsetBibKey::InsetBibKey(string const & key, string const & label):
189 InsetCommand("bibitem", key, label)
197 InsetBibKey::InsetBibKey(InsetBibKey const *b):
198 InsetCommand("bibitem", b->contents, b->options)
200 counter = b->counter;
204 InsetBibKey::~InsetBibKey()
206 if(bibitem_form && bibitem_form->bibitem_form
207 && bibitem_form->bibitem_form->visible)
208 fl_hide_form(bibitem_form->bibitem_form);
211 void InsetBibKey::setCounter(int c)
215 if (contents.empty())
216 contents += tostr(counter);
220 // I'm sorry but this is still necessary because \bibitem is used also
221 // as a LyX 2.x command, and lyxlex is not enough smart to understand
222 // real LaTeX commands. Yes, that could be fixed, but would be a waste
223 // of time cause LyX3 won't use lyxlex anyway. (ale)
224 void InsetBibKey::Write(FILE * file)
227 if (!options.empty()) {
233 fprintf(file, "\\bibitem %s\n", s.c_str());
237 string InsetBibKey::getScreenLabel() const
239 if (!options.empty())
242 return tostr(counter);
247 The value in "Key:" isn't allways set right after a few bibkey insets have
248 been added/removed. Perhaps the wrong object is deleted/used somewhere
252 void InsetBibKey::Edit(int, int)
254 if(current_view->buffer()->isReadonly())
258 bibitem_form = create_form_bibitem_form();
259 fl_set_form_atclose(bibitem_form->bibitem_form,
260 CancelCloseBoxCB, 0);
262 bibitem_form->bibitem_form->u_vdata = this;
263 // InsetBibtex uses the same form, with different labels
264 fl_set_object_label(bibitem_form->key, idex(_("Key:|#K")));
265 fl_set_button_shortcut(bibitem_form->key, scex(_("Key:|#K")), 1);
266 fl_set_object_label(bibitem_form->label, idex(_("Label:|#L")));
267 fl_set_button_shortcut(bibitem_form->label, scex(_("Label:|#L")), 1);
268 fl_set_input(bibitem_form->key, getContents().c_str());
269 fl_set_input(bibitem_form->label, getOptions().c_str());
270 if (bibitem_form->bibitem_form->visible) {
271 fl_raise_form(bibitem_form->bibitem_form);
273 fl_show_form(bibitem_form->bibitem_form, FL_PLACE_MOUSE,
275 _("Bibliography item"));
281 InsetBibtex::InsetBibtex(string const & dbase, string const & style,
283 :InsetCommand("BibTeX", dbase, style), owner(o)
288 string InsetBibtex::getScreenLabel() const
290 return _("BibTeX Generated References");
294 int InsetBibtex::Latex(FILE *file, signed char /*fragile*/)
297 signed char dummy = 0;
298 int result = Latex(bib, dummy);
299 fprintf(file, "%s", bib.c_str());
304 int InsetBibtex::Latex(string &file, signed char /*fragile*/)
306 // this looks like an horrible hack and it is :) The problem
307 // is that owner is not initialized correctly when the bib
308 // inset is cut and pasted. Such hacks will not be needed
311 owner = current_view->buffer();
313 // If we generate in a temp dir, we might need to give an
314 // absolute path there. This is a bit complicated since we can
315 // have a comma-separated list of bibliographies
316 string db_in, adb, db_out;
317 db_in = getContents();
318 db_in= split(db_in, adb, ',');
319 while(!adb.empty()) {
320 if (!owner->niceFile &&
321 IsFileReadable(MakeAbsPath(adb, owner->filepath)+".bib"))
322 adb = MakeAbsPath(adb, owner->filepath);
325 db_in= split(db_in, adb,',');
327 db_out = strip(db_out, ',');
331 && IsFileReadable(MakeAbsPath(getOptions(), owner->filepath)
333 style = MakeAbsPath(getOptions(), owner->filepath);
335 style = getOptions();
337 file += "\\bibliographystyle{";
340 file += "\\bibliography{";
347 // This method returns a comma separated list of Bibtex entries
348 string InsetBibtex::getKeys()
350 // This hack is copied from InsetBibtex::Latex.
351 // Is it still needed? Probably yes.
353 owner = current_view->buffer();
357 string bibfiles = getContents();
358 bibfiles = split(bibfiles, tmp, ',');
359 while(!tmp.empty()) {
360 string fil = findtexfile(ChangeExtension(tmp, "bib", false),
362 lyxerr << "Bibfile: " << fil << endl;
363 // If we didn't find a matching file name just fail silently
365 // This is a _very_ simple parser for Bibtex database
366 // files. All it does is to look for lines starting
367 // in @ and not being @preamble and @string entries.
368 // It does NOT do any syntax checking!
369 ifstream ifs(fil.c_str());
371 while (getline(ifs, linebuf)) {
372 if (prefixIs(linebuf, "@")) {
373 linebuf = subst(linebuf, '{', '(');
374 linebuf = split(linebuf, tmp, '(');
375 tmp = lowercase(tmp);
376 if (!prefixIs(tmp, "@string")
377 && !prefixIs(tmp, "@preamble")) {
378 linebuf = split(linebuf,
388 // Get next file name
389 bibfiles = split(bibfiles, tmp, ',');
395 // BibTeX should have its own dialog. This is provisional.
396 void InsetBibtex::Edit(int, int)
399 bibitem_form = create_form_bibitem_form();
400 fl_set_form_atclose(bibitem_form->bibitem_form,
401 CancelCloseBoxCB, 0);
404 bibitem_form->bibitem_form->u_vdata = this;
405 fl_set_object_label(bibitem_form->key, _("Database:"));
406 fl_set_object_label(bibitem_form->label, _("Style: "));
407 fl_set_input(bibitem_form->key, getContents().c_str());
408 fl_set_input(bibitem_form->label, getOptions().c_str());
409 if (bibitem_form->bibitem_form->visible) {
410 fl_raise_form(bibitem_form->bibitem_form);
412 fl_show_form(bibitem_form->bibitem_form,
413 FL_PLACE_MOUSE, FL_FULLBORDER,
419 bool InsetBibtex::addDatabase(string const & db)
421 if (!contains(contents, db.c_str())) {
422 if (!contents.empty())
431 bool InsetBibtex::delDatabase(string const & db)
433 if (contains(contents, db.c_str())) {
435 int n = tokenPos(contents, ',', bd);
437 // Weird code, would someone care to explain this?(Lgb)
440 contents = subst(contents, tmp.c_str(), ", ");
442 contents = split(contents, bd, ',');
450 // This function should be in LyXView when multiframe works ale970302
451 void BibitemUpdate(Combox * combox)
455 if (!current_view->available())
458 string tmp, bibkeys = current_view->buffer()->getBibkeyList(',');
459 bibkeys = split(bibkeys, tmp,',');
460 while (!tmp.empty()) {
461 combox->addto(tmp.c_str());
462 bibkeys = split(bibkeys, tmp,',');
468 // ale070405 This function maybe shouldn't be here. We'll fix this at 0.13.
469 int bibitemMaxWidth(LyXFont const & font)
472 // Does look like a hack? It is! (but will change at 0.13)
473 LyXParagraph * par = current_view->buffer()->paragraph;
477 int wx = par->bibkey->Width(font);
487 string bibitemWidthest()
490 // Does look like a hack? It is! (but will change at 0.13)
491 LyXParagraph * par = current_view->buffer()->paragraph;
492 InsetBibKey * bkey = 0;
497 int wx = par->bibkey->Width(font);
506 if (bkey && !bkey->getScreenLabel().empty())
507 return bkey->getScreenLabel();