Exemple #1
0
class View (QFrame):

    def __init__ (self, name, graph_view, scene, parent=None):
        
        QFrame.__init__(self, parent)
        
        self.graph_view = graph_view
        self.graph_view.setView0 (self)
        self.scene = scene

        self.setFrameStyle (QFrame.Sunken | QFrame.StyledPanel)
        
        self.font = QFont()
        self.font.setPointSize(10)
        
        
        self.graphicsView = CustomGraphicsView ()
        self.graphicsView.setRenderHint (QPainter.Antialiasing, True)
        self.graphicsView.setDragMode (QGraphicsView.RubberBandDrag)
        self.graphicsView.setViewportUpdateMode (QGraphicsView.SmartViewportUpdate)
        #self.graphicsView.setMouseTracking(True)
        
        # toolbox definition + group page definition
        sizePolicy = QSizePolicy (QSizePolicy.Fixed, QSizePolicy.Expanding)
        self.setObjectName ('Form')
        self.resize (900, 1000)
        self._toolBox = QToolBox (self)
        self._toolBox.setGeometry (QRect (0, 0, 131, 301))
        self._toolBox.setFont (self.font)
        self._toolBox.setObjectName ('_toolBox')
        self._toolBox.setCursor (Qt.PointingHandCursor)
        self.groupCluster = QWidget ()
        self.groupCluster.setGeometry (QRect(0, 0, 91, 241))
        self.groupCluster.setObjectName ('groupCluster')
        self.groupLineEdit = QLineEdit (self.groupCluster)
        self.groupLineEdit.setGeometry (QRect (2, 20, 60, 16))
        self.groupLineEdit.setObjectName ('groupLineEdit')
        self.label = QLabel (self.groupCluster)
        self.label.setGeometry (QRect (4, 6, 62, 16))
        self.label.setFont (self.font)
        self.label.setObjectName ('label')
        self.label_2 = QLabel (self.groupCluster)
        self.label_2.setGeometry (QRect (4, 40, 62, 16))
        self.label_2.setFont (self.font)
        self.label_2.setObjectName ('label_2')
        self.groupLineEdit_2 = QLineEdit (self.groupCluster)
        self.groupLineEdit_2.setGeometry (QRect(2, 54, 60, 16))
        self.groupLineEdit_2.setObjectName ('groupLineEdit_2')
        self.pushButton = QPushButton (self.groupCluster)
        self.pushButton.setGeometry (QRect (2, 90, 60, 16))
        self.pushButton.setFont (self.font)
        self.pushButton.setObjectName ('pushButton')
        self._toolBox.addItem (self.groupCluster, '')
        self._toolBox.setItemText (self._toolBox.indexOf (self.groupCluster), QApplication.translate ("Form", "Group", None, QApplication.UnicodeUTF8))
        self.setWindowTitle (QApplication.translate ("Form", "Form", None, QApplication.UnicodeUTF8))
        self.label.setText (QApplication.translate ("Form", "name group", None, QApplication.UnicodeUTF8))
        self.label_2.setText (QApplication.translate ("Form", "group id", None, QApplication.UnicodeUTF8))
        self.pushButton.setText (QApplication.translate ("Form", "add cluster", None, QApplication.UnicodeUTF8))
        self._toolBox.setSizePolicy (sizePolicy)
        self._toolBox.setEnabled (False)
        
        # adding the first cluster to the toolbox - a cluster is always present!
        self._cluster_page_list = []
        self.connect (self.pushButton, SIGNAL ("clicked()"), self.addCluster)  # connect the 'add-cluster' button to the method that taps into the model for cluster addition.
        self.connect (self.graph_view.getComm(), SIGNAL ("addCluster_MSignal(int)"), self.addClusterPage)
        self.connect (self.graph_view.getComm(), SIGNAL ("deleteCluster_MSignal(int)"), self.removeClusterPage)
        self.connect (self.graph_view.getComm(), SIGNAL ("updateClusterName_MSignal(int, QString)"), self.updateClusterViewName)
        self.addCluster () # add the first cluster. At least one cluster needs to be always present.
        self.disableAllClusterPagesDeleteButton() # since there's only one cluster page, the delete button is disabled.
        
        #size = self.style ().pixelMetric (QStyle.PM_ToolBarIconSize)
        iconSize = QSize (16, 16) #QSize (size, size)
        
        zoomInIcon = QToolButton ()
        zoomInIcon.setCursor (Qt.PointingHandCursor)
        zoomInIcon.setAutoRepeat (True)
        zoomInIcon.setAutoRepeatInterval (33)
        zoomInIcon.setAutoRepeatDelay (0)
        zoomInIcon.setIconSize (iconSize)
        
        zoomOutIcon = QToolButton ()
        zoomOutIcon.setCursor (Qt.PointingHandCursor)
        zoomOutIcon.setAutoRepeat (True)
        zoomOutIcon.setAutoRepeatInterval (33)
        zoomOutIcon.setAutoRepeatDelay (0)
        zoomOutIcon.setIconSize (iconSize)
        
        self.zoomSlider = QSlider ()
        self.zoomSlider.setCursor (Qt.PointingHandCursor)
        self.zoomSlider.setMinimum (200)
        self.zoomSlider.setMaximum (280)
        self.zoomSlider.setValue   (240)
        self.zoomSlider.setTickPosition (QSlider.TicksRight)
        
        # Zoom slider layout
        zoomSliderLayout = QVBoxLayout ()
        zoomSliderLayout.addWidget (zoomInIcon)
        zoomSliderLayout.addWidget (self.zoomSlider)
        zoomSliderLayout.addWidget (zoomOutIcon)
        
        self.printOutBtn = QPushButton()
        self.printOutBtn.setText ("print")
        self.printOutBtn.setFont (self.font)
        self.printOutBtn.setEnabled (False)
        
        self.newJADESceneBtn = QPushButton()
        self.newJADESceneBtn.setText ("new")
        self.newJADESceneBtn.setFont (self.font)
        self.newJADESceneBtn.setEnabled (False)
        
        self.loadNodesDescrpBtn = QPushButton()
        self.loadNodesDescrpBtn.setText ("load Nodes Description")
        self.loadNodesDescrpBtn.setFont (self.font)
        self.loadNodesDescrpBtn.setEnabled (True)
        
        self.graphLoadBtn = QPushButton()
        self.graphLoadBtn.setText ("load")
        self.graphLoadBtn.setFont (self.font)
        self.graphLoadBtn.setEnabled (False)
        
        self.graphSaveBtn = QPushButton()
        self.graphSaveBtn.setText ("save")
        self.graphSaveBtn.setFont (self.font)
        self.graphSaveBtn.setEnabled (False)
        
        self.resetButton = QToolButton ()
        self.resetButton.setText ("r")
        self.resetButton.setFont (self.font)
        self.resetButton.setEnabled (False)
        
        self.message_bar = QLineEdit ()
        self.message_bar.setGeometry (QRect (0, 0, 190, 12))
        self.message_bar.setObjectName ('message_bar')
        self.message_bar.setText ('Node description file, please.')
        self.message_bar.setFont (self.font)
        self.message_bar.setEnabled  (True)
        self.message_bar.setReadOnly (True)
        
        self.spacer = QSpacerItem (30, 20, QSizePolicy.Fixed, QSizePolicy.Fixed );
        
        # Label layout
        labelLayout = QHBoxLayout ()
        self.label = QLabel (name)
        self.label.setFont (self.font)
        labelLayout.addWidget (self.loadNodesDescrpBtn)
        labelLayout.addWidget (self.newJADESceneBtn)
        labelLayout.addWidget (self.graphLoadBtn)
        labelLayout.addWidget (self.graphSaveBtn)
        labelLayout.addWidget (self.printOutBtn)
        labelLayout.addItem   (self.spacer)
        labelLayout.addWidget (self.message_bar)
        #labelLayout.addWidget (self.label)
        labelLayout.addStretch ()
        
        # top layout
        topLayout = QGridLayout ()
        topLayout.setHorizontalSpacing (0)
        topLayout.setVerticalSpacing (0)
        topLayout.addLayout (labelLayout, 0, 1)
        topLayout.addWidget (self._toolBox, 1, 0)
        topLayout.addWidget (self.resetButton, 0, 2)
        topLayout.addWidget (self.graphicsView, 1, 1)
        topLayout.addLayout (zoomSliderLayout, 1, 2)
        self.setLayout (topLayout)
        
        self.connect (self.resetButton, SIGNAL ("clicked()"), self.resetView)
        self.connect (self.zoomSlider,  SIGNAL ("valueChanged(int)"), self.setupMatrix)
        self.connect (self.graphicsView.verticalScrollBar   (), SIGNAL ("valueChanged(int)"), self.setResetButtonEnabled)
        self.connect (self.graphicsView.horizontalScrollBar (), SIGNAL ("valueChanged(int)"), self.setResetButtonEnabled)
        self.connect (zoomInIcon,  SIGNAL ("clicked()"), self.zoomIn)
        self.connect (zoomOutIcon, SIGNAL ("clicked()"), self.zoomOut)
        
        self.setupMatrix ()
        
        self.printer = QPrinter (QPrinter.HighResolution)
        
        self.prev_selection_list = []
        
        self.isClusterRemovalOverridden = False
    
    def setMessageBarText (self, text):
        
        self.message_bar.setText (text)
    
    def enableControls (self):
        
        self.printOutBtn.setEnabled (True)
        self.newJADESceneBtn.setEnabled (True)
        self.graphLoadBtn.setEnabled (True)
        self.graphSaveBtn.setEnabled (True)
        self._toolBox.setEnabled (True)
    
    def disableControls (self):
        
        self.printOutBtn.setEnabled (False)
        self.newJADESceneBtn.setEnabled (False)
        self.graphLoadBtn.setEnabled (False)
        self.graphSaveBtn.setEnabled (False)
        self._toolBox.setEnabled (False)
    
    def setGraphicsViewCSSBackground (self):
        
        self.graphicsView.setStyleSheet('background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(125, 125, 135, 255), stop:1 rgba(215, 215, 215, 255));\ncolor: rgb(255, 255, 255);')
    
    def selectionChanged (self):
        
        current_selection_list = self.scene.selectedItems ()
        list_of_unselected_items = [item for item in self.prev_selection_list if item not in current_selection_list]
        
        # un-mark items in list_of_unselected_items
        for item in list_of_unselected_items:
            if self.graph_view.isTag (item) == True:
                item.switchToUnSelectedStateColour ()
        
        # mark items in current_selection_list
        for item in current_selection_list:
            if self.graph_view.isTag (item) == True:
                item.switchToSelectedStateColour ()
        
        self.prev_selection_list = current_selection_list
    
    # - - -    cluster-specific methods   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    def addCluster (self):
        
        self.graph_view.delegateClusterAddition ()
    
    def addClusterPage (self, new_cluster_id):
        
        self.enableAllClusterPagesDeleteButton () # enable all the cluster page's delete buttons (as I can be bothered to go look for the one that got previously disabled) 
        
        tmp_w = QWidget ()
        tmp_l = QLabel (tmp_w)
        tmp_e = QLineEdit (tmp_w)
        tmp_b = QPushButton (tmp_w)
        self._cluster_page_list.append ([new_cluster_id, tmp_w, tmp_l, tmp_e, tmp_b])
        
        tmp_w.setGeometry (QRect (0, 0, 131, 241))
        tmp_w.setObjectName ('Cluster_' + str (new_cluster_id))
        
        tmp_l.setGeometry (QRect (4, 6, 62, 16))
        tmp_l.setFont (self.font)
        tmp_l.setObjectName ('label_' + str (new_cluster_id))
        
        tmp_e.setGeometry (QRect (2, 20, 60, 16))
        tmp_e.setObjectName ('groupLineEdit_' + str (new_cluster_id))
        
        tmp_b.setGeometry (QRect (2, 50, 60, 16))
        tmp_b.setFont (self.font)
        tmp_b.setObjectName ('pushButton_' + str (new_cluster_id))
        
        self._toolBox.addItem (tmp_w, 'cluster_page_'+str(new_cluster_id))
        self._toolBox.setItemText (self._toolBox.indexOf (tmp_w), QApplication.translate ('Form', 'C_'+str(new_cluster_id), None, QApplication.UnicodeUTF8))
        tmp_l.setText (QApplication.translate ("Form", "name cluster", None, QApplication.UnicodeUTF8))
        tmp_b.setText (QApplication.translate ("Form", "delete", None, QApplication.UnicodeUTF8))
        self._toolBox.setCurrentIndex (new_cluster_id)
        QMetaObject.connectSlotsByName (self)
        
        # hook up the delete button (use a closure)
        receiver = lambda : self.removeCluster (new_cluster_id)
        self.connect (tmp_b, SIGNAL ("clicked()"), receiver)  # connect the 'add cluster' button to the method generating new cluster pages.
        
        receiver2 = lambda value : self.updateClusterModelName (new_cluster_id, value)
        self.connect (tmp_e, SIGNAL ("textChanged(QString)"), receiver2)
    
    def removeAllClusters (self):
        
        copy_list = list (self._cluster_page_list)
        
        self.isClusterRemovalOverridden = True
        for item in copy_list:
                self.removeCluster (item[0])
        
        self.graph_view.initGraphViewLists ()
        self.graph_view.initComm  ()
        self.graph_view.initModel ()
        
        self._cluster_page_list = []
        self.addCluster () # add the first cluster. At least one cluster needs to be always present.
        
        self.isClusterRemovalOverridden = False # remove override
    
    def removeCluster (self, cluster_id):
        
        self.graph_view.delegateClusterRemoval (cluster_id)
    
    def removeClusterPage (self, cluster_id):
        
        threshold = 1 if self.isClusterRemovalOverridden==False else 0
        
        qq = len(self._cluster_page_list)
        if qq > threshold:
            for i in range (qq-1, -1, -1):
                if int(self._cluster_page_list[i][0]) == cluster_id:
                    self._toolBox.removeItem (self._toolBox.indexOf(self._cluster_page_list[i][1]))
                    del self._cluster_page_list[i]
                    break
        
        if len(self._cluster_page_list) == 1:
            self.disableAllClusterPagesDeleteButton ()
    
    def disableAllClusterPagesDeleteButton (self):
        
        if len(self._cluster_page_list) > 0:
            for item in self._cluster_page_list:
                item[4].setEnabled (False)
    
    def enableAllClusterPagesDeleteButton (self):
        
        if len(self._cluster_page_list) > 0:
            for item in self._cluster_page_list:
                item[4].setEnabled (True)
    
    def updateClusterModelName (self, cluster_id, text):
        
        self.graph_view.delegateUpdateClusterName (cluster_id, text)
    
    def updateClusterViewName (self, cluster_id, text):
        
        if len(self._cluster_page_list) > 0:
            for item in self._cluster_page_list:
                if int(item[0]) == cluster_id:
                    item[3].setText (str(text))
    
    def updateCurrentClusterNodeList (self, node):
        
        # fetch the current cluster's id.
        curr_widget = self._toolBox.currentWidget()
        for item in self._cluster_page_list:
            if item[1] == curr_widget:
                
                # delegate cluster node list update.
                self.graph_view.delegateClusterNodeListUpdate (item[0], node)
                break
    
    def getCurrentClusterIndex (self):
        
        return self._toolBox.currentIndex ()
    
    # - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    def getGraphicsView (self):
        
        return self.graphicsView
    
    def resetView (self):
        
        self.zoomSlider.setValue (250)
        self.setupMatrix ()
        self.graphicsView.ensureVisible (QRectF (0, 0, 0, 0))
        
        self.resetButton.setEnabled (False)
    
    def setResetButtonEnabled (self):
        
        self.resetButton.setEnabled (True)
    
    def setupMatrix (self):
        
        scale = pow (2.0, (self.zoomSlider.value () - 250) / 50.0)
        
        matrix = QMatrix ()
        matrix.scale (scale, scale)
        
        self.graphicsView.setMatrix (matrix)
        self.setResetButtonEnabled ()
    
    def printOutGraph (self):
        
        qqq = QPainter (self.printer)
        self.graphicsView.render(qqq)
    
    def importNodesDescription (self):
        
        aa = QFileDialog (self).getOpenFileName()
        if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned.
            self.graph_view.setNodesDescription (open(aa).read())
    
    def resetScene (self):
        
        self.removeAllClusters ()
        self.resetView ()
    
    def exportGraph (self):
        
        aa = QFileDialog (self).getSaveFileName ()
        if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned.
            file0 = open (aa, 'w')
            file0.write (self.graph_view.delegateExport ())
            file0.close ()
            print '\n*** file exported.\n'
    
    def importGraph (self):
        
        aa = QFileDialog (self).getOpenFileName ()
        if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned.
            file0 = open (aa, 'r')
            XML_content = file0.read()
            file0.close ()
            self.graph_view.delegateImport (XML_content)
            print '\n*** file imported.\n'
    
    # zoom slider
    def zoomIn  (self) : self.zoomSlider.setValue (self.zoomSlider.value() + 1)
    def zoomOut (self) : self.zoomSlider.setValue (self.zoomSlider.value() - 1)
    def getZoomSlider (self): return self.zoomSlider
    
    def setToolboxCSSColorScheme (self, css): self._toolBox.setStyleSheet (css)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    def wireViewItemsUp (self):
        
        self.connect (self.newJADESceneBtn,    SIGNAL ("clicked()"), self.resetScene)
        self.connect (self.loadNodesDescrpBtn, SIGNAL ("clicked()"), self.importNodesDescription)
        self.connect (self.graphSaveBtn,       SIGNAL ("clicked()"), self.exportGraph)
        self.connect (self.graphLoadBtn,       SIGNAL ("clicked()"), self.importGraph)
        self.connect (self.printOutBtn,        SIGNAL ("clicked()"), self.printOutGraph)
Exemple #2
0
class MyMainWindow(QMainWindow):
    ' Main Window '
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.statusBar().showMessage(__doc__)
        self.setWindowTitle(__doc__)
        self.setMinimumSize(250, 280)
        self.setMaximumSize(300, 300)
        self.resize(250, 290)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setStyleSheet('''QWidget { color: rgba( 0, 255, 255, 255 );
            background-color: #323232; font-family: 'Ubuntu Light';
            font-size: 14px;
            }

            QToolTip {
                border: 1px solid black;
                background-color: #ffa02f;
                background-image: None;
                padding: 1px;
                border-radius: 3px;
                opacity: 100;
            }

            QWidget:item:hover {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #ca0619
                );
                color: #000000;
            }

            QWidget:item:selected {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QWidget:disabled {
                color: #404040;
                background-color: #323232;
            }

            QWidget:focus {
                background-image: None;
                border: 2px solid QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QPushButton {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #565656,
                    stop: 0.1 #525252,
                    stop: 0.5 #4e4e4e,
                    stop: 0.9 #4a4a4a,
                    stop: 1 #464646
                );
                border-width: 1px;
                border-color: #1e1e1e;
                border-style: solid;
                border-radius: 6;
                padding: 3px;
                font-size: 12px;
                padding-left: 5px;
                padding-right: 5px;
                background-image: None;
            }

            QPushButton:pressed {
                background-image: None;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #2d2d2d,
                    stop: 0.1 #2b2b2b,
                    stop: 0.5 #292929,
                    stop: 0.9 #282828,
                    stop: 1 #252525
                );
            }

            QComboBox {
                background-image: None;
                selection-background-color: #ffaa00;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #565656,
                    stop: 0.1 #525252,
                    stop: 0.5 #4e4e4e,
                    stop: 0.9 #4a4a4a,
                    stop: 1 #464646
                );
                border-style: solid;
                border: 1px solid #1e1e1e;
                border-radius: 5;
            }

            QComboBox:hover, QPushButton:hover {
                background-image: url(.bg.png);
                border: 2px solid QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QComboBox:on {
                padding-top: 3px;
                padding-left: 4px;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #2d2d2d,
                    stop: 0.1 #2b2b2b,
                    stop: 0.5 #292929,
                    stop: 0.9 #282828,
                    stop: 1 #252525
                );
                selection-background-color: #ffaa00;
                background-image: None;
            }

            QComboBox QAbstractItemView {
                background-image: None;
                border: 2px solid darkgray;
                selection-background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QComboBox::drop-down {
                 subcontrol-origin: padding;
                 subcontrol-position: top right;
                 width: 15px;
                 border-left-width: 0px;
                 border-left-color: darkgray;
                 border-left-style: solid;
                 border-top-right-radius: 3px;
                 border-bottom-right-radius: 3px;
                 background-image: None;
             }

            QComboBox::down-arrow { background-image: None; }

            QSlider {
                border-width: 2px;
                border-color: #1e1e1e;
                border-style: solid;
                padding: 3px;
                font-size: 8px;
                padding-left: 5px;
                padding-right: 5px;
                width: 25px;
                border-radius: 5px;
            }

            QSlider::sub-page:vertical {
                background: red;
                border: none;
                width: 25px;
            }

            QSlider::add-page:vertical {
                background: green;
                border: none;
                width: 25px;
            }

            QSlider::handle:vertical {
                background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1,
                    y2:0.273, stop:0 rgba(0, 0, 0, 255),
                    stop:1 rgba(150, 255, 255, 255)
                    );
                width: 10px;
                height: 25px;
                border: 1px solid grey;
                text-align: center;
                border-top-left-radius: 2px;
                border-bottom-left-radius: 2px;
                border-top-right-radius: 2px;
                border-bottom-right-radius 2px;
                margin-left: 2px;
                margin-right: 2px;
            }

            QSlider::handle:vertical:hover {
                border: 2px solid #ffaa00;
                margin-left: 2px;
                margin-right: 2px;
            }

            QSlider::sub-page:vertical:disabled {
                background: #bbb;
                border-color: #999;
            }

            QSlider::add-page:vertical:disabled {
                background: #eee;
                border-color: #999;
            }

            QSlider::handle:vertical:disabled {
                background: #eee;
                border: 1px solid #aaa;
                border-radius: 4px;
            } ''')

        self.label1 = QLabel(self)
        self.label1.setText('Use Debug')
        self.label1.setGeometry(QtCore.QRect(25, 25, 125, 25))

        self.slider1 = QSlider(self)
        self.slider1.setGeometry(QtCore.QRect(150, 25, 25, 25))
        self.slider1.setTickInterval(1)
        self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider1.TickPosition(QSlider.TicksBothSides)
        self.slider1.setRange(0, 1)
        self.slider1.setValue(1)
        self.sli1lbl = QLabel(str(self.slider1.value()), self.slider1)
        self.sli1lbl.move(9, 5)
        self.sli1lbl.setAutoFillBackground(False)
        self.slider1.valueChanged.connect(
            lambda: self.sli1lbl.setText(str(self.slider1.value())))
        self.slider1.sliderPressed.connect(
            lambda: self.slider1.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider1.sliderReleased.connect(
            lambda: self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label2 = QLabel(self)
        self.label2.setText('Make Executable')
        self.label2.setGeometry(QtCore.QRect(25, 75, 125, 25))

        self.slider2 = QSlider(self)
        self.slider2.setGeometry(QtCore.QRect(150, 75, 25, 25))
        self.slider2.setTickInterval(1)
        self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider2.TickPosition(QSlider.TicksBothSides)
        self.slider2.setRange(0, 1)
        self.slider2.setValue(1)
        self.sli2lbl = QLabel(str(self.slider2.value()), self.slider2)
        self.sli2lbl.move(9, 5)
        self.sli2lbl.setAutoFillBackground(False)
        self.slider2.valueChanged.connect(
            lambda: self.sli2lbl.setText(str(self.slider2.value())))
        self.slider2.sliderPressed.connect(
            lambda: self.slider2.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider2.sliderReleased.connect(
            lambda: self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label3 = QLabel(self)
        self.label3.setText('Relative Imports')
        self.label3.setGeometry(QtCore.QRect(25, 125, 125, 25))

        self.slider3 = QSlider(self)
        self.slider3.setGeometry(QtCore.QRect(150, 125, 25, 25))
        self.slider3.setTickInterval(1)
        self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider3.TickPosition(QSlider.TicksBothSides)
        self.slider3.setRange(0, 1)
        self.slider3.setValue(0)
        self.sli3lbl = QLabel(str(self.slider3.value()), self.slider3)
        self.sli3lbl.move(9, 5)
        self.sli3lbl.setAutoFillBackground(False)
        self.slider3.valueChanged.connect(
            lambda: self.sli3lbl.setText(str(self.slider3.value())))
        self.slider3.sliderPressed.connect(
            lambda: self.slider3.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider3.sliderReleased.connect(
            lambda: self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label4 = QLabel(self)
        self.label4.setText('Indent Spaces')
        self.label4.setGeometry(QtCore.QRect(25, 175, 125, 25))

        self.combo1 = QComboBox(self)
        self.combo1.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        self.combo1.addItems(['4', '0', '2', '6', '8'])
        self.combo1.setGeometry(QtCore.QRect(150, 175, 50, 25))

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setGeometry(QtCore.QRect(25, 225, 200, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel |
            QDialogButtonBox.Close | QDialogButtonBox.Help)
        self.buttonBox.setCenterButtons(False)
        self.buttonBox.helpRequested.connect(lambda: QMessageBox.about(
            self, __doc__, str(__doc__ + ', ' + ',\nversion ' + __version__ +
                               '(' + __license__ + '),\nby ' + __author__ + ', '
                               + __email__)))
        self.buttonBox.accepted.connect(self.run)
        self.buttonBox.rejected.connect(self.close)
        palette = self.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(palette)
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

    def run(self):
        'Run the actual conversion.'
        # Ask the User for the source .ui file as input
        filein = str(QFileDialog.getOpenFileName(
            self, __doc__, path.expanduser("~"), 'UI(*.ui)')).strip()
        # Parse Value of Slider1 as the Debug flag parameter
        if self.slider1.value() == 0:
            arg1 = ''
        else:
            arg1 = '--debug '
        # Parse Value of Slider2 as the Execute flag parameter
        if self.slider2.value() == 0:
            arg2 = ''
        else:
            arg2 = '--execute '
        # Parse Value of Slider3 as the relative imports flag parameter
        if self.slider3.value() == 0:
            arg3 = ''
        else:
            arg3 = '--from-imports '
        # debug
        #print(arg1, arg2, arg3, str(self.combo1.currentText()))
        # run the subprocesses
        subprocess.Popen(
            'nice --adjustment=19 pyuic4 ' + arg1 + arg2 + arg3 +
            '--indent=' + str(self.combo1.currentText()) +
            ' --output=' + str(filein).lower().replace('.ui', '.py') +
            ' ' + filein +
            ' && chmod -v +x ' + str(filein).lower().replace('.ui', '.py'),
            shell=True)

    def paintEvent(self, event):
        ' Paint semi-transparent background '
        painter = QPainter(self)
        painter.fillRect(event.rect(), Qt.transparent)
        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0))
        painter.setOpacity(0.75)
        painter.drawRoundedRect(self.rect(), 75, 50)
        painter.end()
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)