3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Jürgen Spitzmüller
9 * Full author contact details are available in file CREDITS.
17 #include "BufferList.h"
18 #include "FuncRequest.h"
20 #include "qt_helpers.h"
22 #include "insets/InsetRef.h"
24 #include "support/FileName.h"
25 #include "support/FileNameList.h"
26 #include "support/filetools.h" // makeAbsPath, makeDisplayPath
30 #include <QListWidget>
31 #include <QListWidgetItem>
32 #include <QPushButton>
34 #include <QCloseEvent>
37 using namespace lyx::support
;
42 GuiRef::GuiRef(GuiView
& lv
)
43 : GuiDialog(lv
, "ref", qt_("Cross-reference")),
44 params_(insetCode("ref"))
50 // Enabling is set in updateRefs. Disable for now in case no
51 // call to updateContents follows (e.g. read-only documents).
52 sortCB
->setEnabled(false);
53 caseSensitiveCB
->setEnabled(false);
54 caseSensitiveCB
->setChecked(false);
55 refsLW
->setEnabled(false);
56 gotoPB
->setEnabled(false);
58 connect(okPB
, SIGNAL(clicked()), this, SLOT(slotOK()));
59 connect(applyPB
, SIGNAL(clicked()), this, SLOT(slotApply()));
60 connect(closePB
, SIGNAL(clicked()), this, SLOT(slotClose()));
61 connect(closePB
, SIGNAL(clicked()), this, SLOT(reset_dialog()));
62 connect(this, SIGNAL(rejected()), this, SLOT(dialog_rejected()));
64 connect(typeCO
, SIGNAL(activated(int)),
65 this, SLOT(changed_adaptor()));
66 connect(referenceED
, SIGNAL(textChanged(QString
)),
67 this, SLOT(changed_adaptor()));
68 connect(nameED
, SIGNAL(textChanged(QString
)),
69 this, SLOT(changed_adaptor()));
70 connect(refsLW
, SIGNAL(itemClicked(QListWidgetItem
*)),
71 this, SLOT(refHighlighted(QListWidgetItem
*)));
72 connect(refsLW
, SIGNAL(itemSelectionChanged()),
73 this, SLOT(selectionChanged()));
74 connect(refsLW
, SIGNAL(itemActivated(QListWidgetItem
*)),
75 this, SLOT(refSelected(QListWidgetItem
*)));
76 connect(sortCB
, SIGNAL(clicked()),
77 this, SLOT(sortToggled()));
78 connect(caseSensitiveCB
, SIGNAL(clicked()),
79 this, SLOT(caseSensitiveToggled()));
80 connect(gotoPB
, SIGNAL(clicked()),
81 this, SLOT(gotoClicked()));
82 connect(updatePB
, SIGNAL(clicked()),
83 this, SLOT(updateClicked()));
84 connect(bufferCO
, SIGNAL(activated(int)),
85 this, SLOT(updateClicked()));
87 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy
);
89 bc().setApply(applyPB
);
90 bc().setCancel(closePB
);
91 bc().addReadOnly(refsLW
);
92 bc().addReadOnly(sortCB
);
93 bc().addReadOnly(caseSensitiveCB
);
94 bc().addReadOnly(nameED
);
95 bc().addReadOnly(referenceED
);
96 bc().addReadOnly(typeCO
);
97 bc().addReadOnly(bufferCO
);
99 restored_buffer_
= -1;
104 void GuiRef::changed_adaptor()
110 void GuiRef::gotoClicked()
116 void GuiRef::selectionChanged()
118 if (isBufferReadonly())
121 QList
<QListWidgetItem
*> selections
= refsLW
->selectedItems();
122 if (selections
.isEmpty())
124 QListWidgetItem
* sel
= selections
.first();
130 void GuiRef::refHighlighted(QListWidgetItem
* sel
)
132 if (isBufferReadonly())
135 /* int const cur_item = refsLW->currentRow();
136 bool const cur_item_selected = cur_item >= 0 ?
137 refsLB->isSelected(cur_item) : false;*/
138 bool const cur_item_selected
= refsLW
->isItemSelected(sel
);
140 if (cur_item_selected
)
141 referenceED
->setText(sel
->text());
145 gotoPB
->setEnabled(true);
147 typeCO
->setEnabled(true);
149 nameED
->setEnabled(true);
153 void GuiRef::refSelected(QListWidgetItem
* sel
)
155 if (isBufferReadonly())
158 /* int const cur_item = refsLW->currentRow();
159 bool const cur_item_selected = cur_item >= 0 ?
160 refsLB->isSelected(cur_item) : false;*/
161 bool const cur_item_selected
= refsLW
->isItemSelected(sel
);
163 if (cur_item_selected
)
164 referenceED
->setText(sel
->text());
165 // <enter> or double click, inserts ref and closes dialog
170 void GuiRef::sortToggled()
172 caseSensitiveCB
->setEnabled(sortCB
->isChecked());
177 void GuiRef::caseSensitiveToggled()
183 void GuiRef::updateClicked()
189 void GuiRef::dialog_rejected()
192 // We have to do this manually, instead of calling slotClose(), because
193 // the dialog has already been made invisible before rejected() triggers.
194 Dialog::disconnect();
198 void GuiRef::reset_dialog()
205 void GuiRef::closeEvent(QCloseEvent
* e
)
213 void GuiRef::updateContents()
215 int orig_type
= typeCO
->currentIndex();
217 referenceED
->setText(toqstr(params_
["reference"]));
219 nameED
->setText(toqstr(params_
["name"]));
220 nameED
->setReadOnly(!nameAllowed() && !isBufferReadonly());
222 // restore type settings for new insets
223 if (params_
["reference"].empty())
224 typeCO
->setCurrentIndex(orig_type
);
226 typeCO
->setCurrentIndex(InsetRef::getType(params_
.getCmdName()));
227 typeCO
->setEnabled(typeAllowed() && !isBufferReadonly());
229 typeCO
->setCurrentIndex(0);
231 // insert buffer list
233 FileNameList
const & buffers
= theBufferList().fileNames();
234 for (FileNameList::const_iterator it
= buffers
.begin();
235 it
!= buffers
.end(); ++it
) {
236 bufferCO
->addItem(toqstr(makeDisplayPath(it
->absFilename())));
239 int const thebuffer
= theBufferList().bufferNum(buffer().fileName());
240 // restore the buffer combo setting for new insets
241 if (params_
["reference"].empty() && restored_buffer_
!= -1
242 && restored_buffer_
< bufferCO
->count() && thebuffer
== active_buffer_
)
243 bufferCO
->setCurrentIndex(restored_buffer_
);
245 int const num
= theBufferList().bufferNum(buffer().fileName());
246 bufferCO
->setCurrentIndex(num
);
247 if (thebuffer
!= active_buffer_
)
248 restored_buffer_
= num
;
250 active_buffer_
= thebuffer
;
253 bc().setValid(false);
257 void GuiRef::applyView()
259 last_reference_
= referenceED
->text();
261 params_
.setCmdName(InsetRef::getName(typeCO
->currentIndex()));
262 params_
["reference"] = qstring_to_ucs4(last_reference_
);
263 params_
["name"] = qstring_to_ucs4(nameED
->text());
265 restored_buffer_
= bufferCO
->currentIndex();
269 bool GuiRef::nameAllowed()
271 KernelDocType
const doc_type
= docType();
272 return doc_type
!= LATEX
&& doc_type
!= LITERATE
;
276 bool GuiRef::typeAllowed()
278 return docType() != DOCBOOK
;
282 void GuiRef::setGoBack()
284 gotoPB
->setText(qt_("&Go Back"));
285 gotoPB
->setToolTip("");
286 gotoPB
->setToolTip(qt_("Jump back"));
290 void GuiRef::setGotoRef()
292 gotoPB
->setText(qt_("&Go to Label"));
293 gotoPB
->setToolTip("");
294 gotoPB
->setToolTip(qt_("Jump to label"));
298 void GuiRef::gotoRef()
300 string ref
= fromqstr(referenceED
->text());
314 inline bool caseInsensitiveLessThan(QString
const & s1
, QString
const & s2
)
316 return s1
.toLower() < s2
.toLower();
320 void GuiRef::redoRefs()
322 // Prevent these widgets from emitting any signals whilst
323 // we modify their state.
324 refsLW
->blockSignals(true);
325 referenceED
->blockSignals(true);
326 refsLW
->setUpdatesEnabled(false);
330 // need this because Qt will send a highlight() here for
331 // the first item inserted
332 QString
const oldSelection(referenceED
->text());
334 QStringList refsStrings
;
335 vector
<docstring
>::const_iterator iter
;
336 for (iter
= refs_
.begin(); iter
!= refs_
.end(); ++iter
)
337 refsStrings
.append(toqstr(*iter
));
339 if (sortCB
->isEnabled() && sortCB
->isChecked()) {
340 if(caseSensitiveCB
->isEnabled() && caseSensitiveCB
->isChecked())
341 qSort(refsStrings
.begin(), refsStrings
.end());
343 qSort(refsStrings
.begin(), refsStrings
.end(),
344 caseInsensitiveLessThan
/*defined above*/);
347 refsLW
->addItems(refsStrings
);
349 referenceED
->setText(oldSelection
);
351 // restore the last selection or, for new insets, highlight
352 // the previous selection
353 if (!oldSelection
.isEmpty() || !last_reference_
.isEmpty()) {
354 bool const newInset
= oldSelection
.isEmpty();
355 QString textToFind
= newInset
? last_reference_
: oldSelection
;
356 last_reference_
.clear();
357 for (int i
= 0; i
!= refsLW
->count(); ++i
) {
358 QListWidgetItem
* item
= refsLW
->item(i
);
359 if (textToFind
== item
->text()) {
360 refsLW
->setCurrentItem(item
);
361 refsLW
->setItemSelected(item
, !newInset
);
362 //Make sure selected item is visible
363 refsLW
->scrollToItem(item
);
364 last_reference_
= textToFind
;
369 refsLW
->setUpdatesEnabled(true);
372 // Re-activate the emission of signals by these widgets.
373 refsLW
->blockSignals(false);
374 referenceED
->blockSignals(false);
378 void GuiRef::updateRefs()
381 int const the_buffer
= bufferCO
->currentIndex();
382 if (the_buffer
!= -1) {
383 FileName
const & name
= theBufferList().fileNames()[the_buffer
];
384 Buffer
const * buf
= theBufferList().getBuffer(name
);
385 buf
->getLabelList(refs_
);
387 sortCB
->setEnabled(!refs_
.empty());
388 caseSensitiveCB
->setEnabled(sortCB
->isEnabled() && sortCB
->isChecked());
389 refsLW
->setEnabled(!refs_
.empty());
390 // refsLW should only be the focus proxy when it is enabled
391 setFocusProxy(refs_
.empty() ? 0 : refsLW
);
392 gotoPB
->setEnabled(!refs_
.empty());
397 bool GuiRef::isValid()
399 return !referenceED
->text().isEmpty();
403 void GuiRef::gotoRef(string
const & ref
)
405 dispatch(FuncRequest(LFUN_BOOKMARK_SAVE
, "0"));
406 dispatch(FuncRequest(LFUN_LABEL_GOTO
, ref
));
410 void GuiRef::gotoBookmark()
412 dispatch(FuncRequest(LFUN_BOOKMARK_GOTO
, "0"));
416 bool GuiRef::initialiseParams(std::string
const & data
)
418 InsetCommand::string2params("ref", data
, params_
);
423 void GuiRef::dispatchParams()
425 std::string
const lfun
= InsetCommand::params2string("ref", params_
);
426 dispatch(FuncRequest(getLfun(), lfun
));
431 Dialog
* createGuiRef(GuiView
& lv
) { return new GuiRef(lv
); }
434 } // namespace frontend
437 #include "moc_GuiRef.cpp"