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