OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / help / centralwidget.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "centralwidget.h"
35
36 #include "helpviewer.h"
37 #include "localhelpmanager.h"
38 #include "topicchooser.h"
39
40 #include <QtCore/QEvent>
41 #include <QtCore/QTimer>
42
43 #include <QtGui/QKeyEvent>
44 #include <QtGui/QLayout>
45 #include <QtGui/QPageSetupDialog>
46 #include <QtGui/QPrinter>
47 #include <QtGui/QPrintDialog>
48 #include <QtGui/QPrintPreviewDialog>
49 #include <QtGui/QStackedWidget>
50
51 #include <QtHelp/QHelpEngine>
52 #include <QtHelp/QHelpSearchEngine>
53
54 using namespace Help::Internal;
55
56 CentralWidget *gStaticCentralWidget = 0;
57
58 // -- CentralWidget
59
60 CentralWidget::CentralWidget(QWidget *parent)
61     : QWidget(parent)
62     , printer(0)
63     , m_stackedWidget(0)
64 {
65     Q_ASSERT(!gStaticCentralWidget);
66     gStaticCentralWidget = this;
67
68     QVBoxLayout *vboxLayout = new QVBoxLayout(this);
69     vboxLayout->setMargin(0);
70     m_stackedWidget = new QStackedWidget(this);
71     vboxLayout->addWidget(m_stackedWidget);
72 }
73
74 CentralWidget::~CentralWidget()
75 {
76 #ifndef QT_NO_PRINTER
77     delete printer;
78 #endif
79
80     QString zoomFactors;
81     QString currentPages;
82     for (int i = 0; i < m_stackedWidget->count(); ++i) {
83         const HelpViewer * const viewer = viewerAt(i);
84         const QUrl &source = viewer->source();
85         if (source.isValid()) {
86             currentPages += source.toString() + QLatin1Char('|');
87             zoomFactors += QString::number(viewer->scale()) + QLatin1Char('|');
88         }
89     }
90
91     QHelpEngineCore *engine = &LocalHelpManager::helpEngine();
92     engine->setCustomValue(QLatin1String("LastShownPages"), currentPages);
93     engine->setCustomValue(QLatin1String("LastShownPagesZoom"), zoomFactors);
94     engine->setCustomValue(QLatin1String("LastTabPage"), currentIndex());
95 }
96
97 CentralWidget *CentralWidget::instance()
98 {
99     Q_ASSERT(gStaticCentralWidget);
100     return gStaticCentralWidget;
101 }
102
103 bool CentralWidget::hasSelection() const
104 {
105     if (HelpViewer* viewer = currentHelpViewer())
106         return !viewer->selectedText().isEmpty();
107     return false;
108 }
109
110 bool CentralWidget::isForwardAvailable() const
111 {
112     const HelpViewer* viewer = currentHelpViewer();
113     if (viewer)
114         return viewer->isForwardAvailable();
115
116     return false;
117 }
118
119 bool CentralWidget::isBackwardAvailable() const
120 {
121     const HelpViewer* viewer = currentHelpViewer();
122     if (viewer)
123         return viewer->isBackwardAvailable();
124
125     return false;
126 }
127
128 HelpViewer* CentralWidget::viewerAt(int index) const
129 {
130     return qobject_cast<HelpViewer*> (m_stackedWidget->widget(index));
131 }
132
133 HelpViewer* CentralWidget::currentHelpViewer() const
134 {
135     return qobject_cast<HelpViewer*> (m_stackedWidget->currentWidget());
136 }
137
138 void CentralWidget::addPage(HelpViewer *page, bool fromSearch)
139 {
140     page->installEventFilter(this);
141     page->setFocus(Qt::OtherFocusReason);
142     connectSignals(page);
143     m_stackedWidget->addWidget(page);
144     if (fromSearch) {
145         connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
146             SLOT(highlightSearchTerms()));
147      }
148 }
149
150 void CentralWidget::removePage(int index)
151 {
152     const bool currentChanged = (index == currentIndex());
153     m_stackedWidget->removeWidget(m_stackedWidget->widget(index));
154     if (currentChanged)
155         emit currentViewerChanged();
156 }
157
158 int CentralWidget::currentIndex() const
159 {
160     return  m_stackedWidget->currentIndex();
161 }
162
163 void CentralWidget::setCurrentPage(HelpViewer *page)
164 {
165     m_stackedWidget->setCurrentWidget(page);
166     emit currentViewerChanged();
167 }
168
169 bool CentralWidget::find(const QString &txt, Find::FindFlags flags,
170     bool incremental)
171 {
172     return currentHelpViewer()->findText(txt, flags, incremental, false);
173 }
174
175 // -- public slots
176
177 void CentralWidget::copy()
178 {
179     if (HelpViewer* viewer = currentHelpViewer())
180         viewer->copy();
181 }
182
183 void CentralWidget::home()
184 {
185     if (HelpViewer* viewer = currentHelpViewer())
186         viewer->home();
187 }
188
189 void CentralWidget::zoomIn()
190 {
191     HelpViewer* viewer = currentHelpViewer();
192     if (viewer)
193         viewer->scaleUp();
194 }
195
196 void CentralWidget::zoomOut()
197 {
198     HelpViewer* viewer = currentHelpViewer();
199     if (viewer)
200         viewer->scaleDown();
201 }
202
203 void CentralWidget::resetZoom()
204 {
205     HelpViewer* viewer = currentHelpViewer();
206     if (viewer)
207         viewer->resetScale();
208 }
209
210 void CentralWidget::forward()
211 {
212     if (HelpViewer* viewer = currentHelpViewer())
213         viewer->forward();
214 }
215
216 void CentralWidget::nextPage()
217 {
218     m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() + 1)
219         % m_stackedWidget->count());
220 }
221
222 void CentralWidget::backward()
223 {
224     if (HelpViewer* viewer = currentHelpViewer())
225         viewer->backward();
226 }
227
228 void CentralWidget::previousPage()
229 {
230     m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() - 1)
231         % m_stackedWidget->count());
232 }
233
234 void CentralWidget::print()
235 {
236 #ifndef QT_NO_PRINTER
237     if (HelpViewer* viewer = currentHelpViewer()) {
238         initPrinter();
239
240         QPrintDialog dlg(printer, this);
241         dlg.setWindowTitle(tr("Print Document"));
242         if (!viewer->selectedText().isEmpty())
243             dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
244         dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
245         dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
246
247         if (dlg.exec() == QDialog::Accepted)
248             viewer->print(printer);
249     }
250 #endif
251 }
252
253 void CentralWidget::pageSetup()
254 {
255 #ifndef QT_NO_PRINTER
256     initPrinter();
257     QPageSetupDialog dlg(printer);
258     dlg.exec();
259 #endif
260 }
261
262 void CentralWidget::printPreview()
263 {
264 #ifndef QT_NO_PRINTER
265     initPrinter();
266     QPrintPreviewDialog preview(printer, this);
267     connect(&preview, SIGNAL(paintRequested(QPrinter*)),
268         SLOT(printPreview(QPrinter*)));
269     preview.exec();
270 #endif
271 }
272
273 void CentralWidget::setSource(const QUrl &url)
274 {
275     if (HelpViewer* viewer = currentHelpViewer()) {
276         viewer->setSource(url);
277         viewer->setFocus(Qt::OtherFocusReason);
278     }
279 }
280
281 void CentralWidget::setSourceFromSearch(const QUrl &url)
282 {
283     if (HelpViewer* viewer = currentHelpViewer()) {
284         connect(viewer, SIGNAL(loadFinished(bool)), this,
285             SLOT(highlightSearchTerms()));
286         viewer->setSource(url);
287         viewer->setFocus(Qt::OtherFocusReason);
288     }
289 }
290
291 void CentralWidget::showTopicChooser(const QMap<QString, QUrl> &links,
292     const QString &keyword)
293 {
294     TopicChooser tc(this, keyword, links);
295     if (tc.exec() == QDialog::Accepted)
296         setSource(tc.link());
297 }
298
299 // -- protected
300
301 void CentralWidget::focusInEvent(QFocusEvent * /* event */)
302 {
303     // If we have a current help viewer then this is the 'focus proxy',
304     // otherwise it's the central widget. This is needed, so an embedding
305     // program can just set the focus to the central widget and it does
306     // The Right Thing(TM)
307     QObject *receiver = m_stackedWidget;
308     if (HelpViewer *viewer = currentHelpViewer())
309         receiver = viewer;
310     QTimer::singleShot(1, receiver, SLOT(setFocus()));
311 }
312
313 // -- private slots
314
315 void CentralWidget::highlightSearchTerms()
316 {
317     if (HelpViewer *viewer = currentHelpViewer()) {
318         QHelpSearchEngine *searchEngine = 
319             LocalHelpManager::helpEngine().searchEngine();
320         QList<QHelpSearchQuery> queryList = searchEngine->query();
321
322         QStringList terms;
323         foreach (const QHelpSearchQuery &query, queryList) {
324             switch (query.fieldName) {
325                 default: break;
326                 case QHelpSearchQuery::ALL: {
327                 case QHelpSearchQuery::PHRASE:
328                 case QHelpSearchQuery::DEFAULT:
329                 case QHelpSearchQuery::ATLEAST:
330                     foreach (QString term, query.wordList)
331                         terms.append(term.remove(QLatin1String("\"")));
332                 }
333             }
334         }
335
336         foreach (const QString& term, terms)
337             viewer->findText(term, 0, false, true);
338         disconnect(viewer, SIGNAL(loadFinished(bool)), this,
339             SLOT(highlightSearchTerms()));
340     }
341 }
342
343 void CentralWidget::printPreview(QPrinter *p)
344 {
345 #ifndef QT_NO_PRINTER
346     HelpViewer *viewer = currentHelpViewer();
347     if (viewer)
348         viewer->print(p);
349 #else
350     Q_UNUSED(p)
351 #endif
352 }
353
354 void CentralWidget::handleSourceChanged(const QUrl &url)
355 {
356     if (sender() == currentHelpViewer())
357         emit sourceChanged(url);
358 }
359
360 // -- private
361
362 void CentralWidget::initPrinter()
363 {
364 #ifndef QT_NO_PRINTER
365     if (!printer)
366         printer = new QPrinter(QPrinter::HighResolution);
367 #endif
368 }
369
370 void CentralWidget::connectSignals(HelpViewer *page)
371 {
372     connect(page, SIGNAL(sourceChanged(QUrl)), this, SLOT(handleSourceChanged(QUrl)));
373     connect(page, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
374     connect(page, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
375     connect(page, SIGNAL(printRequested()), this, SLOT(print()));
376     connect(page, SIGNAL(openFindToolBar()), this, SIGNAL(openFindToolBar()));
377 }
378
379 bool CentralWidget::eventFilter(QObject *object, QEvent *e)
380 {
381     if (e->type() != QEvent::KeyPress)
382         return QWidget::eventFilter(object, e);
383
384     HelpViewer *viewer = currentHelpViewer();
385     QKeyEvent *keyEvent = static_cast<QKeyEvent*> (e);
386     if (viewer == object && keyEvent->key() == Qt::Key_Backspace) {
387         if (viewer->isBackwardAvailable()) {
388 #if !defined(QT_NO_WEBKIT)
389             // this helps in case there is an html <input> field
390             if (!viewer->hasFocus())
391 #endif
392                 viewer->backward();
393         }
394     }
395     return QWidget::eventFilter(object, e);
396 }