]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QCitationDialog.C
70a245e6de9cc72deb3a96e3ccab6659062e828d
[lyx.git] / src / frontends / qt2 / 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 "ui/QCitationFindDialogBase.h"
17 #include "QCitation.h"
18 #include "qt_helpers.h"
19
20 #include "controllers/ControlCitation.h"
21 #include "controllers/ButtonController.h"
22
23 #include <qcheckbox.h>
24 #include <qlineedit.h>
25 #include <qlistbox.h>
26 #include <qmultilineedit.h>
27 #include <qpushbutton.h>
28
29
30 using std::vector;
31 using std::string;
32 using std::swap;
33
34 namespace lyx {
35 namespace frontend {
36
37 QCitationDialog::QCitationDialog(QCitation * form)
38         : QCitationDialogBase(0, 0, false, 0),
39         form_(form)
40 {
41         connect(restorePB, SIGNAL(clicked()),
42                 form, SLOT(slotRestore()));
43         connect(okPB, SIGNAL(clicked()),
44                 form, SLOT(slotOK()));
45         connect(applyPB, SIGNAL(clicked()),
46                 form, SLOT(slotApply()));
47         connect(closePB, SIGNAL(clicked()),
48                 form, SLOT(slotClose()));
49
50         add_ = new QCitationFindDialogBase(this, "", true);
51         connect(add_->previousPB, SIGNAL(clicked()), this, SLOT(previous()));
52         connect(add_->nextPB, SIGNAL(clicked()), this, SLOT(next()));
53         connect(add_->availableLB, SIGNAL(currentChanged(QListBoxItem *)), this, SLOT(availableChanged()));
54         connect(add_->availableLB, SIGNAL(selected(QListBoxItem *)), this, SLOT(addCitation()));
55         connect(add_->availableLB, SIGNAL(selected(QListBoxItem *)), add_, SLOT(accept()));
56         connect(add_->addPB, SIGNAL(clicked()), this, SLOT(addCitation()));
57         connect(selectedLB, SIGNAL(returnPressed(QListBoxItem *)), form, SLOT(slotOK()));
58 }
59
60
61 QCitationDialog::~QCitationDialog()
62 {
63 }
64
65
66 void QCitationDialog::setButtons()
67 {
68         if (form_->readOnly())
69                 return;
70
71         int const sel_nr = selectedLB->currentItem();
72         int const avail_nr = add_->availableLB->currentItem();
73
74         add_->addPB->setEnabled(avail_nr >= 0);
75         deletePB->setEnabled(sel_nr >= 0);
76         upPB->setEnabled(sel_nr > 0);
77         downPB->setEnabled(sel_nr >= 0 && sel_nr < int(selectedLB->count() - 1));
78 }
79
80
81 void QCitationDialog::openFind()
82 {
83         if (form_->readOnly())
84                 return;
85
86         if (isVisible() && selectedLB->count() == 0 
87             && add_->availableLB->count() != 0){
88                 // open the find dialog
89                 add();
90                 // and let the user press ok after a selection
91                 if (selectedLB->count() != 0)
92                         form_->bc().valid();
93         }
94 }
95
96
97 void QCitationDialog::selectedChanged()
98 {
99         form_->fillStyles();
100         biblio::InfoMap const & theMap = form_->controller().bibkeysInfo();
101         infoML->clear();
102
103         int const sel = selectedLB->currentItem();
104         if (sel < 0) {
105                 setButtons();
106                 return;
107         }
108
109         if (!theMap.empty())
110                 infoML->setText(
111                         toqstr(biblio::getInfo(theMap, form_->citekeys[sel])));
112         setButtons();
113 }
114
115
116 void QCitationDialog::previous()
117 {
118         find(biblio::BACKWARD);
119 }
120
121
122 void QCitationDialog::next()
123 {
124         find(biblio::FORWARD);
125 }
126
127
128 void QCitationDialog::availableChanged()
129 {
130         biblio::InfoMap const & theMap = form_->controller().bibkeysInfo();
131         add_->infoML->clear();
132
133         int const sel = add_->availableLB->currentItem();
134         if (sel < 0) {
135                 setButtons();
136                 return;
137         }
138
139         if (!theMap.empty())
140                 add_->infoML->setText(
141                         toqstr(biblio::getInfo(theMap, form_->bibkeys[sel])));
142         setButtons();
143 }
144
145
146 void QCitationDialog::addCitation()
147 {
148         int const sel = add_->availableLB->currentItem();
149
150         if (sel < 0)
151                 return;
152
153         // Add the selected browser_bib keys to browser_cite
154         // multiple selections are possible
155         for (unsigned int i = 0; i != add_->availableLB->count(); i++) {
156                 if (add_->availableLB->isSelected(i)) {
157                         // do not allow duplicates
158                         if ((selectedLB->findItem(add_->availableLB->text(i))) == 0) {
159                                 selectedLB->insertItem(toqstr(form_->bibkeys[i]));
160                                 form_->citekeys.push_back(form_->bibkeys[i]);
161                         }
162                 }
163         }
164
165         int const n = int(form_->citekeys.size());
166         selectedLB->setSelected(n - 1, true);
167
168         form_->changed();
169         form_->fillStyles();
170         setButtons();
171 }
172
173
174 void QCitationDialog::del()
175 {
176         int const sel = selectedLB->currentItem();
177
178         // Remove the selected key from browser_cite
179         selectedLB->removeItem(sel);
180         form_->citekeys.erase(form_->citekeys.begin() + sel);
181
182         form_->changed();
183         form_->fillStyles();
184         setButtons();
185 }
186
187
188 void QCitationDialog::up()
189 {
190         int const sel = selectedLB->currentItem();
191
192         BOOST_ASSERT(sel > 0);
193
194         // Move the selected key up one line
195         string const tmp = form_->citekeys[sel];
196
197         selectedLB->removeItem(sel);
198         swap(form_->citekeys[sel - 1], form_->citekeys[sel]);
199
200         selectedLB->insertItem(toqstr(tmp), sel - 1);
201         selectedLB->setSelected(sel - 1, true);
202
203         form_->changed();
204         form_->fillStyles();
205         setButtons();
206 }
207
208
209 void QCitationDialog::down()
210 {
211         int const sel = selectedLB->currentItem();
212
213         BOOST_ASSERT(sel < (int)form_->citekeys.size());
214
215         // Move the selected key down one line
216         string const tmp = form_->citekeys[sel];
217
218         selectedLB->removeItem(sel);
219         swap(form_->citekeys[sel + 1], form_->citekeys[sel]);
220
221         selectedLB->insertItem(toqstr(tmp), sel + 1);
222         selectedLB->setSelected(sel + 1, true);
223
224         form_->changed();
225         form_->fillStyles();
226         setButtons();
227 }
228
229
230 void QCitationDialog::add()
231 {
232         add_->exec();
233 }
234
235
236 void QCitationDialog::changed_adaptor()
237 {
238         form_->changed();
239 }
240
241
242 void QCitationDialog::find(biblio::Direction dir)
243 {
244         biblio::InfoMap const & theMap = form_->controller().bibkeysInfo();
245
246         biblio::Search const type = add_->searchTypeCB->isChecked()
247                 ? biblio::REGEX : biblio::SIMPLE;
248
249         vector<string>::const_iterator start = form_->bibkeys.begin();
250         int const sel = add_->availableLB->currentItem();
251         if (sel >= 0 && sel <= int(form_->bibkeys.size()-1))
252                 start += sel;
253
254         // Find the NEXT instance...
255         if (dir == biblio::FORWARD)
256                 start += 1;
257
258         bool const casesens = add_->searchCaseCB->isChecked();
259         string const str = fromqstr(add_->searchED->text());
260
261         vector<string>::const_iterator cit =
262                 biblio::searchKeys(theMap, form_->bibkeys, str,
263                                    start, type, dir, casesens);
264
265         // not found. let's loop round
266         if (cit == form_->bibkeys.end()) {
267                 if (dir == biblio::FORWARD) {
268                         start = form_->bibkeys.begin();
269                 }
270                 else start = form_->bibkeys.end() - 1;
271
272                 cit = biblio::searchKeys(theMap, form_->bibkeys, str,
273                                          start, type, dir, casesens);
274
275                 if (cit == form_->bibkeys.end())
276                         return;
277         }
278
279         int const found = int(cit - form_->bibkeys.begin());
280         if (found == sel) {
281                 return;
282         }
283
284         // Update the display
285         // note that we have multi selection mode!
286         add_->availableLB->setSelected(sel, false);
287         add_->availableLB->setSelected(found, true);
288         add_->availableLB->setCurrentItem(found);
289         add_->availableLB->ensureCurrentVisible();
290 }
291
292 } // namespace frontend
293 } // namespace lyx