예제 #1
0
파일: main.py 프로젝트: Zekom/webutil
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        ec = ExplorerContainer()
        super(Main, self).initialize(*args, **kwargs)

        self.editor_s = self.locator.get_service('editor')
        # directory auto completer
        self.completer = QCompleter(self)
        self.dirs = QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.group0 = QGroupBox()
        self.group0.setTitle(' Source ')
        self.source = QComboBox()
        self.source.addItems(['Clipboard', 'Local File', 'Remote URL', 'Ninja'])
        self.source.currentIndexChanged.connect(self.on_source_changed)
        self.infile = QLineEdit(path.expanduser("~"))
        self.infile.setPlaceholderText(' /full/path/to/file.html ')
        self.infile.setCompleter(self.completer)
        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.setCursor(QCursor(Qt.PointingHandCursor))
        self.open.clicked.connect(lambda: self.infile.setText(str(
            QFileDialog.getOpenFileName(self.dock, "Open a File to read from",
            path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e)
            for e in ['css', 'html', 'js', 'txt', '*']])))))
        self.inurl = QLineEdit('http://www.')
        self.inurl.setPlaceholderText('http://www.full/url/to/remote/file.html')
        self.output = QPlainTextEdit(SAMPLE_TEXT)
        vboxg0 = QVBoxLayout(self.group0)
        for each_widget in (self.source, self.infile, self.open, self.inurl,
            self.output, ):
            vboxg0.addWidget(each_widget)
        [a.hide() for a in iter((self.infile, self.open, self.inurl))]

        self.group1 = QGroupBox()
        self.group1.setTitle(' CSS3 ')
        self.group1.setCheckable(True)
        self.group1.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group1.graphicsEffect().setEnabled(False)
        self.group1.toggled.connect(self.toggle_css_group)
        self.ckcss1 = QCheckBox('Remove unnecessary Comments')
        self.ckcss2 = QCheckBox('Remove unnecessary Whitespace characters')
        self.ckcss3 = QCheckBox('Remove unnecessary Semicolons')
        self.ckcss4 = QCheckBox('Remove unnecessary Empty rules')
        self.ckcss5 = QCheckBox('Condense and Convert Colors from RGB to HEX')
        self.ckcss6 = QCheckBox('Condense all Zero units')
        self.ckcss7 = QCheckBox('Condense Multidimensional Zero units')
        self.ckcss8 = QCheckBox('Condense Floating point numbers')
        self.ckcss9 = QCheckBox('Condense HEX Colors')
        self.ckcss10 = QCheckBox('Condense multiple adjacent Whitespace chars')
        self.ckcss11 = QCheckBox('Condense multiple adjacent semicolon chars')
        self.ckcss12 = QCheckBox('Wrap the lines of the to 80 character length')
        self.ckcss13 = QCheckBox('Condense Font Weight values')
        self.ckcss14 = QCheckBox('Condense the 17 Standard Named Colors values')
        self.ckcss15 = QCheckBox('Condense the 124 Extra Named Colors values')
        self.ckcss16 = QCheckBox('Condense all Percentages values when posible')
        self.ckcss17 = QCheckBox('Condense all Pixels values when posible')
        self.ckcss18 = QCheckBox('Remove unnecessary quotes from url()')
        self.ckcss19 = QCheckBox('Add standard Encoding Declaration if missing')
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
            self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9,
            self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13,
            self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17,
            self.ckcss18, self.ckcss19):
            vboxg1.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group2 = QGroupBox()
        self.group2.setTitle(' HTML5 ')
        self.group2.setCheckable(True)
        self.group2.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group2.graphicsEffect().setEnabled(False)
        self.group2.toggled.connect(self.toggle_html_group)
        self.ckhtml0 = QCheckBox('Condense Style and Script HTML Tags')
        self.ckhtml1 = QCheckBox('Condense DOCTYPE to new HTML5 Tags')
        self.ckhtml2 = QCheckBox('Condense Href and Src to protocol agnostic')
        self.ckhtml4 = QCheckBox('Remove unnecessary Tags but keep HTML valid')
        self.help1 = QLabel('''<a href=
            "https://developers.google.com/speed/articles/optimizing-html">
            <small><center>Help about Unneeded Unnecessary HTML tags ?</a>''')
        self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.help1.setOpenExternalLinks(True)
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.ckhtml0, self.ckhtml1, self.ckhtml2,
            self.ckhtml4, self.help1, ):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group3 = QGroupBox()
        self.group3.setTitle(' Javascript ')
        self.ckjs0 = QCheckBox('Condense and Compress Javascript')
        self.ckjs1 = QCheckBox('Condense $(document).ready(function(){ });')
        vboxg2 = QVBoxLayout(self.group3)
        for each_widget in (self.ckjs0, self.ckjs1):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group4 = QGroupBox()
        self.group4.setTitle(' General ')
        self.chckbx1 = QCheckBox('Lower case ALL the text')
        self.chckbx2 = QCheckBox('Remove Spaces, Tabs, New Lines, Empty Lines')
        self.befor, self.after = QProgressBar(), QProgressBar()
        self.befor.setFormat("%v Chars")
        self.after.setFormat("%v Chars")
        vboxg4 = QVBoxLayout(self.group4)
        for each_widget in (self.chckbx1, self.chckbx2,
            QLabel('<b>Before:'), self.befor, QLabel('<b>After:'), self.after):
            vboxg4.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19, self.ckjs1, self.ckhtml0,
            self.ckhtml1, self.ckhtml2, self.ckhtml4, self.chckbx1,
            self.chckbx2))]

        self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Process Text')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)

        def must_glow(widget_list):
            ' apply an glow effect to the widget '
            for glow, each_widget in enumerate(widget_list):
                try:
                    if each_widget.graphicsEffect() is None:
                        glow = QGraphicsDropShadowEffect(self)
                        glow.setOffset(0)
                        glow.setBlurRadius(99)
                        glow.setColor(QColor(99, 255, 255))
                        each_widget.setGraphicsEffect(glow)
                        glow.setEnabled(True)
                except:
                    pass

        must_glow((self.button, ))

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((QLabel('<b>HTML5/CSS3/JS Optimizer Compressor'),
            self.group0, self.group1, self.group2, self.group3, self.group4,
            self.button, ))
        self.scrollable = QScrollArea()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock = QDockWidget()
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setMinimumWidth(350)
        self.dock.setWidget(self.scrollable)
        ec.addTab(self.dock, "Web")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
          ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__,
            HELPMSG))

    def run(self):
        ' run the string replacing '
        if self.source.currentText() == 'Local File':
            with open(path.abspath(str(self.infile.text()).strip()), 'r') as f:
                txt = f.read()
        elif self.source.currentText() == 'Remote URL':
            txt = urlopen(str(self.inurl.text()).strip()).read()
        elif  self.source.currentText() == 'Clipboard':
            txt = str(self.output.toPlainText()) if str(self.output.toPlainText()) is not '' else str(QApplication.clipboard().text())
        else:
            txt = self.editor_s.get_text()
        self.output.clear()
        self.befor.setMaximum(len(txt) + 10)
        self.after.setMaximum(len(txt) + 10)
        self.befor.setValue(len(txt))
        txt = txt.lower() if self.chckbx1.isChecked() is True else txt
        txt = condense_style(txt) if self.ckhtml0.isChecked() is True else txt
        txt = condense_script(txt) if self.ckhtml0.isChecked() is True else txt
        txt = condense_doctype(txt) if self.ckhtml1.isChecked() is True else txt
        txt = condense_href_src(txt) if self.ckhtml2 is True else txt
        txt = clean_unneeded_tags(txt) if self.ckhtml4.isChecked() is True else txt
        txt = condense_doc_ready(txt) if self.ckjs1.isChecked() is True else txt
        txt = jsmin(txt) if self.ckjs0.isChecked() is True else txt
        txt = remove_comments(txt) if self.ckcss1.isChecked() is True else txt
        txt = condense_whitespace(txt) if self.ckcss10.isChecked() is True else txt
        txt = remove_empty_rules(txt) if self.ckcss4.isChecked() is True else txt
        txt = remove_unnecessary_whitespace(txt) if self.ckcss2.isChecked() is True else txt
        txt = remove_unnecessary_semicolons(txt) if self.ckcss3.isChecked() is True else txt
        txt = condense_zero_units(txt) if self.ckcss6.isChecked() is True else txt
        txt = condense_multidimensional_zeros(txt) if self.ckcss7.isChecked() is True else txt
        txt = condense_floating_points(txt) if self.ckcss8.isChecked() is True else txt
        txt = normalize_rgb_colors_to_hex(txt) if self.ckcss5.isChecked() is True else txt
        txt = condense_hex_colors(txt) if self.ckcss9.isChecked() is True else txt
        txt = wrap_css_lines(txt, 80) if self.ckcss12.isChecked() is True else txt
        txt = condense_semicolons(txt) if self.ckcss11.isChecked() is True else txt
        txt = condense_font_weight(txt) if self.ckcss13.isChecked() is True else txt
        txt = condense_std_named_colors(txt) if self.ckcss14.isChecked() is True else txt
        # txt = condense_xtra_named_colors(txt) if self.ckcss14.isChecked() is True else txt  # FIXME
        txt = condense_percentage_values(txt) if self.ckcss16.isChecked() is True else txt
        txt = condense_pixel_values(txt) if self.ckcss17.isChecked() is True else txt
        txt = remove_url_quotes(txt) if self.ckcss18.isChecked() is True else txt
        txt = add_encoding(txt) if self.ckcss19.isChecked() is True else txt
        txt = " ".join(txt.strip().split()) if self.chckbx2.isChecked() is True else txt
        self.after.setValue(len(txt))
        self.output.setPlainText(txt)
        self.output.show()
        self.output.setFocus()
        self.output.selectAll()

    def on_source_changed(self):
        ' do something when the desired source has changed '
        if self.source.currentText() == 'Local File':
            self.open.show()
            self.infile.show()
            self.inurl.hide()
            self.output.hide()
        elif  self.source.currentText() == 'Remote URL':
            self.inurl.show()
            self.open.hide()
            self.infile.hide()
            self.output.hide()
        elif  self.source.currentText() == 'Clipboard':
            self.output.show()
            self.open.hide()
            self.infile.hide()
            self.inurl.hide()
            self.output.setText(QApplication.clipboard().text())
        else:
            self.output.show()
            self.open.hide()
            self.infile.hide()
            self.inurl.hide()
            self.output.setText(self.editor_s.get_text())

    def toggle_css_group(self):
        ' toggle on or off the css checkboxes '
        if self.group1.isChecked() is True:
            [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19))]
            self.group1.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19))]
            self.group1.graphicsEffect().setEnabled(True)

    def toggle_html_group(self):
        ' toggle on or off the css checkboxes '
        if self.group2.isChecked() is True:
            [a.setChecked(True) for a in iter((self.ckhtml0, self.ckhtml1,
                                               self.ckhtml2, self.ckhtml4))]
            self.group2.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in iter((self.ckhtml0, self.ckhtml1,
                                                self.ckhtml2, self.ckhtml4))]
            self.group2.graphicsEffect().setEnabled(True)
예제 #2
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.readOutput)
        self.process.readyReadStandardError.connect(self.readErrors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_finished)
        self.editor_s = self.locator.get_service('editor')
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.group0 = QGroupBox()
        self.group0.setTitle(' Source ')
        self.infile = QLineEdit(path.expanduser("~"))
        self.infile.setPlaceholderText(' /full/path/to/file.html ')
        self.infile.setCompleter(self.completer)
        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.setCursor(QCursor(Qt.PointingHandCursor))
        self.open.clicked.connect(lambda: self.infile.setText(str(
            QFileDialog.getOpenFileName(self.dock, "Open a File to read from",
            path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e)
            for e in ['py', 'pyw', 'txt', '*']])))))
        self.output = QTextEdit()
        vboxg0 = QVBoxLayout(self.group0)
        for each_widget in (self.infile, self.open, self.output):
            vboxg0.addWidget(each_widget)

        self.group1 = QGroupBox()
        self.group1.setTitle(' General ')
        self.group1.setCheckable(True)
        self.group1.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group1.graphicsEffect().setEnabled(False)
        self.group1.toggled.connect(self.toggle_gral_group)
        self.ckgrl1 = QCheckBox('Create standalone executable')
        self.ckgrl2 = QCheckBox('Use Python debug')
        self.ckgrl3 = QCheckBox('Force compilation for MS Windows')
        self.ckgrl4 = QCheckBox('When compiling, disable the console window')
        self.ckgrl5 = QCheckBox('Use link time optimizations if available')
        self.ckgrl6 = QCheckBox('Force the use of clang')
        self.ckgrl7 = QCheckBox('Allow minor devitations from Python behaviour')
        self.ckgrl8 = QCheckBox('Warnings implicit exceptions at compile time')
        self.pyver, self.jobs = QComboBox(), QSpinBox()
        self.pyver.addItems(['2.7', '2.6', '3.2', '3.3'])
        self.jobs.setValue(1)
        self.jobs.setMaximum(12)
        self.jobs.setMinimum(1)
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (self.ckgrl1, self.ckgrl2, self.ckgrl3, self.ckgrl4,
            self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8,
            QLabel('Python Version to Target'), self.pyver,
            QLabel('Multi-Processing Parallel Workers'), self.jobs):
            vboxg1.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                pass

        self.group2 = QGroupBox()
        self.group2.setTitle(' Recursion Control ')
        self.ckrec0 = QCheckBox('Descend to imported modules from standard lib')
        self.ckrec1 = QCheckBox('Force not descend to any imported modules')
        self.ckrec2 = QCheckBox('Try to descend into all imported modules')
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.ckrec0, self.ckrec1, self.ckrec2):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group3 = QGroupBox()
        self.group3.setTitle(' Execution after compilation ')
        self.ckexe0 = QCheckBox('Execute created binary (or import the module)')
        self.ckexe1 = QCheckBox('When executing binary dont reset PYTHONPATH')
        vboxg2 = QVBoxLayout(self.group3)
        for each_widget in (self.ckexe0, self.ckexe1):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group4, self.dumptree = QGroupBox(), QTextEdit()
        self.group4.setTitle(' Dump of internal tree ')
        QVBoxLayout(self.group4).addWidget(self.dumptree)

        self.group5 = QGroupBox()
        self.group5.setTitle(' Code generation ')
        self.chdmp1 = QCheckBox('Statements shall have their line numbers set')
        self.chdmp2 = QCheckBox('Disable all unnecessary Python optimization')
        vboxg5 = QVBoxLayout(self.group5)
        for each_widget in (self.chdmp1, self.chdmp2):
            vboxg5.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group6 = QGroupBox()
        self.group6.setTitle(' Output ')
        self.outdir = QLineEdit(path.expanduser("~"))
        self.outdir.setPlaceholderText(' /full/path/to/target/directory ')
        self.outdir.setCompleter(self.completer)
        self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open2.setCursor(QCursor(Qt.PointingHandCursor))
        self.open2.clicked.connect(lambda: self.outdir.setText(str(
            QFileDialog.getExistingDirectory(self.dock, "Open Target Folder",
            path.expanduser("~")))))
        self.ckcgn2 = QCheckBox('Remove build dir after compile module or exe')
        vboxg6 = QVBoxLayout(self.group6)
        for each_widget in (QLabel('Target Output Directory'), self.outdir,
                            self.open2, self.ckcgn2):
            vboxg6.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group7 = QGroupBox()
        self.group7.setTitle(' Debug ')
        self.ckdbg1 = QCheckBox('Execute self checks to find errors in Nuitka')
        self.ckdbg2 = QCheckBox('Keep debug info in resulting file')
        self.ckdbg3 = QCheckBox('Traced execution output')
        self.ckdbg4 = QCheckBox('Allow compile edited C++ file, debug changes')
        self.ckdbg5 = QCheckBox('Use experimental features')
        vboxg7 = QVBoxLayout(self.group7)
        for each_widget in (self.ckdbg1, self.ckdbg2, self.ckdbg3,
                            self.ckdbg4, self.ckdbg5):
            vboxg7.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group8 = QGroupBox()
        self.group8.setTitle(' Tracing ')
        self.cktrc1 = QCheckBox('Show Scons in non-quiet mode, showing command')
        self.cktrc2 = QCheckBox('Show Progress information and statistics')
        self.cktrc3 = QCheckBox('Show Verbose output details')
        vboxg8 = QVBoxLayout(self.group8)
        for each_widget in (self.cktrc1, self.cktrc2, self.cktrc3):
            vboxg8.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group9 = QGroupBox()
        self.group9.setTitle(' Extras ')
        self.group9.setCheckable(True)
        self.group9.toggled.connect(self.group9.hide)
        self.nice = QSpinBox()
        self.nice.setValue(20)
        self.nice.setMaximum(20)
        self.nice.setMinimum(0)
        self.ckxtr1 = QCheckBox('Open Target Directory later')
        self.ckxtr2 = QCheckBox('Save a LOG file to target later')
        self.ckxtr3 = QCheckBox('Save SH Bash script to reproduce Nuitka build')
        try:
            self.vinfo = QLabel('<center> <b> Nuitka Backend Version: </b>' +
                            getoutput('nuitka --version',).strip())
        except:
            self.vinfo = QLabel('<b>Warning: Failed to query Nuitka Backend!')
        vboxg9 = QVBoxLayout(self.group9)
        for each_widget in (QLabel('Backend CPU Priority'), self.nice,
                            self.ckxtr1, self.ckxtr2, self.ckxtr3, self.vinfo):
            vboxg9.addWidget(each_widget)

        self.group10 = QGroupBox()
        self.group10.setTitle(' Documentation ')
        self.group10.setCheckable(True)
        self.group10.toggled.connect(self.group10.hide)
        vboxg10 = QVBoxLayout(self.group10)
        for each_widget in (QLabel('''<a href=
            "file:///usr/share/doc/nuitka/README.pdf.gz">
            <small><center> Nuitka User Documentation Local PDF </a>'''),
            QLabel('''<a href=
            "file:///usr/share/doc/nuitka/Developer_Manual.pdf.gz">
            <small><center> Nuitka Developer Documentation Local PDF </a>'''),
            QLabel('''<a href="http://nuitka.net/doc/user-manual.html">
            <small><center> Nuitka User Documentation On Line HTML </a>'''),
            QLabel('''<a href="http://nuitka.net/doc/developer-manual.html">
            <small><center> Nuitka Developer Documentation On Line HTML </a>''')
             ):
            vboxg10.addWidget(each_widget)
            each_widget.setOpenExternalLinks(True)
            each_widget.setTextInteractionFlags(Qt.LinksAccessibleByMouse)

        [a.setChecked(True) for a in (self.ckgrl1, self.ckgrl2, self.ckgrl4,
            self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8, self.ckrec0,
            self.ckrec1, self.ckrec2, self.ckexe1, self.ckcgn2, self.ckdbg1,
            self.ckdbg3, self.ckdbg4, self.ckdbg5, self.cktrc1, self.cktrc2,
            self.cktrc3, self.ckxtr1, self.ckxtr2, self.ckxtr3,)]

        self.button = QPushButton(QIcon.fromTheme("face-cool"),
                                  'Compile Python')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((
            QLabel('<b>Python Code to Binary Executable Compiler'), self.group0,
            self.group6, self.group1, self.group2, self.group3, self.group4,
            self.group5, self.group7, self.group8, self.group9, self.group10,
            self.button, ))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Nuitka")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
          ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__,
            HELPMSG))

    def run(self):
        ' run the compile '
        target = path.abspath(str(self.infile.text()).strip())
        self.button.setDisabled(True)
        self.output.clear()
        self.output.show()
        self.output.setFocus()
        self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now())))
        self.output.append(self.formatInfoMsg(' INFO: Dumping Internal Tree'))
        try:
            self.dumptree.setPlainText(
                getoutput('nuitka --dump-tree {}'.format(target)))
            self.dumptree.setMinimumSize(100, 500)
        except:
            self.output.append(self.formatErrorMsg('ERROR:FAIL: Internal Tree'))
        self.output.append(self.formatInfoMsg(' INFO: OK: Parsing Arguments'))
        cmd = ' '.join(('nice --adjustment={} nuitka'.format(self.nice.value()),

            # output
            '--remove-output' if self.ckcgn2.isChecked() is True else '',

            # general
            '--exe' if self.ckgrl1.isChecked() is True else '',
            '--python-debug' if self.ckgrl2.isChecked() is True else '',
            '--verbose' if self.cktrc3.isChecked() is True else '',
            '--windows-target' if self.ckgrl3.isChecked() is True else '',
            '--windows-disable-console' if self.ckgrl4.isChecked() is True else '',
            '--lto' if self.ckgrl5.isChecked() is True else '',
            '--clang' if self.ckgrl6.isChecked() is True else '',
            '--improved' if self.ckgrl7.isChecked() is True else '',
            '--warn-implicit-exceptions' if self.ckgrl8.isChecked() is True else '',

            # recursion control
            '--recurse-stdlib' if self.ckrec0.isChecked() is True else '',
            '--recurse-none' if self.ckrec1.isChecked() is True else '',
            '--recurse-all' if self.ckrec2.isChecked() is True else '',

            # execution after compilation
            '--execute' if self.ckexe0.isChecked() is True else '',
            '--keep-pythonpath' if self.ckexe1.isChecked() is True else '',

            # code generation
            '--code-gen-no-statement-lines' if self.chdmp1.isChecked() is True else '',
            '--no-optimization' if self.chdmp2.isChecked() is True else '',

            # debug
            '--debug' if self.ckdbg1.isChecked() is True else '',
            '--unstripped' if self.ckdbg2.isChecked() is True else '',
            '--trace-execution' if self.ckdbg3.isChecked() is True else '',
            '--c++-only' if self.ckdbg4.isChecked() is True else '',
            '--experimental' if self.ckdbg5.isChecked() is True else '',

            # tracing
            '--show-scons' if self.cktrc1.isChecked() is True else '',
            '--show-progress' if self.cktrc2.isChecked() is True else '',
            '--verbose' if self.cktrc3.isChecked() is True else '',

            # non boolean parametrization
            '--python-version={}'.format(self.pyver.currentText()),
            '--jobs={}'.format(self.jobs.value()),
            '--output-dir="{}"'.format(self.outdir.text()),
            target))
        self.output.append(self.formatInfoMsg(' INFO: Command: {}'.format(cmd)))
        self.output.append(self.formatInfoMsg(' INFO: OK: Starting to Compile'))
        self.process.start(cmd)
        if not self.process.waitForStarted():
            self.output.append(self.formatErrorMsg('ERROR: FAIL: Compile Fail'))
            self.output.append(self.formatErrorMsg('ERROR:FAIL:{}'.format(cmd)))
            self.button.setEnabled(True)
            return
        # write a .sh bash script file on target
        if self.ckxtr3.isChecked() is True:
            sh_file = 'nuitka_compile_python_to_cpp.sh'
            with open(path.join(str(self.outdir.text()), sh_file), 'w') as _sh:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash:
                    {}'''.format(sh_file)))
                _sh.write('#!/usr/bin/env bash {}{}'.format(linesep, cmd))
                _sh.close()
            self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775'))
            try:
                chmod(path.join(str(self.outdir.text()), sh_file), 0775)  # Py2
            except:
                chmod(path.join(str(self.outdir.text()), sh_file), 0o775)  # Py3

    def _process_finished(self):
        """sphinx-build finished sucessfully"""
        self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now())))
        if self.ckxtr2.isChecked() is True:
            log_file = 'nuitka_ninja.log'
            with open(path.join(str(self.outdir.text()), log_file), 'w') as log:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing LOG:
                    {}'''.format(log_file)))
                log.write(self.output.toPlainText())
        if self.ckxtr1.isChecked() is True:
            try:
                startfile(path.abspath(str(self.outdir.text())))
            except:
                Popen(["xdg-open", path.abspath(str(self.outdir.text()))])
        self.button.setDisabled(False)
        self.output.show()
        self.output.setFocus()
        self.output.selectAll()

    def toggle_gral_group(self):
        ' toggle on or off the checkboxes '
        if self.group1.isChecked() is True:
            [a.setChecked(True) for a in (self.ckgrl1, self.ckgrl2, self.ckgrl4,
            self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8)]
            self.group1.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in (self.ckgrl1, self.ckgrl2,
            self.ckgrl4, self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8)]
            self.group1.graphicsEffect().setEnabled(True)

    def readOutput(self):
        """Read and append sphinx-build output to the logBrowser"""
        self.output.append(str(self.process.readAllStandardOutput()))

    def readErrors(self):
        """Read and append sphinx-build errors to the logBrowser"""
        self.output.append(self.formatErrorMsg(str(
                                        self.process.readAllStandardError())))

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)