Esempio n. 1
0
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)
Esempio n. 2
0
File: mplayer.py Progetto: Ptaah/Ekd
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
Esempio n. 3
0
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)
Esempio n. 4
0
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 
Esempio n. 6
0
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')))
Esempio n. 7
0
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()
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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()