]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QCitationDialog.cpp
revert r17737; it was designed to fix bug 2993, but it created bug 3503. Consequently...
[lyx.git] / src / frontends / qt4 / QCitationDialog.cpp
1 /**
2  * \file QCitationDialog.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Kalle Dalheimer
7  * \author John Levon
8  * \author Jürgen Spitzmüller
9  * \author Abdelrazak Younes
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "QCitationDialog.h"
17
18 #include "QCitation.h"
19
20 #include "frontends/controllers/frontend_helpers.h"
21 #include "frontends/controllers/ControlCitation.h"
22
23 #include "debug.h"
24 #include "gettext.h"
25
26 #include <algorithm>
27 #include <vector>
28 #include <string>
29
30 #include <QCloseEvent>
31 #include <QKeyEvent>
32
33 using std::vector;
34 using std::string;
35
36 namespace lyx {
37 namespace frontend {
38
39
40 QCitationDialog::QCitationDialog(Dialog & dialog, QCitation * form)
41         : Dialog::View(dialog, _("Citation")), form_(form)
42 {
43         setupUi(this);
44
45         setWindowTitle(toqstr("LyX: " + getTitle()));
46
47         selectedLV->setModel(form_->selected());
48         availableLV->setModel(form_->available());
49
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 }
69
70
71 QCitationDialog::~QCitationDialog()
72 {
73 }
74
75
76 void QCitationDialog::keyPressEvent(QKeyEvent * event)
77 {
78         if (event->key() == Qt::Key_Escape) {
79                 form_->clearSelection();
80                 form_->clearParams();
81                 event->accept();
82                 close();
83         } else
84                 event->ignore();
85 }
86
87
88 void QCitationDialog::closeEvent(QCloseEvent * e)
89 {
90         form_->clearSelection();
91         form_->clearParams();
92         e->accept();
93 }
94
95
96 void QCitationDialog::apply()
97 {
98         int  const choice = std::max(0, citationStyleCO->currentIndex());
99         style_ = choice;
100         bool const full  = fulllistCB->isChecked();
101         bool const force = forceuppercaseCB->isChecked();
102
103         QString const before = textBeforeED->text();
104         QString const after = textAfterED->text();
105
106         form_->apply(choice, full, force, before, after);
107 }
108
109
110 void QCitationDialog::hide()
111 {
112         form_->clearParams();
113         accept();
114 }
115
116
117 void QCitationDialog::show()
118 {
119         findLE->clear();
120         availableLV->setFocus();
121         QDialog::show();
122 }
123
124
125 bool QCitationDialog::isVisible() const
126 {
127         return QDialog::isVisible();
128 }
129  
130
131 void QCitationDialog::on_okPB_clicked()
132 {
133         apply();
134         form_->clearSelection();
135         hide();
136 }
137
138
139 void QCitationDialog::on_cancelPB_clicked()
140 {
141         form_->clearSelection();
142         hide();
143 }
144
145
146 void QCitationDialog::on_applyPB_clicked()
147 {
148         apply();
149 }
150
151
152 void QCitationDialog::on_restorePB_clicked()
153 {
154         form_->init();
155         update();
156 }
157
158
159 void QCitationDialog::update()
160 {
161         if (selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
162                 if (availableLV->selectionModel()->selectedIndexes().isEmpty() 
163                         && availableLV->model()->rowCount() > 0)
164                                 availableLV->setCurrentIndex(availableLV->model()->index(0,0));
165                 updateInfo(availableLV->currentIndex());
166         } else
167                 updateInfo(selectedLV->currentIndex());
168
169         setButtons();
170
171         textBeforeED->setText(form_->textBefore());
172         textAfterED->setText(form_->textAfter());
173
174         fillStyles();
175         updateStyle();
176 }
177
178
179 void QCitationDialog::updateStyle()
180 {
181         biblio::CiteEngine const engine = form_->getEngine();
182         bool const natbib_engine =
183                 engine == biblio::ENGINE_NATBIB_AUTHORYEAR ||
184                 engine == biblio::ENGINE_NATBIB_NUMERICAL;
185         bool const basic_engine = engine == biblio::ENGINE_BASIC;
186
187         fulllistCB->setEnabled(natbib_engine);
188         forceuppercaseCB->setEnabled(natbib_engine);
189         textBeforeED->setEnabled(!basic_engine);
190         textBeforeLA->setEnabled(!basic_engine);
191
192         string const & command = form_->params().getCmdName();
193
194         // Find the style of the citekeys
195         vector<biblio::CiteStyle> const & styles =
196                 ControlCitation::getCiteStyles();
197         biblio::CitationStyle const cs(command);
198
199         vector<biblio::CiteStyle>::const_iterator cit =
200                 std::find(styles.begin(), styles.end(), cs.style);
201
202         // restore the latest natbib style
203         if (style_ >= 0 && style_ < citationStyleCO->count())
204                 citationStyleCO->setCurrentIndex(style_);
205         else
206                 citationStyleCO->setCurrentIndex(0);
207
208         fulllistCB->setChecked(false);
209         forceuppercaseCB->setChecked(false);
210
211         if (cit != styles.end()) {
212                 int const i = int(cit - styles.begin());
213                 citationStyleCO->setCurrentIndex(i);
214                 fulllistCB->setChecked(cs.full);
215                 forceuppercaseCB->setChecked(cs.forceUCase);
216         }
217 }
218
219
220 void QCitationDialog::fillStyles()
221 {
222         int const orig = citationStyleCO->currentIndex();
223
224         citationStyleCO->clear();
225
226         QStringList selected_keys = form_->selected()->stringList();
227         if (selected_keys.empty()) {
228                 citationStyleCO->setEnabled(false);
229                 citationStyleLA->setEnabled(false);
230                 return;
231         }
232
233         int curr = selectedLV->model()->rowCount() - 1;
234         if (curr < 0)
235                 return;
236
237         if (!selectedLV->selectionModel()->selectedIndexes().empty())
238                 curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
239
240         QStringList sty = form_->citationStyles(curr);
241
242         bool const basic_engine = 
243                 (form_->getEngine() == biblio::ENGINE_BASIC);
244
245         citationStyleCO->setEnabled(!sty.isEmpty() && !basic_engine);
246         citationStyleLA->setEnabled(!sty.isEmpty() && !basic_engine);
247
248         if (sty.isEmpty() || basic_engine)
249                 return;
250
251         citationStyleCO->insertItems(0, sty);
252
253         if (orig != -1 && orig < citationStyleCO->count())
254                 citationStyleCO->setCurrentIndex(orig);
255 }
256
257
258 bool QCitationDialog::isSelected(const QModelIndex & idx)
259 {
260         QString const str = idx.data().toString();
261         return !form_->selected()->stringList().filter(str).isEmpty();
262 }
263
264
265 void QCitationDialog::setButtons()
266 {
267         int const arows = availableLV->model()->rowCount();
268         addPB->setEnabled(arows>0 && !isSelected(availableLV->currentIndex()));
269
270         int const srows = selectedLV->model()->rowCount();
271         int const sel_nr = selectedLV->currentIndex().row();
272         deletePB->setEnabled(sel_nr >= 0);
273         upPB->setEnabled(sel_nr > 0);
274         downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
275         applyPB->setEnabled(srows>0);
276         okPB->setEnabled(srows>0);
277 }
278
279
280 void QCitationDialog::updateInfo(const QModelIndex & idx)
281 {
282         if (idx.isValid()) {
283                 QString const keytxt = form_->getKeyInfo(idx.data().toString());
284                 infoML->document()->setPlainText(keytxt);
285         } else
286                 infoML->document()->clear();
287 }
288
289
290 void QCitationDialog::on_selectedLV_clicked(const QModelIndex &)
291 {
292         availableLV->selectionModel()->reset();
293         update();
294 }
295
296
297 void QCitationDialog::selectedChanged(const QModelIndex & idx, const QModelIndex &)
298 {
299         if (!idx.isValid())
300                 return;
301
302         availableLV->selectionModel()->reset();
303         update();
304 }
305
306
307 void QCitationDialog::on_availableLV_clicked(const QModelIndex &)
308 {
309         selectedLV->selectionModel()->reset();
310         update();
311 }
312
313
314 void QCitationDialog::availableChanged(const QModelIndex & idx, const QModelIndex &)
315 {
316         if (!idx.isValid())
317                 return;
318                 
319         selectedLV->selectionModel()->reset();
320         update();
321 }
322
323
324 void QCitationDialog::on_availableLV_activated(const QModelIndex & idx)
325 {
326         if (isSelected(idx))
327                 return;
328
329         selectedLV->selectionModel()->reset();
330         on_addPB_clicked();
331         if (selectedLV->model()->rowCount() == 1)
332                 on_okPB_clicked();
333 }
334
335
336 void QCitationDialog::on_availableLV_entered(const QModelIndex &)
337 {
338 }
339
340
341 void QCitationDialog::on_addPB_clicked()
342 {
343         QModelIndex idx = selectedLV->currentIndex();
344         form_->addKey(availableLV->currentIndex());
345         if (idx.isValid())
346                 selectedLV->setCurrentIndex(idx);
347         selectedLV->selectionModel()->reset();
348         update();
349 }
350
351
352 void QCitationDialog::on_deletePB_clicked()
353 {
354         QModelIndex idx = selectedLV->currentIndex();
355         int nrows = selectedLV->model()->rowCount();
356         
357         form_->deleteKey(idx);
358
359         if (idx.row() == nrows - 1)     
360                 idx = idx.sibling(idx.row() - 1, idx.column());
361
362         if (nrows>1)
363                 selectedLV->setCurrentIndex(idx);
364
365         availableLV->selectionModel()->reset();
366         update();
367 }
368
369
370 void QCitationDialog::on_upPB_clicked()
371 {
372         QModelIndex idx = selectedLV->currentIndex();
373         form_->upKey(idx);
374         selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
375         availableLV->selectionModel()->reset();
376         update();
377 }
378
379
380 void QCitationDialog::on_downPB_clicked()
381 {
382         QModelIndex idx = selectedLV->currentIndex();
383         form_->downKey(idx);
384         selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
385         availableLV->selectionModel()->reset();
386         update();
387 }
388
389
390 void QCitationDialog::findText(QString const & text)
391 {
392         bool const case_sentitive = caseCB->checkState();
393         bool const reg_exp = regexCB->checkState();
394         form_->findKey(text, false, case_sentitive, reg_exp);
395         selectedLV->selectionModel()->reset();
396         update();
397 }
398
399
400 void QCitationDialog::on_findLE_textChanged(const QString & text)
401 {
402         clearPB->setDisabled(text.isEmpty());
403         if (text.isEmpty())
404                 findLE->setFocus();
405         findText(text);
406 }
407
408
409 void QCitationDialog::on_caseCB_stateChanged(int)
410 {
411         findText(findLE->text());
412 }
413
414
415 void QCitationDialog::on_regexCB_stateChanged(int)
416 {
417         findText(findLE->text());
418 }
419
420
421 void QCitationDialog::changed()
422 {
423         fillStyles();
424         setButtons();
425 }
426
427
428 } // namespace frontend
429 } // namespace lyx
430
431 #include "QCitationDialog_moc.cpp"