dict.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Copyright (C) 2008 Nick Shaforostoff <shaforostoff@kde.ru>
  3. *
  4. * based on work by:
  5. * Copyright (C) 2007 Thomas Georgiou <TAGeorgiou@gmail.com> and Jeff Cooper <weirdsox11@gmail.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "dict.h"
  21. #include <QGraphicsProxyWidget>
  22. #include <QGraphicsLinearLayout>
  23. #include <QTimer>
  24. // #include <QWebView>
  25. #include <QTextBrowser>
  26. #include <KDebug>
  27. #include <KIcon>
  28. #include <KStandardDirs>
  29. #include <KLineEdit>
  30. #include <KEditListBox>
  31. #include <QListView>
  32. #include <QTreeView>
  33. #include <QStringListModel>
  34. #include <KConfigDialog>
  35. #include <KConfigGroup>
  36. #include <Plasma/Animator>
  37. #include <Plasma/IconWidget>
  38. #include <Plasma/LineEdit>
  39. #define AUTO_DEFINE_TIMEOUT 500
  40. using namespace Plasma;
  41. const char* translationCSS =
  42. "body {\n"
  43. "font-size: 10pt; }\n"
  44. "font.dict_name {\n"
  45. "color: blue;\n"
  46. "font-style: italic; }\n"
  47. "font.title {\n"
  48. "font-size: 16pt;\n"
  49. "font-weight: bold; }\n"
  50. "font.explanation {\n"
  51. "color: #7f7f7f;\n"
  52. "font-style: italic; }\n"
  53. "font.abbreviature {\n"
  54. "font-style: italic; }\n"
  55. "font.example {\n"
  56. "font-style: italic; }\n"
  57. "font.transcription {\n"
  58. "font-weight: bold; }\n";
  59. QStarDictApplet::QStarDictApplet(QObject *parent, const QVariantList &args)
  60. : Plasma::Applet(parent, args)
  61. , m_dictsModel(0)
  62. //m_flash(0)
  63. {
  64. setHasConfigurationInterface(true);
  65. setAspectRatioMode(Plasma::IgnoreAspectRatio);
  66. resize(500,200);
  67. }
  68. QStarDictApplet::~QStarDictApplet()
  69. {
  70. m_defBrowser->deleteLater();
  71. }
  72. void QStarDictApplet::init()
  73. {
  74. // KConfigGroup cg = config();
  75. m_wordEdit = new LineEdit(this);
  76. m_wordEdit->nativeWidget()->setClearButtonShown( true );
  77. m_wordEdit->nativeWidget()->setClickMessage(i18n("Enter word to define here"));
  78. m_wordEdit->show();
  79. Plasma::Animator::self()->animateItem(m_wordEdit, Plasma::Animator::AppearAnimation);
  80. // m_defBrowser = new QWebView();
  81. m_defBrowser = new QTextBrowser();
  82. m_defBrowser->document()->setDefaultStyleSheet(QLatin1String(translationCSS));
  83. m_defBrowserProxy = new QGraphicsProxyWidget(this);
  84. m_defBrowserProxy->setWidget(m_defBrowser);
  85. m_defBrowserProxy->hide();
  86. // Icon in upper-left corner
  87. QString iconpath = KStandardDirs::locate("icon", "oxygen/scalable/apps/accessories-dictionary.svgz");
  88. m_icon = new Plasma::IconWidget(this);
  89. m_icon->setSvg(iconpath);
  90. // Position lineedits
  91. //const int wordEditOffset = 40;
  92. m_icon->setPos(12,3);
  93. //m_wordProxyWidget->setPos(15 + wordEditOffset,7);
  94. //m_wordProxyWidget->show();
  95. // TODO m_wordEdit->setDefaultTextColor(Plasma::Theme::self()->color(Plasma::Theme::TextColor));
  96. // Timer for auto-define
  97. m_timer = new QTimer(this);
  98. m_timer->setInterval(AUTO_DEFINE_TIMEOUT);
  99. m_timer->setSingleShot(true);
  100. connect(m_timer, SIGNAL(timeout()), this, SLOT(define()));
  101. m_horLayout = new QGraphicsLinearLayout(Qt::Horizontal);
  102. m_horLayout->addItem(m_icon);
  103. m_horLayout->addItem(m_wordEdit);
  104. m_layout = new QGraphicsLinearLayout(Qt::Vertical);
  105. m_layout->addItem(m_horLayout);
  106. m_layout->addItem(m_defBrowserProxy);
  107. setLayout(m_layout);
  108. m_source.clear();
  109. dataEngine("qstardict")->connectSource(m_source, this);
  110. connect(m_wordEdit, SIGNAL(editingFinished()), this, SLOT(define()));
  111. connect(m_wordEdit->nativeWidget(), SIGNAL(textChanged(const QString&)), this, SLOT(autoDefine(const QString&)));
  112. dataEngine("qstardict")->connectSource("list-dictionaries", this);
  113. //connect(m_defEdit, SIGNAL(linkActivated(const QString&)), this, SLOT(linkDefine(const QString&)));
  114. // This is the fix for links/selecting text
  115. //QGraphicsItem::GraphicsItemFlags flags = m_defEdit->flags();
  116. //flags ^= QGraphicsItem::ItemIsMovable;
  117. // m_defEdit->setFlags(flags);
  118. /*m_flash = new Plasma::Flash(this);
  119. m_flash->setColor(Qt::gray);
  120. QFont fnt = qApp->font();
  121. fnt.setBold(true);
  122. m_flash->setFont(fnt);
  123. m_flash->setPos(25,-10);
  124. m_flash->resize(QSize(200,20));*/
  125. KConfigGroup cg = config();
  126. m_dicts = cg.readEntry("KnownDictionaries", QStringList());
  127. QStringList activeDictNames = cg.readEntry("ActiveDictionaries", QStringList());
  128. for (QStringList::const_iterator i = m_dicts.constBegin(); i != m_dicts.constEnd(); ++i)
  129. m_activeDicts[*i]=activeDictNames.contains(*i);
  130. }
  131. void QStarDictApplet::linkDefine(const QString &text)
  132. {
  133. kDebug() <<"ACTIVATED";
  134. m_wordEdit->setText(text);
  135. define();
  136. }
  137. void QStarDictApplet::dataUpdated(const QString& source, const Plasma::DataEngine::Data &data)
  138. {
  139. if (source=="list-dictionaries")
  140. {
  141. QStringList newDicts=data["dictionaries"].toStringList();
  142. bool changed=false;
  143. for (QStringList::const_iterator i = newDicts.constBegin(); i != newDicts.constEnd(); ++i)
  144. {
  145. if (!m_dicts.contains(*i))
  146. {
  147. m_dicts<<*i;
  148. m_activeDicts[*i]=true;
  149. changed=true;
  150. }
  151. }
  152. QStringList::iterator it = m_dicts.begin();
  153. while (it != m_dicts.end())
  154. {
  155. if (!newDicts.contains(*it))
  156. {
  157. it=m_dicts.erase(it);
  158. changed=true;
  159. }
  160. else
  161. ++it;
  162. }
  163. if (changed)
  164. configAccepted();
  165. // cg.writeEntry("KnownDictionaries", m_dicts);
  166. }
  167. // Q_UNUSED(source);
  168. /*if (m_flash) {
  169. m_flash->kill();
  170. }*/
  171. if (!m_source.isEmpty()) {
  172. m_defBrowserProxy->show();
  173. // TODO Phase::self()->animateItem(m_defBrowserProxy, Phase::Appear);
  174. }
  175. /* if (data.contains("gcide")) {
  176. QString defHeader;
  177. m_defList = data[QString("gcide")].toString().split("<!--PAGE START-->"); //<!--DEFINITION START-->
  178. for (int n = 0; n < m_defList.size(); ++n)
  179. {
  180. if (m_defList[n].contains("<!--DEFINITION START-->") && m_defList[n].contains("<!--PERIOD-->")) {
  181. defHeader=m_defList[n];
  182. } else if (m_defList[n].contains("<!--DEFINITION START-->")) {
  183. defHeader=m_defList.takeAt(n);
  184. }
  185. if (n < m_defList.size() && !m_defList[n].contains("<!--DEFINITION START-->"))
  186. m_defList[n].prepend(defHeader);
  187. }
  188. if (m_defList.size() > 1)
  189. m_defList.removeAt(0);
  190. m_i = m_defList.begin();
  191. m_defEdit->setHtml(*m_i);
  192. if (m_i != --m_defList.end())
  193. m_rightArrow->show();
  194. else
  195. m_rightArrow->hide();
  196. m_leftArrow->hide();
  197. } */
  198. if (data.contains("text")) {
  199. m_defBrowser->setHtml(data[QString("text")].toString());
  200. // m_defBrowser->setHtml(wnToHtml(data[QString("wn")].toString()));
  201. }
  202. updateGeometry();
  203. }
  204. void QStarDictApplet::define()
  205. {
  206. if (m_timer->isActive())
  207. m_timer->stop();
  208. QString newSource=m_wordEdit->text();
  209. QStringList dictsList;
  210. for (QStringList::const_iterator i = m_dicts.constBegin(); i != m_dicts.constEnd(); ++i)
  211. if (m_activeDicts.contains(*i) && m_activeDicts.value(*i))
  212. dictsList<<*i;
  213. if (!newSource.isEmpty() && !dictsList.isEmpty())
  214. newSource.prepend(dictsList.join(",")+':');
  215. if (newSource == m_source)
  216. return;
  217. dataEngine("qstardict")->disconnectSource(m_source, this);
  218. qWarning()<<"here"<<newSource;
  219. if (!newSource.isEmpty())
  220. { //get new definition
  221. //m_flash->flash(i18n("Looking up ") + m_word);
  222. m_source = newSource;
  223. dataEngine("qstardict")->connectSource(m_source, this);
  224. qWarning()<<"connectSource"<<m_source;
  225. }
  226. else
  227. { //make the definition box disappear
  228. // TODO Phase::self()->animateItem(m_defBrowserProxy, Phase::Disappear);
  229. m_defBrowserProxy->hide();
  230. }
  231. updateConstraints();
  232. }
  233. void QStarDictApplet::autoDefine(const QString &word)
  234. {
  235. Q_UNUSED(word)
  236. m_timer->start();
  237. }
  238. class CheckableStringListModel: public QStringListModel
  239. {
  240. public:
  241. CheckableStringListModel(QObject* parent, const QStringList& dicts, const QHash<QString,bool>& activeDicts_)
  242. : QStringListModel(parent)
  243. , activeDicts(activeDicts_)
  244. {
  245. setStringList(dicts);
  246. /* setHeaderData (0, Qt::Horizontal, "020", Qt::DisplayRole);
  247. setHeaderData (0, Qt::Vertical, "020", Qt::DisplayRole);*/
  248. }
  249. QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const
  250. {
  251. if (role!=Qt::DisplayRole)
  252. return QVariant();
  253. return i18n("Dictionary");
  254. }
  255. Qt::DropActions supportedDropActions(){return Qt::MoveAction;}
  256. Qt::ItemFlags flags(const QModelIndex& index) const
  257. {
  258. if (!index.isValid())
  259. return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
  260. return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
  261. }
  262. bool setData (const QModelIndex& index, const QVariant& value, int role=Qt::EditRole)
  263. {
  264. if (role==Qt::CheckStateRole)
  265. {
  266. activeDicts[stringList().at(index.row())]=value.toInt()==Qt::Checked;
  267. return true;
  268. }
  269. else
  270. return QStringListModel::setData(index,value,role);
  271. }
  272. QVariant data(const QModelIndex& index, int role=Qt::EditRole) const
  273. {
  274. if (!index.isValid())
  275. return QVariant();
  276. if (role==Qt::CheckStateRole)
  277. return ( activeDicts.contains(stringList().at(index.row()))&&activeDicts.value(stringList().at(index.row())) )?Qt::Checked:Qt::Unchecked;
  278. return QStringListModel::data(index,role);
  279. }
  280. public:
  281. QHash<QString,bool> activeDicts;
  282. };
  283. void QStarDictApplet::createConfigurationInterface(KConfigDialog *parent)
  284. {
  285. // KConfigGroup cg = config();
  286. //QWidget *widget = new QWidget(parent);
  287. // QListView* widget=new KEditListBox(i18n("Dictionaries activation and order"),
  288. // KEditListBox::CustomEditor::CustomEditor(),
  289. // parent,
  290. // "dict-order",
  291. // false,
  292. // KEditListBox::UpDown);
  293. // QListView* widget=new QListView(parent);
  294. QTreeView* widget=new QTreeView(parent);
  295. widget->setDragEnabled(true);
  296. widget->setAcceptDrops(true);
  297. // widget->viewposrt()->setAcceptDrops(true);
  298. widget->setDragDropMode(QAbstractItemView::InternalMove);
  299. widget->setDropIndicatorShown(true);
  300. widget->setItemsExpandable(false);
  301. widget->setAllColumnsShowFocus(true);
  302. widget->setRootIsDecorated(false);
  303. delete m_dictsModel;
  304. m_dictsModel=new CheckableStringListModel(parent,m_dicts,m_activeDicts);
  305. widget->setModel(m_dictsModel);
  306. // parent->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
  307. parent->addPage(widget, parent->windowTitle(), Applet::icon());
  308. connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
  309. connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
  310. }
  311. void QStarDictApplet::configAccepted()
  312. {
  313. if (m_dictsModel)
  314. {
  315. m_dicts=m_dictsModel->stringList();
  316. m_activeDicts=m_dictsModel->activeDicts;
  317. }
  318. KConfigGroup cg = config();
  319. cg.writeEntry("KnownDictionaries", m_dicts);
  320. QStringList activeDictNames;
  321. for (QStringList::const_iterator i = m_dicts.constBegin(); i != m_dicts.constEnd(); ++i)
  322. if (m_activeDicts.contains(*i) && m_activeDicts.value(*i))
  323. activeDictNames<<*i;
  324. cg.writeEntry("ActiveDictionaries", activeDictNames);
  325. define();
  326. emit configNeedsSaving();
  327. }
  328. #include "dict.moc"