web_widget.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2012, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 
00033 import os
00034 import rospkg
00035 
00036 from python_qt_binding import loadUi
00037 from python_qt_binding.QtCore import Qt, QUrl
00038 from python_qt_binding.QtGui import QIcon
00039 try:
00040     # Qt 5.6 and higher
00041     from python_qt_binding.QtWebEngine import QWebEnginePage as QWebPage
00042     from python_qt_binding.QtWebEngine import QWebEngineView as QWebView
00043 except ImportError:
00044     try:
00045         # Qt 5.0 - 5.5
00046         from python_qt_binding.QtWebKitWidgets import QWebPage, QWebView
00047     except ImportError:
00048         # Qt 4
00049         from python_qt_binding.QtWebKit import QWebPage, QWebView
00050 from python_qt_binding.QtWidgets import QCompleter, QWidget
00051 
00052 
00053 def is_string(s):
00054     """Check if the argument is a string which works for both Python 2 and 3."""
00055     try:
00056         return isinstance(s, basestring)
00057     except NameError:
00058         return isinstance(s, str)
00059 
00060 
00061 class WebWidget(QWidget):
00062     def __init__(self, url=None):
00063         """
00064         Class to load a webpage in a widget.
00065 
00066         :param url: If url is empty then a navigation bar is shown otherwise the url is loaded and the navigation bar is hidden, ''str''
00067         """
00068         super(WebWidget, self).__init__()
00069         rp = rospkg.RosPack()
00070         ui_file = os.path.join(rp.get_path('rqt_web'), 'resource', 'web_widget.ui')
00071         loadUi(ui_file, self)
00072         self.setObjectName('WebWidget')
00073 
00074         self._loading = False
00075         self._stop_icon = QIcon.fromTheme('process-stop')
00076         self._reload_icon = QIcon.fromTheme('view-refresh')
00077         self._working_icon = QIcon.fromTheme('process-working')
00078 
00079         self._completer_word_list = ['']
00080         self._view = QWebView()
00081         self.verticalLayout.addWidget(self._view)
00082         if url is None:
00083             self.set_url("http://ros.org", True)
00084         else:
00085             self.set_url(url, False)
00086 
00087         self.url_lineedit.returnPressed.connect(self._handle_url_change)
00088         self._view.loadFinished[bool].connect(self._handle_load_finished)
00089         self.reload_button.clicked.connect(self._handle_reload_clicked)
00090         self._view.linkClicked.connect(self._handle_link_clicked)
00091         self._view.urlChanged[QUrl].connect(self._handle_url_changed)
00092 
00093     def set_url(self, url, showinput=False):
00094         """
00095         Sets the url and begins loading that page
00096         :param url: url to load in the webview, ''str or QUrl''
00097         :param showinput: if true the input bar will be shown, else hidden, ''bool''
00098         """
00099         if url is not None:
00100             self._url = QUrl(url)
00101             self.set_show_url_input(showinput)
00102             self._view.setUrl(self._url)
00103 
00104     def set_show_url_input(self, showinput):
00105         """
00106         Sets the value of the show_url_input flag and hides/shows the widgets as required
00107         :param showinput: true - show inputbar false - hide , ''bool''
00108         """
00109         self._show_url_input = showinput
00110         self.url_lineedit.setVisible(self._show_url_input)
00111         self.reload_button.setVisible(self._show_url_input)
00112         if self._show_url_input:
00113             self._view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
00114         else:
00115             self._view.page().setLinkDelegationPolicy(QWebPage.DontDelegateLinks)
00116 
00117     def save_settings(self, settings):
00118         settings.set_value('url_completion', self._pack(self._completer_word_list))
00119         settings.set_value('url_current', self._url.toString())
00120 
00121     def restore_settings(self, settings):
00122         self._completer_word_list += self._unpack(settings.value('url_completion'))
00123         self._completer_word_list = list(set(self._completer_word_list))
00124         url = settings.value('url_current')
00125         if url:
00126             self.set_url(url, self._show_url_input)
00127 
00128     def _handle_url_change(self):
00129         self.set_url(self.url_lineedit.text(), True)
00130 
00131     def _handle_link_clicked(self, url):
00132         self.set_url(url, True)
00133 
00134     def _handle_reload_clicked(self):
00135         if self._loading:
00136             self._view.stop()
00137             self._loading = False
00138             self.reload_button.setIcon(self._reload_icon)
00139         else:
00140             self._view.reload()
00141             self._loading = True
00142             self.reload_button.setIcon(self._stop_icon)
00143 
00144     def _handle_url_changed(self, url):
00145         # set text to the current loading item
00146         self.url_lineedit.setText(url.toString())
00147         self.reload_button.setIcon(self._stop_icon)
00148         self._loading = True
00149 
00150     def _handle_load_finished(self, ok):
00151         self._loading = False
00152         self.reload_button.setIcon(self._reload_icon)
00153         if ok:
00154             self._add_completer_list_item(self._url.toString())
00155         else:
00156             # need to disconnect or we will resend the signal once the error page loads
00157             self._view.loadFinished[bool].disconnect(self._handle_load_finished)
00158             self._view.page().currentFrame().setHtml('<html><h2>The url you entered seems to be faulty.</h2></html>')
00159             self._view.loadFinished[bool].connect(self._handle_load_finished)
00160 
00161     def _add_completer_list_item(self, url):
00162         self._completer_word_list.append(self.url_lineedit.text())
00163         self._completer_word_list = list(set(self._completer_word_list))
00164         self._completer = QCompleter(self._completer_word_list)
00165         self._completer.setCaseSensitivity(Qt.CaseInsensitive)
00166         self._completer.setCompletionMode(QCompleter.PopupCompletion)
00167         self.url_lineedit.setCompleter(self._completer)
00168 
00169     @staticmethod
00170     def _pack(data):
00171         """
00172         Packs 'data' into a form that can be easily and readably written to an ini file
00173         :param data: A list of strings to be flattened into a string ''list''
00174         :return: A string suitable for output to ini files ''str''
00175         """
00176         if len(data) == 0:
00177             return ''
00178         if len(data) == 1:
00179             return data[0]
00180         return data
00181 
00182     @staticmethod
00183     def _unpack(data):
00184         """
00185         Unpacks the values read from an ini file
00186         :param data: An entry taken from an ini file ''list or string''
00187         :return: A list of strings ''list''
00188         """
00189         if data is None or data == '':
00190             data = []
00191         elif is_string(data):
00192             data = [data]
00193         return data


rqt_web
Author(s): Aaron Blasdel
autogenerated on Wed May 3 2017 02:53:57