]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormRef.C
Introduce LFUN_PRINT.
[lyx.git] / src / frontends / xforms / FormRef.C
index 23070c366109e3a1a0a07ae3389b9a1c94038b25..0fe2db21726f9dfe1561e9710d7335090b200906 100644 (file)
-// -*- 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"
+
+#include "Tooltips.h"
+#include "xforms_helpers.h"
+#include "xformsBC.h"
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
+#include "insets/insetref.h"
 
+#include "support/lstrings.h" // trim
 
-#include "Dialogs.h"
-#include "FormRef.h"
-#include "LyXView.h"
-#include "buffer.h"
-#include "form_ref.h"
-#include "lyxfunc.h"
+#include "lyx_forms.h"
 
-#include <algorithm>
+using lyx::support::getStringFromVector;
 
+using std::find;
+using std::max;
 using std::sort;
+using std::string;
 using std::vector;
 
-static int formw;
-static int formh;
 
-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::disconnect()
+void FormRef::update()
 {
-       refs.clear();
-       FormCommand::disconnect();
-}
-
+       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::build()
-{
-       dialog_ = build_ref();
+       // 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);
+       }
 
-       fl_addto_choice(dialog_->type,
-                       _(" Ref | Page | TextRef | TextPage | PrettyRef "));
+       // Get the available buffers
+       vector<string> const buffers = controller().getBufferList();
+       vector<string> const choice_documents =
+               getVector(dialog_->choice_document);
 
-       // XFORMS bug workaround
-       // Define the min/max dimensions. Actually applied in update()
-       formw = form()->w, formh = form()->h;
+       // 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, " | ") + ' ';
 
-       // Name is irrelevant to LaTeX documents
-       if ( lv_->buffer()->isLatex() ) {
-               fl_deactivate_object( dialog_->name );
-               fl_set_object_lcol( dialog_->name, FL_INACTIVE );
+               fl_clear_choice(dialog_->choice_document);
+               fl_addto_choice(dialog_->choice_document, choice.c_str());
        }
-         
-       // 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();
-}
 
+       fl_set_choice(dialog_->choice_document,
+                     controller().getBufferNum() + 1);
 
-void FormRef::update(bool switched)
-{
-       if (switched) {
-               hide();
-               return;
-       }
+       string const name = controller().
+               getBufferName(fl_get_choice(dialog_->choice_document) - 1);
+       refs_ = controller().getLabelList(name);
 
-       fl_set_input(dialog_->ref,  params.getContents().c_str());
-       fl_set_input(dialog_->name, params.getOptions().c_str());
+       updateBrowser(refs_);
+}
 
-       Type type = getType();
-       fl_set_choice( dialog_->type, type+1 );
 
-       toggle = GOBACK;
-       fl_set_object_label(dialog_->button_go, _("Goto reference"));
+namespace {
 
-       refs.clear();
-       if ( inset_ == 0 ) {
-               refs = lv_->buffer()->getLabelList();
-               updateBrowser( refs );
-               showBrowser();
+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 {
-               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( formw, formh, 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( 250, formh, 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 h, 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 )
-               fl_set_form_size( form(), w, h );
-
-       fl_set_form_minsize( form(), w, h );
-       fl_set_form_maxsize( form(), 2*w, h );
-
-       if ( form()->w == w ) 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);
 }