lyx_mirror/src/frontends/xforms/FormRef.C
Angus Leeming 2a31934f38 Wrap most of the frontend code up inside namespace lyx::frontend.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8766 a592a061-630c-0410-9148-cb99ea01b6c8
2004-05-19 15:11:37 +00:00

298 lines
7.7 KiB
C

/**
* \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 <config.h>
#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<ControlRef, FormView<FD_ref> > 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 references.");
tooltips().init(dialog_->choice_document, str);
str = _("Sort the references alphabetically.");
tooltips().init(dialog_->check_sort, str);
str = _("Go to selected reference.");
tooltips().init(dialog_->button_go, str);
str = _("Update the list of references.");
tooltips().init(dialog_->button_update, str);
str = _("Select format style of the 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::DocTypes 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<string> const buffers = controller().getBufferList();
vector<string> 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<string> const & keys,
string const & ref)
{
vector<string>::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<int>(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<string> const & akeys) const
{
vector<string> keys(akeys);
if (fl_get_button(dialog_->check_sort))
sort(keys.begin(), keys.end());
vector<string> 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<string>::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 reference / 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 reference.").c_str());
}
fl_set_button_shortcut(dialog_->button_go, "#G", 1);
fl_show_object(dialog_->button_go);
}
} // namespace frontend
} // namespace lyx