PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/mks-svn4458/plugins/child/QtAssistant/src/QtAssistantViewer.cpp

#
C++ | 275 lines | 210 code | 44 blank | 21 comment | 47 complexity | 0888ebf6e8468534c44368d3b3d91610 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, LGPL-3.0, Zlib, AGPL-1.0
  1. /****************************************************************************
  2. Copyright (C) 2005 - 2011 Filipe AZEVEDO & The Monkey Studio Team
  3. http://monkeystudio.org licensing under the GNU GPL.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. ****************************************************************************/
  16. #include "QtAssistantViewer.h"
  17. #include "QtAssistantChild.h"
  18. #include <QHelpEngine>
  19. #include <QNetworkReply>
  20. #include <QTimer>
  21. #include <QDesktopServices>
  22. #include <QWebHistory>
  23. #include <QWheelEvent>
  24. class HelpNetworkReply : public QNetworkReply
  25. {
  26. public:
  27. HelpNetworkReply( const QNetworkRequest& request, const QByteArray& fileData );
  28. virtual void abort();
  29. virtual qint64 bytesAvailable() const
  30. { return data.length() +QNetworkReply::bytesAvailable(); }
  31. protected:
  32. virtual qint64 readData( char* data, qint64 maxlen );
  33. private:
  34. QByteArray data;
  35. qint64 origLen;
  36. };
  37. HelpNetworkReply::HelpNetworkReply( const QNetworkRequest& request, const QByteArray& fileData )
  38. : data( fileData ), origLen( fileData.length() )
  39. {
  40. setRequest( request );
  41. setOpenMode( QIODevice::ReadOnly );
  42. setHeader( QNetworkRequest::ContentTypeHeader, "text/html" );
  43. setHeader( QNetworkRequest::ContentLengthHeader, QByteArray::number( fileData.length() ) );
  44. QTimer::singleShot( 0, this, SIGNAL( metaDataChanged() ) );
  45. QTimer::singleShot( 0, this, SIGNAL( readyRead() ) );
  46. }
  47. void HelpNetworkReply::abort()
  48. {
  49. // nothing to do
  50. }
  51. qint64 HelpNetworkReply::readData( char* buffer, qint64 maxlen )
  52. {
  53. qint64 len = qMin( qint64( data.length() ), maxlen );
  54. if ( len )
  55. {
  56. qMemCopy( buffer, data.constData(), len );
  57. data.remove( 0, len );
  58. }
  59. if ( !data.length() )
  60. QTimer::singleShot( 0, this, SIGNAL( finished() ) );
  61. return len;
  62. }
  63. class HelpNetworkAccessManager : public QNetworkAccessManager
  64. {
  65. public:
  66. HelpNetworkAccessManager( QHelpEngine* engine, QObject* parent );
  67. protected:
  68. virtual QNetworkReply* createRequest( Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0 );
  69. private:
  70. QHelpEngine* mHelpEngine;
  71. };
  72. HelpNetworkAccessManager::HelpNetworkAccessManager( QHelpEngine* engine, QObject* parent )
  73. : QNetworkAccessManager( parent ), mHelpEngine( engine )
  74. {
  75. }
  76. QNetworkReply *HelpNetworkAccessManager::createRequest( Operation op, const QNetworkRequest& request, QIODevice* outgoingData )
  77. {
  78. const QString scheme = request.url().scheme();
  79. if ( scheme == QLatin1String( "qthelp" ) || scheme == QLatin1String( "about" ) )
  80. return new HelpNetworkReply( request, mHelpEngine->fileData( request.url() ) );
  81. return QNetworkAccessManager::createRequest( op, request, outgoingData );
  82. }
  83. class HelpPage : public QWebPage
  84. {
  85. public:
  86. HelpPage( QtAssistantChild* child, QObject* parent );
  87. protected:
  88. virtual QWebPage* createWindow( QWebPage::WebWindowType );
  89. virtual bool acceptNavigationRequest( QWebFrame* frame, const QNetworkRequest& request, NavigationType type );
  90. private:
  91. QtAssistantChild* mChild;
  92. };
  93. HelpPage::HelpPage( QtAssistantChild* child, QObject* parent )
  94. : QWebPage( parent ), mChild( child )
  95. {
  96. }
  97. QWebPage* HelpPage::createWindow( QWebPage::WebWindowType )
  98. {
  99. return mChild->newEmptyViewer()->page();
  100. }
  101. static bool isLocalUrl( const QUrl& url )
  102. {
  103. const QString scheme = url.scheme();
  104. if ( scheme.isEmpty()
  105. || scheme == QLatin1String( "file" )
  106. || scheme == QLatin1String( "qrc" )
  107. || scheme == QLatin1String( "data" )
  108. || scheme == QLatin1String( "qthelp" )
  109. || scheme == QLatin1String( "about" ) )
  110. return true;
  111. return false;
  112. }
  113. bool HelpPage::acceptNavigationRequest( QWebFrame*, const QNetworkRequest& request, QWebPage::NavigationType )
  114. {
  115. const QUrl url = request.url();
  116. if ( isLocalUrl( url ) )
  117. {
  118. return true;
  119. }
  120. else
  121. {
  122. //QDesktopServices::openUrl( url );
  123. return true;
  124. }
  125. }
  126. // QtAssistantViewer
  127. QtAssistantViewer::QtAssistantViewer( QHelpEngine* engine, QtAssistantChild* child, const QUrl& homeUrl )
  128. : QWebView( child )
  129. {
  130. Q_ASSERT( engine );
  131. Q_ASSERT( child );
  132. mEngine = engine;
  133. mChild = child;
  134. mHomeUrl = homeUrl;
  135. setPage( new HelpPage( mChild, this ) );
  136. page()->setNetworkAccessManager( new HelpNetworkAccessManager( engine, this ) );
  137. pageAction( QWebPage::OpenLinkInNewWindow )->setText( tr( "Open Link in New Tab" ) );
  138. pageAction( QWebPage::DownloadLinkToDisk )->setVisible( false );
  139. pageAction( QWebPage::DownloadImageToDisk )->setVisible( false );
  140. pageAction( QWebPage::OpenImageInNewWindow )->setVisible( false );
  141. connect( pageAction( QWebPage::Copy ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  142. connect( pageAction( QWebPage::Cut ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  143. connect( pageAction( QWebPage::Paste ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  144. connect( pageAction( QWebPage::Undo ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  145. connect( pageAction( QWebPage::Redo ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  146. connect( pageAction( QWebPage::Back ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  147. connect( pageAction( QWebPage::Forward ), SIGNAL( changed() ), this, SLOT( actionChanged() ) );
  148. connect( page(), SIGNAL( linkHovered( const QString&, const QString&, const QString& ) ), this, SIGNAL( highlighted( const QString& ) ) );
  149. connect( this, SIGNAL( loadFinished( bool ) ), this, SLOT( loadFinished( bool ) ) );
  150. }
  151. void QtAssistantViewer::setSource( const QUrl& url )
  152. {
  153. mHomeUrl = mHomeUrl.isValid() ? mHomeUrl : url;
  154. load( url );
  155. }
  156. void QtAssistantViewer::resetZoom()
  157. {
  158. setTextSizeMultiplier( 1.0 );
  159. }
  160. void QtAssistantViewer::zoomIn( int range )
  161. {
  162. Q_UNUSED( range );
  163. setTextSizeMultiplier( textSizeMultiplier() +.5 );
  164. }
  165. void QtAssistantViewer::zoomOut( int range )
  166. {
  167. Q_UNUSED( range );
  168. setTextSizeMultiplier( textSizeMultiplier() -.5 );
  169. }
  170. void QtAssistantViewer::home()
  171. {
  172. if ( history()->canGoBack() )
  173. {
  174. history()->goToItem( history()->backItems( history()->count() ).first() );
  175. }
  176. }
  177. void QtAssistantViewer::wheelEvent( QWheelEvent* e )
  178. {
  179. if ( e->modifiers() & Qt::ControlModifier )
  180. {
  181. const int delta = e->delta();
  182. if ( delta > 0 )
  183. zoomOut();
  184. else if ( delta < 0 )
  185. zoomIn();
  186. e->accept();
  187. return;
  188. }
  189. QWebView::wheelEvent( e );
  190. }
  191. void QtAssistantViewer::mouseReleaseEvent( QMouseEvent* e )
  192. {
  193. if ( e->button() == Qt::XButton1 )
  194. {
  195. triggerPageAction( QWebPage::Back );
  196. return;
  197. }
  198. if ( e->button() == Qt::XButton2 )
  199. {
  200. triggerPageAction( QWebPage::Forward );
  201. return;
  202. }
  203. QWebView::mouseReleaseEvent( e );
  204. }
  205. void QtAssistantViewer::actionChanged()
  206. {
  207. QAction* a = qobject_cast<QAction*>( sender() );
  208. if ( a == pageAction( QWebPage::Copy ) )
  209. emit copyAvailable( a->isEnabled() );
  210. else if ( a == pageAction( QWebPage::Cut ) )
  211. emit cutAvailable( a->isEnabled() );
  212. else if ( a == pageAction( QWebPage::Paste ) )
  213. emit pasteAvailable( a->isEnabled() );
  214. else if ( a == pageAction( QWebPage::Undo ) )
  215. emit undoAvailable( a->isEnabled() );
  216. else if ( a == pageAction( QWebPage::Redo ) )
  217. emit redoAvailable( a->isEnabled() );
  218. else if ( a == pageAction( QWebPage::Back ) )
  219. emit backwardAvailable( a->isEnabled() );
  220. else if ( a == pageAction( QWebPage::Forward ) )
  221. emit forwardAvailable( a->isEnabled() );
  222. emit actionsChanged();
  223. }
  224. void QtAssistantViewer::loadFinished( bool ok )
  225. {
  226. Q_UNUSED( ok );
  227. emit sourceChanged( url() );
  228. }