1 //=============================================================================
2 //
3 // File : HelpWindow.cpp
4 // Creation date : Tue Aug 11 2000 18:08:22 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the m_terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #include "HelpWindow.h"
26 #include "HelpWidget.h"
27
28 #include "kvi_settings.h"
29 #include "KviApplication.h"
30 #include "KviIconManager.h"
31 #include "KviOptions.h"
32 #include "KviLocale.h"
33 #include "KviModule.h"
34 #include "KviConfigurationFile.h"
35 #include "kvi_sourcesdate.h"
36
37 #include <QList>
38 #include <QFileInfo>
39 #include <QLineEdit>
40 #include <QMessageBox>
41 #include <QPushButton>
42 #include <QRegExp>
43 #include <QToolTip>
44 #include <QTimer>
45
46 extern HelpIndex * g_pDocIndex;
47 extern KviPointerList<HelpWindow> * g_pHelpWindowList;
48 extern KviPointerList<HelpWidget> * g_pHelpWidgetList;
49
50 //bool g_bIndexingDone = false;
HelpWindow(const char * name)51 HelpWindow::HelpWindow(const char * name)
52 : KviWindow(KviWindow::Help, name)
53 {
54 g_pHelpWindowList->append(this);
55 m_pSplitter = new KviTalSplitter(Qt::Horizontal, this);
56 m_pSplitter->setObjectName("main_splitter");
57 m_pSplitter->setChildrenCollapsible(false);
58
59 m_pHelpWidget = new HelpWidget(m_pSplitter);
60
61 m_pToolBar = new KviTalVBox(m_pSplitter);
62 m_pTabWidget = new QTabWidget(m_pToolBar);
63
64 m_pBottomLayout = new KviTalHBox(m_pToolBar);
65 m_pProgressBar = new QProgressBar(m_pBottomLayout);
66 m_pCancelButton = new QPushButton(m_pBottomLayout);
67 m_pCancelButton->setText(__tr2qs_ctx("Cancel", "logview"));
68 connect(m_pCancelButton, SIGNAL(clicked()), g_pDocIndex, SLOT(setLastWinClosed()));
69 m_pBottomLayout->setVisible(false);
70
71 m_pIndexTab = new KviTalVBox(m_pTabWidget);
72 m_pTabWidget->addTab(m_pIndexTab, __tr2qs("Help Index"));
73
74 KviTalHBox * pSearchBox = new KviTalHBox(m_pIndexTab);
75 m_pIndexSearch = new QLineEdit(pSearchBox);
76 connect(m_pIndexSearch, SIGNAL(textChanged(const QString &)), this, SLOT(searchInIndex(const QString &)));
77 connect(m_pIndexSearch, SIGNAL(returnPressed()), this, SLOT(showIndexTopic()));
78
79 m_pBtnRefreshIndex = new QPushButton(pSearchBox);
80 m_pBtnRefreshIndex->setIcon(*g_pIconManager->getBigIcon(KVI_REFRESH_IMAGE_NAME));
81 connect(m_pBtnRefreshIndex, SIGNAL(clicked()), this, SLOT(refreshIndex()));
82 m_pBtnRefreshIndex->setToolTip(__tr2qs("Refresh index"));
83
84 m_pIndexListWidget = new KviTalListWidget(m_pIndexTab);
85 connect(m_pIndexListWidget, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(indexSelected(QListWidgetItem *)));
86
87 m_pSearchTab = new KviTalVBox(m_pTabWidget);
88 m_pTabWidget->addTab(m_pSearchTab, __tr2qs("Search"));
89
90 m_pTermsEdit = new QLineEdit(m_pSearchTab);
91
92 connect(m_pTermsEdit, SIGNAL(returnPressed()), this, SLOT(startSearch()));
93
94 m_pResultBox = new KviTalListWidget(m_pSearchTab);
95 connect(m_pResultBox, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(searchSelected(QListWidgetItem *)));
96
97 QList<int> li;
98 li.append(width() - 80);
99 li.append(80);
100 m_pSplitter->setSizes(li);
101
102 connect(g_pDocIndex, SIGNAL(indexingStart(int)), this, SLOT(indexingStart(int)));
103 connect(g_pDocIndex, SIGNAL(indexingProgress(int)), this, SLOT(indexingProgress(int)));
104 connect(g_pDocIndex, SIGNAL(indexingEnd()), this, SLOT(indexingEnd()));
105
106 QTimer::singleShot(0, this, SLOT(initialSetup()));
107 }
108
~HelpWindow()109 HelpWindow::~HelpWindow()
110 {
111 g_pHelpWindowList->removeRef(this);
112 }
113
initialSetup()114 void HelpWindow::initialSetup()
115 {
116 m_pIndexSearch->setFocus();
117
118 QString szDoclist, szDict;
119
120 g_pApp->getLocalKvircDirectory(szDoclist, KviApplication::Help, "help.doclist." KVI_SOURCES_DATE);
121 g_pApp->getLocalKvircDirectory(szDict, KviApplication::Help, "help.dict." KVI_SOURCES_DATE);
122
123 if(QFileInfo(szDoclist).exists() && QFileInfo(szDict).exists())
124 {
125 g_pDocIndex->readDict();
126 m_pIndexListWidget->clear();
127 QStringList docList = g_pDocIndex->titlesList();
128 m_pIndexListWidget->addItems(docList);
129 m_pIndexListWidget->sortItems();
130 m_pBtnRefreshIndex->setEnabled(true);
131 }
132 else
133 g_pDocIndex->makeIndex();
134 }
135
indexingStart(int iNum)136 void HelpWindow::indexingStart(int iNum)
137 {
138 m_pBtnRefreshIndex->setEnabled(false);
139 m_pBottomLayout->setVisible(true);
140 m_pProgressBar->setRange(0, iNum);
141 m_pProgressBar->setValue(0);
142 }
143
indexingProgress(int iNum)144 void HelpWindow::indexingProgress(int iNum)
145 {
146 m_pProgressBar->setValue(iNum);
147 }
148
indexingEnd()149 void HelpWindow::indexingEnd()
150 {
151 m_pProgressBar->setValue(0);
152 m_pBottomLayout->setVisible(false);
153 g_pDocIndex->writeDict();
154 m_pIndexListWidget->clear();
155 QStringList docList = g_pDocIndex->titlesList();
156 m_pIndexListWidget->addItems(docList);
157 m_pIndexListWidget->sortItems();
158 m_pBtnRefreshIndex->setEnabled(true);
159 }
160
saveProperties(KviConfigurationFile * cfg)161 void HelpWindow::saveProperties(KviConfigurationFile * cfg)
162 {
163 KviWindow::saveProperties(cfg);
164 cfg->writeEntry("Splitter", m_pSplitter->sizes());
165 }
166
loadProperties(KviConfigurationFile * cfg)167 void HelpWindow::loadProperties(KviConfigurationFile * cfg)
168 {
169 QList<int> def;
170 int w = width();
171 def.append((w * 82) / 100);
172 def.append((w * 18) / 100);
173 m_pSplitter->setSizes(cfg->readIntListEntry("Splitter", def));
174 KviWindow::loadProperties(cfg);
175 }
176
refreshIndex()177 void HelpWindow::refreshIndex()
178 {
179 g_pDocIndex->makeIndex();
180 }
181
startSearch()182 void HelpWindow::startSearch()
183 {
184 QString str = m_pTermsEdit->text();
185 str = str.replace("\'", "\"");
186 str = str.replace("`", "\"");
187 QString buf = str;
188 str = str.replace("-", " ");
189 str = str.replace(QRegExp(R"(\s[\S]?\s)"), " ");
190 m_terms = str.split(" ", QString::SkipEmptyParts);
191 QStringList termSeq;
192 QStringList seqWords;
193 QStringList::iterator it = m_terms.begin();
194 for(; it != m_terms.end(); ++it)
195 {
196 (*it) = (*it).simplified();
197 (*it) = (*it).toLower();
198 (*it) = (*it).replace("\"", "");
199 }
200 if(str.contains('\"'))
201 {
202 if((str.count('\"')) % 2 == 0)
203 {
204 int beg = 0;
205 int end = 0;
206 QString s;
207 beg = str.indexOf('\"', beg);
208 while(beg != -1)
209 {
210 beg++;
211 end = str.indexOf('\"', beg);
212 s = str.mid(beg, end - beg);
213 s = s.toLower();
214 s = s.simplified();
215 if(s.contains('*'))
216 {
217 QMessageBox::warning(this, __tr2qs("Full Text Search - KVIrc"),
218 __tr2qs("Using a wildcard within phrases is not allowed."));
219 return;
220 }
221 seqWords += s.split(' ', QString::SkipEmptyParts);
222 termSeq << s;
223 beg = str.indexOf('\"', end + 1);
224 }
225 }
226 else
227 {
228 QMessageBox::warning(this, __tr2qs("Full Text Search - KVIrc"),
229 __tr2qs("The closing quotation mark is missing."));
230 return;
231 }
232 }
233 setCursor(Qt::WaitCursor);
234 m_foundDocs.clear();
235 m_foundDocs = g_pDocIndex->query(m_terms, termSeq, seqWords);
236
237 m_pResultBox->clear();
238 for(it = m_foundDocs.begin(); it != m_foundDocs.end(); ++it)
239 m_pResultBox->addItem(g_pDocIndex->getDocumentTitle(*it));
240
241 m_terms.clear();
242 bool isPhrase = false;
243 QString s = "";
244 for(const auto & i : buf)
245 {
246 if(i == '\"')
247 {
248 isPhrase = !isPhrase;
249 s = s.simplified();
250 if(!s.isEmpty())
251 m_terms << s;
252 s = "";
253 }
254 else if(i == ' ' && !isPhrase)
255 {
256 s = s.simplified();
257 if(!s.isEmpty())
258 m_terms << s;
259 s = "";
260 }
261 else
262 s += i;
263 }
264 if(!s.isEmpty())
265 m_terms << s;
266
267 setCursor(Qt::ArrowCursor);
268 }
269
270 #ifdef COMPILE_WEBKIT_SUPPORT
textBrowser()271 QWebView * HelpWindow::textBrowser()
272 #else
273 QTextBrowser * HelpWindow::textBrowser()
274 #endif
275 {
276 return m_pHelpWidget->textBrowser();
277 }
278
showIndexTopic()279 void HelpWindow::showIndexTopic()
280 {
281 if(m_pIndexSearch->text().isEmpty() || !m_pIndexListWidget->selectedItems().count())
282 return;
283 int i = g_pDocIndex->titlesList().indexOf(m_pIndexListWidget->selectedItems().at(0)->text());
284 #ifdef COMPILE_WEBKIT_SUPPORT
285 textBrowser()->load(QUrl(g_pDocIndex->documentList()[i]));
286 #else
287 textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[i]));
288 #endif
289 }
290
searchInIndex(const QString & s)291 void HelpWindow::searchInIndex(const QString & s)
292 {
293 QListWidgetItem * item;
294 QString sl = s.toLower();
295 for(int i = 0; i < m_pIndexListWidget->count(); i++)
296 {
297 item = m_pIndexListWidget->item(i);
298 QString t = item->text();
299 if(t.length() >= sl.length() && item->text().left(s.length()).toLower() == sl)
300 {
301 m_pIndexListWidget->setCurrentItem(item);
302 m_pIndexListWidget->scrollToItem(item, QAbstractItemView::PositionAtTop);
303 break;
304 }
305 }
306 }
307
indexSelected(QListWidgetItem * item)308 void HelpWindow::indexSelected(QListWidgetItem * item)
309 {
310 if(!item)
311 return;
312 int i = g_pDocIndex->titlesList().indexOf(item->text());
313 #ifdef COMPILE_WEBKIT_SUPPORT
314 textBrowser()->load(QUrl(g_pDocIndex->documentList()[i]));
315 #else
316 textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[i]));
317 #endif
318 }
319
searchSelected(QListWidgetItem * item)320 void HelpWindow::searchSelected(QListWidgetItem * item)
321 {
322 if(!item)
323 return;
324 int i = g_pDocIndex->titlesList().indexOf(item->text());
325 #ifdef COMPILE_WEBKIT_SUPPORT
326 textBrowser()->load(QUrl(g_pDocIndex->documentList()[i]));
327 #else
328 textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[i]));
329 #endif
330 }
331
myIconPtr()332 QPixmap * HelpWindow::myIconPtr()
333 {
334 return g_pIconManager->getSmallIcon(KviIconManager::QuestionMark);
335 }
336
resizeEvent(QResizeEvent *)337 void HelpWindow::resizeEvent(QResizeEvent *)
338 {
339 m_pSplitter->setGeometry(0, 0, width(), height());
340 }
341
fillCaptionBuffers()342 void HelpWindow::fillCaptionBuffers()
343 {
344 m_szPlainTextCaption = __tr2qs("Help Browser");
345 }
346