Example #1
0
class Slider(QWidget):
    def __init__(self,
                 caption,
                 default_value,
                 minimum_value=1,
                 maximum_value=60,
                 single_step=1,
                 page_step=6,
                 caption_size=None,
                 unit='',
                 time=False,
                 tooltip=''):
        QWidget.__init__(self)

        self.value = default_value
        self.unit = unit
        self.time = time

        description = QLabel(caption)
        description.setWordWrap(True)
        description.setToolTip(tooltip)
        if caption_size:
            description.setMaximumWidth(caption_size)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMaximum(maximum_value)
        self.slider.setMinimum(minimum_value)
        self.slider.setSingleStep(single_step)
        self.slider.setPageStep(page_step)
        self.slider.setToolTip(tooltip)
        #self.slider.setTickInterval(2)
        #self.slider.setTickPosition(QSlider.TicksBelow)
        self.slider.valueChanged.connect(self.__on_change)

        self.value_label = QLabel()

        hbox = QHBoxLayout()
        hbox.addWidget(description)
        hbox.addWidget(self.slider)
        hbox.addWidget(self.value_label)
        hbox.setMargin(0)
        self.setLayout(hbox)
        self.setContentsMargins(5, 0, 5, 0)
        self.slider.setValue(self.value)
        self.__on_change(self.value)

    def __on_change(self, value):
        # FIXME: Fill with spaces to reach the maximum length
        self.value = value
        unit = self.unit
        if self.time:
            minutes = timedelta(minutes=self.value)
            date = datetime(1, 1, 1) + minutes
            text = "%02dh %02dm" % (date.hour, date.minute)
        else:
            text = "%s %s" % (self.value, self.unit)
        self.value_label.setText(text)

    def get_value(self):
        return int(self.slider.value())
Example #2
0
 def getSlider(self, parent):
     sld = QSlider(parent)
     sld.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
     sld.setMinimum(0)
     sld.setMaximum(99)
     sld.setPageStep(10)
     sld.setPageStep(10)
     sld.setMinimumHeight(50)
     sld.setTickInterval(25)
     sld.setTickPosition(QSlider.TicksBothSides)
     return sld
Example #3
0
 def getSlider(self, parent):
     sld = QSlider(parent)
     sld.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
     sld.setMinimum(0)
     sld.setMaximum(99)
     sld.setPageStep(10)
     sld.setPageStep(10)
     sld.setMinimumHeight(50)
     sld.setTickInterval(25)
     sld.setTickPosition(QSlider.TicksBothSides)
     return sld
Example #4
0
class QCustomSlider(QWidget):
    def __init__(self, sliderOrientation=None):
        super(QCustomSlider, self).__init__()
        self._slider = QSlider(sliderOrientation)

        self.setLayout(QVBoxLayout())

        self._labelTicksWidget = QWidget(self)
        self._labelTicksWidget.setLayout(QHBoxLayout())
        self._labelTicksWidget.layout().setContentsMargins(0, 0, 0, 0)

        self.layout().addWidget(self._slider)
        self.layout().addWidget(self._labelTicksWidget)

    def setTickLabels(self, listWithLabels):
        lengthOfList = len(listWithLabels)
        for index, label in enumerate(listWithLabels):
            label = QLabel(str(label))
            label.setContentsMargins(0, 0, 0, 0)
            if index > lengthOfList/3:
                label.setAlignment(QtCore.Qt.AlignCenter)
            if index > 2*lengthOfList/3:
                label.setAlignment(QtCore.Qt.AlignRight)
            self._labelTicksWidget.layout().addWidget(label)

    def setRange(self, mini, maxi):
        self._slider.setRange(mini, maxi)

    def setPageStep(self, value):
        self._slider.setPageStep(value)

    def setTickInterval(self, value):
        self._slider.setTickInterval(value)

    def setTickPosition(self, position):
        self._slider.setTickPosition(position)

    def setValue(self, value):
        self._slider.setValue(value)

    def onValueChangedCall(self, function):
        self._slider.valueChanged.connect(function)
Example #5
0
class MainWin(QMainWindow):
    def __init__(self, mx, spurs, fef, parent=None, plot_lib='mpl'):
        QMainWindow.__init__(self, parent)

        self.mx = mx
        self.spurset = spurs
        self.fef = fef
    
        if plot_lib == 'qwt':
            from chart.qwtchart import qwtchart as chart
        elif plot_lib == 'mpl':
            from chart.mplchart import mplchart as chart
        elif plot_lib == 'pg':
            from chart.pyqtgraphchart import pyqtgraphchart as chart
        else:
            raise NotImplementedError

        self.chart = chart(self.spurset, self.fef, self)
        self.create_menu_bar()
        self.create_main_frame()
        self.hookup()

    def hookup(self):
        # connect all the objects that are supposed to be watching each other
        # for changes and updates.
        self.mx.register(self.chart.draw_spurs)
        self.spurset.register(self.chart.draw_spurs)
        self.chart.picker_watch(self.fef)
        self.fef.register(self.chart.draw_fef)
        self.chart.draw_spurs(self.spurset)
        self.chart.draw_fef(self.fef)

    def IF_slide(self, i):
        """ callback method for the IF selection slider"""
        self.IFtextbox.setText(str(i))
        self.mx.IF = i

    def about(self):
        msg = '''
        A frequency-planing tool based on the method of spur distances.
        (A reference to the article will go here)
        For more info, view the README included with this program.

        Patrick Yeon, 2012'''
        QMessageBox.about(self, 'Spur Distance Chart', msg.strip())

    def mxtypecb(self, i):
        """ callback method for mixer configuration selection combobox"""
        self.mx.m, self.mx.n = [(-1, 1), (1, -1), (1,1)][i]
        # trigger anything watching the mixer
        self.mx.update_watchers()

    def create_main_frame(self):
        self.main_frame = QWidget()
        # Looking at the main frame as two columns. On the left there is the
        # chart and the IF control. In the right column we'll have range
        # settings, mixer settings, and maybe other stuff that comes up?

        self.IFtextbox = QLineEdit()
        self.IFtextbox.setMinimumWidth(6)
        self.IFtextbox.setText(str(self.spurset.mixer.IF))
        # TODO link up the textbox so that it can also be input

        self.IFslider = QSlider(Qt.Horizontal)
        # TODO I'd really like some form of slider that doesn't actually limit
        # the user. Also, if IFtextbox could modify the IF, that'd be nice.
        self.IFslider.setRange(int(self.mx.IF * 0.1), (self.mx.IF * 5))
        self.IFslider.setValue(self.mx.IF)
        self.IFslider.setTracking(True)
        self.IFslider.setTickPosition(QSlider.TicksAbove)
        step = max(1, int(0.01 * self.mx.IF))
        self.IFslider.setSingleStep(step)
        self.IFslider.setPageStep(step * 10)
        self.IFcid = self.connect(self.IFslider, SIGNAL('valueChanged(int)'),
                                  self.IF_slide)

        IFbar = QHBoxLayout()
        IFbar.addWidget(QLabel('IF'))
        IFbar.addWidget(self.IFtextbox)
        IFbar.addWidget(self.IFslider)
        IFbar.addStretch()

        leftcol = QVBoxLayout()
        leftcol.addWidget(self.chart.plot)
        leftcol.addLayout(IFbar)

        # left column done. Now the right-hand side
        rangebox = QVBoxLayout()
        for (prop, name, f) in [(spurset.RFmin, 'RFmin', self.spurset.RFmin),
                                (spurset.RFmax, 'RFmax', self.spurset.RFmax),
                                (spurset.dspan, 'dspan', self.spurset.dspan)]:
            rangebox.addLayout(Fbar(self.spurset, prop,
                                    name, f, 0, 10000))
        autocb = QCheckBox('Auto')
        # Disable it, won't be implemented for release
        # but leave it there, to nag me into doing it.
        autocb.setDisabled(True)
        rangebox.addWidget(autocb)

        # a line to report the front-end filter's limits
        fefstat = QHBoxLayout()
        fefstat.addWidget(QLabel('Filter Range: '))
        fefrange = QLabel('%d - %d' % (self.fef.start, self.fef.stop))
        # TODO not sure about the lambda here. Feels like if I give it time,
        # I'll sort out a sensible overall connection scheme.
        self.fef.register(lambda o: fefrange.setText('%d - %d' % 
                                                     (self.fef.start,
                                                      self.fef.stop)))
        fefstat.addWidget(fefrange)

        # mixer high/low-side injection picker
        mxbar = QHBoxLayout()
        mxbar.addWidget(QLabel('IF = '))
        mxtype = QComboBox()
        mxtype.addItem('LO - RF')
        mxtype.addItem('RF - LO')
        mxtype.addItem('RF + LO')
        # TODO this is ugly
        mxtype.setCurrentIndex([(-1, 1), (1, -1), (1,1)].index((self.mx.m,
                                                                self.mx.n)))
        self.mxtypecid = self.connect(mxtype,
                                      SIGNAL('currentIndexChanged(int)'),
                                      self.mxtypecb)
        mxbar.addWidget(mxtype)

        # alright, the actual column proper in the layout
        vbar = QVBoxLayout()
        vbar.addLayout(rangebox)
        vbar.addLayout(fefstat)
        vbar.addLayout(mxbar)
        legend = self.chart.legend()
        vbar.addWidget(legend)
        # need to let the legend stretch so that everything fits in it
        vbar.setStretchFactor(legend, 1)
        vbar.addStretch()

        hbox = QHBoxLayout()
        hbox.addLayout(leftcol)
        hbox.addLayout(vbar)
        # make sure the legend doesn't stretch so far horizontally that the
        # chart suffers considerable loss of space.
        hbox.setStretchFactor(leftcol, 5)
        hbox.setStretchFactor(vbar, 1)

        self.main_frame.setLayout(hbox)
        self.setCentralWidget(self.main_frame)

    def create_menu_bar(self):
        filemenu = self.menuBar().addMenu('&File')
        close = QAction('&Quit', self)
        close.setShortcut('Ctrl+W')
        self.connect(close, SIGNAL('triggered()'), self.close)
        filemenu.addAction(close)

        helpmenu = self.menuBar().addMenu('&Help')
        about  = QAction('&About', self)
        about.setShortcut('F1')
        self.connect(about, SIGNAL('triggered()'), self.about)
        helpmenu.addAction(about)
Example #6
0
class Window(QWidget):

    def __init__(self, parent = None):

        QWidget.__init__(self, parent)

        format = QAudioFormat()
        format.setChannels(1)
        format.setFrequency(22050)
        format.setSampleSize(16)
        format.setCodec("audio/pcm")
        format.setByteOrder(QAudioFormat.LittleEndian)
        format.setSampleType(QAudioFormat.SignedInt)
        self.output = QAudioOutput(format, self)

        self.frequency = 440
        self.volume = 0
        self.buffer = QBuffer()
        self.data = QByteArray()

        self.deviceLineEdit = QLineEdit()
        self.deviceLineEdit.setReadOnly(True)
        self.deviceLineEdit.setText(QAudioDeviceInfo.defaultOutputDevice().deviceName())

        self.pitchSlider = QSlider(Qt.Horizontal)
        self.pitchSlider.setMaximum(100)
        self.volumeSlider = QSlider(Qt.Horizontal)
        self.volumeSlider.setMaximum(32767)
        self.volumeSlider.setPageStep(1024)

        self.playButton = QPushButton(self.tr("&Play"))

        self.pitchSlider.valueChanged.connect(self.changeFrequency)
        self.volumeSlider.valueChanged.connect(self.changeVolume)
        self.playButton.clicked.connect(self.play)

        formLayout = QFormLayout()
        formLayout.addRow(self.tr("Device:"), self.deviceLineEdit)
        formLayout.addRow(self.tr("P&itch:"), self.pitchSlider)
        formLayout.addRow(self.tr("&Volume:"), self.volumeSlider)

        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.playButton)
        buttonLayout.addStretch()

        horizontalLayout = QHBoxLayout(self)
        horizontalLayout.addLayout(formLayout)
        horizontalLayout.addLayout(buttonLayout)

    def changeFrequency(self, value):

        self.frequency = 440 + (value * 2)

    def play(self):

        if self.output.state() == QAudio.ActiveState:
            self.output.stop()

        if self.buffer.isOpen():
            self.buffer.close()

        self.createData()

        self.buffer.setData(self.data)
        self.buffer.open(QIODevice.ReadOnly)
        self.buffer.seek(0)

        self.output.start(self.buffer)

    def changeVolume(self, value):

        self.volume = value

    def createData(self):

        # Create 2 seconds of data with 22050 samples per second, each sample
        # being 16 bits (2 bytes).

        self.data.clear()
        for i in xrange(2 * 22050):
            t = i / 22050.0
            value = int(self.volume * sin(2 * pi * self.frequency * t))
            self.data.append(struct.pack("<h", value))
Example #7
0
class QtSlider(QtControl, ProxySlider):
    """ A Qt implementation of an Enaml ProxySlider.

    """
    #: A reference to the widget created by the proxy.
    widget = Typed(QSlider)

    #: Cyclic notification guard flags.
    _guard = Int(0)

    #--------------------------------------------------------------------------
    # Initialization API
    #--------------------------------------------------------------------------
    def create_widget(self):
        """ Create the underlying QSlider widget.

        """
        self.widget = QSlider(self.parent_widget())

    def init_widget(self):
        """ Initialize the underlying widget.

        """
        super(QtSlider, self).init_widget()
        d = self.declaration
        self.set_minimum(d.minimum)
        self.set_maximum(d.maximum)
        self.set_value(d.value)
        self.set_orientation(d.orientation)
        self.set_page_step(d.page_step)
        self.set_single_step(d.single_step)
        self.set_tick_interval(d.tick_interval)
        self.set_tick_position(d.tick_position)
        self.set_tracking(d.tracking)
        self.widget.valueChanged.connect(self.on_value_changed)

    #--------------------------------------------------------------------------
    # Signal Handlers
    #--------------------------------------------------------------------------
    def on_value_changed(self):
        """ Send the 'value_changed' action to the Enaml widget when the
        slider value has changed.

        """
        if not self._guard & VALUE_FLAG:
            self._guard |= VALUE_FLAG
            try:
                self.declaration.value = self.widget.value()
            finally:
                self._guard &= ~VALUE_FLAG

    #--------------------------------------------------------------------------
    # ProxySlider API
    #--------------------------------------------------------------------------
    def set_maximum(self, maximum):
        """ Set the maximum value of the underlying widget.

        """
        self.widget.setMaximum(maximum)

    def set_minimum(self, minimum):
        """ Set the minimum value of the underlying widget.

        """
        self.widget.setMinimum(minimum)

    def set_value(self, value):
        """ Set the value of the underlying widget.

        """
        if not self._guard & VALUE_FLAG:
            self._guard |= VALUE_FLAG
            try:
                self.widget.setValue(value)
            finally:
                self._guard &= ~VALUE_FLAG

    def set_page_step(self, page_step):
        """ Set the page step of the underlying widget.

        """
        self.widget.setPageStep(page_step)

    def set_single_step(self, single_step):
        """ Set the single step of the underlying widget.

        """
        self.widget.setSingleStep(single_step)

    def set_tick_interval(self, interval):
        """ Set the tick interval of the underlying widget.

        """
        self.widget.setTickInterval(interval)

    def set_tick_position(self, tick_position):
        """ Set the tick position of the underlying widget.

        """
        self.widget.setTickPosition(TICK_POSITION[tick_position])

    def set_orientation(self, orientation):
        """ Set the orientation of the underlying widget.

        """
        self.widget.setOrientation(ORIENTATION[orientation])

    def set_tracking(self, tracking):
        """ Set the tracking of the underlying widget.

        """
        self.widget.setTracking(tracking)
Example #8
0
class Window(QWidget):

    def __init__(self, parent = None):
    
        QWidget.__init__(self, parent)
        
        format = QAudioFormat()
        format.setChannels(1)
        format.setFrequency(22050)
        format.setSampleSize(16)
        format.setCodec("audio/pcm")
        format.setByteOrder(QAudioFormat.LittleEndian)
        format.setSampleType(QAudioFormat.SignedInt)
        self.output = QAudioOutput(format, self)
        
        self.frequency = 440
        self.volume = 0
        self.buffer = QBuffer()
        self.data = QByteArray()
        
        self.deviceLineEdit = QLineEdit()
        self.deviceLineEdit.setReadOnly(True)
        self.deviceLineEdit.setText(QAudioDeviceInfo.defaultOutputDevice().deviceName())
        
        self.pitchSlider = QSlider(Qt.Horizontal)
        self.pitchSlider.setMaximum(100)
        self.volumeSlider = QSlider(Qt.Horizontal)
        self.volumeSlider.setMaximum(32767)
        self.volumeSlider.setPageStep(1024)
        
        self.playButton = QPushButton(self.tr("&Play"))
        
        self.pitchSlider.valueChanged.connect(self.changeFrequency)
        self.volumeSlider.valueChanged.connect(self.changeVolume)
        self.playButton.clicked.connect(self.play)
        
        formLayout = QFormLayout()
        formLayout.addRow(self.tr("Device:"), self.deviceLineEdit)
        formLayout.addRow(self.tr("P&itch:"), self.pitchSlider)
        formLayout.addRow(self.tr("&Volume:"), self.volumeSlider)
        
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.playButton)
        buttonLayout.addStretch()
        
        horizontalLayout = QHBoxLayout(self)
        horizontalLayout.addLayout(formLayout)
        horizontalLayout.addLayout(buttonLayout)
    
    def changeFrequency(self, value):
    
        self.frequency = 440 + (value * 2)
    
    def play(self):
    
        if self.output.state() == QAudio.ActiveState:
            self.output.stop()
        
        if self.buffer.isOpen():
            self.buffer.close()
        
        self.createData()
        
        self.buffer.setData(self.data)
        self.buffer.open(QIODevice.ReadOnly)
        self.buffer.seek(0)
        
        self.output.start(self.buffer)
    
    def changeVolume(self, value):
    
        self.volume = value
    
    def createData(self):
    
        # Create 2 seconds of data with 22050 samples per second, each sample
        # being 16 bits (2 bytes).
        
        self.data.clear()
        for i in xrange(2 * 22050):
            t = i / 22050.0
            value = int(self.volume * sin(2 * pi * self.frequency * t))
            self.data.append(struct.pack("<h", value))
class MyMainWindow(QMainWindow):
    ' Main Window '
    def __init__(self, AUTO):
        ' Initialize QWidget inside MyMainWindow '
        super(MyMainWindow, self).__init__()
        QWidget.__init__(self)
        self.auto = AUTO
        self.statusBar().showMessage('               {}'.format(__doc__))
        self.setStyleSheet('QStatusBar{color:grey;}')
        self.setWindowTitle(__doc__)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setFont(QFont('Ubuntu Light', 10))
        self.setMaximumSize(QDesktopWidget().screenGeometry().width(),
                            QDesktopWidget().screenGeometry().height())

        self.base = path.abspath(path.join(getcwd(), str(datetime.now().year)))

        # 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)

        # process
        self.process1 = None
        self.process2 = None
        self.cmd1 = 'nice -n {n} arecord{v} -f {f} -c {c} -r {b} -t raw'
        self.cmd2 = 'oggenc - -r -C {c} -R {b} -q {q} {d}{t}{a} -o {o}'
        self.process3 = QProcess(self)
        #self.process3.finished.connect(self.on_process3_finished)
        #self.process3.error.connect(self.on_process3_error)

        self.cmd3 = ('nice -n 20 ' +
          'sox "{o}" -n spectrogram -x {x} -y {y} -z 99 -t "{o}" -o "{o}.png"')
        self.actual_file = ''

        # re starting timers, one stops, one starts
        self.timerFirst = QTimer(self)
        self.timerFirst.timeout.connect(self.end)
        self.timerSecond = QTimer(self)
        self.timerSecond.timeout.connect(self.run)

        # Proxy support, by reading http_proxy os env variable
        proxy_url = QUrl(environ.get('http_proxy', ''))
        QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy
            if str(proxy_url.scheme()).startswith('http')
            else QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(),
                 proxy_url.userName(), proxy_url.password())) \
            if 'http_proxy' in environ else None
        print((' INFO: Proxy Auto-Config as ' + str(proxy_url)))

        # basic widgets layouts and set up
        self.mainwidget = QTabWidget()
        self.mainwidget.setToolTip(__doc__)
        self.mainwidget.setMovable(True)
        self.mainwidget.setTabShape(QTabWidget.Triangular)
        self.mainwidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainwidget.setStyleSheet('QTabBar{color:white;font-weight:bold;}')
        self.mainwidget.setTabBar(TabBar(self))
        self.mainwidget.setTabsClosable(False)
        self.setCentralWidget(self.mainwidget)
        self.dock1 = QDockWidget()
        self.dock2 = QDockWidget()
        self.dock3 = QDockWidget()
        self.dock4 = QDockWidget()
        self.dock5 = QDockWidget()
        for a in (self.dock1, self.dock2, self.dock3, self.dock4, self.dock5):
            a.setWindowModality(Qt.NonModal)
            # a.setWindowOpacity(0.9)
            a.setWindowTitle(__doc__
                             if a.windowTitle() == '' else a.windowTitle())
            a.setStyleSheet('QDockWidget::title{text-align:center;}')
            self.mainwidget.addTab(a, QIcon.fromTheme("face-smile"),
                                   'Double Click Me')

        # Paleta de colores para pintar transparente
        self.palette().setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(self.palette())
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

        # toolbar and basic actions
        self.toolbar = QToolBar(self)
        self.toolbar.setIconSize(QSize(24, 24))
        # spacer widget for left
        self.left_spacer = QWidget(self)
        self.left_spacer.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        # spacer widget for right
        self.right_spacer = QWidget(self)
        self.right_spacer.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        qaqq = QAction(QIcon.fromTheme("application-exit"), 'Quit', self)
        qaqq.setShortcut('Ctrl+Q')
        qaqq.triggered.connect(exit)
        qamin = QAction(QIcon.fromTheme("go-down"), 'Minimize', self)
        qamin.triggered.connect(lambda: self.showMinimized())
        qamax = QAction(QIcon.fromTheme("go-up"), 'Maximize', self)
        qanor = QAction(QIcon.fromTheme("view-fullscreen"),
                        'AutoCenter AutoResize', self)
        qanor.triggered.connect(self.center)
        qatim = QAction(QIcon.fromTheme("mail-signed-verified"),
                        'View Date and Time', self)
        qatim.triggered.connect(self.timedate)
        qabug = QAction(QIcon.fromTheme("help-about"), 'Report a Problem', self)
        qabug.triggered.connect(lambda: qabug.setDisabled(True) if not call(
            'xdg-open mailto:' + '*****@*****.**'.decode('rot13'),
            shell=True) else ' ERROR ')
        qamax.triggered.connect(lambda: self.showMaximized())
        qaqt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self)
        qaqt.triggered.connect(lambda: QMessageBox.aboutQt(self))
        qakde = QAction(QIcon.fromTheme("help-about"), 'About KDE', self)
        if KDE:
            qakde.triggered.connect(KHelpMenu(self, "", False).aboutKDE)
        qaslf = QAction(QIcon.fromTheme("help-about"), 'About Self', self)
        if KDE:
            qaslf.triggered.connect(
                                KAboutApplicationDialog(aboutData, self).exec_)
        else:
            qaslf.triggered.connect(lambda: QMessageBox.about(self.mainwidget,
            __doc__, ''.join((__doc__, linesep, 'version ', __version__, ', (',
            __license__, '), by ', __author__, ', ( ', __email__, ' )', linesep
            ))))
        qafnt = QAction(QIcon.fromTheme("tools-check-spelling"),
                        'Set GUI Font', self)
        if KDE:
            font = QFont()
            qafnt.triggered.connect(lambda:
            self.setStyleSheet(''.join((
                '*{font-family:', str(font.toString()), '}'))
                if KFontDialog.getFont(font)[0] == QDialog.Accepted else ''))
        else:
            qafnt.triggered.connect(lambda:
                self.setStyleSheet(''.join(('*{font-family:',
                            str(QFontDialog.getFont()[0].toString()), '}'))))
        qasrc = QAction(QIcon.fromTheme("applications-development"),
                        'View Source Code', self)
        qasrc.triggered.connect(lambda:
                            call('xdg-open {}'.format(__file__), shell=True))
        qakb = QAction(QIcon.fromTheme("input-keyboard"),
                       'Keyboard Shortcuts', self)
        qakb.triggered.connect(lambda: QMessageBox.information(self.mainwidget,
                               'Keyboard Shortcuts', ' Ctrl+Q = Quit '))
        qapic = QAction(QIcon.fromTheme("camera-photo"),
                        'Take a Screenshot', self)
        qapic.triggered.connect(lambda: QPixmap.grabWindow(
            QApplication.desktop().winId()).save(QFileDialog.getSaveFileName(
            self.mainwidget, " Save Screenshot As ...", path.expanduser("~"),
            ';;(*.png) PNG', 'png')))
        qatb = QAction(QIcon.fromTheme("go-top"), 'Toggle ToolBar', self)
        qatb.triggered.connect(lambda: self.toolbar.hide()
                if self.toolbar.isVisible() is True else self.toolbar.show())
        qati = QAction(QIcon.fromTheme("zoom-in"),
                       'Switch ToolBar Icon Size', self)
        qati.triggered.connect(lambda:
            self.toolbar.setIconSize(self.toolbar.iconSize() * 4)
            if self.toolbar.iconSize().width() * 4 == 24
            else self.toolbar.setIconSize(self.toolbar.iconSize() / 4))
        qasb = QAction(QIcon.fromTheme("preferences-other"),
                       'Toggle Tabs Bar', self)
        qasb.triggered.connect(lambda: self.mainwidget.tabBar().hide()
                               if self.mainwidget.tabBar().isVisible() is True
                               else self.mainwidget.tabBar().show())
        qadoc = QAction(QIcon.fromTheme("help-browser"), 'On-line Docs', self)
        qadoc.triggered.connect(lambda: open_new_tab(str(__url__).strip()))
        qapy = QAction(QIcon.fromTheme("help-about"), 'About Python', self)
        qapy.triggered.connect(lambda: open_new_tab('http://python.org/about'))
        qali = QAction(QIcon.fromTheme("help-browser"), 'Read Licence', self)
        qali.triggered.connect(lambda: open_new_tab(__full_licence__))
        qacol = QAction(QIcon.fromTheme("preferences-system"), 'Set GUI Colors',
                        self)
        if KDE:
            color = QColor()
            qacol.triggered.connect(lambda:
                self.setStyleSheet(''.join(('* { background-color: ',
                                            str(color.name()), '}')))
                if KColorDialog.getColor(color, self) else '')
        else:
            qacol.triggered.connect(lambda: self.setStyleSheet(''.join((
                ' * { background-color: ', str(QColorDialog.getColor().name()),
                ' } '))))
        qatit = QAction(QIcon.fromTheme("preferences-system"),
                        'Set the App Window Title', self)
        qatit.triggered.connect(self.seTitle)
        self.toolbar.addWidget(self.left_spacer)
        self.toolbar.addSeparator()
        self.toolbar.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol,
            qatim, qatb, qafnt, qati, qasb, qatit, qapic, qadoc, qali, qaslf,
            qaqt, qakde, qapy, qabug))
        self.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.right_spacer)
        # define the menu
        menu = self.menuBar()
        # File menu items
        menu.addMenu('&File').addActions((qaqq, ))
        menu.addMenu('&Window').addActions((qamax, qanor, qamin))
        # Settings menu
        menu.addMenu('&Settings').addActions((qasrc, qacol, qafnt, qatim,
                                              qatb, qati, qasb, qapic))
        # Help menu items
        menu.addMenu('&Help').addActions((qadoc, qakb, qabug, qali,
                                          qaqt, qakde, qapy, qaslf))
        # Tray Icon
        tray = QSystemTrayIcon(QIcon.fromTheme("face-devilish"), self)
        tray.setToolTip(__doc__)
        traymenu = QMenu()
        traymenu.addActions((qamax, qanor, qamin, qaqq))
        tray.setContextMenu(traymenu)
        tray.show()

        def contextMenuRequested(point):
            ' quick and dirty custom context menu '
            menu = QMenu()
            menu.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol,
                qafnt, qati, qasb, qatb, qatim, qatit, qapic, qadoc, qali,
                qaslf, qaqt, qakde, qapy, qabug))
            menu.exec_(self.mapToGlobal(point))
        self.mainwidget.customContextMenuRequested.connect(contextMenuRequested)

        def must_be_checked(widget_list):
            ' widget tuple passed as argument should be checked as ON '
            for each_widget in widget_list:
                try:
                    each_widget.setChecked(True)
                except:
                    pass

        def must_have_tooltip(widget_list):
            ' widget tuple passed as argument should have tooltips '
            for each_widget in widget_list:
                try:
                    each_widget.setToolTip(each_widget.text())
                except:
                    each_widget.setToolTip(each_widget.currentText())
                finally:
                    each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        def must_autofillbackground(widget_list):
            ' widget tuple passed as argument should have filled background '
            for each_widget in widget_list:
                try:
                    each_widget.setAutoFillBackground(True)
                except:
                    pass

        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(False)
                        try:
                            each_widget.clicked.connect(lambda:
                            each_widget.graphicsEffect().setEnabled(True)
                            if each_widget.graphicsEffect().isEnabled() is False
                            else each_widget.graphicsEffect().setEnabled(False))
                        except:
                            each_widget.sliderPressed.connect(lambda:
                            each_widget.graphicsEffect().setEnabled(True)
                            if each_widget.graphicsEffect().isEnabled() is False
                            else each_widget.graphicsEffect().setEnabled(False))
                except:
                    pass

        #######################################################################

        # dock 1
        QLabel('<h1 style="color:white;"> Record !</h1>', self.dock1).resize(
               self.dock3.size().width() / 4, 25)
        self.group1 = QGroupBox()
        self.group1.setTitle(__doc__)

        self.spec = QPushButton(self)
        self.spec.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.spec.setMinimumSize(self.spec.size().width(), 250)
        self.spec.setFlat(True)
        self.spec.clicked.connect(self.spectro)

        self.clock = QLCDNumber()
        self.clock.setSegmentStyle(QLCDNumber.Flat)
        self.clock.setMinimumSize(self.clock.size().width(), 50)
        self.clock.setNumDigits(25)
        self.timer1 = QTimer(self)
        self.timer1.timeout.connect(lambda: self.clock.display(
            datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        self.timer1.start(1000)
        self.clock.setToolTip(datetime.now().strftime("%c %x"))
        self.clock.setCursor(QCursor(Qt.CrossCursor))

        self.diskBar = QProgressBar()
        self.diskBar.setMinimum(0)
        self.diskBar.setMaximum(statvfs(HOME).f_blocks *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
        self.diskBar.setValue(statvfs(HOME).f_bfree *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
        self.diskBar.setToolTip(str(statvfs(HOME).f_bfree *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024) + ' Gigabytes free')

        self.feedback = QPlainTextEdit(''.join(('<center><h3>', __doc__,
            ', version', __version__, __license__, ' <br> by ', __author__,
            ' <i>(Dev)</i>, Radio Comunitaria FM Reconquista <i>(Q.A.)</i><br>',
            'FMReconquista.org.ar & GitHub.com/JuanCarlosPaco/Cinta-Testigo')))

        self.rec = QPushButton(QIcon.fromTheme("media-record"), 'Record')
        self.rec.setMinimumSize(self.rec.size().width(), 50)
        self.rec.clicked.connect(self.go)  # self.run

        self.stop = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop')
        self.stop.clicked.connect(self.end)

        self.kill = QPushButton(QIcon.fromTheme("process-stop"), 'Kill')
        self.kill.clicked.connect(self.killer)

        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
            QLabel('<b style="color:white;"> Spectro'), self.spec,
            QLabel('<b style="color:white;"> Time '), self.clock,
            QLabel('<b style="color:white;"> Disk '), self.diskBar,
            QLabel('<b style="color:white;"> STDOUT + STDIN '), self.feedback,
            QLabel('<b style="color:white;"> Record '), self.rec, self.stop,
            self.kill):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(__doc__)

        self.slider = QSlider(self)
        self.slid_l = QLabel(self.slider)
        self.slider.setCursor(QCursor(Qt.OpenHandCursor))
        self.slider.sliderPressed.connect(lambda:
                            self.slider.setCursor(QCursor(Qt.ClosedHandCursor)))
        self.slider.sliderReleased.connect(lambda:
                            self.slider.setCursor(QCursor(Qt.OpenHandCursor)))
        self.slider.valueChanged.connect(lambda:
                            self.slider.setToolTip(str(self.slider.value())))
        self.slider.valueChanged.connect(lambda: self.slid_l.setText(
                    '<h2 style="color:white;">{}'.format(self.slider.value())))
        self.slider.setMinimum(10)
        self.slider.setMaximum(99)
        self.slider.setValue(30)
        self.slider.setOrientation(Qt.Vertical)
        self.slider.setTickPosition(QSlider.TicksBothSides)
        self.slider.setTickInterval(2)
        self.slider.setSingleStep(10)
        self.slider.setPageStep(10)

        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (
            QLabel('<b style="color:white;">MINUTES of recording'), self.slider,
            QLabel('<b style="color:white;"> Default: 30 Min')):
            vboxg2.addWidget(each_widget)

        group3 = QGroupBox()
        group3.setTitle(__doc__)
        try:
            self.label2 = QLabel(getoutput('sox --version', shell=True))
            self.label4 = QLabel(getoutput('arecord --version', shell=1)[:25])
            self.label6 = QLabel(str(getoutput('oggenc --version', shell=True)))
        except:
            print(''' ERROR: No SOX, OGGenc avaliable !
                  ( sudo apt-get install vorbis-tools sox alsa-utils ) ''')
            exit()

        self.button5 = QPushButton(QIcon.fromTheme("audio-x-generic"),
                                   'OGG --> ZIP')
        self.button5.clicked.connect(lambda: make_archive(
            str(QFileDialog.getSaveFileName(self, "Save OGG to ZIP file As...",
            getcwd(), ';;(*.zip)', 'zip')).replace('.zip', ''), "zip",
            path.abspath(path.join(getcwd(), str(datetime.now().year)))))

        self.button1 = QPushButton(QIcon.fromTheme("folder-open"), 'Files')
        self.button1.clicked.connect(lambda:
                                     call('xdg-open ' + getcwd(), shell=True))

        self.button0 = QPushButton(
            QIcon.fromTheme("preferences-desktop-screensaver"), 'LCD OFF')
        self.button0.clicked.connect(lambda:
            call('sleep 3 ; xset dpms force off', shell=True))

        vboxg3 = QVBoxLayout(group3)
        for each_widget in (
            QLabel('<b style="color:white;"> OGG Output Codec '), self.label6,
            QLabel('<b style="color:white;"> Raw Record Backend '), self.label4,
            QLabel('<b style="color:white;"> Helper Libs '), self.label2,
            QLabel('<b style="color:white;"> OGG ZIP '), self.button5,
            QLabel('<b style="color:white;"> Files '), self.button1,
            QLabel('<b style="color:white;"> LCD '), self.button0):
            vboxg3.addWidget(each_widget)
        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)
        self.dock1.setWidget(container)

        # dock 2
        QLabel('<h1 style="color:white;"> Hardware !</h1>', self.dock2).resize(
               self.dock2.size().width() / 4, 25)
        try:
            audioDriverStr = {Solid.AudioInterface.Alsa: "ALSA",
                Solid.AudioInterface.OpenSoundSystem: "Open Sound",
                Solid.AudioInterface.UnknownAudioDriver: "Unknown?"}
            audioInterfaceTypeStr = {
                Solid.AudioInterface.AudioControl: "Control",
                Solid.AudioInterface.UnknownAudioInterfaceType: "Unknown?",
                Solid.AudioInterface.AudioInput: "In",
                Solid.AudioInterface.AudioOutput: "Out"}
            soundcardTypeStr = {
                Solid.AudioInterface.InternalSoundcard: "Internal",
                Solid.AudioInterface.UsbSoundcard: "USB3",
                Solid.AudioInterface.FirewireSoundcard: "FireWire",
                Solid.AudioInterface.Headset: "Headsets",
                Solid.AudioInterface.Modem: "Modem"}
            display = QTreeWidget()
            display.setAlternatingRowColors(True)
            display.setHeaderLabels(["Items", "ID", "Drivers", "I / O", "Type"])
            display.setColumnWidth(0, 350)
            display.setColumnWidth(1, 350)
            display.setColumnWidth(3, 75)
            # retrieve a list of Solid.Device for this machine
            deviceList = Solid.Device.allDevices()
            # filter the list of all devices and display matching results
            # note that we never create a Solid.AudioInterface object, but
            # receive one from the 'asDeviceInterface' call
            for device in deviceList:
                if device.isDeviceInterface(
                                         Solid.DeviceInterface.AudioInterface):
                    audio = device.asDeviceInterface(
                            Solid.DeviceInterface.AudioInterface)
                    devtype = audio.deviceType()
                    devstr = []
                    for key in audioInterfaceTypeStr:
                        flag = key & devtype
                        if flag:
                            devstr.append(audioInterfaceTypeStr[key])
                    QTreeWidgetItem(display, [device.product(), audio.name(),
                        audioDriverStr[audio.driver()], "/".join(devstr),
                        soundcardTypeStr[audio.soundcardType()]])
            self.dock2.setWidget(display)
        except:
            self.dock2.setWidget(QLabel(""" <center style='color:white;'>
            <h1>:(<br>ERROR: Please, install PyKDE !</h1><br>
            <br><i> (Sorry, can not use non-Qt Libs). Thanks </i><center>"""))

        ## dock 3
        QLabel('<h1 style="color:white;"> Previews !</h1>', self.dock3).resize(
               self.dock3.size().width() / 4, 25)
        self.fileView = QColumnView()
        self.fileView.updatePreviewWidget.connect(self.play)
        self.fileView.setToolTip(' Browse and Preview Files ')
        self.media = None
        self.model = QDirModel()
        self.fileView.setModel(self.model)
        self.dock3.setWidget(self.fileView)

        # dock4
        QLabel('<h1 style="color:white;"> Setup !</h1>', self.dock4).resize(
               self.dock4.size().width() / 4, 25)
        self.group4 = QGroupBox()
        self.group4.setTitle(__doc__)

        self.combo0 = QComboBox()
        self.combo0.addItems(['S16_LE', 'S32_LE', 'S16_BE', 'U16_LE', 'U16_BE',
          'S24_LE', 'S24_BE', 'U24_LE', 'U24_BE', 'S32_BE', 'U32_LE', 'U32_BE'])

        self.combo1 = QComboBox()
        self.combo1.addItems(['1', '-1', '0', '2', '3', '4',
                              '5', '6', '7', '8', '9', '10'])

        self.combo2 = QComboBox()
        self.combo2.addItems(['128', '256', '512', '1024', '64', '32', '16'])

        self.combo3 = QComboBox(self)
        self.combo3.addItems(['MONO', 'STEREO', 'Surround'])

        self.combo4 = QComboBox()
        self.combo4.addItems(['44100', '96000', '48000', '32000',
                              '22050', '16000', '11025', '8000'])

        self.combo5 = QComboBox(self)
        self.combo5.addItems(['20', '19', '18', '17', '16', '15', '14', '13',
            '12', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0'])

        self.nepochoose = QCheckBox('Auto-Tag Files using Nepomuk Semantic')

        self.chckbx0 = QCheckBox('Disable Software based Volume Control')

        self.chckbx1 = QCheckBox('Output Sound Stereo-to-Mono Downmix')

        self.chckbx2 = QCheckBox('Add Date and Time MetaData to Sound files')

        self.chckbx3 = QCheckBox('Add Yourself as the Author Artist of Sound')

        vboxg4 = QVBoxLayout(self.group4)
        for each_widget in (
            QLabel('<b style="color:white;"> Sound OGG Quality'), self.combo1,
            QLabel('<b style="color:white;"> Sound Record Format'), self.combo0,
            QLabel('<b style="color:white;"> Sound KBps '), self.combo2,
            QLabel('<b style="color:white;"> Sound Channels '), self.combo3,
            QLabel('<b style="color:white;"> Sound Sample Rate '), self.combo4,
            QLabel('<b style="color:white;"> Sound Volume'), self.chckbx0,
            QLabel('<b style="color:white;"> Sound Mix'), self.chckbx1,
            QLabel('<b style="color:white;"> Sound Meta'), self.chckbx2,
            QLabel('<b style="color:white;"> Sound Authorship'), self.chckbx3,
            QLabel('<b style="color:white;"> CPUs Priority'), self.combo5,
            QLabel('<b style="color:white;">Nepomuk Semantic User Experience'),
            self.nepochoose):
            vboxg4.addWidget(each_widget)
        self.dock4.setWidget(self.group4)

        # dock 5
        QLabel('<h1 style="color:white;"> Voice Changer ! </h1>', self.dock5
               ).resize(self.dock5.size().width() / 3, 25)
        self.group5 = QGroupBox()
        self.group5.setTitle(__doc__)

        self.dial = QDial()
        self.dial.setCursor(QCursor(Qt.OpenHandCursor))
        self.di_l = QLabel(self.dial)
        self.di_l.resize(self.dial.size() / 8)
        self.dial.sliderPressed.connect(lambda:
                            self.dial.setCursor(QCursor(Qt.ClosedHandCursor)))
        self.dial.sliderReleased.connect(lambda:
                            self.dial.setCursor(QCursor(Qt.OpenHandCursor)))
        self.dial.valueChanged.connect(lambda:
                            self.dial.setToolTip(str(self.dial.value())))
        self.dial.valueChanged.connect(lambda: self.di_l.setText(
                    '<h1 style="color:white;">{}'.format(self.dial.value())))
        self.dial.setValue(0)
        self.dial.setMinimum(-999)
        self.dial.setMaximum(999)
        self.dial.setSingleStep(100)
        self.dial.setPageStep(100)
        self.dial.setWrapping(False)
        self.dial.setNotchesVisible(True)

        self.defo = QPushButton(QIcon.fromTheme("media-playback-start"), 'Run')
        self.defo.setMinimumSize(self.defo.size().width(), 50)
        self.defo.clicked.connect(lambda: self.process3.start(
            'play -q -V0 "|rec -q -V0 -n -d -R riaa pitch {} "'
            .format(self.dial.value()) if int(self.dial.value()) != 0 else
            'play -q -V0 "|rec -q -V0 --multi-threaded -n -d -R bend {} "'
            .format(' 3,2500,3 3,-2500,3 ' * 999)))

        self.qq = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop')
        self.qq.clicked.connect(self.process3.kill)

        self.die = QPushButton(QIcon.fromTheme("process-stop"), 'Kill')
        self.die.clicked.connect(lambda: call('killall rec', shell=True))

        vboxg5 = QVBoxLayout(self.group5)
        for each_widget in (self.dial, self.defo, self.qq, self.die):
            vboxg5.addWidget(each_widget)
        self.dock5.setWidget(self.group5)

        # configure some widget settings
        must_be_checked((self.nepochoose, self.chckbx1,
                         self.chckbx2, self.chckbx3))
        must_have_tooltip((self.label2, self.label4, self.label6, self.combo0,
            self.nepochoose, self.combo1, self.combo2, self.combo3, self.combo4,
            self.combo5, self.chckbx0, self.chckbx1, self.chckbx2, self.chckbx3,
            self.rec, self.stop, self.defo, self.qq, self.die, self.kill,
            self.button0, self.button1, self.button5))
        must_autofillbackground((self.clock, self.label2, self.label4,
            self.label6, self.nepochoose, self.chckbx0, self.chckbx1,
            self.chckbx2, self.chckbx3))
        must_glow((self.rec, self.dial, self.combo1))
        self.nepomuk_get('testigo')
        if self.auto is True:
            self.go()

    def play(self, index):
        ' play with delay '
        if not self.media:
            self.media = Phonon.MediaObject(self)
            audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
            Phonon.createPath(self.media, audioOutput)
        self.media.setCurrentSource(Phonon.MediaSource(
            self.model.filePath(index)))
        self.media.play()

    def end(self):
        ' kill it with fire '
        print((' INFO: Stoping Processes at {}'.format(str(datetime.now()))))
        self.process1.terminate()
        self.process2.terminate()
        self.feedback.setText('''
            <h5>Errors for RECORDER QProcess 1:</h5>{}<hr>
            <h5>Errors for ENCODER QProcess 2:</h5>{}<hr>
            <h5>Output for RECORDER QProcess 1:</h5>{}<hr>
            <h5>Output for ENCODER QProcess 2:</h5>{}<hr>
            '''.format(self.process1.readAllStandardError(),
                       self.process2.readAllStandardError(),
                       self.process1.readAllStandardOutput(),
                       self.process2.readAllStandardOutput(),
        ))

    def killer(self):
        ' kill -9 '
        QMessageBox.information(self.mainwidget, __doc__,
            ' KILL -9 was sent to the multi-process backend ! ')
        self.process1.kill()
        self.process2.kill()

    def go(self):
        ' run timeout re-starting timers '
        self.timerFirst.start(int(self.slider.value()) * 60 * 1000 + 2000)
        self.timerSecond.start(int(self.slider.value()) * 60 * 1000 + 2010)
        self.run()

    def run(self):
        ' run forest run '
        print((' INFO: Working at {}'.format(str(datetime.now()))))

        chnl = 1 if self.combo3.currentText() == 'MONO' else 2
        print((' INFO: Using {} Channels . . . '.format(chnl)))

        btrt = int(self.combo4.currentText())
        print((' INFO: Using {} Hz per Second . . . '.format(btrt)))

        threshold = int(self.dial.value())
        print((' INFO: Using Thresold of {} . . . '.format(threshold)))

        print((' INFO: Using Recording time of {}'.format(self.slider.value())))

        frmt = str(self.combo0.currentText()).strip()
        print((' INFO: Using Recording quality of {} ...'.format(frmt)))

        qlt = str(self.combo1.currentText()).strip()
        print((' INFO: Using Recording quality of {} ...'.format(qlt)))

        prio = str(self.combo5.currentText()).strip()
        print((' INFO: Using CPU Priority of {} ...'.format(prio)))

        downmix = '--downmix ' if self.chckbx1.isChecked() is True else ''
        print((' INFO: Using Downmix is {} ...'.format(downmix)))

        aut = '-a ' + getuser() if self.chckbx3.isChecked() is True else ''
        print((' INFO: The Author Artist of this sound is: {}'.format(aut)))

        T = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        tim = '--date {} '.format(T) if self.chckbx2.isChecked() is True else ''
        print((' INFO: The Date and Time of this sound is: {}'.format(tim)))

        vol = ' --disable-softvol' if self.chckbx0.isChecked() is True else ''
        print((' INFO: Software based Volume Control is: {}'.format(vol)))

        # make base directory
        try:
            mkdir(self.base)
            print((' INFO: Base Directory path created {}'.format(self.base)))
        except OSError:
            print((' INFO: Base Directory already exist {}'.format(self.base)))
        except:
            print((' ERROR: Can not create Directory ?, {}'.format(self.base)))

        # make directory tree
        try:
            for dr in range(1, 13):
                mkdir(path.abspath(path.join(self.base, str(dr))))
                print((' INFO:Directory created {}/{}'.format(self.base, dr)))
        except OSError:
            print((' INFO: Directory already exist {}/1,12'.format(self.base)))
        except:
            print((' ERROR: Cant create Directory?, {}/1,12'.format(self.base)))

        # make new filename
        flnm = path.abspath(path.join(self.base, str(datetime.now().month),
                   datetime.now().strftime("%Y-%m-%d_%H:%M:%S.ogg")))
        self.actual_file = flnm
        print((' INFO: Recording on the file {}'.format(flnm)))

        # make custom commands
        cmd1 = self.cmd1.format(n=prio, f=frmt, c=chnl, b=btrt, v=vol)
        cmd2 = self.cmd2.format(c=chnl, b=btrt, q=qlt,
                                d=downmix, o=flnm, a=aut, t=tim)
        print((cmd1, cmd2))
        #  multiprocess recording loop pipe
        self.process1 = QProcess(self)
        self.process2 = QProcess(self)
        self.process1.setStandardOutputProcess(self.process2)
        self.process1.start(cmd1)
        if not self.process1.waitForStarted():
            print((" ERROR: RECORDER QProcess 1 Failed: \n {}   ".format(cmd1)))
        self.process2.start(cmd2)
        if not self.process2.waitForStarted():
            print((" ERROR: ENCODER QProcess 2 Failed: \n   {} ".format(cmd2)))
        self.nepomuk_set(flnm, 'testigo', 'testigo', 'AutoTag by Cinta-Testigo')

    def spectro(self):
        ' spectrometer '
        wid = self.spec.size().width()
        hei = self.spec.size().height()
        command = self.cmd3.format(o=self.actual_file, x=wid, y=hei)
        print(' INFO: Spectrometer is deleting OLD .ogg.png Files on target ')
        call('rm --verbose --force {}/*/*.ogg.png'.format(self.base), shell=1)
        print(' INFO: Spectrometer finished Deleting Files, Starting Render ')
        call(command, shell=True)
        print((''' INFO: Spectrometer finished Rendering Sound using:
               {}{}   OutPut: {}'''.format(command, linesep, self.actual_file)))
        self.spec.setIcon(QIcon('{o}.png'.format(o=self.actual_file)))
        self.spec.setIconSize(QSize(wid, hei))
        self.spec.resize(wid, hei)

    ###########################################################################

    def paintEvent(self, event):
        'Paint semi-transparent background, animated pattern, background text'
        QWidget.paintEvent(self, event)
        # make a painter
        p = QPainter(self)
        p.setRenderHint(QPainter.TextAntialiasing)
        p.setRenderHint(QPainter.HighQualityAntialiasing)
        # fill a rectangle with transparent painting
        p.fillRect(event.rect(), Qt.transparent)
        # animated random dots background pattern
        for i in range(4096):
            x = randint(9, self.size().width() - 9)
            y = randint(9, self.size().height() - 9)
            p.setPen(QPen(QColor(randint(200, 255), randint(200, 255), 255), 1))
            p.drawPoint(x, y)
        # set pen to use white color
        p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
        # Rotate painter 45 Degree
        p.rotate(35)
        # Set painter Font for text
        p.setFont(QFont('Ubuntu', 300))
        # draw the background text, with antialiasing
        p.drawText(99, 199, "Radio")
        # Rotate -45 the QPen back !
        p.rotate(-35)
        # set the pen to no pen
        p.setPen(Qt.NoPen)
        # Background Color
        p.setBrush(QColor(0, 0, 0))
        # Background Opacity
        p.setOpacity(0.75)
        # Background Rounded Borders
        p.drawRoundedRect(self.rect(), 50, 50)
        # finalize the painter
        p.end()

    def seTitle(self):
        ' set the title of the main window '
        dialog = QDialog(self)
        textEditInput = QLineEdit(' Type Title Here ')
        ok = QPushButton(' O K ')
        ok.clicked.connect(lambda: self.setWindowTitle(textEditInput.text()))
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QLabel('Title:'), textEditInput, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def timedate(self):
        ' get the time and date '
        dialog = QDialog(self)
        clock = QLCDNumber()
        clock.setNumDigits(24)
        timer = QTimer()
        timer.timeout.connect(lambda: clock.display(
            datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        timer.start(1000)
        clock.setToolTip(datetime.now().strftime("%c %x"))
        ok = QPushButton(' O K ')
        ok.clicked.connect(dialog.close)
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QCalendarWidget(), clock, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def closeEvent(self, event):
        ' Ask to Quit '
        if QMessageBox.question(self, ' Close ', ' Quit ? ',
           QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def center(self):
        ' Center and resize the window '
        self.showNormal()
        self.resize(QDesktopWidget().screenGeometry().width() // 1.25,
                    QDesktopWidget().screenGeometry().height() // 1.25)
        qr = self.frameGeometry()
        qr.moveCenter(QDesktopWidget().availableGeometry().center())
        self.move(qr.topLeft())

    def nepomuk_set(self, file_tag=None, __tag='', _label='', _description=''):
        ' Quick and Easy Nepomuk Taggify for Files '
        print((''' INFO: Semantic Desktop Experience is Tagging Files :
              {}, {}, {}, {})'''.format(file_tag, __tag, _label, _description)))
        if Nepomuk.ResourceManager.instance().init() is 0:
            fle = Nepomuk.Resource(KUrl(QFileInfo(file_tag).absoluteFilePath()))
            _tag = Nepomuk.Tag(__tag)
            _tag.setLabel(_label)
            fle.addTag(_tag)
            fle.setDescription(_description)
            print(([str(a.label()) for a in fle.tags()], fle.description()))
            return ([str(a.label()) for a in fle.tags()], fle.description())
        else:
            print(" ERROR: FAIL: Nepomuk is not running ! ")

    def nepomuk_get(self, query_to_search):
        ' Quick and Easy Nepomuk Query for Files '
        print((''' INFO: Semantic Desktop Experience is Quering Files :
              {} '''.format(query_to_search)))
        results = []
        nepo = Nepomuk.Query.QueryServiceClient()
        nepo.desktopQuery("hasTag:{}".format(query_to_search))

        def _query(data):
            ''' ('filename.ext', 'file description', ['list', 'of', 'tags']) '''
            results.append(([str(a.resource().genericLabel()) for a in data][0],
                            [str(a.resource().description()) for a in data][0],
            [str(a.label()) for a in iter([a.resource().tags() for a in data][0]
            )]))
        nepo.newEntries.connect(_query)

        def _end():
            '''
            [  ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags'])  ]
            '''
            nepo.newEntries.disconnect
            print(results)
            return results
        nepo.finishedListing.connect(_end)
Example #10
0
class Slider(QWidget):
    def __init__(
        self,
        caption,
        default_value,
        minimum_value=1,
        maximum_value=60,
        single_step=1,
        page_step=6,
        caption_size=None,
        unit="",
        time=False,
        tooltip="",
    ):
        QWidget.__init__(self)

        self.value = default_value
        self.unit = unit
        self.time = time

        description = QLabel(caption)
        description.setWordWrap(True)
        description.setToolTip(tooltip)
        if caption_size:
            description.setMaximumWidth(caption_size)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMaximum(maximum_value)
        self.slider.setMinimum(minimum_value)
        self.slider.setSingleStep(single_step)
        self.slider.setPageStep(page_step)
        self.slider.setToolTip(tooltip)
        # self.slider.setTickInterval(2)
        # self.slider.setTickPosition(QSlider.TicksBelow)
        self.slider.valueChanged.connect(self.__on_change)

        self.value_label = QLabel()

        hbox = QHBoxLayout()
        hbox.addWidget(description)
        hbox.addWidget(self.slider)
        hbox.addWidget(self.value_label)
        hbox.setMargin(0)
        self.setLayout(hbox)
        self.setContentsMargins(5, 0, 5, 0)
        self.slider.setValue(self.value)
        self.__on_change(self.value)

    def __on_change(self, value):
        # FIXME: Fill with spaces to reach the maximum length
        self.value = value
        unit = self.unit
        if self.time:
            minutes = timedelta(minutes=self.value)
            date = datetime(1, 1, 1) + minutes
            text = "%02dh %02dm" % (date.hour, date.minute)
        else:
            text = "%s %s" % (self.value, self.unit)
        self.value_label.setText(text)

    def get_value(self):
        return int(self.slider.value())
Example #11
0
class XZoomSlider(QWidget):
    zoomAmountChanged   = Signal(int)
    
    def __init__(self, parent=None):
        super(XZoomSlider, self).__init__(parent)
        
        # define the interface
        in_icon  = projexui.resources.find('img/zoom_in.png')
        out_icon = projexui.resources.find('img/zoom_out.png')
        
        self._zoomInButton = QToolButton(self)
        self._zoomInButton.setAutoRaise(True)
        self._zoomInButton.setToolTip('Zoom In')
        self._zoomInButton.setIcon(QIcon(in_icon))
        
        self._zoomOutButton = QToolButton(self)
        self._zoomOutButton.setAutoRaise(True)
        self._zoomOutButton.setToolTip('Zoom Out')
        self._zoomOutButton.setIcon(QIcon(out_icon))
        
        self._zoomSlider = QSlider(Qt.Horizontal, self)
        self._zoomSlider.setRange(10, 100)
        self._zoomSlider.setValue(100)
        
        # define the layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self._zoomOutButton)
        layout.addWidget(self._zoomSlider)
        layout.addWidget(self._zoomInButton)
        
        self.setLayout(layout)
        
        # create connections
        self._zoomSlider.valueChanged.connect(self.emitZoomAmountChanged)
        self._zoomInButton.clicked.connect(self.zoomIn)
        self._zoomOutButton.clicked.connect(self.zoomOut)
    
    def emitZoomAmountChanged(self):
        """
        Emits the current zoom amount, provided the signals are not being
        blocked.
        """
        if not self.signalsBlocked():
            self.zoomAmountChanged.emit(self.zoomAmount())
    
    def maximum(self):
        """
        Returns the maximum zoom level for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.maximum()
    
    def minimum(self):
        """
        Returns the minimum zoom level for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.minimum()
    
    def setMaximum(self, maximum):
        """
        Sets the maximum zoom level for this widget.
        
        :param      maximum | <int>
        """
        self._zoomSlider.setMaximum(minimum)
    
    def setMinimum(self, minimum):
        """
        Sets the minimum zoom level for this widget.
        
        :param      minimum | <int>
        """
        self._zoomSlider.setMinimum(minimum)
    
    def setZoomStep(self, amount):
        """
        Sets how much a single step for the zoom in/out will be.
        
        :param      amount | <int>
        """
        self._zoomSlider.setPageStep(amount)
    
    @Slot(int)
    def setZoomAmount(self, amount):
        """
        Sets the zoom amount for this widget to the inputed amount.
        
        :param      amount | <int>
        """
        self._zoomSlider.setValue(amount)
    
    def zoomAmount(self):
        """
        Returns the current zoom amount for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.value()
    
    @Slot()
    def zoomIn(self):
        """
        Zooms in by a single page step.
        """
        self._zoomSlider.triggerAction(QSlider.SliderPageStepAdd)
    
    def zoomInButton(self):
        """
        Returns the zoom in button from the left side of this widget.
        
        :return     <QToolButton>
        """
        return self._zoomInButton
    
    @Slot()
    def zoomOut(self):
        """
        Zooms out by a single page step.
        """
        self._zoomSlider.triggerAction(QSlider.SliderPageStepSub)
    
    def zoomOutButton(self):
        """
        Returns the zoom out button from the right side of this widget.
        
        :return     <QToolButton>
        """
        return self._zoomOutButton
    
    def zoomSlider(self):
        """
        Returns the slider widget of this zoom slider.
        
        :return     <QSlider>
        """
        return self._zoomSlider
    
    def zoomStep(self):
        """
        Returns the amount for a single step when the user clicks the zoom in/
        out amount.
        
        :return     <int>
        """
        return self._zoomSlider.pageStep()
    
    x_maximum  = Property(int, maximum, setMaximum)
    x_minimum  = Property(int, minimum, setMinimum)
    z_zoomStep = Property(int, zoomStep, setZoomStep)
Example #12
0
class MainWin(QMainWindow):
    def __init__(self, mx, spurs, fef, parent=None, plot_lib='mpl'):
        QMainWindow.__init__(self, parent)

        self.mx = mx
        self.spurset = spurs
        self.fef = fef

        if plot_lib == 'qwt':
            from chart.qwtchart import qwtchart as chart
        elif plot_lib == 'mpl':
            from chart.mplchart import mplchart as chart
        elif plot_lib == 'pg':
            from chart.pyqtgraphchart import pyqtgraphchart as chart
        else:
            raise NotImplementedError

        self.chart = chart(self.spurset, self.fef, self)
        self.create_menu_bar()
        self.create_main_frame()
        self.hookup()

    def hookup(self):
        # connect all the objects that are supposed to be watching each other
        # for changes and updates.
        self.mx.register(self.chart.draw_spurs)
        self.spurset.register(self.chart.draw_spurs)
        self.chart.picker_watch(self.fef)
        self.fef.register(self.chart.draw_fef)
        self.chart.draw_spurs(self.spurset)
        self.chart.draw_fef(self.fef)

    def IF_slide(self, i):
        """ callback method for the IF selection slider"""
        self.IFtextbox.setText(str(i))
        self.mx.IF = i

    def about(self):
        msg = '''
        A frequency-planing tool based on the method of spur distances.
        (A reference to the article will go here)
        For more info, view the README included with this program.

        Patrick Yeon, 2012'''
        QMessageBox.about(self, 'Spur Distance Chart', msg.strip())

    def mxtypecb(self, i):
        """ callback method for mixer configuration selection combobox"""
        self.mx.m, self.mx.n = [(-1, 1), (1, -1), (1, 1)][i]
        # trigger anything watching the mixer
        self.mx.update_watchers()

    def create_main_frame(self):
        self.main_frame = QWidget()
        # Looking at the main frame as two columns. On the left there is the
        # chart and the IF control. In the right column we'll have range
        # settings, mixer settings, and maybe other stuff that comes up?

        self.IFtextbox = QLineEdit()
        self.IFtextbox.setMinimumWidth(6)
        self.IFtextbox.setText(str(self.spurset.mixer.IF))
        # TODO link up the textbox so that it can also be input

        self.IFslider = QSlider(Qt.Horizontal)
        # TODO I'd really like some form of slider that doesn't actually limit
        # the user. Also, if IFtextbox could modify the IF, that'd be nice.
        self.IFslider.setRange(int(self.mx.IF * 0.1), (self.mx.IF * 5))
        self.IFslider.setValue(self.mx.IF)
        self.IFslider.setTracking(True)
        self.IFslider.setTickPosition(QSlider.TicksAbove)
        step = max(1, int(0.01 * self.mx.IF))
        self.IFslider.setSingleStep(step)
        self.IFslider.setPageStep(step * 10)
        self.IFcid = self.connect(self.IFslider, SIGNAL('valueChanged(int)'),
                                  self.IF_slide)

        IFbar = QHBoxLayout()
        IFbar.addWidget(QLabel('IF'))
        IFbar.addWidget(self.IFtextbox)
        IFbar.addWidget(self.IFslider)
        IFbar.addStretch()

        leftcol = QVBoxLayout()
        leftcol.addWidget(self.chart.plot)
        leftcol.addLayout(IFbar)

        # left column done. Now the right-hand side
        rangebox = QVBoxLayout()
        for (prop, name, f) in [(spurset.RFmin, 'RFmin', self.spurset.RFmin),
                                (spurset.RFmax, 'RFmax', self.spurset.RFmax),
                                (spurset.dspan, 'dspan', self.spurset.dspan)]:
            rangebox.addLayout(Fbar(self.spurset, prop, name, f, 0, 10000))
        autocb = QCheckBox('Auto')
        # Disable it, won't be implemented for release
        # but leave it there, to nag me into doing it.
        autocb.setDisabled(True)
        rangebox.addWidget(autocb)

        # a line to report the front-end filter's limits
        fefstat = QHBoxLayout()
        fefstat.addWidget(QLabel('Filter Range: '))
        fefrange = QLabel('%d - %d' % (self.fef.start, self.fef.stop))
        # TODO not sure about the lambda here. Feels like if I give it time,
        # I'll sort out a sensible overall connection scheme.
        self.fef.register(lambda o: fefrange.setText('%d - %d' % (
            self.fef.start, self.fef.stop)))
        fefstat.addWidget(fefrange)

        # mixer high/low-side injection picker
        mxbar = QHBoxLayout()
        mxbar.addWidget(QLabel('IF = '))
        mxtype = QComboBox()
        mxtype.addItem('LO - RF')
        mxtype.addItem('RF - LO')
        mxtype.addItem('RF + LO')
        # TODO this is ugly
        mxtype.setCurrentIndex([(-1, 1), (1, -1), (1, 1)].index(
            (self.mx.m, self.mx.n)))
        self.mxtypecid = self.connect(mxtype,
                                      SIGNAL('currentIndexChanged(int)'),
                                      self.mxtypecb)
        mxbar.addWidget(mxtype)

        # alright, the actual column proper in the layout
        vbar = QVBoxLayout()
        vbar.addLayout(rangebox)
        vbar.addLayout(fefstat)
        vbar.addLayout(mxbar)
        legend = self.chart.legend()
        vbar.addWidget(legend)
        # need to let the legend stretch so that everything fits in it
        vbar.setStretchFactor(legend, 1)
        vbar.addStretch()

        hbox = QHBoxLayout()
        hbox.addLayout(leftcol)
        hbox.addLayout(vbar)
        # make sure the legend doesn't stretch so far horizontally that the
        # chart suffers considerable loss of space.
        hbox.setStretchFactor(leftcol, 5)
        hbox.setStretchFactor(vbar, 1)

        self.main_frame.setLayout(hbox)
        self.setCentralWidget(self.main_frame)

    def create_menu_bar(self):
        filemenu = self.menuBar().addMenu('&File')
        close = QAction('&Quit', self)
        close.setShortcut('Ctrl+W')
        self.connect(close, SIGNAL('triggered()'), self.close)
        filemenu.addAction(close)

        helpmenu = self.menuBar().addMenu('&Help')
        about = QAction('&About', self)
        about.setShortcut('F1')
        self.connect(about, SIGNAL('triggered()'), self.about)
        helpmenu.addAction(about)
Example #13
0
class XZoomSlider(QWidget):
    zoomAmountChanged = Signal(int)

    def __init__(self, parent=None):
        super(XZoomSlider, self).__init__(parent)

        # define the interface
        in_icon = projexui.resources.find('img/zoom_in.png')
        out_icon = projexui.resources.find('img/zoom_out.png')

        self._zoomInButton = QToolButton(self)
        self._zoomInButton.setAutoRaise(True)
        self._zoomInButton.setToolTip('Zoom In')
        self._zoomInButton.setIcon(QIcon(in_icon))

        self._zoomOutButton = QToolButton(self)
        self._zoomOutButton.setAutoRaise(True)
        self._zoomOutButton.setToolTip('Zoom Out')
        self._zoomOutButton.setIcon(QIcon(out_icon))

        self._zoomSlider = QSlider(Qt.Horizontal, self)
        self._zoomSlider.setRange(10, 100)
        self._zoomSlider.setValue(100)

        # define the layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self._zoomOutButton)
        layout.addWidget(self._zoomSlider)
        layout.addWidget(self._zoomInButton)

        self.setLayout(layout)

        # create connections
        self._zoomSlider.valueChanged.connect(self.emitZoomAmountChanged)
        self._zoomInButton.clicked.connect(self.zoomIn)
        self._zoomOutButton.clicked.connect(self.zoomOut)

    def emitZoomAmountChanged(self):
        """
        Emits the current zoom amount, provided the signals are not being
        blocked.
        """
        if not self.signalsBlocked():
            self.zoomAmountChanged.emit(self.zoomAmount())

    def maximum(self):
        """
        Returns the maximum zoom level for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.maximum()

    def minimum(self):
        """
        Returns the minimum zoom level for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.minimum()

    def setMaximum(self, maximum):
        """
        Sets the maximum zoom level for this widget.
        
        :param      maximum | <int>
        """
        self._zoomSlider.setMaximum(minimum)

    def setMinimum(self, minimum):
        """
        Sets the minimum zoom level for this widget.
        
        :param      minimum | <int>
        """
        self._zoomSlider.setMinimum(minimum)

    def setZoomStep(self, amount):
        """
        Sets how much a single step for the zoom in/out will be.
        
        :param      amount | <int>
        """
        self._zoomSlider.setPageStep(amount)

    @Slot(int)
    def setZoomAmount(self, amount):
        """
        Sets the zoom amount for this widget to the inputed amount.
        
        :param      amount | <int>
        """
        self._zoomSlider.setValue(amount)

    def zoomAmount(self):
        """
        Returns the current zoom amount for this widget.
        
        :return     <int>
        """
        return self._zoomSlider.value()

    @Slot()
    def zoomIn(self):
        """
        Zooms in by a single page step.
        """
        self._zoomSlider.triggerAction(QSlider.SliderPageStepAdd)

    def zoomInButton(self):
        """
        Returns the zoom in button from the left side of this widget.
        
        :return     <QToolButton>
        """
        return self._zoomInButton

    @Slot()
    def zoomOut(self):
        """
        Zooms out by a single page step.
        """
        self._zoomSlider.triggerAction(QSlider.SliderPageStepSub)

    def zoomOutButton(self):
        """
        Returns the zoom out button from the right side of this widget.
        
        :return     <QToolButton>
        """
        return self._zoomOutButton

    def zoomSlider(self):
        """
        Returns the slider widget of this zoom slider.
        
        :return     <QSlider>
        """
        return self._zoomSlider

    def zoomStep(self):
        """
        Returns the amount for a single step when the user clicks the zoom in/
        out amount.
        
        :return     <int>
        """
        return self._zoomSlider.pageStep()

    x_maximum = Property(int, maximum, setMaximum)
    x_minimum = Property(int, minimum, setMinimum)
    z_zoomStep = Property(int, zoomStep, setZoomStep)