This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This third patch just re-factors some code presently in QCitation*. (It also incorporates some bug fixes that have been committed separately.) We're going to use essentially the same set of widgets for choosing modules that is used for choosing citation keys, so we pull the controlling logic out into a new class, QSelectionManager. I did not make this a QWidget. That seemed to me to be overkill, and it would have made things much more complicated, I think...and I'm not all that experienced with Qt, anyway. Anyone who wants to do that is of course welcome.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19860 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-28 16:49:40 +00:00
|
|
|
/**
|
2007-08-31 05:53:55 +00:00
|
|
|
* \file GuiCitation.cpp
|
2006-03-05 17:24:44 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Angus Leeming
|
|
|
|
* \author Kalle Dalheimer
|
2007-03-25 01:32:12 +00:00
|
|
|
* \author Abdelrazak Younes
|
2007-08-31 22:37:05 +00:00
|
|
|
* \author Richard Heck
|
2006-03-05 17:24:44 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-08-31 05:53:55 +00:00
|
|
|
#include "GuiCitation.h"
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2007-11-29 07:04:28 +00:00
|
|
|
#include "support/debug.h"
|
|
|
|
#include "support/gettext.h"
|
2007-03-25 01:32:12 +00:00
|
|
|
#include "qt_helpers.h"
|
2007-10-06 11:33:33 +00:00
|
|
|
#include "Buffer.h"
|
|
|
|
#include "BufferParams.h"
|
2006-03-05 17:24:44 +00:00
|
|
|
|
|
|
|
#include "support/lstrings.h"
|
2007-08-20 16:30:02 +00:00
|
|
|
#include "support/docstring.h"
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2007-10-07 14:59:01 +00:00
|
|
|
#include "insets/InsetCommand.h"
|
|
|
|
|
2006-03-25 21:26:09 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2007-08-31 22:37:05 +00:00
|
|
|
#include <QCloseEvent>
|
|
|
|
|
|
|
|
#undef KeyPress
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
#include <boost/regex.hpp>
|
|
|
|
|
2007-08-31 22:37:05 +00:00
|
|
|
#include <algorithm>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2006-03-25 21:26:09 +00:00
|
|
|
using std::string;
|
2007-10-06 11:33:33 +00:00
|
|
|
using std::vector;
|
|
|
|
using std::pair;
|
2006-04-11 08:26:43 +00:00
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
namespace lyx {
|
|
|
|
namespace frontend {
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
static vector<biblio::CiteStyle> citeStyles_;
|
|
|
|
|
|
|
|
|
2007-08-31 22:37:05 +00:00
|
|
|
template<typename String>
|
|
|
|
static QStringList to_qstring_list(vector<String> const & v)
|
2006-03-25 21:26:09 +00:00
|
|
|
{
|
2006-04-11 08:26:43 +00:00
|
|
|
QStringList qlist;
|
|
|
|
|
2007-04-25 16:39:21 +00:00
|
|
|
for (size_t i = 0; i != v.size(); ++i) {
|
2006-03-25 21:26:09 +00:00
|
|
|
if (v[i].empty())
|
|
|
|
continue;
|
2006-10-21 00:16:43 +00:00
|
|
|
qlist.append(lyx::toqstr(v[i]));
|
2006-03-25 21:26:09 +00:00
|
|
|
}
|
2006-04-11 08:26:43 +00:00
|
|
|
return qlist;
|
2006-03-25 21:26:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-25 01:32:12 +00:00
|
|
|
|
2007-08-31 22:37:05 +00:00
|
|
|
static vector<lyx::docstring> to_docstring_vector(QStringList const & qlist)
|
2007-03-25 01:32:12 +00:00
|
|
|
{
|
2007-08-20 16:30:02 +00:00
|
|
|
vector<lyx::docstring> v;
|
2007-03-25 10:32:22 +00:00
|
|
|
for (int i = 0; i != qlist.size(); ++i) {
|
2007-03-25 01:32:12 +00:00
|
|
|
if (qlist[i].isEmpty())
|
|
|
|
continue;
|
2007-08-20 16:30:02 +00:00
|
|
|
v.push_back(lyx::qstring_to_ucs4(qlist[i]));
|
2007-03-25 01:32:12 +00:00
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2006-04-11 08:26:43 +00:00
|
|
|
|
2007-11-23 09:44:02 +00:00
|
|
|
GuiCitation::GuiCitation(GuiView & lv)
|
2007-10-07 14:59:01 +00:00
|
|
|
: GuiCommand(lv, "citation")
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
setupUi(this);
|
2007-09-05 20:33:29 +00:00
|
|
|
setViewTitle(_("Citation"));
|
2007-08-31 22:37:05 +00:00
|
|
|
|
|
|
|
connect(citationStyleCO, SIGNAL(activated(int)),
|
|
|
|
this, SLOT(changed()));
|
|
|
|
connect(fulllistCB, SIGNAL(clicked()),
|
|
|
|
this, SLOT(changed()));
|
|
|
|
connect(forceuppercaseCB, SIGNAL(clicked()),
|
|
|
|
this, SLOT(changed()));
|
2007-10-06 11:33:33 +00:00
|
|
|
connect(textBeforeED, SIGNAL(textChanged(QString)),
|
2007-08-31 22:37:05 +00:00
|
|
|
this, SLOT(changed()));
|
2007-10-06 11:33:33 +00:00
|
|
|
connect(textAfterED, SIGNAL(textChanged(QString)),
|
2007-08-31 22:37:05 +00:00
|
|
|
this, SLOT(changed()));
|
|
|
|
connect(clearPB, SIGNAL(clicked()),
|
|
|
|
findLE, SLOT(clear()));
|
|
|
|
connect(this, SIGNAL(rejected()), this, SLOT(cleanUp()));
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
selectionManager = new GuiSelectionManager(availableLV, selectedLV,
|
2007-09-05 20:33:29 +00:00
|
|
|
addPB, deletePB, upPB, downPB, available(), selected());
|
2007-08-31 22:37:05 +00:00
|
|
|
connect(selectionManager, SIGNAL(selectionChanged()),
|
|
|
|
this, SLOT(setCitedKeys()));
|
|
|
|
connect(selectionManager, SIGNAL(updateHook()),
|
|
|
|
this, SLOT(updateDialog()));
|
|
|
|
connect(selectionManager, SIGNAL(okHook()),
|
2007-10-06 11:33:33 +00:00
|
|
|
this, SLOT(on_okPB_clicked()));
|
2007-08-31 22:37:05 +00:00
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::cleanUp()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
clearSelection();
|
2007-10-06 11:33:33 +00:00
|
|
|
clearParams();
|
2007-08-31 22:37:05 +00:00
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::closeEvent(QCloseEvent * e)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
clearSelection();
|
2007-10-06 11:33:33 +00:00
|
|
|
clearParams();
|
2007-09-27 14:59:51 +00:00
|
|
|
GuiDialog::closeEvent(e);
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::applyView()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
int const choice = std::max(0, citationStyleCO->currentIndex());
|
|
|
|
style_ = choice;
|
|
|
|
bool const full = fulllistCB->isChecked();
|
|
|
|
bool const force = forceuppercaseCB->isChecked();
|
|
|
|
|
|
|
|
QString const before = textBeforeED->text();
|
|
|
|
QString const after = textAfterED->text();
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
apply(choice, full, force, before, after);
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::hideView()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-10-06 11:33:33 +00:00
|
|
|
clearParams();
|
2007-08-31 22:37:05 +00:00
|
|
|
accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::showView()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-15 01:53:26 +00:00
|
|
|
init();
|
2007-08-31 22:37:05 +00:00
|
|
|
findLE->clear();
|
|
|
|
availableLV->setFocus();
|
|
|
|
QDialog::show();
|
|
|
|
raise();
|
|
|
|
activateWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
bool GuiCitation::isVisibleView() const
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
return QDialog::isVisible();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_okPB_clicked()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-03 20:28:26 +00:00
|
|
|
applyView();
|
2007-09-05 20:33:29 +00:00
|
|
|
clearSelection();
|
2007-09-03 20:28:26 +00:00
|
|
|
hideView();
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_cancelPB_clicked()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
clearSelection();
|
|
|
|
hideView();
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_applyPB_clicked()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-03 20:28:26 +00:00
|
|
|
applyView();
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_restorePB_clicked()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
init();
|
|
|
|
updateView();
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::updateView()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-15 01:53:26 +00:00
|
|
|
init();
|
2007-08-31 22:37:05 +00:00
|
|
|
fillFields();
|
|
|
|
fillEntries();
|
|
|
|
updateDialog();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
// The main point of separating this out is that the fill*() methods
|
|
|
|
// called in update() do not need to be called for INTERNAL updates,
|
|
|
|
// such as when addPB is pressed, as the list of fields, entries, etc,
|
|
|
|
// will not have changed. At the moment, however, the division between
|
|
|
|
// fillStyles() and updateStyles() doesn't lend itself to dividing the
|
|
|
|
// two methods, though they should be divisible.
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::updateDialog()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
if (selectionManager->selectedFocused()) {
|
|
|
|
if (selectedLV->selectionModel()->selectedIndexes().isEmpty())
|
|
|
|
updateInfo(availableLV->currentIndex());
|
|
|
|
else
|
|
|
|
updateInfo(selectedLV->currentIndex());
|
|
|
|
} else {
|
|
|
|
if (availableLV->selectionModel()->selectedIndexes().isEmpty())
|
|
|
|
updateInfo(QModelIndex());
|
|
|
|
else
|
|
|
|
updateInfo(availableLV->currentIndex());
|
|
|
|
}
|
|
|
|
setButtons();
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
textBeforeED->setText(textBefore());
|
|
|
|
textAfterED->setText(textAfter());
|
2007-08-31 22:37:05 +00:00
|
|
|
fillStyles();
|
|
|
|
updateStyle();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::updateStyle()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-10-06 11:33:33 +00:00
|
|
|
biblio::CiteEngine const engine = getEngine();
|
2007-08-31 22:37:05 +00:00
|
|
|
bool const natbib_engine =
|
|
|
|
engine == biblio::ENGINE_NATBIB_AUTHORYEAR ||
|
|
|
|
engine == biblio::ENGINE_NATBIB_NUMERICAL;
|
|
|
|
bool const basic_engine = engine == biblio::ENGINE_BASIC;
|
|
|
|
|
|
|
|
bool const haveSelection =
|
|
|
|
selectedLV->model()->rowCount() > 0;
|
|
|
|
fulllistCB->setEnabled(natbib_engine && haveSelection);
|
|
|
|
forceuppercaseCB->setEnabled(natbib_engine && haveSelection);
|
|
|
|
textBeforeED->setEnabled(!basic_engine && haveSelection);
|
|
|
|
textBeforeLA->setEnabled(!basic_engine && haveSelection);
|
|
|
|
textAfterED->setEnabled(haveSelection);
|
|
|
|
textAfterLA->setEnabled(haveSelection);
|
|
|
|
citationStyleCO->setEnabled(!basic_engine && haveSelection);
|
|
|
|
citationStyleLA->setEnabled(!basic_engine && haveSelection);
|
|
|
|
|
2007-10-07 14:59:01 +00:00
|
|
|
string const & command = params_.getCmdName();
|
2007-08-31 22:37:05 +00:00
|
|
|
|
|
|
|
// Find the style of the citekeys
|
2007-10-06 11:33:33 +00:00
|
|
|
vector<biblio::CiteStyle> const & styles = citeStyles_;
|
2007-08-31 22:37:05 +00:00
|
|
|
biblio::CitationStyle const cs(command);
|
|
|
|
|
|
|
|
vector<biblio::CiteStyle>::const_iterator cit =
|
|
|
|
std::find(styles.begin(), styles.end(), cs.style);
|
|
|
|
|
|
|
|
// restore the latest natbib style
|
|
|
|
if (style_ >= 0 && style_ < citationStyleCO->count())
|
|
|
|
citationStyleCO->setCurrentIndex(style_);
|
|
|
|
else
|
|
|
|
citationStyleCO->setCurrentIndex(0);
|
|
|
|
|
|
|
|
if (cit != styles.end()) {
|
|
|
|
int const i = int(cit - styles.begin());
|
|
|
|
citationStyleCO->setCurrentIndex(i);
|
|
|
|
fulllistCB->setChecked(cs.full);
|
|
|
|
forceuppercaseCB->setChecked(cs.forceUCase);
|
|
|
|
} else {
|
|
|
|
fulllistCB->setChecked(false);
|
|
|
|
forceuppercaseCB->setChecked(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//This one needs to be called whenever citationStyleCO needs
|
|
|
|
//to be updated---and this would be on anything that changes the
|
|
|
|
//selection in selectedLV, or on a general update.
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::fillStyles()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
int const oldIndex = citationStyleCO->currentIndex();
|
|
|
|
|
|
|
|
citationStyleCO->clear();
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
QStringList selected_keys = selected()->stringList();
|
2007-08-31 22:37:05 +00:00
|
|
|
if (selected_keys.empty()) {
|
|
|
|
citationStyleCO->setEnabled(false);
|
|
|
|
citationStyleLA->setEnabled(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int curr = selectedLV->model()->rowCount() - 1;
|
|
|
|
if (curr < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!selectedLV->selectionModel()->selectedIndexes().empty())
|
|
|
|
curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
QStringList sty = citationStyles(curr);
|
2007-08-31 22:37:05 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
bool const basic_engine = (getEngine() == biblio::ENGINE_BASIC);
|
2007-08-31 22:37:05 +00:00
|
|
|
|
|
|
|
citationStyleCO->setEnabled(!sty.isEmpty() && !basic_engine);
|
|
|
|
citationStyleLA->setEnabled(!sty.isEmpty() && !basic_engine);
|
|
|
|
|
|
|
|
if (sty.isEmpty() || basic_engine)
|
|
|
|
return;
|
|
|
|
|
|
|
|
citationStyleCO->insertItems(0, sty);
|
|
|
|
|
|
|
|
if (oldIndex != -1 && oldIndex < citationStyleCO->count())
|
|
|
|
citationStyleCO->setCurrentIndex(oldIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::fillFields()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
fieldsCO->blockSignals(true);
|
|
|
|
int const oldIndex = fieldsCO->currentIndex();
|
|
|
|
fieldsCO->clear();
|
2007-09-05 20:33:29 +00:00
|
|
|
QStringList const & fields = getFieldsAsQStringList();
|
2007-08-31 22:37:05 +00:00
|
|
|
fieldsCO->insertItem(0, qt_("All Fields"));
|
|
|
|
fieldsCO->insertItem(1, qt_("Keys"));
|
|
|
|
fieldsCO->insertItems(2, fields);
|
|
|
|
if (oldIndex != -1 && oldIndex < fieldsCO->count())
|
|
|
|
fieldsCO->setCurrentIndex(oldIndex);
|
|
|
|
fieldsCO->blockSignals(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::fillEntries()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
entriesCO->blockSignals(true);
|
|
|
|
int const oldIndex = entriesCO->currentIndex();
|
|
|
|
entriesCO->clear();
|
2007-09-05 20:33:29 +00:00
|
|
|
QStringList const & entries = getEntriesAsQStringList();
|
2007-08-31 22:37:05 +00:00
|
|
|
entriesCO->insertItem(0, qt_("All Entry Types"));
|
|
|
|
entriesCO->insertItems(1, entries);
|
|
|
|
if (oldIndex != -1 && oldIndex < entriesCO->count())
|
|
|
|
entriesCO->setCurrentIndex(oldIndex);
|
|
|
|
entriesCO->blockSignals(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
bool GuiCitation::isSelected(const QModelIndex & idx)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
QString const str = idx.data().toString();
|
2007-09-05 20:33:29 +00:00
|
|
|
return selected()->stringList().contains(str);
|
2007-08-31 22:37:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::setButtons()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-09-15 01:53:26 +00:00
|
|
|
selectionManager->update();
|
2007-08-31 22:37:05 +00:00
|
|
|
int const srows = selectedLV->model()->rowCount();
|
|
|
|
applyPB->setEnabled(srows > 0);
|
|
|
|
okPB->setEnabled(srows > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::updateInfo(QModelIndex const & idx)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
if (idx.isValid()) {
|
2007-09-05 20:33:29 +00:00
|
|
|
QString const keytxt = getKeyInfo(idx.data().toString());
|
2007-08-31 22:37:05 +00:00
|
|
|
infoML->document()->setPlainText(keytxt);
|
|
|
|
} else
|
|
|
|
infoML->document()->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::findText(QString const & text, bool reset)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
//"All Fields" and "Keys" are the first two
|
|
|
|
int index = fieldsCO->currentIndex() - 2;
|
2007-10-06 11:33:33 +00:00
|
|
|
vector<docstring> const & fields = availableFields();
|
2007-08-31 22:37:05 +00:00
|
|
|
docstring field;
|
|
|
|
|
|
|
|
if (index <= -1 || index >= int(fields.size()))
|
|
|
|
//either "All Fields" or "Keys" or an invalid value
|
|
|
|
field = from_ascii("");
|
|
|
|
else
|
|
|
|
field = fields[index];
|
|
|
|
|
|
|
|
//Was it "Keys"?
|
|
|
|
bool const onlyKeys = index == -1;
|
|
|
|
|
|
|
|
//"All Entry Types" is first.
|
|
|
|
index = entriesCO->currentIndex() - 1;
|
2007-10-06 11:33:33 +00:00
|
|
|
vector<docstring> const & entries = availableEntries();
|
2007-08-31 22:37:05 +00:00
|
|
|
docstring entryType;
|
|
|
|
if (index < 0 || index >= int(entries.size()))
|
|
|
|
entryType = from_ascii("");
|
|
|
|
else
|
|
|
|
entryType = entries[index];
|
|
|
|
|
|
|
|
bool const case_sentitive = caseCB->checkState();
|
|
|
|
bool const reg_exp = regexCB->checkState();
|
2007-09-05 20:33:29 +00:00
|
|
|
findKey(text, onlyKeys, field, entryType,
|
2007-08-31 22:37:05 +00:00
|
|
|
case_sentitive, reg_exp, reset);
|
|
|
|
//FIXME
|
|
|
|
//It'd be nice to save and restore the current selection in
|
|
|
|
//availableLV. Currently, we get an automatic reset, since the
|
|
|
|
//model is reset.
|
|
|
|
|
|
|
|
updateDialog();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_fieldsCO_currentIndexChanged(int /*index*/)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
findText(findLE->text(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_entriesCO_currentIndexChanged(int /*index*/)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
findText(findLE->text(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_findLE_textChanged(const QString & text)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
clearPB->setDisabled(text.isEmpty());
|
|
|
|
if (text.isEmpty())
|
|
|
|
findLE->setFocus();
|
|
|
|
findText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_caseCB_stateChanged(int)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
findText(findLE->text());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::on_regexCB_stateChanged(int)
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
findText(findLE->text());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::changed()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
|
|
|
fillStyles();
|
|
|
|
setButtons();
|
|
|
|
}
|
|
|
|
|
2006-03-25 21:26:09 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::apply(int const choice, bool const full, bool const force,
|
2007-09-05 20:33:29 +00:00
|
|
|
QString before, QString after)
|
2006-03-05 17:24:44 +00:00
|
|
|
{
|
2007-03-25 01:32:12 +00:00
|
|
|
if (cited_keys_.isEmpty())
|
2006-06-28 08:28:16 +00:00
|
|
|
return;
|
2006-04-11 08:26:43 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
vector<biblio::CiteStyle> const & styles = citeStyles_;
|
2006-04-11 08:26:43 +00:00
|
|
|
|
|
|
|
string const command =
|
|
|
|
biblio::CitationStyle(styles[choice], full, force)
|
|
|
|
.asLatexStr();
|
|
|
|
|
2007-10-07 14:59:01 +00:00
|
|
|
params_.setCmdName(command);
|
|
|
|
params_["key"] = qstring_to_ucs4(cited_keys_.join(","));
|
|
|
|
params_["before"] = qstring_to_ucs4(before);
|
|
|
|
params_["after"] = qstring_to_ucs4(after);
|
2007-10-06 11:33:33 +00:00
|
|
|
dispatchParams();
|
2006-03-25 21:26:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::clearSelection()
|
2006-12-15 09:58:44 +00:00
|
|
|
{
|
2007-03-25 01:32:12 +00:00
|
|
|
cited_keys_.clear();
|
|
|
|
selected_model_.setStringList(cited_keys_);
|
2006-12-15 09:58:44 +00:00
|
|
|
}
|
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QString GuiCitation::textBefore()
|
2006-03-25 21:26:09 +00:00
|
|
|
{
|
2007-10-07 14:59:01 +00:00
|
|
|
return toqstr(params_["before"]);
|
2006-03-25 21:26:09 +00:00
|
|
|
}
|
2006-03-05 17:24:44 +00:00
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QString GuiCitation::textAfter()
|
2006-03-25 21:26:09 +00:00
|
|
|
{
|
2007-10-07 14:59:01 +00:00
|
|
|
return toqstr(params_["after"]);
|
2006-04-11 08:26:43 +00:00
|
|
|
}
|
2006-04-05 23:56:29 +00:00
|
|
|
|
2006-04-11 08:26:43 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::init()
|
2006-04-11 08:26:43 +00:00
|
|
|
{
|
2006-03-25 21:26:09 +00:00
|
|
|
// Make the list of all available bibliography keys
|
2007-10-06 11:33:33 +00:00
|
|
|
all_keys_ = to_qstring_list(availableKeys());
|
2007-03-25 01:32:12 +00:00
|
|
|
available_model_.setStringList(all_keys_);
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2006-03-25 21:26:09 +00:00
|
|
|
// Ditto for the keys cited in this inset
|
2007-10-07 14:59:01 +00:00
|
|
|
QString str = toqstr(params_["key"]);
|
2007-03-25 01:32:12 +00:00
|
|
|
if (str.isEmpty())
|
|
|
|
cited_keys_.clear();
|
|
|
|
else
|
|
|
|
cited_keys_ = str.split(",");
|
|
|
|
selected_model_.setStringList(cited_keys_);
|
2006-03-05 17:24:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::findKey(QString const & str, bool only_keys,
|
2007-08-20 16:30:02 +00:00
|
|
|
docstring field, docstring entryType,
|
|
|
|
bool case_sensitive, bool reg_exp, bool reset)
|
2006-03-25 21:26:09 +00:00
|
|
|
{
|
2007-03-25 01:32:12 +00:00
|
|
|
// Used for optimisation: store last searched string.
|
|
|
|
static QString last_searched_string;
|
|
|
|
// Used to disable the above optimisation.
|
|
|
|
static bool last_case_sensitive;
|
|
|
|
static bool last_reg_exp;
|
|
|
|
// Reset last_searched_string in case of changed option.
|
|
|
|
if (last_case_sensitive != case_sensitive
|
|
|
|
|| last_reg_exp != reg_exp) {
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::GUI, "GuiCitation::findKey: optimisation disabled!");
|
2007-03-25 01:32:12 +00:00
|
|
|
last_searched_string.clear();
|
|
|
|
}
|
|
|
|
// save option for next search.
|
|
|
|
last_case_sensitive = case_sensitive;
|
|
|
|
last_reg_exp = reg_exp;
|
|
|
|
|
|
|
|
Qt::CaseSensitivity qtcase = case_sensitive?
|
|
|
|
Qt::CaseSensitive: Qt::CaseInsensitive;
|
|
|
|
QStringList keys;
|
|
|
|
// If new string (str) contains the last searched one...
|
2007-08-20 16:30:02 +00:00
|
|
|
if (!reset &&
|
|
|
|
!last_searched_string.isEmpty() &&
|
|
|
|
str.size() > 1 &&
|
|
|
|
str.contains(last_searched_string, qtcase))
|
2007-03-25 01:32:12 +00:00
|
|
|
// ... then only search within already found list.
|
|
|
|
keys = available_model_.stringList();
|
|
|
|
else
|
|
|
|
// ... else search all keys.
|
|
|
|
keys = all_keys_;
|
|
|
|
// save searched string for next search.
|
|
|
|
last_searched_string = str;
|
|
|
|
|
|
|
|
QStringList result;
|
2007-08-20 16:30:02 +00:00
|
|
|
|
2007-08-31 22:37:05 +00:00
|
|
|
// First, filter by entryType, which will be faster than
|
|
|
|
// what follows, so we may get to do that on less.
|
2007-08-20 16:30:02 +00:00
|
|
|
vector<docstring> keyVector = to_docstring_vector(keys);
|
2007-10-06 11:33:33 +00:00
|
|
|
filterByEntryType(keyVector, entryType);
|
2007-08-20 16:30:02 +00:00
|
|
|
|
|
|
|
if (str.isEmpty())
|
|
|
|
result = to_qstring_list(keyVector);
|
2007-03-25 01:32:12 +00:00
|
|
|
else
|
2007-10-06 11:33:33 +00:00
|
|
|
result = to_qstring_list(searchKeys(keyVector, only_keys,
|
2007-08-20 16:30:02 +00:00
|
|
|
qstring_to_ucs4(str), field, case_sensitive, reg_exp));
|
|
|
|
|
2007-03-25 01:32:12 +00:00
|
|
|
available_model_.setStringList(result);
|
2006-03-25 21:26:09 +00:00
|
|
|
}
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2006-04-11 08:26:43 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QStringList GuiCitation::getFieldsAsQStringList()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-10-06 11:33:33 +00:00
|
|
|
return to_qstring_list(availableFields());
|
2007-08-20 16:30:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QStringList GuiCitation::getEntriesAsQStringList()
|
2007-08-31 22:37:05 +00:00
|
|
|
{
|
2007-10-06 11:33:33 +00:00
|
|
|
return to_qstring_list(availableEntries());
|
2007-08-20 16:30:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QStringList GuiCitation::citationStyles(int sel)
|
2006-04-11 08:26:43 +00:00
|
|
|
{
|
2007-08-20 16:30:02 +00:00
|
|
|
docstring const key = qstring_to_ucs4(cited_keys_[sel]);
|
2007-10-06 11:33:33 +00:00
|
|
|
return to_qstring_list(bibkeysInfo_.getCiteStrings(key, buffer()));
|
2006-03-05 17:24:44 +00:00
|
|
|
}
|
|
|
|
|
2006-06-28 08:28:16 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
QString GuiCitation::getKeyInfo(QString const & sel)
|
2006-06-28 08:28:16 +00:00
|
|
|
{
|
2007-10-06 11:33:33 +00:00
|
|
|
return toqstr(getInfo(qstring_to_ucs4(sel)));
|
2006-06-28 08:28:16 +00:00
|
|
|
}
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
void GuiCitation::setCitedKeys()
|
This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This third patch just re-factors some code presently in QCitation*. (It also incorporates some bug fixes that have been committed separately.) We're going to use essentially the same set of widgets for choosing modules that is used for choosing citation keys, so we pull the controlling logic out into a new class, QSelectionManager. I did not make this a QWidget. That seemed to me to be overkill, and it would have made things much more complicated, I think...and I'm not all that experienced with Qt, anyway. Anyone who wants to do that is of course welcome.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19860 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-28 16:49:40 +00:00
|
|
|
{
|
|
|
|
cited_keys_ = selected_model_.stringList();
|
|
|
|
}
|
|
|
|
|
2007-10-06 11:33:33 +00:00
|
|
|
|
|
|
|
bool GuiCitation::initialiseParams(string const & data)
|
|
|
|
{
|
2007-10-07 14:59:01 +00:00
|
|
|
InsetCommandMailer::string2params(lfun_name_, data, params_);
|
2007-10-06 11:33:33 +00:00
|
|
|
|
|
|
|
biblio::CiteEngine const engine = buffer().params().getEngine();
|
|
|
|
|
|
|
|
bool use_styles = engine != biblio::ENGINE_BASIC;
|
|
|
|
|
|
|
|
bibkeysInfo_.fillWithBibKeys(&buffer());
|
|
|
|
|
|
|
|
if (citeStyles_.empty())
|
|
|
|
citeStyles_ = biblio::getCiteStyles(engine);
|
|
|
|
else {
|
|
|
|
if ((use_styles && citeStyles_.size() == 1) ||
|
|
|
|
(!use_styles && citeStyles_.size() != 1))
|
|
|
|
citeStyles_ = biblio::getCiteStyles(engine);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiCitation::clearParams()
|
|
|
|
{
|
2007-10-07 14:59:01 +00:00
|
|
|
params_.clear();
|
2007-10-06 11:33:33 +00:00
|
|
|
bibkeysInfo_.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<docstring> const GuiCitation::availableKeys() const
|
|
|
|
{
|
|
|
|
return bibkeysInfo_.getKeys();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<docstring> const GuiCitation::availableFields() const
|
|
|
|
{
|
|
|
|
return bibkeysInfo_.getFields();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<docstring> const GuiCitation::availableEntries() const
|
|
|
|
{
|
|
|
|
return bibkeysInfo_.getEntries();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiCitation::filterByEntryType(
|
|
|
|
vector<docstring> & keyVector, docstring entryType)
|
|
|
|
{
|
|
|
|
if (entryType.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
vector<docstring>::iterator it = keyVector.begin();
|
|
|
|
vector<docstring>::iterator end = keyVector.end();
|
|
|
|
|
|
|
|
vector<docstring> result;
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
docstring const key = *it;
|
|
|
|
BiblioInfo::const_iterator cit = bibkeysInfo_.find(key);
|
|
|
|
if (cit == bibkeysInfo_.end())
|
|
|
|
continue;
|
|
|
|
if (cit->second.entryType == entryType)
|
|
|
|
result.push_back(key);
|
|
|
|
}
|
|
|
|
keyVector = result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
biblio::CiteEngine GuiCitation::getEngine() const
|
|
|
|
{
|
|
|
|
return buffer().params().getEngine();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring GuiCitation::getInfo(docstring const & key) const
|
|
|
|
{
|
|
|
|
if (bibkeysInfo_.empty())
|
|
|
|
return docstring();
|
|
|
|
|
|
|
|
return bibkeysInfo_.getInfo(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Escape special chars.
|
|
|
|
// All characters are literals except: '.|*?+(){}[]^$\'
|
|
|
|
// These characters are literals when preceded by a "\", which is done here
|
|
|
|
// @todo: This function should be moved to support, and then the test in tests
|
|
|
|
// should be moved there as well.
|
|
|
|
static docstring escape_special_chars(docstring const & expr)
|
|
|
|
{
|
|
|
|
// Search for all chars '.|*?+(){}[^$]\'
|
|
|
|
// Note that '[' and '\' must be escaped.
|
|
|
|
// This is a limitation of boost::regex, but all other chars in BREs
|
|
|
|
// are assumed literal.
|
|
|
|
static const boost::regex reg("[].|*?+(){}^$\\[\\\\]");
|
|
|
|
|
|
|
|
// $& is a perl-like expression that expands to all
|
|
|
|
// of the current match
|
|
|
|
// The '$' must be prefixed with the escape character '\' for
|
|
|
|
// boost to treat it as a literal.
|
|
|
|
// Thus, to prefix a matched expression with '\', we use:
|
|
|
|
// FIXME: UNICODE
|
|
|
|
return from_utf8(boost::regex_replace(to_utf8(expr), reg, "\\\\$&"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<docstring> GuiCitation::searchKeys(
|
|
|
|
vector<docstring> const & keys_to_search, bool only_keys,
|
|
|
|
docstring const & search_expression, docstring field,
|
|
|
|
bool case_sensitive, bool regex)
|
|
|
|
{
|
|
|
|
vector<docstring> foundKeys;
|
|
|
|
|
|
|
|
docstring expr = support::trim(search_expression);
|
|
|
|
if (expr.empty())
|
|
|
|
return foundKeys;
|
|
|
|
|
|
|
|
if (!regex)
|
|
|
|
// We must escape special chars in the search_expr so that
|
|
|
|
// it is treated as a simple string by boost::regex.
|
|
|
|
expr = escape_special_chars(expr);
|
|
|
|
|
|
|
|
boost::regex reg_exp(to_utf8(expr), case_sensitive ?
|
|
|
|
boost::regex_constants::normal : boost::regex_constants::icase);
|
|
|
|
|
|
|
|
vector<docstring>::const_iterator it = keys_to_search.begin();
|
|
|
|
vector<docstring>::const_iterator end = keys_to_search.end();
|
|
|
|
for (; it != end; ++it ) {
|
|
|
|
BiblioInfo::const_iterator info = bibkeysInfo_.find(*it);
|
|
|
|
if (info == bibkeysInfo_.end())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
BibTeXInfo const & kvm = info->second;
|
|
|
|
string data;
|
|
|
|
if (only_keys)
|
|
|
|
data = to_utf8(*it);
|
|
|
|
else if (field.empty())
|
|
|
|
data = to_utf8(*it) + ' ' + to_utf8(kvm.allData);
|
|
|
|
else if (kvm.hasField(field))
|
|
|
|
data = to_utf8(kvm.getValueForField(field));
|
|
|
|
|
|
|
|
if (data.empty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (boost::regex_search(data, reg_exp))
|
|
|
|
foundKeys.push_back(*it);
|
|
|
|
}
|
|
|
|
catch (boost::regex_error &) {
|
|
|
|
return vector<docstring>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return foundKeys;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-23 09:44:02 +00:00
|
|
|
Dialog * createGuiCitation(GuiView & lv) { return new GuiCitation(lv); }
|
2007-10-06 11:33:33 +00:00
|
|
|
|
|
|
|
|
2006-03-05 17:24:44 +00:00
|
|
|
} // namespace frontend
|
|
|
|
} // namespace lyx
|
2007-08-31 22:37:05 +00:00
|
|
|
|
|
|
|
#include "GuiCitation_moc.cpp"
|
|
|
|
|