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