2 * \file GuiThesaurus.cpp
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.
14 #include "GuiThesaurus.h"
15 #include "GuiApplication.h"
17 #include "qt_helpers.h"
20 #include "BufferParams.h"
21 #include "BufferView.h"
22 #include "FuncRequest.h"
25 #include "WordLangTuple.h"
27 #include "support/debug.h"
28 #include "support/gettext.h"
29 #include "support/lstrings.h"
31 #include <QAbstractItemModel>
33 #include <QHeaderView>
35 #include <QPushButton>
36 #include <QTreeWidget>
37 #include <QTreeWidgetItem>
40 using namespace lyx::support;
46 GuiThesaurus::GuiThesaurus(GuiView & lv)
47 : GuiDialog(lv, "thesaurus", qt_("Thesaurus"))
51 meaningsTV->setColumnCount(1);
52 meaningsTV->header()->hide();
54 connect(closePB, SIGNAL(clicked()),
55 this, SLOT(slotClose()));
56 connect(replaceED, SIGNAL(returnPressed()),
57 this, SLOT(replaceClicked()));
58 connect(replaceED, SIGNAL(textChanged(QString)),
59 this, SLOT(change_adaptor()));
60 connect(entryCO, SIGNAL(editTextChanged(const QString &)),
61 this, SLOT(entryChanged()));
62 connect(entryCO, SIGNAL(activated(int)),
63 this, SLOT(entryChanged()));
64 connect(lookupPB, SIGNAL(clicked()),
65 this, SLOT(entryChanged()));
66 connect(replacePB, SIGNAL(clicked()),
67 this, SLOT(replaceClicked()));
68 connect(languageCO, SIGNAL(activated(int)),
69 this, SLOT(entryChanged()));
70 connect(meaningsTV, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
71 this, SLOT(itemClicked(QTreeWidgetItem *, int)));
72 connect(meaningsTV, SIGNAL(itemSelectionChanged()),
73 this, SLOT(selectionChanged()));
74 connect(meaningsTV, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
75 this, SLOT(selectionClicked(QTreeWidgetItem *, int)));
78 QAbstractItemModel * language_model = guiApp->languageModel();
79 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
80 language_model->sort(0);
81 languageCO->setModel(language_model);
82 languageCO->setModelColumn(2);
85 if (entryCO->completer())
86 entryCO->completer()->setCompletionMode(QCompleter::PopupCompletion);
88 bc().setCancel(closePB);
89 bc().setApply(replacePB);
90 bc().addReadOnly(replaceED);
91 bc().addReadOnly(replacePB);
92 bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
95 void GuiThesaurus::checkStatus()
97 if (!isBufferAvailable()) {
98 // deactivate the thesaurus if we have no buffer
105 void GuiThesaurus::change_adaptor()
111 void GuiThesaurus::entryChanged()
117 void GuiThesaurus::selectionChanged()
119 int const col = meaningsTV->currentColumn();
120 if (col < 0 || isBufferReadonly())
123 QString item = meaningsTV->currentItem()->text(col);
124 // cut out the classification in brackets:
125 // "hominid (generic term)" -> "hominid"
126 QRegExp re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$");
127 // This is for items with classifications at the beginning:
128 // "(noun) man" -> "man"; "(noun) male (generic term)" -> "male"
129 QRegExp rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$");
130 int pos = re.indexIn(item);
132 item = re.cap(1).trimmed();
133 pos = rex.indexIn(item);
135 item = rex.cap(2).trimmed();
136 replaceED->setText(item);
137 replacePB->setEnabled(!isBufferReadonly());
142 void GuiThesaurus::itemClicked(QTreeWidgetItem * /*item*/, int /*col*/)
148 void GuiThesaurus::selectionClicked(QTreeWidgetItem * item, int col)
150 QString str = item->text(col);
151 // cut out the classification in brackets:
152 // "hominid (generic term)" -> "hominid"
153 QRegExp re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$");
154 // This is for items with classifications at the beginning:
155 // "(noun) man" -> "man"; "(noun) male (generic term)" -> "male"
156 QRegExp rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$");
157 int pos = re.indexIn(str);
159 str = re.cap(1).trimmed();
160 pos = rex.indexIn(str);
162 str = rex.cap(2).trimmed();
163 entryCO->insertItem(0, str);
164 entryCO->setCurrentIndex(0);
171 void GuiThesaurus::updateLists()
175 if (entryCO->currentText().isEmpty())
178 meaningsTV->setUpdatesEnabled(false);
180 QString const lang = languageCO->itemData(
181 languageCO->currentIndex()).toString();
182 Language * language = const_cast<Language*>(lyx::languages.getLanguage(fromqstr(lang)));
183 docstring const lang_code = from_ascii(language->code());
185 Thesaurus::Meanings meanings =
186 getMeanings(WordLangTuple(qstring_to_ucs4(entryCO->currentText()), language));
188 for (Thesaurus::Meanings::const_iterator cit = meanings.begin();
189 cit != meanings.end(); ++cit) {
190 QTreeWidgetItem * i = new QTreeWidgetItem(meaningsTV);
191 i->setText(0, toqstr(cit->first));
192 meaningsTV->expandItem(i);
193 for (vector<docstring>::const_iterator cit2 = cit->second.begin();
194 cit2 != cit->second.end(); ++cit2) {
195 QTreeWidgetItem * i2 = new QTreeWidgetItem(i);
196 i2->setText(0, toqstr(*cit2));
198 meaningsTV->setEnabled(true);
199 lookupPB->setEnabled(true);
200 bool const readonly = isBufferReadonly();
201 replaceED->setEnabled(!readonly);
202 replacePB->setEnabled(!readonly);
205 if (meanings.empty()) {
206 if (!thesaurus.thesaurusAvailable(lang_code)) {
207 QTreeWidgetItem * i = new QTreeWidgetItem(meaningsTV);
208 i->setText(0, qt_("No thesaurus available for this language!"));
209 meaningsTV->setEnabled(false);
210 lookupPB->setEnabled(false);
211 replaceED->setEnabled(false);
212 replacePB->setEnabled(false);
216 meaningsTV->setUpdatesEnabled(true);
217 meaningsTV->update();
221 void GuiThesaurus::updateContents()
224 entryCO->addItem(toqstr(text_));
225 entryCO->setCurrentIndex(0);
226 replaceED->setText("");
227 int const pos = languageCO->findData(toqstr(lang_));
229 languageCO->setCurrentIndex(pos);
234 void GuiThesaurus::replaceClicked()
236 replace(qstring_to_ucs4(replaceED->text()));
240 bool GuiThesaurus::initialiseParams(string const & data)
243 string const lang = rsplit(data, arg, ' ');
244 if (prefixIs(lang, "lang=")) {
245 lang_ = from_utf8(split(lang, '='));
246 text_ = from_utf8(arg);
248 text_ = from_utf8(data);
251 bufferview()->buffer().params().language->lang());
257 void GuiThesaurus::clearParams()
264 void GuiThesaurus::replace(docstring const & newstr)
266 /* FIXME: this is not suitable ! We need to have a "lock"
267 * on a particular charpos in a paragraph that is broken on
270 docstring const data =
271 replace2string(newstr, text_,
272 true, // case sensitive
276 dispatch(FuncRequest(LFUN_WORD_REPLACE, data));
280 Thesaurus::Meanings const & GuiThesaurus::getMeanings(WordLangTuple const & wl)
282 if (wl.word() != laststr_)
283 meanings_ = thesaurus.lookup(wl);
288 Dialog * createGuiThesaurus(GuiView & lv) { return new GuiThesaurus(lv); }
291 } // namespace frontend
295 #include "moc_GuiThesaurus.cpp"