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>
40 QCitationDialog::QCitationDialog(Dialog & dialog, QCitation * form)
41 : Dialog::View(dialog, _("Citation")), form_(form)
45 setWindowTitle(toqstr("LyX: " + getTitle()));
47 selectedLV->setModel(form_->selected());
48 availableLV->setModel(form_->available());
50 connect(citationStyleCO, SIGNAL(activated(int)),
51 this, SLOT(changed()));
52 connect(fulllistCB, SIGNAL(clicked()),
53 this, SLOT(changed()));
54 connect(forceuppercaseCB, SIGNAL(clicked()),
55 this, SLOT(changed()));
56 connect(textBeforeED, SIGNAL(textChanged(const QString&)),
57 this, SLOT(changed()));
58 connect(textAfterED, SIGNAL(textChanged(const QString&)),
59 this, SLOT(changed()));
60 connect(clearPB, SIGNAL(clicked()),
61 findLE, SLOT(clear()));
62 connect(availableLV->selectionModel(),
63 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
64 this, SLOT(availableChanged(const QModelIndex &, const QModelIndex &)));
65 connect(selectedLV->selectionModel(),
66 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
67 this, SLOT(selectedChanged(const QModelIndex &, const QModelIndex &)));
68 connect(this, SIGNAL(rejected()), this, SLOT(cleanUp()));
69 availableLV->installEventFilter(this);
70 selectedLV->installEventFilter(this);
74 QCitationDialog::~QCitationDialog()
79 bool QCitationDialog::eventFilter(QObject * obj, QEvent * event)
81 if (obj == availableLV) {
82 if (event->type() != QEvent::KeyPress)
83 return QObject::eventFilter(obj, event);
84 QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
85 int const keyPressed = keyEvent->key();
86 Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
87 //Enter key without modifier will add current item.
88 //Ctrl-Enter will add it and close the dialog.
89 //This is designed to work both with the main enter key
90 //and the one on the numeric keypad.
91 if ((keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) &&
92 //We want one or both of Control and Keypad, and nothing else
93 //(KeypadModifier is what you get if you use the Enter key on the
96 (keyModifiers == Qt::ControlModifier) ||
97 (keyModifiers == Qt::KeypadModifier) ||
98 (keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier))
101 if (addPB->isEnabled())
103 if (keyModifiers & Qt::ControlModifier)
108 } else if (obj == selectedLV) {
109 //Delete or backspace key will delete current item
110 //...with control modifier will clear the list
111 if (event->type() != QEvent::KeyPress)
112 return QObject::eventFilter(obj, event);
113 QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
114 int const keyPressed = keyEvent->key();
115 Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
116 if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) {
117 if (keyModifiers == Qt::NoModifier && deletePB->isEnabled())
118 on_deletePB_clicked();
119 else if (keyModifiers == Qt::ControlModifier) {
120 form_->clearSelection();
123 //ignore it otherwise
124 return QObject::eventFilter(obj, event);
129 return QObject::eventFilter(obj, event);
133 void QCitationDialog::cleanUp()
135 form_->clearSelection();
136 form_->clearParams();
141 void QCitationDialog::closeEvent(QCloseEvent * e)
143 form_->clearSelection();
144 form_->clearParams();
149 void QCitationDialog::apply()
151 int const choice = std::max(0, citationStyleCO->currentIndex());
153 bool const full = fulllistCB->isChecked();
154 bool const force = forceuppercaseCB->isChecked();
156 QString const before = textBeforeED->text();
157 QString const after = textAfterED->text();
159 form_->apply(choice, full, force, before, after);
163 void QCitationDialog::hide()
165 form_->clearParams();
170 void QCitationDialog::show()
173 availableLV->setFocus();
180 bool QCitationDialog::isVisible() const
182 return QDialog::isVisible();
186 void QCitationDialog::on_okPB_clicked()
189 form_->clearSelection();
194 void QCitationDialog::on_cancelPB_clicked()
196 form_->clearSelection();
201 void QCitationDialog::on_applyPB_clicked()
207 void QCitationDialog::on_restorePB_clicked()
214 void QCitationDialog::update()
216 if (selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
217 if (availableLV->selectionModel()->selectedIndexes().isEmpty()
218 && availableLV->model()->rowCount() > 0)
219 availableLV->setCurrentIndex(availableLV->model()->index(0,0));
220 updateInfo(availableLV->currentIndex());
222 updateInfo(selectedLV->currentIndex());
226 textBeforeED->setText(form_->textBefore());
227 textAfterED->setText(form_->textAfter());
234 void QCitationDialog::updateStyle()
236 biblio::CiteEngine const engine = form_->getEngine();
237 bool const natbib_engine =
238 engine == biblio::ENGINE_NATBIB_AUTHORYEAR ||
239 engine == biblio::ENGINE_NATBIB_NUMERICAL;
240 bool const basic_engine = engine == biblio::ENGINE_BASIC;
242 fulllistCB->setEnabled(natbib_engine);
243 forceuppercaseCB->setEnabled(natbib_engine);
244 textBeforeED->setEnabled(!basic_engine);
245 textBeforeLA->setEnabled(!basic_engine);
247 string const & command = form_->params().getCmdName();
249 // Find the style of the citekeys
250 vector<biblio::CiteStyle> const & styles =
251 ControlCitation::getCiteStyles();
252 biblio::CitationStyle const cs(command);
254 vector<biblio::CiteStyle>::const_iterator cit =
255 std::find(styles.begin(), styles.end(), cs.style);
257 // restore the latest natbib style
258 if (style_ >= 0 && style_ < citationStyleCO->count())
259 citationStyleCO->setCurrentIndex(style_);
261 citationStyleCO->setCurrentIndex(0);
263 fulllistCB->setChecked(false);
264 forceuppercaseCB->setChecked(false);
266 if (cit != styles.end()) {
267 int const i = int(cit - styles.begin());
268 citationStyleCO->setCurrentIndex(i);
269 fulllistCB->setChecked(cs.full);
270 forceuppercaseCB->setChecked(cs.forceUCase);
275 void QCitationDialog::fillStyles()
277 int const orig = citationStyleCO->currentIndex();
279 citationStyleCO->clear();
281 QStringList selected_keys = form_->selected()->stringList();
282 if (selected_keys.empty()) {
283 citationStyleCO->setEnabled(false);
284 citationStyleLA->setEnabled(false);
288 int curr = selectedLV->model()->rowCount() - 1;
292 if (!selectedLV->selectionModel()->selectedIndexes().empty())
293 curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
295 QStringList sty = form_->citationStyles(curr);
297 bool const basic_engine =
298 (form_->getEngine() == biblio::ENGINE_BASIC);
300 citationStyleCO->setEnabled(!sty.isEmpty() && !basic_engine);
301 citationStyleLA->setEnabled(!sty.isEmpty() && !basic_engine);
303 if (sty.isEmpty() || basic_engine)
306 citationStyleCO->insertItems(0, sty);
308 if (orig != -1 && orig < citationStyleCO->count())
309 citationStyleCO->setCurrentIndex(orig);
313 bool QCitationDialog::isSelected(const QModelIndex & idx)
315 QString const str = idx.data().toString();
316 return form_->selected()->stringList().contains(str);
320 void QCitationDialog::setButtons()
322 int const arows = availableLV->model()->rowCount();
323 QModelIndexList const availSels =
324 availableLV->selectionModel()->selectedIndexes();
325 addPB->setEnabled(arows > 0 &&
326 !availSels.isEmpty() &&
327 !isSelected(availSels.first()));
329 int const srows = selectedLV->model()->rowCount();
330 QModelIndexList const selSels =
331 selectedLV->selectionModel()->selectedIndexes();
332 int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
333 deletePB->setEnabled(sel_nr >= 0);
334 upPB->setEnabled(sel_nr > 0);
335 downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
339 void QCitationDialog::updateInfo(const QModelIndex & idx)
342 QString const keytxt = form_->getKeyInfo(idx.data().toString());
343 infoML->document()->setPlainText(keytxt);
345 infoML->document()->clear();
349 void QCitationDialog::on_selectedLV_clicked(const QModelIndex &)
355 void QCitationDialog::selectedChanged(const QModelIndex & idx, const QModelIndex &)
363 void QCitationDialog::on_availableLV_clicked(const QModelIndex &)
369 void QCitationDialog::availableChanged(const QModelIndex & idx, const QModelIndex &)
377 void QCitationDialog::on_availableLV_doubleClicked(const QModelIndex & idx)
386 //helper function for next two
387 QModelIndex getSelectedIndex(QListView * lv) {
388 //Encourage compiler to use NRVO
389 QModelIndex retval = QModelIndex();
390 QModelIndexList selIdx =
391 lv->selectionModel()->selectedIndexes();
393 retval = selIdx.first();
396 }//anonymous namespace
399 void QCitationDialog::on_addPB_clicked()
401 QModelIndex const idxToAdd = getSelectedIndex(availableLV);
402 if (!idxToAdd.isValid())
404 QModelIndex idx = selectedLV->currentIndex();
405 form_->addKey(idxToAdd);
407 selectedLV->setCurrentIndex(idx);
412 void QCitationDialog::on_deletePB_clicked()
414 QModelIndex idx = getSelectedIndex(selectedLV);
417 int nrows = selectedLV->model()->rowCount();
419 form_->deleteKey(idx);
421 if (idx.row() == nrows - 1)
422 idx = idx.sibling(idx.row() - 1, idx.column());
425 selectedLV->setCurrentIndex(idx);
431 void QCitationDialog::on_upPB_clicked()
433 QModelIndex idx = selectedLV->currentIndex();
435 selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
436 availableLV->selectionModel()->reset();
441 void QCitationDialog::on_downPB_clicked()
443 QModelIndex idx = selectedLV->currentIndex();
445 selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
446 availableLV->selectionModel()->reset();
451 void QCitationDialog::findText(QString const & text)
453 bool const case_sentitive = caseCB->checkState();
454 bool const reg_exp = regexCB->checkState();
455 form_->findKey(text, false, case_sentitive, reg_exp);
456 selectedLV->selectionModel()->reset();
461 void QCitationDialog::on_findLE_textChanged(const QString & text)
463 clearPB->setDisabled(text.isEmpty());
470 void QCitationDialog::on_caseCB_stateChanged(int)
472 findText(findLE->text());
476 void QCitationDialog::on_regexCB_stateChanged(int)
478 findText(findLE->text());
482 void QCitationDialog::changed()
489 } // namespace frontend
492 #include "QCitationDialog_moc.cpp"