Exemple #1
0
    def on_radioButton_clicked(self, checked):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        global audio, record_t
        movie = QMovie(":/icon/icon/siri.gif")
        self.label_4.setMovie(movie)

        if checked:
            self.label_4.setStyleSheet("")
            movie.start()
            if self.thread_flag == 0:
                print "abcd"
                self.start_flag = 1
                record_t = MyThread(ui.record_wave, (ui, ),
                                    ui.record_wave.__name__)
                record_t.setDaemon(True)
                record_t.start()
                self.thread_flag = 1
        else:
            movie.stop()
            self.label_4.setStyleSheet(
                "border-image: url(:/icon/icon/siri.gif);")
            if self.thread_flag == 1:
                self.start_flag = 0
                self.thread_flag = 0
Exemple #2
0
class Throbber(QLabel):
    """A throbber."""
    def __init__(self):
        super(Throbber, self).__init__()
        self.setAlignment(Qt.AlignCenter)
        fname = multiplatform.get_path("encuentro/ui/media/throbber.gif")
        self._movie = QMovie(fname)
        self.setMovie(self._movie)

    def hide(self):
        """Overload to control the movie."""
        self._movie.stop()
        super(Throbber, self).hide()

    def show(self):
        """Overload to control the movie."""
        self._movie.start()
        super(Throbber, self).show()
Exemple #3
0
class Radar(QtGui.QLabel):

    def __init__(self, parent, radar, rect):
        global xscale, yscale
        self.rect = rect
        self.baseurl = self.mapurl(radar, rect, False)
        print "google map base url: "+self.baseurl
        self.mkurl = self.mapurl(radar, rect, True)
        self.wxurl = self.radarurl(radar, rect)
        QtGui.QLabel.__init__(self, parent)
        
        self.setObjectName("radar")
        self.setGeometry(rect)
        self.setStyleSheet("#radar { background-color: grey; }")    
        self.setAlignment(Qt.AlignCenter)

        self.wwx = QtGui.QLabel(self)
        self.wwx.setObjectName("wx")
        self.wwx.setStyleSheet("#wx { background-color: transparent; }")    
        self.wwx.setGeometry(0, 0, rect.width(), rect.height())

        self.wmk = QtGui.QLabel(self)
        self.wmk.setObjectName("mk")
        self.wmk.setStyleSheet("#mk { background-color: transparent; }")    
        self.wmk.setGeometry(0, 0, rect.width(), rect.height())

        self.wxmovie = QMovie()

    def mapurl(self, radar,rect,markersonly):
        #'https://maps.googleapis.com/maps/api/staticmap?maptype=hybrid&center='+rcenter.lat+','+rcenter.lng+'&zoom='+rzoom+'&size=300x275'+markersr;
        urlp = [];
        
        if len(ApiKeys.googleapi) > 0: urlp.append('key='+ApiKeys.googleapi)
        urlp.append('center='+str(radar['center'].lat)+','+str(radar['center'].lng))
        zoom = radar['zoom']
        rsize = rect.size()
        if rsize.width() > 640 or rsize.height() > 640:
            rsize = QtCore.QSize(rsize.width()/2,rsize.height()/2)
            zoom -= 1
        urlp.append('zoom='+str(zoom))
        urlp.append('size='+str(rsize.width())+'x'+str(rsize.height()))
        if markersonly:
            urlp.append('style=visibility:off') 
        else:
            urlp.append('maptype=hybrid')
        for marker in radar['markers']:
            marks = []
            for opts in marker:
                if opts != 'location':
                    marks.append(opts + ':' + marker[opts])
            marks.append(str(marker['location'].lat)+','+str(marker['location'].lng))
            urlp.append('markers='+'|'.join(marks))
        return 'http://maps.googleapis.com/maps/api/staticmap?'+'&'.join(urlp)

    def radarurl(self,radar,rect):
        #wuprefix = 'http://api.wunderground.com/api/';
        #wuprefix+wuapi+'/animatedradar/image.gif?maxlat='+rNE.lat+'&maxlon='+rNE.lng+'&minlat='+rSW.lat+'&minlon='+rSW.lng+wuoptionsr;
        #wuoptionsr = '&width=300&height=275&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1';
        rr = getCorners(radar['center'],radar['zoom'],rect.width(),rect.height())
        return (Config.wuprefix+ApiKeys.wuapi+'/animatedradar/image.gif'+
                '?maxlat='+str(rr['N'])+
                '&maxlon='+str(rr['E'])+
                '&minlat='+str(rr['S'])+
                '&minlon='+str(rr['W'])+
                '&width='+str(rect.width())+
                '&height='+str(rect.height())+
                '&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1&radar_bitmap=1&xnoclutter=1&xnoclutter_mask=1&cors=1'
                )
    
    def basefinished(self):
        if self.basereply.error() != QNetworkReply.NoError: return
        self.basepixmap = QPixmap()
        self.basepixmap.loadFromData(self.basereply.readAll())
        if self.basepixmap.size() != self.rect.size():
            self.basepixmap = self.basepixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.setPixmap(self.basepixmap)
    
    def mkfinished(self):
        if self.mkreply.error() != QNetworkReply.NoError: return
        self.mkpixmap = QPixmap()
        self.mkpixmap.loadFromData(self.mkreply.readAll())
        if self.mkpixmap.size() != self.rect.size():
            self.mkpixmap = self.mkpixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.wmk.setPixmap(self.mkpixmap)

    def wxfinished(self):
        if self.wxreply.error() != QNetworkReply.NoError: return
        self.wxdata = QtCore.QByteArray(self.wxreply.readAll())
        self.wxbuff = QtCore.QBuffer(self.wxdata)
        self.wxbuff.open(QtCore.QIODevice.ReadOnly)
        self.wxmovie = QMovie(self.wxbuff, 'GIF')
        self.wwx.setMovie( self.wxmovie)
        if self.parent().isVisible():
            self.wxmovie.start()

    def getwx(self):
        global manager
        self.wxreq = QNetworkRequest(QUrl(self.wxurl+'&rrrand='+str(time.time())))
        self.wxreply = manager.get(self.wxreq)
        QtCore.QObject.connect(self.wxreply, QtCore.SIGNAL("finished()"),self.wxfinished)

    def getbase(self):
        global manager
        self.basereq = QNetworkRequest(QUrl(self.baseurl))
        self.basereply = manager.get(self.basereq)
        QtCore.QObject.connect(self.basereply,QtCore.SIGNAL("finished()"),self.basefinished)

    def getmk(self):
        global manager
        self.mkreq = QNetworkRequest(QUrl(self.mkurl))
        self.mkreply = manager.get(self.mkreq)
        QtCore.QObject.connect(self.mkreply,QtCore.SIGNAL("finished()"),self.mkfinished)
        
    def start(self, interval=10*60*1000):
        self.getbase()
        self.getmk()
        self.getwx()
        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer,QtCore.SIGNAL("timeout()"), self.getwx)
        self.timer.start(interval)
       
    def wxstart(self):
        self.wxmovie.start()
        
    def wxstop(self):
        self.wxmovie.stop()
        
    def stop(self):
        try:
            self.timer.stop()
            self.timer = None
            if self.wxmovie: self.wxmovie.stop()
        except Exception:
            pass
Exemple #4
0
class Radar(QtGui.QLabel):
    def __init__(self, parent, radar, rect, myname):
        global xscale, yscale
        self.myname = myname
        self.rect = rect
        self.baseurl = self.mapurl(radar, rect, False)
        #print "google map base url: "+self.baseurl
        self.mkurl = self.mapurl(radar, rect, True)
        self.wxurl = self.radarurl(radar, rect)
        QtGui.QLabel.__init__(self, parent)
        self.interval = Config.radar_refresh * 60
        self.lastwx = 0

        self.setObjectName("radar")
        self.setGeometry(rect)
        self.setStyleSheet("#radar { background-color: grey; }")
        self.setAlignment(Qt.AlignCenter)

        self.wwx = QtGui.QLabel(self)
        self.wwx.setObjectName("wx")
        self.wwx.setStyleSheet("#wx { background-color: transparent; }")
        self.wwx.setGeometry(0, 0, rect.width(), rect.height())

        self.wmk = QtGui.QLabel(self)
        self.wmk.setObjectName("mk")
        self.wmk.setStyleSheet("#mk { background-color: transparent; }")
        self.wmk.setGeometry(0, 0, rect.width(), rect.height())

        self.wxmovie = QMovie()

    def mapurl(self, radar, rect, markersonly):
        #'https://maps.googleapis.com/maps/api/staticmap?maptype=hybrid&center='+rcenter.lat+','+rcenter.lng+'&zoom='+rzoom+'&size=300x275'+markersr;
        urlp = []

        if len(ApiKeys.googleapi) > 0: urlp.append('key=' + ApiKeys.googleapi)
        urlp.append('center=' + str(radar['center'].lat) + ',' +
                    str(radar['center'].lng))
        zoom = radar['zoom']
        rsize = rect.size()
        if rsize.width() > 640 or rsize.height() > 640:
            rsize = QtCore.QSize(rsize.width() / 2, rsize.height() / 2)
            zoom -= 1
        urlp.append('zoom=' + str(zoom))
        urlp.append('size=' + str(rsize.width()) + 'x' + str(rsize.height()))
        if markersonly:
            urlp.append('style=visibility:off')
        else:
            urlp.append('maptype=hybrid')
        for marker in radar['markers']:
            marks = []
            for opts in marker:
                if opts != 'location':
                    marks.append(opts + ':' + marker[opts])
            marks.append(
                str(marker['location'].lat) + ',' +
                str(marker['location'].lng))
            urlp.append('markers=' + '|'.join(marks))
        return 'http://maps.googleapis.com/maps/api/staticmap?' + '&'.join(
            urlp)

    def radarurl(self, radar, rect):
        #wuprefix = 'http://api.wunderground.com/api/';
        #wuprefix+wuapi+'/animatedradar/image.gif?maxlat='+rNE.lat+'&maxlon='+rNE.lng+'&minlat='+rSW.lat+'&minlon='+rSW.lng+wuoptionsr;
        #wuoptionsr = '&width=300&height=275&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1';
        rr = getCorners(radar['center'], radar['zoom'], rect.width(),
                        rect.height())
        return (
            Config.wuprefix + ApiKeys.wuapi + '/animatedradar/image.gif' +
            '?maxlat=' + str(rr['N']) + '&maxlon=' + str(rr['E']) +
            '&minlat=' + str(rr['S']) + '&minlon=' + str(rr['W']) + '&width=' +
            str(rect.width()) + '&height=' + str(rect.height()) +
            '&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1&radar_bitmap=1&xnoclutter=1&xnoclutter_mask=1&cors=1'
        )

    def basefinished(self):
        if self.basereply.error() != QNetworkReply.NoError: return
        self.basepixmap = QPixmap()
        self.basepixmap.loadFromData(self.basereply.readAll())
        if self.basepixmap.size() != self.rect.size():
            self.basepixmap = self.basepixmap.scaled(self.rect.size(),
                                                     Qt.KeepAspectRatio,
                                                     Qt.SmoothTransformation)
        self.setPixmap(self.basepixmap)

    def mkfinished(self):
        if self.mkreply.error() != QNetworkReply.NoError: return
        self.mkpixmap = QPixmap()
        self.mkpixmap.loadFromData(self.mkreply.readAll())
        if self.mkpixmap.size() != self.rect.size():
            self.mkpixmap = self.mkpixmap.scaled(self.rect.size(),
                                                 Qt.KeepAspectRatio,
                                                 Qt.SmoothTransformation)
        self.wmk.setPixmap(self.mkpixmap)

    def wxfinished(self):
        if self.wxreply.error() != QNetworkReply.NoError:
            print "get radar error " + self.myname + ":" + str(
                self.wxreply.error())
            self.lastwx = 0
            return
        print "radar map received:" + self.myname + ":" + time.ctime()
        self.wxmovie.stop()
        self.wxdata = QtCore.QByteArray(self.wxreply.readAll())
        self.wxbuff = QtCore.QBuffer(self.wxdata)
        self.wxbuff.open(QtCore.QIODevice.ReadOnly)
        mov = QMovie(self.wxbuff, 'GIF')
        print "radar map frame count:" + self.myname + ":" + str(
            mov.frameCount())
        if mov.frameCount() > 2:
            self.lastwx = time.time()
        else:
            # radar image retreval failed
            self.lastwx = 0
            # retry in 5 seconds
            QtCore.QTimer.singleShot(5 * 1000, self.getwx)
            return
        self.wxmovie = mov
        self.wwx.setMovie(self.wxmovie)
        if self.parent().isVisible():
            self.wxmovie.start()

    def getwx(self):
        global lastapiget
        i = 0.1
        # making sure there is at least 2 seconds between radar api calls
        lastapiget += 2
        if time.time() > lastapiget: lastapiget = time.time()
        else: i = lastapiget - time.time()
        print "get radar api call spacing oneshot get i=" + str(i)
        QtCore.QTimer.singleShot(i * 1000, self.getwx2)

    def getwx2(self):
        global manager
        try:
            if self.wxreply.isRunning(): return
        except Exception:
            pass
        print "getting radar map " + self.myname + ":" + time.ctime()
        self.wxreq = QNetworkRequest(
            QUrl(self.wxurl + '&rrrand=' + str(time.time())))
        self.wxreply = manager.get(self.wxreq)
        QtCore.QObject.connect(self.wxreply, QtCore.SIGNAL("finished()"),
                               self.wxfinished)

    def getbase(self):
        global manager
        self.basereq = QNetworkRequest(QUrl(self.baseurl))
        self.basereply = manager.get(self.basereq)
        QtCore.QObject.connect(self.basereply, QtCore.SIGNAL("finished()"),
                               self.basefinished)

    def getmk(self):
        global manager
        self.mkreq = QNetworkRequest(QUrl(self.mkurl))
        self.mkreply = manager.get(self.mkreq)
        QtCore.QObject.connect(self.mkreply, QtCore.SIGNAL("finished()"),
                               self.mkfinished)

    def start(self, interval=0):
        if interval > 0: self.interval = interval
        self.getbase()
        self.getmk()
        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.getwx)

    def wxstart(self):
        print "wxstart for " + self.myname
        if (self.lastwx == 0 or (self.lastwx + self.interval) < time.time()):
            self.getwx()
        # random 1 to 10 seconds added to refresh interval to spread the queries over time
        i = (self.interval + random.uniform(1, 10)) * 1000
        self.timer.start(i)
        self.wxmovie.start()
        QtCore.QTimer.singleShot(1000, self.wxmovie.start)

    def wxstop(self):
        print "wxstop for " + self.myname
        self.timer.stop()
        self.wxmovie.stop()

    def stop(self):
        try:
            self.timer.stop()
            self.timer = None
            if self.wxmovie: self.wxmovie.stop()
        except Exception:
            pass
Exemple #5
0
class Radar(QtGui.QLabel):

    def __init__(self, parent, radar, rect, myname):
        global xscale, yscale
        self.myname = myname
        self.rect = rect
        self.baseurl = self.mapurl(radar, rect, False)
        #print "google map base url: "+self.baseurl
        self.mkurl = self.mapurl(radar, rect, True)
        self.wxurl = self.radarurl(radar, rect)
        QtGui.QLabel.__init__(self, parent)
        self.interval = Config.radar_refresh*60
        self.lastwx = 0
        
        self.setObjectName("radar")
        self.setGeometry(rect)
        self.setStyleSheet("#radar { background-color: grey; }")    
        self.setAlignment(Qt.AlignCenter)

        self.wwx = QtGui.QLabel(self)
        self.wwx.setObjectName("wx")
        self.wwx.setStyleSheet("#wx { background-color: transparent; }")    
        self.wwx.setGeometry(0, 0, rect.width(), rect.height())

        self.wmk = QtGui.QLabel(self)
        self.wmk.setObjectName("mk")
        self.wmk.setStyleSheet("#mk { background-color: transparent; }")    
        self.wmk.setGeometry(0, 0, rect.width(), rect.height()) 

        self.wxmovie = QMovie()

    def mapurl(self, radar,rect,markersonly):
        #'https://maps.googleapis.com/maps/api/staticmap?maptype=hybrid&center='+rcenter.lat+','+rcenter.lng+'&zoom='+rzoom+'&size=300x275'+markersr;
        urlp = [];
        
        if len(ApiKeys.googleapi) > 0: urlp.append('key='+ApiKeys.googleapi)
        urlp.append('center='+str(radar['center'].lat)+','+str(radar['center'].lng))
        zoom = radar['zoom']
        rsize = rect.size()
        if rsize.width() > 640 or rsize.height() > 640:
            rsize = QtCore.QSize(rsize.width()/2,rsize.height()/2)
            zoom -= 1
        urlp.append('zoom='+str(zoom))
        urlp.append('size='+str(rsize.width())+'x'+str(rsize.height()))
        if markersonly:
            urlp.append('style=visibility:off') 
        else:
            urlp.append('maptype=hybrid')
        for marker in radar['markers']:
            marks = []
            for opts in marker:
                if opts != 'location':
                    marks.append(opts + ':' + marker[opts])
            marks.append(str(marker['location'].lat)+','+str(marker['location'].lng))
            urlp.append('markers='+'|'.join(marks))
        return 'http://maps.googleapis.com/maps/api/staticmap?'+'&'.join(urlp)

    def radarurl(self,radar,rect):
        #wuprefix = 'http://api.wunderground.com/api/';
        #wuprefix+wuapi+'/animatedradar/image.gif?maxlat='+rNE.lat+'&maxlon='+rNE.lng+'&minlat='+rSW.lat+'&minlon='+rSW.lng+wuoptionsr;
        #wuoptionsr = '&width=300&height=275&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1';
        rr = getCorners(radar['center'],radar['zoom'],rect.width(),rect.height())
        return (Config.wuprefix+ApiKeys.wuapi+'/animatedradar/image.gif'+
                '?maxlat='+str(rr['N'])+
                '&maxlon='+str(rr['E'])+
                '&minlat='+str(rr['S'])+
                '&minlon='+str(rr['W'])+
                '&width='+str(rect.width())+
                '&height='+str(rect.height())+
                '&newmaps=0&reproj.automerc=1&num=5&delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1&radar_bitmap=1&xnoclutter=1&xnoclutter_mask=1&cors=1'
                )
    
    def basefinished(self):
        if self.basereply.error() != QNetworkReply.NoError: return
        self.basepixmap = QPixmap()
        self.basepixmap.loadFromData(self.basereply.readAll())
        if self.basepixmap.size() != self.rect.size():
            self.basepixmap = self.basepixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.setPixmap(self.basepixmap)
    
    def mkfinished(self):
        if self.mkreply.error() != QNetworkReply.NoError: return
        self.mkpixmap = QPixmap()
        self.mkpixmap.loadFromData(self.mkreply.readAll())
        if self.mkpixmap.size() != self.rect.size():
            self.mkpixmap = self.mkpixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.wmk.setPixmap(self.mkpixmap)

    def wxfinished(self):
        if self.wxreply.error() != QNetworkReply.NoError:
            print "get radar error "+self.myname+":"+str(self.wxreply.error())
            self.lastwx = 0
            return
        print "radar map received:"+self.myname+":"+time.ctime()
	self.wxmovie.stop()
        self.wxdata = QtCore.QByteArray(self.wxreply.readAll())
        self.wxbuff = QtCore.QBuffer(self.wxdata)
        self.wxbuff.open(QtCore.QIODevice.ReadOnly)
        mov = QMovie(self.wxbuff, 'GIF')
        print "radar map frame count:"+self.myname+":"+str(mov.frameCount())
        if mov.frameCount() > 2:
            self.lastwx = time.time()
        else:
            # radar image retreval failed
            self.lastwx = 0
            # retry in 5 seconds
            QtCore.QTimer.singleShot(5*1000, self.getwx)
            return
        self.wxmovie = mov
        self.wwx.setMovie( self.wxmovie)
        if self.parent().isVisible():
            self.wxmovie.start()

    def getwx(self):
        global lastapiget
        i = 0.1
        # making sure there is at least 2 seconds between radar api calls
        lastapiget += 2
        if time.time() > lastapiget: lastapiget = time.time()
        else: i = lastapiget - time.time()
        print "get radar api call spacing oneshot get i="+str(i)
        QtCore.QTimer.singleShot(i*1000, self.getwx2)

    def getwx2(self):
        global manager
        try:
            if self.wxreply.isRunning(): return
        except Exception:
            pass
        print "getting radar map "+self.myname+":"+time.ctime()
        self.wxreq = QNetworkRequest(QUrl(self.wxurl+'&rrrand='+str(time.time())))
        self.wxreply = manager.get(self.wxreq)
        QtCore.QObject.connect(self.wxreply, QtCore.SIGNAL("finished()"),self.wxfinished)

    def getbase(self):
        global manager
        self.basereq = QNetworkRequest(QUrl(self.baseurl))
        self.basereply = manager.get(self.basereq)
        QtCore.QObject.connect(self.basereply,QtCore.SIGNAL("finished()"),self.basefinished)

    def getmk(self):
        global manager
        self.mkreq = QNetworkRequest(QUrl(self.mkurl))
        self.mkreply = manager.get(self.mkreq)
        QtCore.QObject.connect(self.mkreply,QtCore.SIGNAL("finished()"),self.mkfinished)
        
    def start(self, interval=0):
        if interval > 0: self.interval = interval
        self.getbase()
        self.getmk()
        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer,QtCore.SIGNAL("timeout()"), self.getwx)
       
    def wxstart(self):
        print "wxstart for "+self.myname
        if (self.lastwx == 0 or (self.lastwx+self.interval) < time.time()): self.getwx()
        # random 1 to 10 seconds added to refresh interval to spread the queries over time
        i = (self.interval+random.uniform(1,10))*1000
        self.timer.start(i)
        self.wxmovie.start()
        QtCore.QTimer.singleShot(1000, self.wxmovie.start)
        
    def wxstop(self):
        print "wxstop for "+self.myname
        self.timer.stop()
        self.wxmovie.stop()
        
    def stop(self):
        try:
            self.timer.stop()
            self.timer = None
            if self.wxmovie: self.wxmovie.stop()
        except Exception:
            pass
Exemple #6
0
class LearningWizard(QWizard, Ui_Wizard):
    def __init__(self, settings):
        QWizard.__init__(self)
        self.setupUi(self)
        self.settings = settings
        self.wizardPage3.pageCreated.connect(self.showSummary)
        self.wizardPage3.fullfilled = True

        self.wizardPage2.fullfilled = True
        self.errors = 0
        self.steps = 0
        self.delete_images_button.clicked.connect(self.deleteUserImages)
        self.add_files_button.clicked.connect(self.AddFiles)
        self.remove_file_button.clicked.connect(self.removeFile)
        self.save_button.clicked.connect(self.saveImgData)
        self.train_button.clicked.connect(self.trainOCR)
        self.ocr_button.clicked.connect(self.runOCR)
        self.next_button.clicked.connect(self.nextWord)
        self.prev_button.clicked.connect(self.previousWord)
        #self.add_screenshots.clicked.connect(self.AddFiles)
        #self.wizardPage2.pageCreated.connect(self.AnalyzeImg)
        #self.contrast = 0.0
        #self.img_fields = [self.g1,self.g2,self.g3,self.g4,self.g5,self.g6,self.g7,self.g8,self.g9,self.g10,self.g11,self.g12,self.g13,self.g14,self.g15,self.g16,self.g17,self.g18,self.g19,self.g20]
        #self.input_fields = [self.e1,self.e2,self.e3,self.e4,self.e5,self.e6,self.e7,self.e8,self.e9,self.e10,self.e11,self.e12,self.e13,self.e14,self.e15,self.e16,self.e17,self.e18,self.e19,self.e20]
        self.gviews = []
        self.ledits = []
        self.boxlist = []
        self.imglist = []
        self.charlist = []
        self.words = []
        self.boundaries = []
        self.wordcount = 0
        self.current = 0
        self.scene = None
        self.ratio_h = 1.0
        self.ratio_w = 1.0
        self.base = self.loadBase()
        self.user = self.loadUser()
        if not self.base is None:
            self.base_data_label.setText(self.getBaseData())
        if not self.user is None:
            self.delete_images_button.setEnabled(True)
            self.user_data_label.setText(self.getUserData())
        #self.resizeElements()
        
        #for index,item in zip(range(20), self.input_fields):
        #    item.textEdited.connect(partial(self.changeText, index))
        self.train_button.setEnabled(True)
        #self.grid = QGridLayout()
        #self.field_holder.addLayout(self.grid)
        
        
    def deleteUserImages(self):
        self.user = None
        path = self.settings.storage_path+os.sep+"user_training_data.pck"
        remove(path)
        self.user_data_label.setText("-")
        self.delete_images_button.setEnabled(False)
    
    def showSummary(self):
        summary = ""
        userdata = {}
        characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#']
        for word in self.words:
            for letter in word:
                if letter[1] in characters:
                    if letter[1] in userdata:
                        userdata[letter[1]] += 1
                    else:
                        userdata[letter[1]] = 1
        for key in characters:
            if key in userdata:
                summary += '"'+key+'"' +": " +str(userdata[key])+", "
                
        self.summary_label.setText(summary)
    
    def trainOCR(self):
        self.train_button.setEnabled(False)
        alldata = self.connectData()
        testnumbers = self.getRandomData(alldata,[',', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
        testletters = self.getRandomData(alldata,["'", ',', '-', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'])
        teststation = self.getRandomData(alldata,["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'])
        testlevel   = self.getRandomData(alldata,['*', '+', '#'])
        self.movie = QMovie(":/ico/loader.gif")
        self.loader.setMovie(self.movie)
        self.movie.start()
        self.numberstrainerthread = Trainer(self, "numbers", self.base, self.user, testnumbers, testletters, teststation, testlevel)
        self.letterstrainerthread = Trainer(self, "letters", self.base, self.user, testnumbers, testletters, teststation, testlevel)
        self.stationtrainerthread = Trainer(self, "station", self.base, self.user, testnumbers, testletters, teststation, testlevel)
        self.leveltrainerthread   = Trainer(self, "level"  , self.base, self.user, testnumbers, testletters, teststation, testlevel)
        QObject.connect(self.numberstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished)
        QObject.connect(self.letterstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished)
        QObject.connect(self.stationtrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished)
        QObject.connect(self.leveltrainerthread  , SIGNAL('finished(QString, int)'), self.stepFinished)
        #QObject.connect(self.trainerthread, SIGNAL('finishedall(int)'), self.trainingFinished)
        self.numberstrainerthread.execute()
        self.letterstrainerthread.execute()
        self.stationtrainerthread.execute()
        self.leveltrainerthread.execute()
        self.training_summary.setText("Training in progress")

    def trainingFinished(self):
        if self.errors < 3:
            self.training_summary.setText("The training sucessfully finished. Your OCR accuracy should be very high.")
        elif self.errors < 6:
            self.training_summary.setText("The training sucessfully finished. Your OCR accuracy should satisfactory. You might still increase it by repeating this process with other screenshots.")
        elif self.errors < 10:
            self.training_summary.setText("The training sucessfully finished. Your OCR accuracy is sufficient but not perfect. You should repeat this process with other screenshots.")
        else:
            self.training_summary.setText("The training finished. Your OCR accuracy is not sufficient. You should repeat this process with other screenshots.")
        
    def stepFinished(self, value, error):
        self.steps += 1
        self.details.append(value+"\n")
        self.errors += error
        if self.steps == 3:
            self.trainingFinished()
            self.movie.stop()
            self.loader.clear()
    
    def connectData(self):
        connected = {}
        characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#']
        
        if self.user is None:
            self.user = {}
        if self.base is None:
            self.base = {}
            

        for char in characters:
            if char in self.base and char in self.user:
                connected[char] = self.base[char]+self.user[char]
            elif char in self.base:
                connected[char] = self.base[char]
            elif char in self.user:
                connected[char] = self.user[char]
        return connected
        
    def getRandomData(self, data, characters):
        self.testsamples = {}
        samples = 30
        
        for char in characters:
            amount = len(data[char])/400
            if amount > samples:
                picks = random.sample(range(amount), samples)
            else:
                picks = random.sample(range(amount), amount)
                
            temp = bitarray()
            for pick in picks:
                temp += data[char][pick*400:pick*400+400]
                
            self.testsamples[char] = temp
                
        return self.testsamples
    
    def saveImgData(self):
        characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#']
        
        if self.user is None:
            self.user = {}
            
        for word in self.words:
            for letter in word:
                if letter[1] in characters:
                    data = bitarray()
                    image = cv2.resize(letter[0], (20, 20))
                    ret,image = cv2.threshold(image,250,255,cv2.THRESH_BINARY)
                    for row in image:
                        for cell in row:
                            if cell == 255:
                                data.append(True)
                            else:
                                data.append(False)
                    if letter[1] in self.user:
                        self.user[letter[1]] += data
                    else:
                        self.user[letter[1]] = data
                    
        path = self.settings.storage_path+os.sep+"user_training_data.pck"
        file = gzip.GzipFile(path, 'wb')
        pickle.dump(self.user, file,-1)
        file.close()
        
        self.save_button.setEnabled(False)
        self.train_button.setEnabled(True)
                                
        
    
    def changeText(self, index):
        #print index
        self.words[self.current][index][1] = unicode(self.ledits[index].text())
    
    def getBaseData(self):
        text = ""
        keys = []
        for key in self.base:
            keys.append(key)
        keys.sort()
        for key in keys:
            text += key + ": " + str(len(self.base[key])/400)+", "
        #print keys
        return text
        
    def getUserData(self):
        text = ""
        keys = []
        for key in self.user:
            keys.append(key)
        keys.sort()
        for key in keys:
            text += key + ": " + str(len(self.user[key])/400)+", "
        return text
    
    def loadBase(self):
        try:
            path = self.settings.app_path+os.sep+"trainingdata"+os.sep+"base_training_data.pck"
            file = gzip.GzipFile(path, 'rb')
            letters = pickle.load(file)
            file.close()
            return letters
        except:
            return None
        
    def loadUser(self):
        try:
            path = self.settings.storage_path+os.sep+"user_training_data.pck"
            file = gzip.GzipFile(path, 'rb')
            letters = pickle.load(file)
            file.close()
            return letters
        except:
            return None
    
    def removeFile(self):
        item = self.file_list.currentItem()
        self.file_list.takeItem(self.file_list.currentRow())
        del item
    
    def AddFiles(self):
        if self.settings["native_dialog"]:
                files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir'])
        else:
            files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir'], options = QFileDialog.DontUseNativeDialog)

        if files == []:
            return
        first_item = None
        counter = 0
        for file in files:
            file1 = unicode(file).encode(sys.getfilesystemencoding())
            item = CustomQListWidgetItem(split(file1)[1], file1, self.settings)
            if first_item == None:
                first_item = item
            self.file_list.addItem(item)
            counter+=1
    """        
    def resizeElements(self):
        fields = self.input_fields
        for field in fields:
            field.setMinimumSize(QSize(0, self.settings['input_size']))
            field.setMaximumSize(QSize(16777215, self.settings['input_size']))
        canvases = self.img_fields
        for canvas in canvases:
            canvas.setMinimumSize(QSize(0, self.settings['snippet_size']))
            canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size']))
    """        
    def runOCR(self):
        self.add_files_button.setEnabled(False)
        self.remove_file_button.setEnabled(False)
        self.ocr_button.setEnabled(False)
        self.file_list.setEnabled(False)
        self.repaint()
        self.current_image = 0
        self.results = []
        self.images = []
        self.prev = []
        self.marketoffset = []
        self.stationoffset = []
        files = self.file_list.count()
        for i in xrange(files):
            self.file_list.setCurrentRow(i)
            item = self.file_list.currentItem()
            color_image = item.loadColorImage()
            preview_image = item.addTestImage(color_image)
            self.images.append(color_image)
            self.prev.append(preview_image)
            #cv2.imshow("x", color_image)
            #cv2.waitKey(0)
            #
            #images.append(preview_image)
            #self.setPreviewImage(preview_image)
            #return
            self.stationoffset.append(item.ocr_areas.station_name)
            self.marketoffset.append(item.ocr_areas.market_table)
            current_result = OCR(color_image, item.ocr_areas, self.settings["ocr_language"], item, levels = False, levenshtein = False)
            
            self.results.append(current_result)
        self.allBoxes()
        #print len(self.words)
        #print self.words[1]
        self.next_button.setEnabled(True)
        self.prev_button.setEnabled(False)
        self.showSet()
        self.notifier.setText("You did not check every word yet.")

    
    def showSet(self):
        #self.snippet_preview
        
        bound = self.boundaries[self.current]
        #print self.current
        #print bound[1]
        image = self.images[bound[0]][bound[1][1]-2:bound[1][3]+3,bound[1][0]-2:bound[1][2]+2]
        self.drawSnippet(self.snippet_preview, image)
        for gview in self.gviews:
            self.grid.removeWidget(gview)
            gview.deleteLater()
            gview = None
        for ledit in self.ledits:
            self.grid.removeWidget(ledit)
            ledit.deleteLater()
            ledit = None
        self.gviews = []
        self.ledits = []
        letters = len(self.words[self.current])
        for i in range(letters):
            gview = QGraphicsView()
            self.grid.addWidget(gview,0,i)
            self.gviews.append(gview)
            gview.setMaximumSize(50, self.settings['snippet_size'])
            gview.setVerticalScrollBarPolicy(1)
            gview.setHorizontalScrollBarPolicy(1)
            self.drawSnippet(gview, self.words[self.current][i][0])
            
            ledit = QLineEdit()
            self.grid.addWidget(ledit,1,i)
            self.ledits.append(ledit)
            ledit.setMaximumSize(50, self.settings['input_size'])
            ledit.setAlignment(Qt.AlignHCenter)
            ledit.setText(self.words[self.current][i][1])
            
            for index,item in zip(range(50), self.ledits):
                item.textEdited.connect(partial(self.changeText, index))
        self.repaint()
        """
        pictures = len(self.img_fields)
        if pictures < len(self.imglist)-((self.current-1)*20):
            for i in range(20):
                if len(self.imglist) > (self.current*20)+i:
                    self.drawSnippet(self.img_fields[i], self.imglist[(self.current*20)+i])
                    self.input_fields[i].setText(self.charlist[(self.current*20)+i])
                else:
                    self.cleanSnippet(self.img_fields[i])
                    self.input_fields[i].setText("")
                    self.wizardPage2.fullfilled = True
                    self.wizardPage2.completeChanged.emit()
        """
            
    
    def previousWord(self):
        if self.current > 0:
            self.current -= 1
            self.showSet()
        
        self.next_button.setEnabled(True)
        
        if self.current == 0:
            self.prev_button.setEnabled(False)
        else:
            self.prev_button.setEnabled(True)
       
    def nextWord(self):
        #print self.maxcount
        if self.current < self.wordcount-1:
            self.current += 1
            self.showSet()
            
        self.prev_button.setEnabled(True)
            
        if self.current == self.wordcount-1:
            self.next_button.setEnabled(False)
            self.notifier.setText("You checked every word now. If you corrected every letter continue to next page.")
        else:
            self.next_button.setEnabled(True)
            
    def cleanSnippet(self, graphicsview):
        scene = QGraphicsScene()
        graphicsview.setScene(scene)
        
    def drawOCRPreview(self):
        factor = 1.0
        img = self.prev[0]
        
        old_h = img.height()
        old_w = img.width()
        
        pix = img.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        
        new_h = pix.height()
        new_w = pix.width()
        
        self.ratio_h = old_h/float(new_h)
        self.ratio_w = old_w/float(new_w)
        
        self.scene = QGraphicsScene()
        self.scene.addPixmap(pix)
        #self.scene.addPixmap(img)
        
        self.previewRects = []

        pen = QPen(Qt.yellow)
        redpen = QPen(Qt.red)
        bluepen = QPen(Qt.blue)
        greenpen = QPen(Qt.green)
        
        #for box in self.boxes():
        #    rect = self.addRect(self.scene, box, ratio_w, ratio_h, pen)
        #    self.previewRects.append(rect)
        rect = self.addRect(self.scene, self.boxlist[0], self.ratio_w, self.ratio_h, pen)
        self.previewRects.append(rect)
        self.previewSetScene(self.scene)

    
    def drawSnippet(self, graphicsview, snippet):
        """Draw single result item to graphicsview"""
        try:
            h, w = snippet.shape
        except:
            h, w, c = snippet.shape
        if h < 1 or w <1:
            return
        processedimage = array2qimage(snippet)
        pix = QPixmap()
        pix.convertFromImage(processedimage)
        pix = pix.scaled(graphicsview.width(), graphicsview.height()-1, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        scene = QGraphicsScene()
        scene.addPixmap(pix)
        graphicsview.setScene(scene)
        graphicsview.show()
    
    def addRect(self, scene, item, ratio_w, ratio_h, pen):
        """Adds a rectangle to scene and returns it."""
        rect = scene.addRect((item[0])/ratio_w , (item[2])/ratio_h,
                              item[1]/ratio_w, item[3]/ratio_h, pen)
        return rect
    
    def allBoxes(self):
        for i in range(self.file_list.count()):
            self.file_list.setCurrentRow(i)
            current = self.file_list.currentItem()
            
            res = self.results[i].station.name
            cres = self.results[i]
            self.charlist += list(res.value.replace(" ", "").upper())
            
            text = res.value.replace(" ", "")
            imgcount = len(self.results[i].station.name.units)
            charcount = len(text)
            word = []
            
            for j in range(imgcount):
                if j < charcount:
                    char = text[j]
                else:
                    char = ""
                unit = self.results[i].station.name.units[j]
                image = cres.station_img[unit[2]:unit[3]+1,unit[0]:unit[1]]
                #cv2.imshow("x", image)
                #cv2.waitKey(0)
                h = res.h
                if len(image) > 0:
                    if ((h*1.0)/len(image[0])) > 3:
                        y1 = res.y1
                        if y1 < 0:
                            y1 = 0
                        image = cres.station_img[y1:unit[3], unit[0]:unit[1]]
                        border = (h - len(image[0]))/2
                        image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255))

                    if len(image) < h/2.0:
                        y1 = res.y1
                        if y1 < 0:
                            y1 = 0
                        image = cres.station_img[y1:res.y2, unit[0]:unit[1]]
                        border = (h - len(image[0]))/2
                        image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255))
                    
                    th, tw = image.shape
                    if th < 1 or tw < 1:
                        image = np.ones((10,10,1), dtype=np.uint8) * 255
                    self.imglist.append(image)
                    
                word.append([image, char])
                
            self.words.append(word)
            self.boundaries.append([i, [res.box[0]+self.stationoffset[i][0][0],
                                        res.box[1]+self.stationoffset[i][0][1],
                                        res.box[2]+self.stationoffset[i][0][0],
                                        res.box[3]+self.stationoffset[i][0][1]]])

            for line in self.results[i].commodities:
                for item in line.items:
                    if not item is None:
                        text = item.value.replace(" ", "")
                        imgcount = len(item.units)
                        charcount = len(text)
                        word = []
                    
                        self.charlist += list(item.value.replace(" ", "").upper())
                        for j in range(imgcount):
                            if j < charcount:
                                char = text[j]
                            else:
                                char = ""
                            unit = item.units[j]
                            self.boxlist.append([unit[0]+current.market_offset[0],unit[1]-unit[0],
                                            unit[2]+current.market_offset[1],unit[3]-unit[2]])
                                           
                            image = cres.commodities_img[unit[2]:unit[3]+1,unit[0]:unit[1]]
                            h = line.h
                            if len(image) > 0:
                                if ((h*1.0)/len(image[0])) > 3:
                                    y1 = line.y1 if line.y1 >= 0 else 0
                                    if y1 < 0:
                                        y1 = 0
                                    image = cres.commodities_img[y1:unit[3], unit[0]:unit[1]]
                                    if image.shape[0] > 0 and image.shape[1] > 0:
                                        border = (h - len(image[0]))/2
                                        image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255))

                                if len(image) < h/2.0:
                                    y1 = line.y1 if line.y1 >= 0 else 0
                                    if y1 < 0:
                                        y1 = 0
                                    image = cres.commodities_img[y1:line.y2, unit[0]:unit[1]]
                                    if image.shape[0] > 0 and image.shape[1] > 0:
                                        border = (h - len(image[0]))/2
                                        image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255))
                                
                                th, tw = image.shape
                                if th < 1 or tw < 1:
                                    image = np.ones((10,10,1), dtype=np.uint8) * 255
                                self.imglist.append(image)
                            
                            word.append([image, char])
                
                        self.words.append(word)
                        self.boundaries.append([i, [item.box[0]+self.marketoffset[i][0][0],
                                                    item.box[1]+self.marketoffset[i][0][1],
                                                    item.box[2]+self.marketoffset[i][0][0],
                                                    item.box[3]+self.marketoffset[i][0][1]]])
        self.wordcount = len(self.words)
        #self.maxcount = len(self.imglist)/20
        
    
    def setPreviewImage(self, image):
        """Show image in self.preview."""
        #factor = self.factor.value()
        factor = 1.0
        pix = image.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        scene = QGraphicsScene()
        scene.addPixmap(pix)
        self.previewSetScene(scene)
        
    def previewSetScene(self, scene):
        """Shows scene in preview"""
        self.preview.setScene(scene)
        self.preview.show()
Exemple #7
0
class LearningWizard(QWizard, Ui_Wizard):
    def __init__(self, settings):
        QWizard.__init__(self)
        self.setupUi(self)
        self.settings = settings
        self.wizardPage3.pageCreated.connect(self.showSummary)
        self.wizardPage3.fullfilled = True

        self.wizardPage2.fullfilled = True
        self.errors = 0
        self.steps = 0
        self.delete_images_button.clicked.connect(self.deleteUserImages)
        self.add_files_button.clicked.connect(self.AddFiles)
        self.remove_file_button.clicked.connect(self.removeFile)
        self.save_button.clicked.connect(self.saveImgData)
        self.train_button.clicked.connect(self.trainOCR)
        self.ocr_button.clicked.connect(self.runOCR)
        self.next_button.clicked.connect(self.nextWord)
        self.prev_button.clicked.connect(self.previousWord)
        #self.add_screenshots.clicked.connect(self.AddFiles)
        #self.wizardPage2.pageCreated.connect(self.AnalyzeImg)
        #self.contrast = 0.0
        #self.img_fields = [self.g1,self.g2,self.g3,self.g4,self.g5,self.g6,self.g7,self.g8,self.g9,self.g10,self.g11,self.g12,self.g13,self.g14,self.g15,self.g16,self.g17,self.g18,self.g19,self.g20]
        #self.input_fields = [self.e1,self.e2,self.e3,self.e4,self.e5,self.e6,self.e7,self.e8,self.e9,self.e10,self.e11,self.e12,self.e13,self.e14,self.e15,self.e16,self.e17,self.e18,self.e19,self.e20]
        self.gviews = []
        self.ledits = []
        self.boxlist = []
        self.imglist = []
        self.charlist = []
        self.words = []
        self.boundaries = []
        self.wordcount = 0
        self.current = 0
        self.scene = None
        self.ratio_h = 1.0
        self.ratio_w = 1.0
        self.base = self.loadBase()
        self.user = self.loadUser()
        if not self.base is None:
            self.base_data_label.setText(self.getBaseData())
        if not self.user is None:
            self.delete_images_button.setEnabled(True)
            self.user_data_label.setText(self.getUserData())
        #self.resizeElements()

        #for index,item in zip(range(20), self.input_fields):
        #    item.textEdited.connect(partial(self.changeText, index))
        self.train_button.setEnabled(True)
        #self.grid = QGridLayout()
        #self.field_holder.addLayout(self.grid)

    def deleteUserImages(self):
        self.user = None
        path = self.settings.storage_path + os.sep + "user_training_data.pck"
        remove(path)
        self.user_data_label.setText("-")
        self.delete_images_button.setEnabled(False)

    def showSummary(self):
        summary = ""
        userdata = {}
        characters = [
            "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z'
        ]
        for word in self.words:
            for letter in word:
                if letter[1] in characters:
                    if letter[1] in userdata:
                        userdata[letter[1]] += 1
                    else:
                        userdata[letter[1]] = 1
        for key in characters:
            if key in userdata:
                summary += '"' + key + '"' + ": " + str(userdata[key]) + ", "

        self.summary_label.setText(summary)

    def trainOCR(self):
        self.train_button.setEnabled(False)
        alldata = self.connectData()
        testnumbers = self.getRandomData(
            alldata,
            [',', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
        testletters = self.getRandomData(alldata, [
            "'", ',', '-', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z'
        ])
        teststation = self.getRandomData(alldata, [
            "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
            'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
            'Y', 'Z'
        ])
        self.movie = QMovie(":/ico/loader.gif")
        self.loader.setMovie(self.movie)
        self.movie.start()
        self.numberstrainerthread = Trainer(self, "numbers", self.base,
                                            self.user, testnumbers,
                                            testletters, teststation)
        self.letterstrainerthread = Trainer(self, "letters", self.base,
                                            self.user, testnumbers,
                                            testletters, teststation)
        self.stationtrainerthread = Trainer(self, "station", self.base,
                                            self.user, testnumbers,
                                            testletters, teststation)
        QObject.connect(self.numberstrainerthread,
                        SIGNAL('finished(QString, int)'), self.stepFinished)
        QObject.connect(self.letterstrainerthread,
                        SIGNAL('finished(QString, int)'), self.stepFinished)
        QObject.connect(self.stationtrainerthread,
                        SIGNAL('finished(QString, int)'), self.stepFinished)
        #QObject.connect(self.trainerthread, SIGNAL('finishedall(int)'), self.trainingFinished)
        self.numberstrainerthread.execute()
        self.letterstrainerthread.execute()
        self.stationtrainerthread.execute()
        self.training_summary.setText("Training in progress")

    def trainingFinished(self):
        if self.errors < 3:
            self.training_summary.setText(
                "The training sucessfully finished. Your OCR accuracy should be very high."
            )
        elif self.errors < 6:
            self.training_summary.setText(
                "The training sucessfully finished. Your OCR accuracy should satisfactory. You might still increase it by repeating this process with other screenshots."
            )
        elif self.errors < 10:
            self.training_summary.setText(
                "The training sucessfully finished. Your OCR accuracy is sufficient but not perfect. You should repeat this process with other screenshots."
            )
        else:
            self.training_summary.setText(
                "The training finished. Your OCR accuracy is not sufficient. You should repeat this process with other screenshots."
            )

    def stepFinished(self, value, error):
        self.steps += 1
        self.details.append(value + "\n")
        self.errors += error
        if self.steps == 3:
            self.trainingFinished()
            self.movie.stop()
            self.loader.clear()

    def connectData(self):
        connected = {}
        characters = [
            "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z'
        ]

        if self.user is None:
            self.user = {}
        if self.base is None:
            self.base = {}

        for char in characters:
            if char in self.base and char in self.user:
                connected[char] = self.base[char] + self.user[char]
            elif char in self.base:
                connected[char] = self.base[char]
            elif char in self.user:
                connected[char] = self.user[char]
        return connected

    def getRandomData(self, data, characters):
        self.testsamples = {}
        samples = 30

        for char in characters:
            amount = len(data[char]) / 400
            if amount > samples:
                picks = random.sample(range(amount), samples)
            else:
                picks = random.sample(range(amount), amount)

            temp = bitarray()
            for pick in picks:
                temp += data[char][pick * 400:pick * 400 + 400]

            self.testsamples[char] = temp

        return self.testsamples

    def saveImgData(self):
        characters = [
            "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z'
        ]

        if self.user is None:
            self.user = {}

        for word in self.words:
            for letter in word:
                if letter[1] in characters:
                    data = bitarray()
                    image = cv2.resize(letter[0], (20, 20))
                    ret, image = cv2.threshold(image, 250, 255,
                                               cv2.THRESH_BINARY)
                    for row in image:
                        for cell in row:
                            if cell == 255:
                                data.append(True)
                            else:
                                data.append(False)
                    if letter[1] in self.user:
                        self.user[letter[1]] += data
                    else:
                        self.user[letter[1]] = data

        path = self.settings.storage_path + os.sep + "user_training_data.pck"
        file = gzip.GzipFile(path, 'wb')
        pickle.dump(self.user, file, -1)
        file.close()

        self.save_button.setEnabled(False)
        self.train_button.setEnabled(True)

    def changeText(self, index):
        #print index
        self.words[self.current][index][1] = unicode(self.ledits[index].text())

    def getBaseData(self):
        text = ""
        keys = []
        for key in self.base:
            keys.append(key)
        keys.sort()
        for key in keys:
            text += key + ": " + str(len(self.base[key]) / 400) + ", "
        #print keys
        return text

    def getUserData(self):
        text = ""
        keys = []
        for key in self.user:
            keys.append(key)
        keys.sort()
        for key in keys:
            text += key + ": " + str(len(self.user[key]) / 400) + ", "
        return text

    def loadBase(self):
        try:
            path = self.settings.app_path + os.sep + "trainingdata" + os.sep + "base_training_data.pck"
            file = gzip.GzipFile(path, 'rb')
            letters = pickle.load(file)
            file.close()
            return letters
        except:
            return None

    def loadUser(self):
        try:
            path = self.settings.storage_path + os.sep + "user_training_data.pck"
            file = gzip.GzipFile(path, 'rb')
            letters = pickle.load(file)
            file.close()
            return letters
        except:
            return None

    def removeFile(self):
        item = self.file_list.currentItem()
        self.file_list.takeItem(self.file_list.currentRow())
        del item

    def AddFiles(self):
        if self.settings["native_dialog"]:
            files = QFileDialog.getOpenFileNames(
                self, "Open", self.settings['screenshot_dir'])
        else:
            files = QFileDialog.getOpenFileNames(
                self,
                "Open",
                self.settings['screenshot_dir'],
                options=QFileDialog.DontUseNativeDialog)

        if files == []:
            return
        first_item = None
        counter = 0
        for file in files:
            file1 = unicode(file).encode(sys.getfilesystemencoding())
            item = CustomQListWidgetItem(split(file1)[1], file1, self.settings)
            if first_item == None:
                first_item = item
            self.file_list.addItem(item)
            counter += 1

    """        
    def resizeElements(self):
        fields = self.input_fields
        for field in fields:
            field.setMinimumSize(QSize(0, self.settings['input_size']))
            field.setMaximumSize(QSize(16777215, self.settings['input_size']))
        canvases = self.img_fields
        for canvas in canvases:
            canvas.setMinimumSize(QSize(0, self.settings['snippet_size']))
            canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size']))
    """

    def runOCR(self):
        self.add_files_button.setEnabled(False)
        self.remove_file_button.setEnabled(False)
        self.ocr_button.setEnabled(False)
        self.file_list.setEnabled(False)
        self.repaint()
        self.current_image = 0
        self.results = []
        self.images = []
        self.prev = []
        self.marketoffset = []
        self.stationoffset = []
        files = self.file_list.count()
        for i in xrange(files):
            self.file_list.setCurrentRow(i)
            item = self.file_list.currentItem()
            color_image = item.loadColorImage()
            preview_image = item.addTestImage(color_image)
            self.images.append(color_image)
            self.prev.append(preview_image)
            #cv2.imshow("x", color_image)
            #cv2.waitKey(0)
            #
            #images.append(preview_image)
            #self.setPreviewImage(preview_image)
            #return
            self.stationoffset.append(item.ocr_areas.station_name)
            self.marketoffset.append(item.ocr_areas.market_table)
            current_result = OCR(color_image,
                                 item.ocr_areas,
                                 self.settings["ocr_language"],
                                 item,
                                 levels=False,
                                 levenshtein=False)

            self.results.append(current_result)
        self.allBoxes()
        #print len(self.words)
        #print self.words[1]
        self.next_button.setEnabled(True)
        self.prev_button.setEnabled(False)
        self.showSet()
        self.notifier.setText("You did not check every word yet.")

    def showSet(self):
        #self.snippet_preview

        bound = self.boundaries[self.current]
        #print self.current
        #print bound[1]
        image = self.images[bound[0]][bound[1][1] - 2:bound[1][3] + 3,
                                      bound[1][0] - 2:bound[1][2] + 2]
        self.drawSnippet(self.snippet_preview, image)
        for gview in self.gviews:
            self.grid.removeWidget(gview)
            gview.deleteLater()
            gview = None
        for ledit in self.ledits:
            self.grid.removeWidget(ledit)
            ledit.deleteLater()
            ledit = None
        self.gviews = []
        self.ledits = []
        letters = len(self.words[self.current])
        for i in range(letters):
            gview = QGraphicsView()
            self.grid.addWidget(gview, 0, i)
            self.gviews.append(gview)
            gview.setMaximumSize(50, self.settings['snippet_size'])
            gview.setVerticalScrollBarPolicy(1)
            gview.setHorizontalScrollBarPolicy(1)
            self.drawSnippet(gview, self.words[self.current][i][0])

            ledit = QLineEdit()
            self.grid.addWidget(ledit, 1, i)
            self.ledits.append(ledit)
            ledit.setMaximumSize(50, self.settings['input_size'])
            ledit.setAlignment(Qt.AlignHCenter)
            ledit.setText(self.words[self.current][i][1])

            for index, item in zip(range(50), self.ledits):
                item.textEdited.connect(partial(self.changeText, index))
        self.repaint()
        """
        pictures = len(self.img_fields)
        if pictures < len(self.imglist)-((self.current-1)*20):
            for i in range(20):
                if len(self.imglist) > (self.current*20)+i:
                    self.drawSnippet(self.img_fields[i], self.imglist[(self.current*20)+i])
                    self.input_fields[i].setText(self.charlist[(self.current*20)+i])
                else:
                    self.cleanSnippet(self.img_fields[i])
                    self.input_fields[i].setText("")
                    self.wizardPage2.fullfilled = True
                    self.wizardPage2.completeChanged.emit()
        """

    def previousWord(self):
        if self.current > 0:
            self.current -= 1
            self.showSet()

        self.next_button.setEnabled(True)

        if self.current == 0:
            self.prev_button.setEnabled(False)
        else:
            self.prev_button.setEnabled(True)

    def nextWord(self):
        #print self.maxcount
        if self.current < self.wordcount - 1:
            self.current += 1
            self.showSet()

        self.prev_button.setEnabled(True)

        if self.current == self.wordcount - 1:
            self.next_button.setEnabled(False)
            self.notifier.setText(
                "You checked every word now. If you corrected every letter continue to next page."
            )
        else:
            self.next_button.setEnabled(True)

    def cleanSnippet(self, graphicsview):
        scene = QGraphicsScene()
        graphicsview.setScene(scene)

    def drawOCRPreview(self):
        factor = 1.0
        img = self.prev[0]

        old_h = img.height()
        old_w = img.width()

        pix = img.scaled(
            QSize(self.preview.size().width() * factor,
                  self.preview.size().height() * factor), Qt.KeepAspectRatio,
            Qt.SmoothTransformation)
        #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)

        new_h = pix.height()
        new_w = pix.width()

        self.ratio_h = old_h / float(new_h)
        self.ratio_w = old_w / float(new_w)

        self.scene = QGraphicsScene()
        self.scene.addPixmap(pix)
        #self.scene.addPixmap(img)

        self.previewRects = []

        pen = QPen(Qt.yellow)
        redpen = QPen(Qt.red)
        bluepen = QPen(Qt.blue)
        greenpen = QPen(Qt.green)

        #for box in self.boxes():
        #    rect = self.addRect(self.scene, box, ratio_w, ratio_h, pen)
        #    self.previewRects.append(rect)
        rect = self.addRect(self.scene, self.boxlist[0], self.ratio_w,
                            self.ratio_h, pen)
        self.previewRects.append(rect)
        self.previewSetScene(self.scene)

    def drawSnippet(self, graphicsview, snippet):
        """Draw single result item to graphicsview"""
        try:
            h, w = snippet.shape
        except:
            h, w, c = snippet.shape
        if h < 1 or w < 1:
            return
        processedimage = array2qimage(snippet)
        pix = QPixmap()
        pix.convertFromImage(processedimage)
        pix = pix.scaled(graphicsview.width(),
                         graphicsview.height() - 1, Qt.KeepAspectRatio,
                         Qt.SmoothTransformation)
        scene = QGraphicsScene()
        scene.addPixmap(pix)
        graphicsview.setScene(scene)
        graphicsview.show()

    def addRect(self, scene, item, ratio_w, ratio_h, pen):
        """Adds a rectangle to scene and returns it."""
        rect = scene.addRect((item[0]) / ratio_w, (item[2]) / ratio_h,
                             item[1] / ratio_w, item[3] / ratio_h, pen)
        return rect

    def allBoxes(self):
        for i in range(self.file_list.count()):
            self.file_list.setCurrentRow(i)
            current = self.file_list.currentItem()

            res = self.results[i].station.name
            cres = self.results[i]
            self.charlist += list(res.value.replace(" ", "").upper())

            text = res.value.replace(" ", "")
            imgcount = len(self.results[i].station.name.units)
            charcount = len(text)
            word = []

            for j in range(imgcount):
                if j < charcount:
                    char = text[j]
                else:
                    char = ""
                unit = self.results[i].station.name.units[j]
                image = cres.station_img[unit[2]:unit[3] + 1, unit[0]:unit[1]]
                #cv2.imshow("x", image)
                #cv2.waitKey(0)
                h = res.h
                if len(image) > 0:
                    if ((h * 1.0) / len(image[0])) > 3:
                        y1 = res.y1
                        if y1 < 0:
                            y1 = 0
                        image = cres.station_img[y1:unit[3], unit[0]:unit[1]]
                        border = (h - len(image[0])) / 2
                        image = cv2.copyMakeBorder(image,
                                                   0,
                                                   0,
                                                   border,
                                                   border,
                                                   cv2.BORDER_CONSTANT,
                                                   value=(255, 255, 255))

                    if len(image) < h / 2.0:
                        y1 = res.y1
                        if y1 < 0:
                            y1 = 0
                        image = cres.station_img[y1:res.y2, unit[0]:unit[1]]
                        border = (h - len(image[0])) / 2
                        image = cv2.copyMakeBorder(image,
                                                   0,
                                                   0,
                                                   border,
                                                   border,
                                                   cv2.BORDER_CONSTANT,
                                                   value=(255, 255, 255))

                    th, tw = image.shape
                    if th < 1 or tw < 1:
                        image = np.ones((10, 10, 1), dtype=np.uint8) * 255
                    self.imglist.append(image)

                word.append([image, char])

            self.words.append(word)
            self.boundaries.append([
                i,
                [
                    res.box[0] + self.stationoffset[i][0][0],
                    res.box[1] + self.stationoffset[i][0][1],
                    res.box[2] + self.stationoffset[i][0][0],
                    res.box[3] + self.stationoffset[i][0][1]
                ]
            ])

            for line in self.results[i].commodities:
                for item in line.items:
                    if not item is None:
                        text = item.value.replace(" ", "")
                        imgcount = len(item.units)
                        charcount = len(text)
                        word = []

                        self.charlist += list(
                            item.value.replace(" ", "").upper())
                        for j in range(imgcount):
                            if j < charcount:
                                char = text[j]
                            else:
                                char = ""
                            unit = item.units[j]
                            self.boxlist.append([
                                unit[0] + current.market_offset[0],
                                unit[1] - unit[0],
                                unit[2] + current.market_offset[1],
                                unit[3] - unit[2]
                            ])

                            image = cres.commodities_img[unit[2]:unit[3] + 1,
                                                         unit[0]:unit[1]]
                            h = line.h
                            if len(image) > 0:
                                if ((h * 1.0) / len(image[0])) > 3:
                                    y1 = line.y1 if line.y1 >= 0 else 0
                                    if y1 < 0:
                                        y1 = 0
                                    image = cres.commodities_img[
                                        y1:unit[3], unit[0]:unit[1]]
                                    if image.shape[0] > 0 and image.shape[
                                            1] > 0:
                                        border = (h - len(image[0])) / 2
                                        image = cv2.copyMakeBorder(
                                            image,
                                            0,
                                            0,
                                            border,
                                            border,
                                            cv2.BORDER_CONSTANT,
                                            value=(255, 255, 255))

                                if len(image) < h / 2.0:
                                    y1 = line.y1 if line.y1 >= 0 else 0
                                    if y1 < 0:
                                        y1 = 0
                                    image = cres.commodities_img[
                                        y1:line.y2, unit[0]:unit[1]]
                                    if image.shape[0] > 0 and image.shape[
                                            1] > 0:
                                        border = (h - len(image[0])) / 2
                                        image = cv2.copyMakeBorder(
                                            image,
                                            0,
                                            0,
                                            border,
                                            border,
                                            cv2.BORDER_CONSTANT,
                                            value=(255, 255, 255))

                                th, tw = image.shape
                                if th < 1 or tw < 1:
                                    image = np.ones(
                                        (10, 10, 1), dtype=np.uint8) * 255
                                self.imglist.append(image)

                            word.append([image, char])

                        self.words.append(word)
                        self.boundaries.append([
                            i,
                            [
                                item.box[0] + self.marketoffset[i][0][0],
                                item.box[1] + self.marketoffset[i][0][1],
                                item.box[2] + self.marketoffset[i][0][0],
                                item.box[3] + self.marketoffset[i][0][1]
                            ]
                        ])
        self.wordcount = len(self.words)
        #self.maxcount = len(self.imglist)/20

    def setPreviewImage(self, image):
        """Show image in self.preview."""
        #factor = self.factor.value()
        factor = 1.0
        pix = image.scaled(
            QSize(self.preview.size().width() * factor,
                  self.preview.size().height() * factor), Qt.KeepAspectRatio,
            Qt.SmoothTransformation)
        scene = QGraphicsScene()
        scene.addPixmap(pix)
        self.previewSetScene(scene)

    def previewSetScene(self, scene):
        """Shows scene in preview"""
        self.preview.setScene(scene)
        self.preview.show()
Exemple #8
0
class VisionneurImagePourEKD(QScrollArea):
	''' Classe pour l'affichage des images (avec des barres de
	défilement)'''
	def __init__(self, img=None):
		QScrollArea.__init__(self)

		# Déclaration du drapeau: a-t-on chargé un *.gif
		if img and os.path.splitext(img)[1]!=".gif":
			self.gif = 1
		else:
			self.gif = 0
		
		# Facteur de redimensionnement de l'image à afficher par rapport à la taille réelle de l'image
		self.factor = 1
		
		# Variables de paramètres
		self.modeTransformation=Qt.SmoothTransformation
		#self.modeTransformation=Qt.FastTransformation
		
		# widget qui contiendra l'image
		self.imageLabel = QLabel()
		self.imageLabel.setAlignment(Qt.AlignCenter)
		
		self.setBackgroundRole(QPalette.Dark)
		self.setWidget(self.imageLabel)
		# Indispensable pour ne pas avoir d'images tronquées, lors du chargement de nvll img
		self.setWidgetResizable(True)
		
		# Position du curseur dans le QScrollArea au moment du clic de la souris
		self.positionPresseeSourisIni = QPoint()
		# Position du point haut-gauche du QScrollArea par rapport au QPixMap entier au
		# moment du clic de la souris (par la suite appelée "position de la barre de défilement")
        	self.positionBarrePresseeSourisIni = QPoint()
		
		# Création du menu contextuel
		self.menuZoom=QMenu("Zoom")
		
		# Entrée zoom taille réelle
		self.menuTailleReelle=self.menuZoom.addAction(_(u'&Taille Réelle'))
		self.menuTailleReelle.setIcon(QIcon("Icones" + os.sep + "taillereelle.png"))
		self.connect(self.menuTailleReelle, SIGNAL("triggered()"), self.setTailleReelle)
		
		# Entrée zoom taille fenetre
		self.menuTailleFenetre=self.menuZoom.addAction(_(u'&Adapter à la fenêtre'))
		self.menuTailleFenetre.setIcon(QIcon("Icones" + os.sep + "fenetre.png"))
		self.connect(self.menuTailleFenetre, SIGNAL("triggered()"), self.setTailleFenetre)
	
		# Entrée zoom +
		self.menuZoomPlus=self.menuZoom.addAction(_(u'&Zoom Avant'))
		self.menuZoomPlus.setIcon(QIcon("Icones" + os.sep + "zoomplus.png"))
		self.connect(self.menuZoomPlus, SIGNAL("triggered()"), self.zoomAvant)
		
		# Entrée zoom - 
		self.menuZoomMoins=self.menuZoom.addAction(_(u'&Zoom Arrière'))
		self.menuZoomMoins.setIcon(QIcon("Icones" + os.sep + "zoommoins.png"))
		self.connect(self.menuZoomMoins, SIGNAL("triggered()"), self.zoomArriere)
		
		# Entrée mettre en pause/démarrer l'animation du gif
		self.menuStartPauseGif=self.menuZoom.addAction(_(u"Mettre en pause/démarrer l'animation"))
		self.menuStartPauseGif.setIcon(QIcon("Icones" + os.sep + "player_end.png"))
		self.connect(self.menuStartPauseGif, SIGNAL("triggered()"), self.startPauseGif)
			
		# Entrée mettre en pause/démarrer l'animation du gif
		self.menuStopGif=self.menuZoom.addAction(_(u"Arrêter l'animation"))
		self.menuStopGif.setIcon(QIcon("Icones" + os.sep + "player_stop.png"))
		self.connect(self.menuStopGif, SIGNAL("triggered()"), self.stopGif)
		
		# On cache les 2 menus de *.gif si on ne traite pas ce format
		if not self.gif:
			self.menuStartPauseGif.setVisible(False)
			self.menuStopGif.setVisible(False)
		
		# Si une image est en paramètre de classe, on l'affiche directement
		# sinon on pourra toujours l'afficher plus tard en appelant la
		# méthode setImage(), le moment venu
		if img:
			self.setImage(img)
			self.setToolTip(img)
		else:
			# image par défaut
			self.setImage("Icones" + os.sep + "avant-image.png")
			self.setToolTip(_(u"image d'accueil"))
			self.setTailleReelle()
	
	def mousePressEvent(self, event):
		"Menu contextuel et enregistrement de données préparant le déplacement de l'image par pincement"
		
		# Menu contextuel
		if event.button() == Qt.RightButton: 
			self.menuZoom.popup(event.globalPos())
		
		# On enregistre la position du curseur et de la barre de défilement au moment du clic
		elif event.button() == Qt.LeftButton:
			self.positionPresseeSourisIni = QPoint(event.pos())
			self.positionBarrePresseeSourisIni.setX(self.horizontalScrollBar().value())
			self.positionBarrePresseeSourisIni.setY(self.verticalScrollBar().value())
			if PYQT_VERSION_STR >= "4.1.0": 
				# curseur main fermée
				self.setCursor(Qt.ClosedHandCursor)
			else: self.setCursor(Qt.SizeAllCursor)
			event.accept()
	
	def mouseMoveEvent(self, event):
		"Déplacement de l'image dans le QScrollArea quand la souris est pressée"
		
		if self.positionPresseeSourisIni.isNull():
			event.ignore()
			return
		
		# Nouvelles positions de la barre de défilement (selon x et y)
		self.horizontalScrollBar().setValue(self.positionBarrePresseeSourisIni.x() + (self.positionPresseeSourisIni.x() - event.pos().x()))
		self.verticalScrollBar().setValue(self.positionBarrePresseeSourisIni.y() + (self.positionPresseeSourisIni.y() - event.pos().y()))
		self.horizontalScrollBar().update()
		self.verticalScrollBar().update()
		event.accept()
	
	def mouseReleaseEvent(self, event):
		"Réaffichage du curseur classique de la souris"
		self.setCursor(Qt.ArrowCursor)
		event.accept()
	
	def setScaleMode(self, mode):
		"Choix du mode de redimensionnement"
		# Mise à jour du paramètre
		self.modeTransformation=mode
	
	def setTailleFenetre(self):
		"Affichage taille fenetre"
		
		# Gestion de la taille
		#- Si l'image rentre
		##- Si l'image est trop grande
		# On retaille l'image en gardant le ratio entre 
		# le min (si l'image ne rentre pas dans le cadre), le max (sinon) de :
		#         * La largeur de la fenetre
		#         * La largeur de l'image
		#         * La hauteur de la fenetre
		#         * La hauteur de l'image
		if (self.preview.height() < self.height()) and (self.preview.width() < self.width()):
			width=max(self.preview.width(), self.width())
			height=max(self.preview.height(), self.height())
		else :
			width=min(self.preview.width(), self.width())
			height=min(self.preview.height(), self.height())

		if self.gif:
			self.redimGif(width - 5, height - 5)
		else:
			resultat = self.preview.get_preview().scaled(width - 5, height - 5, Qt.KeepAspectRatio, self.modeTransformation)
			debug(u"Preview : %s, taille : %d, %d" % (self.preview.get_imageName(), self.preview.width(), self.preview.height()))
			self.factor = min(float(self.height())/self.preview.height(), float(self.width())/self.preview.width())
		
		#-- On met l'image et on redimensionne le Label pour les images simples
		if not self.gif:
			self.imageLabel.setPixmap(resultat)


			
	
	def setTailleReelle(self):
		"Fonction d'affichage en taille réelle"
		self.preview.origin()

		width, height = self.preview.width(), self.preview.height()

		# On redimensionne le label à la taille de l'image
		if self.gif:
			self.redimGif(width, height)
		else:
			self.imageLabel.setPixmap(self.preview.get_preview())
		self.factor = 1
	
	def zoomAvant(self):
		"Fonction de zoom avant 25%"
		
		# On redimensionne l'image à 125% de la taille actuelle
		factor = 5/4. * self.factor

		width = int(self.preview.width() * factor)
		height = int(self.preview.height() * factor)

		if self.gif:
			self.redimGif(width, height)
		else:
			image = self.preview.get_preview().scaled(width, height, Qt.KeepAspectRatio)
			self.imageLabel.setPixmap(image)
		self.factor = factor
	
	def zoomArriere(self):
		"Fonction de zoom arrière 25%"
		
		# On redimensionne l'image à 75% de la taille actuelle
		factor = 3/4. * self.factor

		width = int(self.preview.width() * factor)
		height = int(self.preview.height() * factor)

		if self.gif:
			self.redimGif(width, height)
		else:
			image = self.preview.get_preview().scaled(width, height, Qt.KeepAspectRatio)
			self.imageLabel.setPixmap(image)
		self.factor = factor
	
	def startPauseGif(self):
		"Démarrer/mettre en pause l'animation de l'image gif"
		if self.movie.state() == QMovie.NotRunning:
			self.movie.start()
		else:
			self.movie.setPaused(self.movie.state() != QMovie.Paused)
	
	def stopGif(self):
		"Arrêter l'animation de l'image gif"
		if self.movie.state() != QMovie.NotRunning:
			self.movie.stop()
	
	def redimGif(self, width, height):
		"""Changer la taille d'affichage du gif en prenant soin d'arrêter et de
		reprendre l'animation si nécessaire.
		Il y a un petit bogue d'affichage sur la redimension (il disparait en changeant
		d'onglet ou de cadre et en revenant.
		"""
		etatInitial = self.movie.state()
		if etatInitial == QMovie.Running:
			self.movie.stop()
		self.movie.setScaledSize(QSize(width, height))
		if etatInitial == QMovie.Running:
			self.movie.start()
		else:
			# On redémarre le gif sinon l'image n'est pas actualisée et reste à la même taille
			self.movie.start()
			self.movie.stop()
	
	def isGif(self):
		"Indique si l'image affichée est un gif. Le test est effectué sur l'extension du fichier"
		return self.gif
	
	def setImage(self, img=None, fauxChemin=None, anim=False):
		"""Fonction de mise en place de l'image.
		Le faux chemin est utile pour dissocier le chemin que verra l'utilisateur
		du chemin de l'image affichée. Ils sont différents uniquement lorsqu'une image
		composite est affichée (cadres masque alpha 3D et image composite).
		L'argument "anim" dit si une image gif doit être animée.
		"""
		
		if not img:
			img = "Icones" + os.sep + "avant-image.png"
			self.setToolTip(_(u"image d'accueil"))
			self.setTailleReelle()
			return
		elif fauxChemin:
			self.setToolTip(fauxChemin)
		else:
			self.setToolTip(img)
		
		# Chargement du gif le cas échéant
		if isinstance(img, str) or isinstance(img, unicode):
			# En général
			extension = os.path.splitext(img)[1]
		elif isinstance(img, QString):
			# Pour selectWidget.py principalement
			extension = "." + QFileInfo(img).suffix()
		if extension == ".gif":
			self.menuStartPauseGif.setVisible(True)
			self.menuStopGif.setVisible(True)
			self.gif = 1
			self.movie = QMovie(img)
			# On démarre le gif de toute façon sinon l'image n'est pas visible
			self.movie.start()
			if not anim:
				self.movie.stop()
			self.imageLabel.setMovie(self.movie)
		else:
			# Pour des images non-gif, on cache les menus d'animation
			self.menuStartPauseGif.setVisible(False)
			self.menuStopGif.setVisible(False)
			self.gif = 0
		

		# Visiblement sous windows la taille du QScrollArea renvoie 0,
		# on passe par l'Objet à l'intérieur pour obtenir la taille de l'image à créer
		self.preview = EkdPreview(img, self.width(), 0, 10, False, True, True) #(chemin, largeur, qualité, cache?, keepRatio?, magnify? )

		# Par défault on charge en taille fenetre
		self.setTailleFenetre()
Exemple #9
0
class ServerToolsWindow(base_class, ui_class):
    __metaclass__ = QSingleton

    def __init__(self, model, parent=None):
        super(ServerToolsWindow, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.spinner_movie = QMovie(Resources.get("icons/servertools-spinner.mng"))
        self.spinner_label.setMovie(self.spinner_movie)
        self.spinner_label.hide()
        self.progress_bar.hide()
        while self.tab_widget.count():
            self.tab_widget.removeTab(0)  # remove the tab(s) added in designer
        self.tab_widget.tabBar().hide()
        self.account_button.setMenu(QMenu(self.account_button))
        self.setWindowTitle("Blink Server Tools")
        self.setWindowIconText("Server Tools")
        self.model = model
        self.tab_widget.addTab(ServerToolsWebView(self), "")
        font = self.account_label.font()
        font.setPointSizeF(self.account_label.fontInfo().pointSizeF() + 2)
        font.setFamily("Sans Serif")
        self.account_label.setFont(font)
        self.model.rowsInserted.connect(self._SH_ModelChanged)
        self.model.rowsRemoved.connect(self._SH_ModelChanged)
        self.account_button.menu().triggered.connect(self._SH_AccountButtonMenuTriggered)
        web_view = self.tab_widget.currentWidget()
        web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
        web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
        web_view.loadProgress.connect(self._SH_WebViewLoadProgress)

    def _SH_AccountButtonMenuTriggered(self, action):
        view = self.tab_widget.currentWidget()
        account = action.data().toPyObject()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab=view.tab, task=view.task)

    def _SH_WebViewLoadStarted(self):
        self.spinner_label.setMovie(self.spinner_movie)
        self.spinner_label.show()
        self.spinner_movie.start()
        self.progress_bar.setValue(0)
        # self.progress_bar.show()

    def _SH_WebViewLoadFinished(self, load_ok):
        self.spinner_movie.stop()
        self.spinner_label.hide()
        self.progress_bar.hide()
        if not load_ok:
            web_view = self.tab_widget.currentWidget()
            icon_path = Resources.get("icons/invalid.png")
            error_message = web_view.last_error or "Unknown error"
            html = """
            <html>
             <head>
              <style>
                .icon    { width: 64px; height: 64px; float: left; }
                .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
              </style>
             </head>
             <body>
              <img class="icon" src="file:%s" />
              <div class="message">Failed to load web page: <b>%s</b></div>
             </body>
            </html>
            """ % (
                icon_path,
                error_message,
            )
            web_view.loadStarted.disconnect(self._SH_WebViewLoadStarted)
            web_view.loadFinished.disconnect(self._SH_WebViewLoadFinished)
            web_view.setHtml(html)
            web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
            web_view.loadFinished.connect(self._SH_WebViewLoadFinished)

    def _SH_WebViewLoadProgress(self, percent):
        self.progress_bar.setValue(percent)

    def _SH_ModelChanged(self, parent_index, start, end):
        menu = self.account_button.menu()
        menu.clear()
        for row in xrange(self.model.rowCount()):
            account_info = self.model.data(self.model.index(row, 0), Qt.UserRole).toPyObject()
            action = QAction(account_info.name, self)
            action.setData(QVariant(account_info.account))
            menu.addAction(action)

    def open_settings_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data().toPyObject()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab="settings")
        self.show()

    def open_search_for_people_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data().toPyObject()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab="contacts", task="directory")
        self.show()

    def open_history_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data().toPyObject()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab="calls")
        self.show()

    def open_buy_pstn_access_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data().toPyObject()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab="payments")
        self.show()
Exemple #10
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.searchEdit.textChanged.connect(self.search_text_changed)
        self.ui.show_button.clicked.connect(self.show_episodes)
        self.ui.searchEdit.returnPressed.connect(self.show_episodes)
        self.episodes = None
        self.episode_list = None
        self.number = 0
        self.anime_list = None
        self.ui.download_button.clicked.connect(self.download)
        self.ui.res_list_widget.currentItemChanged.connect(self.episode_change)
        self.com = Comunicate()
        self.com.sig.connect(self.message)
        self.com.img.connect(self.set_image)
        self.ui.anime_list_widget.itemDoubleClicked.connect(self.show_episodes)
        self.setWindowIcon(QIcon(get_file('animes.png')))
        self.ui.anime_list_widget.itemPressed.connect(self.anime_entered)
        Thread(target=self.load_url_items).start()
        #self.load_url_items()
        self.movie = QMovie(get_file('ajax-loader.gif'))
        self.ui.loading_label.setMovie(self.movie)
        self.link = None
        self.main_download_page = None
        self.tray = SystemTrayIcon(
            QIcon(get_file('animes.png')), self.com, self)
        self.com.op.connect(self.show_semard)
        self.ui.action_About_Semard.activated.connect(self.about_semard)
        self.ui.action_Contato.activated.connect(self.show_feedback)
        self.setWindowTitle('Semard - Animes')
        self.browser = None
        self.player = None
        #self.player_window = player_w

    @Slot(str, bool)
    def openVideo(self, filepath, duplicate_mode):
        movie = os.path.expanduser(filepath)
        if 'http://' not in filepath:
            if not os.access(movie, os.R_OK):
                print('Error: %s file is not readable' % movie)
            sys.exit(1)

        split = urlparse.urlsplit(filepath)
        #name = QInputDialog.getText(self, 'Escolha nome do arquivo', 'Nome do arquivo:')
        name = split.path.split("/")[-1]
        #pa = os.path.join(res, name)
        if duplicate_mode:
            try:
                #media = instance.media_new(movie, 'sout=#duplicate{dst=file{dst=%s},dst=display}' % pa)
                pass
            except NameError:
                print ('NameError: % (%s vs Libvlc %s)' % (sys.exc_info()[1],
                                                           vlc.__version__, vlc.libvlc_get_version()))
        else:
            try:
                #media = instance.media_new(movie)
                if sys.platform in 'win32':
                    subprocess.Popen([os.path.join('vlc','vlc'), movie])
                else:
                    subprocess.Popen(['vlc', movie])
            except NameError:
                print ('NameError: % (%s vs Libvlc %s)' % (sys.exc_info()[1],
                                                           vlc.__version__, vlc.libvlc_get_version()))
                QMessageBox.critical(self, 'Erro','problema ao iniciar o vlc')
                # "--sout=#duplicate{dst=file{dst=example.mpg},dst=display}"

        #player = instance.media_player_new()
        #pplayer.set_media(media)
        #self.player_window.setMedia(media)
        #self.player_window.createUI()
        #self.player_window = Player()
        #media.parse()
        #self.player_window.setWindowTitle(media.get_meta(0))
        #self.player_window.show()
        #self.player_window.resize(640, 480)
        #if sys.platform == "linux2":  # for Linux using the X Server
        #    pplayer.set_xwindow(self.player_window.videoframe.winId())
        #elif sys.platform == "win32":  # for Windows
        #    pplayer.set_hwnd(self.player_window.videoframe.winId())
        #elif sys.platform == "darwin":  # for MacOS
        #    pplayer.set_agl(self.player_window.videoframe.windId())
        #pplayer.play()
        #self.player_window.updateUI()

    @Slot(str, str)
    def start_download(self, filepath, path):
        #thread = QThread(self)
        pbar = QtGui.QProgressBar(self.ui.tab_downloads)
        pbar.setMinimum(0)
        pbar.setMaximum(100)
        pbar.setValue(0)
        self.ui.formLayout.addRow(os.path.basename(path), pbar)
        pbar.show()
        dw = Downloader(str(filepath), str(path), pbar)
        dw.finished.connect(self.finished_download)
        dw.progresschanged.connect(self.show_download_progress)
        dw.started.connect(self.started_download)
        Thread(target=dw.download).start()
        #thread.started.connect(dw.download)
        #thread.finished.connect(self.finished_download)
        #dw.moveToThread(thread)
        #thread.start()

    def finished_download(self, pbar, filename):
        self.tray.showMessage(filename, u'Download concluído.')
        pbar.setValue(100)
        pbar.setEnabled(False)

    def started_download(self, filename):
        filename = os.path.basename(filename)
        self.tray.showMessage(filename, u'Download iniciado.')

    @Slot(float, QtGui.QProgressBar)
    def show_download_progress(self, progress, pbar):
        pbar.setValue(progress)

    def show_feedback(self):
        feed = Feedback(self.com)
        feed.exec_()

    def about_semard(self):
        about = QMessageBox.about(self, "Sobre Semard",
                                  u"""<b>Semard</b> v%s
        <p><b>Copyright (C) 2013</b> Ronnie Andrew.</p>
        <p>Todos os direitos reservados de acordo com a licença GNU GPL v3 ou posterior.</p>
        <p><b>Website Oficial:</b> <a href='https://github.com/ROAND/Series-Manager'>GitHub</a></p>
        <p><b>Plataforma: </b>%s</p>
          """ % (__version__, platform.system()))

    def show_semard(self, message):
        self.show()

    def closeEvent(self, event):
        self.hide()
        self.tray.showMessage(u'Semard', u'Semard ainda está em execução.')
        event.ignore()

    @Slot(str)
    def set_image(self, img_str):
        self.ui.image_label.setPixmap(QPixmap(img_str))

    @Slot(str)
    def message(self, message):
        if str(message) in 'ended':
            self.ui.loading_label.hide()
            # self.repaint()
            self.ui.anime_list_widget.setEnabled(True)
            self.ui.show_button.setEnabled(True)
            self.movie.stop()
        if str(message) in 'started':
            self.ui.loading_label.show()
            # self.repaint()
            self.ui.anime_list_widget.setEnabled(False)
            self.ui.show_button.setEnabled(False)
            self.movie.start()

    def anime_entered(self, item):
        pass

    def load_url_items(self):
        self.com.sig.emit('started')
        self.main_download_page = AnimeList('http://www.anbient.net/lista')
        self.number, self.anime_list = self.main_download_page.get_attrs()
        self.ui.avaLabel.setText('%s disponiveis.' % self.number)
        self.add_full_items_animelist()
        self.com.sig.emit('ended')

    def episode_change(self):
        self.com.sig.emit('started')
        self.ui.options_list_widget.clear()

        if self.ui.res_list_widget.currentItem():
            name = self.ui.res_list_widget.currentItem().text()
            episode = self.episode_list[name]
            self.ui.options_list_widget.addItems(episode.links)
            self.com.sig.emit('ended')

    def download(self):
        #name = self.ui.options_list_widget.currentItem().text()
        link = self.ui.options_list_widget.currentItem().text()
        self.com.sig.emit('started')
        msgBox = QMessageBox()
        msgBox.setWindowTitle(u'Informação')
        msgBox.setText(u'Browser padrão')
        msgBox.setInformativeText(
            u'Você deseja abrir este link com o seu browser padrão?')
        msgBox.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        msgBox.setDefaultButton(QMessageBox.Yes)
        ret = msgBox.exec_()
        if ret == QMessageBox.Yes:
            if sys.platform in 'win32':
                webbrowser.open(link)
            else:
                webbrowser.open(link)
        else:
            browser.ui.webView.setUrl(link)
            browser.show()
        self.com.sig.emit('ended')

    def keyPressEvent(self, event):
        if isinstance(event, PyQt4.QtGui.QKeyEvent):
            if event.key() == Qt.Key_Down:
                self.ui.anime_list_widget.setCurrentRow(
                    self.ui.anime_list_widget.currentRow() + 1)
            elif event.key() == Qt.Key_Up:
                self.ui.anime_list_widget.setCurrentRow(
                    self.ui.anime_list_widget.currentRow() - 1)

    @staticmethod
    def get_img_link(url):
        page = urllib2.urlopen(url)
        page_string = page.read().decode('utf-8')
        soup = BeautifulSoup(page_string)
        spans = soup.find_all('span', {'id': 'posterspan'})
        link = None
        for chil in spans:
            if isinstance(chil, bs4.element.Tag):
                for img in chil.children:
                    if isinstance(img, bs4.element.Tag):
                        link = img['src']
        return link

    def show_ep_thread(self):
        self.ui.res_list_widget.clear()
        anime_name = self.ui.anime_list_widget.currentItem().text()
        link = self.anime_list[anime_name]
        self.episodes = EpisodeList(link)
        # self.episodes.join()
        self.link = self.get_img_link(link)
        self.episode_list = self.episodes.get_episodes()

        anime_name = self.ui.anime_list_widget.currentItem().text()
        link = self.anime_list[anime_name]
        img_link = self.get_img_link(link)
        file_name = img_link
        if os.path.exists(get_file(file_name)):
            self.com.img.emit(get_file(file_name))
            # self.ui.image_label.setPixmap(QPixmap(get_file(file_name)))
        else:
            if img_link is not None:
                file_name = img_link.replace(
                    'http://www.anbient.net/sites/default/files/imagecache/242x0/imagens/poster/', '')
                urllib.urlretrieve(
                    'http://www.anbient.net/sites/default/files/imagecache/242x0/imagens/poster/%s' % file_name,
                    get_file(file_name))
                self.com.img.emit(get_file(file_name))
                # self.ui.image_label.setPixmap(QPixmap(get_file(file_name)))

        self.ui.label_sinopse.setText(self.episodes.get_sinopse().strip())
        try:
            for name in reversed(sorted(self.episode_list.keys(), key=int)):
                episode = self.episode_list[name]
                name, links = episode.get_attrs()
                self.ui.res_list_widget.addItem(name)
        except:
            for name, episode in reversed(sorted(self.episode_list.items())):
                name, links = episode.get_attrs()
                self.ui.res_list_widget.addItem(name)
        self.com.sig.emit('ended')

    def show_episodes(self):
        Thread(target=self.show_ep_thread).start()
        self.com.sig.emit('started')

    def add_full_items_animelist(self):
        self.ui.anime_list_widget.clear()
        for name, link in sorted(self.anime_list.items()):
            self.ui.anime_list_widget.addItem(name)

    def search_text_changed(self, new_text):
        items = self.ui.anime_list_widget.findItems(new_text, Qt.MatchContains)
        if items:
            self.ui.anime_list_widget.setCurrentItem(items[0])
            self.ui.labelSearch.setText('')
        else:
            self.ui.labelSearch.setText('Not Found!')

    def setBrowser(self, browser_param):
        self.browser = browser_param
        self.browser.start_download.connect(self.start_download)
        self.browser.open_video.connect(self.openVideo)
Exemple #11
0
class MuWizard(QWizard):

    def __init__(self, R=None, parent=None):
        QWizard.__init__(self, parent)

        self.R = R
        self.data = None

        self.addPage(self.introPage())
        self.addPage(self.loadPage())
        self.addPage(self.modelsPage())
        self.addPage(self.resultsPage())
        self.setWindowTitle('Wizard of muScale')
        self.setPixmap(QWizard.LogoPixmap, QPixmap(RES + ICONS + LOGO))

        self.setStyleSheet('QWizard {' + GRADIENT +'}\
                        QPushButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 80px;}\
                        QPushButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QPushButton:pressed {\
                            color: #800;\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QPushButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QComboBox {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 1px 18px 1px 3px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QComboBox:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QComboBox::down-arrow {\
                             image: url(' + RES + ICONS + ARROW_DOWN + ');}\
                        QComboBox::down-arrow:on {\
                             top: 1px;\
                             left: 1px;}\
                        QComboBox::drop-down {\
                             subcontrol-origin: padding;\
                             subcontrol-position: top right;\
                             width: 15px;\
                             border-left-width: 1px;\
                             border-left-color: darkgray;\
                             border-left-style: solid;\
                             border-top-right-radius: 3px;\
                             border-bottom-right-radius: 3px;}\
                         QToolButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QToolButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QToolButton:pressed {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QToolButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}')

    def introPage(self):
        intro = QWizardPage()

        intro.setTitle('Hello and welcome')
        label = QLabel('''This is a wizard.
Now you're ready to forecast some time series!
        ''')

        label.setWordWrap(True)
        layout = QVBoxLayout()
        layout.addWidget(label)
        intro.setLayout(layout)

        return intro

    def loadPage(self):
        load = WizardPageEx('loadCheck')

        load.setTitle('Initial data')
        pathLbl = QLabel("<font style='color: gray'>Specify the file with time series to forecast:</font>")
        loadLbl = QLabel("<font style='color: gray'>Click</font>")
        loadLbl.setAlignment(Qt.AlignCenter)

        self.path = QLineEdit()
        self.path.setPlaceholderText('path to file')
        getPath = QToolButton()
        getPath.setText('...')

        self.resultLbl = QLabel()
        self.resultLbl.setAlignment(Qt.AlignCenter)
        self.resultLbl.hide()

        self.preview = QLabel()
        self.preview.setAlignment(Qt.AlignCenter)
        self.preview.setWordWrap(True)
        self.preview.hide()

        self.preview.setAttribute(Qt.WA_Hover)
        self.filter = Filter()
        self.preview.installEventFilter(self.filter)

        getPath.clicked.connect(self.loadData)

        layout = QGridLayout()
        layout.addWidget(pathLbl, 0, 0)
        layout.addWidget(loadLbl, 0, 1)
        layout.addWidget(self.path, 1, 0)
        layout.addWidget(getPath, 1, 1)
        layout.addWidget(self.resultLbl, 2, 0, 1, 2)
        layout.addWidget(self.preview, 3, 0, 1, 2)
        load.setLayout(layout)

        load.previewSeries = SeriesPreview()
        self.previewSeries = load.previewSeries

        # to be able to reference from class namespace
        self.loadCheck = load.check

        return load

    def modelsPage(self):
        models = WizardPageEx('modelCheck')
        models.setTitle('Forecast')

        lbl = QLabel("<font style='color: gray'>Forecast horizon:</font>")
        self.steps = QSpinBox()
        self.steps.setRange(MIN_FORECAST, MAX_FORECAST)
        self.steps.setValue(10)
        self.start = QPushButton('Forecast')
        self.start.clicked.connect(self.modelling)
        self.custom = QPushButton('Advanced')
        self.processing = QLabel()

        self.gifLoading = QMovie(RES + ICONS + PROGRESS, QByteArray(), self)
        self.gifLoading.setCacheMode(QMovie.CacheAll)
        self.gifLoading.setSpeed(100)
        self.processing.setMovie(self.gifLoading)
        self.processing.setAlignment(Qt.AlignCenter)
        self.processing.hide()

        self.status = QLabel()
        self.status.setAlignment(Qt.AlignCenter)
        self.status.hide()

        layout = QGridLayout()
        layout.addWidget(lbl, 0, 0)
        layout.addWidget(self.steps, 0, 1)
        layout.addWidget(self.start, 0, 2)
        layout.addWidget(self.custom, 0, 3)
        layout.addWidget(self.status, 1, 0, 1, 4)
        layout.addWidget(self.processing, 2, 0, 1, 4)
        models.setLayout(layout)

        self.customOpt = CustomOption()
        self.custom.clicked.connect(self.customOpt.show)
        self.modelCheck = models.check

        return models

    def resultsPage(self):
        results = QWizardPage()
        results.setFinalPage(True)
        results.setTitle('Results')

        self.graph = QLabel("<font style='font-size: 16px;'>Plot</font>")
        self.export = QLabel("<font style='font-size: 16px;'>Export</font>")
        self.showData = QLabel("<font style='font-size: 16px;'>Data</font>")
        
        self.plotResult = MplWidget(None)
        self.plotResult.canvas.fig.set_facecolor('white')
        self.resData = QLabel('')
        self.resData.setAlignment(Qt.AlignCenter)
        self.resData.setWordWrap(True)
        self.resData.hide()

        self.resFilter = ResFilter()

        self.resLayout = QVBoxLayout()
        self.resLayout.addWidget(self.export)
        self.resLayout.addWidget(self.graph)
        self.resLayout.addWidget(self.showData)
        self.resLayout.addWidget(self.plotResult)
        self.resLayout.addWidget(self.resData)

        self.plotResult.hide()

        for index in range(0, self.resLayout.count()):
            try:
                self.resLayout.itemAt(index).widget().setAlignment(Qt.AlignCenter)
                self.resLayout.itemAt(index).widget().setStyleSheet('QLabel { color: gray; }')
                self.resLayout.itemAt(index).widget().setAttribute(Qt.WA_Hover)
                self.resLayout.itemAt(index).widget().installEventFilter(self.resFilter)
            except Exception:
                pass

        self.resLayout.setAlignment(Qt.AlignCenter)
        self.resLayout.setSpacing(60)

        results.setLayout(self.resLayout)

        return results

    #---- actions ----#
    def loadData(self):
        fileName = unicode(QFileDialog.getOpenFileName(self, 'Open text file', RES))
        if fileName:
            self.resultLbl.hide()
            self.preview.hide()
            if DataParser.istextfile(fileName):
                self.data = DataParser.getTimeSeriesFromTextData(data=open(fileName, 'r').read())
                if len(self.data[0]) > DATA_LOW_LIMIT:
                    self.resultLbl.setText("<font style='color: gray'>Success! Loaded<b> " + str(len(self.data[0])) +
                                           '</b> values, errors: <b>' + str(
                                            self.data[1]) + '</b></font>')
                    self.resultLbl.show()
                    self.path.setText(fileName)

                    previewLength = 40
                    self.preview.setText("<font style='color: gray'><b>Preview:</b> "+ ' '.join(
                                        [str(e) for e in self.data[0][:previewLength]]) +
                                        "...</font>")
                    self.previewSeries.updateData(self.data)
                    self.preview.show()
                    self.loadCheck.setChecked(True)
                else:
                    self.resultLbl.setText("<font style='color: gray'>Not enough values to form data series.</font>")
                    self.resultLbl.show()
            else:
                self.resultLbl.setText("<font style='color: gray'>Specified file is binary file!</font>")
                self.resultLbl.show()

    def modelling(self):
        self.processing.show()
        self.gifLoading.start()
        self.status.setText('')

        statusText = u"<font style='color: gray'>"

        # decomposition #
        if self.customOpt.options['enable']:
            self.signalEx = self.customOpt.options['signal']
            self.wavelet = pywt.Wavelet(self.customOpt.options['wavelet'])
            wLevel = self.customOpt.options['lvls'] - 1
            maxLevel = pywt.dwt_max_level(len(self.data[0]), self.wavelet)

            if wLevel > maxLevel:
                wLevel = maxLevel

            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                       level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients
        else:
            self.signalEx = pywt.MODES.sp1
            selected = select_wavelet(self.data[0], self.R)
            index = max(selected)
            self.wavelet = pywt.Wavelet(selected[index][1])

            wLevel = calculate_suitable_lvl(self.data[0],
                                         self.wavelet, self.R, swt=False)
            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                     level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients

        statusText += 'Wavelet: <b>' + self.wavelet.family_name + \
                      '</b> (' + self.wavelet.name + ', ' + self.wavelet.symmetry + ', orthogonal: ' + \
                      str(self.wavelet.orthogonal) + ')<br/>'

        statusText += 'Discrete Wavelet Transfom: <b>' + str(wLevel + 1) + ' levels</b><br/>'

        # models #
        options = {}
        options['multi'] = True
        options['fractal'] = False
        options['ljung'] = False
        self.models = auto_model(self.wCoefficients, self.R, options, self.data[0])

        statusText += '<br/>Selected models:<br/>'
        for lvl, model in self.models.iteritems():
            statusText += str(lvl) + '. <b>' + model.enumname.replace('_', ' ') + '</b><br/>'

        # forecasting #
        try:
            frequency = self.customOpt.options['frequency']
        except Exception:
            frequency = 8
        aic = False
        options['hw_gamma'] = True
        options['hw_model'] = 'additive'
        options['hw_period'] = frequency
        options['ar_aic'] = aic
        options['ar_method'] = 'burg'
        options['ar_order'] = 50
        options['arima_auto'] = False
        options['arima_nons'] = True
        options['arima_nons_order'] = [6, 0, 9]
        options['arima_seas'] = True
        options['arima_seas_order'] = [9, 0, 1]
        options['lsf_aic'] = aic
        options['lsf_order'] = 30
        options['ets_auto'] = aic
        options['ets_period'] = frequency
        options['sts_type'] = 'trend'
        options['append_fit'] = True

        self.multi_model_thread = MultiModelThread(self.models,
                                           self.wCoefficients,
                                           self.R,
                                           self.steps.value(),
                                           options,)
        self.multi_model_thread.done.connect(self.multiForecastFinished)
        self.multi_model_thread.start()

        statusText += '<br/>Forecasting...'

        self.status.setText(statusText)
        self.status.show()

    def multiForecastFinished(self, results):
        self.forecast = results
        self.gifLoading.stop()
        self.processing.hide()

        self.status.setText('<br/>'.join(str(self.status.text()).split('<br/>')[:-1]) +
                            '<br/>Forecast complete.')
        self.modelCheck.setChecked(True)

    #---- results -----#
    def togglePlot(self):
        if self.plotResult.isVisible():
            self.plotResult.hide()
            self.export.show()
            self.showData.show()
            self.resLayout.setSpacing(60)
        else:
            self.updateGraph()
            self.plotResult.show()
            self.export.hide()
            self.showData.hide()
            self.resLayout.setSpacing(5)

    def toggleData(self):
        if self.resData.isVisible():
            self.export.show()
            self.graph.show()
            self.showData.show()
            self.resData.hide()
            self.resLayout.setSpacing(60)
            self.adjustSize()
        else:
            self.plotResult.hide()
            self.graph.hide()
            self.export.hide()
            self.showData.show()
            self.resData.show()
            self.resLayout.setSpacing(5)

            res = self.inverseWT()
            max = len(self.data[0]) - 1
            resText = '<table border="0" align="center" style="border-style: groove;">'
            resText += '<tr><td align="center"><i>Initial</i></td><td align="center"><i>Forecast</i></td></tr>'
            resText += '<tr><td align="center">...</td><td></td></tr>'
            table = zip(self.data[0][max-10:max], res[max-10:max])
            for i, j in table:
                resText += '<tr>'
                resText += '<td align="center">' + str(i) + '</td>'
                resText += '<td align="center">' + str(j) + '</td>'
                resText += '</tr>'

            for e in res[max+1:max+10]:
                resText += '<tr>'
                resText += '<td align="center"></td>'
                resText += '<td align="center">' + str(e) + '</td>'
                resText += '</tr>'

            resText += '<tr><td align="center"></td><td align="center">...</td></tr>'
            resText += '</table>'

            self.resData.setText(resText)
            self.adjustSize()

    def inverseWT(self):
        return pywt.waverec(update_dwt([e [1] for e in self.forecast], self.wavelet, self.signalEx),
                                            self.wavelet, mode=self.signalEx)

    def updateGraph(self):
        self.plotResult.updatePlot(self.inverseWT(), label='Simulation', color='r')
        self.plotResult.updatePlot(self.data[0], label='Time series', color='b')

    def exportToXls(self):
        # opening file dialog
        fileName = QFileDialog.getSaveFileName(self,
            'Save as', RES, 'Microsoft Excel Spreadsheet (*.xls)')

        if fileName.count() > 0:
            try:
                COLUMN_WIDTH = 3000

                alignment = Alignment()
                alignment.horizontal = Alignment.HORZ_CENTER
                alignment.vertical = Alignment.VERT_CENTER

                borders = Borders()
                borders.left = Borders.THIN
                borders.right = Borders.THIN
                borders.top = Borders.THIN
                borders.bottom = Borders.THIN

                style = XFStyle()
                style.alignment = alignment
                style.borders = borders

                font = Font()
                font.bold = True
                headerStyle = XFStyle()
                headerStyle.font = font

                separate = Borders()
                separate.left = Borders.THIN
                separate.right = Borders.DOUBLE
                separate.top = Borders.THIN
                separate.bottom = Borders.THIN
                separateStyle = XFStyle()
                separateStyle.borders = separate

                book = Workbook(encoding='utf-8')

                # modelling data
                dec_sheet = book.add_sheet('Data decomposition')

                # decomposition data
                # initial data
                column = 0
                row = 0
                dec_sheet.write(row, column, 'Time series', headerStyle)
                dec_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    dec_sheet.write(row, column, item, separateStyle)
                    row += 1

                # decomposition
                for lvl in self.wCoefficients:
                    row = 0
                    column += 1
                    dec_sheet.write(row, column, 'Level' + str(column - 1), headerStyle)
                    dec_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl:
                        dec_sheet.write(row, column, item, style)
                        row += 1

                # decomposition graphs
                pass

                levels_sheet = book.add_sheet('Multiscale forecast')

                # levels data
                column = 0
                for lvl in self.forecast:
                    row = 0
                    levels_sheet.write(row, column, 'Level' + str(column), headerStyle)
                    levels_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl[1]:
                        levels_sheet.write(row, column, float(item), style)
                        row += 1
                    column += 1

                result_sheet = book.add_sheet('Results')

                # initial
                column = 0
                row = 0
                result_sheet.write(row, column, 'Initial data', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    result_sheet.write(row, column, item, separateStyle)
                    row += 1

                # forecast
                row = 0
                column += 1
                result_sheet.write(row, column, 'Forecast', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.inverseWT():
                    result_sheet.write(row, column, item, style)
                    row += 1

                row = 0
                column = 2
                self.updateGraph()
                self.plotResult.saveFigure('forecast', format='bmp')

                result_sheet.insert_bitmap(RES + TEMP + 'forecast.bmp', row, column)

                # saving xls
                try:
                    book.save(unicode(fileName))
                except Exception:
                    pass

            except Exception, e:
                pass
Exemple #12
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.searchEdit.textChanged.connect(self.search_text_changed)
        self.ui.show_button.clicked.connect(self.show_episodes)
        self.ui.searchEdit.returnPressed.connect(self.show_episodes)
        self.episodes = None
        self.episode_list = None
        self.number = 0
        self.anime_list = None
        self.ui.download_button.clicked.connect(self.download)
        self.ui.res_list_widget.currentItemChanged.connect(self.episode_change)
        self.com = Comunicate()
        self.com.sig.connect(self.message)
        self.com.img.connect(self.set_image)
        self.ui.anime_list_widget.itemDoubleClicked.connect(self.show_episodes)
        self.setWindowIcon(QIcon(get_file('animes.png')))
        self.ui.anime_list_widget.itemPressed.connect(self.anime_entered)
        Thread(target=self.load_url_items).start()
        #self.load_url_items()
        self.movie = QMovie(get_file('ajax-loader.gif'))
        self.ui.loading_label.setMovie(self.movie)
        self.link = None
        self.main_download_page = None
        self.tray = SystemTrayIcon(QIcon(get_file('animes.png')), self.com,
                                   self)
        self.com.op.connect(self.show_semard)
        self.ui.action_About_Semard.activated.connect(self.about_semard)
        self.ui.action_Contato.activated.connect(self.show_feedback)
        self.setWindowTitle('Semard - Animes')
        self.browser = None
        self.player = None
        #self.player_window = player_w

    @Slot(str, bool)
    def openVideo(self, filepath, duplicate_mode):
        movie = os.path.expanduser(filepath)
        if 'http://' not in filepath:
            if not os.access(movie, os.R_OK):
                print('Error: %s file is not readable' % movie)
            sys.exit(1)

        split = urlparse.urlsplit(filepath)
        #name = QInputDialog.getText(self, 'Escolha nome do arquivo', 'Nome do arquivo:')
        name = split.path.split("/")[-1]
        #pa = os.path.join(res, name)
        if duplicate_mode:
            try:
                #media = instance.media_new(movie, 'sout=#duplicate{dst=file{dst=%s},dst=display}' % pa)
                pass
            except NameError:
                print('NameError: % (%s vs Libvlc %s)' %
                      (sys.exc_info()[1], vlc.__version__,
                       vlc.libvlc_get_version()))
        else:
            try:
                #media = instance.media_new(movie)
                if sys.platform in 'win32':
                    subprocess.Popen([os.path.join('vlc', 'vlc'), movie])
                else:
                    subprocess.Popen(['vlc', movie])
            except NameError:
                print('NameError: % (%s vs Libvlc %s)' %
                      (sys.exc_info()[1], vlc.__version__,
                       vlc.libvlc_get_version()))
                QMessageBox.critical(self, 'Erro', 'problema ao iniciar o vlc')
                # "--sout=#duplicate{dst=file{dst=example.mpg},dst=display}"

        #player = instance.media_player_new()
        #pplayer.set_media(media)
        #self.player_window.setMedia(media)
        #self.player_window.createUI()
        #self.player_window = Player()
        #media.parse()
        #self.player_window.setWindowTitle(media.get_meta(0))
        #self.player_window.show()
        #self.player_window.resize(640, 480)
        #if sys.platform == "linux2":  # for Linux using the X Server
        #    pplayer.set_xwindow(self.player_window.videoframe.winId())
        #elif sys.platform == "win32":  # for Windows
        #    pplayer.set_hwnd(self.player_window.videoframe.winId())
        #elif sys.platform == "darwin":  # for MacOS
        #    pplayer.set_agl(self.player_window.videoframe.windId())
        #pplayer.play()
        #self.player_window.updateUI()

    @Slot(str, str)
    def start_download(self, filepath, path):
        #thread = QThread(self)
        pbar = QtGui.QProgressBar(self.ui.tab_downloads)
        pbar.setMinimum(0)
        pbar.setMaximum(100)
        pbar.setValue(0)
        self.ui.formLayout.addRow(os.path.basename(path), pbar)
        pbar.show()
        dw = Downloader(str(filepath), str(path), pbar)
        dw.finished.connect(self.finished_download)
        dw.progresschanged.connect(self.show_download_progress)
        dw.started.connect(self.started_download)
        Thread(target=dw.download).start()
        #thread.started.connect(dw.download)
        #thread.finished.connect(self.finished_download)
        #dw.moveToThread(thread)
        #thread.start()

    def finished_download(self, pbar, filename):
        self.tray.showMessage(filename, u'Download concluído.')
        pbar.setValue(100)
        pbar.setEnabled(False)

    def started_download(self, filename):
        filename = os.path.basename(filename)
        self.tray.showMessage(filename, u'Download iniciado.')

    @Slot(float, QtGui.QProgressBar)
    def show_download_progress(self, progress, pbar):
        pbar.setValue(progress)

    def show_feedback(self):
        feed = Feedback(self.com)
        feed.exec_()

    def about_semard(self):
        about = QMessageBox.about(
            self, "Sobre Semard", u"""<b>Semard</b> v%s
        <p><b>Copyright (C) 2013</b> Ronnie Andrew.</p>
        <p>Todos os direitos reservados de acordo com a licença GNU GPL v3 ou posterior.</p>
        <p><b>Website Oficial:</b> <a href='https://github.com/ROAND/Series-Manager'>GitHub</a></p>
        <p><b>Plataforma: </b>%s</p>
          """ % (__version__, platform.system()))

    def show_semard(self, message):
        self.show()

    def closeEvent(self, event):
        self.hide()
        self.tray.showMessage(u'Semard', u'Semard ainda está em execução.')
        event.ignore()

    @Slot(str)
    def set_image(self, img_str):
        self.ui.image_label.setPixmap(QPixmap(img_str))

    @Slot(str)
    def message(self, message):
        if str(message) in 'ended':
            self.ui.loading_label.hide()
            # self.repaint()
            self.ui.anime_list_widget.setEnabled(True)
            self.ui.show_button.setEnabled(True)
            self.movie.stop()
        if str(message) in 'started':
            self.ui.loading_label.show()
            # self.repaint()
            self.ui.anime_list_widget.setEnabled(False)
            self.ui.show_button.setEnabled(False)
            self.movie.start()

    def anime_entered(self, item):
        pass

    def load_url_items(self):
        self.com.sig.emit('started')
        self.main_download_page = AnimeList('http://www.anbient.net/lista')
        self.number, self.anime_list = self.main_download_page.get_attrs()
        self.ui.avaLabel.setText('%s disponiveis.' % self.number)
        self.add_full_items_animelist()
        self.com.sig.emit('ended')

    def episode_change(self):
        self.com.sig.emit('started')
        self.ui.options_list_widget.clear()

        if self.ui.res_list_widget.currentItem():
            name = self.ui.res_list_widget.currentItem().text()
            episode = self.episode_list[name]
            self.ui.options_list_widget.addItems(episode.links)
            self.com.sig.emit('ended')

    def download(self):
        #name = self.ui.options_list_widget.currentItem().text()
        link = self.ui.options_list_widget.currentItem().text()
        self.com.sig.emit('started')
        msgBox = QMessageBox()
        msgBox.setWindowTitle(u'Informação')
        msgBox.setText(u'Browser padrão')
        msgBox.setInformativeText(
            u'Você deseja abrir este link com o seu browser padrão?')
        msgBox.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        msgBox.setDefaultButton(QMessageBox.Yes)
        ret = msgBox.exec_()
        if ret == QMessageBox.Yes:
            if sys.platform in 'win32':
                webbrowser.open(link)
            else:
                webbrowser.open(link)
        else:
            browser.ui.webView.setUrl(link)
            browser.show()
        self.com.sig.emit('ended')

    def keyPressEvent(self, event):
        if isinstance(event, PyQt4.QtGui.QKeyEvent):
            if event.key() == Qt.Key_Down:
                self.ui.anime_list_widget.setCurrentRow(
                    self.ui.anime_list_widget.currentRow() + 1)
            elif event.key() == Qt.Key_Up:
                self.ui.anime_list_widget.setCurrentRow(
                    self.ui.anime_list_widget.currentRow() - 1)

    @staticmethod
    def get_img_link(url):
        page = urllib2.urlopen(url)
        page_string = page.read().decode('utf-8')
        soup = BeautifulSoup(page_string)
        spans = soup.find_all('span', {'id': 'posterspan'})
        link = None
        for chil in spans:
            if isinstance(chil, bs4.element.Tag):
                for img in chil.children:
                    if isinstance(img, bs4.element.Tag):
                        link = img['src']
        return link

    def show_ep_thread(self):
        self.ui.res_list_widget.clear()
        anime_name = self.ui.anime_list_widget.currentItem().text()
        link = self.anime_list[anime_name]
        self.episodes = EpisodeList(link)
        # self.episodes.join()
        self.link = self.get_img_link(link)
        self.episode_list = self.episodes.get_episodes()

        anime_name = self.ui.anime_list_widget.currentItem().text()
        link = self.anime_list[anime_name]
        img_link = self.get_img_link(link)
        file_name = img_link
        if os.path.exists(get_file(file_name)):
            self.com.img.emit(get_file(file_name))
            # self.ui.image_label.setPixmap(QPixmap(get_file(file_name)))
        else:
            if img_link is not None:
                file_name = img_link.replace(
                    'http://www.anbient.net/sites/default/files/imagecache/242x0/imagens/poster/',
                    '')
                urllib.urlretrieve(
                    'http://www.anbient.net/sites/default/files/imagecache/242x0/imagens/poster/%s'
                    % file_name, get_file(file_name))
                self.com.img.emit(get_file(file_name))
                # self.ui.image_label.setPixmap(QPixmap(get_file(file_name)))

        self.ui.label_sinopse.setText(self.episodes.get_sinopse().strip())
        try:
            for name in reversed(sorted(self.episode_list.keys(), key=int)):
                episode = self.episode_list[name]
                name, links = episode.get_attrs()
                self.ui.res_list_widget.addItem(name)
        except:
            for name, episode in reversed(sorted(self.episode_list.items())):
                name, links = episode.get_attrs()
                self.ui.res_list_widget.addItem(name)
        self.com.sig.emit('ended')

    def show_episodes(self):
        Thread(target=self.show_ep_thread).start()
        self.com.sig.emit('started')

    def add_full_items_animelist(self):
        self.ui.anime_list_widget.clear()
        for name, link in sorted(self.anime_list.items()):
            self.ui.anime_list_widget.addItem(name)

    def search_text_changed(self, new_text):
        items = self.ui.anime_list_widget.findItems(new_text, Qt.MatchContains)
        if items:
            self.ui.anime_list_widget.setCurrentItem(items[0])
            self.ui.labelSearch.setText('')
        else:
            self.ui.labelSearch.setText('Not Found!')

    def setBrowser(self, browser_param):
        self.browser = browser_param
        self.browser.start_download.connect(self.start_download)
        self.browser.open_video.connect(self.openVideo)
Exemple #13
0
    def genOneTab(self, tabtitle="", tabbtn="", tabnums="", strwhere = "where studentsn like '03%' "):
        # tabtitle.setFixedHeight(40)
        # tabtitle.setFixedWidth(160)
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("随堂提问演板")
        tabtitle.setStyleSheet("border: 3px solid blue;\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)
       
        btnlayout = QGridLayout()
        
        cur = conn.cursor()
        strsql = "select studentsn, studentname from student " + strwhere
        cur.execute(strsql)
     
        tmpnum = 0
        for item in cur.fetchall():
            irow = tmpnum // 7
            icol = tmpnum % 7
            tmpnum += 1
            btnlayout.setRowMinimumHeight(irow, 80)

            tmpbtn = QPushButton(item[1])
            # tmpbtn.setFixedHeight(20)
            tmpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))
            # tmpbtn.setStyleSheet("border: 1px solid rgb(255,255,255,0);background-color: rgba(255,255,255,20);font-size:16px;")
            tmpbtn.setFlat(True)

            popMenu = QMenu(self)
            entry1 = popMenu.addAction("正确")
            self.connect(entry1,SIGNAL('triggered()'), lambda item=item[0]: self.answerRight(item))
            entry2 = popMenu.addAction("错误")
            self.connect(entry2,SIGNAL('triggered()'), lambda item=item[0]: self.answerWrong(item))
            entry3 = popMenu.addAction("替换")
            self.connect(entry3,SIGNAL('triggered()'), lambda item=item[0]: self.resetStudent(item))
            tmpbtn.setMenu(popMenu)
            tmpbtn.setAutoDefault(False)
            self.btngroup.addButton(tmpbtn, int(item[0]))

            tmpmovie = QMovie('image/ex_stu.gif', QByteArray(), self)
            tmplabel = QLabel()
            tmplabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            tmplabel.setAlignment(Qt.AlignCenter)
            tmplabel.setMovie(tmpmovie)
            tmplabel.setScaledContents(True)
            tmplabel.setLayout(QHBoxLayout())
            tmplabel.layout().setContentsMargins(0,0,0,0)
            # tmplabel.setStyleSheet("border: 1px solid rgb(255,255,255,0);background-color: rgba(255,255,255,20);font-size:16px;")
            tmplabel.layout().addWidget(tmpbtn)
            tmpmovie.start()
            tmpmovie.stop()

            btnlayout.addWidget(tmplabel, irow, icol)

        tabbtn.setIcon(QIcon("image/start.png"))
        tabbtn.setStyleSheet("border: 5px solid yellow;")
        tabbtn.setFixedHeight(40)
        tabbtn.setFixedWidth(100)
        tabbtn.setFont(QFont('宋体', 20))
        # tabnums.setFixedHeight(45)
        # tabnums.setFixedWidth(60)
        tabnums.setFont(QFont('Courier New', 20))
        tabnums.setStyleSheet("border: 5px solid blue; color:red;font-weight:bold;font-size:26px;\
            border-radius: 6px; \
            padding: 1px 1px 1px 1px;\
            min-width: 2em; ")
        tabnums.setEditable(True)
        tabnums.lineEdit().setReadOnly(True);
        tabnums.lineEdit().setAlignment(Qt.AlignCenter);

        model = tabnums.model()
        for row in list(range(1, 7)):
            item = QStandardItem(str(row))
            item.setTextAlignment(Qt.AlignCenter)
            item.setForeground(QColor('red'))
            item.setBackground(QColor(0,200,50, 130))
            model.appendRow(item)
        tabnums.setCurrentIndex(2)
        # tabnums.setStyleSheet ("QComboBox::drop-down {border-width: 100px;}")
        # tabnums.setStyleSheet ("QComboBox::down-arrow {image: url(image/downarrow.png);top: 10px;left: 1px;}")

        bottomlayout = QHBoxLayout()
        bottomlayout.setSizeConstraint(QLayout.SetFixedSize)
        bottomlayout.addStretch(10)
        bottomlayout.addWidget(tabbtn)
        bottomlayout.setSpacing(5)
        bottomlayout.addWidget(tabnums)
     
        cur.close()
        return(titleLayout, btnlayout, bottomlayout)
Exemple #14
0
class UiController:

    def __init__(self, controller, debug_mode, logger):
        self.controller = controller
        self.datahandler = controller.datahandler
        self.debug_mode = debug_mode
        self.logger = logger

        ### Main Window
        self.main_widget = QMainWindow()
        self.main_widget.setAttribute(Qt.WA_Maemo5StackedWindow)
        self.main_ui = Ui_DropN900Widget()
        self.main_ui.setupUi(self.main_widget)

        # Stacked layout for context switching
        self.stacked_layout = QtGui.QStackedLayout()
        self.main_ui.centralwidget.setLayout(self.stacked_layout)

        # Menu items
        self.action_transfers = QtGui.QAction("Transfers", self.main_widget)
        self.action_settings = QtGui.QAction("Settings", self.main_widget)
        self.action_sync = QtGui.QAction("Synchronize", self.main_widget)
        self.action_sync_photos = QtGui.QAction("Sync Media", self.main_widget)
        self.action_console = QtGui.QAction("Show Log", self.main_widget)
        self.action_about = QtGui.QAction("About", self.main_widget)
        self.action_exit = QtGui.QAction("Exit", self.main_widget)

        self.main_ui.menubar.addAction(self.action_transfers)
        self.main_ui.menubar.addAction(self.action_settings)
        self.main_ui.menubar.addAction(self.action_sync)
        self.main_ui.menubar.addAction(self.action_sync_photos)
        self.main_ui.menubar.addAction(self.action_console)
        self.main_ui.menubar.addAction(self.action_about)
        self.main_ui.menubar.addAction(self.action_exit)

        # Connects
        self.action_transfers.triggered.connect(self.show_transfer_widget)
        self.action_sync.triggered.connect(self.synchronize_now)
        self.action_sync_photos.triggered.connect(self.synchronize_now_photos)
        self.action_settings.triggered.connect(self.show_settings_widget)
        self.action_console.triggered.connect(self.show_console)
        self.action_about.triggered.connect(self.show_about)
        self.action_exit.triggered.connect(self.shut_down)
        
        ### Trusted Login Widget
        self.trusted_login_widget = QWidget()
        self.trusted_login_ui = Ui_TrustedLoginWidget()
        self.trusted_login_ui.setupUi(self.trusted_login_widget)
        self.trusted_login_ui.label_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/images/dropn900_logo.png")).scaled(65,65))

        # Connects
        self.trusted_login_ui.button_auth.clicked.connect(self.try_trusted_login)
        
        ### Manager Widget
        self.manager_widget = QWidget()
        self.manager_ui = Ui_ManagerWidget()
        self.manager_ui.setupUi(self.manager_widget)
        
        # Tree Controller
        tree = self.manager_ui.tree_widget
        self.tree_controller = TreeController(tree, self.manager_ui, self.controller, self.logger)

        # Hide public link elements on start
        self.manager_ui.button_copy_public_link.hide()
        self.manager_ui.button_open_public_link.hide()
        
        # Connects
        self.manager_ui.button_copy_public_link.clicked.connect(self.copy_item_link)
        self.manager_ui.button_open_public_link.clicked.connect(self.open_item_link)
        self.manager_ui.button_download.clicked.connect(self.item_download)
        self.manager_ui.button_upload.clicked.connect(self.item_upload)
        self.manager_ui.button_rename.clicked.connect(self.item_rename)
        self.manager_ui.button_remove.clicked.connect(self.item_remove)
        self.manager_ui.button_new_folder.clicked.connect(self.item_new_folder)
        self.manager_ui.sync_button.clicked.connect(self.synchronize_now)
        self.last_dl_location = None
        self.last_ul_location = None

        ### Console widget
        self.console_widget = QWidget(self.main_widget, Qt.Window)
        self.console_widget.setAttribute(Qt.WA_Maemo5StackedWindow)
        self.console_ui = Ui_ConsoleWidget()
        self.console_ui.setupUi(self.console_widget)
        self.console_ui.button_save.clicked.connect(self.save_log_to_file)
        self.console_ui.button_back.clicked.connect(self.hide_console)
        
        ### Settings widget
        self.settings_widget = None

        ### Fill stacked layout
        self.stacked_layout.addWidget(self.trusted_login_widget)
        self.stacked_layout.addWidget(self.manager_widget)
        self.stacked_layout.setCurrentWidget(self.trusted_login_widget)

        ### Loading Widget
        self.loading_widget = QWidget(self.manager_widget)
        self.loading_ui = Ui_LoadingWidget()
        self.loading_ui.setupUi(self.loading_widget)
        self.manager_ui.action_layout.insertWidget(3, self.loading_widget)
        self.loading_widget.hide()
        
        self.tree_controller.set_loading_ui(self.loading_ui)

        # Init loading animation
        self.loading_animation = QMovie(self.datahandler.datapath("ui/images/loading.gif"), "GIF", self.loading_ui.load_animation_label)
        self.loading_animation.setCacheMode(QMovie.CacheAll)
        self.loading_animation.setSpeed(150)
        self.loading_animation.setScaledSize(QtCore.QSize(48,48))
        self.loading_ui.load_animation_label.setMovie(self.loading_animation)

        # Init hide timer and icons for information messages
        self.information_message_timer = QTimer()
        self.information_message_timer.setSingleShot(True)
        self.information_message_timer.timeout.connect(self.hide_information_message)
        self.information_icon_ok = QPixmap(self.datahandler.datapath("ui/icons/check.png")).scaled(24,24)
        self.information_icon_error = QPixmap(self.datahandler.datapath("ui/icons/cancel.png")).scaled(24,24)
        self.information_icon_queue = QPixmap(self.datahandler.datapath("ui/icons/queue.png")).scaled(24,24)
        
        ### About dialog
        self.about_dialog = AboutDialog(self)
        
        self.set_synching(False)
        
    def set_synching(self, syncing):
        self.manager_ui.sync_button.setVisible(not syncing)
        self.manager_ui.sync_label.setVisible(syncing)

    def set_settings_widget(self, settings_widget):
        self.settings_widget = settings_widget
        
    def set_transfer_widget(self, transfer_widget):
        self.transfer_widget = transfer_widget
        
    def synchronize_now(self):
        self.settings_widget.sync_now_clicked()
        
    def synchronize_now_photos(self):
        self.controller.sync_manager.sync_media()
        
    def show(self):
        # Nokia N900 screen resolution, full screen
        self.main_widget.resize(800, 480) 
        self.main_widget.show()
        self.main_widget.showMaximized()

    def show_settings_widget(self):
        if self.settings_widget != None:
            if not self.settings_widget.isVisible():
                self.settings_widget.show()
                self.settings_widget.check_settings()

    def show_transfer_widget(self):
        if self.settings_widget.isVisible():
            self.settings_widget.hide()
        self.transfer_widget.show()
        
    def show_about(self):
        if not self.about_dialog.isVisible():
            self.about_dialog.show()
        
    def show_note(self, message):
        QMaemo5InformationBox.information(None, QString(message), 0)
        
    def show_banner(self, message, timeout = 5000):
        QMaemo5InformationBox.information(None, QString(message), timeout)
        
    def show_loading_ui(self, message = "", loading = True):
        self.loading_ui.info_label.setText(message)
        self.loading_ui.info_label_icon.hide()
        self.thumb_was_visible = self.manager_ui.thumb_container.isVisible()
        self.manager_ui.thumb_container.hide()
        self.loading_widget.show()

        self.loading_ui.load_animation_label.setVisible(loading)
        if loading:
            self.loading_animation.start()
        else:
            self.loading_animation.stop()

    def show_information_ui(self, message, succesfull, timeout = 4000):
        self.loading_ui.load_animation_label.hide()
        self.thumb_was_visible = self.manager_ui.thumb_container.isVisible()
        if self.thumb_was_visible:
            self.manager_ui.thumb_container.hide()
        self.loading_ui.info_label.setText(message)
        if succesfull == None:
            icon = self.information_icon_queue
        elif succesfull:
            icon = self.information_icon_ok
        else:
            icon = self.information_icon_error
        self.loading_ui.info_label_icon.setPixmap(icon)
        self.loading_ui.info_label_icon.show()
        self.loading_widget.show()
        self.information_message_timer.start(timeout)

    def hide_loading_ui(self):
        if not self.information_message_timer.isActive():
            self.loading_widget.hide()
        if self.loading_animation.state() == QMovie.Running:
            self.loading_animation.stop()

    def hide_information_message(self):
        self.loading_ui.info_label_icon.hide()
        self.hide_loading_ui()
        self.manager_ui.thumb_container.setVisible(self.thumb_was_visible)
            
    def try_trusted_login(self):
        self.trusted_login_ui.label_error.setText("")
        email = self.trusted_login_ui.line_edit_email.text()
        password = self.trusted_login_ui.line_edit_password.text()

        error = None
        if email.isEmpty():
            error = "Email can't be empty!"
        elif email.count("@") != 1:
            error = "Invalid email, check your @ signs!"
        elif email.contains(" "):
            error = "Invalid email, can't have spaces!"
        elif password.isEmpty():
            error = "Password can't be empty!"
            
        if error == None:
            self.show_banner("Authenticating...", 3000)
            self.set_trusted_login_info("Authenticating, please wait...")
            self.truested_email = self.datahandler.to_unicode(str(email.toUtf8()))
            self.trusted_password = self.datahandler.to_unicode(str(password.toUtf8()))
            QTimer.singleShot(100, self.do_trusted_login_networking)
        else:
            self.set_trusted_login_error(error)
            
    def set_trusted_login_error(self, error):
        self.trusted_login_ui.label_error.setStyleSheet("color: #9d1414;")
        self.trusted_login_ui.label_error.setText(error)
        self.truested_email = None
        self.trusted_password = None
        
    def set_trusted_login_info(self, info):
        self.trusted_login_ui.label_error.setStyleSheet("color: #149d2b;")
        self.trusted_login_ui.label_error.setText(info)
        
    def do_trusted_login_networking(self):
        self.controller.end_trusted_auth(self.truested_email.encode("utf-8"), self.trusted_password.encode("utf-8"))
        self.truested_email = None
        self.trusted_password = None
        
    def reset_trusted_login(self):
        self.trusted_login_ui.line_edit_email.clear()
        self.trusted_login_ui.line_edit_password.clear()
        self.trusted_login_ui.label_error.clear()

    def switch_context(self, view = None):
        widget = None
        if view == "trustedlogin":
            widget = self.trusted_login_widget
        if view == "manager":
            widget = self.manager_widget
        if view == "console":
            self.console_widget.show()
        if view == None and self.last_view != None:
            widget = self.last_view
        if widget != None:
            self.last_view = self.stacked_layout.currentWidget()
            self.stacked_layout.setCurrentWidget(widget)

    def get_selected_data(self):
        return self.tree_controller.selected_data
    
    # Signal handlers
            
    def shut_down(self):
        self.main_widget.close()

    def show_console(self):
        if self.console_widget.isVisible() == False:
            self.switch_context("console")
        else:
            self.hide_console()

    def hide_console(self):
        self.console_widget.hide()
                    
    def save_log_to_file(self):
        filename = self.datahandler.get_data_dir_path() + "dropn900.log"
        log_string = str(self.console_ui.text_area.toPlainText())
        try:
            log_file = open(filename, "w")
            log_file.write(log_string)
            log_file.close()
            self.show_banner("Log saved to " + filename)
        except IOError:
            self.logger.error("Could not open " + filename + " to save log")


    def browser_control_clicked(self):
        if self.controller.connected:
            self.switch_context()
        else:
            self.controller.end_auth()
            
    def copy_item_link(self):
        url = self.tree_controller.current_public_link
        if url == None:
            return
        self.datahandler.copy_url_to_clipboard(url)
    
    def open_item_link(self):
        url = self.tree_controller.current_public_link
        if url == None:
            return
        QDesktopServices.openUrl(QtCore.QUrl(url))

    def item_download(self):
        data = self.get_selected_data()
        if data == None:
            return
            
        if self.datahandler.dont_show_dl_dialog == False:
            # This dialog shows sometimes strange stuff on maemo5
            # It's a PyQt4 bug and its the best we got, you can cope with this
            if self.last_dl_location == None:
                self.last_dl_location = self.datahandler.get_data_dir_path()
            local_folder_path = QFileDialog.getExistingDirectory(self.manager_widget, QString("Select Download Folder"), QString(self.last_dl_location), QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly)
            if local_folder_path.isEmpty():
                return
            py_unicode_path = self.datahandler.to_unicode(str(local_folder_path.toUtf8()))
            self.last_dl_location = py_unicode_path
            store_path = py_unicode_path + "/" + data.name
        else:
            dir_check = QDir(self.datahandler.get_data_dir_path())
            if not dir_check.exists():
                self.show_note("Cannot download, destination " + self.datahandler.get_data_dir_path() + " does not exist. Please set a new folder in settings.")
                return
            store_path = self.datahandler.get_data_dir_path() + data.name
        self.controller.connection.get_file(data.path, data.root, store_path, data.get_size(), data.mime_type)
        
    def item_upload(self):
        data = self.get_selected_data()
        if data == None or not data.is_folder():
            return

        # This dialog shows sometimes strange stuff on maemo5
        # It's a PyQt4 bug and its the best we got, you can cope with this
        if self.last_ul_location == None:
            self.last_ul_location = self.datahandler.get_data_dir_path()
        local_file_path = QFileDialog.getOpenFileName(self.manager_widget, QString("Select File for Upload"), QString(self.last_ul_location))
        if local_file_path.isEmpty():
            return
        py_unicode_path = self.datahandler.to_unicode(str(local_file_path.toUtf8()))
        self.last_ul_location = py_unicode_path[0:py_unicode_path.rfind("/")]
        self.controller.connection.upload_file(data.path, data.root, py_unicode_path)
        
    def item_rename(self):
        data = self.get_selected_data()
        if data == None:
            return

        # Get new name from user
        old_name = data.get_name()
        keyword = "file" if not data.is_folder() else "folder"
        new_name, ok = QInputDialog.getText(None, "Renaming " + keyword, "Give new name for " + keyword + " " + old_name, QtGui.QLineEdit.Normal, old_name)
        if not ok:
            return
        # Validate with QString
        if not self.is_name_valid(new_name, keyword):
            return
        # Make QString to python 'unicode'
        new_name = self.datahandler.to_unicode(str(new_name.toUtf8()))
        if old_name == new_name:
            return

        # Extension will be lost, ask user if he wants to leave it
        q_old_name = QtCore.QString(old_name)
        if q_old_name.contains("."):
            if not new_name.contains("."):
                format = old_name[q_old_name.lastIndexOf("."):]
                confirmation = QMessageBox.question(None, "Extension missing", "Do you want to append the original '" + format + "' extensions to the filename '" + new_name + "'?", QMessageBox.Yes, QMessageBox.No)
                if confirmation == QMessageBox.Yes:
                    new_name.append(format)

        # Get final new path and rename
        if data.parent == "/":
            new_name = data.parent + new_name
        else:
            new_name = data.parent + "/" + new_name
        self.controller.connection.rename(data.root, data.path, new_name, data)

    def item_remove(self):
        data = self.get_selected_data()
        if data == None:
            return
        if data.is_folder():
            confirmation = QMessageBox.question(None, "Remove folder verification", "Are you sure you want to remove the entire folder " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel)
        else:
            confirmation = QMessageBox.question(None, "Remove file verification", "Are you sure you want to remove " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel)            
        if confirmation == QMessageBox.Yes:
            self.controller.connection.remove_file(data.root, data.path, data.parent, data.is_folder())
        
    def item_new_folder(self):
        data = self.get_selected_data()
        if data == None:
            return
        if not data.is_folder():
            return
        
        full_create_path = data.path + "/"
        new_folder_name, ok = QInputDialog.getText(None, "Give new folder name", "")
        if not ok:
            return
        # Validate QString
        if not self.is_name_valid(new_folder_name, "folder"):
            return
        # Make QString to python unicode
        new_folder_name = self.datahandler.to_unicode(str(new_folder_name.toUtf8()))
        full_create_path = data.path + "/" + new_folder_name
        self.controller.connection.create_folder(data.root, full_create_path, new_folder_name, data.path)

    def is_name_valid(self, name, item_type):
        if name.isEmpty() or name.isNull():
            return False
        if name.contains("/"):
            self.show_information_ui("Cant use / in new " + item_type + " name", False)
            return False
        if name.contains("\\"):
            self.show_information_ui("Cant use \ in new " + item_type + " name", False)
            return False
        if name.startsWith(" "):
            self.show_information_ui("New " + item_type + " name cant start with a space", False)
            return False
        if name.endsWith(" "):
            self.show_information_ui("New " + item_type + " name cant end with a space", False)
            return False
        return True
Exemple #15
0
class ServerToolsWindow(base_class, ui_class):
    __metaclass__ = QSingleton

    def __init__(self, model, parent=None):
        super(ServerToolsWindow, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.spinner_movie = QMovie(
            Resources.get('icons/servertools-spinner.mng'))
        self.spinner_label.setMovie(self.spinner_movie)
        self.spinner_label.hide()
        self.progress_bar.hide()
        while self.tab_widget.count():
            self.tab_widget.removeTab(0)  # remove the tab(s) added in designer
        self.tab_widget.tabBar().hide()
        self.account_button.setMenu(QMenu(self.account_button))
        self.setWindowTitle('Blink Server Tools')
        self.setWindowIconText('Server Tools')
        self.model = model
        self.tab_widget.addTab(ServerToolsWebView(self), '')
        font = self.account_label.font()
        font.setPointSizeF(self.account_label.fontInfo().pointSizeF() + 2)
        font.setFamily("Sans Serif")
        self.account_label.setFont(font)
        self.model.rowsInserted.connect(self._SH_ModelChanged)
        self.model.rowsRemoved.connect(self._SH_ModelChanged)
        self.account_button.menu().triggered.connect(
            self._SH_AccountButtonMenuTriggered)
        web_view = self.tab_widget.currentWidget()
        web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
        web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
        web_view.loadProgress.connect(self._SH_WebViewLoadProgress)

    def _SH_AccountButtonMenuTriggered(self, action):
        view = self.tab_widget.currentWidget()
        account = action.data()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab=view.tab, task=view.task)

    def _SH_WebViewLoadStarted(self):
        self.spinner_label.show()
        self.spinner_movie.start()
        self.progress_bar.setValue(0)
        #self.progress_bar.show()

    def _SH_WebViewLoadFinished(self, load_ok):
        self.spinner_movie.stop()
        self.spinner_label.hide()
        self.progress_bar.hide()
        if not load_ok:
            web_view = self.tab_widget.currentWidget()
            icon_path = Resources.get('icons/invalid.png')
            error_message = web_view.last_error or 'Unknown error'
            html = """
            <html>
             <head>
              <style>
                .icon    { width: 64px; height: 64px; float: left; }
                .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
              </style>
             </head>
             <body>
              <img class="icon" src="file:%s" />
              <div class="message">Failed to load web page: <b>%s</b></div>
             </body>
            </html>
            """ % (icon_path, error_message)
            web_view.loadStarted.disconnect(self._SH_WebViewLoadStarted)
            web_view.loadFinished.disconnect(self._SH_WebViewLoadFinished)
            web_view.setHtml(html)
            web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
            web_view.loadFinished.connect(self._SH_WebViewLoadFinished)

    def _SH_WebViewLoadProgress(self, percent):
        self.progress_bar.setValue(percent)

    def _SH_ModelChanged(self, parent_index, start, end):
        menu = self.account_button.menu()
        menu.clear()
        for row in xrange(self.model.rowCount()):
            account_info = self.model.data(self.model.index(row, 0),
                                           Qt.UserRole)
            action = QAction(account_info.name, self)
            action.setData(account_info.account)
            menu.addAction(action)

    def open_settings_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab='settings')
        self.show()

    def open_search_for_people_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab='contacts', task='directory')
        self.show()

    def open_history_page(self, account):
        view = self.tab_widget.currentWidget()
        account = account or view.account
        if account is None or account.server.settings_url is None:
            account = self.account_button.menu().actions()[0].data()
        self.account_label.setText(account.id)
        self.tab_widget.setTabText(self.tab_widget.currentIndex(), account.id)
        view.load_account_page(account, tab='calls')
        self.show()