]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormBibtex.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / xforms / FormBibtex.C
index 09ea0ead7582531bc366131af767bccef77c9e33..3703e07f82708cf34b7ec67ba64724e708ce2668 100644 (file)
 /**
  * \file FormBibtex.C
- * Copyright 2001 the LyX Team
- * Read the file COPYING
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
  * \author Angus Leeming
  * \author John Levon
- * \author Herbert Voss <voss@lyx.org>
+ * \author Herbert Voß
+ * \author Rob Lahaye
+ *
+ * Full author contact details are available in file CREDITS.
  */
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include <config.h>
-#include "xformsBC.h"
-#include "ControlBibtex.h"
+
 #include "FormBibtex.h"
-#include "form_bibtex.h"
-#include "gettext.h"
-#include "debug.h"
+#include "ControlBibtex.h"
+#include "forms/form_bibtex.h"
+
+#include "Tooltips.h"
 #include "xforms_helpers.h"
-#include "helper_funcs.h"
-#include "support/LAssert.h"
-#include "support/lstrings.h"
+#include "xformsBC.h"
+
 #include "support/filetools.h"
+#include "support/lstrings.h"
+#include "support/lyxalgo.h"
+
+#include "lyx_forms.h"
 
+using std::vector;
+using std::string;
 
-typedef FormCB<ControlBibtex, FormDB<FD_form_bibtex> > base_class;
+namespace lyx {
 
-FormBibtex::FormBibtex(ControlBibtex & c)
-       : base_class(c, _("BibTeX Database"))
+using support::ChangeExtension;
+using support::compare;
+using support::contains;
+using support::FileFilterList;
+using support::getStringFromVector;
+using support::getVectorFromString;
+using support::OnlyFilename;
+using support::prefixIs;
+using support::split;
+
+namespace frontend {
+
+
+typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
+
+FormBibtex::FormBibtex(Dialog & parent)
+       : base_class(parent, _("BibTeX Database"))
 {}
 
 
 void FormBibtex::build()
 {
-       dialog_.reset(build_bibtex());
-
-       fl_set_input_return(dialog_->database, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->style, FL_RETURN_CHANGED);
-
-        // Manage the ok, apply, restore and cancel/close buttons
-       bc().setOK(dialog_->button_ok);
-       bc().setCancel(dialog_->button_cancel);
-
-       bc().addReadOnly(dialog_->database_browse);
-       bc().addReadOnly(dialog_->database);
-       bc().addReadOnly(dialog_->style_browse);
-       bc().addReadOnly(dialog_->style);
-       bc().addReadOnly(dialog_->radio_bibtotoc);
-
-       // set up the feedback mechanism
-       setPrehandler(dialog_->database_browse);
-       setPrehandler(dialog_->database);
-       setPrehandler(dialog_->style_browse);
-       setPrehandler(dialog_->style);
-       setPrehandler(dialog_->radio_bibtotoc);
+       dialog_.reset(build_bibtex(this));
+
+       // Manage the ok, apply, restore and cancel/close buttons
+       bcview().setOK(dialog_->button_ok);
+       bcview().setApply(dialog_->button_apply);
+       bcview().setCancel(dialog_->button_close);
+       bcview().setRestore(dialog_->button_restore);
+
+       // disable for read-only documents
+       bcview().addReadOnly(dialog_->input_database);
+       bcview().addReadOnly(dialog_->button_database_browse);
+       bcview().addReadOnly(dialog_->button_style_browse);
+       bcview().addReadOnly(dialog_->button_rescan);
+       bcview().addReadOnly(dialog_->input_style);
+       bcview().addReadOnly(dialog_->check_bibtotoc);
+       bcview().addReadOnly(dialog_->choice_btprint);
+
+       // trigger an input event for cut&paste with middle mouse button.
+       setPrehandler(dialog_->input_database);
+       setPrehandler(dialog_->input_style);
+
+       fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
+
+       // callback for double click in browser
+       fl_set_browser_dblclick_callback(dialog_->browser_styles,
+                                        C_FormDialogView_InputCB, 2);
+
+       fl_addto_choice(dialog_->choice_btprint,
+                       _(" all cited references "
+                         "| all uncited references "
+                         "| all references ").c_str());
+
+       // set up the tooltips
+       string str = _("The database you want to cite from. Insert it "
+                      "without the default extension \".bib\". Use comma "
+                      "to separate databases.");
+       tooltips().init(dialog_->button_database_browse, str);
+
+       str = _("Browse directory for BibTeX stylefiles");
+       tooltips().init(dialog_->button_style_browse, str);
+
+       str = _("The BibTeX style to use (only one allowed). Insert it without "
+               "the default extension \".bst\" and without path.");
+       tooltips().init(dialog_->input_style, str);
+
+       str = _("Select if the bibliography should appear in the Table "
+               "of Contents");
+       tooltips().init(dialog_->check_bibtotoc, str);
+
+       str = _("Double click to choose a BibTeX style from the list.");
+       tooltips().init(dialog_->browser_styles, str);
+
+#if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL == 0)
+       // Work-around xforms' bug; enable tooltips for browser widgets.
+       setPrehandler(dialog_->browser_styles);
+#endif
+
+       str = _("Updates your TeX system for a new bibstyle list. Only "
+               "the styles which are in directories where TeX finds them "
+               "are listed!");
+       tooltips().init(dialog_->button_rescan, str);
+
+       str = _("The bibliography section contains...");
+       tooltips().init(dialog_->choice_btprint, str);
 }
 
 
-ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
+ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
 {
-       if (ob == dialog_->database_browse) {
-               // When browsing, take the first file only 
-               string const in_name = fl_get_input(dialog_->database);
-               string out_name = 
-                       controller().Browse("",
-                                           "Select Database",
-                                           "*.bib| BibTeX Databases (*.bib)");
+       if (ob == dialog_->button_database_browse) {
+               // When browsing, take the first file only
+               string const in_name = getString(dialog_->input_database);
+               string out_name = controller().browseBib("");
                if (!out_name.empty()) {
                        // add the database to any existing ones
                        if (!in_name.empty())
-                               out_name = in_name + ", " + out_name;
+                               out_name = in_name + ',' + out_name;
 
-                       fl_freeze_form(form()); 
-                       fl_set_input(dialog_->database, out_name.c_str());
-                       fl_unfreeze_form(form()); 
+                       fl_set_input(dialog_->input_database, out_name.c_str());
                }
-       }
 
-       if (ob == dialog_->style_browse) {
-               string const in_name = fl_get_input(dialog_->style);
-               string out_name = 
-                       controller().Browse(in_name,
-                                           "Select BibTeX-Style",
-                                           "*.bst| BibTeX Styles (*.bst)");
-               if (!out_name.empty()) {
-                       fl_freeze_form(form()); 
-                       fl_set_input(dialog_->style, out_name.c_str());
-                       fl_unfreeze_form(form()); 
+       } else if (ob == dialog_->button_style_browse) {
+               string const in_name = getString(dialog_->input_style);
+               string const style = controller().browseBst(in_name);
+               if (!style.empty()) {
+                       fl_set_input(dialog_->input_style, style.c_str());
+               }
+
+       } else if (ob == dialog_->browser_styles && ob_value == 2) {
+               // double clicked in styles browser
+               string const style = getString(dialog_->browser_styles);
+               if (style.empty()) {
+                       return ButtonPolicy::SMI_NOOP;
+               } else {
+                       fl_set_input(dialog_->input_style,
+                                       ChangeExtension(style, "").c_str());
                }
+               // reset the browser so that the following
+               // single-click callback doesn't do anything
+               fl_deselect_browser(dialog_->browser_styles);
+
+       } else if (ob == dialog_->button_rescan) {
+               fl_clear_browser(dialog_->browser_styles);
+               controller().rescanBibStyles();
+               vector<string> styles;
+               controller().getBibStyles(styles);
+               fl_add_browser_line(dialog_->browser_styles,
+                                   getStringFromVector(styles, "\n").c_str());
        }
-  
-       if (!compare(fl_get_input(dialog_->database),"")) {
+
+       // with an empty database nothing makes sense ...
+       if (!compare(fl_get_input(dialog_->input_database), "")) {
                return ButtonPolicy::SMI_NOOP;
        }
 
@@ -102,106 +176,114 @@ ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
 
 void FormBibtex::update()
 {
-       fl_set_input(dialog_->database,
+       fl_set_input(dialog_->input_database,
                     controller().params().getContents().c_str());
-        string bibtotoc = "bibtotoc";
-       string bibstyle (controller().params().getOptions().c_str());
-       if (prefixIs(bibstyle,bibtotoc)) { // bibtotoc exists?
-               fl_set_button(dialog_->radio_bibtotoc,1);
-               if (contains(bibstyle,',')) { // bibstyle exists?
-                       bibstyle = split(bibstyle,bibtotoc,',');
+
+       string bibtotoc = "bibtotoc";
+       string bibstyle = controller().params().getOptions();
+
+       bool const bibtopic = controller().usingBibtopic();
+       bool const bibtotoc_exists = prefixIs(bibstyle, bibtotoc);
+       fl_set_button(dialog_->check_bibtotoc, bibtotoc_exists && !bibtopic);
+       setEnabled(dialog_->check_bibtotoc, !bibtopic);
+       if (bibtotoc_exists) {
+               if (contains(bibstyle, ',')) { // bibstyle exists?
+                       bibstyle = split(bibstyle, bibtotoc, ',');
                } else {
-                       bibstyle = "";
+                       bibstyle.erase();
                }
+       }
+       fl_set_input(dialog_->input_style, bibstyle.c_str());
 
-               fl_set_input(dialog_->style,bibstyle.c_str());
+       string btprint = controller().params().getSecOptions();
+       int btp = 1;
+       if (btprint == "btPrintNotCited")
+               btp = 2;
+       else if (btprint == "btPrintAll")
+               btp = 3;
 
-       } else {
-               fl_set_button(dialog_->radio_bibtotoc,0);
-               fl_set_input(dialog_->style,bibstyle.c_str());
-       }
-}
+       fl_set_choice(dialog_->choice_btprint, btp);
+       setEnabled(dialog_->choice_btprint, bibtopic);
 
-namespace {
+       vector<string> styles;
+       controller().getBibStyles(styles);
 
-// Remove all duplicate entries in c.
-// Taken stright out of Stroustrup
-template<class C> void eliminate_duplicates(C & c)
-{
-       std::sort(c.begin(), c.end()); // sort
-       typename C::iterator p = std::unique(c.begin(), c.end()); // compact
-       c.erase(p, c.end()); // shrink
+       fl_clear_browser(dialog_->browser_styles);
+       fl_add_browser_line(dialog_->browser_styles,
+                           getStringFromVector(styles, "\n").c_str());
 }
 
+namespace {
+
 string const unique_and_no_extensions(string const & str_in)
 {
-       std::vector<string> dbase = getVectorFromString(str_in);
-       for (std::vector<string>::iterator it = dbase.begin();
+       vector<string> dbase = getVectorFromString(str_in);
+       for (vector<string>::iterator it = dbase.begin();
             it != dbase.end(); ++it) {
-               *it = ChangeExtension(*it, "");
+               *it = ChangeExtension(*it, string());
        }
        eliminate_duplicates(dbase);
-       return subst(getStringFromVector(dbase),",",", ");
+       return getStringFromVector(dbase);
 }
+
 } // namespace anon
 
 
 void FormBibtex::apply()
 {
-       string const db = fl_get_input(dialog_->database);
+       string const db = getString(dialog_->input_database);
        if (db.empty()) {
                // no database -> no bibtex-command and no options!
                controller().params().setContents("");
                controller().params().setOptions("");
+               controller().params().setSecOptions("");
                return;
        }
-       
+
        controller().params().setContents(unique_and_no_extensions(db));
 
        // empty is valid!
-       string bibstyle = fl_get_input(dialog_->style);
+       string bibstyle = getString(dialog_->input_style);
        if (!bibstyle.empty()) {
                // save the BibTeX style without any ".bst" extension
                bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
        }
 
-       bool const bibtotoc = fl_get_button(dialog_->radio_bibtotoc);
-       
-       if (bibtotoc && (!bibstyle.empty())) {
-               // both bibtotoc and style
-               controller().params().setOptions("bibtotoc,"+bibstyle);
-
-       } else if (bibtotoc) {
-               // bibtotoc and no style
-               controller().params().setOptions("bibtotoc");
+       bool const addtotoc = fl_get_button(dialog_->check_bibtotoc);
+       string const bibtotoc = addtotoc ? "bibtotoc" : "";
+       if (addtotoc && !bibstyle.empty()) {
+               // Both bibtotoc and style.
+               controller().params().setOptions(bibtotoc + ',' + bibstyle);
 
-       } else if (!bibstyle.empty()){
-               // only style
-               controller().params().setOptions(bibstyle);
+       } else {
+               // At least one of addtotoc and bibstyle is empty.
+               // No harm to output both!
+               controller().params().setOptions(bibtotoc + bibstyle);
        }
-}
-
-
-string const FormBibtex::getVerboseTooltip(FL_OBJECT * ob) const
-{
-       string str;
-
-       if (ob == dialog_->database) {
-               str = N_("The database you want to cite from. Insert it without the default extension \".bib\". If you insert it with the browser, LyX strips the extension. Several databases must be separated by a comma: \"natbib, books\".");
 
-       } else if (ob == dialog_->database_browse) {
-               str = _("Browse your directory for BibTeX databases.");
-
-       } else if (ob == dialog_->style) {
-               str = _("The BibTeX style to use (only one allowed). Insert it without the default extension \".bst\" and without path. Most of the bibstyles are stored in $TEXMF/bibtex/bst. $TEXMF is the root dir of the local TeX tree. In \"Help->TeX Info\" you can list all installed styles.");
-
-       } else if (ob == dialog_->style_browse) {
-               str = _("Browse your directory for BibTeX stylefiles.");
-
-       } else if (ob == dialog_->radio_bibtotoc) {
-               str = _("Activate this option if you want the bibliography to appear in the Table of Contents (which doesn't happen by default).");
+       // bibtopic allows three kinds of sections:
+       // 1. sections that include all cited references of the database(s)
+       // 2. sec. that include all uncited references of the database(s)
+       // 3. sec. that include all references of the database(s), cited or not
+       if (controller().usingBibtopic()){
+               int btp = fl_get_choice(dialog_->choice_btprint);
+               switch (btp) {
+               case 1:
+                       controller().params().setSecOptions("btPrintCited");
+                       break;
+               case 2:
+                       controller().params().setSecOptions("btPrintNotCited");
+                       break;
+               case 3:
+                       controller().params().setSecOptions("btPrintAll");
+                       break;
+               }
        }
 
-       return str;
+       else
+               controller().params().setSecOptions("");
+
 }
+
+} // namespace frontend
+} // namespace lyx