OSDN Git Service

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