-// -*- C++ -*-
-/* This file is part of
- * ======================================================
+/**
+ * \file FormRef.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
- * LyX, The Document Processor
+ * \author Angus Leeming
*
- * Copyright 2000 The LyX Team.
- *
- * ======================================================
+ * Full author contact details are available in file CREDITS.
*/
#include <config.h>
-#include FORMS_H_LOCATION
+#include "FormRef.h"
+#include "ControlRef.h"
+#include "forms/form_ref.h"
-#ifdef __GNUG__
-#pragma implementation
-#endif
+#include "Tooltips.h"
+#include "xforms_helpers.h"
+#include "xformsBC.h"
+#include "insets/insetref.h"
-#include "Dialogs.h"
-#include "FormRef.h"
-#include "LyXView.h"
-#include "buffer.h"
-#include "form_ref.h"
-#include "lyxfunc.h"
+#include "support/lstrings.h" // trim
-#include <algorithm>
+#include "lyx_forms.h"
+using lyx::support::getStringFromVector;
+
+using std::find;
+using std::max;
using std::sort;
+using std::string;
using std::vector;
-static int const minw_hb = 250;
-static int minw_sb;
-
-FormRef::FormRef(LyXView * lv, Dialogs * d)
- : FormCommand(lv, d, _("Reference")), toggle(GOBACK), dialog_(0)
-{
- // let the dialog be shown
- // These are permanent connections so we won't bother
- // storing a copy because we won't be disconnecting.
- d->showRef.connect(slot(this, &FormRef::showInset));
- d->createRef.connect(slot(this, &FormRef::createInset));
-}
+typedef FormController<ControlRef, FormView<FD_ref> > base_class;
-FormRef::~FormRef()
-{
- delete dialog_;
-}
+FormRef::FormRef(Dialog & parent)
+ : base_class(parent, _("Cross-reference")),
+ at_ref_(false)
+{}
-FL_FORM * FormRef::form() const
+void FormRef::build()
{
- if ( dialog_ ) return dialog_->form;
- return 0;
+ 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::connect()
+void FormRef::update()
{
- fl_set_form_maxsize( form(), 2*minw_, minh_ );
- FormCommand::connect();
-}
-
+ 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);
+ }
-void FormRef::disconnect()
-{
- refs.clear();
- FormCommand::disconnect();
-}
+ // 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);
-void FormRef::build()
-{
- dialog_ = build_ref();
+ // 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_addto_choice(dialog_->type,
- _(" Ref | Page | TextRef | TextPage | PrettyRef "));
+ fl_set_choice(dialog_->choice_document,
+ controller().getBufferNum() + 1);
- // Workaround dumb xforms sizing bug
- minw_ = form()->w;
- minh_ = form()->h;
- minw_sb = minw_;
+ string const name = controller().
+ getBufferName(fl_get_choice(dialog_->choice_document) - 1);
+ refs_ = controller().getLabelList(name);
- // Name is irrelevant to LaTeX documents
- if ( lv_->buffer()->isLatex() ) {
- fl_deactivate_object( dialog_->name );
- fl_set_object_lcol( dialog_->name, FL_INACTIVE );
- }
-
- // Can change reference only through browser
- fl_deactivate_object( dialog_->ref );
-
- bc_.setOK( dialog_->button_ok );
- bc_.setCancel( dialog_->button_cancel );
- bc_.addReadOnly( dialog_->type );
- bc_.refresh();
+ updateBrowser(refs_);
}
-void FormRef::update()
-{
- fl_set_input(dialog_->ref, params.getContents().c_str());
- fl_set_input(dialog_->name, params.getOptions().c_str());
-
- Type type = getType();
- fl_set_choice( dialog_->type, type+1 );
+namespace {
- toggle = GOBACK;
- fl_set_object_label(dialog_->button_go, _("Goto reference"));
+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);
- refs.clear();
- if ( inset_ == 0 ) {
- refs = lv_->buffer()->getLabelList();
- updateBrowser( refs );
- showBrowser();
+ if (cit == keys.end()) {
+ fl_deselect_browser(browser);
} else {
- hideBrowser();
+ 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);
}
- bc_.readOnly( lv_->buffer()->isReadonly() );
}
+} // namespace anon
-void FormRef::updateBrowser( vector<string> keys ) const
+
+void FormRef::updateBrowser(vector<string> const & akeys) const
{
- if ( fl_get_button( dialog_->sort ) )
- sort( keys.begin(), keys.end() );
-
- fl_clear_browser( dialog_->browser );
- for( vector<string>::const_iterator it = keys.begin();
- it != keys.end(); ++it )
- fl_add_browser_line( dialog_->browser, (*it).c_str());
-
- if ( keys.empty() ) {
- fl_add_browser_line( dialog_->browser,
- _("*** No labels found in document ***"));
-
- fl_deactivate_object( dialog_->browser );
- fl_deactivate_object( dialog_->button_update );
- fl_deactivate_object( dialog_->sort );
- fl_set_object_lcol( dialog_->browser, FL_INACTIVE );
- fl_set_object_lcol( dialog_->button_update, FL_INACTIVE );
- fl_set_object_lcol( dialog_->sort, FL_INACTIVE );
- } else {
- fl_set_browser_topline( dialog_->browser, 1 );
- fl_activate_object( dialog_->browser );
- fl_set_object_lcol( dialog_->browser, FL_BLACK );
- fl_activate_object( dialog_->button_update );
- fl_set_object_lcol( dialog_->button_update, FL_BLACK );
- fl_activate_object( dialog_->sort );
- fl_set_object_lcol( dialog_->sort, FL_BLACK );
+ 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());
-void FormRef::showBrowser() const
-{
- fl_show_object( dialog_->browser );
- fl_show_object( dialog_->button_update );
- fl_show_object( dialog_->sort );
-
- setSize( minw_sb, 0 );
-
- fl_deactivate_object( dialog_->type );
- fl_set_object_lcol( dialog_->type, FL_INACTIVE );
- fl_deactivate_object( dialog_->button_go );
- fl_set_object_lcol( dialog_->button_go, FL_INACTIVE );
- fl_set_object_lcol( dialog_->ref, FL_INACTIVE );
- bc_.valid(false);
-}
+ 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);
-void FormRef::hideBrowser() const
-{
- fl_hide_object( dialog_->browser );
- fl_hide_object( dialog_->button_update );
- fl_hide_object( dialog_->sort );
-
- setSize( minw_hb, 280 );
-
- fl_activate_object( dialog_->type );
- fl_set_object_lcol( dialog_->type, FL_BLACK );
- fl_activate_object( dialog_->button_go );
- fl_set_object_lcol( dialog_->button_go, FL_BLACK );
- fl_set_object_lcol( dialog_->ref, FL_BLACK );
- bc_.invalid();
+ 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::setSize( int w, int dx ) const
+void FormRef::apply()
{
- static int x1 = dialog_->name->x;
- static int y1 = dialog_->name->y;
- static int x2 = dialog_->ref->x;
- static int y2 = dialog_->ref->y;
- static int x3 = dialog_->type->x;
- static int y3 = dialog_->type->y;
- static int x4 = dialog_->button_go->x;
- static int y4 = dialog_->button_go->y;
- static int x5 = dialog_->button_ok->x;
- static int y5 = dialog_->button_ok->y;
- static int x6 = dialog_->button_cancel->x;
- static int y6 = dialog_->button_cancel->y;
-
- if ( form()->w != w ) {
- minw_ = w;
- fl_set_form_size( form(), minw_, minh_ );
- } else
- return;
-
- fl_set_object_position( dialog_->name, x1-dx, y1 );
- fl_set_object_position( dialog_->ref, x2-dx, y2 );
- fl_set_object_position( dialog_->type, x3-dx, y3 );
- fl_set_object_position( dialog_->button_go, x4-dx, y4 );
- fl_set_object_position( dialog_->button_ok, x5-dx, y5 );
- fl_set_object_position( dialog_->button_cancel, x6-dx, y6 );
-
- // These two must be reset apparently
- // Name is irrelevant to LaTeX documents
- if ( lv_->buffer()->isLatex() ) {
- fl_deactivate_object( dialog_->name );
- fl_set_object_lcol( dialog_->name, FL_INACTIVE );
- }
-
- // Can change reference only through browser
- fl_deactivate_object( dialog_->ref );
+ 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));
}
-void FormRef::apply()
+ButtonPolicy::SMInput FormRef::input(FL_OBJECT * ob, long)
{
- if (!lv_->view()->available())
- return;
+ ButtonPolicy::SMInput activate(ButtonPolicy::SMI_VALID);
- Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
- params.setCmdName(getName(type));
+ if (ob == dialog_->button_go) {
+ // goto reference / go back
- params.setOptions(fl_get_input(dialog_->name));
+ // No change to data
+ activate = ButtonPolicy::SMI_NOOP;
- if (inset_ != 0) {
- // Only update if contents have changed
- if (params != inset_->params()) {
- inset_->setParams(params);
- lv_->view()->updateInset(inset_, true);
+ at_ref_ = !at_ref_;
+ if (at_ref_) {
+ controller().gotoRef(getString(dialog_->input_ref));
+ } else {
+ controller().gotoBookmark();
}
- } else {
- lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
- params.getAsString());
- }
-}
+ switch_go_button();
+ } else if (ob == dialog_->browser_refs) {
-#ifdef WITH_WARNINGS
-#warning check use of buttoncontroller
-// Seems okay except that goref and goback shouldn't
-// affect the status of ok.
-#endif
-bool FormRef::input( FL_OBJECT *, long data )
-{
- bool activate( true );
- switch( data ) {
- // goto reference / go back
- case 1:
- {
- toggle = static_cast<Goto>(toggle + 1);
- if ( toggle == GOFIRST ) toggle = GOREF;
-
- switch (toggle) {
- case GOREF:
- {
- lv_->getLyXFunc()->
- Dispatch(LFUN_REF_GOTO,
- params.getContents());
- fl_set_object_label(dialog_->button_go, _("Go back"));
- }
- break;
+ unsigned int sel = fl_get_browser(dialog_->browser_refs);
+ if (sel < 1 || sel > refs_.size())
+ return ButtonPolicy::SMI_NOOP;
- case GOBACK:
- {
- lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
- fl_set_object_label(dialog_->button_go,
- _("Goto reference"));
+ if (!kernel().isBufferReadonly()) {
+ string s = fl_get_browser_line(dialog_->browser_refs, sel);
+ fl_set_input(dialog_->input_ref, s.c_str());
}
- break;
- default:
- break;
- }
- }
- break;
-
- // choose browser key
- case 2:
- {
- unsigned int sel = fl_get_browser( dialog_->browser );
- if ( sel < 1 || sel > refs.size() ) break;
-
- string s = fl_get_browser_line( dialog_->browser, sel );
- fl_set_input( dialog_->ref, s.c_str());
- params.setContents( s );
-
- toggle = GOBACK;
- lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
- fl_set_object_label(dialog_->button_go, _("Goto reference"));
-
- fl_activate_object( dialog_->type );
- fl_set_object_lcol( dialog_->type, FL_BLACK );
- fl_activate_object( dialog_->button_go );
- fl_set_object_lcol( dialog_->button_go, FL_BLACK );
- fl_set_object_lcol( dialog_->ref, FL_BLACK );
- }
- break;
-
- // update or sort
- case 3:
- {
- fl_freeze_form( form() );
- updateBrowser( refs );
- fl_unfreeze_form( form() );
- }
- break;
-
- // changed reference type
- case 4:
- {
- Type type = static_cast<Type>(
- fl_get_choice(dialog_->type) - 1 );
- if ( params.getCmdName() == getName( type )
- && inset_ ) {
- activate = false;
- }
- }
- break;
+ if (at_ref_)
+ controller().gotoBookmark();
+ at_ref_ = false;
+ switch_go_button();
- default:
- break;
- }
- return activate;
-}
+ 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) {
-FormRef::Type FormRef::getType() const
-{
- Type type;
+ // No change to data
+ activate = ButtonPolicy::SMI_NOOP;
- if ( params.getCmdName() == "ref" )
- type = REF;
+ 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);
+ }
- else if ( params.getCmdName() == "pageref" )
- type = PAGEREF;
+ fl_freeze_form(form());
+ updateBrowser(refs_);
+ fl_unfreeze_form(form());
- else if ( params.getCmdName() == "vref" )
- type = VREF;
+ } else if (ob == dialog_->choice_format) {
- else if ( params.getCmdName() == "vpageref" )
- type = VPAGEREF;
+ int const type = fl_get_choice(dialog_->choice_format) - 1;
+ if (controller().params().getCmdName() ==
+ InsetRef::getName(type)) {
+ activate = ButtonPolicy::SMI_NOOP;
+ }
+ }
- else
- type = PRETTYREF;
-
- return type;
+ return activate;
}
-string FormRef::getName( Type type ) const
+void FormRef::switch_go_button()
{
- string name;
-
- switch( type ) {
- case REF:
- name = "ref";
- break;
- case PAGEREF:
- name = "pageref";
- break;
- case VREF:
- name = "vref";
- break;
- case VPAGEREF:
- name = "vpageref";
- break;
- case PRETTYREF:
- name = "prettyref";
- break;
+ 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());
}
-
- return name;
+ fl_set_button_shortcut(dialog_->button_go, "#G", 1);
+ fl_show_object(dialog_->button_go);
}