]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormBibtex.C
Bugfixes: checkboxes to radiobuttons (from J�rgen S) and remove a little
[lyx.git] / src / frontends / xforms / FormBibtex.C
index 16a328cbb726ca392380c9aa23d742900b2ffaf5..591a33068b89bca91a40eb80eaeb8dc4c678b60d 100644 (file)
  *
  * \author Angus Leeming
  * \author John Levon
+ * \author Herbert Voss <voss@lyx.org>
  */
 
-#include <config.h>
-
-#include FORMS_H_LOCATION
-
 #ifdef __GNUG__
 #pragma implementation
 #endif
 
-
-#include "Dialogs.h"
+#include <config.h>
+#include "xformsBC.h"
+#include "ControlBibtex.h"
 #include "FormBibtex.h"
-#include "LyXView.h"
-#include "buffer.h"
 #include "form_bibtex.h"
-#include "lyxfunc.h"
+#include "gettext.h"
 #include "debug.h"
+#include "helper_funcs.h"
+#include "support/lstrings.h"
+#include "support/filetools.h"
 
-using std::endl;
 
-FormBibtex::FormBibtex(LyXView * lv, Dialogs * d)
-       : FormCommand(lv, d, _("BibTeX Database"), new OkCancelReadOnlyPolicy),
-         dialog_(0)
-{
-       d->showBibtex.connect(slot(this, &FormBibtex::showInset));
-}
+typedef FormCB<ControlBibtex, FormDB<FD_form_bibtex> > base_class;
 
+FormBibtex::FormBibtex(ControlBibtex & c)
+       : base_class(c, _("BibTeX Database"))
+{}
 
-FormBibtex::~FormBibtex()
+
+void FormBibtex::build()
 {
-       delete dialog_;
-}
+       dialog_.reset(build_bibtex());
 
+       fl_set_input_return(dialog_->database, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->style, FL_RETURN_CHANGED);
 
-FL_FORM * FormBibtex::form() const
-{
-       if (dialog_)
-               return dialog_->form;
-       return 0;
+        // 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);
 }
 
 
-void FormBibtex::connect()
+ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
 {
-       fl_set_form_maxsize(form(), 2 * minw_, minh_);
-       FormCommand::connect();
-}
-       
+       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 (!out_name.empty()) {
+                       // add the database to any existing ones
+                       if (!in_name.empty())
+                               out_name = in_name + ", " + out_name;
+
+                       fl_freeze_form(form()); 
+                       fl_set_input(dialog_->database, out_name.c_str());
+                       fl_unfreeze_form(form()); 
+               }
+       }
+
+       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()); 
+               }
+       }
+  
+       if (!compare(fl_get_input(dialog_->database),"")) {
+               return ButtonPolicy::SMI_NOOP;
+       }
 
-void FormBibtex::build()
-{
-       dialog_ = build_bibtex();
+       return ButtonPolicy::SMI_VALID;
+}
 
-       // Workaround dumb xforms sizing bug
-       minw_ = form()->w;
-       minh_ = form()->h;
 
-       fl_set_input_return(dialog_->database, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->style, FL_RETURN_CHANGED);
+void FormBibtex::update()
+{
+       fl_set_input(dialog_->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,',');
+               } else {
+                       bibstyle = "";
+               }
 
-        // Manage the ok, apply, restore and cancel/close buttons
-       bc_.setOK(dialog_->button_ok);
-       bc_.setCancel(dialog_->button_cancel);
-       bc_.refresh();
+               fl_set_input(dialog_->style,bibstyle.c_str());
 
-       bc_.addReadOnly(dialog_->database);
-       bc_.addReadOnly(dialog_->style);
+       } else {
+               fl_set_button(dialog_->radio_bibtotoc,0);
+               fl_set_input(dialog_->style,bibstyle.c_str());
+       }
 }
 
+namespace {
 
-bool FormBibtex::input(FL_OBJECT *, long)
+// Remove all duplicate entries in c.
+// Taken stright out of Stroustrup
+template<class C> void eliminate_duplicates(C & c)
 {
-       // minimal validation 
-       if (!strcmp(fl_get_input(dialog_->database),""))
-               return false;
-
-       return true;
+       std::sort(c.begin(), c.end()); // sort
+       typename C::iterator p = std::unique(c.begin(), c.end()); // compact
+       c.erase(p, c.end()); // shrink
 }
 
-
-void FormBibtex::update()
+string const unique_and_no_extensions(string const & str_in)
 {
-       fl_set_input(dialog_->database, params.getContents().c_str());
-       fl_set_input(dialog_->style, params.getOptions().c_str());
-       // Surely, this should reset the buttons to their original state?
-       // It doesn't. Instead "Restore" becomes a "Close"
-       //bc_.refresh();
-       bc_.readOnly(lv_->buffer()->isReadonly());
+       std::vector<string> dbase = getVectorFromString(str_in);
+       for (std::vector<string>::iterator it = dbase.begin();
+            it != dbase.end(); ++it) {
+               *it = ChangeExtension(*it, "");
+       }
+       eliminate_duplicates(dbase);
+       return subst(getStringFromVector(dbase),",",", ");
 }
+} // namespace anon
 
 
 void FormBibtex::apply()
 {
-       if (lv_->buffer()->isReadonly())
+       string const db = fl_get_input(dialog_->database);
+       if (db.empty()) {
+               // no database -> no bibtex-command and no options!
+               controller().params().setContents("");
+               controller().params().setOptions("");
                return;
+       }
+       
+       controller().params().setContents(unique_and_no_extensions(db));
 
-       params.setContents(fl_get_input(dialog_->database));
-       params.setOptions(fl_get_input(dialog_->style));
-
-       if (inset_ != 0) {
-               // Only update if contents have changed
-               if (params != inset_->params()) {
-                       if (params.getContents() != inset_->params().getContents())
-                               lv_->view()->ChangeCitationsIfUnique(
-                                       inset_->params().getContents(), params.getContents());
-
-               inset_->setParams(params);
-               lv_->view()->updateInset(inset_, true);
+       // empty is valid!
+       string bibstyle = fl_get_input(dialog_->style);
+       if (!bibstyle.empty()) {
+               // save the BibTeX style without any ".bst" extension
+               bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
+       }
 
-               // We need to do a redraw because the maximum
-               // InsetBibKey width could have changed
-               lv_->view()->redraw();
-               lv_->view()->fitCursor(lv_->view()->getLyXText());
-               }
-       } else
-               lyxerr[Debug::GUI] << "Editing non-existent bibtex inset !" << endl;
+       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");
+
+       } else if (!bibstyle.empty()){
+               // only style
+               controller().params().setOptions(bibstyle);
+       }
 }