]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiRef.cpp
the fun begins....
[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 &>(Dialog::controller());
94 }
95
96
97 void GuiRefDialog::showView()
98 {
99         QDialog::show();
100 }
101
102
103 void GuiRefDialog::changed_adaptor()
104 {
105         changed();
106 }
107
108
109 void GuiRefDialog::gotoClicked()
110 {
111         gotoRef();
112 }
113
114 void GuiRefDialog::selectionChanged()
115 {
116         if (readOnly())
117                 return;
118
119         QList<QListWidgetItem *> selections = refsLW->selectedItems();
120         if (selections.isEmpty())
121                 return;
122         QListWidgetItem * sel = selections.first();
123         refHighlighted(sel);
124         return;
125 }
126
127
128 void GuiRefDialog::refHighlighted(QListWidgetItem * sel)
129 {
130         if (readOnly())
131                 return;
132
133 /*      int const cur_item = refsLW->currentRow();
134         bool const cur_item_selected = cur_item >= 0 ?
135                 refsLB->isSelected(cur_item) : false;*/
136         bool const cur_item_selected = refsLW->isItemSelected(sel);
137
138         if (cur_item_selected)
139                 referenceED->setText(sel->text());
140
141         if (at_ref_)
142                 gotoRef();
143         gotoPB->setEnabled(true);
144         if (typeAllowed())
145                 typeCO->setEnabled(true);
146         if (nameAllowed())
147                 nameED->setEnabled(true);
148 }
149
150
151 void GuiRefDialog::refSelected(QListWidgetItem * sel)
152 {
153         if (readOnly())
154                 return;
155
156 /*      int const cur_item = refsLW->currentRow();
157         bool const cur_item_selected = cur_item >= 0 ?
158                 refsLB->isSelected(cur_item) : false;*/
159         bool const cur_item_selected = refsLW->isItemSelected(sel);
160
161         if (cur_item_selected)
162                 referenceED->setText(sel->text());
163         // <enter> or double click, inserts ref and closes dialog
164         slotOK();
165 }
166
167
168 void GuiRefDialog::sortToggled(bool on)
169 {
170         sort_ = on;
171         redoRefs();
172 }
173
174
175 void GuiRefDialog::updateClicked()
176 {
177         updateRefs();
178 }
179
180
181 void GuiRefDialog::reset_dialog()
182 {
183         at_ref_ = false;
184         setGotoRef();
185 }
186
187
188 void GuiRefDialog::closeEvent(QCloseEvent * e)
189 {
190         slotWMHide();
191         reset_dialog();
192         e->accept();
193 }
194
195
196 void GuiRefDialog::update_contents()
197 {
198         InsetCommandParams const & params = controller().params();
199
200         int orig_type = typeCO->currentIndex();
201
202         referenceED->setText(toqstr(params["reference"]));
203
204         nameED->setText(toqstr(params["name"]));
205         nameED->setReadOnly(!nameAllowed() && !readOnly());
206
207         // restore type settings for new insets
208         if (params["reference"].empty())
209                 typeCO->setCurrentIndex(orig_type);
210         else
211                 typeCO->setCurrentIndex(InsetRef::getType(params.getCmdName()));
212         typeCO->setEnabled(typeAllowed() && !readOnly());
213         if (!typeAllowed())
214                 typeCO->setCurrentIndex(0);
215
216         sortCB->setChecked(sort_);
217
218         // insert buffer list
219         bufferCO->clear();
220         vector<string> const buffers = controller().getBufferList();
221         for (vector<string>::const_iterator it = buffers.begin();
222                 it != buffers.end(); ++it) {
223                 bufferCO->addItem(toqstr(*it));
224         }
225         // restore the buffer combo setting for new insets
226         if (params["reference"].empty() && restored_buffer_ != -1
227         && restored_buffer_ < bufferCO->count())
228                 bufferCO->setCurrentIndex(restored_buffer_);
229         else
230                 bufferCO->setCurrentIndex(controller().getBufferNum());
231
232         updateRefs();
233         bc().setValid(false);
234 }
235
236
237 void GuiRefDialog::applyView()
238 {
239         InsetCommandParams & params = controller().params();
240
241         last_reference_ = referenceED->text();
242
243         params.setCmdName(InsetRef::getName(typeCO->currentIndex()));
244         params["reference"] = qstring_to_ucs4(last_reference_);
245         params["name"] = qstring_to_ucs4(nameED->text());
246
247         restored_buffer_ = bufferCO->currentIndex();
248 }
249
250
251 bool GuiRefDialog::nameAllowed()
252 {
253         Kernel::DocType const doc_type = kernel().docType();
254         return doc_type != Kernel::LATEX &&
255                 doc_type != Kernel::LITERATE;
256 }
257
258
259 bool GuiRefDialog::typeAllowed()
260 {
261         Kernel::DocType const doc_type = kernel().docType();
262         return doc_type != Kernel::DOCBOOK;
263 }
264
265
266 void GuiRefDialog::setGoBack()
267 {
268         gotoPB->setText(qt_("&Go Back"));
269         gotoPB->setToolTip("");
270         gotoPB->setToolTip(qt_("Jump back"));
271 }
272
273
274 void GuiRefDialog::setGotoRef()
275 {
276         gotoPB->setText(qt_("&Go to Label"));
277         gotoPB->setToolTip("");
278         gotoPB->setToolTip(qt_("Jump to label"));
279 }
280
281
282 void GuiRefDialog::gotoRef()
283 {
284         string ref(fromqstr(referenceED->text()));
285
286         if (at_ref_) {
287                 // go back
288                 setGotoRef();
289                 controller().gotoBookmark();
290         } else {
291                 // go to the ref
292                 setGoBack();
293                 controller().gotoRef(ref);
294         }
295         at_ref_ = !at_ref_;
296 }
297
298
299 void GuiRefDialog::redoRefs()
300 {
301         // Prevent these widgets from emitting any signals whilst
302         // we modify their state.
303         refsLW->blockSignals(true);
304         referenceED->blockSignals(true);
305         refsLW->setUpdatesEnabled(false);
306
307         refsLW->clear();
308
309         // need this because Qt will send a highlight() here for
310         // the first item inserted
311         QString const oldSelection(referenceED->text());
312
313         for (std::vector<docstring>::const_iterator iter = refs_.begin();
314                 iter != refs_.end(); ++iter) {
315                 refsLW->addItem(toqstr(*iter));
316         }
317
318         if (sort_)
319                 refsLW->sortItems();
320
321         referenceED->setText(oldSelection);
322
323         // restore the last selection or, for new insets, highlight
324         // the previous selection
325         if (!oldSelection.isEmpty() || !last_reference_.isEmpty()) {
326                 bool const newInset = oldSelection.isEmpty();
327                 QString textToFind = newInset ? last_reference_ : oldSelection;
328                 bool foundItem = false;
329                 for (int i = 0; !foundItem && i < refsLW->count(); ++i) {
330                         QListWidgetItem * item = refsLW->item(i);
331                         if (textToFind == item->text()) {
332                                 refsLW->setCurrentItem(item);
333                                 refsLW->setItemSelected(item, !newInset);
334                                 //Make sure selected item is visible
335                                 refsLW->scrollToItem(item);
336                                 foundItem = true;
337                         }
338                 }
339                 if (foundItem)
340                         last_reference_ = textToFind;
341                 else last_reference_ = "";
342         }
343         refsLW->setUpdatesEnabled(true);
344         refsLW->update();
345
346         // Re-activate the emission of signals by these widgets.
347         refsLW->blockSignals(false);
348         referenceED->blockSignals(false);
349 }
350
351
352 void GuiRefDialog::updateRefs()
353 {
354         refs_.clear();
355         string const name = controller().getBufferName(bufferCO->currentIndex());
356         refs_ = controller().getLabelList(name);
357         sortCB->setEnabled(!refs_.empty());
358         refsLW->setEnabled(!refs_.empty());
359         gotoPB->setEnabled(!refs_.empty());
360         redoRefs();
361 }
362
363
364 bool GuiRefDialog::isValid()
365 {
366         return !referenceED->text().isEmpty();
367 }
368
369 } // namespace frontend
370 } // namespace lyx
371
372 #include "GuiRef_moc.cpp"