[Pkg-privacy-commits] [torbrowser-launcher] 08/39: Refactor Launcher to use Qt5, removing all of gtk2 (does not execute yet still because of twisted issues)

Roger Shimizu rosh at debian.org
Tue Mar 27 15:41:51 UTC 2018


This is an automated email from the git hooks/post-receive script.

rosh pushed a commit to branch rosh/experimental
in repository torbrowser-launcher.

commit f7cc20d62f518de56ef1ca5818826cbc1a782f67
Author: Micah Lee <micah at micahflee.com>
Date:   Thu Mar 22 14:21:23 2018 -0700

    Refactor Launcher to use Qt5, removing all of gtk2 (does not execute yet still because of twisted issues)
---
 torbrowser_launcher/__init__.py |   2 +-
 torbrowser_launcher/launcher.py | 377 ++++++++++++++++++----------------------
 2 files changed, 169 insertions(+), 210 deletions(-)

diff --git a/torbrowser_launcher/__init__.py b/torbrowser_launcher/__init__.py
index c22b336..0f99d05 100644
--- a/torbrowser_launcher/__init__.py
+++ b/torbrowser_launcher/__init__.py
@@ -34,7 +34,7 @@ from PyQt5 import QtCore, QtWidgets
 
 from .common import Common, SHARE
 from .settings import Settings
-#from .launcher import Launcher
+from .launcher import Launcher
 
 
 class Application(QtWidgets.QApplication):
diff --git a/torbrowser_launcher/launcher.py b/torbrowser_launcher/launcher.py
index b51d23d..4e27228 100644
--- a/torbrowser_launcher/launcher.py
+++ b/torbrowser_launcher/launcher.py
@@ -26,8 +26,6 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 """
 
-from __future__ import print_function
-
 import os
 import subprocess
 import time
@@ -55,9 +53,7 @@ import xml.etree.ElementTree as ET
 
 import OpenSSL
 
-import pygtk
-pygtk.require('2.0')
-import gtk
+from PyQt5 import QtCore, QtWidgets, QtGui
 
 
 class TryStableException(Exception):
@@ -76,46 +72,47 @@ class DownloadErrorException(Exception):
     pass
 
 
-class Launcher:
+class Launcher(QtWidgets.QMainWindow):
+    """
+    Launcher window.
+    """
     def __init__(self, common, app, url_list):
+        super(Launcher, self).__init__()
         self.common = common
         self.app = app
-        
+
         self.url_list = url_list
         self.force_redownload = False
 
-        # this is the current version of Tor Browser, which should get updated with every release
-        self.min_version = '6.0.2'
+        # This is the current version of Tor Browser, which should get updated with every release
+        self.min_version = '7.5.2'
 
-        # init launcher
-        self.set_gui(None, '', [])
+        # Init launcher
+        self.set_state(None, '', [])
         self.launch_gui = True
 
-        # if Tor Browser is not installed, detect latest version, download, and install
+        # If Tor Browser is not installed, detect latest version, download, and install
         if not self.common.settings['installed'] or not self.check_min_version():
-            # if downloading over Tor, include txsocksx
+            # If downloading over Tor, include txsocksx
             if self.common.settings['download_over_tor']:
                 try:
                     import txsocksx
                     print(_('Downloading over Tor'))
                 except ImportError:
-                    md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _("The python-txsocksx package is missing, downloads will not happen over tor"))
-                    md.set_position(gtk.WIN_POS_CENTER)
-                    md.run()
-                    md.destroy()
+                    Alert(self.common, _("The python-txsocksx package is missing, downloads will not happen over tor"))
                     self.common.settings['download_over_tor'] = False
                     self.common.save_settings()
 
-            # different message if downloading for the first time, or because your installed version is too low
+            # Different message if downloading for the first time, or because your installed version is too low
             download_message = ""
             if not self.common.settings['installed']:
                 download_message = _("Downloading and installing Tor Browser for the first time.")
             elif not self.check_min_version():
                 download_message = _("Your version of Tor Browser is out-of-date. Downloading and installing the newest version.")
 
-            # download and install
+            # Download and install
             print(download_message)
-            self.set_gui('task', download_message,
+            self.set_state('task', download_message,
                          ['download_version_check',
                           'set_version',
                           'download_sig',
@@ -130,150 +127,121 @@ class Launcher:
             self.launch_gui = False
 
         if self.launch_gui:
-            # build the rest of the UI
-            self.build_ui()
-
-    def configure_window(self):
-        if not hasattr(self, 'window'):
-            self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-            self.window.set_title(_("Tor Browser"))
-            self.window.set_icon_from_file(self.common.paths['icon_file'])
-            self.window.set_position(gtk.WIN_POS_CENTER)
-            self.window.set_border_width(10)
-            self.window.connect("delete_event", self.delete_event)
-            self.window.connect("destroy", self.destroy)
-
-    # there are different GUIs that might appear, this sets which one we want
-    def set_gui(self, gui, message, tasks, autostart=True):
+            # Build the rest of the UI
+
+            # Set up the window
+            self.setWindowTitle(_("Tor Browser"))
+            self.setWindowIcon(QtGui.QIcon(self.common.paths['icon_file']))
+
+            # Label
+            self.label = QtWidgets.QLabel()
+
+            # Progress bar
+            self.progress_bar = QtWidgets.QProgressBar()
+            self.progress_bar.setTextVisible(True)
+            self.progress_bar.setMinimum(0)
+            self.progress_bar.setMaximum(0)
+            self.progress_bar.setValue(0)
+
+            # Buttons
+            self.yes_button = QtWidgets.QPushButton()
+            self.yes_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton))
+            self.yes_button.clicked.connect(self.yes_clicked)
+            self.start_button = QtWidgets.QPushButton()
+            self.start_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton))
+            self.start_button.clicked.connect(self.start)
+            self.cancel_button = QtWidgets.QPushButton()
+            self.start_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton))
+            self.cancel_button.clicked.connect(self.close)
+            buttons_layout = QtWidgets.QHBoxLayout()
+            buttons_layout.addWidget(self.start_button)
+            buttons_layout.addWidget(self.cancel_button)
+
+            # Layout
+            layout = QtWidgets.QVBoxLayout()
+            layout.addWidget(self.label)
+            layout.addWidget(self.progress_bar)
+            layout.addLayout(buttons_layout)
+
+            central_widget = QtWidgets.QWidget()
+            central_widget.setLayout(layout)
+            self.setCentralWidget(central_widget)
+            self.show()
+
+            self.update()
+
+    # Set the current state of Tor Browser Launcher
+    def set_state(self, gui, message, tasks, autostart=True):
         self.gui = gui
         self.gui_message = message
         self.gui_tasks = tasks
         self.gui_task_i = 0
         self.gui_autostart = autostart
 
-    # set all gtk variables to False
-    def clear_ui(self):
-        if hasattr(self, 'box') and hasattr(self.box, 'destroy'):
-            self.box.destroy()
-        self.box = False
-
-        self.label = False
-        self.progressbar = False
-        self.button_box = False
-        self.start_button = False
-        self.exit_button = False
-
-    # build the application's UI
-    def build_ui(self):
-        self.clear_ui()
-
-        self.box = gtk.VBox(False, 20)
-        self.configure_window()
-        self.window.add(self.box)
+    # Show and hide parts of the UI based on the current state
+    def update(self):
+        # Hide widgets
+        self.progress_bar.hide()
+        self.yes_button.hide()
+        self.start_button.hide()
 
         if 'error' in self.gui:
-            # labels
-            self.label = gtk.Label(self.gui_message)
-            self.label.set_line_wrap(True)
-            self.box.pack_start(self.label, True, True, 0)
-            self.label.show()
-
-            # button box
-            self.button_box = gtk.HButtonBox()
-            self.button_box.set_layout(gtk.BUTTONBOX_SPREAD)
-            self.box.pack_start(self.button_box, True, True, 0)
-            self.button_box.show()
+            # Label
+            self.label.setText(self.gui_message)
 
+            # Yes button
             if self.gui != 'error':
-                # yes button
-                yes_image = gtk.Image()
-                yes_image.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
-                self.yes_button = gtk.Button("Yes")
-                self.yes_button.set_image(yes_image)
-                if self.gui == 'error_try_stable':
-                    self.yes_button.connect("clicked", self.try_stable, None)
-                elif self.gui == 'error_try_default_mirror':
-                    self.yes_button.connect("clicked", self.try_default_mirror, None)
-                elif self.gui == 'error_try_forcing_english':
-                    self.yes_button.connect("clicked", self.try_forcing_english, None)
-                elif self.gui == 'error_try_tor':
-                    self.yes_button.connect("clicked", self.try_tor, None)
-                self.button_box.add(self.yes_button)
+                self.yes_button.setText(_('Yes'))
                 self.yes_button.show()
 
-            # exit button
-            exit_image = gtk.Image()
-            exit_image.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_BUTTON)
-            self.exit_button = gtk.Button("Exit")
-            self.exit_button.set_image(exit_image)
-            self.exit_button.connect("clicked", self.destroy, None)
-            self.button_box.add(self.exit_button)
-            self.exit_button.show()
+            # Exit button
+            self.cancel_button.setText(_('Exit'))
 
         elif self.gui == 'task':
-            # label
-            self.label = gtk.Label(self.gui_message)
-            self.label.set_line_wrap(True)
-            self.box.pack_start(self.label, True, True, 0)
-            self.label.show()
-
-            # progress bar
-            self.progressbar = gtk.ProgressBar(adjustment=None)
-            self.progressbar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT)
-            self.progressbar.set_pulse_step(0.01)
-            self.box.pack_start(self.progressbar, True, True, 0)
-
-            # button box
-            self.button_box = gtk.HButtonBox()
-            self.button_box.set_layout(gtk.BUTTONBOX_SPREAD)
-            self.box.pack_start(self.button_box, True, True, 0)
-            self.button_box.show()
-
-            # start button
-            start_image = gtk.Image()
-            start_image.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
-            self.start_button = gtk.Button(_("Start"))
-            self.start_button.set_image(start_image)
-            self.start_button.connect("clicked", self.start, None)
-            self.button_box.add(self.start_button)
+            # Label
+            self.label.setText(self.gui_message)
+
+            # Progress bar
+            self.progress_bar.show()
+
+            # Start button
             if not self.gui_autostart:
                 self.start_button.show()
 
-            # exit button
-            exit_image = gtk.Image()
-            exit_image.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_BUTTON)
-            self.exit_button = gtk.Button(_("Cancel"))
-            self.exit_button.set_image(exit_image)
-            self.exit_button.connect("clicked", self.destroy, None)
-            self.button_box.add(self.exit_button)
-            self.exit_button.show()
-
-        self.box.show()
-        self.window.show()
+            # Cancel button
+            self.cancel_button.setText(_('Cancel'))
 
         if self.gui_autostart:
             self.start(None)
 
-    # start button clicked, begin tasks
+    # Yes button clicked, based on the state decide what to do
+    def yes_clicked(self):
+        if self.gui == 'error_try_stable':
+            self.try_stable()
+        elif self.gui == 'error_try_default_mirror':
+            self.try_default_mirror()
+        elif self.gui == 'error_try_forcing_english':
+            self.try_forcing_english()
+        elif self.gui == 'error_try_tor':
+            self.try_tor()
+
+    # Start button clicked, begin tasks
     def start(self, widget, data=None):
-        # disable the start button
-        if self.start_button:
-            self.start_button.set_sensitive(False)
+        # Hide the start button
+        self.start_button.hide()
 
-        # start running tasks
+        # Start running tasks
         self.run_task()
 
-    # run the next task in the task list
+    # Run the next task in the task list
     def run_task(self):
-        self.refresh_gtk()
-
         if self.gui_task_i >= len(self.gui_tasks):
-            self.destroy(False)
+            self.close()
             return
 
         task = self.gui_tasks[self.gui_task_i]
 
-        # get ready for the next task
+        # Get ready for the next task
         self.gui_task_i += 1
 
         if task == 'download_version_check':
@@ -287,9 +255,8 @@ class Launcher:
                 print(_('Latest version: {}').format(version))
                 self.run_task()
             else:
-                self.set_gui('error', _("Error detecting Tor Browser version."), [], False)
-                self.clear_ui()
-                self.build_ui()
+                self.set_state('error', _("Error detecting Tor Browser version."), [], False)
+                self.update()
 
         elif task == 'download_sig':
             print(_('Downloading'), self.common.paths['sig_url'].format(self.common.settings['mirror']))
@@ -351,7 +318,7 @@ class Launcher:
                 self.file.write(bytes)
                 self.so_far += len(bytes)
                 percent = float(self.so_far) / float(self.total)
-                self.progress.set_fraction(percent)
+                self.progress.setValue(percent)
                 amount = float(self.so_far)
                 units = "bytes"
                 for (size, unit) in [(1024 * 1024, "MiB"), (1024, "KiB")]:
@@ -360,7 +327,7 @@ class Launcher:
                         amount /= float(size)
                         break
 
-                self.progress.set_text(_('Downloaded')+(' %2.1f%% (%2.1f %s)' % ((percent * 100.0), amount, units)))
+                self.progress.setFormat(_('Downloaded')+(' %2.1f%% (%2.1f %s)' % ((percent * 100.0), amount, units)))
 
             def connectionLost(self, reason):
                 self.all_done(reason)
@@ -371,7 +338,7 @@ class Launcher:
             url = None
 
         dl = FileDownloader(
-            self.common, self.file_download, url, response.length, self.progressbar, self.response_finished
+            self.common, self.file_download, url, response.length, self.progress_bar, self.response_finished
         )
         response.deliverBody(dl)
 
@@ -393,41 +360,41 @@ class Launcher:
 
         if isinstance(f.value, TryStableException):
             f.trap(TryStableException)
-            self.set_gui('error_try_stable', str(f.value), [], False)
+            self.set_state('error_try_stable', str(f.value), [], False)
 
         elif isinstance(f.value, TryDefaultMirrorException):
             f.trap(TryDefaultMirrorException)
-            self.set_gui('error_try_default_mirror', str(f.value), [], False)
+            self.set_state('error_try_default_mirror', str(f.value), [], False)
 
         elif isinstance(f.value, TryForcingEnglishException):
             f.trap(TryForcingEnglishException)
-            self.set_gui('error_try_forcing_english', str(f.value), [], False)
+            self.set_state('error_try_forcing_english', str(f.value), [], False)
 
         elif isinstance(f.value, DownloadErrorException):
             f.trap(DownloadErrorException)
-            self.set_gui('error', str(f.value), [], False)
+            self.set_state('error', str(f.value), [], False)
 
         elif isinstance(f.value, DNSLookupError):
             f.trap(DNSLookupError)
             if common.settings['mirror'] != common.default_mirror:
-                self.set_gui('error_try_default_mirror', (_("DNS Lookup Error") + "\n\n" +
+                self.set_state('error_try_default_mirror', (_("DNS Lookup Error") + "\n\n" +
                                                           _("You are currently using a non-default mirror")
                                                           + ":\n{0}\n\n"
                                                           + _("Would you like to switch back to the default?")
                                                           ).format(common.settings['mirror']), [], False)
             else:
-                self.set_gui('error', str(f.value), [], False)
+                self.set_state('error', str(f.value), [], False)
 
         elif isinstance(f.value, ResponseFailed):
             for reason in f.value.reasons:
                 if isinstance(reason.value, OpenSSL.SSL.Error):
                     # TODO: add the ability to report attack by posting bug to trac.torproject.org
                     if not self.common.settings['download_over_tor']:
-                        self.set_gui('error_try_tor',
+                        self.set_state('error_try_tor',
                                      _('The SSL certificate served by https://www.torproject.org is invalid! You may '
                                        'be under attack.') + " " + _('Try the download again using Tor?'), [], False)
                     else:
-                        self.set_gui('error', _('The SSL certificate served by https://www.torproject.org is invalid! '
+                        self.set_state('error', _('The SSL certificate served by https://www.torproject.org is invalid! '
                                                 'You may be under attack.'), [], False)
 
         elif isinstance(f.value, ConnectionRefusedError) and self.common.settings['download_over_tor']:
@@ -435,29 +402,25 @@ class Launcher:
             # connect to the SOCKS server.  If the connection fails at the
             # remote end, we'll get txsocksx.errors.ConnectionRefused.
             addr = self.common.settings['tor_socks_address']
-            self.set_gui('error', _("Error connecting to Tor at {0}").format(addr), [], False)
+            self.set_state('error', _("Error connecting to Tor at {0}").format(addr), [], False)
 
         else:
-            self.set_gui('error', _("Error starting download:\n\n{0}\n\nAre you connected to the internet?").format(f.value), [], False)
+            self.set_state('error', _("Error starting download:\n\n{0}\n\nAre you connected to the internet?").format(f.value), [], False)
 
-        self.build_ui()
+        self.update()
 
     def download(self, name, url, path):
-        # keep track of current download
+        # Keep track of current download
         self.current_download_path = path
-        self.current_download_url = url
+        self.current_download_url = url.encode()
 
         mirror_url = url.format(self.common.settings['mirror'])
+        mirror_url = mirror_url.encode()
 
-        # convert mirror_url from unicode to string, if needed (#205)
-        if isinstance(mirror_url, unicode):
-            mirror_url = unicodedata.normalize('NFKD', mirror_url).encode('ascii', 'ignore')
-
-        # initialize the progress bar
-        self.progressbar.set_fraction(0)
-        self.progressbar.set_text(_('Downloading') + ' {0}'.format(name))
-        self.progressbar.show()
-        self.refresh_gtk()
+        # Initialize the progress bar
+        self.progress_bar.setValue(0)
+        self.progress_bar.setMaximum(100)
+        self.progress_bar.setFormat(_('Downloading') + ' {0}, %p%'.format(name))
 
         if self.common.settings['download_over_tor']:
             from twisted.internet.endpoints import clientFromString
@@ -489,21 +452,21 @@ class Launcher:
         self.common.settings['mirror'] = self.common.default_mirror
         self.common.save_settings()
         subprocess.Popen([self.common.paths['tbl_bin']])
-        self.destroy(False)
+        self.close()
 
     def try_forcing_english(self, widget, data=None):
         # change force english to true and relaunch TBL
         self.common.settings['force_en-US'] = True
         self.common.save_settings()
         subprocess.Popen([self.common.paths['tbl_bin']])
-        self.destroy(False)
+        self.close()
 
     def try_tor(self, widget, data=None):
         # set download_over_tor to true and relaunch TBL
         self.common.settings['download_over_tor'] = True
         self.common.save_settings()
         subprocess.Popen([self.common.paths['tbl_bin']])
-        self.destroy(False)
+        self.close()
 
     def get_stable_version(self):
         tree = ET.parse(self.common.paths['version_check_file'])
@@ -520,9 +483,10 @@ class Launcher:
         return None
 
     def verify(self):
-        self.progressbar.set_fraction(0)
-        self.progressbar.set_text(_('Verifying Signature'))
-        self.progressbar.show()
+        self.progress_bar.setValue(0)
+        self.progress_bar.setMaximum(0)
+        self.progress_bar.setFormat(_('Verifying Signature'))
+        self.progress_bar.show()
 
         def gui_raise_sigerror(self, sigerror='MissingErr'):
             """
@@ -533,9 +497,8 @@ class Launcher:
                        '\nClick Start to refresh the keyring and try again. If the message persists report the above' \
                        ' error code here:\nhttps://github.com/micahflee/torbrowser-launcher/issues'.format(sigerror)
 
-            self.set_gui('task', sigerror, ['start_over'], False)
-            self.clear_ui()
-            self.build_ui()
+            self.set_state('task', sigerror, ['start_over'], False)
+            self.update()
 
         if gpgme_support:
             with gpg.Context() as c:
@@ -560,7 +523,8 @@ class Launcher:
             p = subprocess.Popen(['/usr/bin/gpg', '--homedir', self.common.paths['gnupg_homedir'], '--verify',
                                   self.common.paths['sig_file'], self.common.paths['tarball_file']], stdout=FNULL,
                                  stderr=subprocess.STDOUT)
-            self.pulse_until_process_exits(p)
+            #self.pulse_until_process_exits(p)
+            # TODO: reimplement this
             if p.returncode == 0:
                 self.run_task()
             else:
@@ -571,10 +535,10 @@ class Launcher:
 
     def extract(self):
         # initialize the progress bar
-        self.progressbar.set_fraction(0)
-        self.progressbar.set_text(_('Installing'))
-        self.progressbar.show()
-        self.refresh_gtk()
+        self.progress_bar.setValue(0)
+        self.progress_bar.setMaximum(0)
+        self.progress_bar.setFormat(_('Installing'))
+        self.progress_bar.show()
 
         extracted = False
         try:
@@ -594,9 +558,8 @@ class Launcher:
             pass
 
         if not extracted:
-            self.set_gui('task', _("Tor Browser Launcher doesn't understand the file format of {0}".format(self.common.paths['tarball_file'])), ['start_over'], False)
-            self.clear_ui()
-            self.build_ui()
+            self.set_state('task', _("Tor Browser Launcher doesn't understand the file format of {0}".format(self.common.paths['tarball_file'])), ['start_over'], False)
+            self.update()
             return
 
         self.run_task()
@@ -614,56 +577,33 @@ class Launcher:
         return False
 
     def run(self, run_next_task=True):
-        # don't run if it isn't at least the minimum version
+        # Don't run if it isn't at least the minimum version
         if not self.check_min_version():
             message = _("The version of Tor Browser you have installed is earlier than it should be, which could be a "
                         "sign of an attack!")
             print(message)
 
-            md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _(message))
-            md.set_position(gtk.WIN_POS_CENTER)
-            md.run()
-            md.destroy()
-
+            Alert(self.common, message)
             return
 
-        # hide the TBL window (#151)
-        if hasattr(self, 'window'):
-            self.window.hide()
-            while gtk.events_pending():
-                gtk.main_iteration_do(True)
+        # Hide the TBL window (#151)
+        self.hide()
 
-        # run Tor Browser
+        # Run Tor Browser
         subprocess.call([self.common.paths['tbb']['start']], cwd=self.common.paths['tbb']['dir_tbb'])
 
         if run_next_task:
             self.run_task()
 
-    # make the progress bar pulse until process p (a Popen object) finishes
-    def pulse_until_process_exits(self, p):
-        while p.poll() is None:
-            time.sleep(0.01)
-            self.progressbar.pulse()
-            self.refresh_gtk()
-
-    # start over and download TBB again
+    # Start over and download TBB again
     def start_over(self):
         self.force_redownload = True  # Overwrite any existing file
-        self.label.set_text(_("Downloading Tor Browser Bundle over again."))
+        self.label.setText(_("Downloading Tor Browser Bundle over again."))
         self.gui_tasks = ['download_tarball', 'verify', 'extract', 'run']
         self.gui_task_i = 0
         self.start(None)
 
-    # refresh gtk
-    def refresh_gtk(self):
-        while gtk.events_pending():
-            gtk.main_iteration(False)
-
-    # exit
-    def delete_event(self, widget, event, data=None):
-        return False
-
-    def destroy(self, widget, data=None):
+    def closeEvent(self, event):
         if hasattr(self, 'file_download'):
             self.file_download.close()
         if hasattr(self, 'current_download_path'):
@@ -672,3 +612,22 @@ class Launcher:
             delattr(self, 'current_download_url')
         if reactor.running:
             reactor.stop()
+
+        super(Launcher, self).closeEvent(event)
+
+
+class Alert(QtWidgets.QMessageBox):
+    """
+    An alert box dialog.
+    """
+    def __init__(self, common, message, icon=QtWidgets.QMessageBox.NoIcon, buttons=QtWidgets.QMessageBox.Ok, autostart=True):
+        super(Alert, self).__init__(None)
+
+        self.setWindowTitle(_("Tor Browser Launcher"))
+        self.setWindowIcon(QtGui.QIcon(common.paths['icon_file']))
+        self.setText(message)
+        self.setIcon(icon)
+        self.setStandardButtons(buttons)
+
+        if autostart:
+            self.exec_()

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/torbrowser-launcher.git



More information about the Pkg-privacy-commits mailing list