From: Juergen Spitzmueller Date: Sat, 11 Aug 2018 10:17:42 +0000 (+0200) Subject: Rework BibTeX dialog X-Git-Tag: lyx-2.4.0dev-acb2ca7b~3167 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=07d760ef30be8539b8dd4d8d0650a0339e9837b6;p=features.git Rework BibTeX dialog Fixes concerns reported in #11239 --- diff --git a/src/frontends/qt4/GuiBibtex.cpp b/src/frontends/qt4/GuiBibtex.cpp index 6d1c8c12a5..1778f5646e 100644 --- a/src/frontends/qt4/GuiBibtex.cpp +++ b/src/frontends/qt4/GuiBibtex.cpp @@ -20,6 +20,7 @@ #include "CiteEnginesList.h" #include "Encoding.h" #include "FuncRequest.h" +#include "GuiApplication.h" #include "LyXRC.h" #include "qt_helpers.h" #include "Validator.h" @@ -61,55 +62,60 @@ GuiBibtex::GuiBibtex(GuiView & lv) QDialog::setModal(true); setWindowModality(Qt::WindowModal); + // 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 avail. databases")); + + filterBarL->addWidget(filter_, 0); + findKeysLA->setBuddy(filter_); + connect(buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(slotButtonBox(QAbstractButton *))); connect(stylePB, SIGNAL(clicked()), - this, SLOT(browsePressed())); - connect(deletePB, SIGNAL(clicked()), - this, SLOT(deletePressed())); - connect(upPB, SIGNAL(clicked()), - this, SLOT(upPressed())); - connect(downPB, SIGNAL(clicked()), - this, SLOT(downPressed())); + this, SLOT(browseBstPressed())); connect(styleCB, SIGNAL(editTextChanged(QString)), this, SLOT(change_adaptor())); - connect(databaseLW, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), - this, SLOT(databaseChanged())); connect(bibtocCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(btPrintCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); - connect(addBibPB, SIGNAL(clicked()), - this, SLOT(addPressed())); connect(rescanPB, SIGNAL(clicked()), this, SLOT(rescanClicked())); connect(biblatexOptsLE, SIGNAL(textChanged(QString)), this, SLOT(change_adaptor())); connect(bibEncodingCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); - - add_ = new GuiBibtexAddDialog(this); - add_bc_.setPolicy(ButtonPolicy::OkCancelPolicy); - add_bc_.setOK(add_->buttonBox->button(QDialogButtonBox::Ok)); - add_bc_.setCancel(add_->buttonBox->button(QDialogButtonBox::Cancel)); - add_bc_.addCheckedLineEdit(add_->bibED, 0); - - connect(add_->bibED, SIGNAL(textChanged(QString)), - this, SLOT(bibEDChanged())); - connect(add_->buttonBox, SIGNAL(clicked(QAbstractButton *)), - this, SLOT(addBBClicked(QAbstractButton *))); - connect(add_->rescanPB, SIGNAL(clicked()), - this, SLOT(rescanClicked())); - connect(add_->bibLW, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(addDatabase())); - connect(add_->bibLW, SIGNAL(itemActivated(QListWidgetItem *)), - add_, SLOT(accept())); - connect(add_->bibLW, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), - this, SLOT(availableChanged())); - connect(add_->browsePB, SIGNAL(clicked()), + connect(browseBibPB, SIGNAL(clicked()), this, SLOT(browseBibPressed())); - add_->bibLW->setToolTip(formatToolTip(qt_("This list consists of all databases that are indexed by LaTeX and thus are found without a file path. " + selectionManager = new GuiSelectionManager(this, availableLV, selectedLV, + addBibPB, deletePB, upPB, downPB, &available_model_, &selected_model_); + connect(selectionManager, SIGNAL(selectionChanged()), + this, SLOT(databaseChanged())); + connect(selectionManager, SIGNAL(updateHook()), + this, SLOT(selUpdated())); + connect(selectionManager, SIGNAL(okHook()), + this, SLOT(on_buttonBox_accepted())); + + connect(filter_, SIGNAL(rightButtonClicked()), + this, SLOT(resetFilter())); + connect(filter_, SIGNAL(textEdited(QString)), + this, SLOT(filterChanged(QString))); + connect(filter_, SIGNAL(returnPressed()), + this, SLOT(filterPressed())); +#if (QT_VERSION < 0x050000) + connect(filter_, SIGNAL(downPressed()), + availableLV, SLOT(setFocus())); +#else + connect(filter_, &FancyLineEdit::downPressed, + availableLV, [=](){ focusAndHighlight(availableLV); }); +#endif + + availableLV->setToolTip(formatToolTip(qt_("This list consists of all databases that are indexed by LaTeX and thus are found without a file path. " "This is usually everything in the bib/ subdirectory of LaTeX's texmf tree. " "If you want to reuse your own database, this is the place you should store it."))); @@ -117,14 +123,10 @@ GuiBibtex::GuiBibtex(GuiView & lv) bc().setOK(buttonBox->button(QDialogButtonBox::Ok)); bc().setApply(buttonBox->button(QDialogButtonBox::Apply)); bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel)); - bc().addReadOnly(databaseLW); bc().addReadOnly(stylePB); bc().addReadOnly(styleCB); bc().addReadOnly(bibtocCB); - bc().addReadOnly(addBibPB); bc().addReadOnly(bibEncodingCO); - // Delete/Up/Down are handled with more conditions in - // databaseChanged(). // Always put the default encoding in the first position. bibEncodingCO->addItem(qt_("Document Encoding"), "default"); @@ -139,43 +141,59 @@ GuiBibtex::GuiBibtex(GuiView & lv) ++it; } - // Make sure the delete/up/down buttons are disabled if necessary. - databaseChanged(); + setFocusProxy(filter_); } -void GuiBibtex::addBBClicked(QAbstractButton * button) +void GuiBibtex::init() { - switch (add_->buttonBox->standardButton(button)) { - case QDialogButtonBox::Ok: - addDatabase(); - add_->accept(); - break; - case QDialogButtonBox::Cancel: - add_->reject(); - break; - default: - break; - } + all_bibs_ = bibFiles(false); + available_model_.setStringList(all_bibs_); + + QString bibs = toqstr(params_["bibfiles"]); + if (bibs.isEmpty()) + selected_bibs_.clear(); + else + selected_bibs_ = bibs.split(","); + setSelectedBibs(selected_bibs_); + + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + selectionManager->update(); } -void GuiBibtex::bibEDChanged() +void GuiBibtex::change_adaptor() { - // Indicate to the button controller that the contents have - // changed. The actual test of validity is carried out by - // the checkedLineEdit. - add_bc_.setValid(true); + setButtons(); + changed(); } -void GuiBibtex::change_adaptor() +void GuiBibtex::setButtons() +{ + int const srows = selectedLV->model()->rowCount(); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(srows > 0); + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(srows > 0); +} + + +void GuiBibtex::selUpdated() { + selectionManager->update(); changed(); } -void GuiBibtex::browsePressed() +void GuiBibtex::on_buttonBox_accepted() +{ + applyView(); + clearSelection(); + hide(); +} + + +void GuiBibtex::browseBstPressed() { QString const file = browseBst(QString()); @@ -209,123 +227,65 @@ void GuiBibtex::browseBibPressed() return; QString const f = changeExtension(file, ""); - bool present = false; - - for (int i = 0; i < add_->bibLW->count(); ++i) { - if (add_->bibLW->item(i)->text() == f) - present = true; - } - if (!present) { - add_->bibLW->addItem(f); + if (!selected_bibs_.contains(f)) { + selected_bibs_.append(f); + setSelectedBibs(selected_bibs_); changed(); } - - add_->bibED->setText(f); } -void GuiBibtex::addPressed() +void GuiBibtex::rescanClicked() { - add_bc_.setValid(false); - add_->exec(); + rescanBibStyles(); + updateContents(); } -void GuiBibtex::addDatabase() +void GuiBibtex::clearSelection() { - int const sel = add_->bibLW->currentRow(); - QString const file = add_->bibED->text().trimmed(); - - if (sel < 0 && file.isEmpty()) - return; - - // Add the selected browser_bib keys to browser_database - // multiple selections are possible - for (int i = 0; i != add_->bibLW->count(); ++i) { - QListWidgetItem * const item = add_->bibLW->item(i); - if (add_->bibLW->isItemSelected(item)) { - add_->bibLW->setItemSelected(item, false); - QList matches = - databaseLW->findItems(item->text(), Qt::MatchExactly); - if (matches.empty()) { - QString label = item->text(); - QListWidgetItem * db = new QListWidgetItem(label); - db->setFlags(db->flags() | Qt::ItemIsSelectable); - databaseLW->addItem(db); - } - } - } - - if (!file.isEmpty()) { - add_->bibED->clear(); - QString const f = changeExtension(file, ""); - QList matches = - databaseLW->findItems(f, Qt::MatchExactly); - if (matches.empty()) { - QListWidgetItem * db = new QListWidgetItem(f); - db->setFlags(db->flags() | Qt::ItemIsSelectable); - databaseLW->addItem(db); - } - } - - databaseChanged(); - changed(); + selected_bibs_.clear(); + setSelectedBibs(selected_bibs_); } -void GuiBibtex::deletePressed() +void GuiBibtex::setSelectedBibs(QStringList const sl) { - QListWidgetItem *cur = databaseLW->takeItem(databaseLW->currentRow()); - if (cur) { - delete cur; - databaseChanged(); - changed(); + selected_model_.clear(); + QStringList::const_iterator it = sl.begin(); + QStringList::const_iterator end = sl.end(); + for (int i = 0; it != end; ++it, ++i) { + QStandardItem * si = new QStandardItem(); + si->setData(*it); + si->setText(*it); + si->setToolTip(*it); + si->setEditable(false); + selected_model_.insertRow(i, si); } } -void GuiBibtex::upPressed() +QStringList GuiBibtex::selectedBibs() { - int row = databaseLW->currentRow(); - QListWidgetItem *cur = databaseLW->takeItem(row); - databaseLW->insertItem(row - 1, cur); - databaseLW->setCurrentItem(cur); - changed(); -} - - -void GuiBibtex::downPressed() -{ - int row = databaseLW->currentRow(); - QListWidgetItem *cur = databaseLW->takeItem(row); - databaseLW->insertItem(row + 1, cur); - databaseLW->setCurrentItem(cur); - changed(); -} - - -void GuiBibtex::rescanClicked() -{ - rescanBibStyles(); - updateContents(); + QStringList res; + for (int i = 0; i != selected_model_.rowCount(); ++i) { + QStandardItem const * item = selected_model_.item(i); + if (item) + res.append(item->text()); + } + return res; } void GuiBibtex::databaseChanged() { - bool readOnly = isBufferReadonly(); - int count = databaseLW->count(); - int row = databaseLW->currentRow(); - deletePB->setEnabled(!readOnly && row != -1); - upPB->setEnabled(!readOnly && count > 1 && row > 0); - downPB->setEnabled(!readOnly && count > 1 && row < count - 1); -} - - -void GuiBibtex::availableChanged() -{ - add_bc_.setValid(true); + QString const item = selectionManager->getSelectedIndex().data().toString(); + if (!selected_bibs_.contains(item)) { + selected_bibs_.append(item); + } else + selected_bibs_ = selectedBibs(); + setSelectedBibs(selected_bibs_); } @@ -339,27 +299,6 @@ void GuiBibtex::updateContents() else setTitle(qt_("BibTeX Bibliography")); - databaseLW->clear(); - - docstring bibs = params_["bibfiles"]; - docstring bib; - - while (!bibs.empty()) { - bibs = split(bibs, bib, ','); - bib = trim(bib); - if (!bib.empty()) { - QListWidgetItem * db = new QListWidgetItem(toqstr(bib)); - db->setFlags(db->flags() | Qt::ItemIsSelectable); - databaseLW->addItem(db); - } - } - - add_->bibLW->clear(); - - QStringList bibfiles = bibFiles(); - for (int i = 0; i != bibfiles.count(); ++i) - add_->bibLW->addItem(changeExtension(bibfiles[i], "")); - QString const bibstyle = styleFile(); bibtocCB->setChecked(bibtotoc() && !bibtopic); @@ -424,11 +363,11 @@ void GuiBibtex::applyView() { docstring dbs; - unsigned int maxCount = databaseLW->count(); + unsigned int maxCount = selected_bibs_.count(); for (unsigned int i = 0; i < maxCount; i++) { if (i != 0) dbs += ','; - QString item = databaseLW->item(i)->text(); + QString item = selected_bibs_.at(i); docstring bibfile = qstring_to_ucs4(item); dbs += bibfile; } @@ -459,12 +398,6 @@ void GuiBibtex::applyView() } -bool GuiBibtex::isValid() -{ - return databaseLW->count() != 0; -} - - QString GuiBibtex::browseBib(QString const & in_name) const { QString const label1 = qt_("D&ocuments"); @@ -501,7 +434,7 @@ QStringList GuiBibtex::bibStyles() const } -QStringList GuiBibtex::bibFiles() const +QStringList GuiBibtex::bibFiles(bool const extension) const { QStringList sdata = texFileList("bibFiles.lst"); // test whether we have a valid list, otherwise run rescan @@ -510,7 +443,8 @@ QStringList GuiBibtex::bibFiles() const sdata = texFileList("bibFiles.lst"); } for (int i = 0; i != sdata.size(); ++i) - sdata[i] = onlyFileName(sdata[i]); + sdata[i] = extension ? onlyFileName(sdata[i]) + : changeExtension(onlyFileName(sdata[i]), ""); // sort on filename only (no path) sdata.sort(); return sdata; @@ -526,6 +460,38 @@ void GuiBibtex::rescanBibStyles() const } +void GuiBibtex::findText(QString const & text) +{ + QStringList const result = bibFiles(false).filter(text); + available_model_.setStringList(result); +} + + +void GuiBibtex::filterChanged(const QString & text) +{ + if (!text.isEmpty()) { + findText(filter_->text()); + return; + } + findText(filter_->text()); + filter_->setFocus(); +} + + +void GuiBibtex::filterPressed() +{ + findText(filter_->text()); +} + + +void GuiBibtex::resetFilter() +{ + filter_->setText(QString()); + findText(filter_->text()); +} + + + bool GuiBibtex::usingBibtopic() const { return buffer().params().useBibtopic(); @@ -577,6 +543,7 @@ QString GuiBibtex::styleFile() const bool GuiBibtex::initialiseParams(std::string const & sdata) { InsetCommand::string2params(sdata, params_); + init(); return true; } @@ -588,7 +555,6 @@ void GuiBibtex::dispatchParams() } - Dialog * createGuiBibtex(GuiView & lv) { return new GuiBibtex(lv); } diff --git a/src/frontends/qt4/GuiBibtex.h b/src/frontends/qt4/GuiBibtex.h index 4dbe107fa6..c59f5eee89 100644 --- a/src/frontends/qt4/GuiBibtex.h +++ b/src/frontends/qt4/GuiBibtex.h @@ -14,28 +14,20 @@ #define GUIBIBTEX_H #include "GuiDialog.h" +#include "GuiSelectionManager.h" #include "ButtonController.h" +#include "FancyLineEdit.h" #include "ui_BibtexUi.h" #include "ui_BibtexAddUi.h" #include "insets/InsetCommandParams.h" +#include +#include namespace lyx { namespace frontend { -class GuiBibtexAddDialog : public QDialog, public Ui::BibtexAddUi -{ -public: - GuiBibtexAddDialog(QWidget * parent) : QDialog(parent) - { - Ui::BibtexAddUi::setupUi(this); - QDialog::setModal(true); - setWindowModality(Qt::WindowModal); - } -}; - - class GuiBibtex : public GuiDialog, public Ui::BibtexUi { Q_OBJECT @@ -44,23 +36,18 @@ public: explicit GuiBibtex(GuiView & lv); private Q_SLOTS: - void addBBClicked(QAbstractButton * button); void change_adaptor(); - void browsePressed(); + void on_buttonBox_accepted(); + void browseBstPressed(); void browseBibPressed(); - void addPressed(); - void addDatabase(); - void deletePressed(); - void upPressed(); - void downPressed(); void databaseChanged(); - void availableChanged(); - void bibEDChanged(); void rescanClicked(); + void selUpdated(); + void filterPressed(); + void filterChanged(const QString & text); + void resetFilter(); private: - /// - bool isValid(); /// Apply changes void applyView(); /// update @@ -73,7 +60,7 @@ private: /// get the list of bst files QStringList bibStyles() const; /// get the list of bib files - QStringList bibFiles() const; + QStringList bibFiles(bool const extension = true) const; /// build filelists of all availabe bib/bst/cls/sty-files. done through /// kpsewhich and an external script, saved in *Files.lst void rescanBibStyles() const; @@ -85,6 +72,19 @@ private: bool usingBiblatex() const; /// which stylefile do we use? QString styleFile() const; + /// Clear selected keys + void clearSelection(); + /// Set selected keys + void setSelectedBibs(QStringList const); + /// prepares a call to GuiCitation::searchKeys when we + /// are ready to search the Bib entries + void findText(QString const & text); + /// + void init(); + /// Get selected keys + QStringList selectedBibs(); + /// + void setButtons(); /// bool initialiseParams(std::string const & data); @@ -99,9 +99,17 @@ private: /// InsetCommandParams params_; /// - GuiBibtexAddDialog * add_; - /// - ButtonController add_bc_; + GuiSelectionManager * selectionManager; + /// available keys. + QStringListModel available_model_; + /// selected keys. + QStandardItemModel selected_model_; + /// All keys. + QStringList all_bibs_; + /// Cited keys. + QStringList selected_bibs_; + /// contains the search box + FancyLineEdit * filter_; }; } // namespace frontend diff --git a/src/frontends/qt4/Makefile.am b/src/frontends/qt4/Makefile.am index 0768e6615a..a53e46afd7 100644 --- a/src/frontends/qt4/Makefile.am +++ b/src/frontends/qt4/Makefile.am @@ -268,7 +268,6 @@ UIFILES = \ AboutUi.ui \ BibitemUi.ui \ BiblioUi.ui \ - BibtexAddUi.ui \ BibtexUi.ui \ BoxUi.ui \ BranchesUi.ui \ diff --git a/src/frontends/qt4/ui/BibtexAddUi.ui b/src/frontends/qt4/ui/BibtexAddUi.ui deleted file mode 100644 index a8eb3fc541..0000000000 --- a/src/frontends/qt4/ui/BibtexAddUi.ui +++ /dev/null @@ -1,164 +0,0 @@ - - - BibtexAddUi - - - - 0 - 0 - 328 - 385 - - - - - 0 - 0 - - - - LyX: Add BibTeX Database - - - true - - - - - - - - Databases fou&nd by LaTeX: - - - bibLW - - - - - - - - - - QAbstractItemView::ExtendedSelection - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 162 - 29 - - - - - - - - Rescan LaTeX's index for new databases and styles - - - &Rescan - - - - - - - - - - - Here you can enter a local BibTeX database name or browse your directory. - - - Lo&cal databases: - - - bibED - - - - - - - - - - 0 - 0 - - - - Here you can enter a local BibTeX database name - - - - - - - Browse your local directory - - - &Browse... - - - false - - - true - - - - - - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - bibLW - bibED - browsePB - - - qt_i18n.h - - - - diff --git a/src/frontends/qt4/ui/BibtexUi.ui b/src/frontends/qt4/ui/BibtexUi.ui index 847cb53923..f45080baec 100644 --- a/src/frontends/qt4/ui/BibtexUi.ui +++ b/src/frontends/qt4/ui/BibtexUi.ui @@ -6,8 +6,8 @@ 0 0 - 397 - 536 + 523 + 576 @@ -27,17 +27,58 @@ - + + + + + Found b&y LaTeX: + + + availableLV + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + + + + + - Add a BibTeX database file + Add the selected BibTeX database from the list on the left - &Add... + &Add Selected[[bib]] + + + + + + + Add a BibTeX database from your local directory + + + Add &Local... + + + false + + + true @@ -53,45 +94,105 @@ + + + 0 + 0 + + - Move the selected database upwards in the list + Move the selected citation up (Ctrl-Up) &Up + + + .. + + + false + + + + 0 + 0 + + - Move the selected database downwards in the list + Move the selected citation down (Ctrl-Down) Do&wn + + + .. + + + false + + + + + Qt::Vertical + + + + 20 + 40 + + + + - - + + - + - E&ncoding: + Sele&cted: - bibEncodingCO + selectedLV - - - If your bibliography databases use a different encoding than the LyX document, specify it here + + + QAbstractItemView::NoEditTriggers + + + + + + + + + + + &Filter: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + @@ -105,6 +206,23 @@ + + + + E&ncoding: + + + bibEncodingCO + + + + + + + If your bibliography databases use a different encoding than the LyX document, specify it here + + + @@ -144,10 +262,10 @@ - Choose a style file + Select a style file from your local directory - &Browse... + Add L&ocal... false @@ -207,7 +325,17 @@ - + + + Add bibliography to the table of contents + + + Add bibliography to &TOC + + + + + Qt::Horizontal @@ -221,16 +349,6 @@ - - - - Add bibliography to the table of contents - - - Add bibliography to &TOC - - - @@ -310,11 +428,9 @@ - addBibPB deletePB styleCB stylePB - bibtocCB btPrintCO