]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiRef.cpp
Remove debugging code.
[lyx.git] / src / frontends / qt4 / GuiRef.cpp
index d091d48343e341ca54d327bb1f642bb4be510342..5d46a471c710bb980c0c062085c8f3a480d405b5 100644 (file)
@@ -4,7 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author John Levon
- * \author Jürgen Spitzmüller
+ * \author Jürgen Spitzmüller
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include "GuiRef.h"
 
+#include "GuiApplication.h"
+
 #include "Buffer.h"
+#include "BufferParams.h"
 #include "BufferList.h"
+#include "BufferView.h"
+#include "Cursor.h"
 #include "FuncRequest.h"
 
 #include "qt_helpers.h"
 
 #include "insets/InsetRef.h"
 
-#include "support/filetools.h" // MakeAbsPath, MakeDisplayPath
-
-#include <boost/filesystem/operations.hpp>
+#include "support/FileName.h"
+#include "support/FileNameList.h"
+#include "support/filetools.h" // makeAbsPath, makeDisplayPath
 
 #include <QLineEdit>
 #include <QCheckBox>
-#include <QListWidget>
-#include <QListWidgetItem>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
 #include <QPushButton>
 #include <QToolTip>
 #include <QCloseEvent>
+#include <QHeaderView>
 
-#include <algorithm>
-
-using std::find;
-using std::vector;
-using std::string;
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
 namespace frontend {
 
-using support::makeAbsPath;
-using support::makeDisplayPath;
-
-//FIXME It should be possible to eliminate lfun_name_
-//now and recover that information from params().insetType().
-//But let's not do that quite yet.
-/// Flags what action is taken by Kernel::dispatch()
-static std::string const lfun_name_ = "ref";
-
-GuiRef::GuiRef(LyXView & lv)
-       : GuiDialog(lv, "ref"), Controller(*static_cast<Dialog*>(this)),
-               params_("ref")
+GuiRef::GuiRef(GuiView & lv)
+       : GuiDialog(lv, "ref", qt_("Cross-reference")),
+         params_(insetCode("ref"))
 {
        setupUi(this);
-       setController(this, false);
-       setViewTitle(_("Cross-reference"));
 
-       sort_ = false;
        at_ref_ = false;
 
-       connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
-       connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
-       connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
-       connect(closePB, SIGNAL(clicked()), this, SLOT(reset_dialog()));
-       connect(this, SIGNAL(rejected()), this, SLOT(reset_dialog()));
+       // The filter bar
+       filter_ = new FancyLineEdit(this);
+       filter_->setButtonPixmap(FancyLineEdit::Right, getPixmap("images/", "editclear", "svgz,png"));
+       filter_->setButtonVisible(FancyLineEdit::Right, true);
+       filter_->setButtonToolTip(FancyLineEdit::Right, qt_("Clear text"));
+       filter_->setAutoHideButton(FancyLineEdit::Right, true);
+       filter_->setPlaceholderText(qt_("All available labels"));
+       filter_->setToolTip(qt_("Enter string to filter the list of available labels"));
+#if (QT_VERSION < 0x050000)
+       connect(filter_, SIGNAL(downPressed()),
+               refsTW, SLOT(setFocus()));
+#else
+       connect(filter_, &FancyLineEdit::downPressed,
+               refsTW, [=](){ focusAndHighlight(refsTW); });
+#endif
+
+       filterBarL->addWidget(filter_, 0);
+       findKeysLA->setBuddy(filter_);
+
+       sortingCO->addItem(qt_("By Occurrence"), "unsorted");
+       sortingCO->addItem(qt_("Alphabetically (Case-Insensitive)"), "nocase");
+       sortingCO->addItem(qt_("Alphabetically (Case-Sensitive)"), "case");
+
+       buttonBox->button(QDialogButtonBox::Reset)->setText(qt_("&Update"));
+       buttonBox->button(QDialogButtonBox::Reset)->setToolTip(qt_("Update the label list"));
+
+       refsTW->setColumnCount(1);
+       refsTW->header()->setVisible(false);
+
+       connect(this, SIGNAL(rejected()), this, SLOT(dialogRejected()));
 
        connect(typeCO, SIGNAL(activated(int)),
                this, SLOT(changed_adaptor()));
-       connect(referenceED, SIGNAL(textChanged(const QString &)),
+       connect(referenceED, SIGNAL(textChanged(QString)),
+               this, SLOT(refTextChanged(QString)));
+       connect(referenceED, SIGNAL(textChanged(QString)),
                this, SLOT(changed_adaptor()));
-       connect(nameED, SIGNAL(textChanged(const QString &)),
+       connect(filter_, SIGNAL(textEdited(QString)),
+               this, SLOT(filterLabels()));
+       connect(filter_, SIGNAL(rightButtonClicked()),
+               this, SLOT(resetFilter()));
+       connect(csFindCB, SIGNAL(clicked()),
+               this, SLOT(filterLabels()));
+       connect(nameED, SIGNAL(textChanged(QString)),
                this, SLOT(changed_adaptor()));
-       connect(refsLW, SIGNAL(itemClicked(QListWidgetItem *)),
-               this, SLOT(refHighlighted(QListWidgetItem *)));
-       connect(refsLW, SIGNAL(itemSelectionChanged()),
+       connect(refsTW, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
+               this, SLOT(refHighlighted(QTreeWidgetItem *)));
+       connect(refsTW, SIGNAL(itemSelectionChanged()),
                this, SLOT(selectionChanged()));
-       connect(refsLW, SIGNAL(itemActivated(QListWidgetItem *)),
-               this, SLOT(refSelected(QListWidgetItem *)));
-       connect(sortCB, SIGNAL(clicked(bool)),
-               this, SLOT(sortToggled(bool)));
+       connect(refsTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
+               this, SLOT(refSelected(QTreeWidgetItem *)));
+       connect(sortingCO, SIGNAL(activated(int)),
+               this, SLOT(sortToggled()));
+       connect(groupCB, SIGNAL(clicked()),
+               this, SLOT(groupToggled()));
        connect(gotoPB, SIGNAL(clicked()),
                this, SLOT(gotoClicked()));
-       connect(updatePB, SIGNAL(clicked()),
-               this, SLOT(updateClicked()));
        connect(bufferCO, SIGNAL(activated(int)),
                this, SLOT(updateClicked()));
+       connect(pluralCB, SIGNAL(clicked()),
+               this, SLOT(changed_adaptor()));
+       connect(capsCB, SIGNAL(clicked()),
+               this, SLOT(changed_adaptor()));
+       connect(noprefixCB, SIGNAL(clicked()),
+               this, SLOT(changed_adaptor()));
 
-       setFocusProxy(refsLW);
+       enableBoxes();
 
        bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
-       bc().setOK(okPB);
-       bc().setApply(applyPB);
-       bc().setCancel(closePB);
-       bc().addReadOnly(refsLW);
-       bc().addReadOnly(sortCB);
-       bc().addReadOnly(nameED);
-       bc().addReadOnly(referenceED);
+       bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
+       bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
+       bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
        bc().addReadOnly(typeCO);
-       bc().addReadOnly(bufferCO);
 
        restored_buffer_ = -1;
+       active_buffer_ = -1;
+
+       setFocusProxy(filter_);
+}
+
+
+void GuiRef::enableView(bool enable)
+{
+       if (!enable)
+               // In the opposite case, updateContents() will be called anyway.
+               updateContents();
+       GuiDialog::enableView(enable);
+}
+
+
+void GuiRef::enableBoxes()
+{
+       bool const isFormatted =
+           (InsetRef::getName(typeCO->currentIndex()) == "formatted");
+       bool const isLabelOnly =
+           (InsetRef::getName(typeCO->currentIndex()) == "labelonly");
+       bool const usingRefStyle = buffer().params().use_refstyle;
+       pluralCB->setEnabled(isFormatted && usingRefStyle);
+       capsCB->setEnabled(isFormatted && usingRefStyle);
+       noprefixCB->setEnabled(isLabelOnly);
 }
 
 
 void GuiRef::changed_adaptor()
 {
        changed();
+       enableBoxes();
 }
 
 
 void GuiRef::gotoClicked()
 {
+       // By setting last_reference_, we ensure that the reference
+       // to which we are going (or from which we are returning) is
+       // restored in the dialog. It's a bit of a hack, but it works,
+       // and no-one seems to have any better idea.
+       bool const toggled =
+               last_reference_.isEmpty() || last_reference_.isNull();
+       if (toggled)
+               last_reference_ = referenceED->text();
        gotoRef();
+       if (toggled)
+               last_reference_.clear();
 }
 
+
 void GuiRef::selectionChanged()
 {
        if (isBufferReadonly())
                return;
 
-       QList<QListWidgetItem *> selections = refsLW->selectedItems();
+       QList<QTreeWidgetItem *> selections = refsTW->selectedItems();
        if (selections.isEmpty())
                return;
-       QListWidgetItem * sel = selections.first();
+       QTreeWidgetItem * sel = selections.first();
        refHighlighted(sel);
        return;
 }
 
 
-void GuiRef::refHighlighted(QListWidgetItem * sel)
+void GuiRef::refHighlighted(QTreeWidgetItem * sel)
 {
-       if (controller().isBufferReadonly())
+       if (sel->childCount() > 0) {
+               sel->setExpanded(true);
                return;
+       }
 
-/*     int const cur_item = refsLW->currentRow();
+/*     int const cur_item = refsTW->currentRow();
        bool const cur_item_selected = cur_item >= 0 ?
                refsLB->isSelected(cur_item) : false;*/
-       bool const cur_item_selected = refsLW->isItemSelected(sel);
+       bool const cur_item_selected = refsTW->isItemSelected(sel);
 
        if (cur_item_selected)
-               referenceED->setText(sel->text());
+               referenceED->setText(sel->text(0));
 
        if (at_ref_)
                gotoRef();
        gotoPB->setEnabled(true);
-       if (typeAllowed())
+       if (typeAllowed() && !isBufferReadonly())
                typeCO->setEnabled(true);
-       if (nameAllowed())
-               nameED->setEnabled(true);
+       nameED->setHidden(!nameAllowed());
+       nameL->setHidden(!nameAllowed());
+}
+
+
+void GuiRef::refTextChanged(QString const & str)
+{
+       gotoPB->setEnabled(!str.isEmpty());
+       typeCO->setEnabled(!str.isEmpty());
+       typeLA->setEnabled(!str.isEmpty());
 }
 
 
-void GuiRef::refSelected(QListWidgetItem * sel)
+void GuiRef::refSelected(QTreeWidgetItem * sel)
 {
        if (isBufferReadonly())
                return;
 
-/*     int const cur_item = refsLW->currentRow();
+       if (sel->childCount()) {
+               sel->setExpanded(false);
+               return;
+       }
+
+/*     int const cur_item = refsTW->currentRow();
        bool const cur_item_selected = cur_item >= 0 ?
                refsLB->isSelected(cur_item) : false;*/
-       bool const cur_item_selected = refsLW->isItemSelected(sel);
+       bool const cur_item_selected = refsTW->isItemSelected(sel);
 
        if (cur_item_selected)
-               referenceED->setText(sel->text());
+               referenceED->setText(sel->text(0));
        // <enter> or double click, inserts ref and closes dialog
        slotOK();
 }
 
 
-void GuiRef::sortToggled(bool on)
+void GuiRef::sortToggled()
+{
+       redoRefs();
+}
+
+
+void GuiRef::groupToggled()
 {
-       sort_ = on;
        redoRefs();
 }
 
 
+void GuiRef::on_buttonBox_clicked(QAbstractButton * button)
+{
+       switch (buttonBox->standardButton(button)) {
+       case QDialogButtonBox::Ok:
+               slotOK();
+               break;
+       case QDialogButtonBox::Apply:
+               slotApply();
+               break;
+       case QDialogButtonBox::Cancel:
+               slotClose();
+               resetDialog();
+               break;
+       case QDialogButtonBox::Reset:
+               updateClicked();
+               break;
+       default:
+               break;
+       }
+}
+
+
 void GuiRef::updateClicked()
 {
        updateRefs();
 }
 
 
-void GuiRef::reset_dialog()
+void GuiRef::dialogRejected()
+{
+       resetDialog();
+       // We have to do this manually, instead of calling slotClose(), because
+       // the dialog has already been made invisible before rejected() triggers.
+       Dialog::disconnect();
+}
+
+
+void GuiRef::resetDialog()
 {
        at_ref_ = false;
        setGotoRef();
@@ -194,48 +307,84 @@ void GuiRef::reset_dialog()
 void GuiRef::closeEvent(QCloseEvent * e)
 {
        slotClose();
-       reset_dialog();
-       GuiDialog::closeEvent(e);
+       resetDialog();
+       e->accept();
 }
 
 
 void GuiRef::updateContents()
 {
-       int orig_type = typeCO->currentIndex();
+       QString const orig_type =
+               typeCO->itemData(typeCO->currentIndex()).toString();
+
+       referenceED->clear();
+       nameED->clear();
+       typeCO->clear();
+
+       // FIXME Bring InsetMathRef on par with InsetRef
+       // (see #9798)
+       typeCO->addItem(qt_("<reference>"), "ref");
+       typeCO->addItem(qt_("(<reference>)"), "eqref");
+       typeCO->addItem(qt_("<page>"), "pageref");
+       typeCO->addItem(qt_("on page <page>"), "vpageref");
+       typeCO->addItem(qt_("<reference> on page <page>"), "vref");
+       typeCO->addItem(qt_("Textual reference"), "nameref");
+       if (bufferview()->cursor().inTexted()) {
+               typeCO->addItem(qt_("Formatted reference"), "formatted");
+               typeCO->addItem(qt_("Label only"), "labelonly");
+       } else
+               typeCO->addItem(qt_("Formatted reference"), "prettyref");
 
        referenceED->setText(toqstr(params_["reference"]));
-
        nameED->setText(toqstr(params_["name"]));
-       nameED->setReadOnly(!nameAllowed() && !isBufferReadonly());
+       nameED->setHidden(!nameAllowed());
+       nameL->setHidden(!nameAllowed());
 
        // restore type settings for new insets
-       if (params_["reference"].empty())
-               typeCO->setCurrentIndex(orig_type);
+       bool const new_inset = params_["reference"].empty();
+       if (new_inset) {
+               int index = typeCO->findData(orig_type);
+               if (index == -1)
+                       index = 0;
+               typeCO->setCurrentIndex(index);
+       }
        else
-               typeCO->setCurrentIndex(InsetRef::getType(params_.getCmdName()));
+               typeCO->setCurrentIndex(
+                       typeCO->findData(toqstr(params_.getCmdName())));
        typeCO->setEnabled(typeAllowed() && !isBufferReadonly());
        if (!typeAllowed())
                typeCO->setCurrentIndex(0);
 
-       sortCB->setChecked(sort_);
+       pluralCB->setChecked(params_["plural"] == "true");
+       capsCB->setChecked(params_["caps"] == "true");
+       noprefixCB->setChecked(params_["noprefix"] == "true");
 
        // insert buffer list
        bufferCO->clear();
-       vector<string> buffers = theBufferList().getFileNames();
-       for (vector<string>::iterator it = buffers.begin();
+       FileNameList const buffers(theBufferList().fileNames());
+       for (FileNameList::const_iterator it = buffers.begin();
             it != buffers.end(); ++it) {
-               bufferCO->addItem(toqstr(lyx::to_utf8(makeDisplayPath(*it))));
+               bufferCO->addItem(toqstr(makeDisplayPath(it->absFileName())));
        }
 
+       int const thebuffer = theBufferList().bufferNum(buffer().fileName());
        // restore the buffer combo setting for new insets
-       if (params_["reference"].empty() && restored_buffer_ != -1
-       && restored_buffer_ < bufferCO->count())
+       if (new_inset && restored_buffer_ != -1
+           && restored_buffer_ < bufferCO->count() && thebuffer == active_buffer_)
                bufferCO->setCurrentIndex(restored_buffer_);
-       else
-               bufferCO->setCurrentIndex(bufferNum());
+       else {
+               int const num = theBufferList().bufferNum(buffer().fileName());
+               bufferCO->setCurrentIndex(num);
+               if (thebuffer != active_buffer_)
+                       restored_buffer_ = num;
+       }
+       active_buffer_ = thebuffer;
 
        updateRefs();
-       bc().setValid(false);
+       enableBoxes();
+       // Activate OK/Apply buttons if the users inserts a new ref
+       // and we have a valid pre-setting.
+       bc().setValid(isValid() && new_inset);
 }
 
 
@@ -243,10 +392,15 @@ void GuiRef::applyView()
 {
        last_reference_ = referenceED->text();
 
-       params_.setCmdName(InsetRef::getName(typeCO->currentIndex()));
+       params_.setCmdName(fromqstr(typeCO->itemData(typeCO->currentIndex()).toString()));
        params_["reference"] = qstring_to_ucs4(last_reference_);
        params_["name"] = qstring_to_ucs4(nameED->text());
-
+       params_["plural"] = pluralCB->isChecked() ?
+             from_ascii("true") : from_ascii("false");
+       params_["caps"] = capsCB->isChecked() ?
+             from_ascii("true") : from_ascii("false");
+       params_["noprefix"] = noprefixCB->isChecked() ?
+             from_ascii("true") : from_ascii("false");
        restored_buffer_ = bufferCO->currentIndex();
 }
 
@@ -267,16 +421,14 @@ bool GuiRef::typeAllowed()
 void GuiRef::setGoBack()
 {
        gotoPB->setText(qt_("&Go Back"));
-       gotoPB->setToolTip("");
-       gotoPB->setToolTip(qt_("Jump back"));
+       gotoPB->setToolTip(qt_("Jump back to the original cursor location"));
 }
 
 
 void GuiRef::setGotoRef()
 {
        gotoPB->setText(qt_("&Go to Label"));
-       gotoPB->setToolTip("");
-       gotoPB->setToolTip(qt_("Jump to label"));
+       gotoPB->setToolTip(qt_("Jump to the selected label"));
 }
 
 
@@ -296,69 +448,141 @@ void GuiRef::gotoRef()
        at_ref_ = !at_ref_;
 }
 
+inline bool caseInsensitiveLessThan(QString const & s1, QString const & s2)
+{
+       return s1.toLower() < s2.toLower();
+}
+
 
 void GuiRef::redoRefs()
 {
        // Prevent these widgets from emitting any signals whilst
        // we modify their state.
-       refsLW->blockSignals(true);
+       refsTW->blockSignals(true);
        referenceED->blockSignals(true);
-       refsLW->setUpdatesEnabled(false);
+       refsTW->setUpdatesEnabled(false);
 
-       refsLW->clear();
+       refsTW->clear();
 
        // need this because Qt will send a highlight() here for
        // the first item inserted
        QString const oldSelection(referenceED->text());
 
-       for (std::vector<docstring>::const_iterator iter = refs_.begin();
-               iter != refs_.end(); ++iter) {
-               refsLW->addItem(toqstr(*iter));
+       QStringList refsStrings;
+       QStringList refsCategories;
+       vector<docstring>::const_iterator iter;
+       bool noprefix = false;
+       for (iter = refs_.begin(); iter != refs_.end(); ++iter) {
+               QString const lab = toqstr(*iter);
+               refsStrings.append(lab);
+               if (groupCB->isChecked()) {
+                       if (lab.contains(":")) {
+                               QString const pref = lab.split(':')[0];
+                               if (!refsCategories.contains(pref)) {
+                                       if (!pref.isEmpty())
+                                               refsCategories.append(pref);
+                                       else
+                                               noprefix = true;
+                               }
+                       }
+                       else
+                               noprefix = true;
+               }
+       }
+       // sort categories case-intensively
+       qSort(refsCategories.begin(), refsCategories.end(),
+             caseInsensitiveLessThan /*defined above*/);
+       if (noprefix)
+               refsCategories.insert(0, qt_("<No prefix>"));
+
+       QString const sort = sortingCO->isEnabled() ?
+                               sortingCO->itemData(sortingCO->currentIndex()).toString()
+                               : QString();
+       if (sort == "nocase")
+               qSort(refsStrings.begin(), refsStrings.end(),
+                     caseInsensitiveLessThan /*defined above*/);
+       else if (sort == "case")
+               qSort(refsStrings.begin(), refsStrings.end());
+
+       if (groupCB->isChecked()) {
+               QList<QTreeWidgetItem *> refsCats;
+               for (int i = 0; i < refsCategories.size(); ++i) {
+                       QString const cat = refsCategories.at(i);
+                       QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
+                       item->setText(0, cat);
+                       for (int j = 0; j < refsStrings.size(); ++j) {
+                               QString const ref = refsStrings.at(j);
+                               if ((ref.startsWith(cat + QString(":")))
+                                   || (cat == qt_("<No prefix>")
+                                      && (!ref.mid(1).contains(":") || ref.left(1).contains(":")))) {
+                                               QTreeWidgetItem * child =
+                                                       new QTreeWidgetItem(item);
+                                               child->setText(0, ref);
+                                               item->addChild(child);
+                               }
+                       }
+                       refsCats.append(item);
+               }
+               refsTW->addTopLevelItems(refsCats);
+       } else {
+               QList<QTreeWidgetItem *> refsItems;
+               for (int i = 0; i < refsStrings.size(); ++i) {
+                       QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
+                       item->setText(0, refsStrings.at(i));
+                       refsItems.append(item);
+               }
+               refsTW->addTopLevelItems(refsItems);
        }
-
-       if (sort_)
-               refsLW->sortItems();
-
-       referenceED->setText(oldSelection);
 
        // restore the last selection or, for new insets, highlight
        // the previous selection
        if (!oldSelection.isEmpty() || !last_reference_.isEmpty()) {
                bool const newInset = oldSelection.isEmpty();
                QString textToFind = newInset ? last_reference_ : oldSelection;
-               bool foundItem = false;
-               for (int i = 0; !foundItem && i < refsLW->count(); ++i) {
-                       QListWidgetItem * item = refsLW->item(i);
-                       if (textToFind == item->text()) {
-                               refsLW->setCurrentItem(item);
-                               refsLW->setItemSelected(item, !newInset);
+               referenceED->setText(textToFind);
+               last_reference_.clear();
+               QTreeWidgetItemIterator it(refsTW);
+               while (*it) {
+                       if ((*it)->text(0) == textToFind) {
+                               refsTW->setCurrentItem(*it);
+                               refsTW->setItemSelected(*it, true);
                                //Make sure selected item is visible
-                               refsLW->scrollToItem(item);
-                               foundItem = true;
+                               refsTW->scrollToItem(*it);
+                               last_reference_ = textToFind;
+                               break;
                        }
+                       ++it;
                }
-               if (foundItem)
-                       last_reference_ = textToFind;
-               else last_reference_ = "";
        }
-       refsLW->setUpdatesEnabled(true);
-       refsLW->update();
+       refsTW->setUpdatesEnabled(true);
+       refsTW->update();
+
+       // redo filter
+       filterLabels();
 
        // Re-activate the emission of signals by these widgets.
-       refsLW->blockSignals(false);
+       refsTW->blockSignals(false);
        referenceED->blockSignals(false);
+
+       gotoPB->setEnabled(!referenceED->text().isEmpty());
+       typeCO->setEnabled(!referenceED->text().isEmpty());
+       typeLA->setEnabled(!referenceED->text().isEmpty());
 }
 
 
 void GuiRef::updateRefs()
 {
        refs_.clear();
-       string const name = theBufferList().getFileNames()[bufferCO->currentIndex()];
-       Buffer const * buf = theBufferList().getBuffer(makeAbsPath(name).absFilename());
-       buf->getLabelList(refs_);
-       sortCB->setEnabled(!refs_.empty());
-       refsLW->setEnabled(!refs_.empty());
-       gotoPB->setEnabled(!refs_.empty());
+       int const the_buffer = bufferCO->currentIndex();
+       if (the_buffer != -1) {
+               FileNameList const names(theBufferList().fileNames());
+               FileName const & name = names[the_buffer];
+               Buffer const * buf = theBufferList().getBuffer(name);
+               buf->getLabelList(refs_);
+       }
+       sortingCO->setEnabled(!refs_.empty());
+       refsTW->setEnabled(!refs_.empty());
+       groupCB->setEnabled(!refs_.empty());
        redoRefs();
 }
 
@@ -382,44 +606,47 @@ void GuiRef::gotoBookmark()
 }
 
 
-int GuiRef::bufferNum() const
+void GuiRef::filterLabels()
 {
-       vector<string> buffers = theBufferList().getFileNames();
-       string const name = buffer().fileName();
-       vector<string>::const_iterator cit =
-               std::find(buffers.begin(), buffers.end(), name);
-       if (cit == buffers.end())
-               return 0;
-       return int(cit - buffers.begin());
+       Qt::CaseSensitivity cs = csFindCB->isChecked() ?
+               Qt::CaseSensitive : Qt::CaseInsensitive;
+       QTreeWidgetItemIterator it(refsTW);
+       while (*it) {
+               (*it)->setHidden(
+                       (*it)->childCount() == 0
+                       && !(*it)->text(0).contains(filter_->text(), cs)
+               );
+               ++it;
+       }
 }
 
 
-bool GuiRef::initialiseParams(string const & data)
+void GuiRef::resetFilter()
 {
-       // The name passed with LFUN_INSET_APPLY is also the name
-       // used to identify the mailer.
-       InsetCommandMailer::string2params(lfun_name_, data, params_);
-       return true;
+       filter_->setText(QString());
+       filterLabels();
 }
 
 
-void GuiRef::clearParams()
+bool GuiRef::initialiseParams(std::string const & sdata)
 {
-       params_.clear();
+       InsetCommand::string2params(sdata, params_);
+       return true;
 }
 
 
 void GuiRef::dispatchParams()
 {
-       string const lfun = InsetCommandMailer::params2string(lfun_name_, params_);
+       std::string const lfun = InsetCommand::params2string(params_);
        dispatch(FuncRequest(getLfun(), lfun));
 }
 
 
-Dialog * createGuiRef(LyXView & lv) { return new GuiRef(lv); }
+
+Dialog * createGuiRef(GuiView & lv) { return new GuiRef(lv); }
 
 
 } // namespace frontend
 } // namespace lyx
 
-#include "GuiRef_moc.cpp"
+#include "moc_GuiRef.cpp"