Beispiel #1
0
    def _launchUpdate(self):
        self.setTitle(_('Updating'))
        self.setSubTitle(_('Update in progress...'))

        self.wizard().button(self.wizard().CancelButton).setEnabled(False)
        self.wizard().button(self.wizard().BackButton).setEnabled(False)

        self._process = QtCore.QProcess(self)
        self._process.errorOccurred.connect(self._onError)
        self._process.finished.connect(self._onFinished)
        self._process.readyReadStandardError.connect(self._onStderr)
        self._process.readyReadStandardOutput.connect(self._onStdout)

        manifest = Meta.manifest()
        filename = os.path.join(
            Meta.dataPath('images'),
            manifest['leonardo']['firmware']['current']['name'])

        args = [
            '-patmega32u4',
            '-cavr109',
            '-P%s' % self._devname,
            '-b57600',
            '-D',
            '-Uflash:w:%s:i' % filename,
        ]

        if platform.system() != 'Windows':
            args.insert(0, '-C%s' % Meta.avrdudeConf())

        self._process.start(Settings().avrdude(), args)
Beispiel #2
0
def setup():
    logging.TRACE = 5

    def trace(self, fmt, *args, **kwargs):
        if self.isEnabledFor(logging.TRACE):
            self._log(logging.TRACE, fmt, args, **kwargs)  # pylint: disable=W0212

    logging.Logger.trace = trace
    logging.addLevelName(logging.TRACE, 'TRACE')
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)-15s %(levelname)-8s %(name)-15s %(message)s')

    if platform.system() == 'Darwin':
        localeName = str(QtCore.QLocale.system().uiLanguages()[0]).replace(
            '-', '_')
    else:
        localeName = str(QtCore.QLocale.system().name())

    try:
        locale.setlocale(locale.LC_ALL, localeName)
    except locale.Error as exc:
        logger = logging.getLogger('dsremap')
        logger.error('Cannot set locale to "%s": %s', localeName, exc)

    trans = gettext.translation(Meta.appName(),
                                localedir=Meta.messages(),
                                languages=[localeName],
                                fallback=True)
    trans.install()
Beispiel #3
0
    def cleanup(self):
        files = set()
        for configuration in self.configurations():
            filename = configuration.thumbnail()
            if filename is None:
                continue
            files.add(os.path.basename(filename))

        for name in os.listdir(Meta.dataPath('thumbnails')):
            if name not in files:
                os.remove(os.path.join(Meta.dataPath('thumbnails'), name))
Beispiel #4
0
    def _gotManifest(self, downloader):
        downloader.downloadSize.disconnect(self._onSize)
        downloader.downloadProgress.disconnect(self._onProgress)

        try:
            unused, data = downloader.result()
        except AbortedError:
            self.logger.info('Aborted manifest')
            if self._getValue(self._manifest, self._path +
                              ('current', 'version')) != 0:
                self.accept()
            else:
                self.reject()
            return
        except DownloadError as exc:
            self.logger.error('Downloading manifest: %s', exc)
            if self._getValue(self._manifest, self._path +
                              ('current', 'version')) != 0:
                self.accept()
            else:
                self._msg.setText(
                    _('Cannot download manifest:{error}').format(
                        error='<br /><font color="red">%s</font>' % str(exc)))
                self._btn.setText(_('Bummer'))
                self._state = self.STATE_ERROR
            return

        data = json.loads(data)
        self._getValue(self._manifest, self._path)['latest'] = self._getValue(
            data, self._path + ('latest', ))

        if self._getValue(self._manifest, self._path +
                          ('current', 'version')) == self._getValue(
                              self._manifest,
                              self._path + ('latest', 'version')):
            self.logger.info('Up to date')
            self.accept()
            return

        handle, filename = tempfile.mkstemp(dir=Meta.dataPath('images'))
        os.close(handle)

        self._state = self.STATE_DL
        self._msg.setText(_('Downloading image...'))
        self._downloader = FileDownloader(self,
                                          self.mainWindow().manager(),
                                          filename,
                                          callback=self._gotFile)
        self._downloader.downloadSize.connect(self._onSize)
        self._downloader.downloadProgress.connect(self._onProgress)
        self._downloader.get(Meta.imagesUrl().format(
            filename=self._getValue(self._manifest, self._path +
                                    ('latest', 'name'))))
Beispiel #5
0
    def __init__(self):
        super().__init__([])
        self.setApplicationName(Meta.appName())
        self.setApplicationVersion(str(Meta.appVersion()))
        self.setOrganizationDomain(Meta.appDomain())
        self.setWindowIcon(QtGui.QIcon(':icons/gamepad.svg'))

        # Builtin messages.
        trans = QtCore.QTranslator(self)
        path = QtCore.QLibraryInfo.location(
            QtCore.QLibraryInfo.TranslationsPath)
        trans.load(QtCore.QLocale.system(), 'qtbase', '_', path)
        self.installTranslator(trans)
Beispiel #6
0
 def _tick(self):
     if self._state == 0:
         newDevs = Meta.listSerials() - self._devices
         if newDevs:
             # XXXTODO: support multiple devices ? Would be hard since they disappear after a few seconds...
             self._devname = newDevs.pop()
             self.setSubTitle(
                 _('Found Leonardo at {path}.').format(path=self._devname))
             self._state = 1
     if self._state == 1:
         # Reset
         error = None
         for unused in range(5):
             try:
                 with serial.Serial(self._devname, 2000):
                     pass
             except serial.SerialException as exc:
                 error = exc
                 time.sleep(0.5)
                 # Retry
             else:
                 break
         else:
             self.setSubTitle(
                 _('Error resetting the device: {error}').format(
                     error=str(error)))
             self._finished = True
             self._timer.stop()
             self.completeChanged.emit()
             return
         self._state = 2
     if self._state == 2:
         self._state = 3
         self._timer.stop()
         self._launchUpdate()
Beispiel #7
0
def headers():
    # Log messages
    from tools.build.genids import main
    main([
        '-o',
        os.path.join('src', 'arduino', 'dsremap', 'messages.h'),
        '-s',
        os.path.join('tools', 'strings.pickle'),
        os.path.join('src', 'arduino', 'dsremap', 'messages.txt'),
    ])

    # Opcodes
    from dsrlib.compiler.opcodes import export
    export(os.path.join('src', 'arduino', 'dsremap', 'opcodes.h'))

    # Version
    with codecs.getwriter('utf-8')(open(
            os.path.join('src', 'arduino', 'dsremap', 'version.h'),
            'wb')) as fileobj:
        from dsrlib.meta import Meta
        version = Meta.firmwareVersion()

        fileobj.write('#ifndef _DSREMAP_VERSION_H_\n')
        fileobj.write('#define _DSREMAP_VERSION_H_\n')
        fileobj.write('#define FW_VERSION_MAJOR %d\n' % version.major)
        fileobj.write('#define FW_VERSION_MINOR %d\n' % version.minor)
        fileobj.write('#define FW_VERSION_PATCH %d\n' % version.patch)
        fileobj.write('#endif\n')
Beispiel #8
0
 def exec_(self):  # pylint: disable=C0103
     self._msg.setText(_('Downloading manifest...'))
     self._downloader = StringDownloader(self,
                                         self.mainWindow().manager(),
                                         callback=self._gotManifest)
     self._downloader.downloadSize.connect(self._onSize)
     self._downloader.downloadProgress.connect(self._onProgress)
     self._downloader.get(Meta.imagesUrl().format(filename='manifest.json'))
     return super().exec_()
Beispiel #9
0
    def initializePage(self):
        self.setTitle(_('Image copy'))
        self.setSubTitle(_('Copying image file'))

        manifest = Meta.manifest()
        name = manifest['rpi0w-v2']['image']['current']['name']
        self._src = os.path.join(Meta.dataPath('images'), name)
        self._dst = os.path.join(
            QtCore.QStandardPaths.writableLocation(
                QtCore.QStandardPaths.DownloadLocation),
            '%s.img' % os.path.splitext(name)[0])

        ssid, password = self.wizard().wifi()
        self._thread = ImageCopyThread(self._src, self._dst, ssid, password,
                                       self.wizard().ssh())
        self._thread.progress.connect(self._onProgress)
        self._thread.finished.connect(self._onFinished)
        self._thread.error.connect(self._onError)
        self._thread.start()
Beispiel #10
0
    def initializePage(self):
        self.setTitle(_('Looking for Leonardo'))
        self.setSubTitle(_('Release the <b>reset</b> button now.'))

        self._state = 0
        self._finished = False
        self._devices = Meta.listSerials()
        self._devname = None
        self._process = None
        self._timer.start(200)
Beispiel #11
0
    def _gotFile(self, downloader):
        downloader.downloadSize.disconnect(self._onSize)
        downloader.downloadProgress.disconnect(self._onProgress)

        try:
            downloader.result()
        except AbortedError:
            self.logger.info('Aborted image')
            if self._getValue(self._manifest, self._path +
                              ('current', 'version')) != 0:
                self.accept()
            else:
                self.reject()
            return
        except DownloadError as exc:
            self.logger.error('Downloading image: %s', exc)
            if self._getValue(self._manifest, self._path +
                              ('current', 'version')) != 0:
                self.accept()
            else:
                self._msg.setText(
                    _('Cannot download image: {error}').format(
                        error='<font color="red">%s</font>' % str(exc)))
                self._btn.setText(_('Bummer'))
                self._state = self.STATE_ERROR
            return

        src = downloader.filename()
        dst = os.path.join(
            Meta.dataPath('images'),
            self._getValue(self._manifest, self._path + ('latest', 'name')))
        if os.path.exists(dst):
            os.remove(dst)
        os.rename(src, dst)

        self._getValue(self._manifest, self._path)['current'] = self._getValue(
            self._manifest, self._path).pop('latest')
        Meta.updateManifest(self._manifest)
        self.accept()
Beispiel #12
0
        def gotChangelog(downloader):
            self._changelogDl = None
            try:
                _unused, text = downloader.result()
            except AbortedError:
                self.logger.info('Changelog download aborted')
                return
            except (DownloadError, SSLError) as exc:
                self.logger.exception('Cannot download changelog: %s', exc)
                return

            changelog = Changelog(text)
            if changelog.changesSince(Meta.appVersion()):
                win = ChangelogView(self, changelog)
                win.show()
                win.raise_()
Beispiel #13
0
    def __init__(self, parent, changelog):
        super().__init__(parent)

        self.setWindowTitle(_('New release available'))

        view = QtWidgets.QTextBrowser(self)
        view.setHtml(HTMLChangelogFormatter().format(
            changelog.changesSince(Meta.appVersion())))
        view.setOpenExternalLinks(True)

        btn = QtWidgets.QPushButton(_('OK'), self)
        btn.clicked.connect(self.accept)

        bld = LayoutBuilder(self)
        with bld.vbox() as vbox:
            vbox.addWidget(view)
            with bld.hbox() as hbox:
                hbox.addStretch(1)
                hbox.addWidget(btn)

        self.resize(640, 480)
Beispiel #14
0
def exe():
    if platform.system() == 'Darwin':
        subprocess.run([sys.executable, 'setup.py', 'py2app'], check=True)

        import dmgbuild
        dmgbuild.build_dmg('dsremap-%s.dmg' % str(Meta.appVersion()),
                           Meta.appName(), 'dmgbuild-settings.py')
    elif platform.system() == 'Windows':
        subprocess.run([sys.executable, 'setup.py', 'build'], check=True)
        distdir = r'build\exe.win-%s-%s' % (platform.machine().lower(),
                                            '%d.%d' % sys.version_info[:2])
        with codecs.getwriter('utf-8')(open('installer.nsi', 'wb')) as dst:
            with codecs.getreader('utf-8')(open('installer.nsi.in',
                                                'rb')) as src:
                for line in src:
                    dst.write(
                        line.replace('@APPNAME@', Meta.appName()).replace(
                            '@APPVERSION@', str(Meta.appVersion())).replace(
                                '@DISTDIR@',
                                distdir).replace('@WEBSITE@', Meta.appSite()))
        import winreg
        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE', 0,
                             winreg.KEY_READ | winreg.KEY_WOW64_32KEY)
        try:
            path = winreg.QueryValue(key, 'NSIS')
        except:
            raise RuntimeError(
                'Cannot find NSIS in registry, is it installed ?')
        finally:
            winreg.CloseKey(key)
        # Assuming NSIS 3.x here
        subprocess.run([
            os.path.join(path, 'makensis.exe'), '/INPUTCHARSET', 'UTF8',
            'installer.nsi'
        ],
                       check=True)
    elif platform.system() == 'Linux':
        with codecs.getwriter('utf-8')(open('appimage.yml', 'wb')) as dst:
            with codecs.getreader('utf-8')(open('appimage.yml.in',
                                                'rb')) as src:
                for line in src:
                    dst.write(line.replace('@VERSION@',
                                           str(Meta.appVersion())))
        subprocess.run(
            ['appimage-builder', '--recipe', 'appimage.yml', '--skip-test'],
            check=True)
    else:
        raise RuntimeError('Unsupported platform')
Beispiel #15
0
    def __init__(self, parent, *, path, **kwargs):
        super().__init__(parent, **kwargs)
        self._path = path
        self._state = self.STATE_MANIFEST
        self._manifest = Meta.manifest()
        self._downloader = None

        self._msg = QtWidgets.QLabel(self)
        self._progress = QtWidgets.QProgressBar(self)

        bld = LayoutBuilder(self)
        with bld.vbox() as vbox:
            vbox.setContentsMargins(5, 5, 5, 5)
            vbox.addWidget(self._msg)
            vbox.addWidget(self._progress)
            with bld.hbox() as hbox:
                self._btn = QtWidgets.QPushButton(_('Cancel'), self)
                hbox.addStretch(1)
                hbox.addWidget(self._btn)

        self._btn.clicked.connect(self._cancel)
Beispiel #16
0
 def isFirstVersionLaunch(self):
     with self.grouped('Versions'):
         key = 'v%d_%d_%d' % Meta.appVersion()
         ret = self.booleanValue(key, True)
         self.setBooleanValue(key, False)
         return ret
Beispiel #17
0
    setup(app=['dsremap.py'],
          options={
              'py2app': {
                  'iconfile': os.path.join('icons', 'dsremap.icns')
              }
          },
          setup_requires=['py2app'],
          data_files=data_files)

if platform.system() == 'Windows':
    from cx_Freeze import setup, Executable

    options = {
        'include_files': [
            (r'res\avrdude.conf', r'resources\avrdude.conf'),
            (r'res\configurations', r'resources\configurations'),
            (r'i18n', r'resources\i18n'),
        ]
    }

    setup(name=Meta.appName(),
          version=str(Meta.appVersion()),
          description=Meta.appName(),
          options={'build_exe': options},
          executables=[
              Executable('dsremap.py',
                         base='Win32GUI',
                         icon=r'icons\dsremap.ico')
          ])
Beispiel #18
0
 def pathFor(self, filename):
     dst = Meta.newThumbnail(filename)
     self._zipobj.extract(filename, os.path.dirname(dst))
     os.rename(os.path.join(os.path.dirname(dst), filename), dst)
     return dst
Beispiel #19
0
 def accept(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Meta.releasesUrl()))
     return super().accept()
Beispiel #20
0
 def dropEvent(self, event):
     src = event.mimeData().urls()[0].toLocalFile()
     dst = Meta.newThumbnail(src)
     shutil.copyfile(src, dst)
     cmd = commands.ChangeConfigurationThumbnailCommand(configuration=self.configuration(), filename=dst)
     self.history().run(cmd)
Beispiel #21
0
    def check(self):  # pylint: disable=R0912,R0914,R0915
        if platform.system() == 'Linux':
            # 1. plugdev group

            groupOk = False
            retcode = 0
            try:
                proc = subprocess.Popen(['groups'],
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                outData, unused = proc.communicate()
            except Exception as exc:  # pylint: disable=W0703
                msg = str(exc)
                retcode = 1
            else:
                retcode = proc.returncode
                msg = _('<i>groups</i> exited with code {code}').format(
                    code=proc.returncode)

            if retcode:
                QtWidgets.QMessageBox.warning(
                    self, _('Cannot find groups'),
                    _('Unable to find out which groups you belong to:<p />{error}<p />For this program to work correctly, you must belong to the <i>plugdev</i> group.'
                      ).format(error=msg))
                groupOk = True
            else:
                groups = Meta.decodePlatformString(outData).split()
                groupOk = 'plugdev' in groups

            # 2. udev rules
            udevOk = os.path.exists('/etc/udev/rules.d/80-dsremap.rules')

            if not (udevOk and groupOk):
                msg = _(
                    'The following operations must be done before this program can work correctly:'
                ) + '<p /><ul>'
                if not udevOk:
                    msg += '<li>' + _(
                        'Install udev rules to allow HID communication'
                    ) + '</li>'
                if not groupOk:
                    msg += '<li>' + _(
                        'Add you to the <i>plugdev</i> group') + '</li>'
                msg += '</ul>'
                if not groupOk:
                    msg += '<p />' + _(
                        'You may have to logout and login again, or even reboot, and unplug/replug the Arduino for those changes to apply.'
                    )

                msg += '<p />' + _('You may be prompted for your password.')

                QtWidgets.QMessageBox.information(self, _('System setup'), msg)

                try:
                    if not groupOk:
                        sudoLaunch('usermod', '-a', '-G', 'plugdev',
                                   os.environ['USER'])
                    if not udevOk:
                        # Cannot copy a file from the res directory because root hasn't the permissions on the mount dir...
                        sudoLaunch(
                            'sh', '-c',
                            'echo \'SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="09cc", GROUP="plugdev", MODE="0660"\' > /etc/udev/rules.d/80-dsremap.rules'
                        )
                        sudoLaunch(
                            'sh', '-c',
                            'echo \'SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", GROUP="plugdev", MODE="0660"\' > /etc/udev/rules.d/80-dsremap.rules'
                        )
                        sudoLaunch(
                            'sh', '-c',
                            'echo \'SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", GROUP="plugdev", MODE="0660"\' >> /etc/udev/rules.d/80-dsremap.rules'
                        )
                except SudoNotFound:
                    QtWidgets.QMessageBox.critical(
                        self, _('Error'),
                        _('Unable to find <i>sudo</i> on the path.'))
                except SudoError as exc:
                    QtWidgets.QMessageBox.critical(
                        self, _('Error'),
                        _('Command failed with exit code {code}.<p />{stderr}'
                          ).format(code=exc.code, stderr=exc.stderr))

        with Settings().grouped('DefaultConfigurations') as settings:
            imported = settings.value('Imported').split(
                ',') if settings.contains('Imported') else []
            importer = JSONImporter()
            for name in glob.glob(
                    os.path.join(Meta.defaultConfigurations(), '*.zip')):
                with zipfile.ZipFile(name, mode='r') as zipobj:
                    configuration = importer.read(zipobj)
                if configuration.uuid() not in imported:
                    imported.append(configuration.uuid())
                    self._workspace.configurations().addItem(configuration)
            settings.setValue('Imported', ','.join(imported))

        if not Settings().firmwareUploaded():
            wizard = FirstLaunchWizard(self, mainWindow=self)
            wizard.exec_()
Beispiel #22
0
    def __init__(self):  # pylint: disable=R0915
        super().__init__()

        self._manager = QtNetwork.QNetworkAccessManager(self)

        self._workspace = Workspace()
        self.setCentralWidget(
            WorkspaceView(self, mainWindow=self, workspace=self._workspace))
        self._workspace.load()
        self._devenum = DeviceEnumerator()

        self.setWindowTitle(
            _('{appName} v{appVersion}').format(appName=Meta.appName(),
                                                appVersion=str(
                                                    Meta.appVersion())))
        self.statusBar()

        filemenu = QtWidgets.QMenu(_('File'), self)
        filemenu.addAction(
            uicommands.ExportConfigurationUICommand(
                self, mainWindow=self, container=self.centralWidget()))
        filemenu.addAction(
            uicommands.ImportConfigurationUICommand(self,
                                                    mainWindow=self,
                                                    workspace=self._workspace))
        filemenu.addAction(
            uicommands.ExportBytecodeUICommand(self,
                                               mainWindow=self,
                                               workspace=self._workspace,
                                               container=self.centralWidget()))
        self.menuBar().addMenu(filemenu)

        editmenu = QtWidgets.QMenu(_('Edit'), self)
        editmenu.addAction(uicommands.UndoUICommand(self, mainWindow=self))
        editmenu.addAction(uicommands.RedoUICommand(self, mainWindow=self))
        editmenu.addAction(
            uicommands.ShowSettingsDialogUICommand(self, mainWindow=self))
        self.menuBar().addMenu(editmenu)

        devmenu = uicommands.DeviceMenu(self,
                                        mainWindow=self,
                                        workspace=self._workspace,
                                        enumerator=self._devenum)
        self.menuBar().addMenu(devmenu)

        uploadmenu = uicommands.UploadMenu(self,
                                           mainWindow=self,
                                           container=self.centralWidget(),
                                           workspace=self._workspace,
                                           enumerator=self._devenum)
        self.menuBar().addMenu(uploadmenu)

        helpmenu = QtWidgets.QMenu(_('Help'), self)
        helpmenu.addAction(
            uicommands.ShowAboutDialogUICommand(self, mainWindow=self))
        helpmenu.addAction(uicommands.OpenDocsUICommand(self, mainWindow=self))
        self.menuBar().addMenu(helpmenu)

        with Settings().grouped('UIState') as settings:
            if settings.contains('WindowGeometry'):
                self.restoreGeometry(settings.value('WindowGeometry'))
            else:
                self.resize(1280, 600)
            self.centralWidget().loadState(settings)

        self.raise_()
        self.show()

        settings = Settings()
        if settings.isFirstVersionLaunch():
            QtGui.QDesktopServices.openUrl(QtCore.QUrl(
                Meta.documentationUrl()))

        self.check()

        def gotChangelog(downloader):
            self._changelogDl = None
            try:
                _unused, text = downloader.result()
            except AbortedError:
                self.logger.info('Changelog download aborted')
                return
            except (DownloadError, SSLError) as exc:
                self.logger.exception('Cannot download changelog: %s', exc)
                return

            changelog = Changelog(text)
            if changelog.changesSince(Meta.appVersion()):
                win = ChangelogView(self, changelog)
                win.show()
                win.raise_()

        self._changelogDl = StringDownloader(self,
                                             self.manager(),
                                             callback=gotChangelog)
        self._changelogDl.get(Meta.changelogUrl())
Beispiel #23
0
# Mock imports from Meta
class PyQt5:
    class QtCore:
        pass

    class QtGui:
        pass


sys.modules['PyQt5'] = PyQt5

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src'))
from dsrlib.meta import Meta

project = Meta.appName()
copyright = '2020-2021, %s' % Meta.appAuthor()
author = Meta.appAuthor()

# The short X.Y version
version = '%d.%d' % Meta.appVersion()[:2]
# The full version, including alpha/beta/rc tags
release = str(Meta.appVersion())

# -- General configuration ---------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
Beispiel #24
0
#!/usr/bin/env python3

import os
import sys
import shutil

from PyQt5 import QtCore

sys.path.insert(
    0, os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'src')))

from dsrlib.ui.main import Application
from dsrlib.meta import Meta

if __name__ == '__main__':
    app = Application()
    settings = QtCore.QSettings()
    settings.clear()
    settings.sync()
    shutil.rmtree(Meta.dataPath())
Beispiel #25
0
 def save(self):
     filename = os.path.join(Meta.dataPath(), 'workspace.json')
     writer = JSONWriter()
     with codecs.getwriter('utf-8')(open(filename, 'wb')) as fileobj:
         writer.write(fileobj, self)
Beispiel #26
0
 def do(self):
     QtGui.QDesktopServices.openUrl(QtCore.QUrl(Meta.documentationUrl()))
Beispiel #27
0
 def __init__(self, *args, **kwargs):
     super().__init__(
         *args,
         text=_('About {appname}...').format(appname=Meta.appName()),
         **kwargs)
     self.setMenuRole(self.AboutRole)
Beispiel #28
0
 def _onStdout(self):
     text = Meta.decodePlatformString(self._process.readAllStandardOutput())
     self.logger.info('O: %s', text.strip())
Beispiel #29
0
 def _onStderr(self):
     text = Meta.decodePlatformString(self._process.readAllStandardError())
     self.logger.info('E: %s', text.strip())
Beispiel #30
-1
    def __init__(self, parent):
        super().__init__(parent)

        self.setWindowTitle(
            _('{appname} v{appversion}').format(appname=Meta.appName(),
                                                appversion=str(
                                                    Meta.appVersion())))

        iodev = QtCore.QFile(':/about.html')
        iodev.open(iodev.ReadOnly)
        try:
            about = bytes(iodev.readAll()).decode('utf-8')
        finally:
            iodev.close()
        about = about.format(author=Meta.appAuthor())

        text = QtWidgets.QTextBrowser(self)
        text.setHtml(about)
        text.setOpenExternalLinks(True)

        btn = QtWidgets.QPushButton(_('Done'), self)

        bld = LayoutBuilder(self)
        with bld.vbox() as vbox:
            vbox.addWidget(text)
            with bld.hbox() as buttons:
                buttons.addStretch(1)
                buttons.addWidget(btn)

        btn.clicked.connect(self.accept)

        self.resize(800, 600)