Fix (biblatex) file encoding handling in GuiBibtex (#13109)

(cherry picked from commit 83006fc080)
This commit is contained in:
Juergen Spitzmueller 2024-10-08 14:04:34 +02:00
parent 7093fe18e9
commit 6a9677db4f
3 changed files with 145 additions and 33 deletions

View File

@ -181,8 +181,31 @@ void GuiBibtex::setButtons()
void GuiBibtex::selUpdated() void GuiBibtex::selUpdated()
{ {
vector<docstring> nfe;
if (usingBiblatex()) {
// check for current file encodings
for (int i = 0; i != selected_model_.rowCount(); ++i) {
QStandardItem const * key = selected_model_.item(i, 0);
QComboBox * cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(i, 1)));
QString fenc = cb ? cb->itemData(cb->currentIndex()).toString() : QString();
if (fenc.isEmpty())
fenc = cached_file_encodings_[key->text()];
else
cached_file_encodings_[key->text()] = fenc;
docstring const enc = qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(fenc);
if (key && !key->text().isEmpty() && !fenc.isEmpty() && fenc != "general")
nfe.push_back(enc);
}
}
selectionManager->update(); selectionManager->update();
editPB->setEnabled(deletePB->isEnabled()); editPB->setEnabled(deletePB->isEnabled());
if (usingBiblatex()) {
// Set file encodings as assembled above
for (int i = 0; i != selected_model_.rowCount(); ++i)
addEncCombo(i);
if (!nfe.empty())
setFileEncodings(nfe);
}
updateReAbs(); updateReAbs();
changed(); changed();
} }
@ -282,7 +305,6 @@ void GuiBibtex::inheritPressed()
if (!selected_bibs_.contains(toqstr(f))) { if (!selected_bibs_.contains(toqstr(f))) {
selected_bibs_.append(toqstr(f)); selected_bibs_.append(toqstr(f));
setSelectedBibs(selected_bibs_); setSelectedBibs(selected_bibs_);
string enc;
if (usingBiblatex()) { if (usingBiblatex()) {
string const bfe = buffer().masterParams().bibFileEncoding(to_utf8(f)); string const bfe = buffer().masterParams().bibFileEncoding(to_utf8(f));
if (!bfe.empty()) if (!bfe.empty())
@ -299,6 +321,48 @@ void GuiBibtex::inheritPressed()
} }
void GuiBibtex::updateFileEncodings()
{
vector<docstring> nfe;
for (int i = 0; i != selected_model_.rowCount(); ++i) {
QStandardItem const * key = selected_model_.item(i, 0);
QComboBox * cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(i, 1)));
QString fenc = cb ? cb->itemData(cb->currentIndex()).toString() : QString();
docstring const enc = qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(fenc);
if (key && !key->text().isEmpty() && !fenc.isEmpty() && fenc != "general")
nfe.push_back(enc);
}
if (!nfe.empty()) {
setFileEncodings(nfe);
change_adaptor();
}
}
bool GuiBibtex::hasFileEncodings() const
{
if (!usingBiblatex())
// only with biblatex, we have file encodings
return false;
// first check the applied encodings
docstring_list const mbibs = buffer().masterBuffer()->getBibfiles();
for (auto const & f : mbibs) {
string const bfe = buffer().masterParams().bibFileEncoding(to_utf8(f));
if (!bfe.empty() && bfe != "general")
return true;
}
// now check unapplied ones
for (QString const & enc : cached_file_encodings_) {
if (!enc.isEmpty() && enc != "general")
return true;
}
return false;
}
void GuiBibtex::relAbsPressed() void GuiBibtex::relAbsPressed()
{ {
LocalPath const p = localPathSelected(); LocalPath const p = localPathSelected();
@ -377,6 +441,28 @@ void GuiBibtex::updateReAbs()
} }
void GuiBibtex::addEncCombo(int const row)
{
QComboBox * ecb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(row, 1)));
if (ecb)
// encoding combo already exists
return;
// Add new combo and fill it
QComboBox * cb = new QComboBox;
cb->addItem(qt_("General Encoding"), "general");
cb->addItem(qt_("Document Encoding"), "auto");
QMap<QString, QString>::const_iterator it = encodings_.constBegin();
while (it != encodings_.constEnd()) {
cb->addItem(it.key(), it.value());
++it;
}
cb->setToolTip(qt_("If this bibliography database uses a different "
"encoding than specified below, set it here"));
selectedLV->setIndexWidget(selected_model_.index(row, 1), cb);
}
void GuiBibtex::setSelectedBibs(QStringList const & sl) void GuiBibtex::setSelectedBibs(QStringList const & sl)
{ {
selected_model_.clear(); selected_model_.clear();
@ -384,7 +470,28 @@ void GuiBibtex::setSelectedBibs(QStringList const & sl)
headers << qt_("Database") headers << qt_("Database")
<< qt_("File Encoding"); << qt_("File Encoding");
selected_model_.setHorizontalHeaderLabels(headers); selected_model_.setHorizontalHeaderLabels(headers);
bool const moreencs = usingBiblatex() && sl.count() > 1; 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);
addEncCombo(i);
QString const enc = cached_file_encodings_[*it];
if (!enc.isEmpty()) {
QComboBox * cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(i, 1)));
cb->setCurrentIndex(cb->findData(enc));
}
}
// Decide if we show file encoding combos. This is the case:
// 1. if we use Biblatex
// 2. and we have multiple items (otherwise you could set the genral encodung)
// 3. or a single item already has a non-standard encoding set
bool const moreencs = usingBiblatex() && (sl.count() > 1 || hasFileEncodings());
selectedLV->setColumnHidden(1, !moreencs); selectedLV->setColumnHidden(1, !moreencs);
selectedLV->verticalHeader()->setVisible(false); selectedLV->verticalHeader()->setVisible(false);
selectedLV->horizontalHeader()->setVisible(moreencs); selectedLV->horizontalHeader()->setVisible(moreencs);
@ -399,28 +506,8 @@ void GuiBibtex::setSelectedBibs(QStringList const & sl)
bibEncodingCO->setToolTip(qt_("If your bibliography databases use a different " bibEncodingCO->setToolTip(qt_("If your bibliography databases use a different "
"encoding than the LyX document, specify it here")); "encoding than the LyX document, specify it here"));
} }
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);
QComboBox * cb = new QComboBox;
cb->addItem(qt_("General Encoding"), "general");
cb->addItem(qt_("Document Encoding"), "auto");
QMap<QString, QString>::const_iterator it = encodings_.constBegin();
while (it != encodings_.constEnd()) {
cb->addItem(it.key(), it.value());
++it;
}
cb->setToolTip(qt_("If this bibliography database uses a different "
"encoding than specified below, set it here"));
selectedLV->setIndexWidget(selected_model_.index(i, 1), cb);
}
editPB->setEnabled(deletePB->isEnabled()); editPB->setEnabled(deletePB->isEnabled());
updateFileEncodings();
updateReAbs(); updateReAbs();
} }
@ -527,11 +614,12 @@ void GuiBibtex::applyView()
{ {
docstring dbs; docstring dbs;
int maxCount = selected_bibs_.count(); QStringList sb = selectedBibs();
int maxCount = sb.count();
for (int i = 0; i < maxCount; i++) { for (int i = 0; i < maxCount; i++) {
if (i != 0) if (i != 0)
dbs += ','; dbs += ',';
QString item = selected_bibs_.at(i); QString item = sb.at(i);
docstring bibfile = qstring_to_ucs4(item); docstring bibfile = qstring_to_ucs4(item);
dbs += bibfile; dbs += bibfile;
} }
@ -634,17 +722,30 @@ vector<docstring> GuiBibtex::getFileEncodings()
void GuiBibtex::setFileEncodings(vector<docstring> const & m) void GuiBibtex::setFileEncodings(vector<docstring> const & m)
{ {
if (!usingBiblatex())
// no file encodings
return;
for (docstring const & s: m) { for (docstring const & s: m) {
docstring key; docstring key;
QString enc = toqstr(split(s, key, ' ')); QString enc = toqstr(split(s, key, ' '));
// check if we have the key
QModelIndexList qmil = QModelIndexList qmil =
selected_model_.match(selected_model_.index(0, 0), selected_model_.match(selected_model_.index(0, 0),
Qt::DisplayRole, toqstr(key), 1, Qt::DisplayRole, toqstr(key), 1,
Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap)); Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
if (!qmil.empty()) { if (qmil.isEmpty())
QComboBox * cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(qmil.front().row(), 1))); continue;
cb->setCurrentIndex(cb->findData(enc)); int const row = qmil.front().row();
// assure we have an encoding combo in this row ...
QComboBox * cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(row, 1)));
if (!cb) {
addEncCombo(row);
cb = qobject_cast<QComboBox*>(selectedLV->indexWidget(selected_model_.index(row, 1)));
} }
if (!qmil.empty())
// ... and set it to the desired value
cb->setCurrentIndex(cb->findData(enc));
} }
} }

View File

@ -92,6 +92,8 @@ private:
std::vector<docstring> getFileEncodings(); std::vector<docstring> getFileEncodings();
/// ///
void setFileEncodings(std::vector<docstring> const & m); void setFileEncodings(std::vector<docstring> const & m);
/// Does this have non-default file encodings?
bool hasFileEncodings() const;
/// ///
bool initialiseParams(std::string const & data) override; bool initialiseParams(std::string const & data) override;
@ -111,8 +113,13 @@ private:
LP_Relative LP_Relative
}; };
LocalPath localPathSelected(); LocalPath localPathSelected();
/// /// Update "Make Relative/Absolute" button text and status
void updateReAbs(); void updateReAbs();
/// Update the file encodings in the available widget
void updateFileEncodings();
/// Add an encoding combo to the selected
/// item in row \p row if noe exists yet
void addEncCombo(int const row);
private: private:
/// ///
@ -129,8 +136,10 @@ private:
QStringList selected_bibs_; QStringList selected_bibs_;
/// contains the search box /// contains the search box
FancyLineEdit * filter_; FancyLineEdit * filter_;
/// /// List of available encodings
QMap<QString, QString> encodings_; QMap<QString, QString> encodings_;
/// cache of not yet applied file encodings
QMap<QString, QString> cached_file_encodings_;
}; };
} // namespace frontend } // namespace frontend

View File

@ -70,6 +70,8 @@ What's new
- Use proper background color with default branches and system colors. - Use proper background color with default branches and system colors.
- Fix handling of (biblatex) bib file encodings in dialog (bug 13109).
* INTERNALS * INTERNALS