/** * \file FormRef.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Angus Leeming * * Full author contact details are available in file CREDITS. */ #include #include "FormRef.h" #include "ControlRef.h" #include "forms/form_ref.h" #include "Tooltips.h" #include "xforms_helpers.h" #include "xformsBC.h" #include "insets/insetref.h" #include "support/lstrings.h" // trim #include "lyx_forms.h" using std::find; using std::max; using std::sort; using std::string; using std::vector; namespace lyx { using support::getStringFromVector; namespace frontend { typedef FormController > base_class; FormRef::FormRef(Dialog & parent) : base_class(parent, _("Cross-reference")), at_ref_(false) {} void FormRef::build() { dialog_.reset(build_ref(this)); for (int i = 0; !InsetRef::types[i].latex_name.empty(); ++i) fl_addto_choice(dialog_->choice_format, _(InsetRef::types[i].gui_name).c_str()); // Force the user to use the browser to change refs. fl_deactivate_object(dialog_->input_ref); fl_set_input_return(dialog_->input_name, FL_RETURN_CHANGED); fl_set_input_return(dialog_->input_ref, FL_RETURN_CHANGED); setPrehandler(dialog_->input_name); setPrehandler(dialog_->input_ref); // Manage the ok and cancel/close buttons bcview().setOK(dialog_->button_ok); bcview().setApply(dialog_->button_apply); bcview().setCancel(dialog_->button_close); bcview().setRestore(dialog_->button_restore); bcview().addReadOnly(dialog_->button_update); bcview().addReadOnly(dialog_->input_name); bcview().addReadOnly(dialog_->input_ref); // set up the tooltips string str = _("Select a document for labels."); tooltips().init(dialog_->choice_document, str); str = _("Sort the labels alphabetically."); tooltips().init(dialog_->check_sort, str); str = _("Go to selected label."); tooltips().init(dialog_->button_go, str); str = _("Update the list of labels."); tooltips().init(dialog_->button_update, str); str = _("Select format style of the cross-reference."); tooltips().init(dialog_->choice_format, str); } void FormRef::update() { fl_set_input(dialog_->input_ref, controller().params().getContents().c_str()); fl_set_input(dialog_->input_name, controller().params().getOptions().c_str()); fl_set_choice(dialog_->choice_format, InsetRef::getType(controller().params().getCmdName()) + 1); at_ref_ = false; switch_go_button(); // Name is irrelevant to LaTeX/Literate documents Kernel::DocType const doctype = kernel().docType(); if (doctype == Kernel::LATEX || doctype == Kernel::LITERATE) { setEnabled(dialog_->input_name, false); } else { setEnabled(dialog_->input_name, true); } // type is irrelevant to LinuxDoc/DocBook. if (doctype == Kernel::LINUXDOC || doctype == Kernel::DOCBOOK) { fl_set_choice(dialog_->choice_format, 1); setEnabled(dialog_->choice_format, false); } else { setEnabled(dialog_->choice_format, true); } // Get the available buffers vector const buffers = controller().getBufferList(); vector const choice_documents = getVector(dialog_->choice_document); // If different from the current contents of the choice, then update it if (buffers != choice_documents) { // create a string of entries " entry1 | entry2 | entry3 " // with which to initialise the xforms choice object. string const choice = ' ' + getStringFromVector(buffers, " | ") + ' '; fl_clear_choice(dialog_->choice_document); fl_addto_choice(dialog_->choice_document, choice.c_str()); } fl_set_choice(dialog_->choice_document, controller().getBufferNum() + 1); string const name = controller(). getBufferName(fl_get_choice(dialog_->choice_document) - 1); refs_ = controller().getLabelList(name); updateBrowser(refs_); } namespace { void updateHighlight(FL_OBJECT * browser, vector const & keys, string const & ref) { vector::const_iterator cit = (ref.empty()) ? keys.end() : find(keys.begin(), keys.end(), ref); if (cit == keys.end()) { fl_deselect_browser(browser); } else { int const i = static_cast(cit - keys.begin()); fl_set_browser_topline(browser, max(i-5, 1)); fl_select_browser_line(browser, i+1); } } } // namespace anon void FormRef::updateBrowser(vector const & akeys) const { vector keys(akeys); if (fl_get_button(dialog_->check_sort)) sort(keys.begin(), keys.end()); vector browser_keys = getVector(dialog_->browser_refs); if (browser_keys == keys) { updateHighlight(dialog_->browser_refs, keys, getString(dialog_->input_ref)); return; } fl_clear_browser(dialog_->browser_refs); for (vector::const_iterator it = keys.begin(); it != keys.end(); ++it) fl_add_browser_line(dialog_->browser_refs, it->c_str()); if (keys.empty()) { fl_add_browser_line(dialog_->browser_refs, _("*** No labels found in document ***").c_str()); setEnabled(dialog_->browser_refs, false); setEnabled(dialog_->check_sort, false); fl_set_input(dialog_->input_ref, ""); } else { setEnabled(dialog_->browser_refs, true); setEnabled(dialog_->check_sort, true); updateHighlight(dialog_->browser_refs, keys, getString(dialog_->input_ref)); } } void FormRef::apply() { int const type = fl_get_choice(dialog_->choice_format) - 1; controller().params().setCmdName(InsetRef::getName(type)); controller().params().setOptions(getString(dialog_->input_name)); controller().params().setContents(getString(dialog_->input_ref)); } ButtonPolicy::SMInput FormRef::input(FL_OBJECT * ob, long) { ButtonPolicy::SMInput activate(ButtonPolicy::SMI_VALID); if (ob == dialog_->button_go) { // goto label / go back // No change to data activate = ButtonPolicy::SMI_NOOP; at_ref_ = !at_ref_; if (at_ref_) { controller().gotoRef(getString(dialog_->input_ref)); } else { controller().gotoBookmark(); } switch_go_button(); } else if (ob == dialog_->browser_refs) { unsigned int sel = fl_get_browser(dialog_->browser_refs); if (sel < 1 || sel > refs_.size()) return ButtonPolicy::SMI_NOOP; if (!kernel().isBufferReadonly()) { string s = fl_get_browser_line(dialog_->browser_refs, sel); fl_set_input(dialog_->input_ref, s.c_str()); } if (at_ref_) controller().gotoBookmark(); at_ref_ = false; switch_go_button(); setEnabled(dialog_->choice_format, true); setEnabled(dialog_->button_go, true); fl_set_object_lcol(dialog_->input_ref, FL_BLACK); } else if (ob == dialog_->button_update || ob == dialog_->check_sort || ob == dialog_->choice_document) { // No change to data activate = ButtonPolicy::SMI_NOOP; if (ob == dialog_->button_update || ob == dialog_->choice_document) { string const name = controller().getBufferName(fl_get_choice(dialog_->choice_document) - 1); refs_ = controller().getLabelList(name); } fl_freeze_form(form()); updateBrowser(refs_); fl_unfreeze_form(form()); activate = ButtonPolicy::SMI_NOOP; } else if (ob == dialog_->choice_format) { int const type = fl_get_choice(dialog_->choice_format) - 1; if (controller().params().getCmdName() == InsetRef::getName(type)) { activate = ButtonPolicy::SMI_NOOP; } } return activate; } void FormRef::switch_go_button() { if (at_ref_) { fl_set_object_label(dialog_->button_go, _("Go back").c_str()); tooltips().init(dialog_->button_go, _("Go back to original place.").c_str()); } else { fl_set_object_label(dialog_->button_go, _("Go to").c_str()); tooltips().init(dialog_->button_go, _("Go to selected label.").c_str()); } fl_set_button_shortcut(dialog_->button_go, "#G", 1); fl_show_object(dialog_->button_go); } } // namespace frontend } // namespace lyx