1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: QtxWebBrowser.cxx
24 // Author: Roman NIKOLAEV
26 #include "QtxWebBrowser.h"
27 #include "QtxSearchTool.h"
29 #include <QApplication>
33 #include <QMessageBox>
37 #include <QVBoxLayout>
40 \class WebViewSearcher
41 \brief A class is used with QtxSearchTool in order to search text within the web page
44 class WebViewSearcher : public QtxSearchTool::Searcher
47 WebViewSearcher( QWebView* );
50 bool find( const QString&, QtxSearchTool* );
51 bool findNext( const QString&, QtxSearchTool* );
52 bool findPrevious( const QString&, QtxSearchTool* );
53 bool findFirst( const QString&, QtxSearchTool* );
54 bool findLast( const QString&, QtxSearchTool* );
60 WebViewSearcher::WebViewSearcher( QWebView* view ) : myView( view )
64 WebViewSearcher::~WebViewSearcher()
68 bool WebViewSearcher::find( const QString& text, QtxSearchTool* st )
70 QWebPage::FindFlags fl = 0;
71 if ( st->isCaseSensitive() ) fl = fl | QWebPage::FindCaseSensitively;
72 if ( st->isSearchWrapped() ) fl = fl | QWebPage::FindWrapsAroundDocument;
73 return myView->findText( text, fl );
76 bool WebViewSearcher::findNext( const QString& text, QtxSearchTool* st )
78 return find( text, st );
81 bool WebViewSearcher::findPrevious( const QString& text, QtxSearchTool* st )
83 QWebPage::FindFlags fl = QWebPage::FindBackward;
84 if ( st->isCaseSensitive() ) fl = fl | QWebPage::FindCaseSensitively;
85 if ( st->isSearchWrapped() ) fl = fl | QWebPage::FindWrapsAroundDocument;
86 return myView->findText( text, fl );
89 bool WebViewSearcher::findFirst( const QString&, QtxSearchTool* )
94 bool WebViewSearcher::findLast( const QString&, QtxSearchTool* )
102 \brief The QtxWebBrowser provides a window that can display html pages.
104 Only one instance of the QtxWebBrowser class can be created. To access the browser
105 window, use static method QtxWebBrowser::webBrowser(), which creates an
106 instance of the QtxWebBrowser widget (if it is not yet created) and returns a
109 You should not destroy this instance - it is done automatically after
110 closing of the browser window. To close window programmatically use
113 To set visual properties of the browser use static method setData().
115 The following sample demonstrates how to use web browser.
116 In this code the browser window is created, /data/index.html file is opened
117 and scrolled to the "anchor1" anchor on this page.
120 int main(int argc, char *argv[])
122 QApplication app(argc, argv);
124 // set icon, title and menu items.
125 QtxWebBrowser::setData("browser:title", tr("Web Browser"));
126 QtxWebBrowser::setData("browser:icon", QPixmap(":/icon.png"));
127 QtxWebBrowser::setData("menu:file:title", tr("&File"));
128 QtxWebBrowser::setData("action:close:title", tr("&Close"));
131 QtxWebBrowser::loadUrl("file:///data/index.html", "anchor1");
139 //! The only one instance of web browser
140 QtxWebBrowser* QtxWebBrowser::myBrowser = 0;
142 //! Internal data map to store resources of the browser.
143 QMap<QString, QVariant> QtxWebBrowser::myData;
148 Construct the web browser.
150 QtxWebBrowser::QtxWebBrowser() : QMainWindow( 0 )
152 setAttribute( Qt::WA_DeleteOnClose );
155 QWidget* frame = new QWidget( this );
157 myWebView = new QWebView( frame );
159 QAction *copyAction = myWebView->pageAction(QWebPage::Copy);
160 copyAction->setShortcut(QKeySequence::Copy);
161 myWebView->addAction(copyAction);
164 myWebView->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
165 myFindPanel = new QtxSearchTool( frame, myWebView,
166 QtxSearchTool::Basic | QtxSearchTool::Case | QtxSearchTool::Wrap,
168 myFindPanel->setFrameStyle( QFrame::NoFrame | QFrame::Plain );
169 myFindPanel->setActivators( QtxSearchTool::SlashKey );
170 myFindPanel->setSearcher( new WebViewSearcher( myWebView ) );
171 myFindPanel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
173 myToolbar = addToolBar( tr( "Navigation" ) );
174 myToolbar->addAction( myWebView->pageAction( QWebPage::Back ) );
175 myToolbar->addAction( myWebView->pageAction( QWebPage::Forward ) );
177 myMenus[ File ] = menuBar()->addMenu( tr( "&File" ) );
178 myActions[ Find ] = myMenus[ File ]->addAction( tr( "&Find in text..." ), myFindPanel, SLOT( find() ), QKeySequence( QKeySequence::Find ) );
179 myActions[ FindNext ] = myMenus[ File ]->addAction( tr( "&Find next" ), myFindPanel, SLOT( findNext() ), QKeySequence( QKeySequence::FindNext ) );
180 myActions[ FindPrev ] = myMenus[ File ]->addAction( tr( "&Find previous" ), myFindPanel, SLOT( findPrevious() ), QKeySequence( QKeySequence::FindPrevious ) );
181 myMenus[ File ]->addSeparator();
182 myActions[ Close ] = myMenus[ File ]->addAction( tr( "&Close" ), this, SLOT( close() ) );
184 QVBoxLayout* main = new QVBoxLayout( frame );
185 main->addWidget( myWebView );
186 main->addWidget( myFindPanel );
187 main->setMargin( 0 );
188 main->setSpacing( 3 );
190 connect( myWebView, SIGNAL( titleChanged( QString ) ), SLOT( adjustTitle() ) );
191 connect( myWebView, SIGNAL( linkClicked( QUrl ) ), SLOT( linkClicked( QUrl ) ) );
192 connect( myWebView->page(), SIGNAL( linkHovered( QString, QString, QString ) ), SLOT( linkHovered( QString, QString, QString ) ) );
194 setCentralWidget( frame );
195 setFocusProxy( myWebView );
197 qAddPostRoutine( QtxWebBrowser::clearData );
203 QtxWebBrowser::~QtxWebBrowser()
209 \brief Return the only instance of the QtxWebBrowser
210 \return instance of the QtxWebBrowser
212 QtxWebBrowser* QtxWebBrowser::webBrowser()
215 myBrowser = new QtxWebBrowser();
220 \brief Load given url address and optional scroll to the specified anchor
221 \param url an url address to load
222 \param anchor an anchor to scroll page to
224 void QtxWebBrowser::loadUrl( const QString& url, const QString& anchor )
227 if( !anchor.isEmpty() ) anUrl += "#" + anchor;
228 anUrl.replace('\\', '/');
230 Qtx::alignWidget( webBrowser(), (QWidget*)QApplication::desktop(), Qtx::AlignCenter );
232 webBrowser()->show();
233 webBrowser()->myWebView->load( QUrl( anUrl ) );
234 webBrowser()->setFocus();
235 webBrowser()->activateWindow();
236 webBrowser()->raise();
240 \brief Set browser settings from.
242 This method can be used to setup the browser properties.
243 - \c "browser:title" : title of the browser window
244 - \c "browser:icon" : icon of the browser window
245 - \c "toolbar:title" : title of the toolbar
246 - \c "menu:file:title" : File menu of the browser
247 - \c "action:close:title" : File/Close menu item title
248 - \c "action:close:icon" : File/Close menu item icon
249 - \c "action:back:title" : Navigation/Back menu item title
250 - \c "action:back:icon" : Navigation/Back menu item icon
251 - \c "action:forward:title" : Navigation/Forward menu item title
252 - \c "action:forward:icon" : Navigation/Forward menu item icon
253 - \c "action:find:title" : File/Find menu item title
254 - \c "action:find:icon" : File/Find menu item icon
255 - \c "action:findnext:title" : File/Find Next menu item title
256 - \c "action:findnext:icon" : File/Find Next menu item icon
257 - \c "action:findprev:title" : File/Find Previous menu item title
258 - \c "action:findprev:icon" : File/Find Previous menu item icon
260 \param key name of the property
261 \param val value of the property
264 void QtxWebBrowser::setData( const QString& key, const QVariant& val )
266 myData.insert( key, val );
267 if ( myBrowser ) myBrowser->updateData();
271 \brief Get string value by key from the internal data map
272 \param key data key identifier
273 \return string value assigned to the key (null string if data is not assigned to the key)
276 QString QtxWebBrowser::getStringValue( const QString& key )
279 if ( myData.contains( key ) && myData[key].canConvert( QVariant::String ) )
280 val = myData[key].toString();
285 \brief Get icon value by key from the internal data map
286 \param key data key identifier
287 \return icon assigned to the key (null icon if data is not assigned to the key)
290 QIcon QtxWebBrowser::getIconValue(const QString& key)
293 if ( myData.contains( key ) ) {
294 if ( myData[key].canConvert( QVariant::Pixmap ) )
295 val = myData[key].value<QPixmap>();
296 else if ( myData[key].canConvert( QVariant::Icon ) )
297 val = myData[key].value<QIcon>();
303 \brief Update web browser properties from internal data map
305 void QtxWebBrowser::updateData()
311 QIcon icon = getIconValue( "browser:icon" );
312 if ( !icon.isNull() )
313 setWindowIcon( icon );
316 QString tbTitle = getStringValue( "toolbar:title" );
317 if ( myToolbar && !tbTitle.isEmpty() )
318 myToolbar->setWindowTitle( tbTitle );
321 QString fmenu = getStringValue( "menu:file:title" );
322 if ( myMenus.contains( File ) && !fmenu.isEmpty() )
323 myMenus[ File ]->setTitle( fmenu );
326 QString closeTlt = getStringValue( "action:close:title" );
327 QIcon closeIco = getIconValue( "action:close:icon" );
328 if ( myActions.contains( Close ) ) {
329 if ( !closeTlt.isEmpty() )
330 myActions[ Close ]->setText( closeTlt );
331 if ( !closeIco.isNull() )
332 myActions[ Close ]->setIcon( closeIco );
335 // Navigation/Go Back menu
336 QString backTlt = getStringValue( "action:back:title" );
337 QIcon backIco = getIconValue( "action:back:icon" );
338 if ( !backTlt.isEmpty() )
339 myWebView->pageAction( QWebPage::Back )->setText( backTlt );
340 if ( !backIco.isNull() )
341 myWebView->pageAction( QWebPage::Back )->setIcon( backIco );
343 // Navigation/Go Forward menu
344 QString fwdTlt = getStringValue( "action:forward:title" );
345 QIcon fwdIco = getIconValue( "action:forward:icon" );
346 if ( !fwdTlt.isEmpty() )
347 myWebView->pageAction( QWebPage::Forward )->setText( fwdTlt );
348 if ( !fwdIco.isNull() )
349 myWebView->pageAction( QWebPage::Forward )->setIcon( fwdIco );
352 QString findTlt = getStringValue( "action:find:title" );
353 QIcon findIco = getIconValue( "action:find:icon" );
354 if ( myActions.contains( Find ) ) {
355 if ( !findTlt.isEmpty() )
356 myActions[ Find ]->setText( findTlt );
357 if ( !findIco.isNull() )
358 myActions[ Find ]->setIcon( findIco );
361 // File/Find Next menu
362 QString findNextTlt = getStringValue( "action:findnext:title" );
363 QIcon findNextIco = getIconValue( "action:findnext:icon" );
364 if ( myActions.contains( FindNext ) ) {
365 if ( !findNextTlt.isEmpty() )
366 myActions[ FindNext ]->setText( findNextTlt );
367 if ( !findNextIco.isNull() )
368 myActions[ FindNext ]->setIcon( findNextIco );
371 // File/Find Previous menu
372 QString findPrevTlt = getStringValue( "action:findprev:title" );
373 QIcon findPrevIco = getIconValue( "action:findprev:icon" );
374 if ( myActions.contains( FindPrev ) ) {
375 if ( !findPrevTlt.isEmpty() )
376 myActions[ FindPrev ]->setText( findPrevTlt );
377 if ( !findPrevIco.isNull() )
378 myActions[ FindPrev ]->setIcon( findPrevIco );
383 \brief Clear internal data map
386 void QtxWebBrowser::clearData()
392 \brief Called when users activated any link at the page
393 \param url URL being clicked
396 void QtxWebBrowser::linkClicked( const QUrl& url )
398 myWebView->page()->setLinkDelegationPolicy( QWebPage::DontDelegateLinks );
399 myWebView->load( url );
400 if ( url.scheme() == "file" ) {
401 QString filename = url.toLocalFile();
402 if ( QFileInfo( filename ).suffix().toLower() == "pdf" ) {
405 i = ::system( QString( "start %2" ).arg( filename ).toLatin1().constData() );
407 // special processing of PDF files
409 readers << "xdg-open" << "acroread"<< "okular" << "evince" << "kpdf" << "kghostview" << "xpdf";
410 foreach ( QString r, readers ) {
411 QString reader = QString( "/usr/bin/%1" ).arg( r );
412 if ( QFileInfo( reader ).exists() ) {
413 // Warning: the test on the return value of ::system does not work if the command ends with '&'
414 i = ::system( QString( "%1 %2" ).arg( reader ).arg( url.toLocalFile() ).toLatin1().constData() );
416 // If Salome Qt version is lower than the system one, on KDE an unresolved symbol is raised
417 // In this case, we can try to launch the pdf viewer after unsetting the LD_LIBRARY_PATH environnement variable
418 i = ::system( QString( "unset LD_LIBRARY_PATH ; %1 %2" ).arg( reader ).arg( url.toLocalFile() ).toLatin1().constData() );
427 QMessageBox::warning(this, tr("Opening pdf file"), tr("Impossible to open the pdf file: no viewer found or compatible."));
431 myWebView->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
435 \brief Called when link is hovered
436 \param link link being hovered
437 \param title link title (if it is specified in the markup)
438 \param content provides text within the link element, e.g., text inside an HTML anchor tag
441 void QtxWebBrowser::linkHovered( const QString& link, const QString& /*title*/, const QString& /*context*/ )
443 statusBar()->showMessage( link );
447 \brief Update title of the window
450 void QtxWebBrowser::adjustTitle()
452 QString title = getStringValue( "browser:title" );
453 setWindowTitle( title.isEmpty() ? myWebView->title() : title + QString( " [%1]" ).arg( myWebView->title() ) );