X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiCitation.cpp;h=5e35afca793dd75001c4aaa08f5f10c476b18493;hb=f973855bdea94f0c6edf8eace7548a440f005902;hp=d73f3d3542683a0a44049cf5bcbbfb2ead31fed3;hpb=74f774d6cf18a897deb533d3afc697abb31f824e;p=lyx.git diff --git a/src/frontends/qt4/GuiCitation.cpp b/src/frontends/qt4/GuiCitation.cpp index d73f3d3542..5e35afca79 100644 --- a/src/frontends/qt4/GuiCitation.cpp +++ b/src/frontends/qt4/GuiCitation.cpp @@ -18,7 +18,6 @@ #include "GuiApplication.h" #include "GuiSelectionManager.h" -#include "LyXToolBox.h" #include "qt_helpers.h" #include "Buffer.h" @@ -28,6 +27,7 @@ #include "TextClass.h" #include "FuncRequest.h" +#include "insets/InsetCitation.h" #include "insets/InsetCommand.h" #include "support/debug.h" @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -92,7 +93,7 @@ static vector to_docstring_vector(QStringList const & qlist) GuiCitation::GuiCitation(GuiView & lv) : DialogView(lv, "citation", qt_("Citation")), - style_(0), params_(insetCode("citation")) + style_(QString()), params_(insetCode("citation")) { setupUi(this); @@ -126,6 +127,8 @@ GuiCitation::GuiCitation(GuiView & lv) this, SLOT(on_citationStyleCO_currentIndexChanged(int))); connect(starredCB, SIGNAL(clicked()), this, SLOT(updateStyles())); + connect(literalCB, SIGNAL(clicked()), + this, SLOT(changed())); connect(forceuppercaseCB, SIGNAL(clicked()), this, SLOT(updateStyles())); connect(textBeforeED, SIGNAL(textChanged(QString)), @@ -133,18 +136,18 @@ GuiCitation::GuiCitation(GuiView & lv) connect(textAfterED, SIGNAL(textChanged(QString)), this, SLOT(updateStyles())); connect(textBeforeED, SIGNAL(returnPressed()), - this, SLOT(on_okPB_clicked())); + this, SLOT(on_buttonBox_accepted())); connect(textAfterED, SIGNAL(returnPressed()), - this, SLOT(on_okPB_clicked())); + this, SLOT(on_buttonBox_accepted())); - selectionManager = new GuiSelectionManager(availableLV, selectedLV, - addPB, deletePB, upPB, downPB, &available_model_, &selected_model_); + selectionManager = new GuiSelectionManager(this, availableLV, selectedLV, + addPB, deletePB, upPB, downPB, &available_model_, &selected_model_, 1); connect(selectionManager, SIGNAL(selectionChanged()), this, SLOT(setCitedKeys())); connect(selectionManager, SIGNAL(updateHook()), this, SLOT(updateControls())); connect(selectionManager, SIGNAL(okHook()), - this, SLOT(on_okPB_clicked())); + this, SLOT(on_buttonBox_accepted())); connect(filter_, SIGNAL(rightButtonClicked()), this, SLOT(resetFilter())); @@ -152,6 +155,13 @@ 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 connect(regexp_, SIGNAL(triggered()), this, SLOT(regexChanged())); connect(casesense_, SIGNAL(triggered()), @@ -159,13 +169,15 @@ GuiCitation::GuiCitation(GuiView & lv) connect(instant_, SIGNAL(triggered(bool)), this, SLOT(instantChanged(bool))); - setFocusProxy(filter_); -} - +#if (QT_VERSION < 0x050000) + selectedLV->horizontalHeader()->setResizeMode(QHeaderView::Stretch); +#else + selectedLV->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +#endif -GuiCitation::~GuiCitation() -{ - delete selectionManager; + selectedLV->setToolTip(qt_("Ordered list of all cited references.\n" + "You can reorder, add and remove references with the buttons on the left.")); + setFocusProxy(filter_); } @@ -179,7 +191,7 @@ void GuiCitation::closeEvent(QCloseEvent * e) void GuiCitation::applyView() { int const choice = max(0, citationStyleCO->currentIndex()); - style_ = choice; + style_ = citationStyleCO->itemData(citationStyleCO->currentIndex()).toString(); bool const full = starredCB->isChecked(); bool const force = forceuppercaseCB->isChecked(); @@ -192,13 +204,14 @@ void GuiCitation::applyView() void GuiCitation::showEvent(QShowEvent * e) { - filter_->clear(); + if (!filter_->text().isEmpty()) + filterPressed(); availableLV->setFocus(); DialogView::showEvent(e); } -void GuiCitation::on_okPB_clicked() +void GuiCitation::on_buttonBox_accepted() { applyView(); clearSelection(); @@ -206,23 +219,34 @@ void GuiCitation::on_okPB_clicked() } -void GuiCitation::on_cancelPB_clicked() +void GuiCitation::on_buttonBox_rejected() { clearSelection(); hide(); } -void GuiCitation::on_applyPB_clicked() +void GuiCitation::on_buttonBox_clicked(QAbstractButton * button) { - applyView(); + switch (buttonBox->standardButton(button)) { + case QDialogButtonBox::Apply: + applyView(); + break; + case QDialogButtonBox::Reset: + init(); + updateFilterHint(); + filterPressed(); + break; + default: + break; + } } -void GuiCitation::on_restorePB_clicked() +void GuiCitation::on_literalCB_clicked() { - init(); - updateFilterHint(); + InsetCitation::last_literal = literalCB->isChecked(); + changed(); } @@ -239,13 +263,17 @@ void GuiCitation::updateControls() // will not have changed. void GuiCitation::updateControls(BiblioInfo const & bi) { - QModelIndex idx = selectionManager->getSelectedIndex(); + QModelIndex idx = selectionManager->getSelectedIndex(1); updateInfo(bi, idx); + int i = citationStyleCO->currentIndex(); + if (i == -1 || i > int(citeStyles_.size())) + i = 0; + updateFormatting(citeStyles_[i]); selectionManager->update(); } -void GuiCitation::updateFormatting(CitationStyle currentStyle) +void GuiCitation::updateFormatting(CitationStyle const & currentStyle) { BufferParams const bp = documentBuffer().params(); bool const force = currentStyle.forceUpperCase; @@ -254,15 +282,53 @@ void GuiCitation::updateFormatting(CitationStyle currentStyle) bool const textbefore = currentStyle.textBefore; bool const textafter = currentStyle.textAfter; - bool const haveSelection = - selectedLV->model()->rowCount() > 0; + int const rows = selectedLV->model()->rowCount(); + + bool const qualified = currentStyle.hasQualifiedList + && (rows > 1 + || !params_["pretextlist"].empty() + || !params_["posttextlist"].empty()); + selectedLV->horizontalHeader()->setVisible(qualified); + selectedLV->setColumnHidden(0, !qualified); + selectedLV->setColumnHidden(2, !qualified); + bool const haveSelection = rows > 0; + if (qualified) { + textBeforeLA->setText(qt_("General text befo&re:")); + textAfterLA->setText(qt_("General &text after:")); + textBeforeED->setToolTip(qt_("Text that precedes the whole reference list. " + "For text that precedes individual items, " + "double-click on the respective entry above.")); + textAfterLA->setToolTip(qt_("General &text after:")); + textAfterED->setToolTip(qt_("Text that follows the whole reference list. " + "For text that follows individual items, " + "double-click on the respective entry above.")); + } else { + textBeforeLA->setText(qt_("Text befo&re:")); + if (textbefore && haveSelection) + textBeforeED->setToolTip(qt_("Text that precedes the reference (e.g., \"cf.\")")); + else + textBeforeED->setToolTip(qt_("Text that precedes the reference (e.g., \"cf.\"), " + "if the current citation style supports this.")); + textAfterLA->setText(qt_("&Text after:")); + if (textafter && haveSelection) + textAfterED->setToolTip(qt_("Text that follows the reference (e.g., pages)")); + else + textAfterED->setToolTip(qt_("Text that follows the reference (e.g., pages), " + "if the current citation style supports this.")); + } forceuppercaseCB->setEnabled(force && haveSelection); + if (force && haveSelection) + forceuppercaseCB->setToolTip(qt_("Force upper case in names (\"Del Piero\", not \"del Piero\").")); + else + forceuppercaseCB->setToolTip(qt_("Force upper case in names (\"Del Piero\", not \"del Piero\"), " + "if the current citation style supports this.")); starredCB->setEnabled(full && haveSelection); textBeforeED->setEnabled(textbefore && haveSelection); textBeforeLA->setEnabled(textbefore && haveSelection); textAfterED->setEnabled(textafter && haveSelection); textAfterLA->setEnabled(textafter && haveSelection); + literalCB->setEnabled(textbefore || textafter); citationStyleCO->setEnabled(haveSelection); citationStyleLA->setEnabled(haveSelection); @@ -287,8 +353,18 @@ void GuiCitation::updateFormatting(CitationStyle currentStyle) } else { // This is the default meaning of the starred commands starredCB->setText(qt_("All aut&hors")); - starredCB->setToolTip(qt_("Always list all authors (rather than using \"et al.\")")); + if (full && haveSelection) + starredCB->setToolTip(qt_("Always list all authors (rather than using \"et al.\")")); + else + starredCB->setToolTip(qt_("Always list all authors (rather than using \"et al.\"), " + "if the current citation style supports this.")); } + if (availableLV->selectionModel()->selectedIndexes().isEmpty()) + availableLV->setToolTip(qt_("All references available for citing.")); + else + 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.")); } @@ -306,7 +382,7 @@ void GuiCitation::updateStyles() // Update the styles for the style combo, citationStyleCO. void GuiCitation::updateStyles(BiblioInfo const & bi) { - QStringList selected_keys = selected_model_.stringList(); + QStringList selected_keys = selectedKeys(); int curr = selectedLV->model()->rowCount() - 1; if (curr < 0 || selected_keys.empty()) { @@ -317,9 +393,9 @@ void GuiCitation::updateStyles(BiblioInfo const & bi) } static const size_t max_length = 80; - QStringList sty = citationStyles(bi, max_length); + BiblioInfo::CiteStringMap sty = citationStyles(bi, max_length); - if (sty.isEmpty()) { + if (sty.empty()) { // some error citationStyleCO->setEnabled(false); citationStyleLA->setEnabled(false); @@ -329,16 +405,21 @@ void GuiCitation::updateStyles(BiblioInfo const & bi) citationStyleCO->blockSignals(true); - // save old index - int const curindex = citationStyleCO->currentIndex(); - int const oldIndex = (curindex < 0) ? style_ : curindex; + // save old style selection + QString const curdata = + citationStyleCO->itemData(citationStyleCO->currentIndex()).toString(); + QString const olddata = (curdata.isEmpty()) ? style_ : curdata; citationStyleCO->clear(); - citationStyleCO->insertItems(0, sty); + BiblioInfo::CiteStringMap::const_iterator cit = sty.begin(); + BiblioInfo::CiteStringMap::const_iterator end = sty.end(); + for (int ii = 1; cit != end; ++cit, ++ii) + citationStyleCO->addItem(toqstr(cit->second), toqstr(cit->first)); citationStyleCO->setEnabled(true); citationStyleLA->setEnabled(true); - // restore old index - if (oldIndex != -1 && oldIndex < citationStyleCO->count()) - citationStyleCO->setCurrentIndex(oldIndex); + // restore old style selection + int const i = citationStyleCO->findData(olddata); + if (i != -1) + citationStyleCO->setCurrentIndex(i); citationStyleCO->blockSignals(false); } @@ -376,15 +457,15 @@ void GuiCitation::fillEntries(BiblioInfo const & bi) bool GuiCitation::isSelected(QModelIndex const & idx) { QString const str = idx.data().toString(); - return selected_model_.stringList().contains(str); + return selectedKeys().contains(str); } void GuiCitation::setButtons() { int const srows = selectedLV->model()->rowCount(); - applyPB->setEnabled(srows > 0); - okPB->setEnabled(srows > 0); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(srows > 0); + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(srows > 0); } @@ -506,9 +587,10 @@ void GuiCitation::regexChanged() void GuiCitation::updateFilterHint() { - QString const hint = instant_->isChecked() ? + QString hint = instant_->isChecked() ? qt_("Enter string to filter the list of available citations") : qt_("Enter string to filter the list of available citations and press "); + hint += qt_("\nThe down arrow key will get you into the list of filtered citations."); filter_->setToolTip(hint); } @@ -551,6 +633,11 @@ void GuiCitation::applyParams(int const choice, bool full, bool force, params_["key"] = qstring_to_ucs4(cited_keys_.join(",")); params_["before"] = qstring_to_ucs4(before); params_["after"] = qstring_to_ucs4(after); + if (cs.hasQualifiedList) { + params_["pretextlist"] = getStringFromVector(getPreTexts(), from_ascii("\t")); + params_["posttextlist"] = getStringFromVector(getPostTexts(), from_ascii("\t")); + } + params_["literal"] = literalCB->isChecked() ? from_ascii("true") : from_ascii("false"); dispatchParams(); } @@ -558,7 +645,107 @@ void GuiCitation::applyParams(int const choice, bool full, bool force, void GuiCitation::clearSelection() { cited_keys_.clear(); - selected_model_.setStringList(cited_keys_); + setSelectedKeys(cited_keys_); +} + + +void GuiCitation::setSelectedKeys(QStringList const sl) +{ + selected_model_.clear(); + selected_model_.setColumnCount(3); + QStringList headers; + headers << qt_("Text before") + << qt_("Cite key") + << qt_("Text after"); + selected_model_.setHorizontalHeaderLabels(headers); + selectedLV->setColumnHidden(0, true); + selectedLV->setColumnHidden(2, true); + selectedLV->verticalHeader()->setVisible(false); + selectedLV->horizontalHeader()->setVisible(false); + 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_.setItem(i, 1, si); + } +} + + +QStringList GuiCitation::selectedKeys() +{ + QStringList res; + for (int i = 0; i != selected_model_.rowCount(); ++i) { + QStandardItem const * item = selected_model_.item(i, 1); + if (item) + res.append(item->text()); + } + return res; +} + + +void GuiCitation::setPreTexts(vector const m) +{ + for (docstring const & s: m) { + QStandardItem * si = new QStandardItem(); + docstring key; + docstring pre = split(s, key, ' '); + 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); + } +} + + +vector GuiCitation::getPreTexts() +{ + vector res; + 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()) + res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(pre->text())); + } + return res; +} + + +void GuiCitation::setPostTexts(vector const m) +{ + for (docstring const & s: m) { + QStandardItem * si = new QStandardItem(); + docstring key; + docstring post = split(s, key, ' '); + 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); + } +} + + +vector GuiCitation::getPostTexts() +{ + vector res; + 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()) + res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(post->text())); + } + return res; } @@ -567,6 +754,7 @@ void GuiCitation::init() // Make the list of all available bibliography keys BiblioInfo const & bi = bibInfo(); all_keys_ = to_qstring_list(bi.getKeys()); + available_model_.setStringList(all_keys_); // Ditto for the keys cited in this inset @@ -575,7 +763,7 @@ void GuiCitation::init() cited_keys_.clear(); else cited_keys_ = str.split(","); - selected_model_.setStringList(cited_keys_); + setSelectedKeys(cited_keys_); // Initialize the drop downs fillEntries(bi); @@ -585,21 +773,30 @@ void GuiCitation::init() string const & cmd = params_.getCmdName(); CitationStyle const cs = citationStyleFromString(cmd, documentBuffer().params()); + forceuppercaseCB->setChecked(cs.forceUpperCase); starredCB->setChecked(cs.hasStarredVersion && documentBuffer().params().fullAuthorList()); textBeforeED->setText(toqstr(params_["before"])); textAfterED->setText(toqstr(params_["after"])); + // if this is a new citation, we set the literal checkbox + // to its last set value. + if (cited_keys_.isEmpty()) + literalCB->setChecked(InsetCitation::last_literal); + else + literalCB->setChecked(params_["literal"] == "true"); + + setPreTexts(getVectorFromString(params_["pretextlist"], from_ascii("\t"))); + setPostTexts(getVectorFromString(params_["posttextlist"], from_ascii("\t"))); + // Update the interface updateControls(bi); updateStyles(bi); if (selected_model_.rowCount()) { selectedLV->blockSignals(true); selectedLV->setFocus(); - QModelIndex idx = selected_model_.index(0, 0); - selectedLV->selectionModel()->select(idx, - QItemSelectionModel::ClearAndSelect); + selectedLV->selectRow(0); selectedLV->blockSignals(false); // Find the citation style @@ -618,8 +815,8 @@ void GuiCitation::init() } else availableLV->setFocus(); - applyPB->setEnabled(false); - okPB->setEnabled(false); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } @@ -678,10 +875,32 @@ void GuiCitation::findKey(BiblioInfo const & bi, } -QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size) +BiblioInfo::CiteStringMap GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size) { vector const keys = to_docstring_vector(cited_keys_); vector styles = citeStyles_; + int ind = citationStyleCO->currentIndex(); + if (ind == -1) + ind = 0; + CitationStyle cs = styles[ind]; + vector pretexts = getPreTexts(); + vector posttexts = getPostTexts(); + bool const qualified = cs.hasQualifiedList + && (selectedLV->model()->rowCount() > 1 + || !pretexts.empty() + || !posttexts.empty()); + std::map pres; + for (docstring const & s: pretexts) { + docstring key; + docstring val = split(s, key, ' '); + pres[key] = val; + } + std::map posts; + for (docstring const & s: posttexts) { + docstring key; + docstring val = split(s, key, ' '); + posts[key] = val; + } CiteItem ci; ci.textBefore = qstring_to_ucs4(textBeforeED->text()); ci.textAfter = qstring_to_ucs4(textAfterED->text()); @@ -689,21 +908,24 @@ QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size) ci.Starred = starredCB->isChecked(); ci.context = CiteItem::Dialog; ci.max_size = max_size; - vector ret = bi.getCiteStrings(keys, styles, documentBuffer(), ci); - return to_qstring_list(ret); + ci.isQualified = qualified; + ci.pretexts = pres; + ci.posttexts = posts; + BiblioInfo::CiteStringMap ret = bi.getCiteStrings(keys, styles, documentBuffer(), ci); + return ret; } void GuiCitation::setCitedKeys() { - cited_keys_ = selected_model_.stringList(); + cited_keys_ = selectedKeys(); updateStyles(); } -bool GuiCitation::initialiseParams(string const & data) +bool GuiCitation::initialiseParams(string const & sdata) { - InsetCommand::string2params(data, params_); + InsetCommand::string2params(sdata, params_); citeCmds_ = documentBuffer().params().citeCommands(); citeStyles_ = documentBuffer().params().citeStyles(); init(); @@ -803,19 +1025,19 @@ vector GuiCitation::searchKeys(BiblioInfo const & bi, continue; BibTeXInfo const & kvm = info->second; - string data; + string sdata; if (only_keys) - data = to_utf8(*it); + sdata = to_utf8(*it); else if (field.empty()) - data = to_utf8(*it) + ' ' + to_utf8(kvm.allData()); + sdata = to_utf8(*it) + ' ' + to_utf8(kvm.allData()); else - data = to_utf8(kvm[field]); + sdata = to_utf8(kvm[field]); - if (data.empty()) + if (sdata.empty()) continue; try { - if (lyx::regex_search(data, reg_exp)) + if (lyx::regex_search(sdata, reg_exp)) foundKeys.push_back(*it); } catch (lyx::regex_error const & e) { @@ -842,10 +1064,9 @@ BiblioInfo const & GuiCitation::bibInfo() const } -void GuiCitation::saveSession() const +void GuiCitation::saveSession(QSettings & settings) const { - Dialog::saveSession(); - QSettings settings; + Dialog::saveSession(settings); settings.setValue( sessionKey() + "/regex", regexp_->isChecked()); settings.setValue( @@ -854,6 +1075,8 @@ void GuiCitation::saveSession() const sessionKey() + "/autofind", instant_->isChecked()); settings.setValue( sessionKey() + "/citestyle", style_); + settings.setValue( + sessionKey() + "/literal", InsetCitation::last_literal); } @@ -863,8 +1086,10 @@ void GuiCitation::restoreSession() QSettings settings; regexp_->setChecked(settings.value(sessionKey() + "/regex").toBool()); casesense_->setChecked(settings.value(sessionKey() + "/casesensitive").toBool()); - instant_->setChecked(settings.value(sessionKey() + "/autofind").toBool()); - style_ = settings.value(sessionKey() + "/citestyle").toInt(); + instant_->setChecked(settings.value(sessionKey() + "/autofind", true).toBool()); + style_ = settings.value(sessionKey() + "/citestyle").toString(); + InsetCitation::last_literal = + settings.value(sessionKey() + "/literal", false).toBool(); updateFilterHint(); }