class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class Mplayer(QDialog): REVENIR, PAS_PRECEDENT_SUIVANT, PRECEDENT_SUIVANT, CURSEUR_SUR_UNE_LIGNE,\ CURSEUR_A_PART, PARCOURIR, PAS_PARCOURIR, LIST, RATIO = range(9) HAUTEUR, LARGEUR = range(2) def __init__(self, cheminVideo=[], taille=(250,225), choixWidget=(RATIO, REVENIR, PAS_PRECEDENT_SUIVANT,CURSEUR_SUR_UNE_LIGNE,PAS_PARCOURIR,LIST), debutFin=(0,0), cheminMPlayer=None, barreTaches=None, facteurLimitant=HAUTEUR, cheminParcourir=None, parent=None): """widget mplayer""" QDialog.__init__(self, parent) #=== Paramètres généraux ===# self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_(u"Player vidéo")) #On réduit la marge pour gagner de l'espace self.setContentsMargins(0,0,0,0) self.systeme = os.name ### Quand EKD windows est installé, le chemin des dépendances sont ########### ### positionnées dans les variables d'environnement donc pas besoin de ####### ### collecter le chemin des ces dépendances ################################## self.cheminMPlayer = "mplayer" ############################################################################## # liste de chemins vidéos if type(cheminVideo) != list : self.listeVideos=[cheminVideo] else : self.listeVideos = cheminVideo # est-ce que la vidéo est lue? self.estLue=False # est-ce que la vidéo est en pause? self.estEnPause=False self.debutFin = debutFin # Nom du fichier courant (le self n'est pas encore utile) txtParDefaut = u"Pas de fichier lu" if self.listeVideos.__len__()!=0: self.fichierCourant = [txtParDefaut, self.listeVideos[0]] else: self.fichierCourant = [txtParDefaut, ""] # Barre des tâches de la fenêtre self.barreTaches = barreTaches # Taille de la vidéo self.tailleLargeur=taille[0] self.tailleHauteur=taille[1] # paramètres des boutons-icones iconTaille=22 flat=1 # Pour récupérer le temps courant depuis certains cadre self.temps = 0 self.dureeTimer = 10 # temps en ms ############################################################################################################################### #Pour être plus précis lors de la lecture, on prend comme unité la miliseconde. ###################### ## Il faut donc utiliser une echelle 1000 fois plus grande pour les unités du slider self.echelle=1000 ############################################################################################################################### # Permet de récupérer la durée de la vidéo depuis une instance de la classe # Sert dans certains cadres self.dureeVideo = 0 # Chemin sur lequel peut s'ouvrir la boite de dialogue de fichier # associée au bouton parcourir self.cheminPourBoutonParcourir = cheminParcourir self.taille = taille debug("self.taille avant lecture : %s %s" % (self.taille, type(self.taille))) #=== Widgets ===# self.icone_lire=QIcon("Icones" + os.sep + "player_play.png") self.icone_pause=QIcon("Icones" + os.sep + "player_pause.png") self.icone_arret=QIcon("Icones" + os.sep + "player_stop.png") if Mplayer.REVENIR in choixWidget: self.bout_revenir = QPushButton(u"Revenir") self.bout_revenir.setIcon(QIcon("Icones" + os.sep + "revenir.png")) if Mplayer.PARCOURIR in choixWidget: self.bout_ouvVideo = QPushButton(u"Parcourir...") if Mplayer.PRECEDENT_SUIVANT in choixWidget: self.bout_prec = QPushButton(QIcon("Icones" + os.sep + "player_rew.png"),"") self.bout_prec.setIconSize(QSize(iconTaille, iconTaille)) self.bout_prec.setFlat(flat) self.bout_suivant = QPushButton(QIcon("Icones" + os.sep + "player_fwd.png"),"") self.bout_suivant.setIconSize(QSize(iconTaille, iconTaille)) self.bout_suivant.setFlat(flat) self.LISTW=False if Mplayer.LIST in choixWidget : self.LISTW = True self.listFichiers = QComboBox() self.listFichiers.hide() self.setListeVideo() self.bout_LectPause = QPushButton(self.icone_lire,"") self.bout_LectPause.setIconSize(QSize(iconTaille, iconTaille)) self.bout_LectPause.setFlat(flat) self.bout_Arret = QPushButton(self.icone_arret,"") self.bout_Arret.setIconSize(QSize(iconTaille, iconTaille)) self.bout_Arret.setFlat(flat) # widget qui contiendra la vidéo self.cibleVideo = DisplayVid(self) # par défaut le widget-cible est noir color = QColor(0, 0, 0) self.cibleVideo.setAutoFillBackground(True) self.cibleVideo.setPalette(QPalette(color)) self.cibleVideo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.cibleVideo.setFixedHeight(self.taille[1]) self.cibleVideo.setToolTip(self.fichierCourant[0]) #Choix de l'aspect ratio de la vidéo if Mplayer.RATIO in choixWidget : self.conf = QGroupBox() self.conf.setContentsMargins(0,0,0,0) self.conf.setMinimumSize(QSize(self.tailleLargeur, 0)) self.conf.setObjectName("conf") self.verticalLayout = QHBoxLayout(self.conf) self.verticalLayout.setObjectName("verticalLayout") self.choicenorm = QRadioButton(self.conf) self.choicenorm.setObjectName("choicenorm") self.verticalLayout.addWidget(self.choicenorm) self.choicewide = QRadioButton(self.conf) self.choicewide.setObjectName("choicewide") self.verticalLayout.addWidget(self.choicewide) self.choiceone = QRadioButton(self.conf) self.choiceone.setObjectName("choiceone") self.verticalLayout.addWidget(self.choiceone) self.choicenorm.setText("4:3") self.choicewide.setText("16:9") self.choiceone.setText("w:h") # Checked le ratio de la vidéo if self.listeVideos.__len__()!=0: self.changeRatio(self.listeVideos[0]) else : self.setRatio(4.0/3.0) if Mplayer.RATIO in choixWidget : self.choicenorm.setChecked(True) self.slider = QSlider(Qt.Horizontal) self.slider.setEnabled(True) self.mplayerProcess = QProcess(self) self.timer = QTimer(self) self.tempsChrono = TracerChrono() #=== mise-en-page/plan ===# mhbox = QHBoxLayout() vbox = QVBoxLayout() vbox.addWidget(self.cibleVideo) if Mplayer.RATIO in choixWidget : vbox.addWidget(self.conf) hbox = QHBoxLayout() if Mplayer.REVENIR in choixWidget: hbox.addWidget(self.bout_revenir) if Mplayer.PARCOURIR in choixWidget: hbox.addWidget(self.bout_ouvVideo) hbox.addWidget(self.bout_LectPause) hbox.addWidget(self.bout_Arret) if Mplayer.PRECEDENT_SUIVANT in choixWidget: hbox.addWidget(self.bout_prec) hbox.addWidget(self.bout_suivant) hbox.addWidget(self.tempsChrono) if Mplayer.CURSEUR_A_PART not in choixWidget: hbox.addWidget(self.slider) vbox.addLayout(hbox) if Mplayer.CURSEUR_A_PART in choixWidget: hbox.setAlignment(Qt.AlignLeft) hbox = QHBoxLayout() hbox.addWidget(self.slider) vbox.addLayout(hbox) # Liste fichier dans combobox if self.LISTW : hbox = QHBoxLayout() hbox.addWidget(self.listFichiers) vbox.addLayout(hbox) mhbox.addLayout(vbox) self.setLayout(mhbox) #=== connexion des widgets à des fonctions ===# if Mplayer.REVENIR in choixWidget: self.connect(self.bout_revenir, SIGNAL('clicked()'), SLOT('close()')) if Mplayer.PARCOURIR in choixWidget: self.connect(self.bout_ouvVideo, SIGNAL('clicked()'), self.ouvrirVideo) if Mplayer.PRECEDENT_SUIVANT in choixWidget: self.connect(self.bout_prec, SIGNAL('clicked()'), self.precedent) self.connect(self.bout_suivant, SIGNAL('clicked()'), self.suivant) #Ajouté le 08/11/2009 - Liste des fichiers dans une combobox if self.LISTW : self.connect(self.listFichiers, SIGNAL('currentIndexChanged(int)'), self.changeVideo) self.connect(self.bout_LectPause, SIGNAL('clicked()'), self.lectPause) self.connect(self.bout_Arret, SIGNAL('clicked()'), self.arretMPlayer) self.connect(self.mplayerProcess, SIGNAL('readyReadStandardOutput()'), self.recupSortie) self.connect(self.mplayerProcess, SIGNAL('finished(int,QProcess::ExitStatus)'), self.finVideo) self.connect(self.timer, SIGNAL('timeout()'), self.sonderTempsActuel) self.connect(self.slider, SIGNAL('sliderMoved(int)'), self.changerTempsCurseur) self.connect(self.cibleVideo, SIGNAL('changeSize'), self.sizeMplayer) if Mplayer.RATIO in choixWidget : self.connect(self.choicenorm, SIGNAL("clicked(bool)"), self.defRatio) self.connect(self.choicewide, SIGNAL("clicked(bool)"), self.defRatio) self.connect(self.choiceone, SIGNAL("clicked(bool)"), self.defRatio) def setListeVideo(self) : self.referenceVideo = [] self.listFichiers.clear() for vid in self.listeVideos : self.referenceVideo.append(vid) self.listFichiers.addItem(os.path.basename(vid)) if self.listeVideos.__len__() > 1 : self.listFichiers.show() def setAudio(self,au) : if au : self.cibleVideo.hide() if "conf" in self.__dict__ : self.conf.hide() else : self.cibleVideo.show() if "conf" in self.__dict__ : self.conf.show() def changeVideo(self, index) : self.arretMPlayer() if index >= 0 : # Condition ajoutée pour éviter une erreure de dépassement de range dans la liste. self.listeVideos = self.referenceVideo[index] self.listFichiers.setCurrentIndex(index) def defRatio(self, state=0) : if state : if self.choicenorm.isChecked() : self.setRatio(4.0/3.0) if self.choicewide.isChecked() : self.setRatio(16.0/9.0) if self.choiceone.isChecked() : try : dim=getVideoSize(unicode(self.listeVideos[0])) self.setRatio(dim[0]/dim[1]) except : None self.defRatio() else : self.adjustSize() def setRatio(self,ratio) : self.ratio = ratio self.sizeMplayer() def changeRatio(self,video) : rv = getVideoRatio(video) if rv[0]==0.0 and type(rv[1])==float : rat = rv[1] else : rat = rv[0] if rat > 1.7 : if "choicewide" in self.__dict__ : self.choicewide.setChecked(True) self.setRatio(16.0/9.0) elif rat > 1.3 and rat <= 1.7 : if "choicenorm" in self.__dict__ : self.choicenorm.setChecked(True) self.setRatio(4.0/3.0) elif rat < 1.3 and rat != 0.0 : if "choiceone" in self.__dict__ : self.choiceone.setChecked(True) dim=getVideoSize(video) self.setRatio(dim[0]/dim[1]) else : if "choicenorm" in self.__dict__ : self.choicenorm.setChecked(True) self.setRatio(4.0/3.0) def sizeMplayer(self) : self.cibleVideo.setFixedHeight(int(self.cibleVideo.width()/self.ratio)) def ouvrirVideo(self): """Ouverture de la boîte de dialogue de fichiers""" txt = u"Fichiers vidéo" if self.cheminPourBoutonParcourir: chemin = self.cheminPourBoutonParcourir else: try: chemin = EkdConfig.get('general','video_input_path').decode("UTF8") except: chemin = os.path.expanduser('~') liste=QFileDialog.getOpenFileNames(None, u"Ouvrir", chemin, "%s (*.avi *.mpg *.mpeg *.mjpeg *.flv *.mp4 *.ogg *.vob *.mov *.wmv *.3gp *.h264)\n*" %txt) if not liste: return self.listeVideos = liste self.changeRatio(unicode(self.listeVideos[0])) chemin = unicode(self.listeVideos[0]) EkdConfig.set('general','video_input_path',os.path.dirname(chemin).encode("UTF8")) def setVideos(self, videos) : '''Définie proprement la liste des vidéos à jouer''' if type(videos) != list : self.listeVideos = [videos] else : self.listeVideos = videos if self.LISTW and videos.__len__() > 1 : self.setListeVideo() elif self.LISTW : self.listFichiers.hide() def demarrerMPlayer(self): """démarrage de mplayer avec les arguments choisis""" if self.estLue: return True args = QStringList() # Liste Qt qui contiendra les options de mplayer # Ajout d'options à liste: args << "-option" # mplayer fonctionnera comme un terminal dans ce script args << "-slave" # on ne veut pas avoir des commentaires sans grand intérêt args << "-quiet" # Sous linux, aucun driver n'a été nécessaire et pas de manip pour Wid :) if self.systeme=='posix': # try - except? # la fenêtre de mplayer restera attaché à la fenêtre # wid prend en valeur le nombre identifiant le widget (celui qui contiendra la vidéo) args << "-wid" << QString.number(self.cibleVideo.winId()) # Objet QString car args est une liste de ch de caractères settings = QSettings() videoOutput = settings.value("vo", QVariant('')).toString() if videoOutput: args << '-vo' << videoOutput # Sous windows else: # reinterpret_cast<qlonglong> obligatoire, winId() ne se laissant pas convertir gentiment ;) args << "-wid" << self.cibleVideo.winId().__hex__() args << "-vo" << "directx:noaccel" #args << "-vo" << "gl" # alternative # chemin de la vidéo args << self.listeVideos if PYQT_VERSION_STR >= "4.1.0": # mode de canal: on fusionne le canal de sortie normal (stdout) et celui des erreurs (stderr) self.mplayerProcess.setProcessChannelMode(QProcess.MergedChannels) # démarrage de mplayer (en tenant compte des arguments définis ci-dessus) # comme un nouveau processus self.mplayerProcess.start(self.cheminMPlayer, args) # au cas où mplayer ne démarrerait pas au bout de 3 sec (ex. problème de codec) if not self.mplayerProcess.waitForStarted(3000): QMessageBox.critical(self, u"Avertissement", u"Bogue au lancement de la vidéo avec mplayer") return False # donne le temps toutes les x secondes self.timer.start(self.dureeTimer) self.estLue = True return True def recupSortie(self): """récupère les lignes d'information émises par QProcess (mplayerProcess) et en tire les conséquences""" while self.mplayerProcess.canReadLine(): # renvoie True si une ligne complète peut être lue à partir du système # stocker l'ensemble des bits d'une ligne tampon=QByteArray(self.mplayerProcess.readLine()) # readline: lit une ligne ascii à partir du système # On vérifie si on a eu des réponses if tampon.startsWith("Playing"): # On récupère les infos de base ('$ mplayer -input cmdlist' pour avoir la liste complète - file:///usr/share/doc/mplayer-doc/tech/slave.txt.gz pour plus de détails) self.mplayerProcess.write("get_video_resolution\n") # récupère la résolution de la vidéo self.mplayerProcess.write("get_time_length\n") # Nouveau fichier chargé -> on récupère son nom ind = tampon.length() - 2 # suppression du '.' à la fin tampon.remove(ind,ind) tampon.remove(0, 8) # vire Playing tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) try: # Tour de passe-passe pour ne pas avoir de problème d'accents # Condition pour détection windows if os.name == 'nt': self.fichierCourant[1]=unicode(QString(tampon)) # Condition pour détection Linux ou MacOSX elif os.name in ['posix', 'mac']: self.fichierCourant[1]=unicode(QString(tampon)).encode("Latin1").decode("UTF8") except UnicodeEncodeError, e: debug(e) self.fichierCourant[1]="?" self.cibleVideo.setToolTip(self.fichierCourant[1]) if self.barreTaches is not None: self.barreTaches.showMessage(self.fichierCourant[1]) # réponse à get_video_resolution : ANS_VIDEO_RESOLUTION='<width> x <height>' if tampon.startsWith("ANS_VIDEO_RESOLUTION"): # retourne True si l'ensemble de bits démarre avec "..." debug("tampon : %s" % tampon) # ex. -> ANS_VIDEO_RESOLUTION='352 x 288' tampon.remove(0, 21) # suppression des 21 1er caract -> '352 x 288' tampon.replace(QByteArray("'"), QByteArray("")) # -> 352 x 288 tampon.replace(QByteArray(" "), QByteArray("")) # -> 352x288 tampon.replace(QByteArray("\n"), QByteArray("")) # -> 352x288 # retour chariot unix tampon.replace(QByteArray("\r"), QByteArray("")) # -> 352x288 # retour chariot windows #print "-----tampon.indexOf('x') :", tampon.indexOf('x'), type(tampon.indexOf('x')) sepIndex = tampon.indexOf('x') # récupère la position de 'x' # 3 <type 'int'> #print "-----tampon.left(sepIndex).toInt():", tampon.left(sepIndex).toInt(), type(tampon.left(sepIndex).toInt()) resX = tampon.left(sepIndex).toInt()[0] # -> 352 # (352, True) <type 'tuple'> #print "-----tampon.mid(sepIndex+1).toInt() :", tampon.mid(sepIndex+1).toInt(), type(tampon.mid(sepIndex+1).toInt()) resY = tampon.mid(sepIndex+1).toInt()[0] # -> 288 # (288, True) <type 'tuple'> # on définit les nouvelles dimensions de l'image du widget-mplayer. # try pour éviter les bogues sur les fichiers audio (sans dimension d'image)!!! #try: if resX!=0 or resY!=0: debug( "ratio : %s - %s" % (self.ratio, type(self.ratio))) else: debug("fichier audio") # réponse à get_time_length : ANS_LENGTH=xx.yy elif tampon.startsWith("ANS_LENGTH"): debug("tampon : %s" % tampon) # -> ANS_LENGTH=279.38 tampon.remove(0, 11) # vire ANS_LENGTH= tampon.replace(QByteArray("'"), QByteArray("")) tampon.replace(QByteArray(" "), QByteArray("")) tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) # -> 279.38 #print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat()) tempsMax = tampon.toFloat()[0] # (279.3800048828125, True) <type 'tuple'> self.dureeVideo = tempsMax ## Modifié le 28/05/2009 : On augmente la précision du slider #self.slider.setMaximum(tempsMax) # déf du domaine de valeur du curseur self.slider.setMaximum(tempsMax*self.echelle) # ATTENTION J'AI COMMENTE CETTE LIGNE !!! #self.slider.setMaximum(tempsMax) # réponse à get_time_pos : ANS_TIME_POSITION=xx.y elif tampon.startsWith("ANS_TIME_POSITION"): #print "tampon :",tampon # -> ANS_TIME_POSITION=1.4 (temps courant) tampon.remove(0, 18) # vire ANS_TIME_POSITION= tampon.replace(QByteArray("'"), QByteArray("")) tampon.replace(QByteArray(" "), QByteArray("")) tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) #print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat()) tempsCourant = tampon.toFloat()[0] # (1.3999999761581421, True) <type 'tuple'> # récupération du temps courant: utile dans certains cadres self.temps = tempsCourant # Programmer un arrêt. Utile pour les aperçus temps = float("%.1f" %self.temps) if self.debutFin!=(0,0) and self.debutFin[1]==temps: self.arretMPlayer() return self.slider.setValue(tempsCourant*self.echelle) ############################################################################# self.changerTempsChrono(tempsCourant) # modifier le chrono du bouton
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = ComboFiles() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionShowFileInExplorer = menu.addAction( translations.TR_SHOW_FILE_IN_EXPLORER) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionShowFileInExplorer, SIGNAL("triggered()"), self._show_file_in_explorer) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _show_file_in_explorer(self): '''Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.''' neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("showFileInExplorer(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class LaserRangeFinder(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletLaserRangeFinder, *args) self.lrf = self.device self.cbe_distance = CallbackEmulator(self.lrf.get_distance, self.cb_distance, self.increase_error_count) self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity, self.cb_velocity, self.increase_error_count) self.current_distance = None # int, cm self.current_velocity = None # float, m/s plots_distance = [('Distance', Qt.red, lambda: self.current_distance, format_distance)] plots_velocity = [('Velocity', Qt.red, lambda: self.current_velocity, '{:.2f} m/s'.format)] self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance) self.plot_widget_velocity = PlotWidget('Velocity [m/s]', plots_velocity) self.mode_label = QLabel('Mode:') self.mode_combo = QComboBox() self.mode_combo.addItem("Distance: 1cm resolution, 40m max") self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max") self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max") self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max") self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max") self.mode_combo.currentIndexChanged.connect(self.mode_changed) self.mode_combo.hide() self.label_average_distance = QLabel('Moving Average for Distance:') self.spin_average_distance = QSpinBox() self.spin_average_distance.setMinimum(0) self.spin_average_distance.setMaximum(50) self.spin_average_distance.setSingleStep(1) self.spin_average_distance.setValue(10) self.spin_average_distance.editingFinished.connect( self.spin_average_finished) self.label_average_velocity = QLabel('Moving Average for Velocity:') self.spin_average_velocity = QSpinBox() self.spin_average_velocity.setMinimum(0) self.spin_average_velocity.setMaximum(50) self.spin_average_velocity.setSingleStep(1) self.spin_average_velocity.setValue(10) self.spin_average_velocity.editingFinished.connect( self.spin_average_finished) self.enable_laser = QCheckBox("Enable Laser") self.enable_laser.stateChanged.connect(self.enable_laser_changed) self.label_acquisition_count = QLabel('Acquisition Count:') self.spin_acquisition_count = QSpinBox() self.spin_acquisition_count.setMinimum(1) self.spin_acquisition_count.setMaximum(255) self.spin_acquisition_count.setSingleStep(1) self.spin_acquisition_count.setValue(128) self.enable_qick_termination = QCheckBox("Quick Termination") self.label_threshold = QLabel('Threshold:') self.threshold = QCheckBox("Automatic Threshold") self.spin_threshold = QSpinBox() self.spin_threshold.setMinimum(1) self.spin_threshold.setMaximum(255) self.spin_threshold.setSingleStep(1) self.spin_threshold.setValue(1) self.label_frequency = QLabel('Frequency [Hz]:') self.frequency = QCheckBox( "Automatic Frequency (Disable for Velocity)") self.spin_frequency = QSpinBox() self.spin_frequency.setMinimum(10) self.spin_frequency.setMaximum(500) self.spin_frequency.setSingleStep(1) self.spin_frequency.setValue(10) self.spin_acquisition_count.editingFinished.connect( self.configuration_changed) self.enable_qick_termination.stateChanged.connect( self.configuration_changed) self.spin_threshold.editingFinished.connect(self.configuration_changed) self.threshold.stateChanged.connect(self.configuration_changed) self.spin_frequency.editingFinished.connect(self.configuration_changed) self.frequency.stateChanged.connect(self.configuration_changed) layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_distance) layout_h1.addWidget(self.plot_widget_velocity) layout_h2 = QHBoxLayout() layout_h2.addWidget(self.mode_label) layout_h2.addWidget(self.mode_combo) layout_h2.addWidget(self.label_average_distance) layout_h2.addWidget(self.spin_average_distance) layout_h2.addWidget(self.label_average_velocity) layout_h2.addWidget(self.spin_average_velocity) layout_h2.addStretch() layout_h2.addWidget(self.enable_laser) layout_h3 = QHBoxLayout() layout_h3.addWidget(self.label_frequency) layout_h3.addWidget(self.spin_frequency) layout_h3.addWidget(self.frequency) layout_h3.addStretch() layout_h3.addWidget(self.enable_qick_termination) layout_h4 = QHBoxLayout() layout_h4.addWidget(self.label_threshold) layout_h4.addWidget(self.spin_threshold) layout_h4.addWidget(self.threshold) layout_h4.addStretch() layout_h4.addWidget(self.label_acquisition_count) layout_h4.addWidget(self.spin_acquisition_count) self.widgets_distance = [ self.plot_widget_distance, self.spin_average_distance, self.label_average_distance ] self.widgets_velocity = [ self.plot_widget_velocity, self.spin_average_velocity, self.label_average_velocity ] for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.hide() line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addLayout(layout_h1) layout.addWidget(line) layout.addLayout(layout_h2) layout.addLayout(layout_h3) layout.addLayout(layout_h4) self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0, 3) self.has_configuration_api = self.firmware_version >= (2, 0, 3) def start(self): if self.has_sensor_hardware_version_api: async_call(self.lrf.get_sensor_hardware_version, None, self.get_sensor_hardware_version_async, self.increase_error_count) else: self.get_sensor_hardware_version_async(1) if self.has_configuration_api: async_call(self.lrf.get_configuration, None, self.get_configuration_async, self.increase_error_count) async_call(self.lrf.get_mode, None, self.get_mode_async, self.increase_error_count) async_call(self.lrf.is_laser_enabled, None, self.is_laser_enabled_async, self.increase_error_count) async_call(self.lrf.get_moving_average, None, self.get_moving_average_async, self.increase_error_count) async_call(self.lrf.get_distance, None, self.cb_distance, self.increase_error_count) async_call(self.lrf.get_velocity, None, self.cb_velocity, self.increase_error_count) self.cbe_distance.set_period(25) self.cbe_velocity.set_period(25) self.plot_widget_distance.stop = False self.plot_widget_velocity.stop = False def stop(self): self.cbe_distance.set_period(0) self.cbe_velocity.set_period(0) self.plot_widget_distance.stop = True self.plot_widget_velocity.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLaserRangeFinder.DEVICE_IDENTIFIER def is_laser_enabled_async(self, enabled): if enabled: self.enable_laser.setChecked(True) else: self.enable_laser.setChecked(False) def enable_laser_changed(self, state): if state == Qt.Checked: self.lrf.enable_laser() else: self.lrf.disable_laser() def mode_changed(self, value): if value < 0 or value > 4: return self.lrf.set_mode(value) if value == 0: for w in self.widgets_velocity: w.hide() for w in self.widgets_distance: w.show() else: for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.show() def cb_distance(self, distance): self.current_distance = distance def cb_velocity(self, velocity): self.current_velocity = velocity / 100.0 def configuration_changed(self): acquisition_count = self.spin_acquisition_count.value() enable_quick_termination = self.enable_qick_termination.isChecked() if self.threshold.isChecked(): threshold = 0 else: threshold = self.spin_threshold.value() if self.frequency.isChecked(): frequency = 0 for w in self.widgets_velocity: w.hide() else: frequency = self.spin_frequency.value() for w in self.widgets_velocity: w.show() self.spin_threshold.setDisabled(threshold == 0) self.spin_frequency.setDisabled(frequency == 0) self.lrf.set_configuration(acquisition_count, enable_quick_termination, threshold, frequency) def get_configuration_async(self, conf): self.spin_acquisition_count.blockSignals(True) self.spin_acquisition_count.setValue(conf.acquisition_count) self.spin_acquisition_count.blockSignals(False) self.enable_qick_termination.blockSignals(True) self.enable_qick_termination.setChecked(conf.enable_quick_termination) self.enable_qick_termination.blockSignals(False) self.spin_threshold.blockSignals(True) self.spin_threshold.setValue(conf.threshold_value) self.spin_threshold.setDisabled(conf.threshold_value == 0) self.spin_threshold.blockSignals(False) self.spin_frequency.blockSignals(True) self.spin_frequency.setValue(conf.measurement_frequency) self.spin_frequency.setDisabled(conf.measurement_frequency == 0) self.spin_frequency.blockSignals(False) self.threshold.blockSignals(True) self.threshold.setChecked(conf.threshold_value == 0) self.threshold.blockSignals(False) self.frequency.blockSignals(True) self.frequency.setChecked(conf.measurement_frequency == 0) self.frequency.blockSignals(False) self.configuration_changed() def get_sensor_hardware_version_async(self, value): if value == 1: self.mode_combo.show() self.mode_label.show() self.label_acquisition_count.hide() self.spin_acquisition_count.hide() self.enable_qick_termination.hide() self.label_threshold.hide() self.spin_threshold.hide() self.threshold.hide() self.label_frequency.hide() self.spin_frequency.hide() self.frequency.hide() else: self.mode_combo.hide() self.mode_label.hide() self.label_acquisition_count.show() self.spin_acquisition_count.show() self.enable_qick_termination.show() self.label_threshold.show() self.spin_threshold.show() self.threshold.show() self.label_frequency.show() self.spin_frequency.show() self.frequency.show() for w in self.widgets_distance: w.show() for w in self.widgets_velocity: w.show() def get_mode_async(self, value): self.mode_combo.setCurrentIndex(value) self.mode_changed(value) def get_moving_average_async(self, avg): self.spin_average_distance.setValue(avg.distance_average_length) self.spin_average_velocity.setValue(avg.velocity_average_length) def spin_average_finished(self): self.lrf.set_moving_average(self.spin_average_distance.value(), self.spin_average_velocity.value())
class preferencesDialog(QDialog): newMailerMessage = QtCore.Signal(str, str) def __init__(self, parent): QDialog.__init__(self, parent) self.tmpPref = {} self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.audioManager = parent.audioManager self.mailer = emailSender(self) self.newMailerMessage.connect(self.popMailerMessage) self.tabWidget = QTabWidget() self.tabWidget.currentChanged.connect(self.tabChanged) self.appPrefWidget = QWidget() self.soundPrefWidget = QWidget() self.notificationPrefWidget = QWidget() self.eegPrefWidget = QWidget() #the gui widget for these are in an external dialog self.wavsPref = {} self.wavsPref['endMessageFiles'] = self.tmpPref['pref']['general']['endMessageFiles'] self.wavsPref['endMessageFilesUse'] = self.tmpPref['pref']['general']['endMessageFilesUse'] self.wavsPref['endMessageFilesID'] = self.tmpPref['pref']['general']['endMessageFilesID'] self.wavsPref['endMessageLevels'] = self.tmpPref['pref']['general']['endMessageLevels'] #GENERAL PREF appPrefGrid = QGridLayout() n = 0 self.languageChooserLabel = QLabel(self.tr('Language (requires restart):')) appPrefGrid.addWidget(self.languageChooserLabel, n, 0) self.languageChooser = QComboBox() self.languageChooser.addItems(self.parent().prm['appData']['available_languages']) self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.languageChooser.currentIndexChanged[int].connect(self.onLanguageChooserChange) appPrefGrid.addWidget(self.languageChooser, n, 1) n = n+1 self.countryChooserLabel = QLabel(self.tr('Country (requires restart):')) appPrefGrid.addWidget(self.countryChooserLabel, n, 0) self.countryChooser = QComboBox() self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['language']]) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) appPrefGrid.addWidget(self.countryChooser, n, 1) n = n+1 self.responseBoxLanguageChooserLabel = QLabel(self.tr('Response Box Language (requires restart):')) appPrefGrid.addWidget(self.responseBoxLanguageChooserLabel, n, 0) self.responseBoxLanguageChooser = QComboBox() self.responseBoxLanguageChooser.addItems(self.parent().prm['appData']['available_languages']) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxLanguageChooser.currentIndexChanged[int].connect(self.onResponseBoxLanguageChooserChange) appPrefGrid.addWidget(self.responseBoxLanguageChooser, n, 1) n = n+1 self.responseBoxCountryChooserLabel = QLabel(self.tr('Response Box Country (requires restart):')) appPrefGrid.addWidget(self.responseBoxCountryChooserLabel, n, 0) self.responseBoxCountryChooser = QComboBox() self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['responseBoxLanguage']]) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) appPrefGrid.addWidget(self.responseBoxCountryChooser, n, 1) n = n+1 self.csvSeparatorLabel = QLabel(self.tr('csv separator:')) appPrefGrid.addWidget(self.csvSeparatorLabel, n, 0) self.csvSeparatorWidget = QLineEdit(self.tmpPref['pref']["general"]["csvSeparator"]) appPrefGrid.addWidget(self.csvSeparatorWidget, n, 1) n = n+1 self.listenerNameWarnCheckBox = QCheckBox(self.tr('Warn if listener name missing')) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) appPrefGrid.addWidget(self.listenerNameWarnCheckBox, n, 0) n = n+1 self.sessionLabelWarnCheckBox = QCheckBox(self.tr('Warn if session label missing')) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) appPrefGrid.addWidget(self.sessionLabelWarnCheckBox, n, 0) n = n+1 self.dpCorrCheckBox = QCheckBox(self.tr('d-prime correction')) self.dpCorrCheckBox.setChecked(self.tmpPref['pref']['general']['dprimeCorrection']) self.dpCorrCheckBox.setWhatsThis(self.tr("If checked, when automatically processing result files, convert hit rates of 0 and 1 to 1/2N and 1-1/(2N) respectively, where N is the number of trials, to avoid infinite values of d'")) appPrefGrid.addWidget(self.dpCorrCheckBox, n, 0) n = n+1 self.recursionLimitLabel = QLabel(self.tr('Max Recursion Depth (requires restart):')) appPrefGrid.addWidget(self.recursionLimitLabel, n, 0) self.recursionLimitWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["maxRecursionDepth"])) self.recursionLimitWidget.setValidator(QIntValidator(self)) appPrefGrid.addWidget(self.recursionLimitWidget, n, 1) n = n+1 n = n+1 self.startupCommandLabel = QLabel(self.tr('Execute command at startup:')) appPrefGrid.addWidget(self.startupCommandLabel, n, 0) self.startupCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["startupCommand"]) appPrefGrid.addWidget(self.startupCommandWidget, n, 1) n = n+1 self.appPrefWidget.setLayout(appPrefGrid) self.appPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) #SOUND PREF soundPrefGrid = QGridLayout() n = 0 self.playChooser = QComboBox() self.playChooser.addItems(self.parent().prm['appData']['available_play_commands']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) self.playChooser.currentIndexChanged[int].connect(self.onPlayChooserChange) self.playChooserLabel = QLabel(self.tr('Play Command:')) soundPrefGrid.addWidget(self.playChooserLabel, 0, 0) soundPrefGrid.addWidget(self.playChooser, 0, 1) n = n+1 self.playCommandLabel = QLabel(self.tr('Command:')) soundPrefGrid.addWidget(self.playCommandLabel, n, 0) self.playCommandWidget = QLineEdit(self.tmpPref['pref']['sound']['playCommand']) if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) soundPrefGrid.addWidget(self.playCommandWidget, n, 1) n = n+1 foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() #if alsaaudio is selected, provide device list chooser if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioPlaybackCardList = self.listAlsaaudioPlaybackCards() self.alsaaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.alsaaudioDeviceLabel, n, 0) self.alsaaudioDeviceChooser = QComboBox() self.alsaaudioDeviceChooser.addItems(self.alsaaudioPlaybackCardList) self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref["pref"]["sound"]["alsaaudioDevice"])) soundPrefGrid.addWidget(self.alsaaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "alsaaudio": self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() #if pyaudio is selected, provide device list chooser if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.listPyaudioPlaybackDevices() self.pyaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.pyaudioDeviceLabel, n, 0) self.pyaudioDeviceChooser = QComboBox() self.pyaudioDeviceChooser.addItems(self.pyaudioDeviceListName) try: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) except: self.tmpPref["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.parent().prm["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) soundPrefGrid.addWidget(self.pyaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "pyaudio": self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeLabel = QLabel(self.tr('Buffer Size (samples):')) soundPrefGrid.addWidget(self.bufferSizeLabel, n, 0) self.bufferSizeWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["bufferSize"])) self.bufferSizeWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.bufferSizeWidget, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] not in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() self.samplerateLabel = QLabel(self.tr('Default Sampling Rate:')) soundPrefGrid.addWidget(self.samplerateLabel, n, 0) self.samplerateWidget = QLineEdit(self.tmpPref["pref"]["sound"]["defaultSampleRate"]) #self.samplerateWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.samplerateWidget, n, 1) n = n+1 self.nbitsLabel = QLabel(self.tr('Default Bits:')) self.nbitsChooser = QComboBox() self.nbitsChooser.addItems(self.parent().prm["nBitsChoices"]) self.nbitsChooser.setCurrentIndex(self.parent().prm["nBitsChoices"].index(self.tmpPref["pref"]["sound"]["defaultNBits"])) soundPrefGrid.addWidget(self.nbitsLabel, n, 0) soundPrefGrid.addWidget(self.nbitsChooser, n, 1) n = n+1 self.wavmanagerLabel = QLabel(self.tr('Wav Manager (requires restart):')) self.wavmanagerChooser = QComboBox() self.wavmanagerChooser.addItems(self.parent().prm['appData']['wavmanagers']) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) soundPrefGrid.addWidget(self.wavmanagerLabel, n, 0) soundPrefGrid.addWidget(self.wavmanagerChooser, n, 1) n = n+1 self.writewav = QCheckBox(self.tr('Write wav file')) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) soundPrefGrid.addWidget(self.writewav, n, 0) n = n+1 self.writeSndSeqSegments = QCheckBox(self.tr('Write sound sequence segments wavs')) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) soundPrefGrid.addWidget(self.writeSndSeqSegments, n, 0) n = n+1 self.appendSilenceLabel = QLabel(self.tr('Append silence to each sound (ms):')) soundPrefGrid.addWidget(self.appendSilenceLabel, n, 0) self.appendSilenceWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["appendSilence"])) soundPrefGrid.addWidget(self.appendSilenceWidget, n, 1) n = n+1 self.soundPrefWidget.setLayout(soundPrefGrid) self.soundPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # NOTIFICATION PREF notificationPrefGrid = QGridLayout() n = 0 self.playEndMessage = QCheckBox(self.tr('Play End Message')) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) notificationPrefGrid.addWidget(self.playEndMessage, n, 0) self.endMessageButton = QPushButton(self.tr("Choose Wav"), self) self.endMessageButton.clicked.connect(self.onClickEndMessageButton) notificationPrefGrid.addWidget(self.endMessageButton, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.nBlocksLabel = QLabel(self.tr('blocks before end of experiment:')) notificationPrefGrid.addWidget(self.nBlocksLabel, n, 1) self.nBlocksWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) notificationPrefGrid.addWidget(self.nBlocksWidget, n, 0) n = n+1 self.emailNotify = QCheckBox(self.tr('Send Notification e-mail')) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) notificationPrefGrid.addWidget(self.emailNotify, n, 0) n = n+1 self.nBlocksCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.nBlocksCustomCommandLabel, n, 0) self.nBlocksCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) notificationPrefGrid.addWidget(self.nBlocksCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.atEndLabel = QLabel(self.tr('At the end of the experiment:')) notificationPrefGrid.addWidget(self.atEndLabel, n, 0) n = n+1 self.sendData = QCheckBox(self.tr('Send data via e-mail')) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) notificationPrefGrid.addWidget(self.sendData, n, 0) n = n+1 self.atEndCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.atEndCustomCommandLabel, n, 0) self.atEndCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["atEndCustomCommand"]) notificationPrefGrid.addWidget(self.atEndCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.serverLabel = QLabel(self.tr('Outgoing server (SMTP):')) notificationPrefGrid.addWidget(self.serverLabel, n, 0) self.serverWidget = QLineEdit(self.tmpPref['pref']['email']['SMTPServer']) notificationPrefGrid.addWidget(self.serverWidget, n, 1) n = n+1 self.serverPortLabel = QLabel(self.tr('Port:')) notificationPrefGrid.addWidget(self.serverPortLabel, n, 0) self.serverPortWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.serverPortWidget.setValidator(QIntValidator(self)) notificationPrefGrid.addWidget(self.serverPortWidget, n, 1) n = n+1 self.serverSecurityLabel = QLabel(self.tr('Security:')) notificationPrefGrid.addWidget(self.serverSecurityLabel, n, 0) self.serverSecurityChooser = QComboBox() self.serverSecurityChooser.addItems(["TLS/SSL (a)", "TLS/SSL (b)", "none"]) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) notificationPrefGrid.addWidget(self.serverSecurityChooser, n, 1) n = n+1 self.serverRequiresAuthCheckBox = QCheckBox(self.tr('Server requires authentication')) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) notificationPrefGrid.addWidget(self.serverRequiresAuthCheckBox, n, 0, 1, 2) n = n+1 self.usernameLabel = QLabel(self.tr('Username:'******'pref']['email']['fromUsername']) notificationPrefGrid.addWidget(self.usernameWidget, n, 1) n = n+1 self.passwordLabel = QLabel(self.tr('Password:'******'pref']['email']['fromPassword']) self.passwordWidget.setEchoMode(QLineEdit.Password) notificationPrefGrid.addWidget(self.passwordWidget, n, 1) n = n+1 self.passwordWarningLabel = QLabel(self.tr('Password is NOT stored safely (see manual), use at your own risk!')) notificationPrefGrid.addWidget(self.passwordWarningLabel, n, 0, 1, 2) n = n+1 self.testEmailButton = QPushButton(self.tr("Send test e-mail"), self) self.testEmailButton.clicked.connect(self.onClickTestEmailButton) self.testEmailButton.setToolTip(self.tr("Send a test e-mail")) notificationPrefGrid.addWidget(self.testEmailButton, n, 0, 1, 2) self.notificationPrefWidget.setLayout(notificationPrefGrid) self.notificationPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) ##--#--#--#--#-- # EEG PREF GRID eegPrefGrid = QGridLayout() n = 0 self.ONTriggerLabel = QLabel(self.tr('ON Trigger:')) eegPrefGrid.addWidget(self.ONTriggerLabel, n, 0) self.ONTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["ONTrigger"])) eegPrefGrid.addWidget(self.ONTriggerWidget, n, 1) n = n+1 self.OFFTriggerLabel = QLabel(self.tr('OFF Trigger:')) eegPrefGrid.addWidget(self.OFFTriggerLabel, n, 0) self.OFFTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["OFFTrigger"])) eegPrefGrid.addWidget(self.OFFTriggerWidget, n, 1) n = n+1 self.triggerDurLabel = QLabel(self.tr('Trigger Duration (ms):')) eegPrefGrid.addWidget(self.triggerDurLabel, n, 0) self.triggerDurWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["triggerDur"])) eegPrefGrid.addWidget(self.triggerDurWidget, n, 1) self.eegPrefWidget.setLayout(eegPrefGrid) self.eegPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # ........................ self.tabWidget.addTab(self.appPrefWidget, self.tr("Genera&l")) self.tabWidget.addTab(self.soundPrefWidget, self.tr("Soun&d")) self.tabWidget.addTab(self.notificationPrefWidget, self.tr("Notification&s")) self.tabWidget.addTab(self.eegPrefWidget, self.tr("EE&G")) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply) layout = QVBoxLayout() layout.addWidget(self.tabWidget) layout.addWidget(buttonBox) self.setLayout(layout) def onLanguageChooserChange(self): for i in range(self.countryChooser.count()): self.countryChooser.removeItem(0) self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.languageChooser.currentText()]) def onResponseBoxLanguageChooserChange(self): for i in range(self.responseBoxCountryChooser.count()): self.responseBoxCountryChooser.removeItem(0) self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.responseBoxLanguageChooser.currentText()]) def onPlayChooserChange(self): foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() self.playCommandWidget.setText(foo) self.playCommandWidget.setReadOnly(True) else: self.playCommandWidget.show() self.playCommandLabel.show() self.playCommandWidget.setReadOnly(False) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: if foo == "alsaaudio": self.alsaaudioDeviceLabel.show() self.alsaaudioDeviceChooser.show() else: self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() if self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo == "pyaudio": self.pyaudioDeviceLabel.show() self.pyaudioDeviceChooser.show() else: self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.show() self.bufferSizeWidget.show() else: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() def onClickEndMessageButton(self): dialog = wavListDialog(self) if dialog.exec_(): self.wavsList = dialog.wavsList self.wavsPref = {} self.wavsPref['endMessageFiles'] = [] self.wavsPref['endMessageFilesUse'] = [] self.wavsPref['endMessageFilesID'] = [] self.wavsPref['endMessageLevels'] = [] keys = sorted(self.wavsList.keys()) for key in keys: self.wavsPref['endMessageFiles'].append(str(self.wavsList[key]['file'])) self.wavsPref['endMessageFilesUse'].append(self.wavsList[key]['use']) self.wavsPref['endMessageLevels'].append(self.wavsList[key]['level']) self.wavsPref['endMessageFilesID'].append(key) def onClickTestEmailButton(self): self.mailer.sendTestEmail() def popMailerMessage(self, msg, msgtype): if msgtype == 'critical': QMessageBox.critical(self, self.tr("Error"), msg) elif msgtype == 'warning': QMessageBox.warning(self, self.tr("Warning"), msg) elif msgtype == 'information': QMessageBox.information(self, self.tr("Information"), msg) def tryApply(self): self.tmpPref['pref']['language'] = self.tr(self.languageChooser.currentText()) self.tmpPref['pref']['country'] = self.tr(self.countryChooser.currentText()) self.tmpPref['pref']['responseBoxLanguage'] = self.tr(self.responseBoxLanguageChooser.currentText()) self.tmpPref['pref']['responseBoxCountry'] = self.tr(self.responseBoxCountryChooser.currentText()) self.tmpPref['pref']['general']['csvSeparator'] = self.csvSeparatorWidget.text() self.tmpPref['pref']['general']['ONTrigger'] = self.currLocale.toInt(self.ONTriggerWidget.text())[0] self.tmpPref['pref']['general']['OFFTrigger'] = self.currLocale.toInt(self.OFFTriggerWidget.text())[0] self.tmpPref['pref']['general']['triggerDur'] = self.currLocale.toDouble(self.triggerDurWidget.text())[0] self.tmpPref['pref']['general']['maxRecursionDepth'] = self.currLocale.toInt(self.recursionLimitWidget.text())[0] self.tmpPref['pref']['general']['startupCommand'] = self.startupCommandWidget.text() self.tmpPref['pref']['sound']['playCommand'] = self.tr(self.playCommandWidget.text()) self.tmpPref['pref']['sound']['playCommandType'] = self.tr(self.playChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.tmpPref['pref']['sound']['alsaaudioDevice'] = self.alsaaudioDeviceChooser.currentText() if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['pyaudioDevice'] = self.pyaudioDeviceListIdx[self.pyaudioDeviceChooser.currentIndex()] self.tmpPref['pref']['sound']['wavmanager'] = str(self.wavmanagerChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['bufferSize'] = self.currLocale.toInt(self.bufferSizeWidget.text())[0] self.tmpPref['pref']['sound']['defaultSampleRate'] = self.samplerateWidget.text() self.tmpPref['pref']['sound']['defaultNBits'] = self.nbitsChooser.currentText() self.tmpPref['pref']['sound']['appendSilence'] = self.currLocale.toInt(self.appendSilenceWidget.text())[0] self.tmpPref["pref"]["email"]["nBlocksNotify"] = self.currLocale.toInt(self.nBlocksWidget.text())[0] self.tmpPref["pref"]["general"]["nBlocksCustomCommand"] = self.nBlocksCustomCommandWidget.text() self.tmpPref["pref"]["general"]["atEndCustomCommand"] = self.atEndCustomCommandWidget.text() self.tmpPref["pref"]["email"]['SMTPServer'] = self.serverWidget.text() self.tmpPref["pref"]["email"]['SMTPServerPort'] = self.currLocale.toInt(self.serverPortWidget.text())[0] self.tmpPref["pref"]["email"]['fromUsername'] = self.usernameWidget.text() self.tmpPref["pref"]["email"]['SMTPServerSecurity'] = self.serverSecurityChooser.currentText() self.tmpPref["pref"]["general"]["endMessageFiles"] = self.wavsPref['endMessageFiles'] self.tmpPref["pref"]["general"]["endMessageFilesUse"] = self.wavsPref['endMessageFilesUse'] self.tmpPref["pref"]["general"]["endMessageFilesID"] = self.wavsPref['endMessageFilesID'] self.tmpPref["pref"]["general"]["endMessageLevels"] = self.wavsPref['endMessageLevels'] self.tmpPref["pref"]["email"]['fromPassword'] = self.passwordWidget.text() if self.writewav.isChecked(): self.tmpPref['pref']['sound']['writewav'] = True else: self.tmpPref['pref']['sound']['writewav'] = False if self.writeSndSeqSegments.isChecked(): self.tmpPref['pref']['sound']['writeSndSeqSegments'] = True else: self.tmpPref['pref']['sound']['writeSndSeqSegments'] = False if self.dpCorrCheckBox.isChecked(): self.tmpPref['pref']['general']['dprimeCorrection'] = True else: self.tmpPref['pref']['general']['dprimeCorrection'] = False if self.listenerNameWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['listenerNameWarn'] = True else: self.tmpPref['pref']['general']['listenerNameWarn'] = False if self.sessionLabelWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['sessionLabelWarn'] = True else: self.tmpPref['pref']['general']['sessionLabelWarn'] = False if self.emailNotify.isChecked(): self.tmpPref['pref']['email']['notifyEnd'] = True else: self.tmpPref['pref']['email']['notifyEnd'] = False if self.sendData.isChecked(): self.tmpPref['pref']['email']['sendData'] = True else: self.tmpPref['pref']['email']['sendData'] = False if self.serverRequiresAuthCheckBox.isChecked(): self.tmpPref['pref']['email']['serverRequiresAuthentication'] = True else: self.tmpPref['pref']['email']['serverRequiresAuthentication'] = False if self.playEndMessage.isChecked(): self.tmpPref['pref']['general']['playEndMessage'] = True else: self.tmpPref['pref']['general']['playEndMessage'] = False if self.tmpPref['pref']['email']['notifyEnd'] == True or self.tmpPref['pref']['email']['sendData'] == True: if checkUsernameValid(self.tmpPref["pref"]["email"]['fromUsername']) == False: errMsg = self.tr("Username invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False elif checkServerValid(self.tmpPref["pref"]["email"]['SMTPServer']) == False: errMsg = self.tr("SMTP server name invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False def revertChanges(self): self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) self.csvSeparatorWidget.setText(self.tmpPref['pref']['general']['csvSeparator']) self.ONTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['ONTrigger'])) self.OFFTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['OFFTrigger'])) self.triggerDurWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['triggerDur'])) self.recursionLimitWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['maxRecursionDepth'])) self.startupCommandWidget.setText(self.tmpPref['pref']['general']['startupCommand']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref['pref']['sound']['alsaaudioDevice'])) if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref['pref']['sound']['pyaudioDevice'])) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) self.playCommandWidget.setText(self.tmpPref['pref']['sound']['playCommand']) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['bufferSize'])) self.samplerateWidget.setText(self.tmpPref['pref']['sound']['defaultSampleRate']) self.nbitsChooser.setCurrentIndex(self.nbitsChooser.findText(self.tmpPref['pref']['sound']['defaultNBits'])) self.appendSilenceWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['appendSilence'])) self.nBlocksWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) self.nBlocksCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.atEndCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.serverWidget.setText(self.tmpPref['pref']['email']['SMTPServer']) self.serverPortWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.usernameWidget.setText(self.tmpPref['pref']['email']['fromUsername']) self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) self.wavsPref["endMessageFiles"] = self.tmpPref["pref"]["general"]["endMessageFiles"] self.wavsPref["endMessageFilesUse"] = self.tmpPref["pref"]["general"]["endMessageFilesUse"] self.wavsPref["endMessageFilesID"] = self.tmpPref["pref"]["general"]["endMessageFilesID"] self.wavsPref["endMessageLevels"] = self.tmpPref["pref"]["general"]["endMessageLevels"] if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) self.dpCorrCheckBox.setChecked(self.tmpPref["pref"]["general"]["dprimeCorrection"]) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) def permanentApply(self): self.tryApply() if self.parent().prm['pref']['email']['fromPassword'] != self.tmpPref['pref']['email']['fromPassword']: passwd = bytes(self.passwordWidget.text(),'utf-8') encoded_passwd = base64.b64encode(passwd) encoded_passwd = str(encoded_passwd, "utf-8") #passwd = hashlib.sha1(passwd).hexdigest() self.tmpPref["pref"]["email"]['fromPassword'] = encoded_passwd self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.parent().prm['pref'] = copy.deepcopy(self.tmpPref['pref']) f = open(self.parent().prm['prefFile'], 'wb') pickle.dump(self.parent().prm['pref'], f) f.close() def tabChanged(self): self.tryApply() if self.tmpPref['pref'] != self.parent().prm['pref']: reply = QMessageBox.warning(self, self.tr("Warning"), self.tr('There are unsaved changes. Apply Changes?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.Yes: self.permanentApply() else: self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.revertChanges() def listAlsaaudioPlaybackCards(self): playbackCardList = [] for card in alsaaudio.cards(): try: alsaaudio.PCM(type=alsaaudio.PCM_PLAYBACK, mode=alsaaudio.PCM_NORMAL, card=card) playbackCardList.append(card) except: pass return playbackCardList def listPyaudioPlaybackDevices(self): self.pyaudioHostApiListName = [] self.pyaudioHostApiListIdx = [] self.pyaudioDeviceListName = [] self.pyaudioDeviceListIdx = [] paManager = pyaudio.PyAudio() nDevices = paManager.get_device_count() nApi = paManager.get_host_api_count() for i in range(nApi): self.pyaudioHostApiListName.append(paManager.get_host_api_info_by_index(i)['name']) self.pyaudioHostApiListIdx.append(paManager.get_host_api_info_by_index(i)['index']) for i in range(nDevices): thisDevInfo = paManager.get_device_info_by_index(i) if thisDevInfo["maxOutputChannels"] > 0: self.pyaudioDeviceListName.append(thisDevInfo["name"] + ' - ' + self.pyaudioHostApiListName[thisDevInfo["hostApi"]]) self.pyaudioDeviceListIdx.append(thisDevInfo["index"]) return
class reglageExpert(QWidget) : """Class pour créer les widgets spécifiques pour les réglages plus fin sur la qualité d'encodage, sur le débit binaire des fichiers, ... """ def __init__(self, listeFormat, comboFormat, parent=None) : super(reglageExpert, self).__init__(parent) self.listeFormat = listeFormat self.comboFormat = comboFormat self.format = self.comboFormat.currentIndex() self.parent = parent layout = QHBoxLayout(self) self.textLabel = QLabel(self) self.textLabel.hide() self.expert = QCheckBox(_(u"Réglage expert : "), self) self.qualite = QComboBox(self) layout.addWidget(self.expert) layout.addWidget(self.textLabel) layout.addWidget(self.qualite) layout.addStretch() i=1 while i<9 : self.qualite.addItem(str(i)) i += 1 self.qualite.hide() self.changeFormat(self.comboFormat.currentIndex()) self.connect(self.expert, SIGNAL("stateChanged(int)"), self.setExpert) self.connect(self.comboFormat, SIGNAL("currentIndexChanged(int)"), self.changeFormat) self.connect(self.qualite, SIGNAL("currentIndexChanged(int)"), self.changeQualite) def setExpert(self, state) : if state : self.qualite.show() self.textLabel.show() else : self.qualite.hide() self.textLabel.hide() def changeQualite(self,qualite) : self.changeFormat(self.comboFormat.currentIndex()) def changeFormat(self, format) : if len(self.listeFormat) == 0 : return else : if self.listeFormat[format] == "mp3" or self.listeFormat[format] == "mp2" or self.listeFormat[format] == "ogg" : self.textLabel.setText(_(u"Qualité d'encodage")) self.qualite.setEnabled(True) self.C = u" -C %f " % (10.0*float(self.qualite.currentIndex()+1)/8.0) elif self.listeFormat[format] == "flac" : self.textLabel.setText(_(u"Taux de compression")) self.qualite.setEnabled(True) self.C = u" -C %d " % (self.qualite.currentIndex()+1) else : self.textLabel.setText(_(u"Non applicable, format non compressé")) self.qualite.setDisabled(True) self.C = u"" def getExpertState(self) : return self.expert.isChecked() def getC(self) : return self.C def saveConfig(self, idsection="") : if idsection == "" : return EkdConfig.set(idsection, u'format', unicode(self.comboFormat.currentIndex())) EkdConfig.set(idsection, u'expert', unicode(int(self.getExpertState()))) EkdConfig.set(idsection, u'qualite', unicode(self.qualite.currentIndex())) def loadConfig(self, idsection="") : if idsection == "" : return self.comboFormat.setCurrentIndex(int(EkdConfig.get(idsection, 'format'))) self.expert.setChecked(int(EkdConfig.get(idsection, 'expert'))) self.qualite.setCurrentIndex(int(EkdConfig.get(idsection, 'qualite')))
class UserDialog(QDialog): holdc = {} def __init__(self, parent=None): super(UserDialog, self).__init__(parent) self.pagetitle = self.sessionname self.tableFont = QFont('Century Gothic', 8) self.table = QTableWidget() self.cols = [ 'SN', 'ITEM', 'QUANTITY', 'UNIT AMOUNT', 'TOTAL AMOUNT', 'DATE' ] self.h1_pull_box = QVBoxLayout() #self.tableFont.setFamily('Century Gothic') self.tableHeaderStyle = "::section {" "background-color: teal; color:white}" #pull all CA self.editID = 0 self.hold_unit = {} self.hold_store = {} self.hold_storeGroup = {} self.hold_borrowed = {} from_label = QLabel('From:') to_label = QLabel('To:') self.fromData = QDateEdit() self.toData = QDateEdit() currentDate = QDate() self.fromData.setDate(currentDate.currentDate()) self.fromData.setCalendarPopup(True) self.toData.setDate(currentDate.currentDate()) self.toData.setCalendarPopup(True) menu = QMenu() menu.addAction('All', lambda: self.reloadTable(0)) menu.addAction('In-Stock', lambda: self.reloadTable(1)) menu.addAction('Out-Stock', lambda: self.reloadTable(2)) menu.addAction('Damaged', lambda: self.reloadTable(3)) menu.addAction('Borrowed', lambda: self.reloadTable(4)) self.pull_btn = QPushButton() self.pull_btn.setText("Load") self.pull_btn.setMenu(menu) h_pull_box = QHBoxLayout() h_pull_box.addWidget(from_label) h_pull_box.addWidget(self.fromData) h_pull_box.addWidget(to_label) h_pull_box.addWidget(self.toData) h_pull_box.addWidget(self.pull_btn) storeGroup = self.pullGroupStore() unit = self.pullUnit() self.storeGroupText = QLabel('Category') self.storeGroupData = QComboBox() self.storeGroupData.currentIndexChanged.connect(self.reloadStore) self.storeText = QLabel('Items') self.storeData = QComboBox() self.amountText = QLabel('Total Cost') self.amountData = QLineEdit() self.amountData.setPlaceholderText('0000.00') self.tellerText = QLabel('Reciept No.') self.tellerData = QLineEdit() self.tellerData.setPlaceholderText('xxxxxxxxx') self.quantityText = QLabel('Quantity.') self.quantityData = QLineEdit() self.quantityData.setPlaceholderText('00.0') self.periodText = QLabel('Period (days)') self.periodData = QLineEdit() self.periodData.setPlaceholderText('00.0') self.personText = QLabel('Recieved By:') self.personData = QLineEdit() self.personData.setPlaceholderText('00.0') self.unitText = QLabel('Unit') self.unitData = QComboBox() self.borrowedText = QLabel('Borrowed') self.borrowedData = QComboBox() self.dateText = QLabel('Date') self.dateData = QDateEdit() self.dateData.setDate(currentDate.currentDate()) self.dateData.setCalendarPopup(True) self.descriptionText = QLabel('Description') self.descriptionData = QPlainTextEdit() self.descriptionData.move(200, 100) self.borrowedText.hide() self.borrowedData.hide() mboz = QVBoxLayout() hboz = QHBoxLayout() self.state = QLabel('') self.r1 = QRadioButton('In-stock') self.r1.setChecked(True) self.r1.toggled.connect(lambda: self.changeStates()) self.r2 = QRadioButton('Out-stock') self.r2.toggled.connect(lambda: self.changeStates()) self.r3 = QRadioButton('Damaged') self.r3.toggled.connect(lambda: self.changeStates()) self.r4 = QRadioButton('Borrowed') self.r4.toggled.connect(lambda: self.changeStates()) self.r5 = QRadioButton('Returned') self.r5.toggled.connect(lambda: self.changeStates()) hboz.addWidget(self.r1) hboz.addWidget(self.r2) hboz.addWidget(self.r3) hboz.addWidget(self.r4) hboz.addWidget(self.r5) i = 0 for a in storeGroup: self.hold_storeGroup[i] = a['id'] tex = str(a['name']).upper() self.storeGroupData.addItem(tex) i += 1 i = 0 str_key = self.hold_storeGroup[self.storeGroupData.currentIndex()] store = self.pullStore(str_key) for a in store: self.hold_store[i] = a['id'] tex = str(a['name']).upper() self.storeData.addItem(tex) i += 1 i = 0 for a in unit: self.hold_unit[i] = a['id'] tex = str(a['name']).upper() self.unitData.addItem(tex) i += 1 self.reloadBorrowed() self.FormLayout = QFormLayout() self.FormLayout.addRow(self.storeGroupText, self.storeGroupData) self.FormLayout.addRow(self.storeText, self.storeData) self.FormLayout.addRow(self.tellerText, self.tellerData) self.FormLayout.addRow(self.quantityText, self.quantityData) self.FormLayout.addRow(self.amountText, self.amountData) self.FormLayout.addRow(self.dateText, self.dateData) self.FormLayout.addRow(self.periodText, self.periodData) self.FormLayout.addRow(self.borrowedText, self.borrowedData) self.FormLayout.addRow(self.personText, self.personData) self.FormLayout.addRow(self.descriptionText, self.descriptionData) self.periodText.hide() self.periodData.hide() mboz.addLayout(hboz) mboz.addLayout(self.FormLayout) mboz.addWidget(self.state) groupBox1 = QGroupBox('Add Store Item') groupBox1.setLayout(mboz) self.pb = QPushButton() self.pb.setObjectName("Add") self.pb.setText("Add Store Item") self.pb1 = QPushButton() self.pb1.setObjectName("Edit") self.pb1.setText("Edit Row") self.pb1.setEnabled(False) self.pb2 = QPushButton() self.pb2.setObjectName("Close") self.pb2.setText("Close") self.pb3 = QPushButton() self.pb3.setObjectName("Delete") self.pb3.setText("Delete Row") self.pb3.setEnabled(False) self.pb4 = QPushButton() self.pb4.setObjectName("Reset") self.pb4.setText("Reset") self.pb4.hide() self.pb5 = QPushButton() self.pb5.setObjectName("Change") self.pb5.setText("Change Store") self.pb5.hide() self.pb6 = QPushButton() self.pb6.setObjectName("Clear") self.pb6.setText("Clear Selection") self.pb6.setEnabled(False) hbo = QHBoxLayout() hbo.addWidget(self.pb) hbo.addWidget(self.pb5) hbo.addWidget(self.pb4) hbo.addWidget(self.pb2) groupBox2 = QGroupBox('Store Data') groupBox2.setLayout(hbo) al = self.pullStoreData(0) if al and len(al) > 0: al = al else: al = {} self.storeData.currentIndexChanged.connect( lambda: self.reloadBorrowed()) header = self.table.horizontalHeader() header.setResizeMode(QHeaderView.ResizeToContents) header.setStretchLastSection(True) header.setStyleSheet(self.tableHeaderStyle) vheader = self.table.verticalHeader() vheader.setStyleSheet(self.tableHeaderStyle) # Body self.table.setWindowTitle("Store") self.table.setStyleSheet("color:white") self.table.resize(300, 250) self.table.setFont(self.tableFont) self.table.setSortingEnabled(2) #self.table.resizeColumnsToContents() self.table.setRowCount(len(al)) self.table.setColumnCount(len(self.cols)) self.table.setHorizontalHeaderLabels(self.cols) self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.handleHeaderMenu) self.table.hideColumn(0) self.table.setSelectionMode(QAbstractItemView.MultiSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) i = 0 for q in al: #row id if q['state'] == 1: color = QColor(100, 0, 0) elif q['state'] == 2: color = QColor(100, 100, 0) elif q['state'] == 3: color = QColor(100, 0, 100) elif q['state'] == 4: color = QColor(0, 100, 100) else: color = QColor(0, 50, 150) self.table.setItem(i, 0, QTableWidgetItem(str(q['id']))) self.table.item(i, 0).setBackground(color) self.table.setItem(i, 1, QTableWidgetItem(str(q['itemname']).upper())) self.table.item(i, 1).setBackground(color) self.table.setItem(i, 2, QTableWidgetItem(str(q['quantity']).upper())) self.table.item(i, 2).setBackground(color) try: zamt = str("{:,}".format(float(q['amount']))) except: zamt = '' self.table.setItem(i, 3, QTableWidgetItem(zamt)) self.table.item(i, 3).setBackground(color) try: if len(q['amount']) > 0 and float(q['amount']) > 0: tot = float(q['amount']) * float(q['quantity']) else: tot = 0 except: tot = 0 self.table.setItem(i, 4, QTableWidgetItem(str(tot).upper())) self.table.item(i, 4).setBackground(color) damz = float(q['datepaid']) damt = datetime.utcfromtimestamp(damz).strftime('%d-%m-%Y') self.table.setItem(i, 5, QTableWidgetItem(str(damt))) self.table.item(i, 5).setBackground(color) i += 1 self.table.itemSelectionChanged.connect(self.confirmSelection) self.table.resizeRowsToContents() v_pull_box = QVBoxLayout() self.h1_pull_box.addWidget(self.table) v_pull_box.addLayout(h_pull_box) v_pull_box.addLayout(self.h1_pull_box) h2_pull_box = QHBoxLayout() h2_pull_box.addWidget(self.pb1) h2_pull_box.addWidget(self.pb3) h2_pull_box.addWidget(self.pb6) v_pull_box.addLayout(h2_pull_box) groupBox3 = QGroupBox() groupBox3.setLayout(hbo) groupBox2.setLayout(v_pull_box) grid = QGridLayout() grid.addWidget(groupBox1, 0, 0) grid.addWidget(groupBox2, 0, 1, 2, 1) grid.addWidget(groupBox3, 1, 0) self.setLayout(grid) self.connect(self.pb, SIGNAL("clicked()"), lambda: self.button_click()) self.connect(self.pb1, SIGNAL("clicked()"), lambda: self.button_editshow()) self.connect(self.pb2, SIGNAL("clicked()"), lambda: self.button_close(self)) self.connect(self.pb3, SIGNAL("clicked()"), lambda: self.button_delete()) self.connect(self.pb4, SIGNAL("clicked()"), lambda: self.button_reset()) self.connect(self.pb5, SIGNAL("clicked()"), lambda: self.button_edit()) self.connect(self.pb6, SIGNAL("clicked()"), lambda: self.button_clear()) #self.connect(self.pull_btn, SIGNAL("clicked()"), lambda x =1: self.reloadTable(x)) self.setWindowTitle(self.pagetitle) def stateReciept(self): self.amountText.show() self.amountData.show() self.tellerText.show() self.tellerData.show() self.tellerText.setText('Reciept No.') self.periodText.hide() self.periodData.hide() self.personText.setText('Recieved By:') self.personData.setPlaceholderText('Fullname or department') self.borrowedText.hide() self.borrowedData.hide() self.reloadTable(1) def stateIssue(self): self.amountText.hide() self.amountData.hide() self.tellerText.show() self.tellerData.show() self.tellerText.setText('Issue No.') self.periodText.hide() self.periodData.hide() self.personText.setText('Issued to:') self.personData.setPlaceholderText('Fullname or department issued to') self.borrowedText.hide() self.borrowedData.hide() self.reloadTable(2) def stateDamage(self): self.amountText.hide() self.amountData.hide() self.tellerText.hide() self.tellerData.hide() self.periodText.hide() self.periodData.hide() self.personText.setText('Reported By:') self.personData.setPlaceholderText('Fullname or department') self.borrowedText.hide() self.borrowedData.hide() self.reloadTable(3) def stateBorrowed(self): self.amountText.hide() self.amountData.hide() self.tellerText.hide() self.tellerData.hide() self.periodText.show() self.periodData.show() self.personText.setText('Given to:') self.personData.setPlaceholderText( 'Fullname or department borrowed to') self.borrowedText.hide() self.borrowedData.hide() self.reloadTable(4) def stateReturned(self): self.amountText.hide() self.amountData.hide() self.tellerText.hide() self.tellerData.hide() self.periodText.hide() self.periodData.hide() self.personText.setText('Returned By:') self.personData.setPlaceholderText( 'Fullname or department borrowed to') self.borrowedText.show() self.borrowedData.show() self.reloadBorrowed() self.reloadTable(5) def changeStates(self): self.getQuantity() if self.r1.isChecked(): self.stateReciept() elif self.r2.isChecked(): self.stateIssue() elif self.r3.isChecked(): self.stateDamage() elif self.r4.isChecked(): self.stateBorrowed() elif self.r5.isChecked(): self.stateReturned() def handleHeaderMenu(self, pos): print('column(%d)' % self.table.horizontalHeader().logicalIndexAt(pos)) menu = QMenu() menu.addAction('Add') menu.addAction('Delete') menu.exec_(QCursor.pos()) def pullGroupStore(self): cn = Db() arr = cn.selectn('datas', '', '', {"pubID": 23, "active": 0}) return arr def pullStore(self, a): cn = Db() arr = cn.selectn('datas', '', '', {"subID": a}) return arr def pullUnit(self): cn = Db() arr = cn.selectn('datas', '', '', {"pubID": 20, "active": 0}) return arr def pullStoreData(self, a=None): st_date = self.fromData.date().toPyDate() en_date = self.toData.date().toPyDate() st_date = time.mktime(st_date.timetuple()) en_date = time.mktime(en_date.timetuple()) db = 'school_stores' + str(self.session) cn = Db() arr = cn.selectStoreDate(db, st_date, en_date, a) return arr def mySelectTable(self): ''' get the selected rpws in a table returns list or row ids ''' sels = self.table.selectedIndexes() sels = self.table.selectionModel().selectedRows() park = [] park1 = [] for j in sels: park.append(j.row()) for i in set(park): selected = self.table.item(i, 0).text() park1.append(selected) return park1 def editRow(self, a): _session = self.session g = Db() db = 'school_stores' + str(_session) data = g.selectn(db, '', 1, {'id': a}) if len(data) > 0: try: amt = float(data['amount']) qty = float(data['quantity']) if amt > 0 and qty > 0: cost = amt * qty else: cost = 0 except: cost = 0 amt = 0 qty = 0 if data['state'] == 1: self.r1.setChecked(True) elif data['state'] == 2: self.r2.setChecked(True) elif data['state'] == 3: self.r3.setChecked(True) elif data['state'] == 4: self.r4.setChecked(True) elif data['state'] == 5: self.r5.setChecked(True) self.amountData.setText(str(cost)) self.descriptionData.clear() self.descriptionData.insertPlainText(str(data['description'])) self.tellerData.setText(str(data['teller'])) self.periodData.setText(str(data['period'])) self.personData.setText(str(data['person'])) self.quantityData.setText(str(qty)) stID = self.hold_store.keys()[self.hold_store.values().index( data['itemID'])] self.storeData.setCurrentIndex(stID) def reloadBorrowed(self): self.getQuantity() _store = self.hold_store[self.storeData.currentIndex()] _session = self.session g = Db() db = 'school_stores' + str(_session) data = g.selectn(db, '', '', {'itemID': _store, 'state': 4}) fig = 0 self.borrowedData.clear() self.hold_borrowed = {} i = 0 for a in data: ret = g.selectStoreReturned(db, a['id']) if ret: retu = ret['qty'] else: retu = 0 fig = float(a['quantity']) - float(retu) damz = float(a['datepaid']) if float(fig) > 0: self.hold_borrowed[i] = a['id'] damt = datetime.utcfromtimestamp(damz).strftime('%d-%m-%Y') tex = str(damt) + " " + str( a['person']).upper() + " (" + str(fig).upper() + ")" self.borrowedData.addItem(tex) i += 1 def reloadStore(self): self.getQuantity() cat = self.hold_storeGroup[self.storeGroupData.currentIndex()] store = self.pullStore(cat) self.storeData.clear() self.hold_store = {} i = 0 for a in store: self.hold_store[i] = a['id'] tex = str(a['name']).upper() self.storeData.addItem(tex) i += 1 def getQuantity(self): if self.storeData.currentIndex() > -1: s = self.hold_store[self.storeData.currentIndex()] _session = self.session g = Db() db = 'school_stores' + str(_session) fi = g.selectStoreQuantity(db, s) remain = 0 arr = {} for a in fi: arr[a['state']] = a['qty'] if 1 in arr: re = arr[1] else: re = 0 if 2 in arr: isu = arr[2] else: isu = 0 if 3 in arr: dam = arr[3] else: dam = 0 if 4 in arr: bor = arr[4] else: bor = 0 if 5 in arr: ret = arr[5] else: ret = 0 borrowed = float(bor) - float(ret) issued = float(isu) + float(borrowed) + float(dam) remain = float(re) - float(issued) self.quantityText.setText('QTY: ' + str(remain)) if remain == 0 and (self.r2.isChecked() or self.r3.isChecked() or self.r4.isChecked()): self.quantityData.setEnabled(False) else: self.quantityData.setEnabled(True) return remain def reloadTable(self, a): self.getQuantity() if not a == 0: data = self.pullStoreData(a) else: data = self.pullStoreData() self.table.close() self.table = QTableWidget() header = self.table.horizontalHeader() header.setResizeMode(QHeaderView.ResizeToContents) header.setStretchLastSection(True) header.setStyleSheet(self.tableHeaderStyle) vheader = self.table.verticalHeader() vheader.setStyleSheet(self.tableHeaderStyle) # Body self.table.setWindowTitle("Stores") self.table.setStyleSheet("color:white") self.table.resize(300, 250) self.table.setFont(self.tableFont) self.table.setSortingEnabled(2) self.table.resizeColumnsToContents() self.table.setRowCount(len(data)) self.table.setColumnCount(len(self.cols)) self.table.setHorizontalHeaderLabels(self.cols) self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.handleHeaderMenu) self.table.hideColumn(0) self.table.setSelectionMode(QAbstractItemView.MultiSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) i = 0 for q in data: #row id if q['state'] == 1: color = QColor(100, 0, 0) elif q['state'] == 2: color = QColor(100, 100, 0) elif q['state'] == 3: color = QColor(100, 0, 100) elif q['state'] == 4: color = QColor(0, 100, 100) else: color = QColor(0, 50, 150) self.table.setItem(i, 0, QTableWidgetItem(str(q['id']))) self.table.item(i, 0).setBackground(color) self.table.setItem(i, 1, QTableWidgetItem(str(q['itemname']).upper())) self.table.item(i, 1).setBackground(color) self.table.setItem(i, 2, QTableWidgetItem(str(q['quantity']).upper())) self.table.item(i, 2).setBackground(color) try: zamt = str("{:,}".format(float(q['amount']))) except: zamt = '' self.table.setItem(i, 3, QTableWidgetItem(zamt)) self.table.item(i, 3).setBackground(color) try: if len(q['amount']) > 0 and float(q['amount']) > 0: tot = float(q['amount']) * float(q['quantity']) else: tot = 0 except: tot = 0 self.table.setItem(i, 4, QTableWidgetItem(str(tot).upper())) self.table.item(i, 4).setBackground(color) damz = float(q['datepaid']) damt = datetime.utcfromtimestamp(damz).strftime('%d-%m-%Y') self.table.setItem(i, 5, QTableWidgetItem(str(damt))) self.table.item(i, 5).setBackground(color) i += 1 self.table.itemSelectionChanged.connect(self.confirmSelection) self.table.resizeRowsToContents() self.h1_pull_box.addWidget(self.table) self.table.show() def pullOnes(self, a, b): cn = Db() arr = cn.selectn(a, '', 1, {'id': b}) return arr def confirmSelection(self): item = self.mySelectTable() if len(item) == 1: self.pb1.setEnabled(True) self.pb3.setEnabled(True) self.pb6.setEnabled(True) elif len(item) > 1: self.pb1.setEnabled(False) self.pb3.setEnabled(True) self.pb6.setEnabled(True) else: self.pb1.setEnabled(False) self.pb3.setEnabled(False) self.pb6.setEnabled(False) def button_close(self, b): b.close() def button_editshow(self): item = self.mySelectTable() self.editRow(item[0]) self.pb.hide() self.pb4.show() self.pb5.show() def button_delete(self): item = self.mySelectTable() _session = self.session g = Db() db = 'school_stores' + str(_session) for j in item: g.delete(db, {'id': j}) self.reloadTable(1) def button_edit(self): _session = self.session _amounts = self.amountData.text() _teller = self.tellerData.text() _quantity = self.quantityData.text() _person = self.personData.text() _period = self.periodData.text() _date = self.dateData.date().toPyDate() _date = time.mktime(_date.timetuple()) _description = self.descriptionData.toPlainText() _store = self.hold_store[self.storeData.currentIndex()] _borrowed = self.hold_borrowed[self.borrowedData.currentIndex()] arr = {} #recieved if self.r1.isChecked() and _amounts and not ( _amounts == 0) and int(_store) > 0 and int(_quantity) > 0: _amount = float(_amounts) / float(_quantity) arr['amount'] = _amount arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 1 #issued elif self.r2.isChecked() and int(_store) > 0 and int(_quantity) > 0: _amount = float(_amounts) / float(_quantity) arr['amount'] = _amount arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 2 #damaged elif self.r3.isChecked() and int(_store) > 0 and int(_quantity) > 0: arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 3 elif self.r4.isChecked() and int(_store) > 0 and int(_quantity) > 0: arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['quantity'] = _quantity arr['person'] = _person arr['period'] = _period arr['state'] = 4 elif self.r5.isChecked() and int(_store) > 0 and int(_quantity) > 0: _borrowed = self.hold_borrowed[self.borrowedData.currentIndex()] arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['quantity'] = _quantity arr['person'] = _person arr['period'] = _period arr['active'] = _borrowed arr['state'] = 5 ups = {} ups['id'] = self.editID if int(self.editID) > 0 and len(arr) > 0: db = 'school_stores' + str(_session) g = Db() g.update(db, arr, ups) if int(self.editID) > 0: self.button_reset() def button_reset(self): self.getQuantity() self.reloadTable(1) self.amountData.setText('') self.descriptionData.clear() self.tellerData.setText('') self.personData.setText('') self.periodData.setText('') self.quantityData.setText('') self.pb4.hide() self.pb5.hide() self.pb.show() self.editID = 0 self.button_clear() self.confirmSelection() self.reloadBorrowed() def button_clear(self): self.table.selectionModel().clearSelection() def button_click(self): _session = self.session _amounts = self.amountData.text() _teller = self.tellerData.text() _quantity = self.quantityData.text() _person = self.personData.text() _period = self.periodData.text() _date = self.dateData.date().toPyDate() _date = time.mktime(_date.timetuple()) _description = self.descriptionData.toPlainText() _store = self.hold_store[self.storeData.currentIndex()] arr = {} #recieved if self.r1.isChecked() and _amounts and not ( _amounts == 0) and int(_store) > 0 and int(_quantity) > 0: _amount = float(_amounts) / float(_quantity) arr['amount'] = _amount arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 1 #issued elif self.r2.isChecked() and _amounts and not ( _amounts == 0) and int(_store) > 0 and int(_quantity) > 0: _amount = float(_amounts) / float(_quantity) arr['amount'] = _amount arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 2 #damaged elif self.r3.isChecked() and int(_store) > 0 and int( float(_quantity)) > 0: arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['teller'] = _teller arr['quantity'] = _quantity arr['person'] = _person arr['state'] = 3 elif self.r4.isChecked() and int(_store) > 0 and int( float(_quantity)) > 0: arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['quantity'] = _quantity arr['person'] = _person arr['period'] = _period arr['state'] = 4 elif self.r5.isChecked() and int(_store) > 0 and int( float(_quantity)) > 0 and self.borrowedData.currentIndex() > 0: _borrowed = self.hold_borrowed[self.borrowedData.currentIndex()] arr['datepaid'] = _date arr['description'] = _description arr['itemID'] = _store arr['quantity'] = _quantity arr['person'] = _person arr['period'] = _period arr['active'] = _borrowed arr['state'] = 5 if len(arr) > 0: db = 'school_stores' + str(_session) g = Db() ins = g.insert(db, arr) if int(ins) > 0: self.button_reset()
class ObjectInspector(SMPluginWidget): """ Docstrings viewer widget """ CONF_SECTION = 'inspector' CONFIGWIDGET_CLASS = ObjectInspectorConfigPage LOG_PATH = get_conf_path('.inspector') def __init__(self, parent): SMPluginWidget.__init__(self, parent) self.internal_shell = None # Initialize plugin self.initialize_plugin() self.no_doc_string = _("No documentation available") self._last_console_cb = None self._last_editor_cb = None self.set_default_color_scheme() self.plain_text = PlainText(self) self.rich_text = RichText(self) color_scheme = get_color_scheme(self.get_option('color_scheme_name')) self.set_plain_text_font(self.get_plugin_font(), color_scheme) self.plain_text.editor.toggle_wrap_mode(self.get_option('wrap')) # Add entries to read-only editor context-menu font_action = create_action(self, _("&Font..."), None, 'font.png', _("Set font style"), triggered=self.change_font) self.wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode) self.wrap_action.setChecked(self.get_option('wrap')) self.plain_text.editor.readonly_menu.addSeparator() add_actions(self.plain_text.editor.readonly_menu, (font_action, self.wrap_action)) self.set_rich_text_font(self.get_plugin_font('rich_text')) self.shell = None self.external_console = None # locked = disable link with Console self.locked = False self._last_texts = [None, None] self._last_rope_data = None # Object name layout_edit = QHBoxLayout() layout_edit.setContentsMargins(0, 0, 0, 0) txt = _("Source") if sys.platform == 'darwin': source_label = QLabel(" " + txt) else: source_label = QLabel(txt) layout_edit.addWidget(source_label) self.source_combo = QComboBox(self) self.source_combo.addItems([_("Console"), _("Editor")]) self.connect(self.source_combo, SIGNAL('currentIndexChanged(int)'), self.source_changed) if not programs.is_module_installed('rope'): self.source_combo.hide() source_label.hide() layout_edit.addWidget(self.source_combo) layout_edit.addSpacing(10) layout_edit.addWidget(QLabel(_("Object"))) self.combo = ObjectComboBox(self) layout_edit.addWidget(self.combo) self.object_edit = QLineEdit(self) self.object_edit.setReadOnly(True) layout_edit.addWidget(self.object_edit) self.combo.setMaxCount(self.get_option('max_history_entries')) self.combo.addItems( self.load_history() ) self.connect(self.combo, SIGNAL("valid(bool)"), lambda valid: self.force_refresh()) # Plain text docstring option self.docstring = True self.rich_help = sphinxify is not None \ and self.get_option('rich_mode', True) self.plain_text_action = create_action(self, _("Plain Text"), toggled=self.toggle_plain_text) # Source code option self.show_source_action = create_action(self, _("Show Source"), toggled=self.toggle_show_source) # Rich text option self.rich_text_action = create_action(self, _("Rich Text"), toggled=self.toggle_rich_text) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Automatic import option self.auto_import_action = create_action(self, _("Automatic import"), toggled=self.toggle_auto_import) auto_import_state = self.get_option('automatic_import') self.auto_import_action.setChecked(auto_import_state) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Option menu options_button = create_toolbutton(self, text=_("Options"), icon=get_icon('tooloptions.png')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, [self.rich_text_action, self.plain_text_action, self.show_source_action, None, self.auto_import_action]) options_button.setMenu(menu) layout_edit.addWidget(options_button) if self.rich_help: self.switch_to_rich_text() else: self.switch_to_plain_text() self.plain_text_action.setChecked(not self.rich_help) self.rich_text_action.setChecked(self.rich_help) self.rich_text_action.setEnabled(sphinxify is not None) self.source_changed() # Main layout layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(layout_edit) layout.addWidget(self.plain_text) layout.addWidget(self.rich_text) self.setLayout(layout) # Add worker thread for handling rich text rendering if sphinxify is None: self._sphinx_thread = None else: self._sphinx_thread = SphinxThread(text={}, html_text_no_doc=warning(self.no_doc_string), math_option=self.get_option('math')) self.connect(self._sphinx_thread, SIGNAL('html_ready(QString)'), self._on_sphinx_thread_html_ready) self.connect(self._sphinx_thread, SIGNAL('error_msg(QString)'), self._on_sphinx_thread_error_msg) self._starting_up = True #------ SMPluginWidget API --------------------------------------------- def get_plugin_title(self): """Return widget title""" return _('Object inspector') def get_plugin_icon(self): """Return widget icon""" return get_icon('inspector.png') def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ self.combo.lineEdit().selectAll() return self.combo def get_plugin_actions(self): """Return a list of actions related to plugin""" return [] def register_plugin(self): """Register plugin in Spyder's main window""" self.connect(self, SIGNAL('focus_changed()'), self.main.plugin_focus_changed) self.main.add_dockwidget(self) self.main.console.set_inspector(self) self.internal_shell = self.main.console.shell def closing_plugin(self, cancelable=False): """Perform actions before parent main window is closed""" return True def refresh_plugin(self): """Refresh widget""" if self._starting_up: self._starting_up = False QTimer.singleShot(5000, self.refresh_plugin) self.set_object_text(None, force_refresh=False) def apply_plugin_settings(self, options): """Apply configuration file's plugin settings""" color_scheme_n = 'color_scheme_name' color_scheme_o = get_color_scheme(self.get_option(color_scheme_n)) font_n = 'plugin_font' font_o = self.get_plugin_font() rich_font_n = 'rich_text' rich_font_o = self.get_plugin_font('rich_text') wrap_n = 'wrap' wrap_o = self.get_option(wrap_n) self.wrap_action.setChecked(wrap_o) math_n = 'math' math_o = self.get_option(math_n) if font_n in options: scs = color_scheme_o if color_scheme_n in options else None self.set_plain_text_font(font_o, color_scheme=scs) if rich_font_n in options: self.set_rich_text_font(rich_font_o) elif color_scheme_n in options: self.set_plain_text_color_scheme(color_scheme_o) if wrap_n in options: self.toggle_wrap_mode(wrap_o) if math_n in options: self.toggle_math_mode(math_o) #------ Public API (related to inspector's source) ------------------------- def source_is_console(self): """Return True if source is Console""" return self.source_combo.currentIndex() == 0 def switch_to_editor_source(self): self.source_combo.setCurrentIndex(1) def switch_to_console_source(self): self.source_combo.setCurrentIndex(0) def source_changed(self, index=None): if self.source_is_console(): # Console self.combo.show() self.object_edit.hide() self.show_source_action.setEnabled(True) self.auto_import_action.setEnabled(True) else: # Editor self.combo.hide() self.object_edit.show() self.show_source_action.setDisabled(True) self.auto_import_action.setDisabled(True) self.restore_text() def save_text(self, callback): if self.source_is_console(): self._last_console_cb = callback else: self._last_editor_cb = callback def restore_text(self): if self.source_is_console(): cb = self._last_console_cb else: cb = self._last_editor_cb if cb is None: if self.is_plain_text_mode(): self.plain_text.clear() else: self.rich_text.clear() else: func = cb[0] args = cb[1:] func(*args) if func.im_self is self.rich_text: self.switch_to_rich_text() else: self.switch_to_plain_text() #------ Public API (related to rich/plain text widgets) -------------------- @property def find_widget(self): if self.plain_text.isVisible(): return self.plain_text.find_widget else: return self.rich_text.find_widget def set_rich_text_font(self, font): """Set rich text mode font""" self.rich_text.set_font(font, fixed_font=self.get_plugin_font()) def set_plain_text_font(self, font, color_scheme=None): """Set plain text mode font""" self.plain_text.set_font(font, color_scheme=color_scheme) def set_plain_text_color_scheme(self, color_scheme): """Set plain text mode color scheme""" self.plain_text.set_color_scheme(color_scheme) def change_font(self): """Change console font""" font, valid = QFontDialog.getFont(get_font(self.CONF_SECTION), self, _("Select a new font")) if valid: self.set_plain_text_font(font) set_font(font, self.CONF_SECTION) def toggle_wrap_mode(self, checked): """Toggle wrap mode""" self.plain_text.editor.toggle_wrap_mode(checked) self.set_option('wrap', checked) def toggle_math_mode(self, checked): """Toggle math mode""" self.set_option('math', checked) def is_plain_text_mode(self): """Return True if plain text mode is active""" return self.plain_text.isVisible() def is_rich_text_mode(self): """Return True if rich text mode is active""" return self.rich_text.isVisible() def switch_to_plain_text(self): """Switch to plain text mode""" self.rich_help = False self.plain_text.show() self.rich_text.hide() self.plain_text_action.setChecked(True) def switch_to_rich_text(self): """Switch to rich text mode""" self.rich_help = True self.plain_text.hide() self.rich_text.show() self.rich_text_action.setChecked(True) self.show_source_action.setChecked(False) def set_plain_text(self, text, is_code): """Set plain text docs""" # text is coming from utils.dochelpers.getdoc if type(text) is dict: name = text['name'] if name: rst_title = ''.join(['='*len(name), '\n', name, '\n', '='*len(name), '\n\n']) else: rst_title = '' if text['argspec']: definition = ''.join(['Definition: ', name, text['argspec'], '\n']) else: definition = '' if text['note']: note = ''.join(['Type: ', text['note'], '\n\n----\n\n']) else: note = '' full_text = ''.join([rst_title, definition, note, text['docstring']]) else: full_text = text self.plain_text.set_text(full_text, is_code) self.save_text([self.plain_text.set_text, full_text, is_code]) def set_rich_text_html(self, html_text, base_url): """Set rich text""" self.rich_text.set_html(html_text, base_url) self.save_text([self.rich_text.set_html, html_text, base_url]) #------ Public API --------------------------------------------------------- def set_external_console(self, external_console): self.external_console = external_console def force_refresh(self): if self.source_is_console(): self.set_object_text(None, force_refresh=True) elif self._last_rope_data is not None: text = self._last_rope_data self.set_rope_doc(text, force_refresh=True) def set_object_text(self, text, force_refresh=False, ignore_unknown=False): """Set object analyzed by Object Inspector""" if (self.locked and not force_refresh): return self.switch_to_console_source() add_to_combo = True if text is None: text = unicode(self.combo.currentText()) add_to_combo = False found = self.show_help(text, ignore_unknown=ignore_unknown) if ignore_unknown and not found: return if add_to_combo: self.combo.add_text(text) self.save_history() if self.dockwidget is not None: self.dockwidget.blockSignals(True) self.__eventually_raise_inspector(text, force=force_refresh) if self.dockwidget is not None: self.dockwidget.blockSignals(False) def set_rope_doc(self, text, force_refresh=False): """ Use the object inspector to show text computed with rope from the Editor plugin """ if (self.locked and not force_refresh): return self.switch_to_editor_source() self._last_rope_data = text self.object_edit.setText(text['obj_text']) if self.rich_help: self.set_sphinx_text(text) else: self.set_plain_text(text, is_code=False) if self.dockwidget is not None: self.dockwidget.blockSignals(True) self.__eventually_raise_inspector(text['docstring'], force=force_refresh) if self.dockwidget is not None: self.dockwidget.blockSignals(False) def __eventually_raise_inspector(self, text, force=False): index = self.source_combo.currentIndex() if hasattr(self.main, 'tabifiedDockWidgets'): # 'QMainWindow.tabifiedDockWidgets' was introduced in PyQt 4.5 if self.dockwidget and (force or self.dockwidget.isVisible()) \ and not self.ismaximized \ and (force or text != self._last_texts[index]): dockwidgets = self.main.tabifiedDockWidgets(self.dockwidget) if self.main.console.dockwidget not in dockwidgets and \ (hasattr(self.main, 'extconsole') and \ self.main.extconsole.dockwidget not in dockwidgets): self.dockwidget.show() self.dockwidget.raise_() self._last_texts[index] = text def load_history(self, obj=None): """Load history from a text file in user home directory""" if osp.isfile(self.LOG_PATH): history = [line.replace('\n','') for line in file(self.LOG_PATH, 'r').readlines()] else: history = [] return history def save_history(self): """Save history to a text file in user home directory""" file(self.LOG_PATH, 'w').write("\n".join( \ [ unicode( self.combo.itemText(index) ) for index in range(self.combo.count()) ] )) def toggle_plain_text(self, checked): """Toggle plain text docstring""" if checked: self.docstring = checked self.switch_to_plain_text() self.force_refresh() self.set_option('rich_mode', not checked) def toggle_show_source(self, checked): """Toggle show source code""" if checked: self.switch_to_plain_text() self.docstring = not checked self.force_refresh() self.set_option('rich_mode', not checked) def toggle_rich_text(self, checked): """Toggle between sphinxified docstrings or plain ones""" if checked: self.docstring = not checked self.switch_to_rich_text() self.force_refresh() self.set_option('rich_mode', checked) def toggle_auto_import(self, checked): """Toggle automatic import feature""" self.combo.validate_current_text() self.set_option('automatic_import', checked) self.force_refresh() def toggle_locked(self): """ Toggle locked state locked = disable link with Console """ self.locked = not self.locked self._update_lock_icon() def _update_lock_icon(self): """Update locked state icon""" icon = get_icon("lock.png" if self.locked else "lock_open.png") self.locked_button.setIcon(icon) tip = _("Unlock") if self.locked else _("Lock") self.locked_button.setToolTip(tip) def set_shell(self, shell): """Bind to shell""" if IPythonControlWidget is not None: # XXX(anatoli): hack to make Spyder run on systems without IPython # there should be a better way if isinstance(shell, IPythonControlWidget): # XXX: this ignores passed argument completely self.shell = self.external_console.get_current_shell() else: self.shell = shell def get_shell(self): """Return shell which is currently bound to object inspector, or another running shell if it has been terminated""" if not isinstance(self.shell, ExtPythonShellWidget) \ or not self.shell.externalshell.is_running(): self.shell = None if self.external_console is not None: self.shell = self.external_console.get_running_python_shell() if self.shell is None: self.shell = self.internal_shell return self.shell def set_sphinx_text(self, text): """Sphinxify text and display it""" # If the thread is already running wait for it to finish before # starting it again. if self._sphinx_thread.wait(): # Math rendering option could have changed self._sphinx_thread.math_option = self.get_option('math') self._sphinx_thread.text = text self._sphinx_thread.start() def _on_sphinx_thread_html_ready(self, html_text): """Set our sphinx documentation based on thread result""" self.set_rich_text_html(html_text, QUrl.fromLocalFile(CSS_PATH)) def _on_sphinx_thread_error_msg(self, error_msg): """ Display error message on Sphinx rich text failure""" self.plain_text_action.setChecked(True) QMessageBox.critical(self, _('Object inspector'), _("The following error occured when calling " "<b>Sphinx %s</b>. <br>Incompatible Sphinx " "version or doc string decoding failed." "<br><br>Error message:<br>%s" ) % (sphinx_version, error_msg)) def show_help(self, obj_text, ignore_unknown=False): """Show help""" shell = self.get_shell() if shell is None: return obj_text = unicode(obj_text) if not shell.is_defined(obj_text): if self.get_option('automatic_import') and\ self.internal_shell.is_defined(obj_text, force_import=True): shell = self.internal_shell else: shell = None doc_text = None source_text = None if shell is not None: doc_text = shell.get_doc(obj_text) if isinstance(doc_text, bool): doc_text = None source_text = shell.get_source(obj_text) is_code = False if self.rich_help: self.set_sphinx_text(doc_text) if ignore_unknown: return doc_text is not None else: return True elif self.docstring: hlp_text = doc_text if hlp_text is None: hlp_text = source_text if hlp_text is None: hlp_text = self.no_doc_string if ignore_unknown: return False else: hlp_text = source_text if hlp_text is None: hlp_text = doc_text if hlp_text is None: hlp_text = _("No source code available.") if ignore_unknown: return False else: is_code = True self.set_plain_text(hlp_text, is_code=is_code) return True
class ObjectInspector(SMPluginWidget): """ Docstrings viewer widget """ CONF_SECTION = "inspector" CONFIGWIDGET_CLASS = ObjectInspectorConfigPage LOG_PATH = get_conf_path(".inspector") def __init__(self, parent): SMPluginWidget.__init__(self, parent) self.internal_shell = None # Initialize plugin self.initialize_plugin() self.no_doc_string = _("No documentation available") self._last_console_cb = None self._last_editor_cb = None self.set_default_color_scheme() self.plain_text = PlainText(self) self.rich_text = RichText(self) color_scheme = get_color_scheme(self.get_option("color_scheme_name")) self.set_plain_text_font(self.get_plugin_font(), color_scheme) self.plain_text.editor.toggle_wrap_mode(self.get_option("wrap")) # Add entries to read-only editor context-menu font_action = create_action( self, _("&Font..."), None, "font.png", _("Set font style"), triggered=self.change_font ) self.wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode) self.wrap_action.setChecked(self.get_option("wrap")) self.plain_text.editor.readonly_menu.addSeparator() add_actions(self.plain_text.editor.readonly_menu, (font_action, self.wrap_action)) self.set_rich_text_font(self.get_plugin_font("rich_text")) self.shell = None self.external_console = None # locked = disable link with Console self.locked = False self._last_texts = [None, None] self._last_rope_data = None # Object name layout_edit = QHBoxLayout() layout_edit.setContentsMargins(0, 0, 0, 0) txt = _("Source") if sys.platform == "darwin": source_label = QLabel(" " + txt) else: source_label = QLabel(txt) layout_edit.addWidget(source_label) self.source_combo = QComboBox(self) self.source_combo.addItems([_("Console"), _("Editor")]) self.connect(self.source_combo, SIGNAL("currentIndexChanged(int)"), self.source_changed) if not programs.is_module_installed("rope"): self.source_combo.hide() source_label.hide() layout_edit.addWidget(self.source_combo) layout_edit.addSpacing(10) layout_edit.addWidget(QLabel(_("Object"))) self.combo = ObjectComboBox(self) layout_edit.addWidget(self.combo) self.object_edit = QLineEdit(self) self.object_edit.setReadOnly(True) layout_edit.addWidget(self.object_edit) self.combo.setMaxCount(self.get_option("max_history_entries")) self.combo.addItems(self.load_history()) self.connect(self.combo, SIGNAL("valid(bool)"), lambda valid: self.force_refresh()) # Plain text docstring option self.docstring = True self.rich_help = sphinxify is not None and self.get_option("rich_mode", True) self.plain_text_action = create_action(self, _("Plain Text"), toggled=self.toggle_plain_text) # Source code option self.show_source_action = create_action(self, _("Show Source"), toggled=self.toggle_show_source) # Rich text option self.rich_text_action = create_action(self, _("Rich Text"), toggled=self.toggle_rich_text) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Automatic import option self.auto_import_action = create_action(self, _("Automatic import"), toggled=self.toggle_auto_import) auto_import_state = self.get_option("automatic_import") self.auto_import_action.setChecked(auto_import_state) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Option menu options_button = create_toolbutton(self, text=_("Options"), icon=get_icon("tooloptions.png")) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions( menu, [self.rich_text_action, self.plain_text_action, self.show_source_action, None, self.auto_import_action], ) options_button.setMenu(menu) layout_edit.addWidget(options_button) if self.rich_help: self.switch_to_rich_text() else: self.switch_to_plain_text() self.plain_text_action.setChecked(not self.rich_help) self.rich_text_action.setChecked(self.rich_help) self.rich_text_action.setEnabled(sphinxify is not None) self.source_changed() # Main layout layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(layout_edit) layout.addWidget(self.plain_text) layout.addWidget(self.rich_text) self.setLayout(layout) # Add worker thread for handling rich text rendering if sphinxify is None: self._sphinx_thread = None else: self._sphinx_thread = SphinxThread( text={}, html_text_no_doc=warning(self.no_doc_string), math_option=self.get_option("math") ) self.connect(self._sphinx_thread, SIGNAL("html_ready(QString)"), self._on_sphinx_thread_html_ready) self.connect(self._sphinx_thread, SIGNAL("error_msg(QString)"), self._on_sphinx_thread_error_msg) self._starting_up = True # ------ SMPluginWidget API --------------------------------------------- def get_plugin_title(self): """Return widget title""" return _("Object inspector") def get_plugin_icon(self): """Return widget icon""" return get_icon("inspector.png") def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ self.combo.lineEdit().selectAll() return self.combo def get_plugin_actions(self): """Return a list of actions related to plugin""" return [] def register_plugin(self): """Register plugin in Spyder's main window""" self.connect(self, SIGNAL("focus_changed()"), self.main.plugin_focus_changed) self.main.add_dockwidget(self) self.main.console.set_inspector(self) self.internal_shell = self.main.console.shell def closing_plugin(self, cancelable=False): """Perform actions before parent main window is closed""" return True def refresh_plugin(self): """Refresh widget""" if self._starting_up: self._starting_up = False QTimer.singleShot(5000, self.refresh_plugin) self.set_object_text(None, force_refresh=False) def apply_plugin_settings(self, options): """Apply configuration file's plugin settings""" color_scheme_n = "color_scheme_name" color_scheme_o = get_color_scheme(self.get_option(color_scheme_n)) font_n = "plugin_font" font_o = self.get_plugin_font() rich_font_n = "rich_text" rich_font_o = self.get_plugin_font("rich_text") wrap_n = "wrap" wrap_o = self.get_option(wrap_n) self.wrap_action.setChecked(wrap_o) math_n = "math" math_o = self.get_option(math_n) if font_n in options: scs = color_scheme_o if color_scheme_n in options else None self.set_plain_text_font(font_o, color_scheme=scs) if rich_font_n in options: self.set_rich_text_font(rich_font_o) elif color_scheme_n in options: self.set_plain_text_color_scheme(color_scheme_o) if wrap_n in options: self.toggle_wrap_mode(wrap_o) if math_n in options: self.toggle_math_mode(math_o) # ------ Public API (related to inspector's source) ------------------------- def source_is_console(self): """Return True if source is Console""" return self.source_combo.currentIndex() == 0 def switch_to_editor_source(self): self.source_combo.setCurrentIndex(1) def switch_to_console_source(self): self.source_combo.setCurrentIndex(0) def source_changed(self, index=None): if self.source_is_console(): # Console self.combo.show() self.object_edit.hide() self.show_source_action.setEnabled(True) self.auto_import_action.setEnabled(True) else: # Editor self.combo.hide() self.object_edit.show() self.show_source_action.setDisabled(True) self.auto_import_action.setDisabled(True) self.restore_text() def save_text(self, callback): if self.source_is_console(): self._last_console_cb = callback else: self._last_editor_cb = callback def restore_text(self): if self.source_is_console(): cb = self._last_console_cb else: cb = self._last_editor_cb if cb is None: if self.is_plain_text_mode(): self.plain_text.clear() else: self.rich_text.clear() else: func = cb[0] args = cb[1:] func(*args) if func.im_self is self.rich_text: self.switch_to_rich_text() else: self.switch_to_plain_text() # ------ Public API (related to rich/plain text widgets) -------------------- @property def find_widget(self): if self.plain_text.isVisible(): return self.plain_text.find_widget else: return self.rich_text.find_widget def set_rich_text_font(self, font): """Set rich text mode font""" self.rich_text.set_font(font, fixed_font=self.get_plugin_font()) def set_plain_text_font(self, font, color_scheme=None): """Set plain text mode font""" self.plain_text.set_font(font, color_scheme=color_scheme) def set_plain_text_color_scheme(self, color_scheme): """Set plain text mode color scheme""" self.plain_text.set_color_scheme(color_scheme) def change_font(self): """Change console font""" font, valid = QFontDialog.getFont(get_font(self.CONF_SECTION), self, _("Select a new font")) if valid: self.set_plain_text_font(font) set_font(font, self.CONF_SECTION) def toggle_wrap_mode(self, checked): """Toggle wrap mode""" self.plain_text.editor.toggle_wrap_mode(checked) self.set_option("wrap", checked) def toggle_math_mode(self, checked): """Toggle math mode""" self.set_option("math", checked) def is_plain_text_mode(self): """Return True if plain text mode is active""" return self.plain_text.isVisible() def is_rich_text_mode(self): """Return True if rich text mode is active""" return self.rich_text.isVisible() def switch_to_plain_text(self): """Switch to plain text mode""" self.rich_help = False self.plain_text.show() self.rich_text.hide() self.plain_text_action.setChecked(True) def switch_to_rich_text(self): """Switch to rich text mode""" self.rich_help = True self.plain_text.hide() self.rich_text.show() self.rich_text_action.setChecked(True) self.show_source_action.setChecked(False) def set_plain_text(self, text, is_code): """Set plain text docs""" # text is coming from utils.dochelpers.getdoc if type(text) is dict: name = text["name"] if name: rst_title = "".join(["=" * len(name), "\n", name, "\n", "=" * len(name), "\n\n"]) else: rst_title = "" if text["argspec"]: definition = "".join(["Definition: ", name, text["argspec"], "\n"]) else: definition = "" if text["note"]: note = "".join(["Type: ", text["note"], "\n\n----\n\n"]) else: note = "" full_text = "".join([rst_title, definition, note, text["docstring"]]) else: full_text = text self.plain_text.set_text(full_text, is_code) self.save_text([self.plain_text.set_text, full_text, is_code]) def set_rich_text_html(self, html_text, base_url): """Set rich text""" self.rich_text.set_html(html_text, base_url) self.save_text([self.rich_text.set_html, html_text, base_url]) # ------ Public API --------------------------------------------------------- def set_external_console(self, external_console): self.external_console = external_console def force_refresh(self): if self.source_is_console(): self.set_object_text(None, force_refresh=True) elif self._last_rope_data is not None: text = self._last_rope_data self.set_rope_doc(text, force_refresh=True) def set_object_text(self, text, force_refresh=False, ignore_unknown=False): """Set object analyzed by Object Inspector""" if self.locked and not force_refresh: return self.switch_to_console_source() add_to_combo = True if text is None: text = unicode(self.combo.currentText()) add_to_combo = False found = self.show_help(text, ignore_unknown=ignore_unknown) if ignore_unknown and not found: return if add_to_combo: self.combo.add_text(text) self.save_history() if self.dockwidget is not None: self.dockwidget.blockSignals(True) self.__eventually_raise_inspector(text, force=force_refresh) if self.dockwidget is not None: self.dockwidget.blockSignals(False) def set_rope_doc(self, text, force_refresh=False): """ Use the object inspector to show text computed with rope from the Editor plugin """ if self.locked and not force_refresh: return self.switch_to_editor_source() self._last_rope_data = text self.object_edit.setText(text["obj_text"]) if self.rich_help: self.set_sphinx_text(text) else: self.set_plain_text(text, is_code=False) if self.dockwidget is not None: self.dockwidget.blockSignals(True) self.__eventually_raise_inspector(text["docstring"], force=force_refresh) if self.dockwidget is not None: self.dockwidget.blockSignals(False) def __eventually_raise_inspector(self, text, force=False): index = self.source_combo.currentIndex() if hasattr(self.main, "tabifiedDockWidgets"): # 'QMainWindow.tabifiedDockWidgets' was introduced in PyQt 4.5 if ( self.dockwidget and (force or self.dockwidget.isVisible()) and not self.ismaximized and (force or text != self._last_texts[index]) ): dockwidgets = self.main.tabifiedDockWidgets(self.dockwidget) if self.main.console.dockwidget not in dockwidgets and ( hasattr(self.main, "extconsole") and self.main.extconsole.dockwidget not in dockwidgets ): self.dockwidget.show() self.dockwidget.raise_() self._last_texts[index] = text def load_history(self, obj=None): """Load history from a text file in user home directory""" if osp.isfile(self.LOG_PATH): history = [line.replace("\n", "") for line in file(self.LOG_PATH, "r").readlines()] else: history = [] return history def save_history(self): """Save history to a text file in user home directory""" file(self.LOG_PATH, "w").write( "\n".join([unicode(self.combo.itemText(index)) for index in range(self.combo.count())]) ) def toggle_plain_text(self, checked): """Toggle plain text docstring""" if checked: self.docstring = checked self.switch_to_plain_text() self.force_refresh() self.set_option("rich_mode", not checked) def toggle_show_source(self, checked): """Toggle show source code""" if checked: self.switch_to_plain_text() self.docstring = not checked self.force_refresh() self.set_option("rich_mode", not checked) def toggle_rich_text(self, checked): """Toggle between sphinxified docstrings or plain ones""" if checked: self.docstring = not checked self.switch_to_rich_text() self.force_refresh() self.set_option("rich_mode", checked) def toggle_auto_import(self, checked): """Toggle automatic import feature""" self.combo.validate_current_text() self.set_option("automatic_import", checked) self.force_refresh() def toggle_locked(self): """ Toggle locked state locked = disable link with Console """ self.locked = not self.locked self._update_lock_icon() def _update_lock_icon(self): """Update locked state icon""" icon = get_icon("lock.png" if self.locked else "lock_open.png") self.locked_button.setIcon(icon) tip = _("Unlock") if self.locked else _("Lock") self.locked_button.setToolTip(tip) def set_shell(self, shell): """Bind to shell""" if IPythonControlWidget is not None: # XXX(anatoli): hack to make Spyder run on systems without IPython # there should be a better way if isinstance(shell, IPythonControlWidget): # XXX: this ignores passed argument completely self.shell = self.external_console.get_current_shell() else: self.shell = shell def get_shell(self): """Return shell which is currently bound to object inspector, or another running shell if it has been terminated""" if not isinstance(self.shell, ExtPythonShellWidget) or not self.shell.externalshell.is_running(): self.shell = None if self.external_console is not None: self.shell = self.external_console.get_running_python_shell() if self.shell is None: self.shell = self.internal_shell return self.shell def set_sphinx_text(self, text): """Sphinxify text and display it""" # If the thread is already running wait for it to finish before # starting it again. if self._sphinx_thread.wait(): # Math rendering option could have changed self._sphinx_thread.math_option = self.get_option("math") self._sphinx_thread.text = text self._sphinx_thread.start() def _on_sphinx_thread_html_ready(self, html_text): """Set our sphinx documentation based on thread result""" self.set_rich_text_html(html_text, QUrl.fromLocalFile(CSS_PATH)) def _on_sphinx_thread_error_msg(self, error_msg): """ Display error message on Sphinx rich text failure""" self.plain_text_action.setChecked(True) QMessageBox.critical( self, _("Object inspector"), _( "The following error occured when calling " "<b>Sphinx %s</b>. <br>Incompatible Sphinx " "version or doc string decoding failed." "<br><br>Error message:<br>%s" ) % (sphinx_version, error_msg), ) def show_help(self, obj_text, ignore_unknown=False): """Show help""" shell = self.get_shell() if shell is None: return obj_text = unicode(obj_text) if not shell.is_defined(obj_text): if self.get_option("automatic_import") and self.internal_shell.is_defined(obj_text, force_import=True): shell = self.internal_shell else: shell = None doc_text = None source_text = None if shell is not None: doc_text = shell.get_doc(obj_text) if isinstance(doc_text, bool): doc_text = None source_text = shell.get_source(obj_text) is_code = False if self.rich_help: self.set_sphinx_text(doc_text) if ignore_unknown: return doc_text is not None else: return True elif self.docstring: hlp_text = doc_text if hlp_text is None: hlp_text = source_text if hlp_text is None: hlp_text = self.no_doc_string if ignore_unknown: return False else: hlp_text = source_text if hlp_text is None: hlp_text = doc_text if hlp_text is None: hlp_text = _("No source code available.") if ignore_unknown: return False else: is_code = True self.set_plain_text(hlp_text, is_code=is_code) return True
class TrackSummaryWidget(QWidget): def __init__(self, parent=None): super(TrackSummaryWidget, self).__init__(parent) self.ride_time = QLabel(self) self.calories = QLabel(self) self.avg_speed = QLabel(self) self.max_speed = QLabel(self) self.avg_hr = QLabel(self) self.max_hr = QLabel(self) self.avg_cad = QLabel(self) self.max_cad = QLabel(self) self.avg_pwr = QLabel(self) self.max_pwr = QLabel(self) for l in self.children(): if isinstance(l, QLabel): l.setTextInteractionFlags(Qt.TextSelectableByMouse) self.laps = QComboBox(self) self.laps.hide() self.laps.activated.connect(self._onLapChanged) self._createLayout() def setTrack(self, track): self.lap_summaries = laps = track['gpx'].getLaps() self.laps.clear() self.laps.addItem('Summary') for i, lap in enumerate(laps, 1): self.laps.addItem('Lap {0}'.format(i)) if len(laps) > 1: self.laps.show() else: self.laps.hide() self.setTrackSummary(track['gpx'].getSummary()) self.track = track def setTrackSummary(self, summary): ride_time = str(datetime.timedelta(seconds=summary['ride_time'])) if len(ride_time) == 7: # Add 0 to get the format hh:mm::ss ride_time = '0' + ride_time self.ride_time.setText('<b>Ride time:</b><br> %s' % ride_time) dist = summary['distance'] / 1000.0 self.calories.setText('<b>Distance:</b><br> %.2f Km' % dist) self.avg_speed.setText('<b>Avg Speed:</b><br> %.1f Km/h' % float(summary.get('speed_avg', 0))) self.max_speed.setText('<b>Max Speed:</b><br> %.1f Km/h' % float(summary.get('speed_max', 0))) self.avg_hr.setText('<b>Avg Heart rate:</b><br> %s bpm' % summary.get('hr_avg', '---')) self.max_hr.setText('<b>Max Heart rate:</b><br> %s bpm' % summary.get('hr_max', '---')) self.avg_cad.setText('<b>Avg Cadence:</b><br> %s rpm' % summary.get('cad_avg', '---')) self.max_cad.setText('<b>Max Cadence:</b><br> %s rpm' % summary.get('cad_max', '---')) self.avg_pwr.setText('<b>Avg Power:</b><br> %s watts' % summary.get('pwr_avg', '---')) self.max_pwr.setText('<b>Max Power:</b><br> %s watts' % summary.get('pwr_max', '---')) def _onLapChanged(self, i): if i == 0: self.setTrackSummary(self.track['gpx'].getSummary()) else: self.setTrackSummary(self.lap_summaries[i-1]) def _createLayout(self): l = QVBoxLayout() h = QHBoxLayout() v = QVBoxLayout() v.addWidget(self.ride_time) v.addWidget(self.avg_speed) v.addWidget(self.avg_hr) v.addWidget(self.avg_cad) v.addWidget(self.avg_pwr) h.addLayout(v) v = QVBoxLayout() v.addWidget(self.calories) v.addWidget(self.max_speed) v.addWidget(self.max_hr) v.addWidget(self.max_cad) v.addWidget(self.max_pwr) h.addLayout(v) l.addLayout(h) l.addSpacing(10) l.addWidget(self.laps) l.addStretch() self.setLayout(l)
class lTabOptions(QGroupBox): state_change = pyqtSignal() def __init__(self, parent, run_data_dir): self.block_state_change = False self.run_data_dir = run_data_dir QGroupBox.__init__(self, "Global Tab Options", parent) self.grid_layout = QGridLayout(self) title = QLabel('Lovell') font = QFont() title.setAlignment(Qt.AlignHCenter) font.setPointSize(20) font.setBold(True) title.setFont(font) self.setMinimumWidth(275) self.grid_layout.addWidget(title, self.rowCount(), 0, 1, 2) setPadding(self.grid_layout) self.add_group_selector() self.add_ID_selector() self.add_next_prev_buttons() self.add_notify_box() self.add_reference_buttons() self.add_run_num_buttons() def add_notify_box(self): notifyFont = QFont() notifyFont.setPointSize(8) self.grid_layout.addWidget(QLabel("Notifcations:"), self.rowCount(), 0, 1, 2) self.notifyBox = QTextEdit("Hello world! :)", self) self.notifyBox.setFont(notifyFont) self.grid_layout.addWidget(self.notifyBox, self.rowCount(), 0, 1, 2) def notify(self, text, textHighlight=None): # highlightRange is range in passed text. length = len(self.notifyBox.toPlainText()) self.notifyBox.append(text) self.notifyBox.verticalScrollBar().setValue( self.notifyBox.verticalScrollBar().maximum()) if textHighlight != None: begin = length + text.find(textHighlight) + 1 end = begin + len(textHighlight) fmt = QTextCharFormat() col = QColor(Qt.red) col.setAlpha(130) fmt.setBackground(col) cursor = QTextCursor(self.notifyBox.document()) cursor.setPosition(begin) cursor.setPosition(end, QTextCursor.KeepAnchor) cursor.setCharFormat(fmt) def add_group_selector(self): self.module_group_box = QComboBox(self) self.module_group_box.currentIndexChanged.connect(self.state_changed) lab = QLabel("Module Group:") lab.setAlignment(Qt.AlignRight) self.grid_layout.addWidget(lab, self.rowCount(), 0) self.grid_layout.addWidget(self.module_group_box, self.rowCount() - 1, 1) lab.hide() self.module_group_box.hide() self.module_group_box.addItem("R (0)") self.module_group_box.addItem("Phi (1)") def add_ID_selector(self): self.module_ID_box = QComboBox(self) self.module_ID_box.currentIndexChanged.connect(self.state_changed) lab = QLabel("Sensor ID:") lab.setAlignment(Qt.AlignRight) self.grid_layout.addWidget(lab, self.rowCount(), 0) self.grid_layout.addWidget(self.module_ID_box, self.rowCount() - 1, 1) for i in range(0, 42): self.module_ID_box.addItem(str(i)) for i in range(64, 106): self.module_ID_box.addItem(str(i)) def add_next_prev_buttons(self): self.next_button = QPushButton("Next") self.grid_layout.addWidget(self.next_button, self.rowCount(), 1) self.prev_button = QPushButton("Prev") self.grid_layout.addWidget(self.prev_button, self.rowCount() - 1, 0) self.next_button.clicked.connect(self.next_clicked) self.prev_button.clicked.connect(self.prev_clicked) self.next_four_button = QPushButton("Next Four") self.grid_layout.addWidget(self.next_four_button, self.rowCount(), 1) self.prev_four_button = QPushButton("Prev Four") self.grid_layout.addWidget(self.prev_four_button, self.rowCount() - 1, 0) self.next_four_button.clicked.connect(self.next_four_clicked) self.prev_four_button.clicked.connect(self.prev_four_clicked) def add_run_num_buttons(self): self.add_bar() self.run_num_box = QComboBox(self) self.run_num_box.currentIndexChanged.connect(self.state_changed) self.grid_layout.addWidget(QLabel("Run number:"), self.rowCount(), 0, 1, 2) self.grid_layout.addWidget(self.run_num_box, self.rowCount(), 0, 1, 2) # Reference self.run_numRef_box = QComboBox(self) self.run_numRef_box.currentIndexChanged.connect(self.state_changed) self.grid_layout.addWidget(QLabel("Reference number:"), self.rowCount(), 0, 1, 2) self.grid_layout.addWidget(self.run_numRef_box, self.rowCount(), 0, 1, 2) self.run_numRef_box.addItem('Auto') for run in lInterfaces.run_list(self.run_data_dir): self.run_num_box.addItem(str(run)) self.run_numRef_box.addItem(str(run)) def add_bar(self): bar = QLabel('_______________________________') bar.setAlignment(Qt.AlignHCenter) bar.setAlignment(Qt.AlignVCenter) self.grid_layout.addWidget(bar, self.rowCount(), 0, 1, 2) def add_reference_buttons(self): self.add_bar() self.showing_ref_box = QCheckBox("Display References") self.showing_ref_box.stateChanged.connect(self.reference_button_fading) self.showing_ref_box.setChecked(True) self.overlay_ref_box = QRadioButton("Overlay", self) self.overlay_ref_box.setChecked(True) self.overlay_refDiff_box = QRadioButton("Data - Ref", self) self.overlay_refRatio_box = QRadioButton("Data/Ref", self) self.grid_layout.addWidget(self.showing_ref_box, self.rowCount(), 0, 1, 2) self.grid_layout.addWidget(self.overlay_ref_box, self.rowCount(), 0, 1, 2) self.grid_layout.addWidget(self.overlay_refDiff_box, self.rowCount(), 0, 1, 2) self.grid_layout.addWidget(self.overlay_refRatio_box, self.rowCount(), 0, 1, 2) # Slots. self.showing_ref_box.clicked.connect(self.state_changed) self.overlay_ref_box.clicked.connect(self.state_changed) self.overlay_refDiff_box.clicked.connect(self.state_changed) self.overlay_refRatio_box.clicked.connect(self.state_changed) self.reference_button_fading() def rowCount(self): return self.grid_layout.rowCount() def state_changed(self): if self.block_state_change == False: self.state_change.emit() def state(self): g = self.module_group_box.currentIndex() moduleID = int(self.module_ID_box.currentText()) state = lTabOpsState(moduleID, self.showing_ref_box.isChecked(), self.overlay_ref_box.isChecked(), self.overlay_refDiff_box.isChecked(), self.overlay_refRatio_box.isChecked(), self.run_num_box.currentText(), self.run_numRef_box.currentText(), self.run_data_dir) return state def next_four_clicked(self): self.block_state_change = True for i in range(4): self.next_clicked() self.block_state_change = False self.state_changed() def prev_four_clicked(self): self.block_state_change = True for i in range(4): self.prev_clicked() self.block_state_change = False self.state_changed() def next_clicked(self): currentGroup = self.module_group_box.currentIndex() currentModule = self.module_ID_box.currentIndex() # Check if the last one. if currentModule != self.module_ID_box.count() - 1: self.module_ID_box.setCurrentIndex(currentModule + 1) else: if currentGroup != self.module_group_box.count() - 1: self.module_group_box.setCurrentIndex(currentGroup + 1) else: self.module_group_box.setCurrentIndex(0) self.module_ID_box.setCurrentIndex(0) def prev_clicked(self): currentGroup = self.module_group_box.currentIndex() currentModule = self.module_ID_box.currentIndex() # Check if the first one. if currentModule != 0: self.module_ID_box.setCurrentIndex(currentModule - 1) else: if currentGroup != 0: self.module_group_box.setCurrentIndex(currentGroup - 1) else: self.module_group_box.setCurrentIndex( self.module_group_box.count() - 1) self.module_ID_box.setCurrentIndex(self.module_ID_box.count() - 1) def reference_button_fading(self): if self.showing_ref_box.isChecked(): self.overlay_ref_box.setEnabled(True) self.overlay_refDiff_box.setEnabled(True) self.overlay_refRatio_box.setEnabled(True) else: self.overlay_ref_box.setEnabled(False) self.overlay_refDiff_box.setEnabled(False) self.overlay_refRatio_box.setEnabled(False)
class LegendPropertiesWindow(PyDialog): """ +-------------------+ | Legend Properties | +-----------------------+ | Title ______ Default | | Min ______ Default | | Max ______ Default | | Format ______ Default | | Scale ______ Default | | Phase ______ Default | | Number of Colors ____ | | Number of Labels ____ | | Label Size ____ | (TODO) | ColorMap ____ | (TODO) | | | x Min/Max (Blue->Red) | | o Max/Min (Red->Blue) | | | | x Vertical/Horizontal | | x Show/Hide | | | | Animate | | Apply OK Cancel | +-----------------------+ """ def __init__(self, data, win_parent=None): PyDialog.__init__(self, data, win_parent) self._updated_legend = False self._animation_window_shown = False self._icase = data['icase'] self._default_icase = self._icase self._default_name = data['name'] self._default_min = data['min'] self._default_max = data['max'] self._default_scale = data['default_scale'] self._scale = data['scale'] self._default_phase = data['default_phase'] self._phase = data['phase'] self._default_format = data['default_format'] self._format = data['format'] self._default_labelsize = data['default_labelsize'] self._labelsize = data['labelsize'] self._default_nlabels = data['default_nlabels'] self._nlabels = data['nlabels'] self._default_ncolors = data['default_ncolors'] self._ncolors = data['ncolors'] self._default_colormap = data['default_colormap'] self._colormap = data['colormap'] self._default_is_low_to_high = data['is_low_to_high'] self._default_is_discrete = data['is_discrete'] self._default_is_horizontal = data['is_horizontal'] self._default_is_shown = data['is_shown'] self._is_normals = data['is_normals'] self._update_defaults_to_blank() #self.setupUi(self) self.setWindowTitle('Legend Properties') self.create_widgets() self.create_layout() self.set_connections() self.set_font_size(data['font_size']) def _update_defaults_to_blank(self): """Changes the default (None) to a blank string""" if self._default_colormap is None: self._default_colormap = 'jet' if self._default_labelsize is None: self._default_labelsize = '' if self._default_ncolors is None: self._default_ncolors = '' if self._default_nlabels is None: self._default_nlabels = '' if self._colormap is None: self._colormap = 'jet' if self._labelsize is None: self._labelsize = '' if self._ncolors is None: self._ncolors = '' if self._nlabels is None: self._nlabels = '' def update_legend(self, icase, name, min_value, max_value, data_format, scale, phase, nlabels, labelsize, ncolors, colormap, default_title, default_min_value, default_max_value, default_data_format, default_scale, default_phase, default_nlabels, default_labelsize, default_ncolors, default_colormap, is_low_to_high, is_horizontal_scalar_bar, is_normals, font_size=8): """ We need to update the legend if there's been a result change request """ self.set_font_size(font_size) if icase != self._default_icase: self._icase = icase self._default_icase = icase self._default_name = default_title self._default_min = default_min_value self._default_max = default_max_value self._default_format = default_data_format self._default_is_low_to_high = is_low_to_high self._default_is_discrete = True self._default_is_horizontal = is_horizontal_scalar_bar self._default_scale = default_scale self._default_phase = default_phase self._default_nlabels = default_nlabels self._default_labelsize = default_labelsize self._default_ncolors = default_ncolors self._default_colormap = default_colormap self._is_normals = is_normals if colormap is None: colormap = 'jet' if labelsize is None: labelsize = '' if ncolors is None: ncolors = '' if nlabels is None: nlabels = '' self._update_defaults_to_blank() assert isinstance(scale, float), 'scale=%r' % scale assert isinstance(default_scale, float), 'default_scale=%r' % default_scale if self._default_scale == 0.0: self.scale.setEnabled(False) self.scale_edit.setEnabled(False) self.scale_button.setEnabled(False) else: self.scale.setEnabled(True) self.scale_edit.setEnabled(True) self.scale_button.setEnabled(True) if self._default_phase is None: self._phase = None self.phase.setEnabled(False) self.phase_edit.setEnabled(False) self.phase_button.setEnabled(False) self.phase_edit.setText('0.0') self.phase_edit.setStyleSheet("QLineEdit{background: white;}") else: self._phase = phase self.phase.setEnabled(True) self.phase_edit.setEnabled(True) self.phase_button.setEnabled(True) self.phase_edit.setText(str(phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") #self.on_default_name() #self.on_default_min() #self.on_default_max() #self.on_default_format() #self.on_default_scale() # reset defaults self._name = name self.name_edit.setText(name) self.name_edit.setStyleSheet("QLineEdit{background: white;}") self.min_edit.setText(str(min_value)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") self.max_edit.setText(str(max_value)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") self.format_edit.setText(str(data_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") self._scale = scale self.scale_edit.setText(str(scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(nlabels)) self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.labelsize_edit.setText(str(labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") self.ncolors_edit.setText(str(ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") self.colormap_edit.setCurrentIndex( colormap_keys.index(str(colormap))) # lots of hacking for the Normal vectors enable = True if self._is_normals: enable = False self.max.setVisible(enable) self.min.setVisible(enable) self.max_edit.setVisible(enable) self.min_edit.setVisible(enable) self.max_button.setVisible(enable) self.min_button.setVisible(enable) self.show_radio.setVisible(enable) self.hide_radio.setVisible(enable) self.low_to_high_radio.setVisible(enable) self.high_to_low_radio.setVisible(enable) self.format.setVisible(enable) self.format_edit.setVisible(enable) self.format_edit.setVisible(enable) self.format_button.setVisible(enable) self.nlabels.setVisible(enable) self.nlabels_edit.setVisible(enable) self.nlabels_button.setVisible(enable) self.ncolors.setVisible(enable) self.ncolors_edit.setVisible(enable) self.ncolors_button.setVisible(enable) self.grid2_title.setVisible(enable) self.vertical_radio.setVisible(enable) self.horizontal_radio.setVisible(enable) self.colormap.setVisible(enable) self.colormap_edit.setVisible(enable) self.colormap_button.setVisible(enable) self.on_apply() def create_widgets(self): """creates the menu objects""" # Name self.name = QLabel("Title:") self.name_edit = QLineEdit(str(self._default_name)) self.name_button = QPushButton("Default") # Min self.min = QLabel("Min:") self.min_edit = QLineEdit(str(self._default_min)) self.min_button = QPushButton("Default") # Max self.max = QLabel("Max:") self.max_edit = QLineEdit(str(self._default_max)) self.max_button = QPushButton("Default") #--------------------------------------- # Format self.format = QLabel("Format (e.g. %.3f, %g, %.6e):") self.format_edit = QLineEdit(str(self._format)) self.format_button = QPushButton("Default") #--------------------------------------- # Scale self.scale = QLabel("Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") if self._default_scale == 0.0: self.scale.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) # Phase self.phase = QLabel("Phase (deg):") self.phase_edit = QLineEdit(str(self._phase)) self.phase_button = QPushButton("Default") if self._default_phase is None: self.phase.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) self.phase_edit.setText('0.0') #tip = QtGui.QToolTip() #tip.setTe #self.format_edit.toolTip(tip) #--------------------------------------- # nlabels self.nlabels = QLabel("Number of Labels:") self.nlabels_edit = QLineEdit(str(self._nlabels)) self.nlabels_button = QPushButton("Default") self.labelsize = QLabel("Label Size:") self.labelsize_edit = QLineEdit(str(self._labelsize)) self.labelsize_button = QPushButton("Default") self.ncolors = QLabel("Number of Colors:") self.ncolors_edit = QLineEdit(str(self._ncolors)) self.ncolors_button = QPushButton("Default") self.colormap = QLabel("Color Map:") self.colormap_edit = QComboBox(self) self.colormap_button = QPushButton("Default") for key in colormap_keys: self.colormap_edit.addItem(key) self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap)) # -------------------------------------------------------------- # the header self.grid2_title = QLabel("Color Scale:") # red/blue or blue/red self.low_to_high_radio = QRadioButton('Low -> High') self.high_to_low_radio = QRadioButton('High -> Low') widget = QWidget(self) low_to_high_group = QButtonGroup(widget) low_to_high_group.addButton(self.low_to_high_radio) low_to_high_group.addButton(self.high_to_low_radio) self.low_to_high_radio.setChecked(self._default_is_low_to_high) self.high_to_low_radio.setChecked(not self._default_is_low_to_high) # horizontal / vertical self.horizontal_radio = QRadioButton("Horizontal") self.vertical_radio = QRadioButton("Vertical") widget = QWidget(self) horizontal_vertical_group = QButtonGroup(widget) horizontal_vertical_group.addButton(self.horizontal_radio) horizontal_vertical_group.addButton(self.vertical_radio) self.horizontal_radio.setChecked(self._default_is_horizontal) self.vertical_radio.setChecked(not self._default_is_horizontal) # on / off self.show_radio = QRadioButton("Show") self.hide_radio = QRadioButton("Hide") widget = QWidget(self) show_hide_group = QButtonGroup(widget) show_hide_group.addButton(self.show_radio) show_hide_group.addButton(self.hide_radio) self.show_radio.setChecked(self._default_is_shown) self.hide_radio.setChecked(not self._default_is_shown) # -------------------------------------------------------------- if self._is_normals: self.max.hide() self.min.hide() self.max_edit.hide() self.min_edit.hide() self.max_button.hide() self.min_button.hide() self.format.hide() self.format_edit.hide() self.format_button.hide() self.nlabels.hide() self.nlabels_edit.hide() self.nlabels_button.hide() self.ncolors.hide() self.ncolors_edit.hide() self.ncolors_button.hide() self.grid2_title.hide() self.vertical_radio.hide() self.horizontal_radio.hide() self.show_radio.hide() self.hide_radio.hide() self.low_to_high_radio.hide() self.high_to_low_radio.hide() self.colormap.hide() self.colormap_edit.hide() self.colormap_button.hide() self.animate_button = QPushButton('Create Animation') if self._default_scale == 0.0: self.animate_button.setEnabled(False) self.animate_button.setToolTip( 'This must be a displacement-like result to animate') # closing self.apply_button = QPushButton("Apply") self.ok_button = QPushButton("OK") self.cancel_button = QPushButton("Cancel") def create_layout(self): """displays the menu objects""" grid = QGridLayout() grid.addWidget(self.name, 0, 0) grid.addWidget(self.name_edit, 0, 1) grid.addWidget(self.name_button, 0, 2) grid.addWidget(self.min, 1, 0) grid.addWidget(self.min_edit, 1, 1) grid.addWidget(self.min_button, 1, 2) grid.addWidget(self.max, 2, 0) grid.addWidget(self.max_edit, 2, 1) grid.addWidget(self.max_button, 2, 2) grid.addWidget(self.format, 3, 0) grid.addWidget(self.format_edit, 3, 1) grid.addWidget(self.format_button, 3, 2) grid.addWidget(self.scale, 4, 0) grid.addWidget(self.scale_edit, 4, 1) grid.addWidget(self.scale_button, 4, 2) grid.addWidget(self.phase, 5, 0) grid.addWidget(self.phase_edit, 5, 1) grid.addWidget(self.phase_button, 5, 2) grid.addWidget(self.nlabels, 6, 0) grid.addWidget(self.nlabels_edit, 6, 1) grid.addWidget(self.nlabels_button, 6, 2) #grid.addWidget(self.labelsize, 6, 0) #grid.addWidget(self.labelsize_edit, 6, 1) #grid.addWidget(self.labelsize_button, 6, 2) grid.addWidget(self.ncolors, 7, 0) grid.addWidget(self.ncolors_edit, 7, 1) grid.addWidget(self.ncolors_button, 7, 2) grid.addWidget(self.colormap, 8, 0) grid.addWidget(self.colormap_edit, 8, 1) grid.addWidget(self.colormap_button, 8, 2) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.cancel_button) grid2 = QGridLayout() grid2.addWidget(self.grid2_title, 0, 0) grid2.addWidget(self.low_to_high_radio, 1, 0) grid2.addWidget(self.high_to_low_radio, 2, 0) grid2.addWidget(self.vertical_radio, 1, 1) grid2.addWidget(self.horizontal_radio, 2, 1) grid2.addWidget(self.show_radio, 1, 2) grid2.addWidget(self.hide_radio, 2, 2) grid2.addWidget(self.animate_button, 3, 1) #grid2.setSpacing(0) vbox = QVBoxLayout() vbox.addLayout(grid) #vbox.addLayout(checkboxes) vbox.addLayout(grid2) vbox.addStretch() vbox.addLayout(ok_cancel_box) #Create central widget, add layout and set #central_widget = QtGui.QWidget() #central_widget.setLayout(vbox) #self.setCentralWidget(central_widget) self.setLayout(vbox) def set_connections(self): """creates the actions for the buttons""" self.name_button.clicked.connect(self.on_default_name) self.min_button.clicked.connect(self.on_default_min) self.max_button.clicked.connect(self.on_default_max) self.format_button.clicked.connect(self.on_default_format) self.scale_button.clicked.connect(self.on_default_scale) self.phase_button.clicked.connect(self.on_default_phase) self.nlabels_button.clicked.connect(self.on_default_nlabels) self.labelsize_button.clicked.connect(self.on_default_labelsize) self.ncolors_button.clicked.connect(self.on_default_ncolors) self.colormap_button.clicked.connect(self.on_default_colormap) self.animate_button.clicked.connect(self.on_animate) self.show_radio.clicked.connect(self.on_show_hide) self.hide_radio.clicked.connect(self.on_show_hide) self.apply_button.clicked.connect(self.on_apply) self.ok_button.clicked.connect(self.on_ok) self.cancel_button.clicked.connect(self.on_cancel) if qt_version == 4: self.connect(self, QtCore.SIGNAL('triggered()'), self.closeEvent) #self.colormap_edit.activated[str].connect(self.onActivated) #else: # closeEvent??? def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font) self.name_edit.setFont(font) self.min_edit.setFont(font) self.max_edit.setFont(font) self.format_edit.setFont(font) self.scale_edit.setFont(font) self.phase_edit.setFont(font) self.nlabels_edit.setFont(font) self.labelsize_edit.setFont(font) self.ncolors_edit.setFont(font) def on_animate(self): """opens the animation window""" name, flag0 = self.check_name(self.name_edit) if not flag0: return scale, flag1 = self.check_float(self.scale_edit) if not flag1: scale = self._scale data = { 'font_size': self.out_data['font_size'], 'icase': self._icase, 'name': name, 'time': 2, 'frames/sec': 30, 'resolution': 1, 'iframe': 0, 'scale': scale, 'default_scale': self._default_scale, 'is_scale': self._default_phase is None, 'phase': self._phase, 'default_phase': self._default_phase, 'dirname': os.path.abspath(os.getcwd()), 'clicked_ok': False, 'close': False, } if not self._animation_window_shown: self._animation_window = AnimationWindow(data, win_parent=self) self._animation_window.show() self._animation_window_shown = True self._animation_window.exec_() else: self._animation_window.activateWindow() if data['close']: if not self._animation_window._updated_animation: #self._apply_animation(data) pass self._animation_window_shown = False del self._animation_window else: self._animation_window.activateWindow() def on_default_name(self): """action when user clicks 'Default' for name""" name = str(self._default_name) self.name_edit.setText(name) self.name_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_min(self): """action when user clicks 'Default' for min value""" self.min_edit.setText(str(self._default_min)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_max(self): """action when user clicks 'Default' for max value""" self.max_edit.setText(str(self._default_max)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_format(self): """action when user clicks 'Default' for the number format""" self.format_edit.setText(str(self._default_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_scale(self): """action when user clicks 'Default' for scale factor""" self.scale_edit.setText(str(self._default_scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_phase(self): """action when user clicks 'Default' for phase angle""" self.phase_edit.setText(str(self._default_phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_ncolors(self): """action when user clicks 'Default' for number of colors""" self.ncolors_edit.setText(str(self._default_ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_colormap(self): """action when user clicks 'Default' for the color map""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) def on_default_nlabels(self): """action when user clicks 'Default' for number of labels""" self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(self._default_nlabels)) def on_default_labelsize(self): """action when user clicks 'Default' for number of labelsize""" self.labelsize_edit.setText(str(self._default_labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") def on_show_hide(self): """action when user clicks the 'Show/Hide' radio button""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) is_shown = self.show_radio.isChecked() self.vertical_radio.setEnabled(is_shown) self.horizontal_radio.setEnabled(is_shown) @staticmethod def check_name(cell): cell_value = cell.text() try: text = str(cell_value).strip() except UnicodeEncodeError: cell.setStyleSheet("QLineEdit{background: red;}") return None, False if len(text): cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False @staticmethod def check_colormap(cell): text = str(cell.text()).strip() if text in colormap_keys: cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False def on_validate(self): name_value, flag0 = self.check_name(self.name_edit) min_value, flag1 = self.check_float(self.min_edit) max_value, flag2 = self.check_float(self.max_edit) format_value, flag3 = self.check_format(self.format_edit) scale, flag4 = self.check_float(self.scale_edit) phase, flag5 = self.check_float(self.phase_edit) nlabels, flag6 = self.check_positive_int_or_blank(self.nlabels_edit) ncolors, flag7 = self.check_positive_int_or_blank(self.ncolors_edit) labelsize, flag8 = self.check_positive_int_or_blank( self.labelsize_edit) colormap = str(self.colormap_edit.currentText()) if all([flag0, flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8]): if 'i' in format_value: format_value = '%i' assert isinstance(scale, float), scale self.out_data['name'] = name_value self.out_data['min'] = min_value self.out_data['max'] = max_value self.out_data['format'] = format_value self.out_data['scale'] = scale self.out_data['phase'] = phase self.out_data['nlabels'] = nlabels self.out_data['ncolors'] = ncolors self.out_data['labelsize'] = labelsize self.out_data['colormap'] = colormap self.out_data['is_low_to_high'] = self.low_to_high_radio.isChecked( ) self.out_data['is_horizontal'] = self.horizontal_radio.isChecked() self.out_data['is_shown'] = self.show_radio.isChecked() self.out_data['clicked_ok'] = True self.out_data['close'] = True #print('self.out_data = ', self.out_data) #print("name = %r" % self.name_edit.text()) #print("min = %r" % self.min_edit.text()) #print("max = %r" % self.max_edit.text()) #print("format = %r" % self.format_edit.text()) return True return False def on_apply(self): passed = self.on_validate() if passed: self.win_parent._apply_legend(self.out_data) return passed def on_ok(self): passed = self.on_apply() if passed: self.close() #self.destroy() def on_cancel(self): self.out_data['close'] = True self.close()