예제 #1
0
class TrackProgressDialog(QDialog):
    finished = pyqtSignal()

    def __init__(self, parent=None, numStages=1):
        QDialog.__init__(self, parent)

        self.currentStep = 0
        self.progress = None

        l = QVBoxLayout()
        self.setLayout(l)

        self.overallProgress = QProgressBar()
        self.overallProgress.setRange(0, numStages)
        self.overallProgress.setFormat("step %v of " + str(numStages))

        self.currentStepProgress = QProgressBar()
        self.currentStepProgress.setRange(0, 100)
        self.currentStepProgress.setFormat("%p %")

        self.overallLabel = QLabel("Overall progress")
        self.currentStepLabel = QLabel("Current step")

        l.addWidget(self.overallLabel)
        l.addWidget(self.overallProgress)
        l.addWidget(self.currentStepLabel)
        l.addWidget(self.currentStepProgress)
        l.maximumSize()

        self.update()

    def __onNewStep(self, description):
        self.currentStep += 1
        self.currentStepProgress.setValue(0)
        self.overallProgress.setValue(self.currentStep)
        self.currentStepLabel.setText(description)
        self.update()

    def __onCurrentStepProgressChanged(self, progress):
        timesHundred = round(1000.0 * progress)
        timesTen = round(100.0 * progress)
        if (not self.currentStepProgress.value()
                == timesTen) and (timesHundred - 10 * timesTen) == 0:
            self.currentStepProgress.setValue(timesTen)
            self.update()

    def run(self):
        self.trackProgress = TrackProgress(self)
        self.trackProgress.progress.connect(
            self.__onCurrentStepProgressChanged, Qt.BlockingQueuedConnection)
        self.trackProgress.newStep.connect(self.__onNewStep,
                                           Qt.BlockingQueuedConnection)
        self.trackProgress.done.connect(self.onTrackDone)
        self.trackProgress.start()

    def onTrackDone(self):
        self.trackProgress.wait(
        )  # Join the extractor thread so its safe to immediately destroy the window
        self.finished.emit()
        self.close()
예제 #2
0
    def _before_upload(self, doc_type):
        """
        Activated just before an upload. It disables user actions and shows
        a progress bar.
        """
        doc_info = self.row_document_info_from_type(doc_type)
        if not doc_info:
            return

        row_num = doc_info.row_num

        # Disable user actions in the given row
        self._enable_user_action_widgets(
            row_num,
            False
        )

        # Show progress bar
        pg_bar = QProgressBar()
        pg_bar.setRange(0, 0)
        pg_bar.setTextVisible(False)
        # Remove text before showing progress bar
        ti = self.item(row_num, 2)
        ti.setText('')
        self.setCellWidget(row_num, 2, pg_bar)
    def _createTrackProgress(self, parent, track):

        w = QWidget(parent)
        l = QVBoxLayout(w)


        p = QProgressBar(w)
        p.setRange(0, 100)
        p.setValue(track['progress'])
        w.progress = p

        label = QLabel(w)
        label.setContentsMargins(5, 2, 5, 2)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)

        if track['name'] is not None:
            label.setText(track['name'])
        elif track['error']:
            label.setText('<font color="red">%s</font>' % track['error'])
            p.setValue(100)

        w.label = label


        l.addWidget(label)
        l.addWidget(p)

        w.setLayout(l)

        return w
예제 #4
0
    def __init__(self, parent=None):
        from radiance import __version__
        self.__version = __version__
        self.parent = parent
        
        pixmap = QPixmap(QString(':/Radiance/splashscreen.png'))
        flags = Qt.WindowStaysOnTopHint
        QSplashScreen.__init__(self, pixmap, flags)
        self.setMask(pixmap.mask())
        
        # Custom progress bar stylesheet
        progressbar_stylesheet = """
        QProgressBar:horizontal {
            border: 1px solid black;
            background: white;
            padding: 1px;
        }
        QProgressBar::chunk:horizontal {
            background-color: qlineargradient(spread: pad, x1: 1, y1: 0.5, x2: 0, y2: 0.5, stop: 0 black, stop: 1 white);
        }
        """
        
        # Place progress bar to bottom of splash screen.
        progressbar = QProgressBar(self)
        progressbar.setRange(0, 0)
        progressbar.setGeometry(10, self.height() - 20, self.width() - 20, 10)
        progressbar.setTextVisible(False)
        progressbar.setStyleSheet(progressbar_stylesheet)
        self.progressbar = progressbar

        self.show()
예제 #5
0
class progressBar:
    def __init__(self, parent, msg='', steps=0):
        '''
        progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar
        :param parent:
        :param msg: string
        '''
        self.iface = parent.iface
        widget = self.iface.messageBar().createMessage("fdtm plugin:", msg)
        self.progressBar = QProgressBar()
        self.progressBar.setRange(0, steps)  #(1,steps)
        self.progressBar.setValue(0)
        self.progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        widget.layout().addWidget(self.progressBar)
        qApp.processEvents()
        self.iface.messageBar().pushWidget(widget, QgsMessageBar.INFO, 50)
        qApp.processEvents()

    def setStep(self, step):
        self.progressBar.setValue(step)
        qApp.processEvents()

    def stop(self, msg=''):
        '''
        the progressbar is stopped with a succes message
        :param msg: string
        :return:
        '''
        self.iface.messageBar().clearWidgets()
        message = self.iface.messageBar().createMessage("fdtm plugin:", msg)
        self.iface.messageBar().pushWidget(message, QgsMessageBar.SUCCESS, 3)
예제 #6
0
    def downloadBtnClicked(self):
        # TODO: disable search button till the downloads finish or stopped manually
        self.ui.downloadBtn.setText("Please wait...")
        self.ui.downloadBtn.setEnabled(False)
        QtGui.QApplication.processEvents()
        selected_range = self.ui.chapterTable.selectedRanges()
        selected_range = [i for r in selected_range
                          for i in range(r.topRow(), r.bottomRow() + 1)]
        # "selected_range" is a list of positions in table
        print "{} items selected".format(len(selected_range))
        for i in selected_range:
            try:
                index = i
                file = DownloadFile(self.course.getMp4UrlMirror(index),
                                    self.get_file_path(index),
                                    index,
                                    lambda index, size, tot, i=index:
                                        self.updateProgress.emit(
                                            index, size, tot, i))
                pg = QProgressBar()
                pg.setRange(0, 100)
                pg.setValue(0)
                self.ui.chapterTable.setCellWidget(i, 1, pg)
                self.downloadQueue.addToQueue(file)
                print file.fileName + " Added to download queue"
            except Exception as e:
                pass

        self.ui.downloadBtn.setText("Start Download")
        self.ui.downloadBtn.setEnabled(True)
        QtGui.QApplication.processEvents()
예제 #7
0
class BusyBar(QThread):
    """
    Adapted from: http://stackoverflow.com/questions/8007602/
    looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e  
           
    Looping progress bar
    create the signal that the thread will emit
    
    .. note::
       This function creates a busy bar but I have not figured out how to \
       attach it to a process. Therefore, it is currently functionally \
       useless.
    """
    changeValue = pyqtSignal(int)

    def __init__(self, text=""):
        QThread.__init__(self, parent=None)
        self.text = text
        self.stop = False
        self.proBar = QProgressBar()
        self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen)
        self.proBar.setRange(0, 100)
        self.proBar.setTextVisible(True)
        self.proBar.setFormat(self.text)
        self.proBar.setValue(0)
        self.proBar.setFixedSize(300, 40)
        self.proBar.setAlignment(Qt.AlignCenter)
        self.proBar.show()

        #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection)
        # Make the Busybar delete itself and the QProgressBar when done
        self.finished.connect(self.onFinished)

    def run(self):
        """
        """
        while not self.stop:
            # keep looping while self is visible
            # Loop sending mail
            for i in range(100):
                # emit the signal instead of calling setValue
                # also we can't read the progress bar value from the thread
                self.changeValue.emit(i)
                time.sleep(0.01)
            self.changeValue.emit(0)

    def onFinished(self):
        """
        """
        self.proBar.deleteLater()
        self.deleteLater()

    def Kill(self):
        """
        """
        self.stop = True
예제 #8
0
class BusyBar(QThread):        
    """
    Adapted from: http://stackoverflow.com/questions/8007602/
    looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e  
           
    Looping progress bar
    create the signal that the thread will emit
    
    .. note::
       This function creates a busy bar but I have not figured out how to \
       attach it to a process. Therefore, it is currently functionally \
       useless.
    """
    changeValue = pyqtSignal(int)
    def __init__(self, text = "" ):
        QThread.__init__(self, parent = None)
        self.text = text
        self.stop = False
        self.proBar = QProgressBar()
        self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen )
        self.proBar.setRange( 0, 100 )
        self.proBar.setTextVisible( True )
        self.proBar.setFormat( self.text )
        self.proBar.setValue( 0 )
        self.proBar.setFixedSize( 300 , 40 )
        self.proBar.setAlignment(Qt.AlignCenter)
        self.proBar.show()

        #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection)
        # Make the Busybar delete itself and the QProgressBar when done        
        self.finished.connect(self.onFinished)

    def run(self):
        """
        """
        while not self.stop:                
            # keep looping while self is visible
            # Loop sending mail 
            for i in range(100):
                # emit the signal instead of calling setValue
                # also we can't read the progress bar value from the thread
                self.changeValue.emit( i )
                time.sleep(0.01)
            self.changeValue.emit( 0 )

    def onFinished(self):
        """
        """
        self.proBar.deleteLater()
        self.deleteLater()

    def Kill(self):
        """
        """
        self.stop = True
예제 #9
0
class ThreadManagerDialog(QDialog):
    def __init__( self, iface, title="Worker Thread"):
        QDialog.__init__( self, iface)#.mainWindow() )
        self.iface = iface
        self.setWindowTitle(title)
        self.setLayout(QVBoxLayout())
        self.primaryLabel = QLabel(self)
        self.layout().addWidget(self.primaryLabel)
        self.primaryBar = QProgressBar(self)
        self.layout().addWidget(self.primaryBar)
        self.secondaryLabel = QLabel(self)
        self.layout().addWidget(self.secondaryLabel)
        self.secondaryBar = QProgressBar(self)
        self.layout().addWidget(self.secondaryBar)
        self.closeButton = QPushButton("Close")
        self.closeButton.setEnabled(False)
        self.layout().addWidget(self.closeButton)
        self.closeButton.clicked.connect(self.reject)
    def run(self):
        self.runThread()
        self.exec_()
    def runThread( self):
        QObject.connect( self.workerThread, SIGNAL( "jobFinished( PyQt_PyObject )" ), self.jobFinishedFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryValue( PyQt_PyObject )" ), self.primaryValueFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryRange( PyQt_PyObject )" ), self.primaryRangeFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryText( PyQt_PyObject )" ), self.primaryTextFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryValue( PyQt_PyObject )" ), self.secondaryValueFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryRange( PyQt_PyObject )" ), self.secondaryRangeFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryText( PyQt_PyObject )" ), self.secondaryTextFromThread )
        self.workerThread.start()
    def cancelThread( self ):
        self.workerThread.stop()
    def jobFinishedFromThread( self, success ):
        self.workerThread.stop()
        self.primaryBar.setValue(self.primaryBar.maximum())
        self.secondaryBar.setValue(self.secondaryBar.maximum())
        self.emit( SIGNAL( "jobFinished( PyQt_PyObject )" ), success )
        self.closeButton.setEnabled( True )
    def primaryValueFromThread( self, value ):
        self.primaryBar.setValue(value)
    def primaryRangeFromThread( self, range_vals ):
        self.primaryBar.setRange( range_vals[ 0 ], range_vals[ 1 ] )
    def primaryTextFromThread( self, value ):
        self.primaryLabel.setText(value)
    def secondaryValueFromThread( self, value ):
        self.secondaryBar.setValue(value)
    def secondaryRangeFromThread( self, range_vals ):
        self.secondaryBar.setRange( range_vals[ 0 ], range_vals[ 1 ] )
    def secondaryTextFromThread( self, value ):
        self.secondaryLabel.setText(value)
예제 #10
0
class BlockingTask(QObject):
    """
    Blocking task provides a UI wrapper for long running tasks.
    While the task is executed a modal progress dialog will be shown.
    The task can be canceled through the UI.
    """
    load_finished = pyqtSignal(scene.Scene)

    def __init__(self, scene_load_func, message, *args, **kwargs):
        super(BlockingTask, self).__init__(*args, **kwargs)
        self.scene_load_func = scene_load_func
        self.message = message

        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 0)
        self.worker = None

    def start_task(self):
        self._async_execute()

    def _on_load_finished(self):
        logger.debug('On task finished')
        self.scene = self.worker.result
        if self.scene is not None:
            self.load_finished.emit(self.scene)
        self.progress_dialog.hide()

    def _on_load_start(self):
        logger.debug('On task start')
        self.progress_dialog = QProgressDialog(self.message,
                                               "Abort",
                                               0,
                                               0,
                                               self.parent(),
                                               flags=Qt.CustomizeWindowHint,
                                               )
        self.progress_dialog.setWindowModality(Qt.WindowModal)
        self.progress_dialog.canceled.connect(self._abort)
        self.progress_dialog.show()

    def _abort(self):
        self.worker.terminate()

    def _async_execute(self):
        self._on_load_start()
        self.worker = TaskWorker(self.scene_load_func)
        self.worker.task_done.connect(self._on_load_finished)
        self.worker.start()
예제 #11
0
def show_progress(i_face, msg):
    """
    Creates and shows a progress bar for some event.
    Does not have any progress information.
    Used to show user that something should be happening in the background

    :param i_face: iface where the progressbar will be shown
    :param msg: Message to be displayed in front of the progress bar
    """

    # Progress bar (without progress)
    bar = QProgressBar()
    bar.setRange(0, 0)
    progress_msg = i_face.messageBar().createMessage(msg)
    progress_msg.layout().addWidget(bar)
    i_face.messageBar().pushWidget(progress_msg, level=0)
예제 #12
0
 def __init__(self, parent, msg = ''):
     '''
     progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar
     :param parent:
     :param msg: string
     '''
     self.iface = parent.iface
     widget = self.iface.messageBar().createMessage("GooGIS plugin:",msg)
     progressBar = QProgressBar()
     progressBar.setRange(0,0) #(1,steps)
     progressBar.setValue(0)
     progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
     widget.layout().addWidget(progressBar)
     QtGui.qApp.processEvents()
     self.iface.messageBar().pushWidget(widget, QgsMessageBar.INFO, 50)
     QtGui.qApp.processEvents()
예제 #13
0
def create_progress_message_bar(iface, msg, no_percentage=False):
    """
    Use the messageBar of QGIS to display a message describing what's going
    on (typically during a time-consuming task), and a bar showing the
    progress of the process.

    :param msg: Message to be displayed, describing the current task
    :type: str

    :returns: progress object on which we can set the percentage of
    completion of the task through progress.setValue(percentage)
    :rtype: QProgressBar
    """
    progress_message_bar = iface.messageBar().createMessage(msg)
    progress = QProgressBar()
    if no_percentage:
        progress.setRange(0, 0)
    progress_message_bar.layout().addWidget(progress)
    iface.messageBar().pushWidget(progress_message_bar,
                                  iface.messageBar().INFO)
    return progress_message_bar, progress
예제 #14
0
파일: LDSGUI.py 프로젝트: josephramsay/LDS
class LDSControls(QFrame):
        
    STATIC_IMG = ('error_static.png','linz_static.png','busy_static.png','clean_static.png')
    ANIM_IMG   = ('error.gif','linz.gif','layer.gif','clean.gif')
    
    IMG_SPEED  = 100
    IMG_WIDTH  = 64
    IMG_HEIGHT = 64
    
    MAX_WD = 450
    
    GD_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../bin/gdal/gdal-data'))
    STATUS = LU.enum('ERROR','IDLE','BUSY','CLEAN')
    
    def __init__(self,parent):
        super(LDSControls, self).__init__()
        self.parent = parent
        self.initConf()
        self.initEPSG()
        self.initUI()
        
    def initConf(self):
        '''Read files in conf dir ending in conf'''
        self.cflist = ConfigInitialiser.getConfFiles()
        #self.imgset = self.STATIC_IMG if ConfigWrapper().readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        #self.imgset = self.STATIC_IMG if self.parent.confconn.tp.src.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        sep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.SRCNAME,self.parent.confconn.uconf)
        self.imgset = self.STATIC_IMG if sep.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.SRCNAME)
        
    def initEPSG(self):
        '''Read GDAL EPSG files, splitting by NZ(RSR) and RestOfTheWorld'''

        gcsf = gdal.FindFile('gdal','gcs.csv') 
        if not gcsf:
            gcsf = os.path.join(self.GD_PATH,'gcs.csv')
        pcsf = gdal.FindFile('gdal','pcs.csv') 
        if not pcsf: 
            pcsf = os.path.join(self.GD_PATH,'pcs.csv')
        gcs = ConfigInitialiser.readCSV(gcsf)
        pcs = ConfigInitialiser.readCSV(pcsf)

        self.nzlsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]]
        self.rowsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]]
                   
                   
    def initUI(self):
        
        # 0      1          2       3       4       5      6    7    8
        #'destname','lgselect','layer','uconf','group','epsg','fd','td','int'
        
        #self.rdest,rlgselect,self.rlayer,ruconf,self.rgroup,repsg,rfd,rtd,rint = readlist 
        
        QToolTip.setFont(QFont('SansSerif', 10))
        
        #labels
        destLabel = QLabel('Destination')
        lgLabel = QLabel('Group/Layer')
        epsgLabel = QLabel('EPSG')
        fromDateLabel = QLabel('From Date')
        toDateLabel = QLabel('To Date')
        confLabel = QLabel('User Config')
        
        self.view = QLabel() 
        self.view.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.view.setAlignment(Qt.AlignCenter)

        self.confcombo = QComboBox(self)
        self.confcombo.setToolTip('Enter your user config name (file) here')
        self.confcombo.addItems(self.cflist)
        self.confcombo.setEditable(False)
        #self.confcombo.currentIndexChanged.connect(self.doLGEditUpdate)
        
        #combos
        self.lgcombo = QComboBox(self)
        self.lgcombo.setMaximumWidth(self.MAX_WD)
        self.lgcombo.setDuplicatesEnabled(False)
        #self.lgcombo.setInsertPolicy(QComboBox.InsertAlphabetically)#?doesnt seem to work
        self.lgcombo.setToolTip('Select either Layer or Group entry')
        self.lgcombo.setEditable(False)
        self.sepindex = None
        #self.updateLGValues()
        
        self.epsgcombo = QComboBox(self)
        self.epsgcombo.setMaximumWidth(self.MAX_WD)
        self.epsgcombo.setToolTip('Setting an EPSG number here determines the output SR of the layer')  
        self.epsgcombo.addItems([i[1] for i in self.nzlsr])
        self.epsgcombo.insertSeparator(len(self.nzlsr))
        self.epsgcombo.addItems([i[1] for i in self.rowsr])
        self.epsgcombo.setEditable(True)
        self.epsgcombo.setEnabled(False)
        
        self.destlist = self.getConfiguredDestinations()
        self.destcombo = QComboBox(self)
        self.destcombo.setToolTip('Choose the desired output type')   
        self.destcombo.setEditable(False)
        self.destcombo.addItems(self.destlist)

        #date selection
        self.fromdateedit = QDateEdit()
        self.fromdateedit.setCalendarPopup(True)
        self.fromdateedit.setEnabled(False)
        
        self.todateedit = QDateEdit()
        self.todateedit.setCalendarPopup(True)
        self.todateedit.setEnabled(False)
        
        #check boxes
        self.epsgenable = QCheckBox()
        self.epsgenable.setCheckState(False)
        self.epsgenable.clicked.connect(self.doEPSGEnable)       
        
        self.fromdateenable = QCheckBox()
        self.fromdateenable.setCheckState(False)
        self.fromdateenable.clicked.connect(self.doFromDateEnable)
        
        self.todateenable = QCheckBox()
        self.todateenable.setCheckState(False) 
        self.todateenable.clicked.connect(self.doToDateEnable)
        
        self.progressbar = QProgressBar()
        self.progressbar.setRange(0,100)
        self.progressbar.setVisible(True)
        self.progressbar.setMinimumWidth(self.MAX_WD)
        
        
        #buttons        
        self.initbutton = QPushButton("waiting")
        self.initbutton.setToolTip('Initialise the Layer Configuration')
        self.initbutton.clicked.connect(self.doInitClickAction)
        
        self.cleanbutton = QPushButton("Clean")
        self.cleanbutton.setToolTip('Clean the selected layer/group from local storage')
        self.cleanbutton.clicked.connect(self.doCleanClickAction)
        
        self.replicatebutton = QPushButton("Replicate")
        self.replicatebutton.setToolTip('Execute selected replication')
        self.replicatebutton.clicked.connect(self.doReplicateClickAction)
        
        self.cancelbutton = QPushButton("Close")
        self.cancelbutton.setToolTip('Close the LDS Replicate application')       
        self.cancelbutton.clicked.connect(self.parent.close)


        #set dialog values using GPR
        self.updateGUIValues(self.parent.gvs)
        
        #set onchange here otherwise we get circular initialisation
        self.destcombo.currentIndexChanged.connect(self.doDestChanged)
        self.confcombo.currentIndexChanged.connect(self.doConfChanged)
        self.lgcombo.currentIndexChanged.connect(self.doLGComboChanged)

        self.setStatus(self.STATUS.IDLE)
        
        #grid
        grid = QGridLayout()
        grid.setSpacing(10)
        
        
        #placement section ------------------------------------
        #---------+---------+--------+---------+--------
        # dest LB |         | dest DD
        # grp LB  |         | grp DD
        # conf LB |         | conf DD
        # epsg L  | epsg CB | epsg DD
        # f dt L  | f dt CB | f dt DD
        # t td L  | t td CB | t td DD
        # icon    |       <- progress ->
        # layer B | <- . -> |repl B  | clean B | close B 
        #---------+---------+--------+---------+--------

        grid.addWidget(destLabel, 1, 0)
        grid.addWidget(self.destcombo, 1, 2)

        #grid.addWidget(layerLabel, 2, 0)
        grid.addWidget(lgLabel, 2, 0)
        grid.addWidget(self.lgcombo, 2, 2)
        
        grid.addWidget(confLabel, 3, 0)
        grid.addWidget(self.confcombo, 3, 2)
        
        #grid.addWidget(groupLabel, 4, 0)
        #grid.addWidget(self.groupEdit, 4, 2)
        
        grid.addWidget(epsgLabel, 5, 0)
        grid.addWidget(self.epsgenable, 5, 1)
        grid.addWidget(self.epsgcombo, 5, 2)

        grid.addWidget(fromDateLabel, 6, 0)
        grid.addWidget(self.fromdateenable, 6, 1)
        grid.addWidget(self.fromdateedit, 6, 2)
        
        grid.addWidget(toDateLabel, 7, 0)
        grid.addWidget(self.todateenable, 7, 1)
        grid.addWidget(self.todateedit, 7, 2)
        
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.view) 
        hbox3.addStretch(1)
        hbox3.addWidget(self.progressbar)

        #hbox3.addLayout(vbox2)
        #hbox3.addLayout(vbox3)
        
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.initbutton)
        hbox4.addStretch(1)
        hbox4.addWidget(self.replicatebutton)
        hbox4.addWidget(self.cleanbutton)
        hbox4.addWidget(self.cancelbutton)
        

        vbox = QVBoxLayout()
        #vbox.addStretch(1)
        vbox.addLayout(grid)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        
        self.setLayout(vbox)  
       
    #def setProgress(self,pct):
    #    self.progressbar.setValue(pct)
        
    def setStatus(self,status,message='',tooltip=None):
        '''Sets indicator icon and statusbar message'''
        self.parent.statusbar.showMessage(message)
        self.parent.statusbar.setToolTip(tooltip if tooltip else '')

        #progress
        loc = os.path.abspath(os.path.join(IMG_LOC,self.imgset[status]))
        #loc = os.path.abspath(os.path.join(os.path.dirname(__file__),self.parent.IMG_LOC,self.imgset[status]))
        self.progressbar.setVisible(status in (self.STATUS.BUSY, self.STATUS.CLEAN))
        
        #icon
        anim = QMovie(loc, QByteArray(), self)
        anim.setScaledSize(QSize(self.IMG_WIDTH,self.IMG_HEIGHT))
        anim.setCacheMode(QMovie.CacheAll)
        anim.setSpeed(self.IMG_SPEED)
        self.view.clear()
        self.view.setMovie(anim)
        anim.start()

        self.view.repaint()
        QApplication.processEvents(QEventLoop.AllEvents)

    def mainWindowEnable(self,enable=True):
        cons = (self.lgcombo, self.confcombo, self.destcombo, 
                self.initbutton, self.replicatebutton, self.cleanbutton, self.cancelbutton,
                self.epsgenable,self.fromdateenable,self.todateenable,
                self.parent.menubar)
        for c in cons:
            c.setEnabled(enable)
            
        if enable:
            self.epsgcombo.setEnabled(self.epsgenable.checkState())
            self.fromdateedit.setEnabled(self.fromdateenable.checkState())
            self.todateedit.setEnabled(self.todateenable.checkState())
        else:
            self.epsgcombo.setEnabled(False)
            self.fromdateedit.setEnabled(False)
            self.todateedit.setEnabled(False)
   
        QApplication.restoreOverrideCursor() if enable else QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 

    def refreshLGCombo(self):
        '''Re index LG combobox since a refreshLG call (new dest?) will usually mean new groups'''
        self.lgcombo.clear()
        self.lgcombo.addItems([i[2] for i in self.parent.confconn.lglist])
        #NOTE the separator consumes an index, if not clearing the combobox selectively remove the old sepindex (assumes g preceeds l)
        #if self.sepindex:
        #    self.lgcombo.removeItem(self.sepindex)
        self.sepindex = [i[0] for i in self.parent.confconn.lglist].count(LORG.GROUP)
        self.lgcombo.insertSeparator(self.sepindex)
        
    def updateLGValues(self,uconf,lgval,dest):
        '''Sets the values displayed in the Layer/Group combo'''
        #because we cant seem to sort combobox entries and want groups at the top, clear and re-add
        #TRACE#        
        #pdb.set_trace()
        sf = None
        try:
            self.parent.confconn.initConnections(uconf,lgval,dest)
        except Exception as e:
            sf=1
            ldslog.error('Error Updating UC Values. '+str(e))
            
        if sf:
            self.setStatus(self.STATUS.ERROR,'Error Updating UC Values', str(e))
        else:
            self.setStatus(self.STATUS.IDLE)
            
        self.refreshLGCombo()
        
    def centre(self):
        
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    
    def gprParameters(self,rdest):
        '''Zip default and GPR values'''
        return [x if LU.assessNone(x) else y for x,y in zip(self.parent.gpr.readsec(rdest),self.parent.DEF_RVALS[1:])]
    
    def getLCE(self,ln):
        '''Read layer parameters'''
        dep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        #sep = self.parent.confconn.reg.openEndPoint('WFS',self.parent.confconn.uconf)
        self.parent.confconn.reg.setupLayerConfig(self.parent.confconn.tp,None,dep,initlc=False)
        lce = dep.getLayerConf().readLayerParameters(ln)
        #self.parent.confconn.reg.closeEndPoint('WFS')
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        sep,dep = None,None
        return lce
    
    
    def doDestChanged(self):
        '''Read the destname parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rvals = self.gprParameters(rdest)
        self.updateGUIValues([rdest]+rvals)    
        
        
    def doConfChanged(self):
        '''Read the user conf parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rlg,_,rep,rfd,rtd = self.gprParameters(rdest)
        ruc = str(self.cflist[self.confcombo.currentIndex()])
        self.updateGUIValues((rdest,rlg,ruc,rep,rfd,rtd))
        
        
    def doLGComboChanged(self):
        '''Read the layer/group value and change epsg to layer or gpr match'''
        #get a matching LG entry and test whether its a layer or group
        #lgi = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgi = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #lgi can be none if we init a new group, in which case we use the GPR value
        if lgi:
            lge = self.parent.confconn.lglist[lgi]
            lce = self.getLCE(lge[1]) if lge[0]==LORG.LAYER else None
        else:
            lce = None
        
        #look for filled layer conf epsg OR use prefs stored in gpr
        if lce and LU.assessNone(lce.epsg):
            epsgval = lce.epsg
        else:
            rdest = str(self.destlist[self.destcombo.currentIndex()])
            _,_,epsgval,_,_ = self.gprParameters(rdest)
        epsgindex = [i[0] for i in self.nzlsr+[(0,0)]+self.rowsr].index(epsgval)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(int(epsgindex))

        
    def updateGUIValues(self,readlist):
        '''Fill dialog values from provided list'''
        #TODO. Remove circular references when setCurrentIndex() triggers do###Changed()
        #Read user input
        rdest,self.rlgval,ruconf,repsg,rfd,rtd = readlist
        
        #--------------------------------------------------------------------
        
        #Destination Menu
        selecteddest = LU.standardiseDriverNames(rdest)
        if selecteddest not in self.destlist:
            self.destlist = self.getConfiguredDestinations()
            self.destcombo.addItem(selecteddest)
        destindex = self.destlist.index(selecteddest) if selecteddest else 0
        
        if self.destcombo.currentIndex() != destindex:
            self.destcombo.setCurrentIndex(destindex)
        
        #InitButton
        self.initbutton.setText('Layer Select')
        
        #Config File
        confindex = 0
        if LU.assessNone(ruconf):
            ruconf = ruconf.split('.')[0]
            if ruconf not in self.cflist:
                self.cflist += [ruconf,]
                self.confcombo.addItem(ruconf)
            confindex = self.cflist.index(ruconf)
            
        if self.confcombo.currentIndex() != confindex:
            self.confcombo.setCurrentIndex(confindex)
        #self.confEdit.setText(ruconf if LU.assessNone(ruconf) else '')
        
        #Layer/Group Selection
        self.updateLGValues(ruconf,self.rlgval,rdest)
        lgindex = None
        if LU.assessNone(self.rlgval):
            #index of list value
            lgindex = self.parent.confconn.getLayerGroupIndex(self.rlgval,col=1)
            
        if LU.assessNone(lgindex):
            #advance by 1 for sep
            lgindex += 1 if lgindex>self.sepindex else 0 
        else:
            #using the separator index sets the combo to blank
            lgindex = self.sepindex
        if self.lgcombo.currentIndex() != lgindex:
            self.lgcombo.setCurrentIndex(lgindex)
        #self.doLGEditUpdate()
        
        #EPSG
        #                                user > layerconf
        #useepsg = LU.precedence(repsg, lce.epsg if lce else None, None)
        epsgindex = [i[0] for i in self.nzlsr+[(None,None)]+self.rowsr].index(repsg)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(epsgindex)
            
        #epsgedit = self.epsgcombo.lineEdit()
        #epsgedit.setText([e[1] for e in self.nzlsr+self.rowsr if e[0]==repsg][0])
        
        #epsgedit.setText([e for e in self.nzlsr+self.rowsr if re.match('^\s*(\d+).*',e).group(1)==repsg][0])
        
        #To/From Dates
        if LU.assessNone(rfd):
            self.fromdateedit.setDate(QDate(int(rfd[0:4]),int(rfd[5:7]),int(rfd[8:10])))
        else:
            early = DataStore.EARLIEST_INIT_DATE
            self.fromdateedit.setDate(QDate(int(early[0:4]),int(early[5:7]),int(early[8:10])))
            
        if LU.assessNone(rtd):
            self.todateedit.setDate(QDate(int(rtd[0:4]),int(rtd[5:7]),int(rtd[8:10]))) 
        else:
            today = DataStore.getCurrent()
            self.todateedit.setDate(QDate(int(today[0:4]),int(today[5:7]),int(today[8:10])))
            
        #Internal/External CheckBox
#        if LU.assessNone(rint):
#            self.internalTrigger.setChecked(rint.lower()==DataStore.CONF_INT)
#        else:
#            self.internalTrigger.setChecked(DataStore.DEFAULT_CONF==DataStore.CONF_INT)
        
        
    def getConfiguredDestinations(self):
        defml = ['',]+DataStore.DRIVER_NAMES.values()
        return [d for d in self.parent.gpr.getDestinations() if d in defml]
        
    def doEPSGEnable(self):
        self.epsgcombo.setEnabled(self.epsgenable.isChecked())
        
    def doFromDateEnable(self):
        self.fromdateedit.setEnabled(self.fromdateenable.isChecked())
          
    def doToDateEnable(self):
        self.todateedit.setEnabled(self.todateenable.isChecked())  
          
    def readParameters(self):
        '''Read values out of dialogs'''
        destination = LU.assessNone(str(self.destlist[self.destcombo.currentIndex()]))
        #lgindex = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgindex = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #NB need to test for None explicitly since zero is a valid index
        lgval = self.parent.confconn.lglist[lgindex][1] if LU.assessNone(lgindex) else None       
        #uconf = LU.standardiseUserConfigName(str(self.confcombo.lineEdit().text()))
        #uconf = str(self.confcombo.lineEdit().text())
        uconf = str(self.cflist[self.confcombo.currentIndex()])
        ee = self.epsgenable.isChecked()
        epsg = None if ee is False else re.match('^\s*(\d+).*',str(self.epsgcombo.lineEdit().text())).group(1)
        fe = self.fromdateenable.isChecked()
        te = self.todateenable.isChecked()
        fd = None if fe is False else str(self.fromdateedit.date().toString('yyyy-MM-dd'))
        td = None if te is False else str(self.todateedit.date().toString('yyyy-MM-dd'))
        
        return destination,lgval,uconf,epsg,fe,te,fd,td
    
    def doInitClickAction(self):
        '''Initialise the LC on LC-button-click, action'''
        try:
            try:
                self.setStatus(self.STATUS.BUSY,'Opening Layer-Config Editor')  
                self.progressbar.setValue(0)
                self.parent.runLayerConfigAction()
            finally:
                self.setStatus(self.STATUS.IDLE,'Ready')
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Error in Layer-Config',str(sys.exc_info()))#e))
        
    def doCleanClickAction(self):
        '''Set clean anim and run clean'''
        #lgo = self.lgcombo.currentText().toUtf8().data()
        lgo = LQ.readWidgetText(self.lgcombo.currentText())
        
        try:
            self.setStatus(self.STATUS.CLEAN,'Running Clean '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(True)
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Clean of '+lgo,str(sys.exc_info()))#e))
        
    def doReplicateClickAction(self):
        '''Set busy anim and run repl'''
        lgo = self.lgcombo.currentText()#.toUtf8().data()#only used for error messages
        try:
            self.setStatus(self.STATUS.BUSY,'Running Replicate '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(False)
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Replication of '+lgo,str(sys.exc_info()))#e))

    def runReplicationScript(self,clean=False):
        '''Run the layer/group repliction script'''
        destination,lgval,uconf,epsg,fe,te,fd,td = self.readParameters()
        uconf_path = LU.standardiseUserConfigName(uconf)
        destination_path = LU.standardiseLayerConfigName(destination)
        destination_driver = LU.standardiseDriverNames(destination)

        if not os.path.exists(uconf_path):
            self.userConfMessage(uconf_path)
            return
        elif not MainFileReader(uconf_path).hasSection(destination_driver):
            self.userConfMessage(uconf_path,destination_driver)
            return
        #-----------------------------------------------------
        #'destname','layer','uconf','group','epsg','fd','td','int'
     
        self.parent.gpr.write((destination_driver,lgval,uconf,epsg,fd,td))        
        ldslog.info(u'dest={0}, lg={1}, conf={2}, epsg={3}'.format(destination_driver,lgval,uconf,epsg))
        ldslog.info('fd={0}, td={1}, fe={2}, te={3}'.format(fd,td,fe,te))
        lgindex = self.parent.confconn.getLayerGroupIndex(lgval,col=1)
        #lorg = self.parent.confconn.lglist[lgindex][0]
        #----------don't need lorg in TP anymore but it is useful for sorting/counting groups
        #self.parent.confconn.tp.setLayerOrGroup(lorg)
        self.parent.confconn.tp.setLayerGroupValue(lgval)
        if self.fromdateenable.isChecked(): self.parent.confconn.tp.setFromDate(fd)
        if self.todateenable.isChecked(): self.parent.confconn.tp.setToDate(td)
        self.parent.confconn.tp.setUserConf(uconf)
        if self.epsgenable: self.parent.confconn.tp.setEPSG(epsg)
        
        #because clean state persists in TP
        if clean:
            self.parent.confconn.tp.setCleanConfig()
        else:
            self.parent.confconn.tp.clearCleanConfig()
        #(re)initialise the data source since uconf may have changed
        #>>#self.parent.confconn.tp.src = self.parent.confconn.initSourceWrapper()
        #--------------------------
        ###ep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        
        ###self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        ###ep = None
        #Open ProcessRunner and run with TP(proc)/self(gui) instances
        #HACK temp add of dest_drv to PR call
        try:
            #TODO. Test for valid LC first
            self.tpr = ProcessRunner(self,destination_driver)
        except Exception as e:
            ldslog.error('Cannot create ProcessRunner {}. NB Possible missing Layer Config {}'.format(str(e),destination_path))
            self.layerConfMessage(destination_path)
            return
        #If PR has been successfully created we must vave a valid dst    
        self.tpr.start()
        
    def quitProcessRunner(self):
        self.tpr.join()
        self.tpr.quit()
        self.trp = None

        
    def userConfMessage(self,uconf,secname=None):
        ucans = QMessageBox.warning(self, 'User Config Missing/Incomplete', 
                                'Specified User-Config file, '+str(uconf)+' does not exist' if secname is None else 'User-Config file does not contain '+str(secname)+' section', 
                                'Back','Initialise User Config')
        if not ucans:
            #Retry
            ldslog.warn('Retry specifying UC')
            #self.confcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset User Config Wizard')
        self.parent.runWizardAction()


    def layerConfMessage(self,dest):
        lcans = QMessageBox.warning(self, 'Layer Config Missing', 
                                'Required Layer-Config file, '+str(dest)+' does not exist', 
                                'Back','Run Layer Select')
        if not lcans:
            #Retry
            ldslog.warn('Retry specifying LC')
            #self.destcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset Layer Config')
        self.doInitClickAction()
예제 #15
0
def createUnbefFlaechen(dbQK,
                        liste_selAbflparamTeilgeb,
                        autokorrektur,
                        dbtyp='spatialite'):
    '''Import der Kanaldaten aus einer HE-Firebird-Datenbank und Schreiben in eine QKan-SpatiaLite-Datenbank.

    :dbQK:                  Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet.
    :type database:         DBConnection (geerbt von dbapi...)

    :liste_selAbflparamTeilgeb:    Liste der bei der Bearbeitung zu berücksichtigenden Kombinationen aus 
                            Abflussparameter und Teilgebiet (Tabelle tezg)
    :type:                  list

    :autokorrektur:         Option, ob eine automatische Korrektur der Bezeichnungen durchgeführt
                            werden soll. Falls nicht, wird die Bearbeitung mit einer Fehlermeldung
                            abgebrochen.
    :type autokorrektur:    String
    
    :dbtyp:                 Typ der Datenbank (spatialite, postgis)
    :type dbtyp:            String
    
    :returns:               void
    
    Für alle TEZG-Flächen wird, falls nicht schon vorhanden, ein unbefestigtes Flächenobjekt erzeugt. 
    Dazu können in der Auswahlmaske zunächst die Kombinationen aus Abflussparameter und Teilgebiet 
    gewählt werden, die in der Tabelle "tezg" vorkommen und die nachfolgenden Voraussetzungen erfüllen:

    - Im Feld "abflussparameter" muss auf einen Abflussparameter verwiesen werden, der für unbefestigte 
      Flächen erzeugt wurde (infiltrationsparameter > 0)
    '''

    global progress_bar
    progress_bar = QProgressBar(iface.messageBar())
    progress_bar.setRange(0, 100)
    status_message = iface.messageBar().createMessage(
        u"Info",
        u"Erzeugung von unbefestigten Flächen in Arbeit. Bitte warten.")
    status_message.layout().addWidget(progress_bar)
    iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO, 10)

    # status_message.setText(u"Erzeugung von unbefestigten Flächen ist in Arbeit.")
    progress_bar.setValue(1)

    # ------------------------------------------------------------------------------
    # Datenbankverbindungen

    # Kontrolle, ob tezg-Flächen eindeutig Namen haben:

    if not checknames(dbQK, u'tezg', u'flnam', u'ft_', autokorrektur):
        return False
    if not checknames(dbQK, u'flaechen', u'flnam', u'f_', autokorrektur):
        return False

    # Prüfung, ob unzulässige Kombinationen ausgewählt wurden
    if len(liste_selAbflparamTeilgeb) > 0:
        logger.debug(u'\nliste_selAbflparamTeilgeb (2): {}'.format(
            liste_selAbflparamTeilgeb))
        if False in [(attr[-1] == u'') for attr in liste_selAbflparamTeilgeb]:
            fehlermeldung(
                u"Falsche Auswahl",
                u"Bitte nur zulässige Abflussparameter und Teilgebiete auswählen (siehe Spalte 'Anmerkungen')"
            )
            return False
    else:
        sql = u"""SELECT count(*) AS anz
            FROM tezg AS te
            LEFT JOIN abflussparameter AS ap
            ON te.abflussparameter = ap.apnam
            LEFT JOIN bodenklassen AS bk
            ON bk.bknam = ap.bodenklasse
            WHERE te.abflussparameter ISNULL OR
                  bk.infiltrationsrateanfang ISNULL OR
                  bk.infiltrationsrateanfang < 0.00001"""
        if not dbQK.sql(sql, u'QKan.CreateUnbefFlaechen (1)'):
            return False
        data = dbQK.fetchall()
        if len(data) > 0:
            if data[0][0] > 0:
                fehlermeldung(
                    u"Unvollständige Daten",
                    u"In der Tabelle TEZG-Flächen sind noch fehlerhafte Daten zu den Abflussparametern oder den Bodenklassen enthalten. "
                )
                return False

    # Für die Erzeugung der Restflächen reicht eine SQL-Abfrage aus.

    # status_message.setText(u"Erzeugung von unbefestigten Flächen")
    progress_bar.setValue(10)

    # Vorbereitung des Auswahlkriteriums für die SQL-Abfrage: Kombination aus abflussparameter und teilgebiet
    # Dieser Block ist identisch in k_unbef und in application enthalten

    if len(liste_selAbflparamTeilgeb) == 0:
        auswahl = u''
    elif len(liste_selAbflparamTeilgeb) == 1:
        auswahl = u' AND'
    elif len(liste_selAbflparamTeilgeb) >= 2:
        auswahl = u' AND ('
    else:
        fehlermeldung(u"Interner Fehler", u"Fehler in Fallunterscheidung!")
        return False

    # Anfang SQL-Krierien zur Auswahl der tezg-Flächen
    first = True
    for attr in liste_selAbflparamTeilgeb:
        if attr[4] == u'None' or attr[1] == u'None':
            fehlermeldung(
                u'Datenfehler: ',
                u'In den ausgewählten Daten sind noch Datenfelder nicht definiert ("NULL").'
            )
            return False
        if first:
            first = False
            auswahl += u""" (tezg.abflussparameter = '{abflussparameter}' AND
                            tezg.teilgebiet = '{teilgebiet}')""".format(
                abflussparameter=attr[0], teilgebiet=attr[1])
        else:
            auswahl += u""" OR\n      (tezg.abflussparameter = '{abflussparameter}' AND
                            tezg.teilgebiet = '{teilgebiet}')""".format(
                abflussparameter=attr[0], teilgebiet=attr[1])

    if len(liste_selAbflparamTeilgeb) >= 2:
        auswahl += u")"
    # Ende SQL-Krierien zur Auswahl der tezg-Flächen

    # Erläuterung zur nachfolgenden SQL-Abfrage:
    # 1. aus der Abfrage werden alle Datensätze ohne geom-Objekte ausgeschlossen
    # 2. Wenn in einer tezg-Fläche keine Fläche liegt, wird einfach die tezg-Fläche übernommen

    sql = u"""WITH flbef AS (
            SELECT 'fd_' || ltrim(tezg.flnam, 'ft_') AS flnam, 
              tezg.haltnam AS haltnam, tezg.neigkl AS neigkl, 
              tezg.regenschreiber AS regenschreiber, tezg.teilgebiet AS teilgebiet,
              tezg.abflussparameter AS abflussparameter,
              'Erzeugt mit Plugin Erzeuge unbefestigte Flaechen' AS kommentar, 
              MakeValid(tezg.geom) AS geot, 
              ST_Union(MakeValid(flaechen.geom)) AS geob
            FROM (SELECT * FROM tezg WHERE geom IS NOT NULL) AS tezg
            LEFT JOIN (SELECT * FROM flaechen WHERE geom IS NOT NULL) AS flaechen
            ON Intersects(tezg.geom, flaechen.geom)
            WHERE 'fd_' || ltrim(tezg.flnam, 'ft_') not in 
            (   SELECT flnam FROM flaechen WHERE flnam IS NOT NULL){auswahl}
            GROUP BY tezg.pk)
            INSERT INTO flaechen (flnam, haltnam, neigkl, regenschreiber, teilgebiet, abflussparameter, kommentar, geom) 
             SELECT flnam AS flnam, haltnam, neigkl, regenschreiber, teilgebiet, abflussparameter,
            kommentar, 
            CASE WHEN geob IS NULL  THEN geot ELSE CastToMultiPolygon(Difference(geot,geob)) END AS geof FROM flbef
            WHERE area(geof) > 0.5 AND geof IS NOT NULL""".format(
        auswahl=auswahl)

    logger.debug(u'QKan.k_unbef (3) - liste_selAbflparamTeilgeb = \n{}'.format(
        str(liste_selAbflparamTeilgeb)))
    if not dbQK.sql(sql, u"QKan.CreateUnbefFlaechen (4)"):
        return False

    # # status_message.setText(u"Erstellen der Anbindungen für die unbefestigten Flächen")
    # progress_bar.setValue(50)

    # # Hinzufügen von Verknüpfungen in die Tabelle linkfl für die neu erstellten unbefestigten Flächen
    # sql = u"""INSERT INTO linkfl (flnam, aufteilen, teilgebiet, geom, glink)
    # SELECT
    # fl.flnam AS flnam,
    # NULL AS aufteilen,
    # fl.teilgebiet AS teilgebiet,
    # NULL AS geom,
    # MakeLine(PointOnSurface(fl.geom),Centroid(ha.geom)) AS glink
    # FROM flaechen AS fl
    # LEFT JOIN haltungen AS ha
    # ON fl.haltnam = ha.haltnam
    # INNER JOIN tezg AS tg
    # ON 'fd_' || ltrim(tg.flnam, 'ft_') = fl.flnam
    # WHERE fl.flnam NOT IN
    # (   SELECT flnam FROM linkfl WHERE flnam IS NOT NULL)"""

    # if not dbQK.sql(sql, u"QKan.CreateUnbefFlaechen (5)"):
    # return False

    # status_message.setText(u"Nachbearbeitung")
    progress_bar.setValue(90)

    dbQK.commit()
    del dbQK

    # Karte aktualisieren
    iface.mapCanvas().refreshAllLayers()

    iface.mainWindow().statusBar().clearMessage()
    iface.messageBar().pushMessage(u"Information",
                                   u"Restflächen sind erstellt!",
                                   level=QgsMessageBar.INFO)
    QgsMessageLog.logMessage(u"\nRestflächen sind erstellt!",
                             level=QgsMessageLog.INFO)

    progress_bar.setValue(100)
    status_message.setText(
        u"Erzeugung von unbefestigten Flächen abgeschlossen.")
    status_message.setLevel(QgsMessageBar.SUCCESS)
예제 #16
0
파일: process.py 프로젝트: halbbob/dff
class CarvingProcess(QWidget, EventHandler):
    def __init__(self, selector, vnode):
        QWidget.__init__(self)
        EventHandler.__init__(self)
        self.vnode = vnode
        self.filesize = vnode.value().size()
        self.tm = TaskManager()
        self.selector = selector
        self.setLayout(QVBoxLayout())
        self.factor = 1
        self.parsetime = 0
        self.time = time.time()
        self.starttime = time.time()
        self.createStartOffset()
        self.createButtons()
        self.createStateInfo()


    def createStartOffset(self):
        self.offsetLayout = QHBoxLayout()
        self.offsetSpinBox = QFFSpinBox(self)
        self.offsetSpinBox.setMinimum(0)
        self.offsetSpinBox.setMaximum(self.filesize)
        self.offsetLabel = QLabel("start offset:")
        self.offsetLayout.addWidget(self.offsetLabel)
        self.offsetLayout.addWidget(self.offsetSpinBox)
        self.layout().addLayout(self.offsetLayout)


    def createButtons(self):
        self.startButton = QPushButton("Start")
        self.stopButton = QPushButton("Stop")
        self.stopButton.setEnabled(False)
        self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCarving)
        self.connect(self.startButton, SIGNAL("clicked()"), self.startCarving)
        self.connect(self, SIGNAL("ended"), self.carvingEnded)
        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.startButton)
        self.buttonLayout.addWidget(self.stopButton)
        self.layout().addLayout(self.buttonLayout)


    def createStateInfo(self):
        self.stateLayout = QVBoxLayout()

        self.overallLayout = QHBoxLayout()
        self.currentLabel = QLabel("Overall progress :")
        self.currentProgress = QProgressBar()
        self.overallLayout.addWidget(self.currentLabel)
        self.overallLayout.addWidget(self.currentProgress)
        self.stateLayout.addLayout(self.overallLayout)

        self.elapsedLabel = QLabel("elapsed time:    00d00h00m00s")
        self.stateLayout.addWidget(self.elapsedLabel)
        self.estimatedLabel = QLabel("estimated time: 00d00h00m00s")
        self.stateLayout.addWidget(self.estimatedLabel)
        self.totalLabel = QLabel("total headers found: 0")
        self.stateLayout.addWidget(self.totalLabel)
        self.stateLayout.setEnabled(False)
        self.layout().addLayout(self.stateLayout)


    def createContext(self, selected):
        lpatterns = VList()
        lpatterns.thisown = False
        for filetype in selected.iterkeys():
            patterns = selected[filetype][0]
            aligned = selected[filetype][1]
            for pattern in patterns:
                vpattern = VMap()
                vpattern.thisown = False
                vfiletype = Variant(filetype, typeId.String)
                vfiletype.thisown = False
                vpattern["filetype"] = vfiletype
                header = VMap()
                header.thisown = False
                val = Variant(pattern[0], typeId.String)
                val.thisown = False
                header["needle"] = val
                val = Variant(len(pattern[0]), typeId.UInt32)
                val.thisown = False
                header["size"] = val
                footer = VMap()
                footer.thisown = False
                val = Variant(pattern[1], typeId.String)
                val.thisown = False
                footer["needle"] = val
                val = Variant(len(pattern[1]), typeId.UInt32)
                val.thisown = False
                footer["size"] = val
                vheader = Variant(header)
                vheader.thisown = False
                vpattern["header"] = vheader
                vfooter = Variant(footer)
                vfooter.thisown = False
                vpattern["footer"] = vfooter
                vwindow = Variant(int(pattern[2]), typeId.UInt32)
                vwindow.thisown = False
                vpattern["window"] = vwindow
                val = Variant(aligned, typeId.Bool)
                val.thisown = False
                vpattern["aligned"] = val
                lpatterns.append(vpattern)
        vpatterns = Variant(lpatterns)
        vpatterns.thisown = False
        return vpatterns



    def startCarving(self):
        selected = self.selector.selectedItems()
        patterns = self.createContext(selected)
        args = VMap()
        args.thisown = False
        args["patterns"] = patterns
        args["file"] = self.vnode
        startoff = Variant(self.offsetSpinBox.value(), typeId.UInt64)
        startoff.thisown = False
        args["start-offset"] = startoff
        factor = round(float(self.filesize) / 2147483647)
        self.startButton.setEnabled(False)
        self.stopButton.setEnabled(True)
        self.stopButton.setDown(False)
        if factor == 0:
            factor = 1
        proc = self.tm.add("carver", args, ["gui", "thread"])
        if proc:
            self.doJob(self.filesize, factor, self.offsetSpinBox.value())
            self.stateLayout.setEnabled(True)
            self.connection(proc.inst)
            proc.inst.connection(self)
            #self.connect(self, SIGNAL("stateInfo(QString)"), self.setStateInfo)



    def carvingEnded(self, res):
        #results = str(res).split("\n")
        #print results
        #for item in results:
        #    begidx = item.find(":")
        #    self.res.add_const(str(item[:begidx]), str(item[begidx+1:] + "\n"))
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)
        self.stateLayout.setEnabled(False)


    def stopCarving(self):
        self.killJob()
        self.stopButton.setDown(True)


    def strtime(self, day, hour, min, sec):
        day = str(day)
        hour = str(hour)
        min = str(min)
        sec = str(sec)
        res = "0" * (2-len(day)) + day + "d" + "0" * (2-len(hour)) + hour + "h" + "0" * (2-len(min)) + min + "m" + "0" * (2-len(sec)) + sec + "s"
        return res


    def timesec2str(self, timesec):
        day = hour = min = sec = 0
        if timesec > 3600 * 24:
            day = timesec / (3600 * 24)
            timesec = timesec % (3600 * 24)
        if timesec > 3600:
            hour = timesec / 3600
            timesec = timesec % 3600
        if timesec > 60:
            min = timesec / 60
            timesec = timesec % 60
        sec = timesec
        res = self.strtime(int(day), int(hour), int(min), int(sec))
        return res


    def Event(self, e):
        if e.type == Carver.Position:
            self.emit(SIGNAL("updatePosition"), e)
        elif e.type == Carver.Matches:
            self.emit(SIGNAL("updateMatches"), e)
        elif e.type == Carver.EndOfProcessing:
            self.emit(SIGNAL("ended"), "")


    def updatePosition(self, e):
        ref = time.time() - self.time
        self.time = time.time()
        if not str(ref).startswith("0.0"):
            ref *= self.parsetime
            res = self.timesec2str(ref)
            self.estimatedLabel.setText("estimated time: " + res)
        res = self.timesec2str(time.time() - self.starttime)
        self.elapsedLabel.setText("elapsed time:    " + res)
        i = int(e.value.value() / self.factor)
        if i > 2147483647:
            i = 2147483647
        self.emit(SIGNAL("valueChanged(int)"), i)
        info = self.currentProgress.text() + " - " + self.totalLabel.text()
        self.emit(SIGNAL("stateInfo(QString)"), info)


    def updateMatches(self, e):
        self.totalLabel.setText("total headers found: " + str(e.value))
            


    def doJob(self, filesize, factor, start):
        self.factor = factor
        self.parsetime = filesize / (10*1204*1024)
        self.elapsedLabel.setText("elapsed time:    00d00h00m00s")
        self.estimatedLabel.setText("estimated time: 00d00h00m00s")
        self.totalLabel.setText("total headers found: 0")
        maxrange = int(filesize / self.factor)
        if maxrange > 2147483647:
            maxrange = 2147483647
        self.currentProgress.setRange(0, maxrange)
        self.currentProgress.setValue(0)
        self.connect(self, SIGNAL("valueChanged(int)"), self.currentProgress.setValue)
        self.time = time.time()
        self.starttime = time.time()
        self.connect(self, SIGNAL("updateMatches"), self.updateMatches)
        self.connect(self, SIGNAL("updatePosition"), self.updatePosition)


    def killJob(self):
        e = event()
        e.thisown = False
        e.value = None
        e.type = Carver.Stop
        self.notify(e)
예제 #17
0
class UploadDialog(QDialog):


    def __init__(self, tracks, device_info=None, username=None, password=None, auth_token=None, parent=None):
        super(UploadDialog, self).__init__(parent)

        self.tracks = tracks

        self.username = username
        self.password = password
        self._first_auth = True

        self.total_progress = QProgressBar(self)
        self.total_progress.setRange(0, len(tracks))
        self.total_progress.setValue(0)
        self.total_progress.setFormat('%v of %m tracks uploaded')

        self.item_progress = QProgressBar(self)
        self.item_progress.setRange(0, 100)
        self.item_progress.setValue(0)
        self.item_progress.setFormat('%p%')

        self.buttons = QDialogButtonBox(QDialogButtonBox.Cancel)
        self.buttons.rejected.connect(self.reject)

        self.status_msg = QLabel('Starting upload', self)


        self.setWindowTitle('Uploading')


        self._createLayout()


        self.upload = StravaUpload(tracks, device_info=device_info, parent=self, auth_token=auth_token)

        self.upload.authNeeded.connect(self._onAuthNeeded)
        self.upload.itemProgress.connect(self.item_progress.setValue)
        self.upload.totalProgress.connect(self.total_progress.setValue)
        self.upload.statusMessage.connect(self.status_msg.setText)
        self.upload.finished.connect(self._onFinished)



        self.rejected.connect(self._onCanceled)

        QTimer.singleShot(100, self.upload.start)

    def _createLayout(self):

        l = QVBoxLayout()

        l.addWidget(self.status_msg)
        l.addWidget(self.item_progress)
        l.addWidget(self.total_progress)
        l.addWidget(self.buttons)

        self.setLayout(l)



    def _onAuthNeeded(self):


        if self._first_auth and self.username is not None and self.password is not None:
            self._first_auth = False
            self.upload.authenticate(self.username, self.password)
            return

        d = AuthDialog(self)
        if d.exec_() == QDialog.Accepted:
            u, p = d.getValues()
            self.upload.authenticate(u, p)
        else:
            log.debug('Auth dialog rejected')
            self._onCanceled()

    def _onFinished(self):

        res = self.upload.results

        if len(res) != len(self.tracks):
            res.extend([{'status' : 'ERROR', 'msg' : 'Canceled'}] * (len(self.tracks) - len(res)))

        log.debug('Upload finished')

        d = ResultDialog(zip(self.tracks, res), self)

        d.exec_()
        self.accept()


    def _onCanceled(self):
        log.debug('Upload canceled')
        self.upload.cancel()

        self._onFinished()
class _CancellableProgressEditor(Editor):

    title = Unicode   # synced from factory.title_name 
    message = Unicode # synced from factory.message_name
    min = Int#Float   # synced from factory.min_name
    max = Int#Float   # synced from factory.max_name
    show_time = Bool  # synced from factory.show_time_name

    def _title_changed(self):
        if self._title is not None:
            self._title.setText('<B>%s</B>' % self.title)
            self._title.setVisible(len(self.title) > 0)
    
    def _message_changed(self):
        if self._message is not None:
            self._message.setText(self.message)
            self._message.setVisible(len(self.message) > 0)
        if self.factory.prefix_message:
            self.set_text()

    def _show_time_changed(self):
        if self._time_widget is not None:
            self._time_widget.setVisible(self.show_time)
    
    @on_trait_change('min, max')
    def change_range(self):
        if self._progress_bar is not None:
            self._progress_bar.setRange(self.min, self.max)
            self.update_editor()
    
    def init(self, parent):

        self.title = self.factory.title
        if len(self.factory.title_name) > 0:
            self.sync_value(self.factory.title_name, 'title')#, 'from')
        
        self.message = self.factory.message
        if len(self.factory.message_name) > 0:
            self.sync_value(self.factory.message_name, 'message')#, 'from')

        self.min = self.factory.min
        if len(self.factory.min_name) > 0:
            self.sync_value(self.factory.min_name, 'min')#, 'from')

        self.max = self.factory.max
        if len(self.factory.max_name) > 0:
            self.sync_value(self.factory.max_name, 'max')#, 'from')
        
        self.show_time = self.factory.show_time
        if len(self.factory.show_time_name) > 0:
            self.sync_value(self.factory.show_time_name, 'show_time')#, 'from')
        
        self.control = self._create_control(parent)

        self.can_cancel = self.factory.can_cancel
        if len(self.factory.can_cancel_name) > 0:
            self.sync_value(self.factory.can_cancel_name, 'can_cancel')#, 'from')
                
        self.set_tooltip()
        self.reset()

    can_cancel = Bool(False)
    from traits.api import Any
    buttons = Any
    @on_trait_change('can_cancel')
    def set_buttons_visible(self, value):
        self.buttons.setVisible(value)

    def _create_control(self, parent):
        layout = QVBoxLayout()
        
        if len(self.title) > 0:
            self._title = QLabel('<B>%s</B>' % self.title)
            layout.addWidget(self._title)
    
        if not self.factory.prefix_message and len(self.message) > 0:
            self._message = QLabel(self.message)
#            self._message = QTextEdit(self.message)
#            self._message.setReadOnly(True)
            layout.addWidget(self._message)
    
        self._progress_bar = QProgressBar()
        self._progress_bar.setRange(self.min, self.max)
        if not self.factory.can_cancel:
            layout.addWidget(self._progress_bar)
        else:
            self.buttons = QDialogButtonBox()
            self.buttons.addButton(u'Cancel', QDialogButtonBox.RejectRole)
            self.buttons.connect(self.buttons, SIGNAL('rejected()'), self.factory.cancelled)
            grid_layout = QGridLayout()
            grid_layout.addWidget(self._progress_bar, 0, 0)
            grid_layout.setColumnStretch(0, 1)
            grid_layout.addWidget(self.buttons, 0, 1)
            layout.addLayout(grid_layout)
                
        if self.factory.show_time:
            elapsed_label = QLabel('Elapsed time:')
            estimated_label = QLabel('Estimated time:')
            remaining_label = QLabel('Remaining time:')
            self._elapsed_control = QLabel('unknown')
            self._estimated_control = QLabel('unknown')
            self._remaining_control = QLabel('unknown')
            grid_layout = QGridLayout()
            grid_layout.addWidget(elapsed_label, 0, 0)
            grid_layout.addWidget(self._elapsed_control, 0, 1)
            grid_layout.addWidget(estimated_label, 1, 0)
            grid_layout.addWidget(self._estimated_control, 1, 1)
            grid_layout.addWidget(remaining_label, 2, 0)
            grid_layout.addWidget(self._remaining_control, 2, 1)
            grid_layout.setColumnStretch(1, 1)
            self._time_widget = QWidget()
            self._time_widget.setLayout(grid_layout)
            layout.addWidget(self._time_widget)
        
        if self.factory.show_text:
            self.set_text()
        else:
            self._progress_bar.setTextVisible(False)

        widget = QWidget()
        widget.setLayout(layout)
        return widget

    def set_text(self):
        if self._progress_bar is None:
            return
        if self.factory.prefix_message:
            format = self.message + ' '
        else:
            format = ''
        if self.factory.show_value:
            format += '%v'
        if self.factory.show_max:
            if self.factory.show_value:
                format += '/'
            format += '%m'
        if self.factory.show_value or self.factory.show_max:
            format += ' '
        if self.factory.show_percent:
            if self.factory.show_value or self.factory.show_max:
                format += '(%p%)'
            else:
                format += '%p%'
        self._progress_bar.setFormat(format)

    def _set_time_label(self, value, control):
        hours = value / 3600
        minutes = (value % 3600) / 60
        seconds = value % 60
        label = "%1u:%02u:%02u" % (hours, minutes, seconds)
        control.setText(control.text()[:-7] + label)

    def update_editor(self):
        if self.factory.min <= self.value <= self.factory.max:
            if self.value == self.factory.min:
                self.reset()
            self._progress_bar.setValue(self.value)

        if self.factory.show_time:
            if (self.factory.max != self.factory.min):
                percent = (float(self.value) - self.factory.min) / (self.factory.max - self.factory.min)
                # if float(<undefined>) raises an error here then probably the
                # name of the trait this is editing is mispelled or owned by
                # the handler, e.g. 'handler.progress' instead of 'progress'. 
            else:
                percent = 1.0
            if self.factory.show_time and (percent != 0):
                current_time = time.time()
                elapsed = current_time - self._start_time
                estimated = elapsed / percent
                remaining = estimated - elapsed
                self._set_time_label(elapsed, self._elapsed_control)
                self._set_time_label(estimated, self._estimated_control)
                self._set_time_label(remaining, self._remaining_control)            

    def reset(self):
        self._progress_bar.reset()
        self._start_time = time.time()
예제 #19
0
파일: FeedLol.py 프로젝트: bodil/feedlol
class FeedLol(QMainWindow):
    def __init__(self, parent = None):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("FeedLol")
        
        self.aboutAction = QAction(QIcon("data/icons/help-about.svg"), "&About FeedLol...", self)
        self.connect(self.aboutAction, SIGNAL("triggered()"), self.slotAbout)
        
        self.reloadAction = QAction(QIcon("data/icons/view-refresh.svg"), "&Reload", self)
        self.reloadAction.setShortcut(QKeySequence.Refresh)
        
        self.homeAction = QAction(QIcon("data/icons/go-home.svg"), "Go &Home", self)
        self.homeAction.setShortcut("Alt+Home")
        
        self.userAction = QAction(QIcon("data/icons/user-identity.svg"), "&Me", self)
        self.userAction.setShortcut("Ctrl+M")
        
        self.logoutAction = QAction(QIcon("data/icons/dialog-close.svg"), "Log&out", self)
        self.logoutAction.setShortcut(QKeySequence.Close)
        
        self.settingsAction = QAction(QIcon("data/icons/configure.svg"), "&Preferences...", self)
        self.connect(self.settingsAction, SIGNAL("triggered()"), self.slotSettings)

        self.toolbar = QToolBar("Toolbar", self)
        self.toolbar.setObjectName("toolbar")
        self.toolbar.addAction(self.homeAction)
        self.toolbar.addAction(self.userAction)
        self.toolbar.addAction(self.reloadAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.logoutAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.settingsAction)
        self.toolbar.addAction(self.aboutAction)
        self.addToolBar(self.toolbar)
        
        self.loadStatus = QProgressBar(self)
        self.loadStatus.setRange(0, 100)
        self.loadStatus.setMaximumWidth(200)
        self.loadStatus.setTextVisible(False)
        self.loadStatus.hide()
        self.statusBar().addPermanentWidget(self.loadStatus)

        self.feedView = FeedView(self)
        self.setCentralWidget(self.feedView)
        self.connect(self.feedView, SIGNAL("titleChanged(const QString&)"), self.slotSetTitle)
        self.connect(self.feedView, SIGNAL("statusBarMessage(const QString&)"), self.statusBar(), SLOT("showMessage(const QString&)"))
        self.connect(self.feedView, SIGNAL("loadStarted()"), self.loadStart)
        self.connect(self.feedView, SIGNAL("loadFinished(bool)"), self.loadStop)
        self.connect(self.feedView, SIGNAL("loadProgress(int)"), self.loadProgress)
        self.connect(self.reloadAction, SIGNAL("triggered()"), self.feedView.reload)
        self.connect(self.homeAction, SIGNAL("triggered()"), self.feedView.goHome)
        self.connect(self.userAction, SIGNAL("triggered()"), self.feedView.goToUserPage)
        self.connect(self.logoutAction, SIGNAL("triggered()"), self.feedView.logout)
        self.connect(self.feedView.page(), SIGNAL("linkHovered(const QString&, const QString&, const QString&)"), self.linkHovered)
        
        self.settingsDialog = SettingsDialog(self.feedView, self)

        settings = QSettings()
        
        if settings.contains("proxy/type"):
            proxy = QNetworkProxy()
            proxyType = settings.value("proxy/type").toInt()[0]
            proxy.setType( (proxyType == 2) and QNetworkProxy.Socks5Proxy or ( (proxyType == 1) and QNetworkProxy.HttpProxy or QNetworkProxy.NoProxy ) )
            if proxy.type() != QNetworkProxy.NoProxy:
                proxy.setHostName(settings.value("proxy/host").toString())
                proxy.setPort(settings.value("proxy/port").toInt()[0])
                if settings.value("proxy/user").toString():
                    proxy.setUser(settings.value("proxy/user").toString())
                    proxy.setPassword(settings.value("proxy/password").toString())
            QNetworkProxy.setApplicationProxy(proxy)

        if settings.contains("mainWindow/geometry"):
            self.restoreGeometry(settings.value("mainWindow/geometry").toByteArray())
        else:
            self.resize(320,480)
        if settings.contains("mainWindow/state"):
            self.restoreState(settings.value("mainWindow/state").toByteArray())
        
        self.feedView.goHome()
        
    def saveConfig(self):
        settings = QSettings()
        settings.setValue("mainWindow/geometry", QVariant(self.saveGeometry()))
        settings.setValue("mainWindow/state", QVariant(self.saveState()))
        session = self.feedView.siteServer.session
        from cPickle import dumps
        session = dumps(session)
        settings.setValue("session", QVariant(session))
        proxy = QNetworkProxy.applicationProxy()
        proxyType = (proxy.type() == QNetworkProxy.Socks5Proxy) and 2 or ( (proxy.type() == QNetworkProxy.HttpProxy) and 1 or 0 )
        settings.setValue("proxy/type", QVariant(proxyType))
        settings.setValue("proxy/host", QVariant(proxy.hostName()))
        settings.setValue("proxy/port", QVariant(proxy.port()))
        settings.setValue("proxy/user", QVariant(proxy.user()))
        settings.setValue("proxy/password", QVariant(proxy.password()))

    def slotAbout(self):
        from PyQt4.QtGui import QMessageBox
        QMessageBox.about(self, "FeedLol", "<h2>FeedLol 0.1</h2><p>Copyright &copy; 2008 <a href=\"mailto:[email protected]\">Bodil Stokke</a></p>")
        
    def slotSettings(self):
        self.settingsDialog.updateSettings()
        if self.settingsDialog.exec_() == QDialog.Accepted:
            self.settingsDialog.applySettings()

    def slotSetTitle(self, title):
        self.setWindowTitle("FeedLol: " + title)
        
    def loadStart(self):
        self.loadStatus.show()
    
    def loadStop(self):
        self.loadStatus.hide()
        
    def loadProgress(self, progress):
        self.loadStatus.setValue(progress)
    
    def linkHovered(self, url, title, text):
        if url and QUrl(url).scheme() != "chrome":
            self.statusBar().showMessage(url)
        else:
            self.statusBar().clearMessage()
예제 #20
0
class LineCounterDialog( QDialog, object ):
    """ line counter dialog implementation """

    def __init__( self, fName = None, editor = None, parent = None ):

        QDialog.__init__( self, parent )

        self.__cancelRequest = False
        self.__inProgress = False
        if fName is not None:
            self.__fName = fName.strip()
        else:
            self.__fName = None
        self.__editor = editor
        self.__createLayout()
        self.setWindowTitle( "Line counter" )
        QTimer.singleShot( 0, self.__process )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 220 )
        self.setSizeGripEnabled( True )

        self.verticalLayout = QVBoxLayout( self )

        # Info label
        self.infoLabel = FitPathLabel( self )
        #sizePolicy = QSizePolicy( QSizePolicy.Expanding,
        #                          QSizePolicy.Preferred )
        sizePolicy = QSizePolicy( QSizePolicy.Minimum,
                                  QSizePolicy.Preferred )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth(
                    self.infoLabel.sizePolicy().hasHeightForWidth() )
        self.infoLabel.setSizePolicy( sizePolicy )
        self.verticalLayout.addWidget( self.infoLabel )

        # Progress bar
        self.progressBar = QProgressBar( self )
        self.progressBar.setValue( 0 )
        self.progressBar.setOrientation( Qt.Horizontal )
        self.verticalLayout.addWidget( self.progressBar )

        # Result window
        self.resultEdit = QTextEdit( self )
        self.resultEdit.setTabChangesFocus( False )
        self.resultEdit.setAcceptRichText( False )
        self.resultEdit.setReadOnly( True )
        self.resultEdit.setFontFamily( GlobalData().skin.baseMonoFontFace )
        font = self.resultEdit.font()

        # Calculate the vertical size
        fontMetrics = QFontMetrics( font )
        rect = fontMetrics.boundingRect( "W" )
        # 6 lines, 5 line spacings, 2 frames
        self.resultEdit.setMinimumHeight( rect.height() * 7 + 4 * 5 +
                                          self.resultEdit.frameWidth() * 2 )
        self.verticalLayout.addWidget( self.resultEdit )

        # Buttons
        self.buttonBox = QDialogButtonBox( self )
        self.buttonBox.setOrientation( Qt.Horizontal )
        self.buttonBox.setStandardButtons( QDialogButtonBox.Close )
        self.verticalLayout.addWidget( self.buttonBox )

        self.buttonBox.rejected.connect( self.__onClose )
        return

    def __scanDir( self, path, files ):
        " Recursively builds a list of python files "

        if path in self.__scannedDirs:
            return

        self.__scannedDirs.append( path )
        for item in os.listdir( path ):
            if os.path.isdir( path + item ):
                nestedDir = os.path.realpath( path + item )
                if not nestedDir.endswith( os.path.sep ):
                    nestedDir += os.path.sep
                self.__scanDir( nestedDir, files )
            else:
                candidate = os.path.realpath( path + item )
                if candidate.endswith( ".py" ) or \
                   candidate.endswith( ".py3" ) or \
                   candidate.endswith( ".pyw" ):
                    if not candidate in files:
                        files.append( candidate )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process( self ):
        " Accumulation process "

        self.__inProgress = True
        if self.__fName is not None:
            if os.path.exists( self.__fName ):
                if os.path.isdir( self.__fName ):
                    self.__fName = os.path.realpath( self.__fName )
                    if not self.__fName.endswith( os.path.sep ):
                        self.__fName += os.path.sep
                    files = []
                    self.__scannedDirs = []
                    QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )
                    self.__scanDir( self.__fName, files )
                    QApplication.restoreOverrideCursor()
                else:
                    files = [ self.__fName ]
            else:
                files = []
        elif self.__editor is not None:
            files = [ "buffer" ]
        else:
            files = GlobalData().project.filesList
        self.progressBar.setRange( 0, len( files ) )

        accumulator = LinesCounter()
        current = LinesCounter()

        index = 1
        for fileName in files:

            if self.__cancelRequest:
                self.__inProgress = False
                self.close()
                return

            self.infoLabel.setPath( 'Processing: ' + fileName )

            processed = False
            if self.__editor is not None:
                current.getLinesInBuffer( self.__editor )
                processed = True
            else:
                if (fileName.endswith( '.py' ) or \
                    fileName.endswith( '.py3' ) or \
                    fileName.endswith( '.pyw' )) and \
                   os.path.exists( fileName ):
                    current.getLines( fileName )
                    processed = True

            if processed:
                accumulator.files += current.files
                accumulator.filesSize += current.filesSize
                accumulator.codeLines += current.codeLines
                accumulator.emptyLines += current.emptyLines
                accumulator.commentLines += current.commentLines
                accumulator.classes += current.classes

            self.progressBar.setValue( index )
            index += 1

            QApplication.processEvents()

        self.infoLabel.setPath( 'Done' )
        self.__inProgress = False

        # Update text in the text window
        nFiles = splitThousands( str( accumulator.files ) )
        filesSize = splitThousands( str( accumulator.filesSize ) )
        classes = splitThousands( str( accumulator.classes ) )
        codeLines = splitThousands( str( accumulator.codeLines ) )
        emptyLines = splitThousands( str( accumulator.emptyLines ) )
        commentLines = splitThousands( str( accumulator.commentLines ) )
        totalLines = splitThousands( str( accumulator.codeLines +
                                          accumulator.emptyLines +
                                          accumulator.commentLines ) )

        output = "Classes:                 " + classes + "\n" \
                 "Code lines:              " + codeLines + "\n" \
                 "Empty lines:             " + emptyLines + "\n" \
                 "Comment lines:           " + commentLines + "\n" \
                 "Total lines:             " + totalLines

        if self.__editor is None:
            output = "Number of python files:  " + nFiles + "\n" \
                     "Total files size:        " + filesSize + " bytes\n" + \
                     output
        else:
            output = "Number of characters:    " + filesSize + "\n" + \
                     output

        self.resultEdit.setText( output )
        return
예제 #21
0
class MainWindow(QMainWindow):
        def __init__(self):
                QMainWindow.__init__(self)
                
                self.ui = Ui_MainWindow()
                self.ui.setupUi(self)

                self.setCentralWidget(self.ui.mangaTableView)
                self.newMangaDialog = NewMangaDialog()
                self.mangaDownloadDialog = MangaDownloadDialog()

                self.mangaTableModel = QStandardItemModel(0, 3, self)
                self.mangaTableModel.setHorizontalHeaderItem(0, QStandardItem(QString("Manga")))
                self.mangaTableModel.setHorizontalHeaderItem(1, QStandardItem(QString("Latest Chapter")))
                self.mangaTableModel.setHorizontalHeaderItem(2, QStandardItem(QString("Status")))
                self.ui.mangaTableView.setModel(self.mangaTableModel)

                newMangaAction = QAction(QIcon("./icon/add.ico"),'New Manga', self)
                newMangaAction.setShortcut('Ctrl+N')
                newMangaAction.triggered.connect(self.newMangaDialog.show)

                removeMangaAction = QAction(QIcon("./icon/delete.ico"),'Remove Manga', self)
                removeMangaAction.setShortcut('Delete')

                preferencesAction = QAction(QIcon("./icon/preferences.ico"),'Preferences', self)                

                aboutAction = QAction(QIcon("./icon/about.ico"),'About', self)

                self.ui.toolBar.addAction(newMangaAction)
                self.ui.toolBar.addAction(removeMangaAction)
                self.ui.toolBar.addSeparator()
                self.ui.toolBar.addAction(preferencesAction)
                self.ui.toolBar.addSeparator()
                self.ui.toolBar.addAction(aboutAction)

                self.progressBar = QProgressBar(self.ui.statusbar)
                self.ui.statusbar.addPermanentWidget(self.progressBar)
                self.progressBar.hide()

        def closeEvent(self, QCloseEvent):
                mangaList = []
                for i in range(self.mangaTableModel.rowCount()):
                        mangaList.append({
                                                "name" : str(self.mangaTableModel.item(i, 0).text()),
                                                "latestChapter" : str(self.mangaTableModel.item(i, 1).text()),
                                                "status" : "Updated",
                                                "link" : "/trial.html"
                                        })
                self.emit(SIGNAL("applicationClosed"),mangaList)

        def initializeProgressBar(self, size):
                self.progressBar.setRange(0, size)
                self.progressBar.setValue(0)
                self.progressBar.show()

        def updateProgressBar(self, value):
                self.progressBar.setValue(value)

        def updateStatusBar(self, msg):
                self.ui.statusbar.showMessage(msg)

        def updateMangaTable(self, chapter):
                isFound = False
                for i in range(self.mangaTableModel.rowCount()):
                        mangaItem = self.mangaTableModel.item(i)
                        if mangaItem.text() == chapter["name"]:
                                self.mangaTableModel.item(i, 1).setText(chapter["latestChapter"])
                                self.mangaTableModel.item(i, 2).setText(chapter["status"])
                                isFound = True
                                break

                if not isFound:
                        self.addRowToMangaTable(chapter)

        def addMangaListToMangaTable(self, mangaList):
                for i in range(len(mangaList)):
                        self.addRowToMangaTable(mangaList[i])

        def addRowToMangaTable(self, manga):
                i = self.mangaTableModel.rowCount()

                mangaItem = QStandardItem(QString(manga["name"]))
                latestChapterItem = QStandardItem(QString(manga["latestChapter"]))
                statusItem = QStandardItem(QString(manga["status"]))

                brush = QBrush(QColor(255, 255, 255)) if i%2==0 else QBrush(QColor(200, 200, 200))

                mangaItem.setBackground(brush)
                latestChapterItem.setBackground(brush)
                statusItem.setBackground(brush)

                self.mangaTableModel.setItem(i, 0, mangaItem)
                self.mangaTableModel.setItem(i, 1, latestChapterItem)
                self.mangaTableModel.setItem(i, 2, statusItem)
예제 #22
0
class ExcelWorkbookView(QWidget):
    """A read-only table view for browsing MS Excel data."""
    def __init__(self, *args, **kwargs):
        super(QWidget, self).__init__(*args, **kwargs)
        self._init_ui()

        # Optional args
        self._dt_format = kwargs.pop('date_format', '%Y-%m-%d')

        # Map for sheet widgets
        self._ws_info = {}

        # Reset the view
        self.reset_view()

        # Check availability of XLRD library
        if not XLRD_AVAIL:
            QMessageBox.critical(
                self, self.tr('Missing Dependency'),
                self.
                tr('\'xlrd\' library is missing.\nExcel data cannot be loaded '
                   'without this library. Please install it and try again.'))
            self.setEnabled(False)

            return

    @property
    def date_format(self):
        """
        :return: Returns the format used to render the date/time in the
        view. The default formatting will return the date in ISO 8601 format
        i.e. 'YYYY-MM-DD' where the format is '%Y-%m-%d'.
        :rtype: str
        """
        return self._dt_format

    @date_format.setter
    def date_format(self, format):
        """
        Sets the format used to render the date/time in the view. The format
        needs to be in a format that is understood by Python's 'strftime()'
        function.
        :param format: Format for rendering date/time
        :type format: str
        """
        self._dt_format = format

    def worksheet_info(self, idx):
        """
        :param idx:
        :return: Returns a WorksheetInfo object containing references to the
        ExcelWorksheetView, xlrd.sheet.Sheet and name of the sheet, will
        return None if the index does not exist.
        :rtype: WorksheetInfo
        """
        return self._ws_info.get(idx, None)

    def current_worksheet_info(self):
        """
        :return: Returns the WorksheetInfo object for the current displayed
        tab. None if the view is empty.
        :rtype:WorksheetInfo
        """
        curr_idx = self._tbw.currentIndex()
        return self.worksheet_info(curr_idx)

    @property
    def progress_bar(self):
        """
        :return: Returns the progress bar for showing progress when Excel
        data is being added to the table.
        :rtype: QProgressBar
        """
        return self._pg_par

    def sizeHint(self):
        return QSize(480, 360)

    def clear_view(self):
        # Removes and deletes all sheet widgets and resets the widget registry index.
        self._tbw.clear()
        self._ws_info.clear()

    def reset_view(self):
        # Clears the view and add an empty default sheet.
        self.clear_view()
        self._add_default_sheet()

    def _add_default_sheet(self):
        # Add a default/empty sheet to the view.
        def_sheet = ExcelSheetView()
        self._tbw.addTab(def_sheet, self.tr('Sheet 1'))

    def _init_ui(self):
        # Set up layout and widgets
        self._vl = QVBoxLayout()
        self._tbw = QTabWidget()
        self._tbw.setTabShape(QTabWidget.Triangular)
        self._tbw.setTabPosition(QTabWidget.South)
        self._tbw.setStyleSheet('QTabBar::tab:selected { color: green; }')
        self._vl.addWidget(self._tbw)
        self._pg_par = QProgressBar()
        self._pg_par.setVisible(False)
        self._vl.addWidget(self._pg_par)
        self.setLayout(self._vl)

    def add_xlrd_sheet(self, xsheet):
        """
        Adds data contained in a sheet object to the view.
        :param xsheet: Object containing worksheet data.
        :type xsheet: xlrd.sheet.Sheet
        """
        worksheet = ExcelSheetView()
        worksheet.date_format = self._dt_format
        name = xsheet.name
        idx = self._tbw.addTab(worksheet, name)
        self._tbw.setTabToolTip(idx, name)

        worksheet.load_worksheet(xsheet)

        # Add worksheet info to collection
        wsi = WorksheetInfo()
        wsi.name = name
        wsi.idx = idx
        wsi.ws_widget = worksheet
        wsi.ws = xsheet

        self._ws_info[wsi.idx] = wsi

    def load_workbook(self, path):
        """
        Loads the workbook contained in the specified file to the view.
        :param path: Path to fil containing workbook data.
        :type path: str
        """
        xfile = QFile(path)
        if not xfile.exists():
            QMessageBox.critical(
                self, self.tr('Invalid path'),
                u'\'{0}\' {1}'.format(path, self.tr('does not exist.')))

            return

        # Check permissions
        xfileinfo = QFileInfo(xfile)
        if not xfileinfo.isReadable():
            QMessageBox.critical(
                self, self.tr('Unreadable file'),
                u'{0} {1}'.format(path, self.tr('is not readable.')))

            return

        # Clear view
        self.clear_view()

        # Show progress bar
        self._pg_par.setVisible(True)
        pg_val = 0

        # Add sheets
        wb = open_workbook(path)
        self._pg_par.setRange(0, wb.nsheets)
        for s in wb.sheets():
            self.add_xlrd_sheet(s)

            # Update progress bar
            pg_val += 1
            self._pg_par.setValue(pg_val)

        self._pg_par.setVisible(False)
예제 #23
0
    def updateVersion(self):
        """Prüft die Version der Datenbank. 

            :returns: Anpassung erfolgreich: True = alles o.k.
            :rtype: logical
            
            Voraussetzungen: 
             - Die aktuelle Datenbank ist bereits geöffnet. 

            Die aktuelle Versionsnummer steht in der Datenbank: info.version
            Diese wird mit dem Attribut self.actversion verglichen. Bei Differenz werden 
            die nötigen Anpassungen vorgenommen und die Versionsnummer jeweils aktualisiert.
            Falls Tabellenspalten umbenannt oder gelöscht wurden, wird eine Warnmeldung erzeugt
            mit der Empfehlung, das aktuelle Projekt neu zu laden. 
        """

        logger.debug('0 - actversion = {}'.format(self.actversion))

        # ---------------------------------------------------------------------------------------------
        # Aktuelle Version abfragen

        sql = u"""SELECT value
                FROM info
                WHERE subject = 'version'"""

        if not self.sql(sql, u'dbfunc.version (1)'):
            return False

        data = self.cursl.fetchone()
        if data is not None:
            versiondbQK = data[0]
            logger.debug(
                'dbfunc.version: Aktuelle Version der qkan-Datenbank ist {}'.
                format(versiondbQK))
        else:
            logger.debug(
                'dbfunc.version: Keine Versionsnummer vorhanden. data = {}'.
                format(repr(data)))
            sql = u"""INSERT INTO info (subject, value) Values ('version', '1.9.9')"""
            if not self.sql(sql, u'dbfunc.version (2)'):
                return False

            versiondbQK = u'1.9.9'

        logger.debug('0 - versiondbQK = {}'.format(versiondbQK))

        self.versionlis = [
            int(el.replace('a', '').replace('b', '').replace('c', ''))
            for el in versiondbQK.split('.')
        ]

        # ---------------------------------------------------------------------------------------------
        # Aktualisierung von Version 1.9.9 und früher

        if versionolder(self.versionlis, [2, 0, 2]):

            # Tabelle einleit
            sqllis = [
                u"""CREATE TABLE IF NOT EXISTS einleit(
                pk INTEGER PRIMARY KEY AUTOINCREMENT,
                elnam TEXT,
                haltnam TEXT,
                teilgebiet TEXT, 
                zufluss REAL,
                kommentar TEXT,
                createdat TEXT DEFAULT CURRENT_DATE)""",
                u"""SELECT AddGeometryColumn('einleit','geom',{},'POINT',2)""".
                format(self.epsg),
                u"""SELECT CreateSpatialIndex('einleit','geom')"""
            ]
            for sql in sqllis:
                if not self.sql(sql, u'dbfunc.version (3c)'):
                    return False

            sqllis = [
                u"""CREATE TABLE IF NOT EXISTS linksw (
                    pk INTEGER PRIMARY KEY AUTOINCREMENT,
                    elnam TEXT,
                    haltnam TEXT,
                    teilgebiet TEXT)""",
                u"""SELECT AddGeometryColumn('linksw','geom',{},'POLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw','gbuf',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw','glink',{},'LINESTRING',2)"""
                .format(self.epsg),
                u"""SELECT CreateSpatialIndex('linksw','geom')"""
            ]
            for sql in sqllis:
                if not self.sql(sql, u'dbfunc.version (3d)'):
                    return False

            self.versionlis = [2, 0, 2]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 1, 2]):

            attrlis = self.attrlist(u'linksw')
            if not attrlis:
                fehlermeldung(u'dbfunc.version (2.0.2):',
                              u'attrlis für linksw ist leer')
                return False
            elif u'elnam' not in attrlis:
                logger.debug(u'linksw.elnam ist nicht in: {}'.format(
                    str(attrlis)))
                sql = u"""ALTER TABLE linksw ADD COLUMN elnam TEXT"""
                if not self.sql(sql, u'dbfunc.version (2.0.2-1)'):
                    return False
                self.commit()

            attrlis = self.attrlist(u'linkfl')
            if not attrlis:
                fehlermeldung(u'dbfunc.version (2.0.2):',
                              u'attrlis für linkfl ist leer')
                return False
            elif u'tezgnam' not in attrlis:
                logger.debug(u'linkfl.tezgnam ist nicht in: {}'.format(
                    str(attrlis)))
                sql = u"""ALTER TABLE linkfl ADD COLUMN tezgnam TEXT"""
                if not self.sql(sql, u'dbfunc.version (2.0.2-3)'):
                    return False
                self.commit()

            self.versionlis = [2, 1, 2]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 2, 0]):
            attrlis = self.attrlist(u'einleit')
            if not attrlis:
                return False
            elif u'ew' not in attrlis:
                logger.debug(u'einleit.ew ist nicht in: {}'.format(
                    str(attrlis)))
                sql = u"""ALTER TABLE einleit ADD COLUMN ew REAL"""
                if not self.sql(sql, u'dbfunc.version (2.1.2-1)'):
                    return False
                sql = u"""ALTER TABLE einleit ADD COLUMN einzugsgebiet TEXT"""
                if not self.sql(sql, u'dbfunc.version (2.1.2-2)'):
                    return False
                self.commit()

            sql = u"""CREATE TABLE IF NOT EXISTS einzugsgebiete (
                pk INTEGER PRIMARY KEY AUTOINCREMENT,
                tgnam TEXT,
                ewdichte REAL,
                wverbrauch REAL,
                stdmittel REAL,
                fremdwas REAL,
                kommentar TEXT,
                createdat TEXT DEFAULT CURRENT_DATE)"""

            if not self.sql(sql, u'dbfunc.version (2.1.2-3)'):
                return False

            sql = u"""SELECT AddGeometryColumn('einzugsgebiete','geom',{},'MULTIPOLYGON',2)""".format(
                self.epsg)
            if not self.sql(sql, u'dbfunc.version (2.1.2-4)'):
                return False

            sql = u"""SELECT CreateSpatialIndex('einzugsgebiete','geom')"""
            if not self.sql(sql, u'dbfunc.version (2.1.2-5)'):
                return False

            self.versionlis = [2, 2, 0]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 2, 1]):

            attrlis = self.attrlist(u'flaechen')
            if not attrlis:
                return False
            elif u'abflusstyp' not in attrlis:
                logger.debug(u'flaechen.abflusstyp ist nicht in: {}'.format(
                    str(attrlis)))
                sql = u"""ALTER TABLE flaechen ADD COLUMN abflusstyp TEXT"""
                if not self.sql(sql, u'dbfunc.version (2.2.0-1)'):
                    return False
                self.commit()

            self.versionlis = [2, 2, 1]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 2, 2]):

            attrlis = self.attrlist(u'flaechen')
            if not attrlis:
                return False
            elif u'abflusstyp' not in attrlis:
                logger.debug(u'flaechen.abflusstyp ist nicht in: {}'.format(
                    str(attrlis)))
                sql = u"""ALTER TABLE flaechen ADD COLUMN abflusstyp TEXT"""
                if not self.sql(sql, u'dbfunc.version (2.2.1-1)'):
                    return False
                self.commit()

            self.versionlis = [2, 2, 2]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 2, 3]):

            global progress_bar
            progress_bar = QProgressBar(iface.messageBar())
            progress_bar.setRange(0, 100)
            status_message = iface.messageBar().createMessage(
                u"",
                u"Die Datenbank wird an Version 2.2.3 angepasst. Bitte warten..."
            )
            status_message.layout().addWidget(progress_bar)
            iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO,
                                          10)

            progress_bar.setValue(80)

            # Tabelle flaechen -------------------------------------------------------------

            # 1. Schritt: Trigger für zu ändernde Tabelle abfragen und in triggers speichern
            # sql = u"""SELECT type, sql FROM sqlite_master WHERE tbl_name='flaechen'"""
            # if not self.sql(sql, u'dbfunc.version.pragma (1)'):
            # return False
            # triggers = self.fetchall()

            # 2. Schritt: Tabelle umbenennen, neu anlegen und Daten rüberkopieren
            sqllis = [
                u"""BEGIN TRANSACTION;""", u"""CREATE TABLE flaechen_t (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        flnam TEXT,
                        haltnam TEXT,
                        neigkl INTEGER DEFAULT 0,
                        abflusstyp TEXT, 
                        he_typ INTEGER DEFAULT 0,
                        speicherzahl INTEGER DEFAULT 2,
                        speicherkonst REAL,
                        fliesszeit REAL,
                        fliesszeitkanal REAL,
                        teilgebiet TEXT,
                        regenschreiber TEXT,
                        abflussparameter TEXT,
                        aufteilen TEXT DEFAULT 'nein',
                        kommentar TEXT,
                        createdat TEXT DEFAULT CURRENT_DATE);""",
                u"""SELECT AddGeometryColumn('flaechen_t','geom',{},'MULTIPOLYGON',2);"""
                .format(self.epsg), u"""INSERT INTO flaechen_t 
                        (      "flnam", "haltnam", "neigkl", "he_typ", "speicherzahl", "speicherkonst", "fliesszeit", "fliesszeitkanal",
                               "teilgebiet", "regenschreiber", "abflussparameter", "aufteilen", "kommentar", "createdat", "geom")
                        SELECT "flnam", "haltnam", "neigkl", "he_typ", "speicherzahl", "speicherkonst", "fliesszeit", "fliesszeitkanal",
                               "teilgebiet", "regenschreiber", "abflussparameter", "aufteilen", "kommentar", "createdat", "geom"
                        FROM "flaechen";""",
                u"""SELECT DiscardGeometryColumn('flaechen','geom')""",
                u"""DROP TABLE flaechen;""", u"""CREATE TABLE flaechen (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        flnam TEXT,
                        haltnam TEXT,
                        neigkl INTEGER DEFAULT 0,
                        abflusstyp TEXT, 
                        he_typ INTEGER DEFAULT 0,
                        speicherzahl INTEGER DEFAULT 2,
                        speicherkonst REAL,
                        fliesszeit REAL,
                        fliesszeitkanal REAL,
                        teilgebiet TEXT,
                        regenschreiber TEXT,
                        abflussparameter TEXT,
                        aufteilen TEXT DEFAULT 'nein',
                        kommentar TEXT,
                        createdat TEXT DEFAULT CURRENT_DATE);""",
                u"""SELECT AddGeometryColumn('flaechen','geom',{},'MULTIPOLYGON',2);"""
                .format(self.epsg),
                u"""SELECT CreateSpatialIndex('flaechen','geom')""",
                u"""INSERT INTO flaechen 
                        (      "flnam", "haltnam", "neigkl", "he_typ", "speicherzahl", "speicherkonst", "fliesszeit", "fliesszeitkanal",
                               "teilgebiet", "regenschreiber", "abflussparameter", "aufteilen", "kommentar", "createdat", "geom")
                        SELECT "flnam", "haltnam", "neigkl", "he_typ", "speicherzahl", "speicherkonst", "fliesszeit", "fliesszeitkanal",
                               "teilgebiet", "regenschreiber", "abflussparameter", "aufteilen", "kommentar", "createdat", "geom"
                        FROM "flaechen_t";""",
                u"""SELECT DiscardGeometryColumn('flaechen_t','geom')""",
                u"""DROP TABLE flaechen_t;"""
            ]

            for sql in sqllis:
                if not self.sql(
                        sql, u'dbfunc.version (2.2.2-1)', transaction=True):
                    return False

            # 3. Schritt: Trigger wieder herstellen
            # for el in triggers:
            # if el[0] != 'table':
            # sql = el[1]
            # logger.debug(u"Trigger 'flaechen' verarbeitet:\n{}".format(el[1]))
            # if not self.sql(sql, u'dbfunc.version (2.2.2-2)', transaction=True):
            # return False
            # else:
            # logger.debug(u"1. Trigger 'table' erkannt:\n{}".format(el[1]))

            # 4. Schritt: Transaction abschließen
            self.commit()

            # 5. Schritt: Spalte abflusstyp aus Spalte he_typ übertragen
            sql = u"""UPDATE flaechen SET abflusstyp = 
                    CASE he_typ 
                        WHEN 0 THEN 'Direktabfluss' 
                        WHEN 1 THEN 'Fließzeiten' 
                        WHEN 2 THEN 'Schwerpunktfließzeit'
                        ELSE NULL END
                    WHERE abflusstyp IS NULL"""

            if not self.sql(sql, u'dbfunc.version (2.2.2-3)'):
                return False

            progress_bar.setValue(20)

            # Tabelle linksw -------------------------------------------------------------

            # 1. Schritt: Trigger für zu ändernde Tabelle abfragen und in triggers speichern
            # sql = u"""SELECT type, sql FROM sqlite_master WHERE tbl_name='linksw'"""
            # if not self.sql(sql, u'dbfunc.version.pragma (3)'):
            # return False
            # triggers = self.fetchall()

            # 2. Schritt: Tabelle umbenennen, neu anlegen und Daten rüberkopieren
            sqllis = [
                u"""BEGIN TRANSACTION;""", u"""CREATE TABLE linksw_t (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        elnam TEXT,
                        haltnam TEXT,
                        teilgebiet TEXT)""",
                u"""SELECT AddGeometryColumn('linksw_t','geom',{},'POLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw_t','gbuf',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw_t','glink',{},'LINESTRING',2)"""
                .format(self.epsg), u"""INSERT INTO linksw_t 
                        (      "elnam", "haltnam", "teilgebiet", "geom", "gbuf", "glink")
                        SELECT "elnam", "haltnam", "teilgebiet", "geom", "gbuf", "glink"
                        FROM "linksw";""",
                u"""SELECT DiscardGeometryColumn('linksw','geom')""",
                u"""SELECT DiscardGeometryColumn('linksw','gbuf')""",
                u"""SELECT DiscardGeometryColumn('linksw','glink')""",
                u"""DROP TABLE linksw;""", u"""CREATE TABLE linksw (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        elnam TEXT,
                        haltnam TEXT,
                        teilgebiet TEXT)""",
                u"""SELECT AddGeometryColumn('linksw','geom',{},'POLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw','gbuf',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linksw','glink',{},'LINESTRING',2)"""
                .format(self.epsg),
                u"""SELECT CreateSpatialIndex('linksw','geom')""",
                u"""INSERT INTO linksw 
                        (      "elnam", "haltnam", "teilgebiet", "geom", "gbuf", "glink")
                        SELECT "elnam", "haltnam", "teilgebiet", "geom", "gbuf", "glink"
                        FROM "linksw_t";""",
                u"""SELECT DiscardGeometryColumn('linksw_t','geom')""",
                u"""SELECT DiscardGeometryColumn('linksw_t','gbuf')""",
                u"""SELECT DiscardGeometryColumn('linksw_t','glink')""",
                u"""DROP TABLE linksw_t;"""
            ]

            for sql in sqllis:
                if not self.sql(
                        sql, u'dbfunc.version (2.2.2-4)', transaction=True):
                    return False

            # 3. Schritt: Trigger wieder herstellen
            # for el in triggers:
            # if el[0] != 'table':
            # sql = el[1]
            # logger.debug(u"Trigger 'linksw' verarbeitet:\n{}".format(el[1]))
            # if not self.sql(sql, u'dbfunc.version (2.2.2-5)', transaction=True):
            # return False
            # else:
            # logger.debug(u"1. Trigger 'table' erkannt:\n{}".format(el[1]))

            # 4. Schritt: Transaction abschließen
            self.commit()

            progress_bar.setValue(40)

            # Tabelle linkfl -------------------------------------------------------------

            # 1. Schritt: Trigger für zu ändernde Tabelle abfragen und in triggers speichern
            # sql = u"""SELECT type, sql FROM sqlite_master WHERE tbl_name='linkfl'"""
            # if not self.sql(sql, u'dbfunc.version.pragma (5)'):
            # return False
            # triggers = self.fetchall()

            # 2. Schritt: Temporäre Tabelle anlegen, Daten rüber kopieren,
            #             Tabelle löschen und wieder neu anlegen und Daten zurück kopieren

            sqllis = [
                u"""BEGIN TRANSACTION;""", u"""CREATE TABLE linkfl_t (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        flnam TEXT,
                        haltnam TEXT,
                        tezgnam TEXT,
                        aufteilen TEXT,
                        teilgebiet TEXT);""",
                u"""SELECT AddGeometryColumn('linkfl_t','geom',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linkfl_t','gbuf',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linkfl_t','glink',{},'LINESTRING',2)"""
                .format(self.epsg), u"""INSERT INTO linkfl_t 
                        (      "flnam", "haltnam", "tezgnam", "aufteilen", "teilgebiet", "geom", "gbuf", "glink")
                        SELECT "flnam", "haltnam", "tezgnam", "aufteilen", "teilgebiet", "geom", "gbuf", "glink"
                        FROM "linkfl";""",
                u"""SELECT DiscardGeometryColumn('linkfl','geom')""",
                u"""SELECT DiscardGeometryColumn('linkfl','gbuf')""",
                u"""SELECT DiscardGeometryColumn('linkfl','glink')""",
                u"""DROP TABLE linkfl;""", u"""CREATE TABLE linkfl (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        flnam TEXT,
                        haltnam TEXT,
                        tezgnam TEXT,
                        aufteilen TEXT,
                        teilgebiet TEXT);""",
                u"""SELECT AddGeometryColumn('linkfl','geom',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linkfl','gbuf',{},'MULTIPOLYGON',2)"""
                .format(self.epsg),
                u"""SELECT AddGeometryColumn('linkfl','glink',{},'LINESTRING',2)"""
                .format(self.epsg),
                u"""SELECT CreateSpatialIndex('linkfl','glink')""",
                u"""INSERT INTO linkfl 
                        (      "flnam", "haltnam", "tezgnam", "aufteilen", "teilgebiet", "geom", "gbuf", "glink")
                        SELECT "flnam", "haltnam", "tezgnam", "aufteilen", "teilgebiet", "geom", "gbuf", "glink"
                        FROM "linkfl_t";""",
                u"""SELECT DiscardGeometryColumn('linkfl_t','geom')""",
                u"""SELECT DiscardGeometryColumn('linkfl_t','gbuf')""",
                u"""SELECT DiscardGeometryColumn('linkfl_t','glink')""",
                u"""DROP TABLE linkfl_t;"""
            ]

            for sql in sqllis:
                if not self.sql(
                        sql, u'dbfunc.version (2.2.2-6)', transaction=True):
                    return False

            # 3. Schritt: Trigger wieder herstellen
            # for el in triggers:
            # if el[0] != 'table':
            # sql = el[1]
            # logger.debug(u"Trigger 'linkfl' verarbeitet:\n{}".format(el[1]))
            # if not self.sql(sql, u'dbfunc.version (2.2.2-7)', transaction=True):
            # return False
            # else:
            # logger.debug(u"1. Trigger 'table' erkannt:\n{}".format(el[1]))

            # 4. Schritt: Transaction abschließen
            self.commit()

            progress_bar.setValue(60)

            # Tabelle einleit -------------------------------------------------------------

            # 1. Schritt: Trigger für zu ändernde Tabelle abfragen und in triggers speichern
            # sql = u"""SELECT type, sql FROM sqlite_master WHERE tbl_name='einleit'"""
            # if not self.sql(sql, u'dbfunc.version.pragma (7)'):
            # return False
            # triggers = self.fetchall()

            # 2. Schritt: Tabelle umbenennen, neu anlegen und Daten rüberkopieren
            sqllis = [
                u"""BEGIN TRANSACTION;""", u"""CREATE TABLE einleit_t (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        elnam TEXT,
                        haltnam TEXT,
                        teilgebiet TEXT, 
                        zufluss REAL,
                        ew REAL,
                        einzugsgebiet TEXT,
                        kommentar TEXT,
                        createdat TEXT DEFAULT CURRENT_DATE);""",
                u"""SELECT AddGeometryColumn('einleit_t','geom',{},'POINT',2)"""
                .format(self.epsg), u"""INSERT INTO einleit_t 
                        (      "elnam", "haltnam", "teilgebiet", "zufluss", "ew", "einzugsgebiet", "kommentar", "createdat", "geom")
                        SELECT "elnam", "haltnam", "teilgebiet", "zufluss", "ew", "einzugsgebiet", "kommentar", "createdat", "geom"
                        FROM "einleit";""",
                u"""SELECT DiscardGeometryColumn('einleit','geom')""",
                u"""DROP TABLE einleit;""", u"""CREATE TABLE einleit (
                        pk INTEGER PRIMARY KEY AUTOINCREMENT,
                        elnam TEXT,
                        haltnam TEXT,
                        teilgebiet TEXT, 
                        zufluss REAL,
                        ew REAL,
                        einzugsgebiet TEXT,
                        kommentar TEXT,
                        createdat TEXT DEFAULT CURRENT_DATE);""",
                u"""SELECT AddGeometryColumn('einleit','geom',{},'POINT',2)""".
                format(self.epsg),
                u"""SELECT CreateSpatialIndex('einleit','geom')""",
                u"""INSERT INTO einleit 
                        (      "elnam", "haltnam", "teilgebiet", "zufluss", "ew", "einzugsgebiet", "kommentar", "createdat", "geom")
                        SELECT "elnam", "haltnam", "teilgebiet", "zufluss", "ew", "einzugsgebiet", "kommentar", "createdat", "geom"
                        FROM "einleit_t";""",
                u"""SELECT DiscardGeometryColumn('einleit_t','geom')""",
                u"""DROP TABLE einleit_t;"""
            ]

            for sql in sqllis:
                if not self.sql(
                        sql, u'dbfunc.version (2.2.2-8)', transaction=True):
                    return False

            # 3. Schritt: Trigger wieder herstellen
            # for el in triggers:
            # if el[0] != 'table':
            # sql = el[1]
            # logger.debug(u"Trigger 'einleit' verarbeitet:\n{}".format(el[1]))
            # if not self.sql(sql, u'dbfunc.version (2.2.2-9)', transaction=True):
            # return False
            # else:
            # logger.debug(u"1. Trigger 'table' erkannt:\n{}".format(el[1]))

            # 4. Schritt: Transaction abschließen

            self.commit()

            progress_bar.setValue(100)
            status_message.setText(
                u"Achtung! Benutzerhinweis: Die Datenbank wurde geändert. Bitte QGIS-Projekt neu laden..."
            )
            status_message.setLevel(QgsMessageBar.WARNING)
            iface.messageBar().pushMessage(
                u"Achtung! Benutzerhinweis!",
                u"Die Datenbank wurde geändert. Bitte QGIS-Projekt neu laden...",
                level=QgsMessageBar.WARNING,
                duration=0)

            # Versionsnummer hochsetzen

            self.versionlis = [2, 2, 3]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 2, 16]):

            sql = u"""
                CREATE TABLE IF NOT EXISTS dynahal (
                    pk INTEGER PRIMARY KEY AUTOINCREMENT,
                    haltnam TEXT,
                    schoben TEXT,
                    schunten TEXT,
                    teilgebiet TEXT,
                    kanalnummer TEXT,
                    haltungsnummer TEXT,
                    anzobob INTEGER,
                    anzobun INTEGER,
                    anzunun INTEGER,
                    anzunob INTEGER)"""
            if not self.sql(sql, u'dbfunc.version (2.4.1-1)'):
                return False

            sql = u"""
                ALTER TABLE profile ADD COLUMN kp_key TEXT
            """
            if not self.sql(sql, u'dbfunc.version (2.4.1-3)'):
                return False

            sql = u"""
                ALTER TABLE entwaesserungsarten ADD COLUMN kp_nr INTEGER
            """
            if not self.sql(sql, u'dbfunc.version (2.4.1-2)'):
                return False

            sqllis = [
                u"""UPDATE entwaesserungsarten SET kp_nr = 0 WHERE bezeichnung = 'Mischwasser'""",
                u"""UPDATE entwaesserungsarten SET kp_nr = 1 WHERE bezeichnung = 'Schmutzwasser'""",
                u"""UPDATE entwaesserungsarten SET kp_nr = 2 WHERE bezeichnung = 'Regenwasser'"""
            ]

            for sql in sqllis:
                if not self.sql(sql, u'dbfunc.version (2.4.1-4)'):
                    return False

            self.commit()

            # Versionsnummer hochsetzen

            self.versionlis = [2, 2, 16]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 4, 9]):

            sql = u'''DROP VIEW IF EXISTS "v_linkfl_check"'''

            if not self.sql(sql, u'dbfunc.version (2.4.9-1)'):
                return False

            sql = u'''CREATE VIEW IF NOT EXISTS "v_linkfl_check" AS 
                    WITH lfok AS
                    (   SELECT 
                            lf.pk AS "pk",
                            lf.flnam AS "linkfl_nam", 
                            lf.haltnam AS "linkfl_haltnam", 
                            fl.flnam AS "flaech_nam",
                            tg.flnam AS "tezg_nam",
                            min(lf.pk) AS pkmin, 
                            max(lf.pk) AS pkmax,
                            count(*) AS anzahl
                        FROM linkfl AS lf
                        LEFT JOIN flaechen AS fl
                        ON lf.flnam = fl.flnam
                        LEFT JOIN tezg AS tg
                        ON lf.tezgnam = tg.flnam
                        WHERE fl.aufteilen = "ja" and fl.aufteilen IS NOT NULL
                        GROUP BY fl.flnam, tg.flnam
                        UNION
                        SELECT 
                            lf.pk AS "pk",
                            lf.flnam AS "linkfl_nam", 
                            lf.haltnam AS "linkfl_haltnam", 
                            fl.flnam AS "flaech_nam",
                            NULL AS "tezg_nam",
                            min(lf.pk) AS pkmin, 
                            max(lf.pk) AS pkmax,
                            count(*) AS anzahl
                        FROM linkfl AS lf
                        LEFT JOIN flaechen AS fl
                        ON lf.flnam = fl.flnam
                        WHERE fl.aufteilen <> "ja" OR fl.aufteilen IS NULL
                        GROUP BY fl.flnam)
                    SELECT pk, anzahl, CASE WHEN anzahl > 1 THEN 'mehrfach vorhanden' WHEN flaech_nam IS NULL THEN 'Keine Fläche' WHEN linkfl_haltnam IS NULL THEN  'Keine Haltung' ELSE 'o.k.' END AS fehler
                    FROM lfok'''

            if not self.sql(sql, u'dbfunc.version (2.4.9-2)'):
                return False

            sql = u'''DROP VIEW IF EXISTS "v_flaechen_ohne_linkfl"'''

            if not self.sql(sql, u'dbfunc.version (2.4.9-3)'):
                return False

            sql = u'''CREATE VIEW IF NOT EXISTS "v_flaechen_ohne_linkfl" AS 
                    SELECT 
                        fl.pk, 
                        fl.flnam AS "flaech_nam",
                        fl.aufteilen AS "flaech_aufteilen", 
                        'Verbindung fehlt' AS "Fehler"
                    FROM flaechen AS fl
                    LEFT JOIN linkfl AS lf
                    ON lf.flnam = fl.flnam
                    LEFT JOIN tezg AS tg
                    ON tg.flnam = lf.tezgnam
                    WHERE ( (fl.aufteilen <> "ja" or fl.aufteilen IS NULL) AND
                             lf.pk IS NULL) OR
                          (  fl.aufteilen = "ja" AND fl.aufteilen IS NOT NULL AND 
                             lf.pk IS NULL)
                    UNION
                    VALUES
                        (0, '', '', 'o.k.')'''

            if not self.sql(sql, u'dbfunc.version (2.4.9-4)'):
                return False

            self.commit()

            # Versionsnummer hochsetzen

            self.versionlis = [2, 4, 9]

        # ---------------------------------------------------------------------------------------------------------
        if versionolder(self.versionlis, [2, 5, 2]):

            # Einleitungen aus Aussengebieten ----------------------------------------------------------------

            sql = u'''CREATE TABLE aussengebiete (
                pk INTEGER PRIMARY KEY AUTOINCREMENT, 
                gebnam TEXT, 
                schnam TEXT, 
                hoeheob REAL, 
                hoeheun REAL, 
                fliessweg REAL, 
                basisabfluss REAL, 
                cn REAL, 
                regenschreiber TEXT, 
                teilgebiet TEXT, 
                kommentar TEXT, 
                createdat TEXT DEFAULT CURRENT_DATE)'''

            if not self.sql(sql, u'dbfunc.version (2.5.2-1)'):
                return False

            sql = u"""SELECT AddGeometryColumn('aussengebiete','geom',{},'MULTIPOLYGON',2)""".format(
                self.epsg)

            if not self.sql(sql, u'dbfunc.version (2.5.2-2)'):
                return False

            sql = u"""SELECT CreateSpatialIndex('aussengebiete','geom')"""

            if not self.sql(sql, u'dbfunc.version (2.5.2-3)'):
                return False

            # Anbindung Aussengebiete -------------------------------------------------------------------------

            sql = u"""CREATE TABLE linkageb (
                pk INTEGER PRIMARY KEY AUTOINCREMENT,
                gebnam TEXT,
                schnam TEXT,
                teilgebiet TEXT)"""

            if not self.sql(sql, u'dbfunc.version (2.5.2-4)'):
                return False

            sql = u"""SELECT AddGeometryColumn('linkageb','glink',{epsg},'LINESTRING',2)""".format(
                epsg=self.epsg)

            if not self.sql(sql, u'dbfunc.version (2.5.2-5)'):
                return False

            sql = u"""SELECT CreateSpatialIndex('linkageb','glink')"""

            if not self.sql(sql, u'dbfunc.version (2.5.2-6)'):
                return False

            self.commit()

            # Versionsnummer hochsetzen

            self.versionlis = [2, 5, 2]

            # Formulare aktualisieren ----------------------------------------------------------
            #
            # Dieser Block muss im letzten Update vorkommen, in dem auch Formulare geändert wurden...
            #
            # Spielregel: QKan-Formulare werden ohne Rückfrage aktualisiert.
            # Falls eigene Formulare gewünscht sind, können diese im selben Verzeichnis liegen,
            # die Eingabeformulare müssen jedoch andere Namen verwenden, auf die entsprechend
            # in der Projektdatei verwiesen werden muss.

            try:
                projectpath = os.path.dirname(self.dbname)
                if u'eingabemasken' not in os.listdir(projectpath):
                    os.mkdir(os.path.join(projectpath, u'eingabemasken'))
                formpath = os.path.join(projectpath, u'eingabemasken')
                formlist = os.listdir(formpath)

                logger.debug(
                    u"\nEingabeformulare aktualisieren: \n" +
                    "projectpath = {projectpath}\n".format(
                        projectpath=projectpath) +
                    "formpath = {formpath}\n".format(formpath=formpath) +
                    "formlist = {formlist}\n".format(formlist=formlist) +
                    "templatepath = {templatepath}".format(
                        templatepath=self.templatepath))

                for formfile in glob.iglob(
                        os.path.join(self.templatepath, u'*.ui')):
                    logger.debug(
                        u"Eingabeformular aktualisieren: {} -> {}".format(
                            formfile, formpath))
                    shutil.copy2(formfile, formpath)
            except BaseException as err:
                fehlermeldung(
                    u'Fehler beim Aktualisieren der Eingabeformulare\n',
                    u"{e}".format(e=repr(err)))

        # ------------------------------------------------------------------------------------------
        # Aktuelle Version in Tabelle "info" schreiben

        sql = u"""UPDATE info SET value = '{}' WHERE subject = 'version'""".format(
            self.actversion)
        if not self.sql(sql, u'dbfunc.version (aktuell)'):
            return False

        self.commit()
        return True
예제 #24
0
class OWDatabasesPack(OWWidget.OWWidget):
    settingsList = ["fileslist", "downloadurl", "downloadmessage"]

    def __init__(self, parent=None, signalManager=None, title="Databases Pack"):

        super(OWDatabasesPack, self).__init__(parent, signalManager, title, wantMainArea=False)

        self.fileslist = [("Taxonomy", "ncbi_taxonomy.tar.gz")]
        self.downloadurl = "https://dl.dropboxusercontent.com/u/100248799/sf_pack.tar.gz"
        self.downloadmessage = (
            "Downloading a subset of available databases for a smoother " + "ride through the workshop"
        )
        self.loadSettings()
        self._tmpfile = None
        self.reply = None

        # Locks held on server files
        self.locks = []
        self.net_manager = QNetworkAccessManager()
        # Lock all files in files list so any other (in process) atempt to
        # download the files waits)
        box = OWGUI.widgetBox(self.controlArea, "Info")
        self.info = OWGUI.widgetLabel(box, self.downloadmessage)
        self.info.setWordWrap(True)

        box = OWGUI.widgetBox(self.controlArea, "Status")
        self.statusinfo = OWGUI.widgetLabel(box, "Please wait")
        self.statusinfo.setWordWrap(True)
        self.progressbar = QProgressBar()
        box.layout().addWidget(self.progressbar)

        self.setMinimumWidth(250)

        already_available = [
            (domain, filename) for domain in serverfiles.listdomains() for filename in serverfiles.listfiles(domain)
        ]

        if set(self.fileslist) <= set(already_available):
            # All files are already downloaded
            self.statusinfo.setText("All files already available")
            self.setStatusMessage("Done")
        else:
            for domain, filename in self.fileslist + [("_tmp_cache_", "pack")]:
                manager = serverfiles._lock_file(domain, filename)
                try:
                    manager.__enter__()
                except Exception:
                    warnings.warn("Could not acquire lock for {0} {0}".format(domain, filename))
                    self.warning(0, "...")
                else:
                    self.locks.append(manager)

            QTimer.singleShot(0, self.show)
            QTimer.singleShot(0, self.run)

    def run(self):
        self.setStatusMessage("Downloading")
        self.info.setText(self.downloadmessage)

        target_dir = os.path.join(environ.buffer_dir, "serverfiles_pack_cache")

        try:
            os.makedirs(target_dir)
        except OSError:
            pass

        self.progressBarInit()

        req = QNetworkRequest(QUrl(self.downloadurl))
        self.reply = self.net_manager.get(req)
        self.reply.downloadProgress.connect(self._progress)
        self.reply.error.connect(self._error)
        self.reply.finished.connect(self._finished)
        self.reply.readyRead.connect(self._read)
        url = urlparse.urlsplit(self.downloadurl)
        self._tmpfilename = posixpath.basename(url.path)

        self._tmpfile = open(os.path.join(target_dir, self._tmpfilename), "wb+")

    def _progress(self, rec, total):
        if rec == 0 and total == 0:
            self.progressbar.setRange(0, 0)
            self.progressBarValue = 1.0
        else:
            self.progressbar.setRange(0, total)
            self.progressbar.setValue(rec)
            self.progressBarValue = 100.0 * rec / (total or 1)

    def _error(self, error):
        self.statusinfo.setText(u"Error: {0}".format(error.errorString()))
        self.error(0, "Error: {0}".format(error.errorString()))
        self.setStatusMessage("Error")
        self._releaselocks()
        self._removetmp()
        self.progressBarFinshed()

    def _read(self):
        contents = str(self.reply.readAll())
        self._tmpfile.write(contents)

    def _finished(self):
        self.progressbar.reset()
        if self.reply.error() != QNetworkReply.NoError:
            self._releaselocks()
            self._removetmp()
            return

        self.statusinfo.setText("Extracting")
        self.setStatusMessage("Extracting")
        try:
            self._extract()
        except Exception:
            # Permission errors, ... ??
            pass

        self.statusinfo.setText("Done")
        self.setStatusMessage("Done")
        self.progressbar.reset()
        self.progressBarFinished()

        self._releaselocks()
        self._removetmp()

    def _extract(self):
        self._tmpfile.seek(0, 0)
        archive = tarfile.open(fileobj=self._tmpfile)
        target_dir = serverfiles.localpath()
        archive.extractall(target_dir)

    def onDeleteWidget(self):
        super(OWDatabasesPack, self).onDeleteWidget()
        self._releaselocks()

        if self.reply is not None and self.reply.isOpen():
            self.reply.finished.disconnect(self._finished)
            self.reply.error.disconnect(self._error)
            self.reply.close()

        if self._tmpfile is not None:
            self._tmpfile.close()
            self._tmpfile = None

    def _releaselocks(self):
        for lock in self.locks:
            lock.__exit__(None, None, None)
        self.locks = []

    def _removetmp(self):
        if self._tmpfile is not None:
            self._tmpfile.close()
            self._tmpfile = None

        tmp_file = os.path.join(environ.buffer_dir, "serverfiles_pack_cache", self._tmpfilename)

        os.remove(tmp_file)
예제 #25
0
class FileItem(QTreeWidgetItem):

    cols = ['Filepath', 'Renamed Filepath']

    invalid_char_map = {':': ''}

    re_filename_episodes = [
        re.compile(
            r'.*[Ss](?P<season>\d{1,2})[\s\-_]*[Ee](?P<episode>\d{1,2}).*',
            re.I),
        re.compile(
            r'.*season\s*(?P<season>\d{1,2})[\s\-_]*episode\s*[Ee](?P<episode>\d{1,2}).*',
            re.I),
    ]

    re_filepath_episodes = [
        re.compile(
            r'.*season\s*(?P<season>\d{1,2})\\(?:season\s*\d{1,2}[\s\-_]*)?(?:episode|ep\.?|e)\s*(?P<episode>\d{1,2}).*',
            re.I),
    ]

    def __init__(self, parent, filepath, mediaman):
        super(FileItem, self).__init__(parent)
        self._renamed = False
        self.mediaman = mediaman
        self.filepath = filepath
        self.renamed_filepath = None
        self.media_info = None
        self.episode_info = None
        self.thread = None
        self.pbar = None
        self.setText(0, self.filepath)
        self.send_thread()

    def send_thread(self):
        if self.thread is None:
            self.thread = FilepathSearchThread(self.treeWidget())
            self.thread.finished.connect(self.receive_thread)
        thread_ready = self.thread.wait(10000)
        if thread_ready:
            tree = self.treeWidget()
            self.pbar = QProgressBar(tree)
            self.pbar.setRange(0, 0)
            tree.setItemWidget(self, 1, self.pbar)
            self.thread.filepath = self.filepath
            self.thread.start()

    def receive_thread(self):
        self.media_info = self.thread.result
        self.pbar.reset()
        tree = self.treeWidget()
        tree.removeItemWidget(self, 1)
        self.pbar.deleteLater()
        self.refresh()

    def _replace_invalid_chars(self, text):
        for k, v in FileItem.invalid_char_map.items():
            if k in text:
                text = text.replace(k, v)
        return text

    def refresh(self):
        moviedir = self.mediaman.moviedir()
        tvdir = self.mediaman.tvdir()

        if self.media_info:
            title = self.media_info.get('title')
            title = self._replace_invalid_chars(title)
            year = self.media_info.get('year')

            filename, ext = os.path.splitext(os.path.basename(self.filepath))

            if self.episode_info or self.media_info.get('episodes'):
                if not self.episode_info:
                    episodes = self.media_info['episodes']
                    ep_match = None
                    for reg in FileItem.re_filename_episodes:
                        m = reg.search(filename)
                        if m:
                            ep_match = m.groupdict()
                            break
                    if not ep_match:
                        for reg in FileItem.re_filepath_episodes:
                            m = reg.search(self.filepath)
                            if m:
                                ep_match = m.groupdict()

                    if ep_match:
                        season, episode = int(ep_match['season']), int(
                            ep_match['episode'])
                        for episode_info in episodes:
                            if (episode_info['season'],
                                    episode_info['episode']) == (season,
                                                                 episode):
                                self.episode_info = episode_info
                                break

                if self.episode_info:
                    self.renamed_filepath = ur'{tvdir}\{title}\Season{season:02d}\{title}.S{season:02d}E{episode:02d}.{episode_title}{ext}'.format(
                        tvdir=tvdir,
                        title=title,
                        year=year,
                        season=self.episode_info['season'],
                        episode=self.episode_info['episode'],
                        episode_title=self._replace_invalid_chars(
                            self.episode_info['title']),
                        ext=ext,
                    )
                else:
                    self.renamed_filepath = ur'{tvdir}\{title}\Season00\{title}.S00E00.XXX{ext}'.format(
                        tvdir=tvdir,
                        title=title,
                        year=year,
                        ext=ext,
                    )

            else:
                self.renamed_filepath = ur'{moviedir}\{title} ({year})\{title}{ext}'.format(
                    moviedir=moviedir, title=title, year=year, ext=ext)

            self.setText(1, self.renamed_filepath)
            if os.path.exists(self.renamed_filepath):
                self.setBackgroundColor(
                    FileItem.cols.index('Renamed Filepath'),
                    QColor(0, 255, 0, 100))
예제 #26
0
class RipperWidget(SmoothWidget, ripper.Ripper):
    """ One-button multi-track ripper.
    """
    def __init__(self, parent=None):
        SmoothWidget.__init__(self, parent)
        ripper.Ripper.__init__(self)
        Layout = QVBoxLayout(self)

        self.discLabel = QLabel(self)
        Layout.addWidget(self.discLabel)

        # ONLY ONE BUTTON!
        self.button = QPushButton('Cancel', self)
        self.button.setEnabled(True)
        self.button.hide()
        QObject.connect(self.button, SIGNAL('clicked()'),
                        self.cancel)
        Layout.addWidget(self.button)

        self.catFrame = QFrame(self)
        self.catFrame.setFrameStyle(QFrame.StyledPanel)
        self.catFrame.hide()
        QHBoxLayout(self.catFrame)
        self.categories = CategoryButtons(self.catFrame)
        QObject.connect(self.categories, SIGNAL('selected(QString &)'),
                        self.start)
        self.catFrame.layout().addWidget(self.categories)
        Layout.addWidget(self.catFrame)
        
        self.progress = QProgressBar(self)
        self.progress.setRange(0, 100)
        self.progress.hide()
        Layout.addWidget(self.progress)

    def start(self, category):
        """ Should already have the track info. """
        self.genre = str(category)
        self._progress_data = {}
        self.disc_length = 0.0
        for i in range(self.count):
            sec = cd_logic.get_track_time_total(i)
            self._progress_data[i] = {'rip' : 0,
                                      'enc' : 0,
                                      'length' : sec}
            self.disc_length += sec
        self.rip_n_encode()

        text = '%s - %s' % (self.artist, self.album)
        self.discLabel.setText('Copying "'+text+'"...')
        self.button.show()
        self.progress.show()
        self.catFrame.hide()
            
    def cancel(self):        
        self.stop_request = True
        path = os.path.join(ripper.LIBRARY,
                            self.genre,
                            self.artist+' - '+self.album)
        os.system('rm -rf \"%s\"' % path)
        self.discLabel.setText('Canceled')
        self.button.hide()
        self.progress.hide()
        self.progress.setValue(0)
        self.emit(SIGNAL('canceled()'))

    def read_disc_info(self):
        self.discLabel.setText('Getting disc info...')
        ripper.Ripper.read_disc_info(self)

    def ripper_event(self, e):
        """ """
        event = QEvent(event_type(e.type))
        event.data = e.__dict__
        QApplication.instance().postEvent(self, event)

    def customEvent(self, e):
        if e.type() == event_type(ripper.CDDB_DONE):
            self.button.setEnabled(True)
            text = '%s - %s' % (self.artist, self.album)
            text += '           ( Select a category... )'
            self.discLabel.setText(text)
            self.catFrame.show()
            self.emit(SIGNAL('foundDiscInfo()'))
        elif e.type() == event_type(ripper.STATUS_UPDATE):
            self.updateProgress(e.data)
            self.emit(SIGNAL('status(QEvent *)'), e)

    def updateProgress(self, data):
        """
        assume rip and enc are equal in time.
        """
        state = data['state']
        tracknum = data['tracknum']
        percent = data['percent']
        goal_percents = self.count * 200

        item = self._progress_data[tracknum]
        if state == 'rip':
            item['rip'] = percent
        elif state == 'enc':
            item['enc'] = percent
        else:
            # err, etc...
            item['rip'] = 0
            item['enc'] = 0

        total = 0
        for i, v in self._progress_data.items():
            seconds = v['length']
            rip_perc = v['rip']
            enc_perc = v['enc']

            worth = seconds / self.disc_length
            rip_perc *= worth
            enc_perc *= worth
            total += rip_perc + enc_perc
            #print i, worth, rip_perc, enc_perc, total
        percent = total / 2
        self.progress.setValue(percent)

        if percent == 100:
            if self.is_ripping:
                print 'percent == 100 but still ripping?'
            if self.is_encoding:
                print 'percent == 100 but still encoding?'
            else:
                print 'percent == 100 and ripper finished'
            self.button.hide()
            self.progress.hide()
            text = 'Finished copying \"%s - %s\"' % (self.artist, self.album)
            self.discLabel.setText(text)
            self.emit(SIGNAL('doneRipping()'))
예제 #27
0
파일: window.py 프로젝트: ThePsyjo/PyWv
class MainWindow(QMainWindow):
	def __init__(self):
		QMainWindow.__init__(self)
		
		self.setWindowTitle('%s %s' % (QApplication.applicationName(), QApplication.applicationVersion()));

		self.config = ConfigHandler(os.path.join(os.path.expanduser('~'), '.pywv/pywv.cfg'), self)

		self.setStyle(QStyleFactory.create(self.config.loadStyle()))
		if self.config.loadStyleSheet():
			self.setStyleSheet(self.config.loadStyleSheet())
		else:
			self.setStyleSheet("* {}") # without any stylesheet, windowstyles won't apply


		self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks | QMainWindow.VerticalTabs);

#		self.dummy = QWidget(self)
		self.setCentralWidget(QWidget(self))

		self.pBar = QProgressBar(self)
		self.pBar.setRange(0, self.config.loadReloadInterval())
		self.pBar.setFormat("%v Sekunden")
		if not self.config.loadAutoload():
			self.pBar.hide()

		self.statusBar = QStatusBar(self)
		self.setStatusBar(self.statusBar)
		self.statusBar.addWidget(self.pBar)

		self.reloadTimer = QTimer(self);
		self.reloadTimer.setInterval(self.config.loadReloadInterval() * 1000)
		self.connect(self.reloadTimer, SIGNAL('timeout()'), self.reload_)
		if self.config.loadAutoload():
			self.reloadTimer.start()

		self.autoloadStatusTimer = QTimer(self)
		self.autoloadStatusTimer.setInterval(1000) # 1 sec
		self.connect(self.autoloadStatusTimer, SIGNAL('timeout()'), self.onAutoloadStatus)
		self.autoloadStatusTimer.start()

		self.mAction = self.menuBar().addMenu(self.tr("&Action"))
		self.mAction.addAction(self.tr("&update"), self.reload_, QKeySequence('F5'))
		self.mAction.addAction(self.tr("e&xit"), self.onExit, 'Ctrl+Q')

		self.mStyle = QMenu(self.tr("&Style"), self)
		for s in list(QStyleFactory.keys()):#       // fill in all available Styles
			self.mStyle.addAction(s)
		self.connect(self.mStyle, SIGNAL('triggered(QAction*)'), self.onStyleMenu)

		self.mOption = self.menuBar().addMenu(self.tr("&Options"))
		self.mOption.addAction(self.tr("reloadinterval") , self.onReloadTime , 'F8')
		self.mOption.addAction(self.tr("manage links")   , self.onNewLink    , 'F6')
		self.mOption.addSeparator()

		self.ontopAction       = QAction(self.tr("always on &top")  , self)
		self.showTrayAction    = QAction(self.tr("show tray &icon") , self)
		self.closeToTrayAction = QAction(self.tr("close to &tray")  , self)
		self.autoloadAction    = QAction(self.tr("auto&load")       , self)

		self.ontopAction.setCheckable(True)
		self.showTrayAction.setCheckable(True)
		self.closeToTrayAction.setCheckable(True)
		self.autoloadAction.setCheckable(True)

		self.showTrayAction.setChecked   (self.config.loadShowTray()   )
		self.ontopAction.setChecked      (self.config.loadOntop()      )
		self.closeToTrayAction.setChecked(self.config.loadCloseToTray())
		self.autoloadAction.setChecked   (self.config.loadAutoload()   )

		self.connect(self.ontopAction       , SIGNAL('toggled(bool)') , self.onOntopAction)
		self.connect(self.showTrayAction    , SIGNAL('toggled(bool)') , self.onShowTrayAction)
		self.connect(self.closeToTrayAction , SIGNAL('toggled(bool)') , self.onCloseToTrayAction)
		self.connect(self.autoloadAction    , SIGNAL('toggled(bool)') , self.onAutoloadAction)

		self.mOption.addAction(self.ontopAction)
		self.mOption.addAction(self.showTrayAction)
		self.mOption.addAction(self.closeToTrayAction)
		self.mOption.addAction(self.autoloadAction)
		self.mOption.addSeparator()
		self.mOption.addMenu(self.mStyle)

		self.trayIcon = QSystemTrayIcon(QIcon(':/appicon'), self);
		self.trayMgr = TrayManager(self.config, self.trayIcon)
		self.connect(self.trayIcon, SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), self.onTrayIcon)
		if self.config.loadShowTray(): self.trayIcon.show()

		self.trayIconMenu = QMenu()
		self.trayIconMenu.addAction(self.tr("e&xit"), self.onExit)
		self.trayIcon.setContextMenu(self.trayIconMenu)

		self.mAbout = self.menuBar().addMenu(self.tr("&about"))
		self.mAbout.addAction(QApplication.applicationName(), self.onAboutAppAction)
		self.mAbout.addAction("Qt", self.onAboutQtAction)

		self.createWidgets()

		self.resize(self.config.loadWindowSize())
		self.restoreState(self.config.loadWindowState())

		if self.config.loadIsVisible():
			self.show()
			self.reload_()

	def __del__(self):
		self.config.saveWindowState(self.saveState())

	def createSingleWidget(self, name):
#		print 'crt', name, type(name), '\n', self.widgets
#		print 'crt', name, type(name)
		links = self.config.loadLinks()
		if links[name]['type'] == 'generic':
			self.widgets[name] = GenericWidget(name, self.config, self)
		else:
			pluginsAvail = classdirPlugins().all_()
			for plugin in pluginsAvail:
				if links[name]['type'] == plugin['class']:
					pluginClass = plugin['class']
					break
				else:
					continue

			exec('self.widgets[name] = %s(name, self.config, self)' % pluginClass)
		#	print(('loaded plugin', self.widgets[name]))

		self.addDockWidget(0x4, self.widgets[name])
		self.widgets[name].reload_()

	def delWidget(self, name):
		#print 'del', name, type(name), '\n', self.widgets
		self.removeDockWidget(self.widgets[name])
		self.widgets[name].deleteLater()
		self.widgets[name] = None
		del self.widgets[name]

	def createWidgets(self):
		self.widgets = {}
		for name in self.config.loadLinks():
			self.createSingleWidget(name)


	@pyqtSlot()
	def onExit(self):
		self.config.saveWindowSize(self.size())
		QApplication.exit();

	def closeEvent(self, event):
		self.config.saveWindowSize(self.size())
#	       	QApplication.exit()
		# tray is visible -> close to tray
		# else close app
		if self.trayIcon.isVisible():
			event.accept()
		else:
			QApplication.exit()
			return
		# if close-to-tray is set, do so
		if self.config.loadCloseToTray():
			event.accept()
		else:
			QApplication.exit()
			return;
		# save this state
		if	self.trayIcon.isVisible():	self.config.saveIsVisible(False)
		else:					self.config.saveIsVisible(True);
	@pyqtSlot()
	def reload_(self):
		for name in self.widgets:
			self.widgets[name].reload_()
		self.pBar.setValue(self.config.loadReloadInterval())
		self.reloadTimer.start(self.config.loadReloadInterval()*1000)

	@pyqtSlot()
	def onAutoloadStatus(self):
		self.pBar.setValue(self.pBar.value()-1)
#		print([idx for idx in self.widgets])

	def onStyleMenu(self, a):
		QApplication.setStyle(QStyleFactory.create(a.text()))
		self.setStyle(QStyleFactory.create(a.text()))
		self.config.saveStyle(a.text())

	def onReloadTime(self):
		ok = False
		value, ok = QInputDialog.getInteger(self,
			self.tr("reloadinterval"), # title
			self.tr("insert time in s"), # text
			self.config.loadReloadInterval(), # default
			10, # minimum
			86400, # maximum (at least once a day)
			1, # step
			)
		if ok:
			self.config.saveReloadInterval(value)
			self.pBar.setRange(0,self.config.loadReloadInterval())
			self.reload_()

	def onAutoloadAction(self, b):
		if b:
			self.reloadTimer.start()
			self.pBar.show()
			self.reload_()
		else:
			self.reloadTimer.stop()
			self.pBar.hide()
		self.config.saveAutoload(b)

	def onNewLink(self):
		inp = LinkInput(self.config, self)
		if inp.exec_():
			# sync active widgets
			for name in inp.modifiedWidgets():
				if name in self.widgets:
					self.delWidget(name)
					self.createSingleWidget(name)
				else:
					self.createSingleWidget(name)

			# remove deleted
#			for name in self.widgets: print 'shown', name
#			for name in self.config.loadLinks(): print 'conf', name
			todel = []
			for name in self.widgets:
				if name not in self.config.loadLinks():
					todel.append(name)

			for widget in todel:
				self.delWidget(widget)

	def onOntopAction(self, b):
		if b:	self.setWindowFlags(Qt.Dialog | Qt.WindowStaysOnTopHint)
		else:	self.setWindowFlags(Qt.Dialog)
		self.setWindowIcon(QIcon(':/appicon'))
		self.show();
		self.config.saveOntop(b)

	def onShowTrayAction(self, b):
		if b:	self.trayIcon.show()
		else:	self.trayIcon.hide()
		self.config.saveShowTray(b)

	def onCloseToTrayAction(self, b):
		self.config.saveCloseToTray(b)

	def onTrayIcon(self, reason):
		if reason == QSystemTrayIcon.Trigger:
			if(self.isVisible()):
				self.config.saveWindowSize(self.size())
				self.hide()
				self.config.saveIsVisible(False)
			else:
				self.show()
				self.resize(self.config.loadWindowSize())
				self.config.saveIsVisible(True)

	def onAboutAppAction(self):
		QMessageBox.about(self, self.tr("&about"), self.tr("name %1 version %2").arg(QApplication.applicationName()).arg(QApplication.applicationVersion()))
	def onAboutQtAction(self):
		QMessageBox.aboutQt(self, self.tr("&about"))
예제 #28
0
파일: mw.py 프로젝트: sam81/consonance_rate
class mainWin(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        screen = QDesktopWidget().screenGeometry()
        self.setGeometry(80, 100, int((1/2)*screen.width()), int((4/10)*screen.height()))
        self.main_frame = QFrame()
        self.cw = QFrame()
        self.cw.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        self.main_sizer = QVBoxLayout()
        self.hbox1_sizer = QHBoxLayout()
        self.setWindowTitle(self.tr("Consonance Rating"))
        ##
        self.sessionRunning = False
        self.listenerID = ""
        self.currentTrial = 1
        self.intervals_db = pd.read_csv(os.path.abspath(os.path.dirname(__file__)) + "/resources/intervals_database.csv", sep=";")
        # self.rootNotes = np.array([110, 130.81, 185])
        # self.intervalsCents = np.array([100,
        #                                500,
        #                                600,
        #                                700,
        #                                800,
        #                                1100])
        #self.rootNotes = np.array([110, 185])
        self.rootNotes = np.array([146.83,
                                   155.56,
                                   164.81,
                                   174.61,
                                   185,
                                   196,
                                   207.65,
                                   220])
        self.intervalsCents = np.array([600,
                                      
                                      
                                       700
                                      
                                       ])

        self.diadDur = 1980
        self.diadRamps = 10
        self.diadTotLev = np.array([40, 80])
        self.diadFilterType = "lowpass"
        self.diadFilterCutoffs = (2500,)
        self.diadLowHarm = 1
        self.diadHighHarm = 50
        self.diadNote1Chan = "Both"
        self.diadNote2Chan = "Both"
        self.fs = 48000
        self.maxLevel = self.getPhonesCal()
        self.noise1SL = -200
        self.noise1LowFreq = 0
        self.noise1HighFreq = 2000
        self.noise1Type = "Pink"
        self.noise2Type = "Pink"
        self.noise2SL = np.array([0, 40])
        self.noise2LowFreq = 4000
        self.noise2HighFreq = 8000
        self.noise1RefHz = 100
        self.noise2RefHz = 4000
        self.preTrialNoiseRefHz = 1000
        self.preTrialNoiseLowFreq = 20
        self.preTrialNoiseHighFreq = 8000
        self.preTrialNoiseDur = 1980
        self.preTrialNoiseRamps = 10
        self.preTrialNoiseSL = np.array([0, 40])
        self.preTrialNoiseType = "Pink"
        self.preTrialNoiseChannel = "Both"
        self.preTrialNoiseDiadISI = 500
        self.noiseChannel = "Both"

        self.nPracticeTrialsXStim = 4
        self.nTrialsXStim = 2
        self.nTrials = len(self.rootNotes)*len(self.intervalsCents)*len(self.diadTotLev)*(self.nTrialsXStim) + self.nPracticeTrialsXStim*len(self.intervalsCents)*len(self.diadTotLev)
        print(self.nTrials)
        practiceTrials = []
        mainTrials = []
        for rootNote in self.rootNotes:
            for intervalCents in self.intervalsCents:
                for n in range(self.nTrialsXStim):
                    mainTrials.append((rootNote, intervalCents, "main", self.diadTotLev[0], self.noise2SL[0], self.preTrialNoiseSL[0]))

        for intervalCents in self.intervalsCents:
            for n in range(self.nPracticeTrialsXStim):
                practiceTrials.append((random.choice(self.rootNotes), intervalCents, "practice", self.diadTotLev[0], self.noise2SL[0], self.preTrialNoiseSL[0]))

        random.shuffle(practiceTrials)
        random.shuffle(mainTrials)

        practiceTrials2 = []
        mainTrials2 = []
        for rootNote in self.rootNotes:
            for intervalCents in self.intervalsCents:
                for n in range(self.nTrialsXStim):
                    mainTrials2.append((rootNote, intervalCents, "main", self.diadTotLev[1], self.noise2SL[1], self.preTrialNoiseSL[1]))

        for intervalCents in self.intervalsCents:
            for n in range(self.nPracticeTrialsXStim):
                practiceTrials2.append((random.choice(self.rootNotes), intervalCents, "practice", self.diadTotLev[1], self.noise2SL[1], self.preTrialNoiseSL[1]))

        random.shuffle(practiceTrials2)
        random.shuffle(mainTrials2)

        #root note
        #interval cents
        #practice or main
        #dialTotLev
        #noise2SL
        #preTrialNoiseSL

        #remove some practice trials
        #practiceTrials = practiceTrials[0:4]
        #practiceTrials2 = practiceTrials2[0:4]
        
        self.trialList = []
        if random.choice([0,1]) == 0:
            self.trialList.extend(practiceTrials)
            self.trialList.extend(practiceTrials2)
        else:
            self.trialList.extend(practiceTrials2)
            self.trialList.extend(practiceTrials)
        if random.choice([0,1]) == 0:
            self.trialList.extend(mainTrials)
            self.trialList.extend(mainTrials2)
        else:
            self.trialList.extend(mainTrials2)
            self.trialList.extend(mainTrials)

        
      
        print(len(self.trialList))
        self.menubar = self.menuBar()
        self.fileMenu = self.menubar.addMenu(self.tr('-'))
        
        self.editPhonesAction = QAction(self.tr('Phones Calibration'), self)
        self.fileMenu.addAction(self.editPhonesAction)
        self.editPhonesAction.triggered.connect(self.onEditPhones)

        
        self.setupListenerButton = QPushButton(self.tr("Setup Listener"), self)
        self.setupListenerButton.clicked.connect(self.onClickSetupListenerButton)
        self.setupListenerButton.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        # self.setupListenerButton.setToolTip(self.tr("Choose file to save results"))
        # self.setupListenerButton.setWhatsThis(self.tr("Choose where to save the result files"))
        self.setupListenerButton.setStyleSheet('font-size: 32pt; font-weight: bold')
        self.hbox1_sizer.addWidget(self.setupListenerButton)
        self.main_sizer.addLayout(self.hbox1_sizer)

        #statusButtonFont = QFont("Arial", 26);
        self.statusButton = QPushButton(self.tr("Start"), self)
        self.statusButton.clicked.connect(self.onClickStatusButton)
        self.statusButton.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.main_sizer.addWidget(self.statusButton)
        #self.statusButton.setFont(statusButtonFont)
        self.statusButton.setStyleSheet('font-size: 32pt; font-weight: bold')
        self.statusButton.hide()
        self.cw.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        borderWidth = 4
        self.main_sizer.addItem(QSpacerItem(20, 60, QSizePolicy.Fixed))

        self.overallRatingSliderValue = QLabel(self.tr("0"), self)
        self.main_sizer.addWidget(self.overallRatingSliderValue)
        self.overallRatingSliderValue.setStyleSheet('font-size: 22pt; font-weight: normal')
        self.overallRatingSliderValue.setAlignment(Qt.AlignCenter)

        self.main_sizer.addItem(QSpacerItem(20,60, QSizePolicy.Fixed))
        sliderFont = QFont("Ubuntu", 18)
        self.overallRatingSlider = Qwt.QwtSlider(self, Qt.Horizontal, Qwt.QwtSlider.BottomScale)
        self.overallRatingSlider.setFont(sliderFont)
        self.overallRatingSlider.setScale(-3.0,3.0, 1)
        self.overallRatingSlider.setRange(-3.0,3.0)
        self.overallRatingSlider.valueChanged[float].connect(self.sliderChanged)
        self.overallRatingSlider.setMinimumSize(800, 20)
        self.overallRatingSlider.setBorderWidth(borderWidth)
        self.main_sizer.addWidget(self.overallRatingSlider)

        self.main_sizer.addItem(QSpacerItem(20,30, QSizePolicy.Fixed))
        self.gauge = QProgressBar(self)
        self.gauge.setRange(0, 100)
        self.main_sizer.addWidget(self.gauge)
      
        self.cw.setLayout(self.main_sizer)
    

        self.setCentralWidget(self.cw)
        self.show()

    def onClickStatusButton(self):
        if self.statusButton.text() == self.tr("Finished"):
            return
        self.sessionRunning = True
        self.statusButton.setText(self.tr("Running"))
        QApplication.processEvents()
        if self.listenerID == "":
            text, ok = QInputDialog.getText(self, "" , "Listener ID: ")
            if ok:
                self.listenerID = text
                self.statusButton.setText(self.tr("Start"))
            return

        if self.currentTrial == 1:
            self.setupListenerButton.hide()
            self.overallRatingSlider.setValue(0)
            self.overallRatingSliderValue.setText("")
           
            self.doTrial()
            return

        if self.overallRatingSliderValue.text() == "":
            ret = QMessageBox.warning(self, self.tr("Warning"),
                                      self.tr("You need to move the slider before going to the next trial.\nIf you want to assign a score of zero move the slider forth and then back to the zero position."),
                                      QMessageBox.Ok)
            return

        if self.currentTrial > 1:
            self.storeRating()
            self.gauge.setValue((self.currentTrial-1)/self.nTrials*100)
            #self.sliderChanged(0)
            self.sliderLabelReset()
            self.statusButton.setText(self.tr("Running"))
            QApplication.processEvents()
        if self.currentTrial <= self.nTrials :
            self.doTrial()
        else:
            self.statusButton.setText(self.tr("Finished"))
     
            
    def doTrial(self):
        self.statusButton.setText(self.tr("Running"))
        QApplication.processEvents()

        #root note
        rootNote = self.trialList[self.currentTrial-1][0]
        #interval cents
        intervalCents = self.trialList[self.currentTrial-1][1]
        #practice or main
        trialMode = self.trialList[self.currentTrial-1][2]
        #dialTotLev
        diadTotLev = self.trialList[self.currentTrial-1][3]
        #noise2SL
        noise2SL = self.trialList[self.currentTrial-1][4]
        #preTrialNoiseSL
        preTrialNoiseSL = self.trialList[self.currentTrial-1][5]

        try:
            intervalName = self.intervals_db["name"][self.intervals_db["cents"] == self.trialList[self.currentTrial-1][1]].values[0]
        except:
            intervalName = str(self.trialList[self.currentTrial-1][1])
        print(intervalName)

        preTrialNoise = broadbandNoise(spectrumLevel=preTrialNoiseSL,
                                       duration=self.preTrialNoiseDur,
                                       ramp=self.preTrialNoiseRamps, channel=self.preTrialNoiseChannel,
                                       fs=self.fs, maxLevel=self.maxLevel)
        if self.preTrialNoiseType == "Pink":
            preTrialNoise = makePinkRef(preTrialNoise, self.fs, self.preTrialNoiseRefHz)

        preTrialNoise = fir2Filter2(preTrialNoise, filterType="bandpass", nTaps=256, cutoffs=(self.preTrialNoiseLowFreq, self.preTrialNoiseHighFreq), transitionWidth=0.2, fs=self.fs)
            
        diad = makeDiad(rootNote, intervalCents,
                       filterType=self.diadFilterType,
                       filterCutoffs=self.diadFilterCutoffs,
                       lowHarm=self.diadLowHarm, highHarm=self.diadHighHarm,
                       diadTotLev=diadTotLev, duration=self.diadDur,
                       ramp=self.diadRamps, note1Channel=self.diadNote1Chan,
                       note2Channel=self.diadNote2Chan, fs=self.fs,
                       maxLevel=self.maxLevel)

        noise1 = broadbandNoise(spectrumLevel=self.noise1SL,
                                       duration=self.diadDur,
                                       ramp=self.diadRamps*6, channel=self.noiseChannel,
                                       fs=self.fs, maxLevel=self.maxLevel)
        if self.noise1Type == "Pink":
            noise1 = makePinkRef(noise1, self.fs, self.noise1RefHz)
        noise1 = fir2Filter2(noise1, filterType="bandpass", nTaps=256,
                             cutoffs=(self.noise1LowFreq, self.noise1HighFreq),
                             transitionWidth=0.2, fs=self.fs)
        noise1 = noise1[0:diad.shape[0],:]
        noise1 = gate(self.diadRamps, noise1, self.fs)
        
        noise2 = broadbandNoise(spectrumLevel=noise2SL,
                                duration=self.diadDur,
                                ramp=self.diadRamps*6, channel=self.noiseChannel,
                                fs=self.fs, maxLevel=self.maxLevel)
        if self.noise2Type == "Pink":
            noise2 = makePinkRef(noise2, self.fs, self.noise2RefHz)
        noise2 = fir2Filter2(noise2, filterType="bandpass", nTaps=256,
                             cutoffs=(self.noise2LowFreq, self.noise2HighFreq),
                             transitionWidth=0.2, fs=self.fs)
        noise2 = noise2[0:diad.shape[0],:]
        noise2 = gate(self.diadRamps, noise2, self.fs)

        stim = diad+noise1+noise2
        noiseDiadSilence = makeSilence(self.preTrialNoiseDiadISI)
        snd = np.concatenate((preTrialNoise, noiseDiadSilence, stim), axis=0)

        wavwrite(snd, self.fs, 32, "snd.wav")
        wavwrite(diad, self.fs, 32, "diad.wav")
        wavwrite(diad+noise1+noise2, self.fs, 32, "diad_in_noise.wav")
        sound(snd)

        self.currentTrial = self.currentTrial+1

    def storeRating(self):
        try:
            intervalName = self.intervals_db["name"][self.intervals_db["cents"] == self.trialList[self.currentTrial-2][1]].values[0]
        except:
            intervalName = str(self.trialList[self.currentTrial-2][1])
        #rootNote = str(self.trialList[self.currentTrial-2][0])

        #root note
        rootNote = self.trialList[self.currentTrial-2][0]
        #interval cents
        intervalCents = self.trialList[self.currentTrial-2][1]
        #practice or main
        trialMode = self.trialList[self.currentTrial-2][2]
        #dialTotLev
        diadTotLev = self.trialList[self.currentTrial-2][3]
        #noise2SL
        noise2SL = self.trialList[self.currentTrial-2][4]
        #preTrialNoiseSL
        preTrialNoiseSL = self.trialList[self.currentTrial-2][5]

        # if self.currentTrial-1 <= len(self.rootNotes)*len(self.intervalsCents)*self.nPracticeTrialsXStim:
        #     trialMode = "practice"
        # else:
        #     trialMode = "main"
        self.thisPageFile.write(self.listenerID + ';')
        self.thisPageFile.write(str(rootNote) + ';')
        self.thisPageFile.write(intervalName + ';')
        self.thisPageFile.write(str(intervalCents) + ';')
        self.thisPageFile.write(trialMode + ';')
        self.thisPageFile.write(str(diadTotLev) + ';')
        #self.thisPageFile.write(str(noise2SL) + ';')
        self.thisPageFile.write(self.overallRatingSliderValue.text() + '\n')
        self.thisPageFile.flush()
        self.overallRatingSlider.setValue(0)
        self.overallRatingSliderValue.setText("")
        


    def sliderChanged(self, value):
        self.overallRatingSliderValue.setText(str(round(value,1)))
        if self.currentTrial > 1 and self.statusButton.text() != self.tr("Finished"):
            self.statusButton.setText(self.tr("Next"))

    def sliderLabelReset(self):
        self.overallRatingSliderValue.setText("0")

    def onClickSetupListenerButton(self):
        text, ok = QInputDialog.getText(self, "" , "Listener ID: ")
        if ok:
            self.listenerID = text
        else:
            return
        ftow = QFileDialog.getSaveFileName(self, self.tr('Choose file to write results'), "", self.tr('All Files (*)'), "", QFileDialog.DontConfirmOverwrite)[0]
        if len(ftow) > 0:
            self.thisPagePath = ftow
            self.thisPageFile = open(self.thisPagePath, "a")
            self.thisPageFile.write("listener;root_note;interval;intervalCents;trial_type;totLev;rating\n")

            self.setupListenerButton.hide()
            self.statusButton.show()
        else:
            return

    def getPhonesCal(self):
        fHandle = open(phonesCalFile, 'r')
        currCal = float(fHandle.readline().strip())
        fHandle.close()

        return currCal

    def writePhonesCal(self, val):
        fHandle = open(phonesCalFile, 'w')
        fHandle.write(str(val))
        fHandle.close()


    def onEditPhones(self):
        currCal = self.getPhonesCal()
        val, ok = QInputDialog.getDouble(self, self.tr('Phones Calibration'), self.tr('Phones Max. Level'), currCal)
        self.writePhonesCal(val)
        self.maxLevel = val
예제 #29
0
class HoldersTableView(QWidget):
    """A read-only table view for browsing MS Excel or CSV data."""
    def __init__(self, *args, **kwargs):
        super(QWidget, self).__init__(*args, **kwargs)
        self._init_ui()

        # Optional args
        self._dt_format = kwargs.pop('date_format', '%d-%m-%Y')

        # Map for sheet widgets
        self._ws_info = {}

        # Reset the view
        self.reset_view()

    @property
    def date_format(self):
        """
        :return: Returns the format used to render the date/time in the
        view. The default formatting will return the date in ISO 8601 format
        i.e. 'YYYY-MM-DD' where the format is '%Y-%m-%d'.
        :rtype: str
        """
        return self._dt_format

    @date_format.setter
    def date_format(self, format):
        """
        Sets the format used to render the date/time in the view. The format
        needs to be in a format that is understood by Python's 'strftime()'
        function.
        :param format: Format for rendering date/time
        :type format: str
        """
        self._dt_format = format

    def worksheet_info(self, idx):
        """
        :param idx:
        :return: Returns a WorksheetInfo object containing references to the
        ExcelWorksheetView, xlrd.sheet.Sheet and name of the sheet, will
        return None if the index does not exist.
        :rtype: WorksheetInfo
        """
        return self._ws_info.get(idx, None)

    @property
    def progress_bar(self):
        """
        :return: Returns the progress bar for showing progress when Excel
        data is being added to the table.
        :rtype: QProgressBar
        """
        return self._pg_par

    def sizeHint(self):
        return QSize(480, 360)

    def clear_view(self):
        # Removes and deletes all sheet widgets and resets the widget registry index.
        self._tbw.clear()
        self._ws_info.clear()

    def reset_view(self):
        # Clears the view and add an empty default sheet.
        self.clear_view()
        self._add_default_sheet()

    def _add_default_sheet(self):
        # Add a default/empty sheet to the view.
        def_sheet = HoldersSheetView()
        self._tbw.addTab(def_sheet, self.tr('Sheet 1'))

    def _init_ui(self):
        # Set up layout and widgets
        self._vl = QVBoxLayout()
        self._tbw = QTabWidget()
        self._tbw.setTabShape(QTabWidget.Triangular)
        self._tbw.setTabPosition(QTabWidget.South)
        self._tbw.setStyleSheet('QTabBar::tab:selected { color: green; }')
        self._vl.addWidget(self._tbw)
        self._pg_par = QProgressBar()
        self._pg_par.setVisible(False)
        self._vl.addWidget(self._pg_par)
        self.setLayout(self._vl)

    def add_vector_layer(self, vl):
        """
        Adds data contained in Qgis vector layer object to the view.
        :param vl: Object containing holders data.
        :type vl: QgsVectorLayer
        """
        holders_sheet = HoldersSheetView()
        holders_sheet.date_format = self._dt_format
        name = vl.name()
        idx = self._tbw.addTab(holders_sheet, name)
        self._tbw.setTabToolTip(idx, name)

        holders_sheet.load_qgs_vector_layer(vl)

        # Add worksheet info to collection
        wsi = WorksheetInfo()
        wsi.name = name
        wsi.idx = idx
        wsi.ws_widget = holders_sheet
        wsi.ws = vl

        self._ws_info[wsi.idx] = wsi

    def current_sheet_view(self):
        """
        Gets the sheet view in the current tab view.
        :return: Sheet view widget.
        :rtype: HoldersSheetView
        """
        return self._tbw.currentWidget()

    def sheet_view(self, idx):
        """
        Gets the sheet view widget with the given index.
        :param idx: Index number.
        :type idx: int
        :return: Sheet view widget.
        :rtype: HoldersSheetView
        """
        return self.worksheet_info(idx).ws_widget

    def load_holders_file(self, path):
        """
        Loads the holders data contained in the specified file to the view.
        :param path: Path to file containing holders data.
        :type path: str
        """
        holders_file = QFile(path)
        if not holders_file.exists():
            QMessageBox.critical(
                self, self.tr('Invalid path'),
                u'\'{0}\' {1}'.format(path, self.tr('does not exist.')))

            return

        # Check permissions
        holders_fileinfo = QFileInfo(holders_file)
        if not holders_fileinfo.isReadable():
            QMessageBox.critical(
                self, self.tr('Unreadable file'),
                u'{0} {1}'.format(path, self.tr('is not readable.')))

            return

        # Get file extension
        ext = holders_fileinfo.suffix()

        # Get reader based on suffix
        if ext not in holder_readers:
            msg = 'No reader defined for \'{0}\' file extension'.format(ext)
            QMessageBox.critical(self, self.tr('Invalid Extension'), msg)

            return

        reader = holder_readers[ext]

        vl = None

        try:
            # Get vector layer
            vl = reader(path)
        except Exception as ex:
            QMessageBox.critical(self, self.tr('Error Loading Data Source.'),
                                 str(ex))

            return

        if not vl:
            QMessageBox.critical(
                self.parentWidget(), self.tr('Null Data Source'),
                self.tr('Data source object is None, cannot be loaded.'))

            return

        if not vl.isValid():
            err = vl.error()
            if not err.isEmpty():
                err_msg = err.summary()
            else:
                err_msg = 'The holders data source is invalid.'

            QMessageBox.critical(self.parentWidget(),
                                 self.tr('Invalid Data Source'), err_msg)

            return

        # Clear view
        self.clear_view()

        # Show progress bar
        self._pg_par.setVisible(True)
        pg_val = 0

        # Add vector layer to the view
        self._pg_par.setRange(0, 1)
        self.add_vector_layer(vl)

        self._pg_par.setValue(1)

        self._pg_par.setVisible(False)
예제 #30
0
class CompileWidget(QWidget):

    progress = pyqtSignal(int)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self._options = None
        self._conf = None

        self._go = QPushButton('Go')
        self._go.setMaximumWidth(100)
        font = self._go.font()
        font.setPointSizeF(font.pointSizeF() * 2.0)
        font.setWeight(QFont.Bold)
        self._go.setFont(font)
        self._go.clicked.connect(self.go)

        self._saveLog = QPushButton('Save')
        saveLogLabel = QLabel('Log File:')
        saveLogBrowse = QPushButton('&Browse')
        saveLogBrowse.clicked.connect(self.browseSaveLog)
        self._saveLogEdit = QLineEdit('')

        gLayout = QGridLayout()
        gLayout.addWidget(saveLogLabel, 0, 0, 1, 1, Qt.AlignRight)
        gLayout.addWidget(self._saveLogEdit, 0, 1, 1, 6)
        gLayout.addWidget(saveLogBrowse, 0, 7, 1, 1)

        self._console = QTextEdit()
        self._console.setLineWrapMode(QTextEdit.NoWrap)
        self._console.setMinimumSize(800, 400)
        palette = self._console.palette()
        palette.setColor(QPalette.Base, QColor.fromRgb(255, 255,
                                                       221))  # ffffdd.
        self._console.setPalette(palette)
        font = QFont('Bitstream Vera Sans Mono',
                     self._console.font().pointSize())
        self._console.setFont(font)
        self._highlighter = Highlighter(self._console.document())

        self._progressBar = QProgressBar()
        self._progressBar.setRange(0, 100)
        self._progressBar.setTextVisible(True)

        hLayout = QHBoxLayout()
        hLayout.addStretch()
        hLayout.addWidget(self._go)
        hLayout.addStretch()
        hLayout.addWidget(self._saveLog)
        hLayout.addStretch()

        vLayout = QVBoxLayout()
        vLayout.addLayout(hLayout)
        vLayout.addLayout(gLayout)
        vLayout.addWidget(self._progressBar)
        vLayout.addWidget(self._console)
        self.setLayout(vLayout)

        self.progress.connect(self._progressBar.setValue)
        self._saveLog.clicked.connect(self.saveLog)

        self.readSettings()
        return

    def _setOptions(self, options):
        self._options = options

    def _setConf(self, conf):
        self._conf = conf

    def _getOptions(self):
        return self._options

    def _getConf(self):
        return self._conf

    options = property(_getOptions, _setOptions)
    conf = property(_getConf, _setConf)

    def browseSaveLog(self):
        self._saveLogEdit.setText(
            QFileDialog.getSaveFileName(self, 'Select Log File Report',
                                        self._saveLogEdit.text(),
                                        'Report Files (*.log *.txt)'))
        return

    def saveLog(self):
        if self._saveLogEdit.text():
            fd = open(self._saveLogEdit.text(), 'w+')
            fd.write(self._console.toPlainText())
            fd.close()
        return

    def shellCommand(self):
        command = [self.conf.bootstrapDir + '/ccb.py']
        for project in self.options.projects:
            for tool in project.actives:
                command += ['--tool=' + tool]
        toolsCount = len(command) - 1

        if self.conf.rootDir: command += ['--root=%s' % self.conf.rootDir]

        #if self.options.svnUpdate:   command += [ '--svn-update' ]
        #if self.options.svnStatus:   command += [ '--svn-update' ]
        if self.options.enableDoc: command += ['--doc']
        if self.options.devtoolset2: command += ['--devtoolset-2']
        if self.options.qt5: command += ['--qt5']
        if self.options.noCache: command += ['--no-cache']
        if self.options.rmBuild: command += ['--rm-build']
        if self.options.verbose: command += ['--verbose']
        if self.options.make:
            makeArguments = 'install ' + self.options.threads
            command += ['--make=%s' % makeArguments]

        if self.options.buildMode == 'Debug':
            command += ['--debug']
        return toolsCount, command

    def go(self):
        rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
        reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')

        if not self.options or not self.conf: return

        toolsCount, command = self.shellCommand()
        if not toolsCount: return

        self._progressBar.reset()
        self._progressBar.setRange(0, toolsCount * 100)

        strCommand = command[0]
        for arg in command[1:]:
            strCommand += ' ' + arg
        strCommand += '\n\n'
        self._console.setFontItalic(True)
        self._console.insertPlainText(strCommand)
        self._console.setFontItalic(False)

        toolsDone = -1
        builderProcess = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT)
        while True:
            line = builderProcess.stdout.readline()
            if line == '': break

            m = rePercentage.match(line)
            if m:
                self.progress.emit(toolsDone * 100 + int(m.group('percent')))
            else:
                m = reProcessTool.match(line)
                if m:
                    toolsDone += 1

            self._console.insertPlainText(line)

            scrollBar = self._console.verticalScrollBar()
            scrollBar.setValue(scrollBar.maximum())
            QApplication.processEvents()
        builderProcess.wait()
        if builderProcess.returncode == None:
            pass
        return

    def readSettings(self):
        settings = QSettings()
        self._saveLogEdit.setText(settings.value('compile/saveLog').toString())
        return

    def saveSettings(self):
        settings = QSettings()
        settings.setValue('compile/saveLog', self._saveLogEdit.text())
        return
예제 #31
0
class NotUsedAnalysisProgress( QDialog ):
    " Progress of the not used analysis "

    Functions = 0
    Classes   = 1
    Globals   = 2

    def __init__( self, what, sourceModel, parent = None ):
        QDialog.__init__( self, parent )

        if what not in [ self.Functions, self.Classes, self.Globals ]:
            raise Exception( "Unsupported unused analysis type: " + \
                             str( what ) )

        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what              # what is in source model
        self.__srcModel = sourceModel   # source model of globals or
                                        # functions or classes

        # Avoid pylint complains
        self.__progressBar = None
        self.__infoLabel = None
        self.__foundLabel = None
        self.__found = 0        # Number of found

        self.__createLayout()
        self.setWindowTitle( self.__formTitle() )
        QTimer.singleShot( 0, self.__process )
        return

    def keyPressEvent( self, event ):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent( self, event )
        return

    def __formTitle( self ):
        " Forms the progress dialog title "
        title = "Unused "
        if self.__what == self.Functions:
            title += 'function'
        elif self.__what == self.Classes:
            title += 'class'
        else:
            title += 'globlal variable'
        return title + " analysis"

    def __formInfoLabel( self, name ):
        " Forms the info label "
        if self.__what == self.Functions:
            return 'Function: ' + name
        if self.__what == self.Classes:
            return 'Class: ' + name
        return 'Globlal variable: ' + name

    def __whatAsString( self ):
        " Provides 'what' as string "
        if self.__what == self.Functions:
            return 'function'
        if self.__what == self.Classes:
            return 'class'
        return 'global variable'

    def __updateFoundLabel( self ):
        " Updates the found label "
        text = "Found: " + str( self.__found ) + " candidate"
        if self.__found != 1:
            text += "s"
        self.__foundLabel.setText( text )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 20 )
        self.setSizeGripEnabled( True )

        verticalLayout = QVBoxLayout( self )

        # Note label
        noteLabel = QLabel( "<b>Note</b>: the analysis is " \
                            "suggestive and not precise. " \
                            "Use the results with caution.\n", self )
        verticalLayout.addWidget( noteLabel )

        # Info label
        self.__infoLabel = QLabel( self )
        verticalLayout.addWidget( self.__infoLabel )

        # Progress bar
        self.__progressBar = QProgressBar( self )
        self.__progressBar.setValue( 0 )
        self.__progressBar.setOrientation( Qt.Horizontal )
        verticalLayout.addWidget( self.__progressBar )

        # Found label
        self.__foundLabel = QLabel( self )
        verticalLayout.addWidget( self.__foundLabel )

        # Buttons
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Close )
        verticalLayout.addWidget( buttonBox )

        buttonBox.rejected.connect( self.__onClose )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process( self ):
        " Analysis process "

        self.__inProgress = True

        mainWindow = GlobalData().mainWindow
        editorsManager = mainWindow.editorsManagerWidget.editorsManager
        modified = editorsManager.getModifiedList( True ) # True - only project files
        if modified:
            modNames = [ modItem[ 0 ] for modItem in modified ]
            label = "File"
            if len( modified ) >= 2:
                label += "s"
            label += ": "
            logging.warning( "The analisys is performed for the content of saved files. " \
                             "The unsaved modifications will not be taken into account. " \
                             + label + ", ".join( modNames ) )

        self.__updateFoundLabel()
        self.__progressBar.setRange( 0,
                                   len( self.__srcModel.rootItem.childItems ) )
        QApplication.processEvents()
        QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )

        count = 0
        candidates = []
        for treeItem in self.__srcModel.rootItem.childItems:
            if self.__cancelRequest:
                break

            name = str( treeItem.data( 0 ) ).split( '(' )[ 0 ]
            path = os.path.realpath( treeItem.getPath() )
            lineNumber = int( treeItem.data( 2 ) )
            absPosition = treeItem.sourceObj.absPosition

            count += 1
            self.__progressBar.setValue( count )
            self.__infoLabel.setText( self.__formInfoLabel( name ) )
            QApplication.processEvents()

            # Analyze the name
            found = False
            try:
                # True is for throwing exceptions
                locations = getOccurrences( path, absPosition, True )

                if len( locations ) == 1 and \
                   locations[ 0 ][ 1 ] == lineNumber:
                    found = True
                    index = getSearchItemIndex( candidates, path )
                    if index < 0:
                        widget = mainWindow.getWidgetForFileName( path )
                        if widget is None:
                            uuid = ""
                        else:
                            uuid = widget.getUUID()
                        newItem = ItemToSearchIn( path, uuid )
                        candidates.append( newItem )
                        index = len( candidates ) - 1
                    candidates[ index ].addMatch( name, lineNumber )

            except Exception, exc:
                # There is nothing interesting with exceptions here.
                # It seems to me that rope throws them in case if the same item
                # is declared multiple times in a file. I also suspect that
                # exceptions may come up in case of syntactic errors.
                # So I just suppress them.
                pass

                #logging.warning( "Error detected while analysing " + \
                #                 self.__whatAsString() + " '" + name + \
                #                 "'. Message: " + str( exc ) )

            if found:
                self.__found += 1
                self.__updateFoundLabel()
            QApplication.processEvents()

        if self.__found == 0:
            # The analysis could be interrupted
            if not self.__cancelRequest:
                logging.info( "No unused candidates found" )
        else:
            mainWindow.displayFindInFiles( "", candidates )

        QApplication.restoreOverrideCursor()
        self.__infoLabel.setText( 'Done' )
        self.__inProgress = False

        self.accept()
        return
예제 #32
0
class ImportsDiagramProgress( QDialog ):
    " Progress of the diagram generator "

    def __init__( self, what, options, path = "", buf = "", parent = None ):
        QDialog.__init__( self, parent )
        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what
        self.__options = options
        self.__path = path          # could be a dir or a file
        self.__buf = buf            # content in case of a modified file

        # Working process data
        self.__participantFiles = []    # Collected list of files
        self.__projectImportDirs = []
        self.__projectImportsCache = {} # utils.settings -> /full/path/to.py
        self.__dirsToImportsCache = {}  # /dir/path -> { my.mod: path.py, ... }

        self.dataModel = ImportDiagramModel()
        self.scene = QGraphicsScene()

        # Avoid pylint complains
        self.progressBar = None
        self.infoLabel = None

        self.__createLayout()
        self.setWindowTitle( 'Imports/dependencies diagram generator' )
        QTimer.singleShot( 0, self.__process )
        return

    def keyPressEvent( self, event ):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent( self, event )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 20 )
        self.setSizeGripEnabled( True )

        verticalLayout = QVBoxLayout( self )

        # Info label
        self.infoLabel = QLabel( self )
        verticalLayout.addWidget( self.infoLabel )

        # Progress bar
        self.progressBar = QProgressBar( self )
        self.progressBar.setValue( 0 )
        self.progressBar.setOrientation( Qt.Horizontal )
        verticalLayout.addWidget( self.progressBar )

        # Buttons
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Close )
        verticalLayout.addWidget( buttonBox )

        buttonBox.rejected.connect( self.__onClose )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __buildParticipants( self ):
        " Builds a list of participating files and dirs "
        if self.__what in [ ImportsDiagramDialog.SingleBuffer,
                            ImportsDiagramDialog.SingleFile ]:
            # File exists but could be modified
            self.__path = os.path.realpath( self.__path )
            self.__participantFiles.append( self.__path )
            return

        if self.__what == ImportsDiagramDialog.ProjectFiles:
            self.__scanProjectDirs()
            return

        # This is a recursive directory
        self.__path = os.path.realpath( self.__path )
        self.__scanDirForPythonFiles( self.__path + os.path.sep )
        return

    def __scanDirForPythonFiles( self, path ):
        " Scans the directory for the python files recursively "
        for item in os.listdir( path ):
            if item in [ ".svn",  ".cvs" ]:
                continue
            if os.path.isdir( path + item ):
                self.__scanDirForPythonFiles( path + item + os.path.sep )
                continue
            if item.endswith( ".py" ) or item.endswith( ".py3" ):
                fName = os.path.realpath( path + item )
                # If it was a link, the target could be non-python
                if fName.endswith( ".py" ) or fName.endswith( ".py3" ):
                    self.__participantFiles.append( fName )
        return

    def __scanProjectDirs( self ):
        " Populates participant lists from the project files "
        for fName in GlobalData().project.filesList:
            if fName.endswith( ".py" ) or fName.endswith( ".py3" ):
                self.__participantFiles.append( fName )
        return

    def isProjectImport( self, importString ):
        " Checks if it is a project import string and provides a path if so "
        if importString in self.__projectImportsCache:
            return self.__projectImportsCache[ importString ]

        subpath = importString.replace( '.', os.path.sep )
        candidates = [ subpath + ".py", subpath + ".py3",
                       subpath + os.path.sep + "__init__.py",
                       subpath + os.path.sep + "__init__.py3" ]
        for path in self.__projectImportDirs:
            for item in candidates:
                fName = path + os.path.sep + item
                if os.path.isfile( fName ):
                    self.__projectImportsCache[ importString ] = fName
                    return fName
        return None

    def isLocalImport( self, dirName, importString ):
        " Checks if it is local dir import string and provides a path if so "
        dirFound = False
        if dirName in self.__dirsToImportsCache:
            dirFound = True
            importsDict = self.__dirsToImportsCache[ dirName ]
            if importString in importsDict:
                return importsDict[ importString ]

        subpath = importString.replace( '.', os.path.sep )
        candidates = [ subpath + ".py", subpath + ".py3",
                       subpath + os.path.sep + "__init__.py",
                       subpath + os.path.sep + "__init__.py3" ]
        for item in candidates:
            fName = dirName + os.path.sep + item
            if os.path.isfile( fName ):
                # Found on the FS. Add to the dictionary
                if dirFound:
                    importsDict[ importString ] = fName
                else:
                    self.__dirsToImportsCache[ dirName ] = { importString: fName }
                return fName
        return None

    def isSystemWideImport( self, importString ):
        " Provides a path to the system wide import or None "
        # Systemwide modules may not have a path if it is a
        # built-in module, or to have a path to an .so library
        try:
            path = getSystemWideModules()[ importString ]
            if path is None:
                return True, None
            if path.endswith( ".py" ):
                return True, path
            if path.endswith( ".py3" ):
                return True, path
            return True, None
        except:
            return False, None

    def __addBoxInfo( self, box, info ):
        " Adds information to the given box if so configured "
        if info.docstring is not None:
            box.docstring = info.docstring.text

        if self.__options.includeClasses:
            for klass in info.classes:
                box.classes.append( klass )

        if self.__options.includeFuncs:
            for func in info.functions:
                box.funcs.append( func )

        if self.__options.includeGlobs:
            for glob in info.globals:
                box.globs.append( glob )

        if self.__options.includeConnText:
            for imp in info.imports:
                box.imports.append( imp )

        return

    def __addDocstringBox( self, info, fName, modBoxName ):
        " Adds a docstring box if needed "
        if self.__options.includeDocs:
            if info.docstring is not None:
                docBox = DgmDocstring()
                docBox.docstring = info.docstring
                docBox.refFile = fName

                # Add the box and its connection
                docBoxName = self.dataModel.addDocstringBox( docBox )

                conn = DgmConnection()
                conn.kind = DgmConnection.ModuleDoc
                conn.source = modBoxName
                conn.target = docBoxName
                self.dataModel.addConnection( conn )

                # Add rank for better layout
                rank = DgmRank()
                rank.firstObj = modBoxName
                rank.secondObj = docBoxName
                self.dataModel.addRank( rank )
        return

    def __getSytemWideImportDocstring( self, path ):
        " Provides the system wide module docstring "
        if not path.endswith( '.py' ) and not path.endswith( '.py3' ):
            return ""

        try:
            info = GlobalData().briefModinfoCache.get( path )
            if info.docstring is not None:
                return info.docstring.text
            return ""
        except:
            return ""

    @staticmethod
    def __getModuleTitle( fName ):
        " Extracts a module name out of the file name "
        baseTitle = os.path.basename( fName ).split( '.' )[ 0 ]
        if baseTitle != "__init__":
            return baseTitle

        # __init__ is not very descriptive. Add a top level dir.
        dirName = os.path.dirname( fName )
        topDir = os.path.basename( dirName )
        return topDir + "(" + baseTitle + ")"

    def __addSingleFileToDataModel( self, info, fName ):
        " Adds a single file to the data model "
        if fName.endswith( "__init__.py" ) or \
           fName.endswith( "__init__.py3" ):
            if not info.classes and not info.functions and \
               not info.globals and not info.imports:
                # Skip dummy init files
                return

        modBox = DgmModule()
        modBox.refFile = fName

        modBox.kind = DgmModule.ModuleOfInterest
        modBox.title = self.__getModuleTitle( fName )

        self.__addBoxInfo( modBox, info )
        modBoxName = self.dataModel.addModule( modBox )
        self.__addDocstringBox( info, fName, modBoxName )

        # Add what is imported
        isProjectFile = GlobalData().project.isProjectFile( fName )
        for item in info.imports:
            impBox = DgmModule()

            importPath = None
            systemWideImportPath = None
            if isProjectFile:
                importPath = self.isProjectImport( item.name )
            if importPath is None:
                importPath = self.isLocalImport( os.path.dirname( fName ), item.name )

            if importPath is not None:
                impBox.kind = DgmModule.OtherProjectModule
                impBox.title = os.path.basename( importPath ).split( '.' )[ 0 ]
                impBox.refFile = importPath
                otherInfo = GlobalData().briefModinfoCache.get( importPath )

                # It's a local or project import
                self.__addBoxInfo( impBox, otherInfo )

            else:
                impBox.kind = DgmModule.UnknownModule
                impBox.title = item.name

                found, systemWideImportPath = self.isSystemWideImport( item.name )
                if found:
                    if systemWideImportPath is not None:
                        impBox.kind = DgmModule.SystemWideModule
                        impBox.refFile = systemWideImportPath
                        impBox.docstring = \
                            self.__getSytemWideImportDocstring( \
                                            systemWideImportPath )
                    else:
                        impBox.kind = DgmModule.BuiltInModule

            impBoxName = self.dataModel.addModule( impBox )

            impConn = DgmConnection()
            impConn.kind = DgmConnection.ModuleDependency
            impConn.source = modBoxName
            impConn.target = impBoxName

            if self.__options.includeConnText:
                for impWhat in item.what:
                    if impWhat.name != "":
                        impConn.labels.append( impWhat )
            self.dataModel.addConnection( impConn )

        return

    def __process( self ):
        " Accumulation process "

        # Intermediate working data
        self.__participantFiles = []
        self.__projectImportDirs = []
        self.__projectImportsCache = {}

        self.dataModel.clear()
        self.__inProgress = True

        try:
            self.infoLabel.setText( 'Building the list of files to analyze...' )
            QApplication.processEvents()

            # Build the list of participating python files
            self.__buildParticipants()
            self.__projectImportDirs = \
                        GlobalData().project.getImportDirsAsAbsolutePaths()


            QApplication.processEvents()
            if self.__cancelRequest == True:
                QApplication.restoreOverrideCursor()
                self.close()
                return

            self.progressBar.setRange( 0, len( self.__participantFiles ) )
            index = 1

            # Now, parse the files and build the diagram data model
            if self.__what == ImportsDiagramDialog.SingleBuffer:
                info = getBriefModuleInfoFromMemory( str( self.__buf ) )
                self.__addSingleFileToDataModel( info, self.__path )
            else:
                infoSrc = GlobalData().briefModinfoCache
                for fName in self.__participantFiles:
                    self.progressBar.setValue( index )
                    self.infoLabel.setText( 'Analyzing ' + fName + "..." )
                    QApplication.processEvents()
                    if self.__cancelRequest == True:
                        QApplication.restoreOverrideCursor()
                        self.dataModel.clear()
                        self.close()
                        return
                    info = infoSrc.get( fName )
                    self.__addSingleFileToDataModel( info, fName )
                    index += 1

            # The import caches and other working data are not needed anymore
            self.__participantFiles = None
            self.__projectImportDirs = None
            self.__projectImportsCache = None


            # Generating the graphviz layout
            self.infoLabel.setText( 'Generating layout using graphviz...' )
            QApplication.processEvents()

            graph = getGraphFromDescriptionData( self.dataModel.toGraphviz() )
            graph.normalize( self.physicalDpiX(), self.physicalDpiY() )
            QApplication.processEvents()
            if self.__cancelRequest == True:
                QApplication.restoreOverrideCursor()
                self.dataModel.clear()
                self.close()
                return

            # Generate graphics scene
            self.infoLabel.setText( 'Generating graphics scene...' )
            QApplication.processEvents()
            self.__buildGraphicsScene( graph )

            # Clear the data model
            self.dataModel = None
        except Exception, exc:
            QApplication.restoreOverrideCursor()
            logging.error( str( exc ) )
            self.__inProgress = False
            self.__onClose()
            return

        QApplication.restoreOverrideCursor()
        self.infoLabel.setText( 'Done' )
        QApplication.processEvents()
        self.__inProgress = False

        self.accept()
        return
예제 #33
0
파일: process.py 프로젝트: kzwkt/dff
class CarvingProcess(QWidget, EventHandler):
    def __init__(self, selector, vnode):
        QWidget.__init__(self)
        EventHandler.__init__(self)
        self.vnode = vnode.value()
        self.filesize = self.vnode.size()
        self.tm = TaskManager()
        self.selector = selector
        self.setLayout(QVBoxLayout())
        self.factor = 1
        self.parsetime = 0
        self.time = time.time()
        self.starttime = time.time()
        self.createStartOffset()
        self.createButtons()
        self.createStateInfo()

    def createStartOffset(self):
        self.offsetLayout = QHBoxLayout()
        self.offsetSpinBox = QFFSpinBox(self)
        self.offsetSpinBox.setMinimum(0)
        self.offsetSpinBox.setMaximum(self.filesize)
        self.offsetLabel = QLabel("start offset:")
        self.offsetLayout.addWidget(self.offsetLabel)
        self.offsetLayout.addWidget(self.offsetSpinBox)
        self.layout().addLayout(self.offsetLayout)

    def createButtons(self):
        self.startButton = QPushButton("Start")
        self.stopButton = QPushButton("Stop")
        self.stopButton.setEnabled(False)
        self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCarving)
        self.connect(self.startButton, SIGNAL("clicked()"), self.startCarving)
        self.connect(self, SIGNAL("ended"), self.carvingEnded)
        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.startButton)
        self.buttonLayout.addWidget(self.stopButton)
        self.layout().addLayout(self.buttonLayout)

    def createStateInfo(self):
        self.stateLayout = QVBoxLayout()

        self.overallLayout = QHBoxLayout()
        self.currentLabel = QLabel("Overall progress :")
        self.currentProgress = QProgressBar()
        self.overallLayout.addWidget(self.currentLabel)
        self.overallLayout.addWidget(self.currentProgress)
        self.stateLayout.addLayout(self.overallLayout)

        self.elapsedLabel = QLabel("elapsed time:    00d00h00m00s")
        self.stateLayout.addWidget(self.elapsedLabel)
        self.estimatedLabel = QLabel("estimated time: 00d00h00m00s")
        self.stateLayout.addWidget(self.estimatedLabel)
        self.totalLabel = QLabel("total headers found: 0")
        self.stateLayout.addWidget(self.totalLabel)
        self.stateLayout.setEnabled(False)
        self.layout().addLayout(self.stateLayout)

    def createContext(self, selected):
        lpatterns = VList()
        for filetype in selected.iterkeys():
            patterns = selected[filetype][0]
            aligned = selected[filetype][1]
            for pattern in patterns:
                vpattern = VMap()
                vpattern["filetype"] = Variant(filetype, typeId.String)

                header = VMap()
                header["needle"] = Variant(pattern[0], typeId.String)
                header["size"] = Variant(len(pattern[0]), typeId.UInt32)

                footer = VMap()
                footer["needle"] = Variant(pattern[1], typeId.String)
                footer["size"] = Variant(len(pattern[1]), typeId.UInt32)

                vpattern["header"] = Variant(header)
                vpattern["footer"] = Variant(footer)
                vpattern["window"] = Variant(int(pattern[2]), typeId.UInt32)
                vpattern["aligned"] = Variant(aligned, typeId.Bool)
                lpatterns.append(vpattern)
        return lpatterns

    def startCarving(self):
        selected = self.selector.selectedItems()
        if len(selected):
            try:
                f = self.vnode.open()
                f.close()
            except:
                mbox = QMessageBox(
                    QMessageBox.Warning, self.tr("Carver bad input"),
                    self.
                    tr("The provided input file seems to be a directory. Please, apply the module on a file"
                       ), QMessageBox.Ok, self)
                mbox.exec_()
                return
            patterns = self.createContext(selected)
            args = VMap()
            args["patterns"] = Variant(patterns)
            args["file"] = Variant(self.vnode)
            args["start-offset"] = Variant(self.offsetSpinBox.value(),
                                           typeId.UInt64)
            factor = round(float(self.filesize) / 2147483647)
            self.startButton.setEnabled(False)
            self.stopButton.setEnabled(True)
            self.stopButton.setDown(False)
            if factor == 0:
                factor = 1
            proc = self.tm.add("carver", args, ["gui", "thread"])
            if proc:
                self.doJob(self.filesize, factor, self.offsetSpinBox.value())
                self.stateLayout.setEnabled(True)
                self.connection(proc.inst)
                proc.inst.connection(self)
                #self.connect(self, SIGNAL("stateInfo(QString)"), self.setStateInfo)
        else:
            mbox = QMessageBox(
                QMessageBox.Warning, self.tr("Carver no items selected"),
                self.
                tr("No items have been provided to know what to look for. Please chose types you want to search."
                   ), QMessageBox.Ok, self)
            mbox.exec_()
            return

    def carvingEnded(self, res):
        #results = str(res).split("\n")
        #print results
        #for item in results:
        #    begidx = item.find(":")
        #    self.res.add_const(str(item[:begidx]), str(item[begidx+1:] + "\n"))
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)
        self.stateLayout.setEnabled(False)

    def stopCarving(self):
        self.killJob()
        self.stopButton.setDown(True)

    def strtime(self, day, hour, min, sec):
        day = str(day)
        hour = str(hour)
        min = str(min)
        sec = str(sec)
        res = "0" * (2 - len(day)) + day + "d" + "0" * (
            2 - len(hour)) + hour + "h" + "0" * (
                2 - len(min)) + min + "m" + "0" * (2 - len(sec)) + sec + "s"
        return res

    def timesec2str(self, timesec):
        day = hour = min = sec = 0
        if timesec > 3600 * 24:
            day = timesec / (3600 * 24)
            timesec = timesec % (3600 * 24)
        if timesec > 3600:
            hour = timesec / 3600
            timesec = timesec % 3600
        if timesec > 60:
            min = timesec / 60
            timesec = timesec % 60
        sec = timesec
        res = self.strtime(int(day), int(hour), int(min), int(sec))
        return res

    def Event(self, e):
        if e.type == Carver.Position:
            self.emit(SIGNAL("updatePosition"), e)
        elif e.type == Carver.Matches:
            self.emit(SIGNAL("updateMatches"), e)
        elif e.type == Carver.EndOfProcessing:
            self.emit(SIGNAL("ended"), "")

    def updatePosition(self, e):
        ref = time.time() - self.time
        self.time = time.time()
        if not str(ref).startswith("0.0"):
            ref *= self.parsetime
            res = self.timesec2str(ref)
            self.estimatedLabel.setText("estimated time: " + res)
        res = self.timesec2str(time.time() - self.starttime)
        self.elapsedLabel.setText("elapsed time:    " + res)
        i = int(e.value.value() / self.factor)
        if i > 2147483647:
            i = 2147483647
        self.emit(SIGNAL("valueChanged(int)"), i)
        info = self.currentProgress.text() + " - " + self.totalLabel.text()
        self.emit(SIGNAL("stateInfo(QString)"), info)

    def updateMatches(self, e):
        self.totalLabel.setText("total headers found: " + str(e.value))

    def doJob(self, filesize, factor, start):
        self.factor = factor
        self.parsetime = filesize / (10 * 1204 * 1024)
        self.elapsedLabel.setText("elapsed time:    00d00h00m00s")
        self.estimatedLabel.setText("estimated time: 00d00h00m00s")
        self.totalLabel.setText("total headers found: 0")
        maxrange = int(filesize / self.factor)
        if maxrange > 2147483647:
            maxrange = 2147483647
        self.currentProgress.setRange(0, maxrange)
        self.currentProgress.setValue(0)
        self.connect(self, SIGNAL("valueChanged(int)"),
                     self.currentProgress.setValue)
        self.time = time.time()
        self.starttime = time.time()
        self.connect(self, SIGNAL("updateMatches"), self.updateMatches)
        self.connect(self, SIGNAL("updatePosition"), self.updatePosition)

    def killJob(self):
        e = event()
        e.thisown = False
        e.type = Carver.Stop
        self.notify(e)
예제 #34
0
파일: tt2.py 프로젝트: ThePsyjo/myTools
class ImportWidget(QDialog):
	def __init__(self, db_path, parent = None):
		QWidget.__init__(self)
		self.setParent(parent)
		self.setWindowFlags(Qt.Dialog)
		self.setWindowTitle(self.tr('Import'))
		self.setModal(1)

		self.startButton = QPushButton(self)
		self.startButton.setText('&start')
		self.connect( self.startButton, SIGNAL('clicked()'), self.onStart )

		self.stopButton = QPushButton(self)
		self.stopButton.setText('&cancel')
		self.stopButton.setEnabled( False )
		self.connect( self.stopButton, SIGNAL('clicked()'), self.onStop )

		self.okButton = QPushButton(self)
		self.okButton.setText('&done')
		self.okButton.setEnabled( False )
		self.connect( self.okButton, SIGNAL('clicked()'), self.onOk )

		self.statusBar = QProgressBar(self)
		self.statusBar.setRange(0, 100)
		self.statusLabel = QLabel(self)

		self.worker = ImportWorker(db_path, self)
		self.connect( self.worker, SIGNAL('statusChanged'), self.statusBar.setValue )
		self.connect( self.worker, SIGNAL('done'), self.onDone )
		self.connect( self.worker, SIGNAL('message'), self.statusLabel.setText )
		self.connect( self.worker, SIGNAL('range'), self.statusBar.setRange )
	
		self.layout = QGridLayout(self)
		self.layout.addWidget( self.startButton, 0, 0 )
		self.layout.addWidget( self.stopButton, 0, 1 )
		self.layout.addWidget( self.okButton, 0, 2 )
		self.layout.addWidget( self.statusBar, 1, 0, 1, 3 )
		self.layout.addWidget( self.statusLabel, 2, 0, 1, 3 )

	def onStart(self):
		self.startButton.setEnabled( False )
		self.stopButton.setEnabled( True )
		self.statusBar.setEnabled( True )
		self.statusLabel.setEnabled( True )
		Thread(target=self.worker.run).start()

	def onDone(self):
		self.okButton.setEnabled( True )
		self.stopButton.setEnabled( False )

	def onStop(self):
		self.worker.term()
		self.statusBar.setEnabled( False )
		self.statusLabel.setEnabled( False )
		self.startButton.setEnabled( True )
		self.stopButton.setEnabled( False )
	
	def onOk(self):
		self.accept()

	def closeEvent(self,event):
		if self.worker.running:
			event.ignore()
		else:
			event.accept()
예제 #35
0
class OWDatabasesPack(OWWidget.OWWidget):
    settingsList = ["fileslist", "downloadurl", "downloadmessage"]

    def __init__(self, parent=None, signalManager=None,
                 title="Databases Pack"):

        super(OWDatabasesPack, self).__init__(
            parent, signalManager, title, wantMainArea=False)

        self.fileslist = [("Taxonomy", "ncbi_taxonomy.tar.gz")]
        self.downloadurl = "https://dl.dropboxusercontent.com/u/100248799/sf_pack.tar.gz"
        self.downloadmessage = (
            "Downloading a subset of available databases for a smoother " +
            "ride through the workshop"
        )
        self.loadSettings()
        self._tmpfile = None
        self.reply = None

        # Locks held on server files
        self.locks = []
        self.net_manager = QNetworkAccessManager()
        # Lock all files in files list so any other (in process) atempt to
        # download the files waits)
        box = OWGUI.widgetBox(self.controlArea, "Info")
        self.info = OWGUI.widgetLabel(box, self.downloadmessage)
        self.info.setWordWrap(True)

        box = OWGUI.widgetBox(self.controlArea, "Status")
        self.statusinfo = OWGUI.widgetLabel(box, "Please wait")
        self.statusinfo.setWordWrap(True)
        self.progressbar = QProgressBar()
        box.layout().addWidget(self.progressbar)

        self.setMinimumWidth(250)

        already_available = [(domain, filename)
                             for domain in serverfiles.listdomains()
                             for filename in serverfiles.listfiles(domain)]

        if set(self.fileslist) <= set(already_available):
            # All files are already downloaded
            self.statusinfo.setText("All files already available")
            self.setStatusMessage("Done")
        else:
            for domain, filename in self.fileslist + [("_tmp_cache_", "pack")]:
                manager = serverfiles._lock_file(domain, filename)
                try:
                    manager.__enter__()
                except Exception:
                    warnings.warn("Could not acquire lock for {0} {0}"
                                  .format(domain, filename))
                    self.warning(0, "...")
                else:
                    self.locks.append(manager)

            QTimer.singleShot(0, self.show)
            QTimer.singleShot(0, self.run)

    def run(self):
        self.setStatusMessage("Downloading")
        self.info.setText(self.downloadmessage)

        target_dir = os.path.join(environ.buffer_dir, "serverfiles_pack_cache")

        try:
            os.makedirs(target_dir)
        except OSError:
            pass

        self.progressBarInit()

        req = QNetworkRequest(QUrl(self.downloadurl))
        self.reply = self.net_manager.get(req)
        self.reply.downloadProgress.connect(self._progress)
        self.reply.error.connect(self._error)
        self.reply.finished.connect(self._finished)
        self.reply.readyRead.connect(self._read)
        url = urlparse.urlsplit(self.downloadurl)
        self._tmpfilename = posixpath.basename(url.path)

        self._tmpfile = open(
            os.path.join(target_dir, self._tmpfilename), "wb+"
        )

    def _progress(self, rec, total):
        if rec == 0 and total == 0:
            self.progressbar.setRange(0, 0)
            self.progressBarValue = 1.0
        else:
            self.progressbar.setRange(0, total)
            self.progressbar.setValue(rec)
            self.progressBarValue = 100.0 * rec / (total or 1)

    def _error(self, error):
        self.statusinfo.setText(
            u"Error: {0}".format(error.errorString())
        )
        self.error(0, "Error: {0}".format(error.errorString()))
        self.setStatusMessage("Error")
        self._releaselocks()
        self._removetmp()
        self.progressBarFinshed()

    def _read(self):
        contents = str(self.reply.readAll())
        self._tmpfile.write(contents)

    def _finished(self):
        self.progressbar.reset()
        if self.reply.error() != QNetworkReply.NoError:
            self._releaselocks()
            self._removetmp()
            return

        self.statusinfo.setText("Extracting")
        self.setStatusMessage("Extracting")
        try:
            self._extract()
        except Exception:
            # Permission errors, ... ??
            pass

        self.statusinfo.setText("Done")
        self.setStatusMessage("Done")
        self.progressbar.reset()
        self.progressBarFinished()

        self._releaselocks()
        self._removetmp()

    def _extract(self):
        self._tmpfile.seek(0, 0)
        archive = tarfile.open(fileobj=self._tmpfile)
        target_dir = serverfiles.localpath()
        archive.extractall(target_dir)

    def onDeleteWidget(self):
        super(OWDatabasesPack, self).onDeleteWidget()
        self._releaselocks()

        if self.reply is not None and self.reply.isOpen():
            self.reply.finished.disconnect(self._finished)
            self.reply.error.disconnect(self._error)
            self.reply.close()

        if self._tmpfile is not None:
            self._tmpfile.close()
            self._tmpfile = None

    def _releaselocks(self):
        for lock in self.locks:
            lock.__exit__(None, None, None)
        self.locks = []

    def _removetmp(self):
        if self._tmpfile is not None:
            self._tmpfile.close()
            self._tmpfile = None

        tmp_file = os.path.join(
            environ.buffer_dir, "serverfiles_pack_cache", self._tmpfilename
        )

        os.remove(tmp_file)
예제 #36
0
class MyCustomDialog(QDialog):
 
    def __init__(self):
        super(MyCustomDialog, self).__init__()
        layout = QVBoxLayout(self)
 
        # Create a progress bar and a button and add them to the main layout
        self.progressBarUpdate = QProgressBar(self)
        self.progressBarUpdate.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.progressBarUpdate)

        pushButtonUpdate = QPushButton("Start", self)
        layout.addWidget(pushButtonUpdate)
        pushButtonCancel = QPushButton("Cancel", self)
        layout.addWidget(pushButtonCancel)
 
        pushButtonUpdate.clicked.connect(self.check_folder_exists)

        # Set data for download and saving in path
        self.location = os.path.abspath(os.path.join('temp', 'example-app-0.3.win32.zip'))
        self.url = 'http://sophus.bplaced.net/download/example-app-0.3.win32.zip'
 
        self.download_task = Download_Thread(self.location, self.url)
        self.download_task.notify_progress.connect(self.on_progress)
        self.download_task.finished_thread.connect(self.on_finished)
        self.download_task.error_http.connect(self.on_HTTPError)
        self.download_task.finished_download.connect(self.on_finish_download)

        pushButtonCancel.clicked.connect(self.on_finished)

    def on_start(self):
        self.progressBarUpdate.setRange(0, 0)
        self.download_task.start()

    def on_finish_download(self):
        msg_box = QMessageBox()

        QMessageBox.question(msg_box, ' Message ',
                                           "The file has been fully downloaded.", msg_box.Ok)
            
    def on_HTTPError(self):
        reply = QMessageBox.question(self, ' Error ',
                                           "The file could not be downloaded. Will they do it again?", QMessageBox.Yes | 
            QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.on_start()
        else:
            event.ignore() 
 
    def on_progress(self, i):
        self.progressBarUpdate.setRange(0, 100)
        self.progressBarUpdate.setValue(i)
 
    def check_folder_exists(self):
        location = os.path.abspath(os.path.join('temp'))
        if not os.path.exists(location):
            os.makedirs(location)
            print "Folder was created"
            self.on_start()
        else:
            print "Folder already exists"
            self.on_start()
 
    def on_finished(self):
        self.progressBarUpdate.setValue(0)
        self.close()

    def closeEvent(self, event):
        self.download_task.stop()
예제 #37
0
class BR_JobDock(QDockWidget):
    transcode_data = pyqtSignal([dict], [str])
    job_complete = pyqtSignal()

    def __init__(self, job, passes, job_id, closesig, source, parent=None):
        name = source.title
        super().__init__(name, parent)
        self.job = job
        self.passes = passes
        self.job_id = job_id
        self.closesig = closesig
        self.source = source

        self.setWindowTitle(name)
        self.setFeatures(QDockWidget.DockWidgetMovable
                         | QDockWidget.DockWidgetFloatable)
        self.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.setFloating(True)

        self.widget = QWidget()
        layout = QVBoxLayout()
        #        layout.setSizeConstraint(QVBoxLayout.SetFixedSize)
        message_layout = QFormLayout()
        self.lblPass = QLabel('Pass ? of {}'.format(passes))
        message_layout.addRow(self.lblPass)
        self.lblFrame = QLabel('?')
        message_layout.addRow('Frame:', self.lblFrame)
        self.lblFps = QLabel('?')
        message_layout.addRow('Frames per Second:', self.lblFps)
        self.lblSize = QLabel('?')
        message_layout.addRow('File Size:', self.lblSize)
        self.lblTime = QLabel('?')
        message_layout.addRow('Video Time:', self.lblTime)
        self.lblBitrate = QLabel('?')
        message_layout.addRow('Bitrate:', self.lblBitrate)
        layout.addLayout(message_layout)

        self.progressbar = QProgressBar()
        self.progressbar.setRange(0, self.source.length.total_seconds())
        layout.addWidget(self.progressbar)

        self.qualitybar = QualityBar()
        layout.addWidget(self.qualitybar)

        btn_layout = QHBoxLayout()
        btn_More = QPushButton('More')
        btn_More.setCheckable(True)
        btn_layout.addWidget(btn_More)
        btn_layout.addStretch()
        self.btnCancel = QPushButton('Close')
        self.btnCancel.setIcon(QIcon(QPixmap(':/icons/application-exit.png')))
        self.btnCancel.clicked.connect(self.on_cancel_clicked)
        btn_layout.addWidget(self.btnCancel)
        layout.addLayout(btn_layout)

        self.terminal = QPlainTextEdit()
        self.terminal.setReadOnly(True)
        self.terminal.setShown(False)
        #        self.terminal.setMinimumWidth(400)
        btn_More.toggled.connect(self.terminal.setVisible)
        layout.addWidget(self.terminal)

        griplayout = QHBoxLayout()
        griplayout.addWidget(QSizeGrip(self.widget))
        griplayout.addStretch()
        griplayout.addWidget(QSizeGrip(self.widget))
        layout.addLayout(griplayout)

        self.widget.setLayout(layout)
        self.setWidget(self.widget)

        self.transcode_data[dict].connect(self.on_avconv_data)
        self.transcode_data[str].connect(self.on_terminal_data)
        self.closesig.connect(parent.on_jobclose)

    def start(self, dir):
        self.runjob = TranscodeJob(self.job, self.passes, self.source, dir,
                                   self.transcode_data, self.job_complete)
        self.runjob.completesig.connect(self.on_job_complete)
        self.btnCancel.setText('Stop')
        self.runjob.start()

    @pyqtSlot(dict)
    def on_avconv_data(self, match):
        self.lblPass.setText('Pass {pass} of {passes}'.format(**match))
        self.lblFrame.setText('{frame}'.format(**match))
        self.lblFps.setText('{fps}'.format(**match))
        size = round(int(match['size']) / 1024, 2)
        self.lblSize.setText('{} MB'.format(size))
        time = DvdTimeDelta(seconds=float(match['time']))
        self.lblTime.setText('{}'.format(time))
        self.lblBitrate.setText('{bitrate} kbps'.format(**match))
        self.qualitybar.setValue(int(round(float(match['q']) * 10)))
        self.progressbar.setValue(int(round(float(match['time']))))

    @pyqtSlot(str)
    def on_terminal_data(self, text):
        self.terminal.appendPlainText(text)

    @pyqtSlot()
    def on_cancel_clicked(self):
        if self.runjob.is_alive():
            msg = QMessageBox(QMessageBox.Question, 'Cancelling Job',
                              'Do you want to cancel the running job?')
            msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            msg.setDefaultButton(QMessageBox.No)
            ans = msg.exec_()
            if ans == QMessageBox.Yes:
                self.runjob.cancel()
        else:
            self.close_demand()

    @pyqtSlot()
    def on_job_complete(self):
        self.lblPass.setText('Completed')
        self.btnCancel.setText('Close')

    def close_demand(self):
        self.closesig.emit(self.job_id)
        self.close()

    def cancel(self):
        self.runjob.cancel()
        self.runjob.join()
예제 #38
0
class DeviceInfoWidget(QWidget):

    DEVICE_IMAGES = {
        'rider20' : resource_path('img/rider20_icon.jpg'),
        'rider30' : resource_path('img/rider30_icon.jpg'),
        'rider35' : resource_path('img/rider35_icon.jpg'),
        'rider40' : resource_path('img/rider40_icon.jpg'),
        'rider50' : resource_path('img/rider50_icon.jpg'),
        'rider' : resource_path('img/rider_icon.jpg'),
        'cardio30' : resource_path('img/cardio30_icon.jpg'),
        'cardio35' : resource_path('img/cardio35_icon.jpg'),
        'cardio' : resource_path('img/cardio_icon.jpg'),
    }


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

        self.image = QLabel(self)
        self.image.setPixmap(QPixmap(self.DEVICE_IMAGES['rider']))

        self.image_frame = QFrame(self)
        self.image_frame.setMaximumHeight(55)
        self.image_frame.setMinimumHeight(55)
        self.image_frame.setMaximumWidth(55)
        self.image_frame.setMinimumWidth(55)
        self.image_frame.setFrameShape(QFrame.StyledPanel)
        self.image_frame.setFrameShadow(QFrame.Raised)


        self.storage_usage = QProgressBar(self)
        self.storage_usage.setFormat('Disk usage %p%')
        self.storage_usage.setRange(0, 100)
        self.storage_usage.setValue(0)


        self.device_name = QLabel(self)
        self.device_name.setText('<b>Unknown</b>')
        self.device_name.setContentsMargins(3, 0, 0, 0)

        self._createLayout()


    def setDeviceInfo(self, dev_info):


        name = dev_info['name'].lower()

        if name in self.DEVICE_IMAGES:
            img = self.DEVICE_IMAGES[name]
        elif 'rider' in name:
            img = self.DEVICE_IMAGES['rider']
        elif 'cardio' in name:
            img = self.DEVICE_IMAGES['cardio']
        else:
            img = self.DEVICE_IMAGES['rider']

        self.device_name.setText('<b>%s</b>' % dev_info['name'])

        self.image.setPixmap(QPixmap(img))

        self.storage_usage.setValue(
            float(dev_info['storage_used']) / dev_info['total_storage'] * 100
        )





    def _createLayout(self):


        l = QHBoxLayout()
        l.addWidget(self.image)
        l.setContentsMargins(1, 1, 1, 1)

        self.image_frame.setLayout(l)

        l = QHBoxLayout()

        l.addWidget(self.image_frame)

        v = QVBoxLayout()

        v.addWidget(self.device_name)
        v.addWidget(self.storage_usage, 1)

        l.addLayout(v)

        self.setLayout(l)
예제 #39
0
class UploadDialog(QDialog):


    def __init__(self, bbclient, parent=None, session_id=None, username=None, password=None):
        super(UploadDialog, self).__init__(parent,
                Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowMinMaxButtonsHint)

        self.session_id = session_id
        self.username = username
        self.password = password
        self._first_auth = True


        self.total_progress = QProgressBar(self)
        self.total_progress.setRange(0, 100)
        self.total_progress.setValue(0)
        self.total_progress.setFormat('%p%')


        self.status_msg = QLabel('Starting upload', self)


        self.setWindowTitle('Uploading')


        self._createLayout()


        self.upload = BrytonSportUpload(bbclient, parent=self)

        self.upload.authNeeded.connect(self._onAuthNeeded)
        self.upload.totalProgress.connect(self.total_progress.setValue)
        self.upload.statusMessage.connect(self.status_msg.setText)
        self.upload.finished.connect(self._onFinished)
        self.upload.failed.connect(self._onError)
        # self.upload.start()

        QTimer.singleShot(100, self.upload.start)




    def _createLayout(self):

        l = QVBoxLayout()

        l.addWidget(self.status_msg)
        l.addWidget(self.total_progress)

        self.setLayout(l)



    def _onAuthNeeded(self):

        if self._first_auth and self.username is not None and self.password is not None:
            self._first_auth = False
            self.upload.authenticate(self.username, self.password)
            return


        d = AuthDialog(self)

        if d.exec_() == QDialog.Accepted:
            u, p = d.getValues()
            self.upload.authenticate(u, p)
        else:
            self.accept()


    def _onFinished(self):

        QMessageBox.information(self, 'Upload Finished', 'The tracks was successfully uploaded.')

        self.accept()

    def _onError(self):
        QMessageBox.warning(self, 'Upload Failed', 'The upload failed with an unknown error.')
        self.accept()
예제 #40
0
class ProgressDialog ( MProgressDialog, Window ):
    """ A simple progress dialog window which allows itself to be updated

        FIXME: buttons are not set up correctly yet
    """

    #-- Facet Definitions ------------------------------------------------------

    progress_bar    = Instance( QProgressBar )
    title           = Unicode
    message         = Unicode
    min             = Int
    max             = Int
    margin          = Int( 5 )
    can_cancel      = Bool( False )
    show_time       = Bool( False )
    show_percent    = Bool( False )
    _user_cancelled = Bool( False )
    dialog_size     = Instance( QRect )

    # Label for the 'cancel' button
    cancel_button_label = Unicode( 'Cancel' )

    #-- Public Methods ---------------------------------------------------------

    def open ( self ):
        super( ProgressDialog, self ).open()
        self._start_time = time.time()


    def close ( self ):
        self.progress_bar.destroy()
        self.progress_bar = None

        super( ProgressDialog, self ).close()


    def update ( self, value ):
        """
        Updates the progress bar to the desired value. If the value is >=
        the maximum and the progress bar is not contained in another panel
        the parent window will be closed

        """

        if self.progress_bar is None:
            return ( None, None )

        self.progress_bar.setValue( value )

        percent = (float( value ) - self.min) / (self.max - self.min)

        if self.show_time and (percent != 0):
            current_time = time.time()
            elapsed      = current_time - self._start_time
            estimated    = elapsed / percent
            remaining    = estimated - elapsed

            self._set_time_label( elapsed,   self._elapsed_control )
            self._set_time_label( estimated, self._estimated_control )
            self._set_time_label( remaining, self._remaining_control )
            self._message_control.setText( self.message )

        if self.show_percent:
            self._percent_control = "%3f" % ((percent * 100) % 1)

        if (value >= self.max) or self._user_cancelled:
            self.close()

        return ( not self._user_cancelled, False )


    def reject ( self, event ):
        self._user_cancelled = True
        self.close()


    def _set_time_label ( self, value, control ):
        hours   = value / 3600
        minutes = (value % 3600) / 60
        seconds = value % 60
        label   = "%1u:%02u:%02u" % ( hours, minutes, seconds )

        control.setText( control.text()[:-7] + label )


    def _create_buttons ( self, dialog, layout ):
        """ Creates the buttons.
        """
        # Create the button:
        buttons = QDialogButtonBox()

        if self.can_cancel:
            buttons.addButton( self.cancel_button_label,
                               QDialogButtonBox.RejectRole )

        buttons.addButton( QDialogButtonBox.Ok )

        # TODO: hookup the buttons to our methods, this may involve subclassing
        # from QDialog

        if self.can_cancel:
            buttons.connect( buttons, SIGNAL( 'rejected()' ), dialog,
                             SLOT( 'reject() ' ) )
        buttons.connect( buttons, SIGNAL( 'accepted()' ), dialog,
                         SLOT( 'accept()' ) )

        layout.addWidget( buttons )


    def _create_label ( self, dialog, layout, text ):
        dummy = QLabel( text, dialog )
        dummy.setAlignment( Qt.AlignTop | Qt.AlignLeft )

        label = QLabel( "unknown", dialog )
        label.setAlignment( Qt.AlignTop | Qt.AlignLeft | Qt.AlignRight )

        sub_layout = QHBoxLayout()

        sub_layout.addWidget( dummy )
        sub_layout.addWidget( label )

        layout.addLayout( sub_layout )

        return label


    def _create_gauge ( self, dialog, layout ):
        self.progress_bar = QProgressBar( dialog )
        self.progress_bar.setRange( self.min, self.max )
        layout.addWidget( self.progress_bar )


    def _create_message ( self, dialog, layout ):
        label = QLabel( self.message, dialog )
        label.setAlignment( Qt.AlignTop | Qt.AlignLeft )
        layout.addWidget( label )
        self._message_control = label


    def _create_percent ( self, dialog, layout ):
        #not an option with the QT progress bar
        return


    def _create_timer ( self, dialog, layout ):
        if not self.show_time:
            return

        self._elapsed_control   = self._create_label( dialog, layout,
                                                      "Elapsed time : " )
        self._estimated_control = self._create_label( dialog, layout,
                                                      "Estimated time : " )
        self._remaining_control = self._create_label( dialog, layout,
                                                      "Remaining time : " )


    def _create_control ( self, parent ):
        control = QDialog( parent )
        control.setWindowTitle( self.title )

        return control


    def _create ( self ):
        super( ProgressDialog, self )._create()

        contents = self._create_contents( self.control )


    def _create_contents ( self, parent ):
        dialog = parent
        layout = QVBoxLayout( dialog )

        # The 'guts' of the dialog:
        self._create_message( dialog, layout )
        self._create_gauge(   dialog, layout )
        self._create_percent( dialog, layout )
        self._create_timer(   dialog, layout )
        self._create_buttons( dialog, layout )

        parent.setLayout( layout )

#-- EOF ------------------------------------------------------------------------
예제 #41
0
class LDSControls(QFrame):
        
    STATIC_IMG = ('error_static.png','linz_static.png','busy_static.png','clean_static.png')
    ANIM_IMG   = ('error.gif','linz.gif','layer.gif','clean.gif')
    
    IMG_SPEED  = 100
    IMG_WIDTH  = 64
    IMG_HEIGHT = 64
    
    MAX_WD = 450
    
    GD_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../bin/gdal/gdal-data'))
    STATUS = LU.enum('ERROR','IDLE','BUSY','CLEAN')
    
    def __init__(self,parent):
        super(LDSControls, self).__init__()
        self.parent = parent
        self.initConf()
        self.initEPSG()
        self.initUI()
        
    def initConf(self):
        '''Read files in conf dir ending in conf'''
        self.cflist = ConfigInitialiser.getConfFiles()
        #self.imgset = self.STATIC_IMG if ConfigWrapper().readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        #self.imgset = self.STATIC_IMG if self.parent.confconn.tp.src.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        sep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.SRCNAME,self.parent.confconn.uconf)
        self.imgset = self.STATIC_IMG if sep.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.SRCNAME)
        
    def initEPSG(self):
        '''Read GDAL EPSG files, splitting by NZ(RSR) and RestOfTheWorld'''

        gcsf = gdal.FindFile('gdal','gcs.csv') 
        if not gcsf:
            gcsf = os.path.join(self.GD_PATH,'gcs.csv')
        pcsf = gdal.FindFile('gdal','pcs.csv') 
        if not pcsf: 
            pcsf = os.path.join(self.GD_PATH,'pcs.csv')
        gcs = ConfigInitialiser.readCSV(gcsf)
        pcs = ConfigInitialiser.readCSV(pcsf)

        self.nzlsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]]
        self.rowsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]]
                   
                   
    def initUI(self):
        
        # 0      1          2       3       4       5      6    7    8
        #'destname','lgselect','layer','uconf','group','epsg','fd','td','int'
        
        #self.rdest,rlgselect,self.rlayer,ruconf,self.rgroup,repsg,rfd,rtd,rint = readlist 
        
        QToolTip.setFont(QFont('SansSerif', 10))
        
        #labels
        destLabel = QLabel('Destination')
        lgLabel = QLabel('Group/Layer')
        epsgLabel = QLabel('EPSG')
        fromDateLabel = QLabel('From Date')
        toDateLabel = QLabel('To Date')
        confLabel = QLabel('User Config')
        
        self.view = QLabel() 
        self.view.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.view.setAlignment(Qt.AlignCenter)

        self.confcombo = QComboBox(self)
        self.confcombo.setToolTip('Enter your user config name (file) here')
        self.confcombo.addItems(self.cflist)
        self.confcombo.setEditable(False)
        #self.confcombo.currentIndexChanged.connect(self.doLGEditUpdate)
        
        #combos
        self.lgcombo = QComboBox(self)
        self.lgcombo.setMaximumWidth(self.MAX_WD)
        self.lgcombo.setDuplicatesEnabled(False)
        #self.lgcombo.setInsertPolicy(QComboBox.InsertAlphabetically)#?doesnt seem to work
        self.lgcombo.setToolTip('Select either Layer or Group entry')
        self.lgcombo.setEditable(False)
        self.sepindex = None
        #self.updateLGValues()
        
        self.epsgcombo = QComboBox(self)
        self.epsgcombo.setMaximumWidth(self.MAX_WD)
        self.epsgcombo.setToolTip('Setting an EPSG number here determines the output SR of the layer')  
        self.epsgcombo.addItems([i[1] for i in self.nzlsr])
        self.epsgcombo.insertSeparator(len(self.nzlsr))
        self.epsgcombo.addItems([i[1] for i in self.rowsr])
        self.epsgcombo.setEditable(True)
        self.epsgcombo.setEnabled(False)
        
        self.destlist = self.getConfiguredDestinations()
        self.destcombo = QComboBox(self)
        self.destcombo.setToolTip('Choose the desired output type')   
        self.destcombo.setEditable(False)
        self.destcombo.addItems(self.destlist)

        #date selection
        self.fromdateedit = QDateEdit()
        self.fromdateedit.setCalendarPopup(True)
        self.fromdateedit.setEnabled(False)
        
        self.todateedit = QDateEdit()
        self.todateedit.setCalendarPopup(True)
        self.todateedit.setEnabled(False)
        
        #check boxes
        self.epsgenable = QCheckBox()
        self.epsgenable.setCheckState(False)
        self.epsgenable.clicked.connect(self.doEPSGEnable)       
        
        self.fromdateenable = QCheckBox()
        self.fromdateenable.setCheckState(False)
        self.fromdateenable.clicked.connect(self.doFromDateEnable)
        
        self.todateenable = QCheckBox()
        self.todateenable.setCheckState(False) 
        self.todateenable.clicked.connect(self.doToDateEnable)
        
        self.progressbar = QProgressBar()
        self.progressbar.setRange(0,100)
        self.progressbar.setVisible(True)
        self.progressbar.setMinimumWidth(self.MAX_WD)
        
        
        #buttons        
        self.initbutton = QPushButton("waiting")
        self.initbutton.setToolTip('Initialise the Layer Configuration')
        self.initbutton.clicked.connect(self.doInitClickAction)
        
        self.cleanbutton = QPushButton("Clean")
        self.cleanbutton.setToolTip('Clean the selected layer/group from local storage')
        self.cleanbutton.clicked.connect(self.doCleanClickAction)
        
        self.replicatebutton = QPushButton("Replicate")
        self.replicatebutton.setToolTip('Execute selected replication')
        self.replicatebutton.clicked.connect(self.doReplicateClickAction)
        
        self.cancelbutton = QPushButton("Close")
        self.cancelbutton.setToolTip('Close the LDS Replicate application')       
        self.cancelbutton.clicked.connect(self.parent.close)


        #set dialog values using GPR
        self.updateGUIValues(self.parent.gvs)
        
        #set onchange here otherwise we get circular initialisation
        self.destcombo.currentIndexChanged.connect(self.doDestChanged)
        self.confcombo.currentIndexChanged.connect(self.doConfChanged)
        self.lgcombo.currentIndexChanged.connect(self.doLGComboChanged)

        self.setStatus(self.STATUS.IDLE)
        
        #grid
        grid = QGridLayout()
        grid.setSpacing(10)
        
        
        #placement section ------------------------------------
        #---------+---------+--------+---------+--------
        # dest LB |         | dest DD
        # grp LB  |         | grp DD
        # conf LB |         | conf DD
        # epsg L  | epsg CB | epsg DD
        # f dt L  | f dt CB | f dt DD
        # t td L  | t td CB | t td DD
        # icon    |       <- progress ->
        # layer B | <- . -> |repl B  | clean B | close B 
        #---------+---------+--------+---------+--------

        grid.addWidget(destLabel, 1, 0)
        grid.addWidget(self.destcombo, 1, 2)

        #grid.addWidget(layerLabel, 2, 0)
        grid.addWidget(lgLabel, 2, 0)
        grid.addWidget(self.lgcombo, 2, 2)
        
        grid.addWidget(confLabel, 3, 0)
        grid.addWidget(self.confcombo, 3, 2)
        
        #grid.addWidget(groupLabel, 4, 0)
        #grid.addWidget(self.groupEdit, 4, 2)
        
        grid.addWidget(epsgLabel, 5, 0)
        grid.addWidget(self.epsgenable, 5, 1)
        grid.addWidget(self.epsgcombo, 5, 2)

        grid.addWidget(fromDateLabel, 6, 0)
        grid.addWidget(self.fromdateenable, 6, 1)
        grid.addWidget(self.fromdateedit, 6, 2)
        
        grid.addWidget(toDateLabel, 7, 0)
        grid.addWidget(self.todateenable, 7, 1)
        grid.addWidget(self.todateedit, 7, 2)
        
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.view) 
        hbox3.addStretch(1)
        hbox3.addWidget(self.progressbar)

        #hbox3.addLayout(vbox2)
        #hbox3.addLayout(vbox3)
        
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.initbutton)
        hbox4.addStretch(1)
        hbox4.addWidget(self.replicatebutton)
        hbox4.addWidget(self.cleanbutton)
        hbox4.addWidget(self.cancelbutton)
        

        vbox = QVBoxLayout()
        #vbox.addStretch(1)
        vbox.addLayout(grid)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        
        self.setLayout(vbox)  
       
    #def setProgress(self,pct):
    #    self.progressbar.setValue(pct)
        
    def setStatus(self,status,message='',tooltip=None):
        '''Sets indicator icon and statusbar message'''
        self.parent.statusbar.showMessage(message)
        self.parent.statusbar.setToolTip(tooltip if tooltip else '')

        #progress
        loc = os.path.abspath(os.path.join(IMG_LOC,self.imgset[status]))
        #loc = os.path.abspath(os.path.join(os.path.dirname(__file__),self.parent.IMG_LOC,self.imgset[status]))
        self.progressbar.setVisible(status in (self.STATUS.BUSY, self.STATUS.CLEAN))
        
        #icon
        anim = QMovie(loc, QByteArray(), self)
        anim.setScaledSize(QSize(self.IMG_WIDTH,self.IMG_HEIGHT))
        anim.setCacheMode(QMovie.CacheAll)
        anim.setSpeed(self.IMG_SPEED)
        self.view.clear()
        self.view.setMovie(anim)
        anim.start()

        self.view.repaint()
        QApplication.processEvents(QEventLoop.AllEvents)

    def mainWindowEnable(self,enable=True):
        cons = (self.lgcombo, self.confcombo, self.destcombo, 
                self.initbutton, self.replicatebutton, self.cleanbutton, self.cancelbutton,
                self.epsgenable,self.fromdateenable,self.todateenable,
                self.parent.menubar)
        for c in cons:
            c.setEnabled(enable)
            
        if enable:
            self.epsgcombo.setEnabled(self.epsgenable.checkState())
            self.fromdateedit.setEnabled(self.fromdateenable.checkState())
            self.todateedit.setEnabled(self.todateenable.checkState())
        else:
            self.epsgcombo.setEnabled(False)
            self.fromdateedit.setEnabled(False)
            self.todateedit.setEnabled(False)
   
        QApplication.restoreOverrideCursor() if enable else QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 

    def refreshLGCombo(self):
        '''Re index LG combobox since a refreshLG call (new dest?) will usually mean new groups'''
        self.lgcombo.clear()
        self.lgcombo.addItems([i[2] for i in self.parent.confconn.lglist])
        #NOTE the separator consumes an index, if not clearing the combobox selectively remove the old sepindex (assumes g preceeds l)
        #if self.sepindex:
        #    self.lgcombo.removeItem(self.sepindex)
        self.sepindex = [i[0] for i in self.parent.confconn.lglist].count(LORG.GROUP)
        self.lgcombo.insertSeparator(self.sepindex)
        
    def updateLGValues(self,uconf,lgval,dest):
        '''Sets the values displayed in the Layer/Group combo'''
        #because we cant seem to sort combobox entries and want groups at the top, clear and re-add
        #TRACE#        
        #pdb.set_trace()
        sf = None
        try:
            self.parent.confconn.initConnections(uconf,lgval,dest)
        except Exception as e:
            sf=1
            ldslog.error('Error Updating UC Values. '+str(e))
            
        if sf:
            self.setStatus(self.STATUS.ERROR,'Error Updating UC Values', str(e))
        else:
            self.setStatus(self.STATUS.IDLE)
            
        self.refreshLGCombo()
        
    def centre(self):
        
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    
    def gprParameters(self,rdest):
        '''Zip default and GPR values'''
        return [x if LU.assessNone(x) else y for x,y in zip(self.parent.gpr.readsec(rdest),self.parent.DEF_RVALS[1:])]
    
    def getLCE(self,ln):
        '''Read layer parameters'''
        dep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        #sep = self.parent.confconn.reg.openEndPoint('WFS',self.parent.confconn.uconf)
        self.parent.confconn.reg.setupLayerConfig(self.parent.confconn.tp,None,dep,initlc=False)
        lce = dep.getLayerConf().readLayerParameters(ln)
        #self.parent.confconn.reg.closeEndPoint('WFS')
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        sep,dep = None,None
        return lce
    
    
    def doDestChanged(self):
        '''Read the destname parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rvals = self.gprParameters(rdest)
        self.updateGUIValues([rdest]+rvals)    
        
        
    def doConfChanged(self):
        '''Read the user conf parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rlg,_,rep,rfd,rtd = self.gprParameters(rdest)
        ruc = str(self.cflist[self.confcombo.currentIndex()])
        self.updateGUIValues((rdest,rlg,ruc,rep,rfd,rtd))
        
        
    def doLGComboChanged(self):
        '''Read the layer/group value and change epsg to layer or gpr match'''
        #get a matching LG entry and test whether its a layer or group
        #lgi = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgi = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #lgi can be none if we init a new group, in which case we use the GPR value
        if lgi:
            lge = self.parent.confconn.lglist[lgi]
            lce = self.getLCE(lge[1]) if lge[0]==LORG.LAYER else None
        else:
            lce = None
        
        #look for filled layer conf epsg OR use prefs stored in gpr
        if lce and LU.assessNone(lce.epsg):
            epsgval = lce.epsg
        else:
            rdest = str(self.destlist[self.destcombo.currentIndex()])
            _,_,epsgval,_,_ = self.gprParameters(rdest)
        epsgindex = [i[0] for i in self.nzlsr+[(0,0)]+self.rowsr].index(epsgval)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(int(epsgindex))

        
    def updateGUIValues(self,readlist):
        '''Fill dialog values from provided list'''
        #TODO. Remove circular references when setCurrentIndex() triggers do###Changed()
        #Read user input
        rdest,self.rlgval,ruconf,repsg,rfd,rtd = readlist
        
        #--------------------------------------------------------------------
        
        #Destination Menu
        selecteddest = LU.standardiseDriverNames(rdest)
        if selecteddest not in self.destlist:
            self.destlist = self.getConfiguredDestinations()
            self.destcombo.addItem(selecteddest)
        destindex = self.destlist.index(selecteddest) if selecteddest else 0
        
        if self.destcombo.currentIndex() != destindex:
            self.destcombo.setCurrentIndex(destindex)
        
        #InitButton
        self.initbutton.setText('Layer Select')
        
        #Config File
        confindex = 0
        if LU.assessNone(ruconf):
            ruconf = ruconf.split('.')[0]
            if ruconf not in self.cflist:
                self.cflist += [ruconf,]
                self.confcombo.addItem(ruconf)
            confindex = self.cflist.index(ruconf)
            
        if self.confcombo.currentIndex() != confindex:
            self.confcombo.setCurrentIndex(confindex)
        #self.confEdit.setText(ruconf if LU.assessNone(ruconf) else '')
        
        #Layer/Group Selection
        self.updateLGValues(ruconf,self.rlgval,rdest)
        lgindex = None
        if LU.assessNone(self.rlgval):
            #index of list value
            lgindex = self.parent.confconn.getLayerGroupIndex(self.rlgval,col=1)
            
        if LU.assessNone(lgindex):
            #advance by 1 for sep
            lgindex += 1 if lgindex>self.sepindex else 0 
        else:
            #using the separator index sets the combo to blank
            lgindex = self.sepindex
        if self.lgcombo.currentIndex() != lgindex:
            self.lgcombo.setCurrentIndex(lgindex)
        #self.doLGEditUpdate()
        
        #EPSG
        #                                user > layerconf
        #useepsg = LU.precedence(repsg, lce.epsg if lce else None, None)
        epsgindex = [i[0] for i in self.nzlsr+[(None,None)]+self.rowsr].index(repsg)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(epsgindex)
            
        #epsgedit = self.epsgcombo.lineEdit()
        #epsgedit.setText([e[1] for e in self.nzlsr+self.rowsr if e[0]==repsg][0])
        
        #epsgedit.setText([e for e in self.nzlsr+self.rowsr if re.match('^\s*(\d+).*',e).group(1)==repsg][0])
        
        #To/From Dates
        if LU.assessNone(rfd):
            self.fromdateedit.setDate(QDate(int(rfd[0:4]),int(rfd[5:7]),int(rfd[8:10])))
        else:
            early = DataStore.EARLIEST_INIT_DATE
            self.fromdateedit.setDate(QDate(int(early[0:4]),int(early[5:7]),int(early[8:10])))
            
        if LU.assessNone(rtd):
            self.todateedit.setDate(QDate(int(rtd[0:4]),int(rtd[5:7]),int(rtd[8:10]))) 
        else:
            today = DataStore.getCurrent()
            self.todateedit.setDate(QDate(int(today[0:4]),int(today[5:7]),int(today[8:10])))
            
        #Internal/External CheckBox
#        if LU.assessNone(rint):
#            self.internalTrigger.setChecked(rint.lower()==DataStore.CONF_INT)
#        else:
#            self.internalTrigger.setChecked(DataStore.DEFAULT_CONF==DataStore.CONF_INT)
        
        
    def getConfiguredDestinations(self):
        defml = ['',]+DataStore.DRIVER_NAMES.values()
        return [d for d in self.parent.gpr.getDestinations() if d in defml]
        
    def doEPSGEnable(self):
        self.epsgcombo.setEnabled(self.epsgenable.isChecked())
        
    def doFromDateEnable(self):
        self.fromdateedit.setEnabled(self.fromdateenable.isChecked())
          
    def doToDateEnable(self):
        self.todateedit.setEnabled(self.todateenable.isChecked())  
          
    def readParameters(self):
        '''Read values out of dialogs'''
        destination = LU.assessNone(str(self.destlist[self.destcombo.currentIndex()]))
        #lgindex = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgindex = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #NB need to test for None explicitly since zero is a valid index
        lgval = self.parent.confconn.lglist[lgindex][1] if LU.assessNone(lgindex) else None       
        #uconf = LU.standardiseUserConfigName(str(self.confcombo.lineEdit().text()))
        #uconf = str(self.confcombo.lineEdit().text())
        uconf = str(self.cflist[self.confcombo.currentIndex()])
        ee = self.epsgenable.isChecked()
        epsg = None if ee is False else re.match('^\s*(\d+).*',str(self.epsgcombo.lineEdit().text())).group(1)
        fe = self.fromdateenable.isChecked()
        te = self.todateenable.isChecked()
        fd = None if fe is False else str(self.fromdateedit.date().toString('yyyy-MM-dd'))
        td = None if te is False else str(self.todateedit.date().toString('yyyy-MM-dd'))
        
        return destination,lgval,uconf,epsg,fe,te,fd,td
    
    def doInitClickAction(self):
        '''Initialise the LC on LC-button-click, action'''
        try:
            try:
                self.setStatus(self.STATUS.BUSY,'Opening Layer-Config Editor')  
                self.progressbar.setValue(0)
                self.parent.runLayerConfigAction()
            finally:
                self.setStatus(self.STATUS.IDLE,'Ready')
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Error in Layer-Config',str(sys.exc_info()))#e))
        
    def doCleanClickAction(self):
        '''Set clean anim and run clean'''
        #lgo = self.lgcombo.currentText().toUtf8().data()
        lgo = LQ.readWidgetText(self.lgcombo.currentText())
        
        try:
            self.setStatus(self.STATUS.CLEAN,'Running Clean '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(True)
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Clean of '+lgo,str(sys.exc_info()))#e))
        
    def doReplicateClickAction(self):
        '''Set busy anim and run repl'''
        lgo = self.lgcombo.currentText()#.toUtf8().data()#only used for error messages
        try:
            self.setStatus(self.STATUS.BUSY,'Running Replicate '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(False)
            ldslog.debug('TRPfinish')
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Replication of '+lgo,str(sys.exc_info()))#e))

    def runReplicationScript(self,clean=False):
        '''Run the layer/group repliction script'''
        destination,lgval,uconf,epsg,fe,te,fd,td = self.readParameters()
        uconf_path = LU.standardiseUserConfigName(uconf)
        destination_path = LU.standardiseLayerConfigName(destination)
        destination_driver = LU.standardiseDriverNames(destination)

        if not os.path.exists(uconf_path):
            self.userConfMessage(uconf_path)
            return
        elif not MainFileReader(uconf_path).hasSection(destination_driver):
            self.userConfMessage(uconf_path,destination_driver)
            return
        #-----------------------------------------------------
        #'destname','layer','uconf','group','epsg','fd','td','int'
     
        self.parent.gpr.write((destination_driver,lgval,uconf,epsg,fd,td))        
        ldslog.info(u'dest={0}, lg={1}, conf={2}, epsg={3}'.format(destination_driver,lgval,uconf,epsg))
        ldslog.info('fd={0}, td={1}, fe={2}, te={3}'.format(fd,td,fe,te))
        lgindex = self.parent.confconn.getLayerGroupIndex(lgval,col=1)
        #lorg = self.parent.confconn.lglist[lgindex][0]
        #----------don't need lorg in TP anymore but it is useful for sorting/counting groups
        #self.parent.confconn.tp.setLayerOrGroup(lorg)
        self.parent.confconn.tp.setLayerGroupValue(lgval)
        if self.fromdateenable.isChecked(): self.parent.confconn.tp.setFromDate(fd)
        if self.todateenable.isChecked(): self.parent.confconn.tp.setToDate(td)
        self.parent.confconn.tp.setUserConf(uconf)
        if self.epsgenable: self.parent.confconn.tp.setEPSG(epsg)
        
        #because clean state persists in TP
        if clean:
            self.parent.confconn.tp.setCleanConfig()
        else:
            self.parent.confconn.tp.clearCleanConfig()
        #(re)initialise the data source since uconf may have changed
        #>>#self.parent.confconn.tp.src = self.parent.confconn.initSourceWrapper()
        #--------------------------
        ###ep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        
        ###self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        ###ep = None
        #Open ProcessRunner and run with TP(proc)/self(gui) instances
        #HACK temp add of dest_drv to PR call
        try:
            #TODO. Test for valid LC first
            self.tpr = ProcessRunner(self,destination_driver)
        except Exception as e:
            ldslog.error('Cannot create ProcessRunner {}. NB Possible missing Layer Config {}'.format(str(e),destination_path))
            self.layerConfMessage(destination_path)
            return
        #If PR has been successfully created we must vave a valid dst    
        ldslog.debug('TRPstart')
        self.tpr.start()
        
#     def quitProcessRunner(self):
#         self.tpr.join()
#         self.tpr.quit()
#         self.trp = None

        
    def userConfMessage(self,uconf,secname=None):
        ucans = QMessageBox.warning(self, 'User Config Missing/Incomplete', 
                                'Specified User-Config file, '+str(uconf)+' does not exist' if secname is None else 'User-Config file does not contain '+str(secname)+' section', 
                                'Back','Initialise User Config')
        if not ucans:
            #Retry
            ldslog.warn('Retry specifying UC')
            #self.confcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset User Config Wizard')
        self.parent.runWizardAction()


    def layerConfMessage(self,dest):
        lcans = QMessageBox.warning(self, 'Layer Config Missing', 
                                'Required Layer-Config file, '+str(dest)+' does not exist', 
                                'Back','Run Layer Select')
        if not lcans:
            #Retry
            ldslog.warn('Retry specifying LC')
            #self.destcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset Layer Config')
        self.doInitClickAction()
예제 #42
0
class NotUsedAnalysisProgress(QDialog):
    " Progress of the not used analysis "

    Functions = 0
    Classes = 1
    Globals = 2

    def __init__(self, what, sourceModel, parent=None):
        QDialog.__init__(self, parent)

        if what not in [self.Functions, self.Classes, self.Globals]:
            raise Exception( "Unsupported unused analysis type: " + \
                             str( what ) )

        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what  # what is in source model
        self.__srcModel = sourceModel  # source model of globals or
        # functions or classes

        # Avoid pylint complains
        self.__progressBar = None
        self.__infoLabel = None
        self.__foundLabel = None
        self.__found = 0  # Number of found

        self.__createLayout()
        self.setWindowTitle(self.__formTitle())
        QTimer.singleShot(0, self.__process)
        return

    def keyPressEvent(self, event):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent(self, event)
        return

    def __formTitle(self):
        " Forms the progress dialog title "
        title = "Unused "
        if self.__what == self.Functions:
            title += 'function'
        elif self.__what == self.Classes:
            title += 'class'
        else:
            title += 'globlal variable'
        return title + " analysis"

    def __formInfoLabel(self, name):
        " Forms the info label "
        if self.__what == self.Functions:
            return 'Function: ' + name
        if self.__what == self.Classes:
            return 'Class: ' + name
        return 'Globlal variable: ' + name

    def __whatAsString(self):
        " Provides 'what' as string "
        if self.__what == self.Functions:
            return 'function'
        if self.__what == self.Classes:
            return 'class'
        return 'global variable'

    def __updateFoundLabel(self):
        " Updates the found label "
        text = "Found: " + str(self.__found) + " candidate"
        if self.__found != 1:
            text += "s"
        self.__foundLabel.setText(text)
        return

    def __createLayout(self):
        """ Creates the dialog layout """

        self.resize(450, 20)
        self.setSizeGripEnabled(True)

        verticalLayout = QVBoxLayout(self)

        # Note label
        noteLabel = QLabel( "<b>Note</b>: the analysis is " \
                            "suggestive and not precise. " \
                            "Use the results with caution.\n", self )
        verticalLayout.addWidget(noteLabel)

        # Info label
        self.__infoLabel = QLabel(self)
        verticalLayout.addWidget(self.__infoLabel)

        # Progress bar
        self.__progressBar = QProgressBar(self)
        self.__progressBar.setValue(0)
        self.__progressBar.setOrientation(Qt.Horizontal)
        verticalLayout.addWidget(self.__progressBar)

        # Found label
        self.__foundLabel = QLabel(self)
        verticalLayout.addWidget(self.__foundLabel)

        # Buttons
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Close)
        verticalLayout.addWidget(buttonBox)

        buttonBox.rejected.connect(self.__onClose)
        return

    def __onClose(self):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process(self):
        " Analysis process "

        self.__inProgress = True

        mainWindow = GlobalData().mainWindow
        editorsManager = mainWindow.editorsManagerWidget.editorsManager
        modified = editorsManager.getModifiedList(
            True)  # True - only project files
        if modified:
            modNames = [modItem[0] for modItem in modified]
            label = "File"
            if len(modified) >= 2:
                label += "s"
            label += ": "
            logging.warning( "The analisys is performed for the content of saved files. " \
                             "The unsaved modifications will not be taken into account. " \
                             + label + ", ".join( modNames ) )

        self.__updateFoundLabel()
        self.__progressBar.setRange(0,
                                    len(self.__srcModel.rootItem.childItems))
        QApplication.processEvents()
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        count = 0
        candidates = []
        for treeItem in self.__srcModel.rootItem.childItems:
            if self.__cancelRequest:
                break

            name = str(treeItem.data(0)).split('(')[0]
            path = os.path.realpath(treeItem.getPath())
            lineNumber = int(treeItem.data(2))
            absPosition = treeItem.sourceObj.absPosition

            count += 1
            self.__progressBar.setValue(count)
            self.__infoLabel.setText(self.__formInfoLabel(name))
            QApplication.processEvents()

            # Analyze the name
            found = False
            try:
                # True is for throwing exceptions
                locations = getOccurrences(path, absPosition, True)

                if len( locations ) == 1 and \
                   locations[ 0 ][ 1 ] == lineNumber:
                    found = True
                    index = getSearchItemIndex(candidates, path)
                    if index < 0:
                        widget = mainWindow.getWidgetForFileName(path)
                        if widget is None:
                            uuid = ""
                        else:
                            uuid = widget.getUUID()
                        newItem = ItemToSearchIn(path, uuid)
                        candidates.append(newItem)
                        index = len(candidates) - 1
                    candidates[index].addMatch(name, lineNumber)

            except Exception, exc:
                # There is nothing interesting with exceptions here.
                # It seems to me that rope throws them in case if the same item
                # is declared multiple times in a file. I also suspect that
                # exceptions may come up in case of syntactic errors.
                # So I just suppress them.
                pass

                #logging.warning( "Error detected while analysing " + \
                #                 self.__whatAsString() + " '" + name + \
                #                 "'. Message: " + str( exc ) )

            if found:
                self.__found += 1
                self.__updateFoundLabel()
            QApplication.processEvents()

        if self.__found == 0:
            # The analysis could be interrupted
            if not self.__cancelRequest:
                logging.info("No unused candidates found")
        else:
            mainWindow.displayFindInFiles("", candidates)

        QApplication.restoreOverrideCursor()
        self.__infoLabel.setText('Done')
        self.__inProgress = False

        self.accept()
        return
예제 #43
0
class FileItem(QTreeWidgetItem):

    cols = ['Filepath', 'Renamed Filepath']

    invalid_char_map = {':': ''}

    re_filename_episodes = [
        re.compile(r'.*[Ss](?P<season>\d{1,2})[\s\-_]*[Ee](?P<episode>\d{1,2}).*', re.I),
        re.compile(r'.*season\s*(?P<season>\d{1,2})[\s\-_]*episode\s*[Ee](?P<episode>\d{1,2}).*', re.I),
    ]

    re_filepath_episodes = [
        re.compile(r'.*season\s*(?P<season>\d{1,2})\\(?:season\s*\d{1,2}[\s\-_]*)?(?:episode|ep\.?|e)\s*(?P<episode>\d{1,2}).*', re.I),
    ]

    def __init__(self, parent, filepath, mediaman):
        super(FileItem, self).__init__(parent)
        self._renamed = False
        self.mediaman = mediaman
        self.filepath = filepath
        self.renamed_filepath = None
        self.media_info = None
        self.episode_info = None
        self.thread = None
        self.pbar = None
        self.setText(0, self.filepath)
        self.send_thread()

    def send_thread(self):
        if self.thread is None:
            self.thread = FilepathSearchThread(self.treeWidget())
            self.thread.finished.connect(self.receive_thread)
        thread_ready = self.thread.wait(10000)
        if thread_ready:
            tree = self.treeWidget()
            self.pbar = QProgressBar(tree)
            self.pbar.setRange(0, 0)
            tree.setItemWidget(self, 1, self.pbar)
            self.thread.filepath = self.filepath
            self.thread.start()

    def receive_thread(self):
        self.media_info = self.thread.result
        self.pbar.reset()
        tree = self.treeWidget()
        tree.removeItemWidget(self, 1)
        self.pbar.deleteLater()
        self.refresh()


    def _replace_invalid_chars(self, text):
        for k, v in FileItem.invalid_char_map.items():
            if k in text:
                text = text.replace(k, v)
        return text

    def refresh(self):
        moviedir = self.mediaman.moviedir()
        tvdir = self.mediaman.tvdir()

        if self.media_info:
            title = self.media_info.get('title')
            title = self._replace_invalid_chars(title)
            year = self.media_info.get('year')

            filename, ext = os.path.splitext(os.path.basename(self.filepath))

            if self.episode_info or self.media_info.get('episodes'):
                if not self.episode_info:
                    episodes = self.media_info['episodes']
                    ep_match = None
                    for reg in FileItem.re_filename_episodes:
                        m = reg.search(filename)
                        if m:
                            ep_match = m.groupdict()
                            break
                    if not ep_match:
                        for reg in FileItem.re_filepath_episodes:
                            m = reg.search(self.filepath)
                            if m:
                                ep_match = m.groupdict()

                    if ep_match:
                        season, episode = int(ep_match['season']), int(ep_match['episode'])
                        for episode_info in episodes:
                            if (episode_info['season'], episode_info['episode']) == (season, episode):
                                self.episode_info = episode_info
                                break

                if self.episode_info:
                    self.renamed_filepath = ur'{tvdir}\{title}\Season{season:02d}\{title}.S{season:02d}E{episode:02d}.{episode_title}{ext}'.format(
                        tvdir=tvdir,
                        title=title,
                        year=year,
                        season=self.episode_info['season']  ,
                        episode=self.episode_info['episode'],
                        episode_title=self._replace_invalid_chars(self.episode_info['title']),
                        ext=ext,
                    )
                else:
                    self.renamed_filepath = ur'{tvdir}\{title}\Season00\{title}.S00E00.XXX{ext}'.format(
                        tvdir=tvdir,
                        title=title,
                        year=year,
                        ext=ext,
                    )


            else:
                self.renamed_filepath = ur'{moviedir}\{title} ({year})\{title}{ext}'.format(
                    moviedir=moviedir,
                    title=title,
                    year=year,
                    ext=ext
                )


            self.setText(1, self.renamed_filepath)
            if os.path.exists(self.renamed_filepath):
                self.setBackgroundColor(FileItem.cols.index('Renamed Filepath'), QColor(0, 255, 0, 100))