]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiRef.cpp
74e01fd60c3f39bfb47cf435c4148a51b6b94d04
[lyx.git] / src / frontends / qt4 / GuiRef.cpp
1 /**
2  * \file GuiRef.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Jürgen Spitzmüller
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiRef.h"
15
16 #include "ControlRef.h"
17 #include "qt_helpers.h"
18
19 #include "insets/InsetRef.h"
20
21 #include <QLineEdit>
22 #include <QCheckBox>
23 #include <QListWidget>
24 #include <QListWidgetItem>
25 #include <QPushButton>
26 #include <QToolTip>
27 #include <QCloseEvent>
28
29
30 using std::vector;
31 using std::string;
32
33
34 namespace lyx {
35 namespace frontend {
36
37 GuiRefDialog::GuiRefDialog(LyXView & lv)
38         : GuiDialog(lv, "ref")
39 {
40         setupUi(this);
41         setController(new ControlRef(*this));
42         setViewTitle(_("Cross-reference"));
43
44         sort_ = false;
45         at_ref_ = false;
46
47         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
48         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
49         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
50         connect(closePB, SIGNAL(clicked()), this, SLOT(reset_dialog()));
51         connect(this, SIGNAL(rejected()), this, SLOT(reset_dialog()));
52
53         connect(typeCO, SIGNAL(activated(int)),
54                 this, SLOT(changed_adaptor()));
55         connect(referenceED, SIGNAL(textChanged(const QString &)),
56                 this, SLOT(changed_adaptor()));
57         connect(nameED, SIGNAL(textChanged(const QString &)),
58                 this, SLOT(changed_adaptor()));
59         connect(refsLW, SIGNAL(itemClicked(QListWidgetItem *)),
60                 this, SLOT(refHighlighted(QListWidgetItem *)));
61         connect(refsLW, SIGNAL(itemSelectionChanged()),
62                 this, SLOT(selectionChanged()));
63         connect(refsLW, SIGNAL(itemActivated(QListWidgetItem *)),
64                 this, SLOT(refSelected(QListWidgetItem *)));
65         connect(sortCB, SIGNAL(clicked(bool)),
66                 this, SLOT(sortToggled(bool)));
67         connect(gotoPB, SIGNAL(clicked()),
68                 this, SLOT(gotoClicked()));
69         connect(updatePB, SIGNAL(clicked()),
70                 this, SLOT(updateClicked()));
71         connect(bufferCO, SIGNAL(activated(int)),
72                 this, SLOT(updateClicked()));
73
74         setFocusProxy(refsLW);
75
76         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
77         bc().setOK(okPB);
78         bc().setApply(applyPB);
79         bc().setCancel(closePB);
80         bc().addReadOnly(refsLW);
81         bc().addReadOnly(sortCB);
82         bc().addReadOnly(nameED);
83         bc().addReadOnly(referenceED);
84         bc().addReadOnly(typeCO);
85         bc().addReadOnly(bufferCO);
86
87         restored_buffer_ = -1;
88 }
89
90
91 ControlRef & GuiRefDialog::controller() const
92 {
93         return static_cast<ControlRef &>(GuiDialog::controller());
94 }
95
96
97 void GuiRefDialog::changed_adaptor()
98 {
99         changed();
100 }
101
102
103 void GuiRefDialog::gotoClicked()
104 {
105         gotoRef();
106 }
107
108 void GuiRefDialog::selectionChanged()
109 {
110         if (readOnly())
111                 return;
112
113         QList<QListWidgetItem *> selections = refsLW->selectedItems();
114         if (selections.isEmpty())
115                 return;
116         QListWidgetItem * sel = selections.first();
117         refHighlighted(sel);
118         return;
119 }
120
121
122 void GuiRefDialog::refHighlighted(QListWidgetItem * sel)
123 {
124         if (readOnly())
125                 return;
126
127 /*      int const cur_item = refsLW->currentRow();
128         bool const cur_item_selected = cur_item >= 0 ?
129                 refsLB->isSelected(cur_item) : false;*/
130         bool const cur_item_selected = refsLW->isItemSelected(sel);
131
132         if (cur_item_selected)
133                 referenceED->setText(sel->text());
134
135         if (at_ref_)
136                 gotoRef();
137         gotoPB->setEnabled(true);
138         if (typeAllowed())
139                 typeCO->setEnabled(true);
140         if (nameAllowed())
141                 nameED->setEnabled(true);
142 }
143
144
145 void GuiRefDialog::refSelected(QListWidgetItem * sel)
146 {
147         if (readOnly())
148                 return;
149
150 /*      int const cur_item = refsLW->currentRow();
151         bool const cur_item_selected = cur_item >= 0 ?
152                 refsLB->isSelected(cur_item) : false;*/
153         bool const cur_item_selected = refsLW->isItemSelected(sel);
154
155         if (cur_item_selected)
156                 referenceED->setText(sel->text());
157         // <enter> or double click, inserts ref and closes dialog
158         slotOK();
159 }
160
161
162 void GuiRefDialog::sortToggled(bool on)
163 {
164         sort_ = on;
165         redoRefs();
166 }
167
168
169 void GuiRefDialog::updateClicked()
170 {
171         updateRefs();
172 }
173
174
175 void GuiRefDialog::reset_dialog()
176 {
177         at_ref_ = false;
178         setGotoRef();
179 }
180
181
182 void GuiRefDialog::closeEvent(QCloseEvent * e)
183 {
184         slotClose();
185         reset_dialog();
186         e->accept();
187 }
188
189
190 void GuiRefDialog::update_contents()
191 {
192         InsetCommandParams const & params = controller().params();
193
194         int orig_type = typeCO->currentIndex();
195
196         referenceED->setText(toqstr(params["reference"]));
197
198         nameED->setText(toqstr(params["name"]));
199         nameED->setReadOnly(!nameAllowed() && !readOnly());
200
201         // restore type settings for new insets
202         if (params["reference"].empty())
203                 typeCO->setCurrentIndex(orig_type);
204         else
205                 typeCO->setCurrentIndex(InsetRef::getType(params.getCmdName()));
206         typeCO->setEnabled(typeAllowed() && !readOnly());
207         if (!typeAllowed())
208                 typeCO->setCurrentIndex(0);
209
210         sortCB->setChecked(sort_);
211
212         // insert buffer list
213         bufferCO->clear();
214         vector<string> const buffers = controller().getBufferList();
215         for (vector<string>::const_iterator it = buffers.begin();
216                 it != buffers.end(); ++it) {
217                 bufferCO->addItem(toqstr(*it));
218         }
219         // restore the buffer combo setting for new insets
220         if (params["reference"].empty() && restored_buffer_ != -1
221         && restored_buffer_ < bufferCO->count())
222                 bufferCO->setCurrentIndex(restored_buffer_);
223         else
224                 bufferCO->setCurrentIndex(controller().getBufferNum());
225
226         updateRefs();
227         bc().setValid(false);
228 }
229
230
231 void GuiRefDialog::applyView()
232 {
233         InsetCommandParams & params = controller().params();
234
235         last_reference_ = referenceED->text();
236
237         params.setCmdName(InsetRef::getName(typeCO->currentIndex()));
238         params["reference"] = qstring_to_ucs4(last_reference_);
239         params["name"] = qstring_to_ucs4(nameED->text());
240
241         restored_buffer_ = bufferCO->currentIndex();
242 }
243
244
245 bool GuiRefDialog::nameAllowed()
246 {
247         KernelDocType const doc_type = controller().docType();
248         return doc_type != LATEX && doc_type != LITERATE;
249 }
250
251
252 bool GuiRefDialog::typeAllowed()
253 {
254         return controller().docType() != DOCBOOK;
255 }
256
257
258 void GuiRefDialog::setGoBack()
259 {
260         gotoPB->setText(qt_("&Go Back"));
261         gotoPB->setToolTip("");
262         gotoPB->setToolTip(qt_("Jump back"));
263 }
264
265
266 void GuiRefDialog::setGotoRef()
267 {
268         gotoPB->setText(qt_("&Go to Label"));
269         gotoPB->setToolTip("");
270         gotoPB->setToolTip(qt_("Jump to label"));
271 }
272
273
274 void GuiRefDialog::gotoRef()
275 {
276         string ref = fromqstr(referenceED->text());
277
278         if (at_ref_) {
279                 // go back
280                 setGotoRef();
281                 controller().gotoBookmark();
282         } else {
283                 // go to the ref
284                 setGoBack();
285                 controller().gotoRef(ref);
286         }
287         at_ref_ = !at_ref_;
288 }
289
290
291 void GuiRefDialog::redoRefs()
292 {
293         // Prevent these widgets from emitting any signals whilst
294         // we modify their state.
295         refsLW->blockSignals(true);
296         referenceED->blockSignals(true);
297         refsLW->setUpdatesEnabled(false);
298
299         refsLW->clear();
300
301         // need this because Qt will send a highlight() here for
302         // the first item inserted
303         QString const oldSelection(referenceED->text());
304
305         for (std::vector<docstring>::const_iterator iter = refs_.begin();
306                 iter != refs_.end(); ++iter) {
307                 refsLW->addItem(toqstr(*iter));
308         }
309
310         if (sort_)
311                 refsLW->sortItems();
312
313         referenceED->setText(oldSelection);
314
315         // restore the last selection or, for new insets, highlight
316         // the previous selection
317         if (!oldSelection.isEmpty() || !last_reference_.isEmpty()) {
318                 bool const newInset = oldSelection.isEmpty();
319                 QString textToFind = newInset ? last_reference_ : oldSelection;
320                 bool foundItem = false;
321                 for (int i = 0; !foundItem && i < refsLW->count(); ++i) {
322                         QListWidgetItem * item = refsLW->item(i);
323                         if (textToFind == item->text()) {
324                                 refsLW->setCurrentItem(item);
325                                 refsLW->setItemSelected(item, !newInset);
326                                 //Make sure selected item is visible
327                                 refsLW->scrollToItem(item);
328                                 foundItem = true;
329                         }
330                 }
331                 if (foundItem)
332                         last_reference_ = textToFind;
333                 else last_reference_ = "";
334         }
335         refsLW->setUpdatesEnabled(true);
336         refsLW->update();
337
338         // Re-activate the emission of signals by these widgets.
339         refsLW->blockSignals(false);
340         referenceED->blockSignals(false);
341 }
342
343
344 void GuiRefDialog::updateRefs()
345 {
346         refs_.clear();
347         string const name = controller().getBufferName(bufferCO->currentIndex());
348         refs_ = controller().getLabelList(name);
349         sortCB->setEnabled(!refs_.empty());
350         refsLW->setEnabled(!refs_.empty());
351         gotoPB->setEnabled(!refs_.empty());
352         redoRefs();
353 }
354
355
356 bool GuiRefDialog::isValid()
357 {
358         return !referenceED->text().isEmpty();
359 }
360
361 } // namespace frontend
362 } // namespace lyx
363
364 #include "GuiRef_moc.cpp"