2 * \file QCitationDialog.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Kalle Dalheimer
8 * \author Jürgen Spitzmüller
9 * \author Abdelrazak Younes
11 * Full author contact details are available in file CREDITS.
16 #include "QCitationDialog.h"
18 #include "QCitation.h"
20 #include "frontends/controllers/frontend_helpers.h"
21 #include "frontends/controllers/ControlCitation.h"
30 #include <QCloseEvent>
42 QCitationDialog::QCitationDialog(Dialog & dialog, QCitation * form)
43 : Dialog::View(dialog, _("Citation")), form_(form)
47 setWindowTitle(toqstr("LyX: " + getTitle()));
49 selectedLV->setModel(form_->selected());
50 availableLV->setModel(form_->available());
52 connect(citationStyleCO, SIGNAL(activated(int)),
53 this, SLOT(changed()));
54 connect(fulllistCB, SIGNAL(clicked()),
55 this, SLOT(changed()));
56 connect(forceuppercaseCB, SIGNAL(clicked()),
57 this, SLOT(changed()));
58 connect(textBeforeED, SIGNAL(textChanged(const QString&)),
59 this, SLOT(changed()));
60 connect(textAfterED, SIGNAL(textChanged(const QString&)),
61 this, SLOT(changed()));
62 connect(clearPB, SIGNAL(clicked()),
63 findLE, SLOT(clear()));
64 connect(availableLV->selectionModel(),
65 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
66 this, SLOT(availableChanged(const QModelIndex &, const QModelIndex &)));
67 connect(selectedLV->selectionModel(),
68 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
69 this, SLOT(selectedChanged(const QModelIndex &, const QModelIndex &)));
70 connect(this, SIGNAL(rejected()), this, SLOT(cleanUp()));
71 availableLV->installEventFilter(this);
72 selectedLV->installEventFilter(this);
76 QCitationDialog::~QCitationDialog()
81 bool QCitationDialog::eventFilter(QObject * obj, QEvent * event)
83 if (obj == availableLV) {
84 if (event->type() != QEvent::KeyPress)
85 return QObject::eventFilter(obj, event);
86 QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
87 int const keyPressed = keyEvent->key();
88 Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
89 //Enter key without modifier will add current item.
90 //Ctrl-Enter will add it and close the dialog.
91 //This is designed to work both with the main enter key
92 //and the one on the numeric keypad.
93 if ((keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) &&
94 //We want one or both of Control and Keypad, and nothing else
95 //(KeypadModifier is what you get if you use the Enter key on the
98 (keyModifiers == Qt::ControlModifier) ||
99 (keyModifiers == Qt::KeypadModifier) ||
100 (keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier))
103 if (addPB->isEnabled())
105 if (keyModifiers & Qt::ControlModifier)
110 } else if (obj == selectedLV) {
111 //Delete or backspace key will delete current item
112 //...with control modifier will clear the list
113 if (event->type() != QEvent::KeyPress)
114 return QObject::eventFilter(obj, event);
115 QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
116 int const keyPressed = keyEvent->key();
117 Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
118 if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) {
119 if (keyModifiers == Qt::NoModifier && deletePB->isEnabled())
120 on_deletePB_clicked();
121 else if (keyModifiers == Qt::ControlModifier) {
122 form_->clearSelection();
125 //ignore it otherwise
126 return QObject::eventFilter(obj, event);
131 return QObject::eventFilter(obj, event);
135 void QCitationDialog::cleanUp()
137 form_->clearSelection();
138 form_->clearParams();
143 void QCitationDialog::closeEvent(QCloseEvent * e)
145 form_->clearSelection();
146 form_->clearParams();
151 void QCitationDialog::apply()
153 int const choice = std::max(0, citationStyleCO->currentIndex());
155 bool const full = fulllistCB->isChecked();
156 bool const force = forceuppercaseCB->isChecked();
158 QString const before = textBeforeED->text();
159 QString const after = textAfterED->text();
161 form_->apply(choice, full, force, before, after);
165 void QCitationDialog::hide()
167 form_->clearParams();
172 void QCitationDialog::show()
175 availableLV->setFocus();
182 bool QCitationDialog::isVisible() const
184 return QDialog::isVisible();
188 void QCitationDialog::on_okPB_clicked()
191 form_->clearSelection();
196 void QCitationDialog::on_cancelPB_clicked()
198 form_->clearSelection();
203 void QCitationDialog::on_applyPB_clicked()
209 void QCitationDialog::on_restorePB_clicked()
216 void QCitationDialog::update()
218 if (selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
219 if (availableLV->selectionModel()->selectedIndexes().isEmpty()
220 && availableLV->model()->rowCount() > 0)
221 availableLV->setCurrentIndex(availableLV->model()->index(0,0));
222 updateInfo(availableLV->currentIndex());
224 updateInfo(selectedLV->currentIndex());
228 textBeforeED->setText(form_->textBefore());
229 textAfterED->setText(form_->textAfter());
236 void QCitationDialog::updateStyle()
238 biblio::CiteEngine const engine = form_->getEngine();
239 bool const natbib_engine =
240 engine == biblio::ENGINE_NATBIB_AUTHORYEAR ||
241 engine == biblio::ENGINE_NATBIB_NUMERICAL;
242 bool const basic_engine = engine == biblio::ENGINE_BASIC;
244 fulllistCB->setEnabled(natbib_engine);
245 forceuppercaseCB->setEnabled(natbib_engine);
246 textBeforeED->setEnabled(!basic_engine);
247 textBeforeLA->setEnabled(!basic_engine);
249 string const & command = form_->params().getCmdName();
251 // Find the style of the citekeys
252 vector<biblio::CiteStyle> const & styles =
253 ControlCitation::getCiteStyles();
254 biblio::CitationStyle const cs(command);
256 vector<biblio::CiteStyle>::const_iterator cit =
257 std::find(styles.begin(), styles.end(), cs.style);
259 // restore the latest natbib style
260 if (style_ >= 0 && style_ < citationStyleCO->count())
261 citationStyleCO->setCurrentIndex(style_);
263 citationStyleCO->setCurrentIndex(0);
265 fulllistCB->setChecked(false);
266 forceuppercaseCB->setChecked(false);
268 if (cit != styles.end()) {
269 int const i = int(cit - styles.begin());
270 citationStyleCO->setCurrentIndex(i);
271 fulllistCB->setChecked(cs.full);
272 forceuppercaseCB->setChecked(cs.forceUCase);
277 void QCitationDialog::fillStyles()
279 int const orig = citationStyleCO->currentIndex();
281 citationStyleCO->clear();
283 QStringList selected_keys = form_->selected()->stringList();
284 if (selected_keys.empty()) {
285 citationStyleCO->setEnabled(false);
286 citationStyleLA->setEnabled(false);
290 int curr = selectedLV->model()->rowCount() - 1;
294 if (!selectedLV->selectionModel()->selectedIndexes().empty())
295 curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
297 QStringList sty = form_->citationStyles(curr);
299 bool const basic_engine =
300 (form_->getEngine() == biblio::ENGINE_BASIC);
302 citationStyleCO->setEnabled(!sty.isEmpty() && !basic_engine);
303 citationStyleLA->setEnabled(!sty.isEmpty() && !basic_engine);
305 if (sty.isEmpty() || basic_engine)
308 citationStyleCO->insertItems(0, sty);
310 if (orig != -1 && orig < citationStyleCO->count())
311 citationStyleCO->setCurrentIndex(orig);
315 bool QCitationDialog::isSelected(const QModelIndex & idx)
317 QString const str = idx.data().toString();
318 return form_->selected()->stringList().contains(str);
322 void QCitationDialog::setButtons()
324 int const arows = availableLV->model()->rowCount();
325 QModelIndexList const availSels =
326 availableLV->selectionModel()->selectedIndexes();
327 addPB->setEnabled(arows > 0 &&
328 !availSels.isEmpty() &&
329 !isSelected(availSels.first()));
331 int const srows = selectedLV->model()->rowCount();
332 QModelIndexList const selSels =
333 selectedLV->selectionModel()->selectedIndexes();
334 int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
335 deletePB->setEnabled(sel_nr >= 0);
336 upPB->setEnabled(sel_nr > 0);
337 downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
341 void QCitationDialog::updateInfo(const QModelIndex & idx)
344 QString const keytxt = form_->getKeyInfo(idx.data().toString());
345 infoML->document()->setPlainText(keytxt);
347 infoML->document()->clear();
351 void QCitationDialog::on_selectedLV_clicked(const QModelIndex &)
357 void QCitationDialog::selectedChanged(const QModelIndex & idx, const QModelIndex &)
365 void QCitationDialog::on_availableLV_clicked(const QModelIndex &)
371 void QCitationDialog::availableChanged(const QModelIndex & idx, const QModelIndex &)
379 void QCitationDialog::on_availableLV_doubleClicked(const QModelIndex & idx)
388 //helper function for next two
389 QModelIndex getSelectedIndex(QListView * lv) {
390 //Encourage compiler to use NRVO
391 QModelIndex retval = QModelIndex();
392 QModelIndexList selIdx =
393 lv->selectionModel()->selectedIndexes();
395 retval = selIdx.first();
398 }//anonymous namespace
401 void QCitationDialog::on_addPB_clicked()
403 QModelIndex const idxToAdd = getSelectedIndex(availableLV);
404 if (!idxToAdd.isValid())
406 QModelIndex idx = selectedLV->currentIndex();
407 form_->addKey(idxToAdd);
409 selectedLV->setCurrentIndex(idx);
414 void QCitationDialog::on_deletePB_clicked()
416 QModelIndex idx = getSelectedIndex(selectedLV);
419 int nrows = selectedLV->model()->rowCount();
421 form_->deleteKey(idx);
423 if (idx.row() == nrows - 1)
424 idx = idx.sibling(idx.row() - 1, idx.column());
427 selectedLV->setCurrentIndex(idx);
433 void QCitationDialog::on_upPB_clicked()
435 QModelIndex idx = selectedLV->currentIndex();
437 selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
438 availableLV->selectionModel()->reset();
443 void QCitationDialog::on_downPB_clicked()
445 QModelIndex idx = selectedLV->currentIndex();
447 selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
448 availableLV->selectionModel()->reset();
453 void QCitationDialog::findText(QString const & text)
455 bool const case_sentitive = caseCB->checkState();
456 bool const reg_exp = regexCB->checkState();
457 form_->findKey(text, false, case_sentitive, reg_exp);
458 selectedLV->selectionModel()->reset();
463 void QCitationDialog::on_findLE_textChanged(const QString & text)
465 clearPB->setDisabled(text.isEmpty());
472 void QCitationDialog::on_caseCB_stateChanged(int)
474 findText(findLE->text());
478 void QCitationDialog::on_regexCB_stateChanged(int)
480 findText(findLE->text());
484 void QCitationDialog::changed()
491 } // namespace frontend
494 #include "QCitationDialog_moc.cpp"