X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FGuiCitation.cpp;h=c5fa26631098b17c331d78b0fc71ea603b2b0c45;hb=29a8097c3c14aad871c7e396a59542fe47e39ea1;hp=196ec44d2b7b5bb6c26c022353082e03e62edf61;hpb=c293be56bd12c5dc46e5cedd2828e33918fccef7;p=lyx.git diff --git a/src/frontends/qt/GuiCitation.cpp b/src/frontends/qt/GuiCitation.cpp index 196ec44d2b..c5fa266310 100644 --- a/src/frontends/qt/GuiCitation.cpp +++ b/src/frontends/qt/GuiCitation.cpp @@ -7,7 +7,7 @@ * \author Angus Leeming * \author Kalle Dalheimer * \author Abdelrazak Younes - * \author Richard Heck + * \author Richard Kimberly Heck * * Full author contact details are available in file CREDITS. */ @@ -16,14 +16,17 @@ #include "GuiCitation.h" +#include "FancyLineEdit.h" #include "GuiApplication.h" #include "GuiSelectionManager.h" +#include "GuiView.h" #include "qt_helpers.h" #include "Buffer.h" #include "BufferView.h" -#include "BiblioInfo.h" #include "BufferParams.h" +#include "Citation.h" +#include "Cursor.h" #include "TextClass.h" #include "FuncRequest.h" @@ -42,14 +45,10 @@ #include #include -#include -#include - #undef KeyPress -#include "support/regex.h" - #include +#include #include #include @@ -99,10 +98,7 @@ GuiCitation::GuiCitation(GuiView & lv) // 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_->setClearButton(true); filter_->setPlaceholderText(qt_("All avail. citations")); filterBarL->addWidget(filter_, 0); @@ -144,6 +140,8 @@ GuiCitation::GuiCitation(GuiView & lv) addPB, deletePB, upPB, downPB, &available_model_, &selected_model_, 1); connect(selectionManager, SIGNAL(selectionChanged()), this, SLOT(setCitedKeys())); + connect(selectionManager, SIGNAL(updateHook()), + this, SLOT(setCitedKeys())); connect(selectionManager, SIGNAL(updateHook()), this, SLOT(updateControls())); connect(selectionManager, SIGNAL(okHook()), @@ -155,13 +153,8 @@ GuiCitation::GuiCitation(GuiView & lv) 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, [this](){ focusAndHighlight(availableLV); }); connect(regexp_, SIGNAL(triggered()), this, SLOT(regexChanged())); connect(casesense_, SIGNAL(triggered()), @@ -169,11 +162,7 @@ GuiCitation::GuiCitation(GuiView & lv) connect(instant_, SIGNAL(triggered(bool)), this, SLOT(instantChanged(bool))); -#if (QT_VERSION < 0x050000) - selectedLV->horizontalHeader()->setResizeMode(QHeaderView::Stretch); -#else selectedLV->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); -#endif selectedLV->setToolTip(qt_("Ordered list of all cited references.\n" "You can reorder, add and remove references with the buttons on the left.")); @@ -199,6 +188,7 @@ void GuiCitation::applyView() QString const after = textAfterED->text(); applyParams(choice, full, force, before, after); + connectToNewInset(); } @@ -284,12 +274,7 @@ void GuiCitation::updateFormatting(CitationStyle const & currentStyle) int const rows = selectedLV->model()->rowCount(); - bool const qualified = currentStyle.hasQualifiedList - && (rows > 1 - || !params_["pretextlist"].empty() - || !params_["posttextlist"].empty() - || !getPreTexts().empty() - || !getPostTexts().empty()); + bool const qualified = currentStyle.hasQualifiedList && rows > 0; selectedLV->horizontalHeader()->setVisible(qualified); selectedLV->setColumnHidden(0, !qualified); @@ -368,6 +353,8 @@ void GuiCitation::updateFormatting(CitationStyle const & currentStyle) availableLV->setToolTip(qt_("All references available for citing.\n" "To add the selected one, hit Add, press Enter or double-click.\n" "Hit Ctrl-Enter to add and close the dialog.")); + // With qualified citation lists, it makes sense to add the same key multiple times + selectionManager->allowMultiSelection(currentStyle.hasQualifiedList); } @@ -389,6 +376,8 @@ void GuiCitation::updateStyles(BiblioInfo const & bi) int curr = selectedLV->model()->rowCount() - 1; if (curr < 0 || selected_keys.empty()) { + last_chosen_style_ = + citationStyleCO->itemData(citationStyleCO->currentIndex()).toString(); citationStyleCO->clear(); citationStyleCO->setEnabled(false); citationStyleLA->setEnabled(false); @@ -411,7 +400,10 @@ void GuiCitation::updateStyles(BiblioInfo const & bi) // save old style selection QString const curdata = citationStyleCO->itemData(citationStyleCO->currentIndex()).toString(); - QString const olddata = (curdata.isEmpty()) ? style_ : curdata; + QString const olddata = (curdata.isEmpty()) ? + (last_chosen_style_.isEmpty() ? style_ : last_chosen_style_): curdata; + // reset this + last_chosen_style_.clear(); citationStyleCO->clear(); BiblioInfo::CiteStringMap::const_iterator cit = sty.begin(); BiblioInfo::CiteStringMap::const_iterator end = sty.end(); @@ -652,7 +644,7 @@ void GuiCitation::clearSelection() } -void GuiCitation::setSelectedKeys(QStringList const sl) +void GuiCitation::setSelectedKeys(QStringList const & sl) { selected_model_.clear(); selected_model_.setColumnCount(3); @@ -690,8 +682,10 @@ QStringList GuiCitation::selectedKeys() } -void GuiCitation::setPreTexts(vector const m) +void GuiCitation::setPreTexts(vector const & m) { + // account for multiple use of the same keys + QList handled; for (docstring const & s: m) { QStandardItem * si = new QStandardItem(); docstring key; @@ -699,11 +693,16 @@ void GuiCitation::setPreTexts(vector const m) si->setData(toqstr(pre)); si->setText(toqstr(pre)); QModelIndexList qmil = - selected_model_.match(selected_model_.index(0, 1), - Qt::DisplayRole, toqstr(key), 1, - Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap)); - if (!qmil.empty()) - selected_model_.setItem(qmil.front().row(), 0, si); + selected_model_.match(selected_model_.index(0, 1), + Qt::DisplayRole, toqstr(key), -1, + Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap)); + for (auto const & idx : qmil) { + if (!handled.contains(idx)) { + selected_model_.setItem(idx.row(), 0, si); + handled.append(idx); + break; + } + } } } @@ -714,15 +713,17 @@ vector GuiCitation::getPreTexts() for (int i = 0; i != selected_model_.rowCount(); ++i) { QStandardItem const * key = selected_model_.item(i, 1); QStandardItem const * pre = selected_model_.item(i, 0); - if (key && pre && !key->text().isEmpty() && !pre->text().isEmpty()) + if (key && pre && !key->text().isEmpty()) res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(pre->text())); } return res; } -void GuiCitation::setPostTexts(vector const m) +void GuiCitation::setPostTexts(vector const & m) { + // account for multiple use of the same keys + QList handled; for (docstring const & s: m) { QStandardItem * si = new QStandardItem(); docstring key; @@ -730,11 +731,16 @@ void GuiCitation::setPostTexts(vector const m) si->setData(toqstr(post)); si->setText(toqstr(post)); QModelIndexList qmil = - selected_model_.match(selected_model_.index(0, 1), - Qt::DisplayRole, toqstr(key), 1, - Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap)); - if (!qmil.empty()) - selected_model_.setItem(qmil.front().row(), 2, si); + selected_model_.match(selected_model_.index(0, 1), + Qt::DisplayRole, toqstr(key), -1, + Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap)); + for (auto const & idx : qmil) { + if (!handled.contains(idx)) { + selected_model_.setItem(idx.row(), 2, si); + handled.append(idx); + break; + } + } } } @@ -745,7 +751,7 @@ vector GuiCitation::getPostTexts() for (int i = 0; i != selected_model_.rowCount(); ++i) { QStandardItem const * key = selected_model_.item(i, 1); QStandardItem const * post = selected_model_.item(i, 2); - if (key && post && !key->text().isEmpty() && !post->text().isEmpty()) + if (key && post && !key->text().isEmpty()) res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(post->text())); } return res; @@ -892,17 +898,17 @@ BiblioInfo::CiteStringMap GuiCitation::citationStyles(BiblioInfo const & bi, siz && (selectedLV->model()->rowCount() > 1 || !pretexts.empty() || !posttexts.empty()); - std::map pres; + vector> pres; for (docstring const & s: pretexts) { docstring key; docstring val = split(s, key, ' '); - pres[key] = val; + pres.push_back(make_pair(key, val)); } - std::map posts; + vector> posts; for (docstring const & s: posttexts) { docstring key; docstring val = split(s, key, ' '); - posts[key] = val; + posts.push_back(make_pair(key, val)); } CiteItem ci; ci.textBefore = qstring_to_ucs4(textBeforeED->text()); @@ -943,7 +949,7 @@ void GuiCitation::clearParams() void GuiCitation::filterByEntryType(BiblioInfo const & bi, - vector & keyVector, docstring entry_type) + vector & keyVector, docstring const & entry_type) { if (entry_type.empty()) return; @@ -973,30 +979,21 @@ static docstring escape_special_chars(docstring const & expr) { // Search for all chars '.|*?+(){}[^$]\' // Note that '[', ']', and '\' must be escaped. - static const lyx::regex reg("[.|*?+(){}^$\\[\\]\\\\]"); + static const regex reg("[.|*?+(){}^$\\[\\]\\\\]"); // $& is an ECMAScript format expression that expands to all // of the current match -#ifdef LYX_USE_STD_REGEX // To prefix a matched expression with a single literal backslash, we // need to escape it for the C++ compiler and use: // FIXME: UNICODE - return from_utf8(lyx::regex_replace(to_utf8(expr), reg, string("\\$&"))); -#else - // A backslash in the format string starts an escape sequence in boost. - // Thus, to prefix a matched expression with a single literal backslash, - // we need to give two backslashes to the regex engine, and escape both - // for the C++ compiler and use: - // FIXME: UNICODE - return from_utf8(lyx::regex_replace(to_utf8(expr), reg, string("\\\\$&"))); -#endif + return from_utf8(regex_replace(to_utf8(expr), reg, string("\\$&"))); } vector GuiCitation::searchKeys(BiblioInfo const & bi, vector const & keys_to_search, bool only_keys, - docstring const & search_expression, docstring field, - bool case_sensitive, bool regex) + docstring const & search_expression, docstring const & field, + bool case_sensitive, bool re) { vector foundKeys; @@ -1004,17 +1001,17 @@ vector GuiCitation::searchKeys(BiblioInfo const & bi, if (expr.empty()) return foundKeys; - if (!regex) + if (!re) // We must escape special chars in the search_expr so that - // it is treated as a simple string by lyx::regex. + // it is treated as a simple string by regex. expr = escape_special_chars(expr); - lyx::regex reg_exp; + regex reg_exp; try { reg_exp.assign(to_utf8(expr), case_sensitive ? - lyx::regex_constants::ECMAScript : lyx::regex_constants::icase); - } catch (lyx::regex_error const & e) { - // lyx::regex throws an exception if the regular expression is not + regex_constants::ECMAScript : regex_constants::icase); + } catch (regex_error const & e) { + // regex throws an exception if the regular expression is not // valid. LYXERR(Debug::GUI, e.what()); return vector(); @@ -1040,10 +1037,10 @@ vector GuiCitation::searchKeys(BiblioInfo const & bi, continue; try { - if (lyx::regex_search(sdata, reg_exp)) + if (regex_search(sdata, reg_exp)) foundKeys.push_back(*it); } - catch (lyx::regex_error const & e) { + catch (regex_error const & e) { LYXERR(Debug::GUI, e.what()); return vector(); } @@ -1097,9 +1094,6 @@ void GuiCitation::restoreSession() } -Dialog * createGuiCitation(GuiView & lv) { return new GuiCitation(lv); } - - } // namespace frontend } // namespace lyx